ConversationMenuRange
A conversational menu range is a two-dimensional array of buttons.
This array is a part of the total two-dimensional array of buttons. This is mostly useful if you want to dynamically generate the structure of the conversational menu on the fly.
Type Parameters
C
C extends Context
Properties
[ops]
[ops]: MaybeDynamicRange<C>[];
Methods
addRange
addRange(...range: MaybeDynamicRange<C>[]);
This method is used internally whenever a new range is added.
add
add(...btns: MenuButton<C>[]);
This method is used internally whenever new buttons are added. Adds the buttons to the current row.
row
row();
Adds a ‘line break’. Call this method to make sure that the next added buttons will be on a new row.
url
Adds a new URL button. Telegram clients will open the provided URL when the button is pressed. Note that they will not notify your bot when that happens, so you cannot react to this button.
text
// Overload 1
text(text: MaybeDynamicString<C>, ...middleware: ConversationMenuMiddleware<C>[]): this;
// Overload 2
text(text: TextAndPayload<C>, ...middleware: ConversationMenuMiddleware<C & { match: string }>[]): this;
// Overload 3
text(text: MaybePayloadString<C>, ...middleware: ConversationMenuMiddleware<C>[]): this;
Adds a new text button. You may pass any number of listeners. They will be called when the button is pressed.
menu.text('Hit me!', ctx => ctx.reply('Ouch!'))
If you pass several listeners, make sure that you understand what middleware is.
You can also use this method to register a button that depends on the current context.
function greetInstruction(ctx: MyConversationContext): string {
const username = ctx.from?.first_name
return `Greet ${username ?? 'me'}!`,
}
const menu = conversation.menu()
.text(greetInstruction, ctx => ctx.reply("I'm too shy."))
// This will send a conversational menu with one text button,
// and the text has the name of the user that the bot is replying to.
await ctx.reply('What shall I do?', { reply_markup: menu })
If you base the text on a variable defined inside the conversation, you can easily create a settings panel with toggle buttons.
// Button will toggle between 'Yes' and 'No' when pressed
let flag = true
menu.text(ctx => flag ? 'Yes' : 'No', async ctx => {
flag = !flag
ctx.menu.update()
})
webApp
webApp(text: MaybeDynamicString<C>, url: string);
Adds a new web app button, confer https://
login
Adds a new login button. This can be used as a replacement for the Telegram Login Widget. You must specify an HTTPS URL used to automatically authorize the user.
switchInline
switchInline(text: MaybeDynamicString<C>, query: string);
Adds a new inline query button. Telegram clients will let the user pick a chat when this button is pressed. This will start an inline query. The selected chat will be prefilled with the name of your bot. You may provide a text that is specified along with it.
Your bot will in turn receive updates for inline queries. You can listen to inline query updates like this:
// Listen for specifc query
bot.inlineQuery('my-query', ctx => { ... })
// Listen for any query
bot.on('inline_query', ctx => { ... })
Technically, it is also possible to wait for an inline query inside the conversation using conversation
. However, updates about inline queries do not contain a chat identifier. Hence, it is typically not possible to handle them inside a conversation, as conversation data is stored per chat by default.
switchInlineCurrent
switchInlineCurrent(text: MaybeDynamicString<C>, query: string);
Adds a new inline query button that acts on the current chat. The selected chat will be prefilled with the name of your bot. You may provide a text that is specified along with it. This will start an inline query.
Your bot will in turn receive updates for inline queries. You can listen to inline query updates like this:
// Listen for specifc query
bot.inlineQuery('my-query', ctx => { ... })
// Listen for any query
bot.on('inline_query', ctx => { ... })
Technically, it is also possible to wait for an inline query inside the conversation using conversation
. However, updates about inline queries do not contain a chat identifier. Hence, it is typically not possible to handle them inside a conversation, as conversation data is stored per chat by default.
switchInlineChosen
switchInlineChosen(text: MaybeDynamicString<C>, query: SwitchInlineQueryChosenChat);
Adds a new inline query button. Telegram clients will let the user pick a chat when this button is pressed. This will start an inline query. The selected chat will be prefilled with the name of your bot. You may provide a text that is specified along with it.
Your bot will in turn receive updates for inline queries. You can listen to inline query updates like this:
bot.on('inline_query', ctx => { ... })
Technically, it is also possible to wait for an inline query inside the conversation using conversation
. However, updates about inline queries do not contain a chat identifier. Hence, it is typically not possible to handle them inside a conversation, as conversation data is stored per chat by default.
copyText
copyText(text: string, copyText: string | CopyTextButton);
Adds a new copy text button. When clicked, the specified text will be copied to the clipboard.
game
game(text: MaybeDynamicString<C>);
Adds a new game query button, confer https://
This type of button must always be the first button in the first row.
pay
pay(text: MaybeDynamicString<C>);
Adds a new payment button, confer https://
This type of button must always be the first button in the first row and can only be used in invoice messages.
submenu
// Overload 1
submenu(
text: MaybeDynamicString<C>,
menu: string | { id: string },
...middleware: ConversationMenuMiddleware<C>[],
): this;
// Overload 2
submenu(
text: TextAndPayload<C>,
menu: string | { id: string },
...middleware: ConversationMenuMiddleware<C & { match: string }>[],
): this;
// Overload 3
submenu(
text: MaybePayloadString<C>,
menu: string | { id: string },
...middleware: ConversationMenuMiddleware<C>[],
): this;
Adds a button that navigates to a given conversational submenu when pressed. You can pass in an instance of another conversational menu, or just the identifier of a conversational menu. This way, you can effectively create a network of conversational menus with navigation between them.
You can also navigate to this submenu manually by calling ctx
, where menu
is the target submenu (or its identifier).
You can call submenu
to add a button that navigates back to the parent menu. For this to work, you must specify the parent
option when creating the conversational menu via conversation
.
back
// Overload 1
back(text: MaybeDynamicString<C>, ...middleware: ConversationMenuMiddleware<C>[]): this;
// Overload 2
back(text: TextAndPayload<C>, ...middleware: ConversationMenuMiddleware<C & { match: string }>[]): this;
// Overload 3
back(text: MaybePayloadString<C>, ...middleware: ConversationMenuMiddleware<C>[]): this;
Adds a text button that performs a navigation to the parent menu via ctx
. For this to work, you must specify the parent
option when creating the conversational menu via conversation
.
dynamic
dynamic(rangeBuilder: (ctx: C, range: ConversationMenuRange<C>) => MaybePromise<MaybeRawRange<C> | void>);
This is a dynamic way to initialize the conversational menu. A typical use case is when you want to create an arbitrary conversational menu, using the data from your database:
const menu = conversation.menu()
const data = await conversation.external(() => fetchDataFromDatabase())
menu.dynamic(ctx => data.reduce((range, entry) => range.text(entry)), new ConversationMenuRange())
await ctx.reply("Menu", { reply_markup: menu })
append
append(range: MaybeRawRange<C>);
Appends a given range to this range. This will effectively replay all operations of the given range onto this range.