telebot icon indicating copy to clipboard operation
telebot copied to clipboard

Calling askUser plugin on message from button fails

Open ruvater opened this issue 8 years ago • 2 comments

Hi!

I've encountered an issue with askUser plugin + keyboard buttons:

bot.on('/start', (msg) => {
  return bot.sendMessage(msg.from.id, 'Hi', {replyMarkup: bot.keyboard([[bot.button('', 'message')]])})
})

bot.on(/message/, (msg) => {
  return bot.sendMessage(msg.from.id, '?', {ask: 'sample'})
})

bot.on('ask.sample', (msg, props) => {
  console.log(`Received "${msg.text}"`)
})

bot.start();

After starting bot and clicking "message" button, Received "message" is printed

I found, regexp handler's promise is being resolved before message is handled by askUser plugin

To solve this issue, all regexp handlers can be combined into text handler, but is there more elegant solution?

ruvater avatar Aug 06 '17 22:08 ruvater

@ruvater Thanks for reporting the issue. Today I encountered this bug as well and spent all my day to find it!! So could you give us a quick fix until the next release? If it's necessary, I will pick the plugins code into my project until the next release.

mehrancodes avatar Dec 23 '17 21:12 mehrancodes

@mehranrasulian

Just move all involved text message handlers into "*" handler. So my example would be:

bot.on('*', (msg) => {
  if (msg.text && msg.text.match(/message/)) {
    return bot.sendMessage(msg.from.id, '?', {ask: 'sample'})
  }
})

Anyway, I found no way to make askUser plugin work, because all the data is stored in memory and it's lost when the server is restarted.

As a result, I got to this

bot.on('text', (msg, props) => {
  if (msg.text && msg.text.match(/message/)) {
    return bot.sendMessage(msg.from.id, '?', {ask: 'sample'})
  } else if {
     // Other handlers
  } else {
    return getUserValue(msg.chat.id, 'ask')
      .then((ask) => {
        if (ask) {
          bot.event('ask.' + ask, msg, props)
        } else {
          return defaultAction()
        }  
      })
  }

})

where getUserValue returns a promise that resolves to a value from some permanent storage. Moreover, we now control the order of execution, so it fixes the original issue.

ruvater avatar Dec 24 '17 01:12 ruvater