Inline & reply keyboards
Two button systems live side by side. Inline keyboards attach to a specific message and survive edits. Reply keyboards replace the user's regular keyboard with a panel of quick replies.
Two kinds of keyboards
Inline keyboards are buttons under a message. They produce callback queries, open URLs, launch Web Apps, request logins, or trigger payment flows. They persist with the message; editing the message can change the buttons.
Reply keyboards replace the user's on-screen text keyboard with a panel of buttons. They do not produce callback queries — tapping a button sends its label as a regular text message. Once shown, they stay until you replace or remove them.
Inline keyboards
kbd := telegram.NewKeyboard().
Row(
telegram.Button.Data("Yes", "y"),
telegram.Button.Data("No", "n"),
).
Row(
telegram.Button.URL("Read more", "https://gogram.dev"),
).
Build()
client.SendMessage(peerID, "Continue?", &telegram.SendOptions{
ReplyMarkup: kbd,
})kbd := telegram.NewKeyboard().
Row(
telegram.Button.Data("Yes", "y"),
telegram.Button.Data("No", "n"),
).
Row(
telegram.Button.URL("Read more", "https://gogram.dev"),
).
Build()
client.SendMessage(peerID, "Continue?", &telegram.SendOptions{
ReplyMarkup: kbd,
})Build with NewKeyboard and chain .Row(...) for each row. .Build() returns a ReplyMarkup ready to pass on SendOptions.
Button types
- Data(text, data)
- Standard callback button. Data ≤ 64 bytes.
- URL(text, url)
- Open the URL on tap.
- WebApp(text, url)
- Open the URL inside a Mini App with the Telegram JS bridge.
- Login(text, url, opts)
- OAuth-style flow that passes a verified Telegram identity to your server.
- Switch(text, query, sameChat)
- Open inline mode in the current or another chat with a pre-filled query.
- Game(text)
- Open a Telegram HTML5 Game.
- Buy(text)
- Trigger the payment flow for a previously-sent invoice.
- CopyText(text, copy)
- Copy a string to the clipboard.
Reply keyboards
kbd := telegram.NewKeyboard().
Row(
telegram.Button.Reply("📊 Stats"),
telegram.Button.Reply("🛠 Settings"),
).
WithOneTime(true).
WithResize(true).
BuildReply()
client.SendMessage(peerID, "Pick one:", &telegram.SendOptions{ReplyMarkup: kbd})kbd := telegram.NewKeyboard().
Row(
telegram.Button.Reply("📊 Stats"),
telegram.Button.Reply("🛠 Settings"),
).
WithOneTime(true).
WithResize(true).
BuildReply()
client.SendMessage(peerID, "Pick one:", &telegram.SendOptions{ReplyMarkup: kbd})Options on the builder: .WithOneTime(true) hides the keyboard after one use, .WithResize(true) shrinks the buttons to fit content, .WithPlaceholder("type here") sets the input placeholder.
Buttons can also request data from the user: a contact card (Button.RequestContact), a location (Button.RequestLocation), a poll (Button.RequestPoll), or a peer (Button.RequestPeer).
ForceReply
Force the user's next message in the chat to start as a reply to this one. Helps guide conversational flows without an explicit Ask wait:
client.SendMessage(peerID, "What is your name?", &telegram.SendOptions{
ReplyMarkup: telegram.NewForceReply(true),
})client.SendMessage(peerID, "What is your name?", &telegram.SendOptions{
ReplyMarkup: telegram.NewForceReply(true),
})Removing a keyboard
client.SendMessage(peerID, "ok", &telegram.SendOptions{
ReplyMarkup: telegram.NewRemoveKeyboard(),
})client.SendMessage(peerID, "ok", &telegram.SendOptions{
ReplyMarkup: telegram.NewRemoveKeyboard(),
})Removes the active reply keyboard. Inline keyboards are removed by editing the message with an empty ReplyMarkup.
