Skip to content

Commit ac99d25

Browse files
ernadoclaude
andcommitted
docs(examples): add inline and buttons examples
inline demonstrates AnswerInlineQuery with article results; buttons demonstrates inline keyboards, callback queries (AnswerCallback) and editing the message in response. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent b9df976 commit ac99d25

2 files changed

Lines changed: 166 additions & 0 deletions

File tree

examples/buttons/main.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Command buttons is a bot built on github.com/gotd/botapi that demonstrates
2+
// inline keyboards and callback queries: /menu shows a keyboard, and tapping a
3+
// button answers the callback and edits the message.
4+
//
5+
// Run it with an MTProto app identity (https://my.telegram.org) and a BotFather
6+
// token:
7+
//
8+
// APP_ID=12345 APP_HASH=abcdef BOT_TOKEN=123:abc go run ./examples/buttons
9+
package main
10+
11+
import (
12+
"context"
13+
"os"
14+
"os/signal"
15+
"strconv"
16+
"time"
17+
18+
"go.uber.org/zap"
19+
20+
"github.com/gotd/botapi"
21+
)
22+
23+
func menu() *botapi.InlineKeyboardMarkup {
24+
return &botapi.InlineKeyboardMarkup{
25+
InlineKeyboard: [][]botapi.InlineKeyboardButton{
26+
{
27+
{Text: "👍 Like", CallbackData: "vote:up"},
28+
{Text: "👎 Dislike", CallbackData: "vote:down"},
29+
},
30+
{
31+
{Text: "gotd/td", URL: "https://github.com/gotd/td"},
32+
},
33+
},
34+
}
35+
}
36+
37+
func main() {
38+
log, _ := zap.NewDevelopment()
39+
defer func() { _ = log.Sync() }()
40+
41+
appID, err := strconv.Atoi(os.Getenv("APP_ID"))
42+
if err != nil {
43+
log.Fatal("APP_ID must be a number (see https://my.telegram.org)", zap.Error(err))
44+
}
45+
46+
bot, err := botapi.New(os.Getenv("BOT_TOKEN"), botapi.Options{
47+
AppID: appID,
48+
AppHash: os.Getenv("APP_HASH"),
49+
Logger: log,
50+
})
51+
if err != nil {
52+
log.Fatal("Create bot", zap.Error(err))
53+
}
54+
55+
bot.Use(botapi.Recover(), botapi.Timeout(30*time.Second))
56+
57+
bot.OnCommand("menu", func(c *botapi.Context) error {
58+
_, err := c.Reply("How do you like this bot?", botapi.WithReplyMarkup(menu()))
59+
return err
60+
})
61+
62+
// Respond to the inline-keyboard taps. The CallbackPrefix predicate filters
63+
// to our "vote:" buttons.
64+
bot.OnCallbackQuery(func(c *botapi.Context) error {
65+
choice := "🤷"
66+
switch c.Update.CallbackQuery.Data {
67+
case "vote:up":
68+
choice = "👍"
69+
case "vote:down":
70+
choice = "👎"
71+
}
72+
// Acknowledge the tap (removes the client-side loading state).
73+
if err := c.AnswerCallback(botapi.WithCallbackText("Thanks for voting " + choice)); err != nil {
74+
return err
75+
}
76+
// Edit the original message to reflect the choice.
77+
msg := c.Update.CallbackQuery.Message
78+
if msg == nil {
79+
return nil
80+
}
81+
_, err := c.Bot.EditMessageText(c, botapi.ID(msg.Chat.ID), msg.MessageID, "You voted "+choice)
82+
return err
83+
}, botapi.CallbackPrefix("vote:"))
84+
85+
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
86+
defer cancel()
87+
88+
log.Info("Starting buttons bot")
89+
if err := bot.Run(ctx); err != nil {
90+
log.Fatal("Run", zap.Error(err))
91+
}
92+
}

examples/inline/main.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Command inline is an inline bot built on github.com/gotd/botapi. Type the
2+
// bot's @username followed by a query in any chat and it offers article results
3+
// echoing the query; picking one sends the text.
4+
//
5+
// Run it with an MTProto app identity (https://my.telegram.org) and a BotFather
6+
// token (inline mode must be enabled for the bot via @BotFather):
7+
//
8+
// APP_ID=12345 APP_HASH=abcdef BOT_TOKEN=123:abc go run ./examples/inline
9+
package main
10+
11+
import (
12+
"context"
13+
"os"
14+
"os/signal"
15+
"strconv"
16+
"strings"
17+
18+
"go.uber.org/zap"
19+
20+
"github.com/gotd/botapi"
21+
)
22+
23+
func main() {
24+
log, _ := zap.NewDevelopment()
25+
defer func() { _ = log.Sync() }()
26+
27+
appID, err := strconv.Atoi(os.Getenv("APP_ID"))
28+
if err != nil {
29+
log.Fatal("APP_ID must be a number (see https://my.telegram.org)", zap.Error(err))
30+
}
31+
32+
bot, err := botapi.New(os.Getenv("BOT_TOKEN"), botapi.Options{
33+
AppID: appID,
34+
AppHash: os.Getenv("APP_HASH"),
35+
Logger: log,
36+
})
37+
if err != nil {
38+
log.Fatal("Create bot", zap.Error(err))
39+
}
40+
41+
bot.OnInlineQuery(func(c *botapi.Context) error {
42+
q := strings.TrimSpace(c.Update.InlineQuery.Query)
43+
if q == "" {
44+
return c.AnswerInline(nil)
45+
}
46+
results := []botapi.InlineQueryResult{
47+
&botapi.InlineQueryResultArticle{
48+
ID: "upper",
49+
Title: "UPPERCASE",
50+
Description: strings.ToUpper(q),
51+
InputMessageContent: &botapi.InputTextMessageContent{
52+
MessageText: strings.ToUpper(q),
53+
},
54+
},
55+
&botapi.InlineQueryResultArticle{
56+
ID: "echo",
57+
Title: "Echo",
58+
Description: q,
59+
InputMessageContent: &botapi.InputTextMessageContent{
60+
MessageText: q,
61+
},
62+
},
63+
}
64+
return c.AnswerInline(results, botapi.WithInlineCacheTime(1))
65+
})
66+
67+
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
68+
defer cancel()
69+
70+
log.Info("Starting inline bot")
71+
if err := bot.Run(ctx); err != nil {
72+
log.Fatal("Run", zap.Error(err))
73+
}
74+
}

0 commit comments

Comments
 (0)