Skip to main content
Level: Beginner · Tags: WhatsApp, Telegram, Flows, Buttons Features shown: flow().choose() numbered menus · then sub-flows · c.state · bot.conversation() · buttons per transport · capability matrix

Prerequisites

Node.js 22.12 or newer and a folder with "type": "module" (see Getting started). Then install:

The complete bot

Sample transcript

Captured with npx botmesh dev bot.js. The simulator renders native buttons, so rate shows them; :click 1 taps the first one:

How it works

  • .choose(prompt, options, key) sends a numbered menu and waits. The user answers with the number, the key or the label (“pepperoni”); anything else re-sends the menu. The chosen key lands in c.state[key].
  • then runs when that option is picked: a whole flow (order, which runs inline and comes back) or a function such as (_ctx, c) => c.say(...). flow([]) has no trigger, so it only runs from the menu.
  • Buttons. WhatsApp Web dropped native buttons, so on Baileys ctx.buttons() would arrive as a numbered list the user answers with a number. ctx.capabilities?.buttons tells whether the channel renders them; a tap arrives as a buttons message whose text is the button id, so c.waitAny() takes it (c.waitText() only accepts typed text, and the user could still type instead of tapping). Elsewhere c.choose() asks the same question as a numbered menu.
  • Escape hatch. Add slashCommandsPlugin and /cancel leaves any menu: commands always win over an active conversation.

Run it on WhatsApp or Telegram

node bot.js prints a QR: scan it in WhatsApp → Linked devices (menus are numbered). On Telegram, install @botmesh/telegram and swap the provider as shown in Or connect Telegram: rate then shows an inline keyboard.

Next steps