MTGo Command Handler Bot
This example demonstrates a bot with /start, /help, /ping, and /echo commands using MTGo's command filter and context-based handlers.
Full Code
package main
import (
"context"
"fmt"
"log"
"os"
"strings"
"time"
tg "github.com/mtgo-labs/mtgo/telegram"
"github.com/mtgo-labs/mtgo/telegram/types"
)
func main() {
apiID := mustAtoi(mustEnv("API_ID"))
apiHash := mustEnv("API_HASH")
botToken := mustEnv("BOT_TOKEN")
client, err := tg.NewClient(apiID, apiHash, &tg.Config{
BotToken: botToken,
SessionName: "command_bot",
SavePeers: true,
})
if err != nil {
log.Fatalf("new client: %v", err)
}
// /start - welcome message
client.OnMessage(func(c *tg.Client, msg *types.Message) {
msg.Reply("Welcome! I respond to /start, /help, /ping, and /echo <text>.")
}, tg.Command("start"))
// /help - list available commands
client.OnMessage(func(c *tg.Client, msg *types.Message) {
helpText := `Available commands:
/start - Welcome message
/help - Show this help
/ping - Check response time
/echo <text> - Echo your text back`
msg.Reply(helpText)
}, tg.Command("help"))
// /ping - measure response time
client.OnMessage(func(c *tg.Client, msg *types.Message) {
elapsed := time.Since(msg.Date.Time())
msg.Reply(fmt.Sprintf("Pong! Message took %v to arrive.", elapsed))
}, tg.Command("ping"))
// /echo <text> - echo the provided text
client.OnMessage(func(c *tg.Client, msg *types.Message) {
args := msg.Args()
if args == "" {
msg.Reply("Usage: /echo <text>")
return
}
msg.Reply(args)
}, tg.Command("echo"))
// Catch-all: unknown commands
client.OnMessage(func(c *tg.Client, msg *types.Message) {
msg.Reply(fmt.Sprintf("Unknown command: %s\nUse /help to see available commands.", msg.Text))
}, tg.All, tg.StopPropagation)
if err := client.Connect(0); err != nil {
log.Fatalf("connect: %v", err)
}
defer client.Stop()
bot, err := client.GetMe(context.Background())
if err != nil {
log.Fatalf("get me: %v", err)
}
fmt.Printf("Bot @%s is running\n", bot.Username)
client.Idle()
}
func mustEnv(key string) string {
v := os.Getenv(key)
if v == "" {
log.Fatalf("environment variable %s is required", key)
}
return v
}
func mustAtoi(s string) int {
var n int
if _, err := fmt.Sscanf(s, "%d", &n); err != nil {
log.Fatalf("invalid integer %q: %v", s, err)
}
return n
}How It Works
Command Filters
The tg.Command("name") filter matches messages that start with /name:
client.OnMessage(handler, tg.Command("start"))The filter handles variations automatically:
/start— plain command/start@botname— command with bot username/START— case-insensitive
Parsing Arguments
msg.Args() returns everything after the command:
// For "/echo hello world"
msg.Text // "/echo hello world"
msg.Args() // "hello world"For more complex argument parsing, split the args string:
parts := strings.Fields(msg.Args())
// "/echo hello world" → ["hello", "world"]Handler Order and StopPropagation
Handlers are evaluated in registration order. Without StopPropagation, a message matching /start would trigger the /start handler and fall through to subsequent handlers.
// This handler catches everything that wasn't handled above
client.OnMessage(func(c *tg.Client, msg *types.Message) {
msg.Reply("Unknown command.")
}, tg.All, tg.StopPropagation)tg.All— matches all messages (no filter)tg.StopPropagation— stops checking further handlers after this one matches
Since the catch-all is registered last and uses StopPropagation, it only fires for messages not caught by earlier command handlers.
Adding More Commands
To add a new command, register a handler before the catch-all:
// /time - show current time
client.OnMessage(func(c *tg.Client, msg *types.Message) {
msg.Reply(time.Now().Format(time.RFC1123))
}, tg.Command("time"))Group-Only Commands
Restrict commands to group chats:
client.OnMessage(func(c *tg.Client, msg *types.Message) {
msg.Reply("This command only works in groups!")
}, tg.Command("groupinfo"), tg.Group)Combining Filters
Use multiple filters by passing them as additional arguments:
// Only in private chats, only for the /admin command
client.OnMessage(handler, tg.Command("admin"), tg.Private)Running
export API_ID=12345
export API_HASH=your_api_hash
export BOT_TOKEN=your_bot_token
go run main.goTest by sending /start, /help, /ping, and /echo hello world to your bot.
