如何利用AWS监听存储桶并上传到tg bot

业务描述:

需要监听aws的存储中的最新消息,发送新的消息推送到指定tg的频道。

主要流程:

1.上传消息到s3存储桶(不做具体描述)

2.通过aws的lambda监听s3存储桶的最新消息(txt文件)

3.将txt文件内容处理后推送到tg频道中

具体流程:

一、准备工作

1.创建bot

2.在频道中添加bot作为管理员

3.获取bot的token和频道的channel id

二、监听s3消息并推送到指定的tg频道中

1.创建函数

2.上传代码到lambda中

注:建议使用zip上传
代码源中必须包含package和node_modules,需要项目的完整环境
注: 代码如下,可以根据自己的业务调整。我的业务tg频道的channel id是从txt中解析获取。
注: 需要注意parse_mode的选择
注: 在lambda中发送完消息之后是无法获取状态的,也就是代码中response是没法获取状态的,不管成功失败。这也就导致了会存在消息丢失的情况

javascript 复制代码
const TelegramBot = require('node-telegram-bot-api');
const AWS = require('aws-sdk');

const s3 = new AWS.S3();
const TELEGRAM_BOT_TOKEN = '你的tg bot token'; // Telegram Bot Token
const TARGET_BUCKET_NAME = '你需要监听的存储桶的名称'; // 监听的目标存储桶名称

// Initialize the Telegram bot
const bot = new TelegramBot(TELEGRAM_BOT_TOKEN);

// AWS Lambda Handler
exports.handler = async (event, context) => {
  const functionName = context.functionName; // 获取 Lambda 函数的名称
  // tg-bot-test:测试环境   tg-bot:生产
  const [TEXT_NAME, MEDIA_NAME] = functionName === 'tg-bot-test' ? ['text-output-test', 'media-test'] : ['text-output', 'media'];

  try {
    const currentTime = new Date();
    for (const record of event.Records) {
        const bucket = record.s3.bucket.name; // 存储桶名称
        const key = decodeURIComponent(record.s3.object.key.replace(/\+/g, ' ')); // 对象键
        const eventName = record.eventName;
        
        // 仅处理指定存储桶的事件(新增)
        if (bucket === TARGET_BUCKET_NAME && eventName.startsWith('ObjectCreated:Put')) {
            console.log(`New file uploaded: ${key} to bucket: ${bucket}`);

            // 获取对象的元数据
            const metadata = await getObjectMetadata(bucket, key);
            const creationTime = metadata.LastModified; // 获取创建时间
            const timeDiffInSeconds = (currentTime - creationTime) / 1000; // 计算时间差(秒)

            console.log(`File creation time: ${creationTime}, Time difference: ${timeDiffInSeconds} seconds`);

            // 若创建时间超过 60 秒,则不再继续执行
            if (timeDiffInSeconds > 60) {
                console.log(`File ${key} creation time exceeds 60 seconds, stopping execution...`);
                return; // 结束 Lambda 函数的执行
            }

            // 检查文件是否在指定的文件夹中
            if (key.startsWith(`${TEXT_NAME}/`)) {
                // 从 S3 获取文本文件内容
                const textContent = await getFileContentFromS3(bucket, key);
                console.log(`Updated file: ${key}`); // 打印更新文件的名称
                console.log(`textContent: ${textContent}`);
                
                // 获取第三行内容并转换为数字
                let numberValue = 0;
                const lines = textContent.split('\n');
                let captionContent = "";
                let channelId = "";
                if (lines.length >= 3) {
                    channelId = lines[0].trim();  // 获取发送到的频道的id
                    console.log("channelId:", channelId);
                    const thirdLine = lines[2].trim(); // 获取第三行并去除多余空格
                    numberValue = parseFloat(thirdLine); // 转换为数字
                    console.log(`Third line as number: ${numberValue}`); // 打印数字值
                    captionContent = lines.slice(3).join('\n').trim(); // 从第三行之后的所有内容
                } else {
                    console.error('The file does not contain enough lines.');
                    return;
                }

                // 提取文件名(去除文件夹和后缀)
                const fileName = key.split('/').pop().split('.').slice(0, -1).join('.');
                console.log(`File name without folder and extension: ${fileName}`); // 打印文件名

                // 生成所有图片的名称
                let allImage = [];
                for (let index = 0; index < numberValue; index++) {
                    allImage.push(`${fileName}.img${index}.jpg`);
                }
                console.log(`All images: ${allImage}`);

                // 收集图片的 URL
                const imageUrls = allImage.map(image => `https://${bucket}.s3.us-east-1.amazonaws.com/${MEDIA_NAME}/${image}`);

                // 发送所有图片作为一条消息
                await sendPhotosToTelegram(imageUrls, captionContent, channelId);
            }
        }
    }
  } catch (error) {
    console.error("error message:", error);
  }
};

