Repository navigation
how to send messages in order? #192
Description
Activity
if I understood rightly you problem, receiving replies in various order, happens due to bot.sendMessage asyncronicity.
You can use Promise's
.then()method. It accepts only one parameter: a callback with a(n optional) parameter that will contain last sent message details, like message_id.So you can do:
bot.sendMessage(...).then(() => { bot.sendMessage(...); });
Chaining such this way messages is a bad way, but the only one Imho.
Reacted by Rahul Vagadiya, Michael Pablo Gomes da Silva and Guillaume DorschnerI am in support of @alexandercerutti's answer.
first approach:
Furthermore, here is another approach you can use to send multiple messages:
var Promise = require('bluebird'); function sendMessages(bot, chatId, messages) { return Promise.mapSeries(messages, function(message) { return bot.sendMessage(chatId, message); }); } // example usage sendMessages(bot, chatId, ["first", "second", "third"]) .then(function() { console.log("All messages sent, in series!"); });
However, the above approach assumes you have the messages prepared in advance.
second approach:
For the use case where you are invoking
bot.sendMessage()arbitrarily, you might want to implement it using a queue of messages:var Promise = require('bluebird'); var queue = []; var inUseQueue = []; function _sendMessages() { // if we are already sending messages from the queue, or // the queue is empty, stop if (inUseQueue.length || !queue.length) return; console.log("processing queue"); inUseQueue = queue; queue = []; Promise.mapSeries(inUseQueue, function(request) { var resolve = request.resolve; var reject = request.reject; var bot = request.bot; console.log("sending message '%s'", request.message); return bot.sendMessage(request.chatId, request.message) .then(resolve) .catch(reject); }).then(function() { console.log("queue processed"); inUseQueue = []; _sendMessages(); }); } function sendMessage(bot, chatId, message) { var resolve, reject; var promise = new Promise(function(promiseResolve, promiseReject) { resolve = promiseResolve; reject = promiseReject; }); console.log("pushing message '%s' to queue", message); queue.push({ bot, chatId, message, resolve, reject }); process.nextTick(_sendMessages); return promise; } // example usage function toLog(message) { return function() { console.log(message); }; }; sendMessage(bot, chatId, "first").then(toLog("first sent!")); setTimeout(function() { sendMessage(bot, chatId, "second").then(toLog("second sent!")); }, 1000); setTimeout(function() { sendMessage(bot, chatId, "third").then(toLog("third sent!")); }, 2000);
The above example usage gave me this output:
pushing message 'first' to queue processing queue sending message 'first' pushing message 'second' to queue pushing message 'third' to queue first sent! queue processed processing queue sending message 'second' second sent! sending message 'third' third sent! queue processedHope that gives you an idea of how to solve your problem.
(And maybe a PR for this could be awesome!)
Reacted by Mohamed Sohail, Soheil Saghian, yeygeni, Pavel Holyavkin, vlad, letam, Igor, TiZi0352, Giorgio Robino, Sergey Gustun and 2 moreReacted by Igor, TiZi0352 and Giorgio RobinoReacted by TiZi0352 and silvio-barbottoReacted by TiZi0352oh well. I guess I'll make generic per-user "dispatch queue" where I'd put the messages and it would ensure it wont interleave them... or aggregate, if I accidentally spam it with 100 msgs :)
Thanks for the advice though.
UPD: nice, you added the queue example while I was writing my comment :)
(And maybe a PR for this could be awesome!)
@GochoMugo btw, I noticed we have a fork (node-telegram-bot-api-latest), shall I switch to it and submit PRs there, if any?
@wizzardo That repo is mainly for merging PRs from this repo. It is just bleeding-edge for kinda-advanced users (and might disappear, if @yagop keeps up with PRs here). Also see the beginning of the README in the fork.
So, please draft your PRs against this repo. I will (most probably) help you perfect it here, then we will have our bot automatically draft it from here to the fork and we merge.
hmmm... given there was a few months since last PR was merged, maybe it's possible to ask @yagop for commit access?
I might do that some time to come, but I gave him the benefit of doubt: we get busy at times, you know! But I might query him and see the result.
I have built a wrapper around this library to add higher-level features. Currently, it supports sending messages in order. It is called tgfancy. See https://github.com/GochoMugo/tgfancy for more information.
Reacted by Pavel Holyavkin/cc @phillipadsmith
Reacted by Phillip SmithReacted by Phillip Smith
when using e.g. C# Telegram.Bot library, I can do successive calls to bot.sendmessage and the user receives them in the order which I used to send. With node-telegram-bot-api, I often get replies in random order.
Repro: create a basic echo bot, verify it works, stop bot, send 3-4 messages, start bot, see messages received by bot in order, but replies in chat in random order.