yao/integrations/telegram/bot.go
Max ea9e070f29 Enhance robot integration with Telegram and improve event handling
- Add Telegram integration support by introducing a dispatcher for handling Telegram events and messages.
- Implement event notifications for robot configuration changes (creation, update, deletion) to facilitate integration with external services.
- Refactor the robot initialization process to load robots into cache and start the dispatcher, improving the overall system setup.
- Update the delivery event structure to include additional metadata for better context during message handling.
- Enhance logging capabilities for better observability during robot execution and event processing.
2026-03-01 22:03:25 +08:00

83 lines
2.3 KiB
Go

package telegram
import (
"fmt"
"net/http"
"strings"
"time"
"github.com/go-telegram/bot"
)
const defaultAPIBase = "https://api.telegram.org"
// Bot represents a single Telegram bot instance bound to a specific token.
// Each registered robot gets its own Bot. All API methods live on Bot so
// callers never need to pass the token around.
type Bot struct {
token string
secretToken string // for webhook X-Telegram-Bot-Api-Secret-Token verification
apiBase string // e.g. "https://api.telegram.org" or "http://localhost:3001"
httpClient *http.Client
}
// BotOption configures optional Bot parameters.
type BotOption func(*Bot)
// WithAPIBase sets a custom Bot API server URL (e.g. a local telegram-bot-api instance).
func WithAPIBase(url string) BotOption {
return func(b *Bot) {
b.apiBase = strings.TrimRight(url, "/")
}
}
// NewBot creates a Bot bound to the given token.
// secretToken is optional — when set it is sent with SetWebhook and used by
// VerifyWebhook to authenticate incoming requests.
func NewBot(token string, secretToken string, opts ...BotOption) *Bot {
b := &Bot{
token: token,
secretToken: secretToken,
apiBase: defaultAPIBase,
httpClient: &http.Client{Timeout: 90 * time.Second},
}
for _, o := range opts {
o(b)
}
return b
}
// Token returns the raw bot token.
func (b *Bot) Token() string { return b.token }
// SecretToken returns the webhook secret (may be empty).
func (b *Bot) SecretToken() string { return b.secretToken }
// APIBase returns the API server base URL.
func (b *Bot) APIBase() string { return b.apiBase }
// botURL builds the bot-method base URL: {apiBase}/bot{token}
func (b *Bot) botURL() string {
return b.apiBase + "/bot" + b.token
}
// fileURL builds the file download URL: {apiBase}/file/bot{token}/{path}
func (b *Bot) fileURL(filePath string) string {
return b.apiBase + "/file/bot" + b.token + "/" + filePath
}
// sdk returns a go-telegram/bot.Bot instance for typed method calls.
func (b *Bot) sdk() (*bot.Bot, error) {
opts := []bot.Option{
bot.WithSkipGetMe(),
bot.WithHTTPClient(90*time.Second, b.httpClient),
}
if b.apiBase != defaultAPIBase {
opts = append(opts, bot.WithServerURL(b.apiBase))
}
sdkBot, err := bot.New(b.token, opts...)
if err != nil {
return nil, fmt.Errorf("create bot sdk: %w", err)
}
return sdkBot, nil
}