stateless-question
stateless-question copied to clipboard
[BUG] Always asking the question when entering the chat
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));
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 :)
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 ;)
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
ReplyKeyboardRemoveon messages that do not have any otherReplyMarkup. - Send a new message with
ReplyKeyboardRemoveand 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…
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.
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.
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.
Is there anything that needs to be done here? Otherwise, I'd close this issue.
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.
Reported this bug there: https://bugs.telegram.org/c/25208