yagop / node-telegram-bot-api

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

Respond to image captions in onText listeners #354

Open david1602 opened 7 years ago

david1602 commented 7 years ago

Feature Request

I have:

Introduction

I personally think the onText of the bot API should also listen to image captions. I think the issue here is that if you check pictures via the onMessage function, the text is within the caption property rather than the text property of the message.

Currently if you register a bot.onText(/test/, callback), test will match in messages, but won't match in image captions.

Example

The example would be 1:1 the same, or optionally there could be an onCaption event. I'd prefer a unified response to captions and messages, but that's just me.

My bot dynamically adds listeners, so it looks sort of like this:

registerRegex(bot, regex, response) {
        const parsed = new RegExp(regex, 'gi');
        bot.onText(parsed, (msg, matches) => {
            const chatId = msg.chat.id;
            // Go through all the params and replace
            const returnMsg = matches.reduce( (prev, curr, idx) => {
                if (idx === 0)
                    return prev;

                const currentRegex = new RegExp(`\\$${idx}`, 'g');
                return prev.replace(currentRegex, matches[idx]);
            }, response);
            bot.sendMessage(chatId, returnMsg);
        })
    }

Wouldn't it work to update this? The question is if that's a desired behavior by the community anyway.

      if (message.caption || message.text) {
        const content = message.caption || message.text; // Grab the text if no caption is available
        debug('Text message');
        this._textRegexpCallbacks.some(reg => {
          debug('Matching %s with %s', message.text, reg.regexp);
          const result = reg.regexp.exec(content); // Use the variable here
          if (!result) {
            return false;
          }
          // reset index so we start at the beginning of the regex each time
          reg.regexp.lastIndex = 0;
          debug('Matches %s', reg.regexp);
          reg.callback(message, result);
          // returning truthy value exits .some
          return this.options.onlyFirstMatch;
        });
      }
      if (message.reply_to_message) {
        // Only callbacks waiting for this message
        this._replyListeners.forEach(reply => {
          // Message from the same chat
          if (reply.chatId === message.chat.id) {
            // Responding to that message
            if (reply.messageId === message.reply_to_message.message_id) {
              // Resolve the promise
              reply.callback(message);
            }
          }
        });
      }
GochoMugo commented 7 years ago

But the TelegramBot#onText() implies we are listening on text messages, not images. A unified solution would require that the user checks, in their listener, whether they have received a text message or an image, etc. I believe that would create too much friction. I would prefer going with a separate method.

MCSH commented 7 years ago

I think it would be possible to use a middleware (#313) to trigger onText for an image if the user wants...

david1602 commented 7 years ago

Possibly. But middlewares are not yet implemented.

@GochoMugo couldn't we pass another optional options parameter or so that would also listen to images?