Skip to content

Button params: inline or stored ​

Telegram limits callback data to 64 bytes, and modified clients can forge it. buttons.params decides where button params live:

modecallback dataforgeablesize
inlinep|order|id=42yesthrows above 64 bytes
auto (default)inline if it fits, else s|<token>inline onesunlimited
storeds|<token> whenever there are paramsnounlimited
signedp|order|id=42&_s=<signature>noinline 64 bytes (overflow is stored)

A stored button saves { target, params, user } and carries only a 16-character token.

  • The token resolves only for the user the button was rendered for, in owner-only menus (buttons.ownerOnly, default on). Inline-mode messages and menus with allowedUsers aren't bound to one user.
  • Re-rendering the same button reuses its token.
  • In stored mode, incoming inline params are rejected, so p|order|id=999 sent by a modified client does nothing.
  • Pass { store: true } to store the params of a single button.

Signed buttons keep their params inline and add a short HMAC signature, so they can't be forged and nothing is written to storage when you render:

ts
new EasyTG({ buttons: { params: 'signed', secret: process.env.BUTTON_SECRET } }); // ≥ 16 characters

The signature covers the bot, the chat, the target, the params and, for owner-only menus, the user. Deep links are signed too, but without a user or bot, so they can be shared. Keep the secret stable: changing it invalidates the buttons already in chats. Param names starting with _ are reserved.

MIT licensed