Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to get the response of the keyboard selection? #108

Closed
sgkhode opened this issue Apr 19, 2016 · 23 comments
Closed

How to get the response of the keyboard selection? #108

sgkhode opened this issue Apr 19, 2016 · 23 comments

Comments

@sgkhode
Copy link

sgkhode commented Apr 19, 2016

I want to use keyboard to get the selected option. How to get the selected option ? Any example?

@rithvikvibhu
Copy link

rithvikvibhu commented Apr 27, 2016

+1
@sgkhode I got as far as options in bot.SendMessage()

var option = {
            "parse_mode": "Markdown",
            "reply_markup": {
                "ReplyKeyboardMarkup": {
                    "keyboard": [
                        ['Yes'],
                        ['No']
                    ]
                }
            }
        };
bot.sendMessage(msg.chat.id, "*Some* message here.", option);

Markdown works, so the 'option' object is being used. The keyboard still doesn't show. Take a look at https://core.telegram.org/bots/api#sendmessage and https://core.telegram.org/bots/api#replykeyboardmarkup

@icdevin
Copy link

icdevin commented Apr 27, 2016

The Telegram documentation is kind of vague, but reply_markup doesn't require you to specify the type of object being passed (e.g. InlineKeyboardMarkup or ReplyKeyboardMarkup), but you do need to make sure whatever object type of KeyboardMarkup you choose conforms to the specs. In this case, the keyboard property must be an array of arrays of these. Each array in the outer array represents a physical row of buttons, so this kind of arrangement -- [ [{...}, {...}], [{...}, {...}] ] would have two rows with two buttons each. Make sure to add the required properties to each button object (e.g. text).

Try this:

var options = {
  "parse_mode": "Markdown",
  "reply_markup": {
    "keyboard": [
      [{ text: "Yes" }],
      [{ text: "No" }]
    ]
  }
};

If this doesn't work, try JSON.stringifying the reply_markup object, like this:

var options = {
  "parse_mode": "Markdown",
  "reply_markup": JSON.stringify({
    "keyboard": [
      [{ text: "Yes" }],
      [{ text: "No" }]
    ]
  })
};

@rithvikvibhu
Copy link

Actually, I got it working. Yay.

var option = {
            "parse_mode": "Markdown",
            "reply_markup": {  "keyboard": [["Yes"],["No"]]  }
        };
bot.sendMessage(msg.chat.id, "*Some* message here.", option);

@rithvikvibhu
Copy link

@sgkhode You can close the issue if it anything above works for you. Cheers!

@jackdh
Copy link

jackdh commented May 12, 2016

@rithvikvibhu

Well you've just discussed how to send the keyboard if I'm not mistaken, the original question was how to read the response from that keyboard. I would also like to see an example of how this is done.

@rithvikvibhu
Copy link

@jackdh Sorry about that, didn't read the question properly :P

I got this working:

bot.onText(/^\/selectseries/, function(msg, match) {
    var seriesKB = [];  // The keyboard array
    bot.sendMessage(msg.chat.id, "Select a serie", {
        "reply_markup": {
            "keyboard": seriesKB,
            "one_time_keyboard": true
        }
    });
    bot.onText(/.+/g, function(msg, match) {
        bot.sendMessage(msg.chat.id, "You selected " + match);
        var selectedSerie = msg.query;
    });
});

@ffuubarbuzz
Copy link

@rithvikvibhu Won't your bot.onText(/.+/g be called on every message got after "/selectseries" one?

@rithvikvibhu
Copy link

Tested it and it seems so @ThiRaBrTNK
Checked the docs. There's nothing about stopping listeners. Anyone have ideas? We might have to do this manually. So telegram.js (line 560ish):

onText(regexp, callback) {
    this.textRegexpCallbacks.push({ regexp, callback });
}

I'm not on my laptop right now, but someone could meddle with this and insert a line with .pop() or .remove()

@ericzon
Copy link

ericzon commented Jun 5, 2016

@rithvikvibhu Tested .textRegexpCallbacks.pop(); and it works perfectly!

@rithvikvibhu
Copy link

rithvikvibhu commented Jun 6, 2016

@ericzon Thanks for testing it out!

@yagop is it possible to add this to the docs? Maybe even add a function

@raphaklaus
Copy link

@rithvikvibhu Thanks for your reply, but I'm afraid .pop() will withdraw other users onText if your bot process more than one user (90% of cases).

@rithvikvibhu
Copy link

rithvikvibhu commented Jul 13, 2016

@raphaklaus How are you implementing your multi user bot? It might be possible to tag users and remove their onText.

