如何解决Telegram Bot (Telegraf) 陷入无限循环
我的名为 status 的函数发送有关存储在 Firebase 实时数据库 中的产品的信息。当用户询问我的机器人状态时,Firebase 函数从数据库获取数据,然后为用户分配的每个产品发回电报消息。对于某些用户来说,这可能需要一些时间甚至 2 分钟。
当第一个用户第一次询问机器人状态和机器人功能时,一切正常。
但是当第二个用户询问状态第一次调用机器人功能时(当功能仍在为第一个用户运行时)第一次调用运行重新开始,在第一次调用完成后,最后处理第二次调用。
当第三用户在旧调用未完成的情况下调用函数时,一切堆叠,最后一切循环直到所有函数调用结束 .因为 bot 有近 2000 个活跃用户,上述问题陷入了“无限”循环,因为一些用户不断地为自己调用“状态”。
这种情况导致用户收到几乎无限数量的消息。
我在 Firebase 上使用 JavaScript 和 Node 12。
const { Telegraf,Markup } = require('telegraf');
const { telegrafThrottler } = require('telegraf-throttler');
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const debug = true;
admin.initializeApp(); // initialize firebase-admin
const bot = new Telegraf(functions.config().telegram_token.key); // initialize Telegraf bot
const throttler = telegrafThrottler(); // Telegraf Throttler
bot.use(throttler);
/**
*
bot.command('some_commands_here',async (ctx) => {
const nothing = 'THIS IS NOT IMPORTANT';
});
bot.command(...) more commands
*/
/** action with infinite loop problem */
bot.action('status',async (ctx) => {
const uid = ctx.update.callback_query.from.id;
let userData = await getUserAccountData(admin,uid); // get some data from firebase realtime db
if (userData !== null) {
let userProducts = await getUserProducts(admin,uid); // get some data from firebase realtime db
if (userProducts !== null) {
// userProducts contain even 200 items for one user
for (const [privateProductId,privateProductData] of Object.entries(userProducts)) {
// some not important logic that create message and keyboard context
// after this bot send informations about every product (can be even 200 messages )
await bot.telegram.sendMessage(uid,`${message}`,{
parse_mode: 'html',reply_markup: keyboard.reply_markup,});
}
}
}
// some not important logic if userData / userProducts are null
});
/** Default response for undefinded msg/commands */
bot.on('message',(ctx) => ctx.reply("Use /help if You don't know commands!"));
/** bot catch errors here */
bot.catch((err,ctx) => {
if (debug) {functions.logger.error(`Bot Catched ERROR: ${err}`);}
bot.telegram.sendMessage(123456789,`Bot Catched ERROR: ${err}`);
});
const runtimeOpts = {
timeoutSeconds: 500,memory: '1GB',};
exports.bot = functions.region('europe-west3').runWith(runtimeOpts).https.onRequest((req,res) => {
// bot.handleUpdate(req.body,res);
bot.handleUpdate(req.body,res).catch((err) => {
if (debug) {functions.logger.error(err);}
});
});
解决方法
好的终于找到原因了^^
我在我的代码中错过了 process.once,因为该函数被执行了不止一次。
process.once('SIGINT',() => bot.stop('SIGINT'));
process.once('SIGTERM',() => bot.stop('SIGTERM'));
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。