yagop / node-telegram-bot-api

Telegram Bot API for NodeJS
MIT License
8.45k stars 1.53k forks source link

Telegram Bot sending Photo and documents to everyone who started bot #633

Closed HeeroML closed 3 years ago

HeeroML commented 6 years ago

Bug Report

I have read:

I am using the latest version of the library.

Expected Behavior

I try to send a picture stored on my server to only the user who clicks on a inline button.

Actual Behavior

After clicking inline button, bots sends it to every user who started the bot.

Steps to reproduce the Behavior

this.bot.onText(/\Tools\s*(.*)/, function (msg, match) {
        const user_id = msg.chat.id;
        self.lookup_user_lang(user_id, function (l_key) {
            var tools_text = self.msg_lookup.get_text(l_key, 'tools_text');
            var tools_in_menu = self.msg_lookup.get_text(l_key, 'tools_in_menu');
            var tools_text_2 = self.msg_lookup.get_text(l_key, 'tools_text_2');
            var return_menu = self.msg_lookup.get_text(l_key, 'return_menu');
            self.bot.sendMessage(user_id,tools_text,tools_in_menu) .then(() => {
                return self.bot.sendMessage(user_id,tools_text_2, return_menu)
            });
            self.bot.on("callback_query", function(callbackQuery) {
                // 'callbackQuery' is of type CallbackQuery
                if (callbackQuery.data === 't1') {
                    self.bot.sendPhoto(user_id, 'some url' );
                    self.bot.sendMessage(user_id, 'Bild gesendet' )
                } if (callbackQuery.data === 't2') {
                    self.bot.sendMessage(user_id, 'Video gesendet' )
                } if (callbackQuery.data === 't3') {
                    self.bot.sendMessage(user_id, 'Sonstiges gesendet' )
                };
                self.bot.answerCallbackQuery(callbackQuery.id);
            });
        });
    });

Thats the code, also here is the reply markup:


                'tools_in_menu': {
                    reply_markup: JSON.stringify({
                        inline_keyboard: [
                            [{text: 'Grafik', callback_data: 'p1'}],
                            [{text: 'Video', callback_data: 'p2'}],
                            [{text: 'Sonstiges', callback_data: 'p3'}],
                        ],
                        resize_keyboard: true,
                        parse_mode: 'Markdown'
                    }),

                },

So whats the issue here?

DtCarrot commented 6 years ago

Can you check whether the sendMessage and sendPhoto in the if loop is only called once for each callback?

Also, in the reply markup, the callback_data is set as p1, p2 and p3 but you are checking for t1, t2, t3 in the .on('callback_query') callback function.

HeeroML commented 6 years ago

That data is fine, I just changed names later. Didn't reflect on second code. But what would that change if it's called Everytime?

HeeroML commented 6 years ago

Do you mean that's running it on every user? BTW need to add, only sends to people in that Menu with that buttons. So if you see this Buttons you get the message. How does this work? Do I need to ask for user ID in front of it? Doesn't makes logical sense to me 😁 is callback queryb sending a user id? So I make && in the if.

DtCarrot commented 6 years ago

sendMessage(userId) should only send the message to the specified userId defined in the paramter. That's why I found it weird that the photo / video is being sent to all users.

HeeroML commented 6 years ago

But actually, you could be right. Everyone in this menu with this buttons is in that function. So the if applies to them. so my question is, it's weird still. Can't test right now, need to do later

DtCarrot commented 6 years ago

Think I may know why,

It may have to do with the fact that you create the telegram bot event listener within the /Tools onText event handler. This means that you are accidentally creating a new event listener 'callback_query' everytime a user enters /Tools in telegram (Not sure what it does). You are also not getting the user id from the 'callback_query' but the 'onText' listener instead. Thus, it will send the photo to every user that has entered /Tools before.

HeeroML commented 6 years ago

Just thinking how I fix this, a short check for callback user id should be enough. Or I make it outside of that event Listener tools

DtCarrot commented 6 years ago

I suggest doing the following, place the .on('callback_query') out of the onText event listener.

Get the user id from callbackQuery.from.id instead. Use this user id when invoking the sendMessage(userId) function.

-- Start of code -- this.bot.on('callback_query', function (callbackQuery) { ... }

this.bot.onText(/\Tools\s(.)/, function (msg, match) { const user_id = msg.chat.id; self.lookup_user_lang(user_id, function (l_key) { var tools_text = self.msg_lookup.get_text(l_key, 'tools_text'); var tools_in_menu = self.msg_lookup.get_text(l_key, 'tools_in_menu'); var tools_text_2 = self.msg_lookup.get_text(l_key, 'tools_text_2'); var return_menu = self.msg_lookup.get_text(l_key, 'return_menu'); self.bot.sendMessage(user_id,tools_text,tools_in_menu) .then(() => { return self.bot.sendMessage(user_id,tools_text_2, return_menu) });

-- end of code --

HeeroML commented 6 years ago

Thanks I try and close if it's working, started to think it's a bug of the script, cause it made no sense too me 😂