Register a handler for a command by passing the /command string as the endpoint:
b.Handle("/start", func(c tele.Context) error { return c.Send("Welcome! Use /help to see available commands.")})b.Handle("/help", func(c tele.Context) error { return c.Send("Here is what I can do...")})
The handler receives a Context that wraps the incoming update. Telebot matches the command text using the regex ^(/\w+)(@(\w+))?(\s|$)(.+)?, so only exact /command prefixes are routed.
In group chats, users can address commands to a specific bot: /command@botname. Telebot handles this automatically — it matches /start and /start@mybot to the same handler, provided the bot username matches b.Me.Username.You do not need to register separate handlers for the @botname variants.
// Handles both "/start" and "/start@mybot" in groupsb.Handle("/start", func(c tele.Context) error { return c.Reply("Hello!")})
Telegram supports deep links via t.me/botname?start=PAYLOAD. When a user follows such a link, the bot receives a /start message with the payload appended.Read the payload via c.Message().Payload:
b.Handle("/start", func(c tele.Context) error { payload := c.Message().Payload if payload == "" { return c.Send("Hello!") } // e.g. payload == "ref_123" from t.me/mybot?start=ref_123 return c.Send("You came from referral: " + payload)})
c.Message().Payload contains everything after the command text and a single space. For /start ref_123, Payload is "ref_123".
Register the command list displayed in Telegram’s UI via b.SetCommands(). Commands are passed as a []tele.Command slice along with optional scope and language parameters.
commands := []tele.Command{ {Text: "start", Description: "Start the bot"}, {Text: "help", Description: "Show help"}, {Text: "settings", Description: "Open settings"},}// Set for all users in all chats (default scope)if err := b.SetCommands(commands); err != nil { log.Fatal(err)}
You can scope commands to specific contexts using tele.CommandScope:
// Admin-only commands visible only in a specific chatadminScope := tele.CommandScope{ Type: tele.CommandScopeChatAdmin, ChatID: -1001234567890,}adminCmds := []tele.Command{ {Text: "ban", Description: "Ban a user"}, {Text: "kick", Description: "Kick a user"},}b.SetCommands(adminCmds, adminScope)
// Get the current command listcmds, err := b.Commands()// Delete commands for the default scopeb.DeleteCommands()// Delete scoped commandsb.DeleteCommands(tele.CommandScope{Type: tele.CommandScopeAllGroupChats})