Ma fonction nommée statut envoie des informations sur les produits stockés dans Firebase Realtime Database . Lorsque l'utilisateur demande l'état à mon bot, la fonction Firebase récupère les données de la base de données, puis renvoie un message Telegram pour chaque produit attribué à l'utilisateur. Pour certains utilisateurs, cela peut prendre un certain temps voire 2 minutes.

Lorsque le 1er utilisateur demande au bot son statut et que la fonction du bot s'exécute pour la première fois, tout va bien.

MAIS lorsque le 2ème utilisateur demande l'état lors du premier appel de la fonction du bot ( lorsque la fonction est toujours en cours d'exécution pour le 1er utilisateur ), le premier appel est lancé démarrer sur et après le premier appel, le deuxième appel est finalement traité.

Lorsque le 3e appel des utilisateurs fonctionne alors que les anciens appels ne sont pas terminés, tout s’empile et enfin tout boucle jusqu’à ce que tous les appels de fonction soient terminés . Étant donné que le bot compte près de 2000 utilisateurs actifs , ce problème ci-dessus se déroule en boucle "infinie" car certains utilisateurs appellent constamment le "statut" pour eux-mêmes.

Cette situation fait que les utilisateurs reçoivent un nombre presque infini de messages .

J'utilise JavaScript et Node 12 sur Firebase.

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);}
    });
});
0
serwer20 27 févr. 2021 à 21:59

1 réponse

Meilleure réponse

OK Enfin j'ai trouvé la cause ^^

J'ai manqué process.once dans mon code, car cette fonction a été exécutée plus d'une fois.

process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));
2
serwer20 27 févr. 2021 à 20:25