AWS Lambda - 使用 MySQL 的 Telegram Bot - 循环消息 \ 相同消息
Posted
技术标签:
【中文标题】AWS Lambda - 使用 MySQL 的 Telegram Bot - 循环消息 \\ 相同消息【英文标题】:AWS Lambda - Telegram Bot with MySQL - Loop Message \ Same MessageAWS Lambda - 使用 MySQL 的 Telegram Bot - 循环消息 \ 相同消息 【发布时间】:2020-07-29 03:39:06 【问题描述】:我正在开发一个 AWS Lambda 函数来托管我的 Telegram Bot。
项目详情:
它正在使用 webhook(API 网关); Lambda 函数将接收 Telegram 消息并检查数据库; 我正在使用 mysql 来存储用户和一些详细信息。简单的工作流程:
用户发送 Telegram 消息 -> Telegram Webhook -> API Gateway -> AWS Lambda -> MYSQL 查询 -> 回复 Telegram 用户守则
索引.js
const bot = require('./Bot')
exports.handler = function(event, context, callback)
const tmp = JSON.parse(event.body)
bot.handleUpdate(tmp)
.then(() =>
var response = "statusCode": 200, "body": "OK"
//callback(null, response)
//context.succeed(response)
)
在 Bot.js 中,有一个 MYSQL 查询来检查用户是否在允许的日期和小时内发送消息。
问题:
如果我使用回调(null, response)
查询以正确的方式运行; 用户收到回复。在这种情况下,我不断从 webhook 循环接收相同的消息。据我所见,响应不起作用
如果我使用 context.succeed(response)
查询未运行; 用户没有收到回复。在这种情况下,我只收到一次原始消息。
任何人都知道什么可以解决这个问题。我已经尝试使用上下文和回调,但是查询没有运行,用户也没有收到回复。
【问题讨论】:
【参考方案1】:经过长时间检查所有日志并了解我的基础架构的场景后,我解决了这个问题。让我们首先以更好的方式了解情况:
场景的更多细节:
我检查了 API Gateway 和 Lambda 中可接受的最大超时值是:
Lambda:最多 15 分钟 API 网关: 最长 - 30 秒了解这些值后,我开始查看我的 Lambda 函数日志:
原代码: 1分钟完成执行 改进的代码: 40 秒完成执行如您所见,即使在改进了我的代码之后,它也没有在 API 网关超时之前完成。它开始了我面临的问题。
如果您查看 Telegram Webhook 信息:
要检查的网址: https://api.telegram.org/botYOUR TOKEN/getWebhookInfo我一遍又一遍地在待处理状态中收到相同的消息。它导致收到的消息出现循环。如果您没有对状态为 200 的 Telegram Webhook 做出响应,它将继续为您发送该消息。
回到简单的工作流程
用户发送 Telegram 消息 -> Telegram Webhook -> API Gateway -> AWS Lambda -> MYSQL 查询 -> 回复 Telegram 用户问题发生在 Telegram Webhook 和 API 网关之间。由于我的 Lambda 函数需要 30 多秒才能完成,我们的 API 网关永远不会发送响应。它使 Telegram Webhook 不断重复发送相同的消息。
我的解决方法:
我们需要在 API Gateway 超时(30 秒)内发回响应,但我们还需要保持 Lambda 函数运行,直到它以预期结果完成。
搜索后发现题目:Nodejs - Invoke an AWS.Lambda function from within another lambda function
如果我们调用第二个 Lambda,我们可以并行运行它,而第一个 Lambda 可以为 Telegram Webhook 发送预期的响应。
解决方案:
基于这个主题,我检查了一下如何在不等待响应的情况下运行第二个 Lambda 函数,答案是:“Lambda as an EVENT”
更多详情在这里: https://docs.aws.amazon.com/lambda/latest/dg/lambda-invocation.html
正如本主题所解释的,如果您将 Lambda 函数作为 EVENT 调用,将会发生什么:
Lambda 1 -> 调用 Lambda 2 Lambda 2 -> 为 Lambda 1 发送状态 202 Lambda 1 -> 为 Telegram Webhook 发送状态 200 Lambda 2 -> 继续运行直到完成工作这解决了整个问题。
现在 Telegram Webhook 正在接收预期状态,并且我的 Bot 正在并行运行。 现在也许你期待最终的代码。所以我会和你分享。
代码:
Lambda 1 AWS = require('aws-sdk');
AWS.config.region = 'sa-east-1'; //Change for your own region
var lambda = new AWS.Lambda();
exports.handler = function(event, context, callback)
console.log(event)
var params =
FunctionName: 'Lambda Function Name',
InvocationType: 'Event',
Payload: JSON.stringify(event)
;
lambda.invoke(params, function(err, data)
if (err)
console.log(err)
)
callback(null, statusCode: 200, body: '')
Lambda 2
const bot = require('./Bot')
exports.handler = function(event)
const tmp = JSON.parse(event.body)
bot.handleUpdate(tmp)
附加提示:
您的 Lambda 1 将需要运行 Lambda 2 所需的角色。如果您启用 CloudWatch Logs,它将为您提供所有必要的角色,但我将分享我在下面设置的角色:
【讨论】:
以上是关于AWS Lambda - 使用 MySQL 的 Telegram Bot - 循环消息 \ 相同消息的主要内容,如果未能解决你的问题,请参考以下文章
无法从 AWS Lambda 连接到 AWS RDS MySql DB。 ClassNotFoundException:com.mysql.jdbc
使用 Node.js 从 AWS Lambda 函数连接到 MySql 数据库,没有连接回调
AWS Lambda Invoke 不执行 lambda 函数