node-telegram-bot-api: ReplyKeyboardMarkup problem

Hi, i saw various issues about this argument but still not working.

I used this code:

var yesno = {
        parse_mode: "Markdown",
        reply_markup: {
                ReplyKeyboardMarkup: {
                        "resize_keyboard": true,
                        "one_time_keyboard": true,
                        "keyboard": [["Yes"],["Back"]]
                }
        }
};

To reply a message without change function, but it doesn’t print keybard so not work. I tried without ReplyKeyboardMarkup but with force_reply, keyboard appers but not link to reply message.

var yesno = {
        parse_mode: "Markdown",
        reply_markup: {
                "force_reply": true,
                "resize_keyboard": true,
                "one_time_keyboard": true,
                "keyboard": [["Yes"],["Back"]]
        }
};

What can i do? Thanks!

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 19 (5 by maintainers)

Most upvoted comments

Yeah, there are two functions:

(From above)

Catching answers/replies:

bot.on("message", function(msg) {
     const callback = answerCallbacks[msg.chat.id];
     if (callback) {
         delete answerCallbacks[msg.chat.id];
         return callback(msg);
      }
});

This function will not be repeated, as it handles answer for all your queries. It only need to exist once.

Your query and answer:

bot.sendMessage(chatId, messageText).then(function() {
    // add a new 'answer' callback to receive the reply message
    answerCallbacks[chatId] = function(answer) {
        // ... do something with your answer ...
    };
});

All your logic remains together. As you see above, in the .then(), we are adding a new function to handle the query.

NOTE:

The implementation is quite premature. A better implementation can be drawn up.

Works perfectly! Thanks!!

There’s a logic error in your code.

bot.sendMessage(message.chat.id, "Are you sure?", yesno).then(() => {
     // this function is executed when the above message has been
     // successfully sent to the target chat

     // this registers an event handler to be invoked (only once) when
     // a message update is received.
     // To be clear, this listens for ANY message update. It does NOT
     // listen for a reply from this SPECIFIC user.
     // There's a possibility of this handler receiving a message from
     // ANOTHER user.
     bot.once('message', (answer) => {
        var res = answer.text;
              if (res == "Back to menu"){
                        return;
               }else if (res == "Yes"){
                         //other things
               }
      });
});

This means that, in situations where users are few, the bot.once() will most likely receive the correct user’s reply, since the chances of another user sending us a message, while we wait for a reply (with bot.once()) is relatively low.

If the are many users, these chances increase. Thus, there might exist scenarios where the bot.once() handler receives a reply from the wrong user.

First, bot API parameters let you choose only one option among force_reply, InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardHide. So, “keyboard”, “resize_keyboard” and “one_time_keyboard” will be ignored due to force_reply.

Then, if I understood rightly your problem, as I solved in my issue topic, you can use Promise’s .then() method to set a new “waiting-for-a-reply” by not using bot.onReplyToMessage() but using EventEmitter 3 method

.once(trigger, callback)

which attach an event and then remove it once received the trigger (unlike .on(trigger, callback), which doesn’t remove the event).

This has to be done if your bot function is going to be built for a one-to-one interaction and not group interaction. Instead, you can put into your .then() callback the already said .onReplyToMessage().

In both cases as Object to be passed to .sendMessage() is something like this:

const yesno = {
    parse_mode: "Markdown",
    reply_markup: {
        keyboard: [["Yes"], ["Back"]],
        resize_keyboard: true,
        one_time_keyboard: true,
    },
};

Just remember that by putting buttons in a way like that, you will always have two rows, with one button per row. You can also do

keyboard: [["Yes", "Back"]],

and they will be putted in two rows in case of small window/screen (depending by the device).

If I didn’t understand correctly your problem, please answer back, explaining in a way more detailed. I hope to have been helpful. 😉