node-telegram-bot-api icon indicating copy to clipboard operation
node-telegram-bot-api copied to clipboard

Respond to image captions in onText listeners

Open david1602 opened this issue 8 years ago • 3 comments

Feature Request

I have:

  • searched for such a feature request (https://github.com/yagop/node-telegram-bot-api/labels/enhancement) and found none

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);
            }
          }
        });
      }

david1602 avatar Jun 20 '17 12:06 david1602

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.

GochoMugo avatar Jun 27 '17 07:06 GochoMugo

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

MCSH avatar Jun 28 '17 23:06 MCSH

Possibly. But middlewares are not yet implemented.

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

david1602 avatar Jun 29 '17 14:06 david1602