Skip to main content

Handling updates

Updates are how Telegram pushes events to your client: new messages, edits, typing notifications, inline queries, and dozens more. You receive them by setting an UpdateHandler in telegram.Options.

The update dispatcher

tg.NewUpdateDispatcher returns a handler that routes each update type to a callback you register. Pass it as both the dispatcher you register on and the UpdateHandler:

dispatcher := tg.NewUpdateDispatcher()

client := telegram.NewClient(appID, appHash, telegram.Options{
UpdateHandler: dispatcher,
})

dispatcher.OnNewMessage(func(ctx context.Context, e tg.Entities, u *tg.UpdateNewMessage) error {
m, ok := u.Message.(*tg.Message)
if !ok {
return nil
}
fmt.Println("message:", m.Message)
return nil
})

Common handlers:

MethodFires on
OnNewMessageNew message in a private chat or group
OnNewChannelMessageNew message in a channel/supergroup
OnEditMessageA message was edited
OnBotCallbackQueryInline keyboard button pressed (bots)
OnBotInlineQueryInline query to your bot
OnUserTyping / OnChatUserTypingTyping indicators

There are handlers for the full update set — see the tg reference.

The Entities argument

Updates reference users and chats by ID. The tg.Entities value passed to each handler resolves those IDs to full objects that arrived alongside the update:

dispatcher.OnNewMessage(func(ctx context.Context, e tg.Entities, u *tg.UpdateNewMessage) error {
m, ok := u.Message.(*tg.Message)
if !ok {
return nil
}
if peer, ok := m.PeerID.(*tg.PeerUser); ok {
if user, ok := e.Users[peer.UserID]; ok {
fmt.Printf("from %s\n", user.FirstName)
}
}
return nil
})

Filtering your own messages

For userbots, skip outgoing messages or you may echo yourself into a loop:

if !ok || m.Out {
return nil // outgoing, ignore
}

Keeping the client alive

Updates only arrive while the client is connected, so a bot must block inside Run instead of returning immediately. telegram.RunUntilCanceled does exactly that:

return client.Run(ctx, func(ctx context.Context) error {
// ... authenticate, register handlers ...
return telegram.RunUntilCanceled(ctx, client)
})

BotFromEnvironment accepts RunUntilCanceled as its lifecycle function so you don't write this by hand — see the Echo bot tutorial.

Don't miss updates

The plain dispatcher delivers updates as they arrive, but a client that was offline can miss updates, and channel updates need explicit gap handling. For correctness across reconnects, wrap the dispatcher in the update-recovery engine.