Closed jlanza closed 4 years ago
I'm not sure if I understand what you are trying to achieve. You want to access submenu entries either via menu or from the question answer?
Also I'm not sure where this TypeError occurs. Can you give me the call stack where this happens?
Better than the TypeError, I provide you with almost a MWE.
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('referral', async (ctx) => {
const shopRegex = new RegExp('(/submenu/items:(.*))/default$');
const res = ctx.message.reply_to_message.entities![0].url!.match(shopRegex);
const menuPath = res![1];
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);
export const menuMiddleware = new MenuMiddleware<TelegrafContext>('/', menu);
The menu structure should be something like /submenu/items:(.*)/default
The idea is that when I click on /submenu/items:item1
I will get a button with the text Default
. Clicking on this button I will be asked to enter some data which will be retrieved using the statelessQuestion
. Using the trick with the "hided link", the path could be extracted from the response. within the statelessQuestion
callback.
What I want is to get back to/display /submenu/items:item1
after answering the question.
Here is what happens. If I replace WHAT_DO_IH_AVE_TO_PUT_HERE
by subMenu
the code runs flawlessly but I get back to /submenu
. If I replace it by menuTemplate
I get an exception.
Is there any way to return to a submenu generated using chooseIntoSubmenu
? Otherwise I would have to create the menus "manually" per item in stead of using this functionality.
Awesome, now I understand what you are trying to do.
The menuPath you are using afterwards with replyMenuToContext
does not end with a '/'.
A basic assumption this library does is "a menu ends with /, a button does not".
When you include that final slash, the correct menu is opened.
Send Menu Functions like replyMenuToContext
should complain when the path isnt ending with '/' so other people will not fall for the same mistake.
Your exception then results from the ctx.match which doesnt have the entry for the submenu. ~Thats something this library should do, but sadly I dont have the time for that currently.~
Edit: which is not possible from within the library as the menu given has no clue about their parent menues. But you can use menuMiddleware.replyToContext(context, path)
which is filling ctx.match
correctly.
As you are familiar with RegExp and the path, you can also do it outside of the library in your code.
Awesome, now I understand what you are trying to do.
Glad you like ;) I will be uploading the bot to github in the next few days. I would like to solve the other issue I just referenced here. I have to thank you as the library helps quite a lot.
Edit: which is not possible from within the library as the menu given has no clue about their parent menues. But you can use menuMiddleware.replyToContext(context, path) which is filling ctx.match correctly.
Great... This works. Using directly replyToContext as you initially said, didn't work.
Great... This works. Using directly replyToContext as you initially said, didn't work.
When changing the regex group so it includes the last / it should work: const shopRegex = new RegExp('(/submenu/items:(.*))/default$');
It should result in the Error again, which is the attempt of accessing [1] from ctx.match which doesnt exist (sadly) (here: Menu Template for ${ctx.match![1]}
)
When I said "Great" I had already added the '/' to the group ;) Thanks a lot.
I'll just close this due to inactivity. If you have any questions feel free to ask ahead!
I want to use
replyMenuToContext
to return to a menu generated when clicking on an option of a choice tochooseIntoSubmenu
.Currently this is not working and it is only possible to return to the full list of options.
This one is returning:
However if I put
await replyMenuToContext(subMenu, ctx, '/configure/items:item1);
it works but returns to the list of options.Is there any way you can achieve that or the only way I have is to manually create all the menus? I can do that by running a foreach on all the items in the array and generating a real menu for each one, but I'd rather prefer the
chooseIntoSubmenu
.