Telegram¶
The Telegram provider uses telebot to connect to the Telegram Bot API.
Installation¶
Configuration¶
import "github.com/plexusone/omnichat/providers/telegram"
p, err := telegram.New(telegram.Config{
Token: "123456789:ABCdefGHIjklMNOpqrsTUVwxyz",
Logger: slog.Default(),
})
Config Options¶
| Field | Type | Required | Description |
|---|---|---|---|
Token |
string |
Yes | Bot token from BotFather |
Logger |
*slog.Logger |
No | Logger instance |
Getting a Bot Token¶
- Open Telegram and search for @BotFather
- Send
/newbotcommand - Follow prompts to name your bot
- Copy the token provided
Usage¶
Basic Setup¶
package main
import (
"context"
"log/slog"
"os"
"github.com/plexusone/omnichat/provider"
"github.com/plexusone/omnichat/providers/telegram"
)
func main() {
logger := slog.Default()
p, err := telegram.New(telegram.Config{
Token: os.Getenv("TELEGRAM_TOKEN"),
Logger: logger,
})
if err != nil {
panic(err)
}
router := provider.NewRouter(logger)
router.Register(p)
router.OnMessage(provider.All(), func(ctx context.Context, msg provider.IncomingMessage) error {
return router.Send(ctx, "telegram", msg.ChatID, provider.OutgoingMessage{
Content: "Hello from Telegram!",
})
})
ctx := context.Background()
router.ConnectAll(ctx)
defer router.DisconnectAll(ctx)
select {}
}
Sending Media¶
// Send a photo
router.Send(ctx, "telegram", chatID, provider.OutgoingMessage{
Content: "Check out this photo!",
Media: []provider.Media{{
Type: provider.MediaTypeImage,
URL: "https://example.com/photo.jpg",
}},
})
// Send a document
router.Send(ctx, "telegram", chatID, provider.OutgoingMessage{
Media: []provider.Media{{
Type: provider.MediaTypeDocument,
Data: fileBytes,
Filename: "report.pdf",
MimeType: "application/pdf",
}},
})
// Send a voice message
router.Send(ctx, "telegram", chatID, provider.OutgoingMessage{
Media: []provider.Media{{
Type: provider.MediaTypeVoice,
Data: audioBytes,
MimeType: "audio/ogg",
}},
})
Reply to Messages¶
router.OnMessage(provider.All(), func(ctx context.Context, msg provider.IncomingMessage) error {
return router.Send(ctx, "telegram", msg.ChatID, provider.OutgoingMessage{
Content: "Replying to your message!",
ReplyTo: msg.ID,
})
})
Message Mapping¶
| Telegram | OmniChat |
|---|---|
| Chat ID | ChatID |
| Message ID | ID |
| From ID | SenderID |
| From FirstName | SenderName |
| Text | Content |
| ReplyToMessage | ReplyTo |
| Photo/Document/Audio | Media |
| Private chat | IsDM = true |
Bot Commands¶
Configure commands via BotFather:
- Send
/setcommandsto @BotFather - Send your bot's commands:
Handle commands in your message handler:
router.OnMessage(provider.All(), func(ctx context.Context, msg provider.IncomingMessage) error {
switch {
case strings.HasPrefix(msg.Content, "/start"):
return router.Send(ctx, "telegram", msg.ChatID, provider.OutgoingMessage{
Content: "Welcome! Send me a message.",
})
case strings.HasPrefix(msg.Content, "/help"):
return router.Send(ctx, "telegram", msg.ChatID, provider.OutgoingMessage{
Content: "Available commands:\n/start - Start\n/help - Help",
})
default:
// Handle regular messages
}
return nil
})
Group Chats¶
The bot can be added to groups:
- Search for your bot in Telegram
- Add to group
- Optionally make it admin for full access
Group messages have IsDM = false:
router.OnMessage(provider.GroupOnly(), func(ctx context.Context, msg provider.IncomingMessage) error {
// Handle group messages
return nil
})
Inline Mode¶
For inline queries, use telebot directly:
// Access underlying telebot instance if needed
// This requires type assertion to access provider internals
Environment Variables¶
Troubleshooting¶
Bot not responding¶
- Verify token is correct
- Check bot privacy mode with
/setprivacy(disable for group messages) - Ensure bot is started (users must send
/startfirst in DMs)
Media upload fails¶
- Check file size limits (photos: 10MB, documents: 50MB)
- Verify MIME type is correct
- Ensure file data is valid
Rate limiting¶
Telegram allows ~30 messages/second. For broadcasts, implement delays:
for _, chatID := range chatIDs {
router.Send(ctx, "telegram", chatID, msg)
time.Sleep(50 * time.Millisecond)
}