toggle's "set" method never executes
See original GitHub issueDescribe the bug For Toogle option, although the menu is rendered, “set” function is never runs.
Versions Did you updated telegraf and telegraf-inline-menu to the latest version?
- Version of telegraf: 4.3.0
- Version of telegraf-inline-menu: 6.2.1
- telegraf-session-redis: 5.1.0
What version of NodeJS (and TypeScript) do you use?
- Version of NodeJS: 14.2.0
- Version of TypeScript: 4.2.4
To Reproduce I have the following code.
const categoriesTemplate = new MenuTemplate(
ctx => 'Select categories'
);
let options = Object.keys(categories);
options.forEach((key:string) => {
categoriesTemplate.toggle(categories[key], key, {
set: async (ctx, checked, path): Promise<string> => {
console.log('SET: ', checked, ctx, path);
/* @ts-ignore */
let SESSION = ctx.session;
if (checked){
SESSION.categories.push(key);
} else {
SESSION.categories.splice(SESSION.categories.indexOf(key),1);
}
console.log('SET - ',SESSION.categories);
return 'unfinished code, since it doesn\'t reach here anyway';
},
isSet: async (ctx: unknown, path) => {
console.log('ISSET: '/*,ctx*/);
/* @ts-ignore */
let SESSION = ctx.session as RedisSessionData;
return SESSION.categories.indexOf(key) > -1;
}
});
});
const MainMenuTemplate = new MenuTemplate(
ctx => 'Main Menu'
);
MainMenuTemplate.submenu('Categories', 'categories', categoriesTemplate);
const MainMenu = new MenuMiddleware('/', MainMenuTemplate);
export default MainMenu;
It takes the keys from a json [Key]=Label, and draws the menu. To this point, it has worked properly. The isSet method is also working as expected. However, the console.log on “set” is never reached, so no matter how many times I press the buttons on telegram, all it does is essentially refresh it.
I tried taking out the async, but nothing works, it simply never runs. I don’t know how the plugin works, so I should mention that I’m using “telegraf-session-redis”, which has not been updated in a long time, so I’m unsure if it could be a case of conflict.
Another project that I have access to uses older versions of Telegraf, the same Redis Plugin and and older version of Inline Menu, and still works.
Expected behavior The “set” method would be executed, which would allow me to interact with the menu.
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (2 by maintainers)
Top GitHub Comments
I found the error. And I guess it’s indeed not a bug. Now that I look at the first post, it’s indeed not there because I thought it wasn’t relevant.
Because I get the options from an API, the template is made after it returns, however, the rest of the menu ends up updated later, so while the options are added properly, the actions don’t seem to target the updated menu.
So the moment that I just made everything static, the “set” worked.
I’m not sure if this could be considered a bug, since, as you said initially, you are supposed to have everything done by the time you export the Main Menu, but it seems I got mislead by the fact that the updates did show, although the interaction did not.
TL;DR
set
does not.Not sure how the paths work in finding if an option exists or not, but I guess those are not updated after exported
Finally I was able to do it. Now that I knew the problem, I had to do a lot of rearrangement on the code.
Because I had the MainMenu and Authentication in different places, I had to turn them into functions to accept the results from the API, and then those would render the Menu as soon as it’s rendered, so basically, on my base bot file:
So it can both “select one and deselects everything else automatically” and “select one and only deselects manually”? That feels confusing for a single method.
Some time ago I had worked with Angular on a personal app, and because there were no extra plugins, I could do everything looking beautiful and finely. This time however, I had been having a lot of small compilations problems with types as I’m using external libraries like Telegraf that I don’t know much about yet, and considering that the code is not working, it doesn’t help in that regard either, so I’m adding
ts-ignore
for tests trying to make it work without thinking too much.I’m a newbie in typescript, although I have used typed languages before, there are some things that I’m still learning, so for the time, I’m just trying not to waste too much time on stuff that may not work, and the fix it properly once it does. I’m only using in cases such as using it as local variables.
I think I found some more relevant information:
https://github.com/EdJoPaTo/telegraf-inline-menu/blob/main/source/menu-template.ts - Line 336
This is where the “set” options are set up.
I have changed my variables as according to your suggestion into random strings: The field is
abc
, the options are[def, ghi, xyz]
, and they are inside the submenu/categorias
.But when I check the regular expression there, it gives me
/abcT:(.+)$/
, so I’m guessing it’s ignoring the submenu? I did try to addcategorias/
just as a test straight there, and I did get the erroractions are not relative. They have to be below the menu (dont contain / or ..)
, but then again, maybe a bug when using inside submenus?I am trying to patch it up locally as testing for something that can work, so if I truly find a bug I can report, but since I only have the JS compiled resource on the node_modules folder, and am trying to understand the ideas, it’s a bit convoluted.
I did notice that
ctx.update.callback_query.data
does return the selected option'/categorias/abcT:xyz'
hence I thought that maybe the regex, which doesn’t look for anything before the select’s name is ignoring it.And about moving it to the main menu, the situation is that the main menu may contain other submenus, besides it already has a link to the company’s website. So to keep it presentable to clients, it’s better presented on its own as a submenu.
I just noticed that you have the
.chooseIntoSubmenu
into Submenu method… Although I would have to find a way to get the categories from the API before the MainMenu is exported… Although I’m guessing this one works with a single option, and returns back to the main menu, right? …