const getObjectMetadata = async (bucket, key) => {
  const params = {
      Bucket: bucket,
      Key: key
  };
  const metadata = await s3.headObject(params).promise();
  return metadata; // 返回对象的元数据
};

const getFileContentFromS3 = async (bucket, key) => {
    const params = {
        Bucket: bucket,
        Key: key
    };
    const data = await s3.getObject(params).promise();
    return data.Body.toString('utf-8'); // 返回文件内容,假设是文本文件
};

const sendPhotosToTelegram = async (imageUrls, captionContent, channelId) => {
  const media = imageUrls.map((url) => ({
      type: 'photo',
      media: url,
  }));

  // 如果有需要,可以为第一张图片添加 caption
  if (captionContent) {
      media[0].caption = captionContent;
      media[0].parse_mode = 'Markdown'; 	//注意此处的选择,Markdown是支持多图和超链接文本的,但是MarkdownV2是不支持超链接文本的,而且也不支持特殊字符
  }
  
  try {
      console.log("request==================start");
      const response = await bot.sendMediaGroup(`@${channelId}`, media);
      console.log("request==================end");
      console.log('Response from Telegram:', response); // 打印 Telegram 的响应(lambda没有效果)
      return response;
  } catch (error) {
      console.error('Error sending photos to Telegram:', error.response ? error.response.data : error.message);
      throw error;
  }
};

其他

1.在没有解决消息丢失的情况下建议不要使用lambda推送重要消息

2.可以使用mq来完成消息的监听和发送,这样response也可以监听到状态,也不会存在消息丢失情况,即使丢失也可以通过状态控制。

相关推荐
HaoHao_0104 分钟前
AWS 上的 Red Hat OpenShift 服务
服务器·数据库·云计算·aws·云服务器
佛州小李哥3 小时前
在亚马逊云科技上云原生部署DeepSeek-R1模型(上)
人工智能·ai·语言模型·云计算·aws·亚马逊云科技·deepseek
HaoHao_0101 天前
AWS Fargate
大数据·服务器·云计算·aws·云服务器
F——1 天前
云计算——AWS Solutions Architect – Associate(saa)1、什么是云,AWS介绍
运维·学习·云计算·aws
HaoHao_0101 天前
AWS App2Container
服务器·云计算·aws·云服务器
在云上(oncloudai)2 天前
AWS 成本和使用情况报告:全面管理云支出和优化资源
云计算·aws
weixin_307779132 天前
AWS门店人流量数据分析项目的设计与实现
python·数据分析·系统架构·云计算·aws
weixin_307779132 天前
在AWS上设计与实现个人财务助理的Web应用程序
人工智能·python·flask·云计算·aws
weixin_307779132 天前
AWS上设计可图形化创建处理逻辑的智能电话语音客服程序的流程和关键代码
人工智能·python·自然语言处理·音视频·aws
佛州小李哥2 天前
AI安全最佳实践:AI云原生开发安全评估矩阵(上)
人工智能·科技·安全·ai·语言模型·aws·亚马逊云科技