stateless-question icon indicating copy to clipboard operation
stateless-question copied to clipboard

[BUG] Always asking the question when entering the chat

Open jlanza opened this issue 5 years ago • 9 comments

Following the conversation on issue #119 in telegraf-inline-menu I have used stalessquestion to get input from a user on a menu button click. The problem that answering or not the question, every time the user exits (not leave) the chat, and go back to it, the question is displayed. I don't know why. I think it is a kind of bug or maybe a misunderstanding on the way to use the library.

Any help is welcomed.

const menu = new MenuTemplate<TelegrafContext>(() => 'Main Menu\n' + new Date().toISOString())

const menuTemplate = new MenuTemplate<TelegrafContext>(ctx => `Menu Template for ${ctx.match![1]}`)
const statelessQuestion = new TelegrafStatelessQuestion('stateless', async (ctx) => {
  await replyMenuToContext(WHAT_DO_IH_AVE_TO_PUT_HERE, ctx, menuPath);
});

bot.use(referralQuestion.middleware());
menuTemplate.interact('Default', 'default', {
  do: async (ctx, path) => {
    statelessQuestion.replyWithMarkdown(ctx, 
      'Please enter the new text for ' + ctx.match![1] + '.[ ](http://t.me/#menupath' 
      + path //ctx.match![0] 
      + ')');
    return true;
  }
});

const subMenu = new MenuTemplate<TelegrafContext>('Submenu')
subMenu.chooseIntoSubmenu('items', ['item1', 'item2'], menuTemplate, {columns: 1});

menu.submenu('Submenu', 'submenu', subMenu);
const menuMiddleware = new MenuMiddleware<TelegrafContext>('/', menu);
bot.use(menuMiddleware.middleware());

bot.command('openmenu', async (ctx) => menuMiddleware.replyToContext(ctx));

jlanza avatar Aug 28 '20 13:08 jlanza

I assume that as a bug of the Telegram clients.

One workaround I tested a few days ago is to send ReplyKeyboardRemove as reply_markup on other messages. As you can only include one reply_markup per message and the inline menu is one of them, you will need another message there to do that. In my case where I tried I have notifications independently sent. I just always send these notifications with remove_keyboard which seems to work fine in the end.

An ugly way might be to send a message with no real content but the ReplyKeyboardRemove and delete that instantly. Which basically costs two requests (which is bad when your bot gets lots of users). Also I'm not sure if that works as Telegram Clients seem to look onto the last few messages, where they find the ForceReply and display it to the user.

Another experiment might be an edit of the question via editMessageReplyMarkup. Maybe that can remove that ForceReply from the message. If that turns out working that could be included in this library.

Hope it helps :)

EdJoPaTo avatar Aug 29 '20 04:08 EdJoPaTo

editMessageReplyMarkup only allows you to include an Inline Keyboard 👍 The trick I did, following your advice, is quite simple:

    await menuMiddleware.replyToContext(ctx, menuPath)
    const msg = await ctx.reply(`TBR`, Extra.markup({
      remove_keyboard: true
    }));
    await ctx.deleteMessage(msg.message_id);

It seems to be working and the users doesn't notice that much. Let's see if this is stable ;)

jlanza avatar Aug 31 '20 13:08 jlanza

Yeah… sadly editMessageReplyMarkup does not work for us… So we have probably only these two ways of which you used the second one:

  • Send the ReplyKeyboardRemove on messages that do not have any other ReplyMarkup.
  • Send a new message with ReplyKeyboardRemove and delete it instantly.

The first has the benefit of no additional requests which makes that scale way better. The second way works always, even when there is no message without ReplyMarkup involved (like a bot only having an inline menu). But at the cost of two additional requests. I would always prefer the first one when possible.

Maybe that should be documented in the readme…

EdJoPaTo avatar Sep 01 '20 12:09 EdJoPaTo

Hello. I have the same issue with 2 questions in a row. Only second question appears in this case. Can you please provide an example for the first fix you suggested?

I have such code: bot.zip

Thank you for any help. I really can't figure out where the fix must be used and how.

QreKer avatar Nov 09 '20 09:11 QreKer

Have you tried the example code I included? If I recall correctly, you have add an extra question and remove it. This way there is no entry "left" in Telegram poll.

jlanza avatar Nov 09 '20 09:11 jlanza

so I need to add something like:

const clearPoll = newTelegrafStatelessQuestions('clearPoll', async (ctx, additionalState) => { const msg = await ctx.reply(TBR, Extra.markup({ remove_keyboard: true })); await ctx.deleteMessage(msg.message_id); });

and call it like: await clearPoll.replyWithMarkdown(ctx, 'clear', additionalState);

in my second question?

UPD: The solution not solved my problem at all. Only added annoying animation after every action.

QreKer avatar Nov 09 '20 09:11 QreKer

Is there anything that needs to be done here? Otherwise, I'd close this issue.

KnorpelSenf avatar May 01 '22 09:05 KnorpelSenf

I think we cant do anything here to fix it as it would require some other feature of the Telegram API. It might be helpful to leave this open so its easier to find this known issue.

EdJoPaTo avatar May 01 '22 10:05 EdJoPaTo

Reported this bug there: https://bugs.telegram.org/c/25208

LWJerri avatar Feb 17 '23 00:02 LWJerri