@raphaklaus
Copy link

Yes, I've made it changing the _processUpdate inside node-telegram-bot-api function to get the right callbacks, and removing them... But I think is good to state that only using .pop() is not enough to solve this problem and can lead to problems if your bot process multi users.

@rithvikvibhu
Copy link

@raphaklaus I'm actually curious on how you are storing users. Is it linked to a database/file or just in variables? Could you post a snippet of your _processUpdate or anything else you've changed? Also the part where the onText is removed
Thanks

@raphaklaus
Copy link

Take a look:
https://gist.github.com/raphaklaus/f1b1d1d2f95a066c9e4af65b9bb1c24d

In this line, I create a new method called onTextReply() supporting Telegram user's id (which I got with a previous sendMessage()) and just push it to the textRegexpCallbacks array as you can see in this gist.

Since all regex callbacks are processed specific for each user (https://gist.github.com/raphaklaus/f1b1d1d2f95a066c9e4af65b9bb1c24d#file-process-update-L27), you can remove them or not, it'll not mess things up.

@GochoMugo
Copy link
Collaborator

Please note that the _processUpdate() and 'textRegexpCallbacks' are private! And should NOT be used externally! Anything with a leading _ is private and is subject to change without deprecation! (We admit that textRegexpCallbacks was poorly named; it ought to have a leading _!) I can assure you right now that any code depending on the above stated interfaces will break in the next release!

Otherwise, the main concern in this thread would be how to hold a conversation with your bot user. There are better ways to do so in your application code, other than solely relying on onText(). With that said, we are working on a proper solution over at tgfancy#5.

As my final note, please be aware that this library is mostly focused on providing a wrapper around the Telegram Bot API, and more complex patterns, such as the one discussed above, are better implemented in your application code, or in a higher-level library!

@raphaklaus
Copy link

@GochoMugo, thanks for your concerns, but I think this issue come into this way due lack of author's support in the past.

I'm glad that something is being done. Looking forward to see this Telegram Bot Forms. :)

@ShashankaNataraj
Copy link

Well I cant believe this library allows for showing a custom keyboard but not for the reply to be read!

How am I supposed to create a multi user 3 step questionnaire if I cant read the users selection??

@raphaklaus
Copy link

@ShashankaNataraj, I managed to overcome this situation by creating an answerCallbacks in my code. Take a look into this repo: https://github.com/raphaklaus/telegram-news-bot/

@GochoMugo
Copy link
Collaborator

@ShashankaNataraj You have to implement it! This library is thin! It will NOT do everything for you! Again, that should be left for a higher-level library!!!

PS: More contribution to this open-source project will help lessen work for everyone! Also, we are doing some work over at tgfancy.

@ShashankaNataraj
Copy link

ShashankaNataraj commented Jan 9, 2017

@raphaklaus @GochoMugo Got you! I implemented a set of regex's to capture button output message and respond to them with another keyboard thus implementing my questionnaire! I now have a set of 5 questions which I ask the user and then get the responses to each one and store them in memory (as of now).

Only question I have now is how to dismiss the custom keyboard and allow the user to input his email address for the last question in the questionnaire!

EDIT: I got my answer by going through the telegram docs: "one_time_keyboard": true will dismiss the keyboard as soon as it has been used. Im using this on the final questionnaire.

My thanks to @GochoMugo on open sourcing contributing to this excellent lib! I will try to contribute something to this library soon!

@ghost
Copy link

ghost commented Jul 2, 2017

@ShashankaNataraj You can also just send ReplyKeyboardRemove to remove the reply keyboard:

{
  "reply_markup": {
    "remove_keyboard": true
  }
}

@SatoX69
Copy link

SatoX69 commented Jun 17, 2024

@jackdh Sorry about that, didn't read the question properly :P

I got this working:

bot.onText(/^\/selectseries/, function(msg, match) {
    var seriesKB = [];  // The keyboard array
    bot.sendMessage(msg.chat.id, "Select a serie", {
        "reply_markup": {
            "keyboard": seriesKB,
            "one_time_keyboard": true
        }
    });
    bot.onText(/.+/g, function(msg, match) {
        bot.sendMessage(msg.chat.id, "You selected " + match);
        var selectedSerie = msg.query;
    });
});

How to receive the event of it, like suppose it sent a keyboard, I selected one of the items and it sent that text to the chat from my side, what's the event catcher for this? Like bot.on('???')

Edit 1: My bad, looking at the code again, it seems like there's no such event for it except the good ol message and text

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests