Documentation
¶
Overview ¶
Package bot provides bot adapters for various IM platforms.
This package implements a unified interface for connecting to multiple chat platforms, including Discord, Telegram, Feishu (Lark), and DingTalk. Each adapter handles platform-specific connection logic, message formatting, and communication patterns.
Supported Platforms ¶
- Discord: WebSocket connection with real-time message handling
- Telegram: Long polling for message updates
- Feishu/Lark: WebSocket long connection for enterprise messaging
- DingTalk: WebSocket long connection for enterprise messaging
Usage ¶
To use a bot adapter:
- Create a bot instance using the New* function for your platform
- Call Start() with a message handler callback
- Send messages using SendMessage()
- Call Stop() when shutting down
Example:
discordBot := bot.NewDiscordBot(token, channelID)
err := discordBot.Start(func(msg bot.BotMessage) {
fmt.Printf("Received: %s\n", msg.Content)
})
if err != nil {
log.Fatal(err)
}
discordBot.SendMessage(channelID, "Hello, world!")
discordBot.Stop()
Thread Safety ¶
All bot adapters are thread-safe and use internal mutexes to protect shared state. The message handler callback may be called concurrently from multiple goroutines.
Index ¶
- Constants
- func DefaultCredentialsPath() string
- type ApiError
- type BotAdapter
- type BotMessage
- type C2CMessageData
- type Credentials
- type DefaultTypingIndicator
- type DingTalkBot
- func (d *DingTalkBot) GetMessageHandler() func(BotMessage)
- func (d *DingTalkBot) SendMessage(conversationID, message string) error
- func (d *DingTalkBot) SetMessageHandler(handler func(BotMessage))
- func (d *DingTalkBot) SetProxyManager(mgr proxy.Manager)
- func (d *DingTalkBot) Start(messageHandler func(BotMessage)) error
- func (d *DingTalkBot) Stop() error
- type DiscordBot
- func (d *DiscordBot) GetMessageHandler() func(BotMessage)
- func (d *DiscordBot) SendMessage(channel, message string) error
- func (d *DiscordBot) SetMessageHandler(handler func(BotMessage))
- func (d *DiscordBot) SetProxyManager(mgr proxy.Manager)
- func (d *DiscordBot) Start(messageHandler func(BotMessage)) error
- func (d *DiscordBot) Stop() error
- type DiscordMessage
- type DiscordSessionInterface
- type FeishuBot
- func (f *FeishuBot) AddTypingIndicator(messageID string) bool
- func (f *FeishuBot) GetMessageHandler() func(BotMessage)
- func (f *FeishuBot) RemoveTypingIndicator(messageID string) error
- func (f *FeishuBot) SendMessage(chatID, message string) error
- func (f *FeishuBot) SetEncryptKey(key string)
- func (f *FeishuBot) SetMessageHandler(handler func(BotMessage))
- func (f *FeishuBot) SetProxyManager(mgr proxy.Manager)
- func (f *FeishuBot) SetVerificationToken(token string)
- func (f *FeishuBot) Start(messageHandler func(BotMessage)) error
- func (f *FeishuBot) Stop() error
- func (f *FeishuBot) SupportsTypingIndicator() bool
- type GatewayPayload
- type HelloData
- type IdentifyData
- type QQBot
- func (q *QQBot) AddTypingIndicator(messageID string) bool
- func (q *QQBot) GetMessageHandler() func(BotMessage)
- func (q *QQBot) RemoveTypingIndicator(messageID string) error
- func (q *QQBot) SendMessage(channel, message string) error
- func (q *QQBot) SetMessageHandler(handler func(BotMessage))
- func (q *QQBot) SetProxyManager(mgr proxy.Manager)
- func (q *QQBot) Start(messageHandler func(BotMessage)) error
- func (q *QQBot) Stop() error
- func (q *QQBot) SupportsTypingIndicator() bool
- type QQGatewayResponse
- type QQTokenResponse
- type SendMessageRequest
- type SendMessageResponse
- type TelegramBot
- func (t *TelegramBot) GetMessageHandler() func(BotMessage)
- func (t *TelegramBot) SendMessage(chatID, message string) error
- func (t *TelegramBot) SetMessageHandler(handler func(BotMessage))
- func (t *TelegramBot) SetProxyManager(mgr proxy.Manager)
- func (t *TelegramBot) Start(messageHandler func(BotMessage)) error
- func (t *TelegramBot) Stop() error
- type TextContent
- type WeixinBot
- func (b *WeixinBot) AddTypingIndicator(messageID string) bool
- func (b *WeixinBot) RemoveTypingIndicator(messageID string) error
- func (b *WeixinBot) SendMessage(channel, message string) error
- func (b *WeixinBot) SetProxyManager(mgr proxy.Manager)
- func (b *WeixinBot) Start(messageHandler func(BotMessage)) error
- func (b *WeixinBot) Stop() error
Constants ¶
const ( QQTokenURL = "https://bots.qq.com/app/getAppAccessToken" QQAPIBase = "https://api.sgroup.qq.com" QQGatewayURL = QQAPIBase + "/gateway" )
QQ Bot API endpoints
const ( OPDispatch = 0 // Event dispatch OPHeartbeat = 1 // Heartbeat OPIdentify = 2 // Identify OPResume = 6 // Resume OPReconnect = 7 // Reconnect request OPInvalidSession = 9 // Invalid session OPHello = 10 // Hello OPHeartbeatAck = 11 // Heartbeat acknowledgement )
WebSocket OP codes (https://bots.qq.com/docs/gateway/gateway-events)
const ( MessageTypeUser = 1 MessageTypeBot = 2 )
const ( MessageStateNew = 0 MessageStateGenerating = 1 MessageStateFinish = 2 )
const ( MessageItemTypeText = 1 MessageItemTypeImage = 2 MessageItemTypeVoice = 3 MessageItemTypeFile = 4 MessageItemTypeVideo = 5 )
const ( QRStatusWait = "wait" QRStatusScaned = "scaned" QRStatusConfirmed = "confirmed" QRStatusExpired = "expired" )
const ( DefaultBaseURL = "https://ilinkai.weixin.qq.com" DefaultBaseVersion = "1.0.0" QRCodePollInterval = 2 * time.Second APITimeout = 15 * time.Second MaxMessageLength = 2000 MaxChunkLength = 2000 SessionExpiredErrCode = -14 )
const (
IntentPublicMessages = 1 << 25 // Public message events (1 << 25)
)
Intents for subscribing to events
Variables ¶
This section is empty.
Functions ¶
func DefaultCredentialsPath ¶ added in v0.1.2
func DefaultCredentialsPath() string
Types ¶
type ApiError ¶ added in v0.1.2
func (*ApiError) IsSessionExpired ¶ added in v0.1.2
type BotAdapter ¶
type BotAdapter interface {
// Start starts the bot, establishes connection and begins listening for messages
Start(messageHandler func(BotMessage)) error
// SendMessage sends a message to the IM platform
// Adapter is responsible for:
// - Truncating to platform limits
// - Splitting long messages when necessary
// - Platform-specific formatting
SendMessage(channel, message string) error
// SupportsTypingIndicator returns true if the platform supports typing indicators
SupportsTypingIndicator() bool
// AddTypingIndicator adds a typing indicator to a message (if supported)
// messageID is the ID of the user's message to react to
// Returns true if successfully added
AddTypingIndicator(messageID string) bool
// RemoveTypingIndicator removes the typing indicator from a message
RemoveTypingIndicator(messageID string) error
// SetProxyManager sets the proxy manager for the bot
SetProxyManager(mgr proxy.Manager)
// Stop stops the bot and cleans up resources
Stop() error
}
BotAdapter defines the interface for bot adapters
type BotMessage ¶
type BotMessage struct {
Platform string // feishu/discord/telegram
UserID string // Unique user identifier (for permission control)
Channel string // Channel/session ID
MessageID string // Message ID (for typing indicator)
Content string // Message content
Timestamp time.Time
}
BotMessage represents a bot message structure
type C2CMessageData ¶
type C2CMessageData struct {
ID string `json:"id"`
Timestamp string `json:"timestamp"`
Author struct {
UserOpenID string `json:"user_openid"`
} `json:"author"`
Content string `json:"content"`
}
C2CMessageData represents C2C (private chat) message data from WebSocket event
type Credentials ¶ added in v0.1.2
type DefaultTypingIndicator ¶
type DefaultTypingIndicator struct{}
DefaultTypingIndicator provides default empty implementations for typing indicator methods This can be embedded in bot adapters that don't support typing indicators
func (*DefaultTypingIndicator) AddTypingIndicator ¶
func (d *DefaultTypingIndicator) AddTypingIndicator(messageID string) bool
AddTypingIndicator does nothing (not supported by default)
func (*DefaultTypingIndicator) RemoveTypingIndicator ¶
func (d *DefaultTypingIndicator) RemoveTypingIndicator(messageID string) error
RemoveTypingIndicator does nothing (not supported by default)
func (*DefaultTypingIndicator) SupportsTypingIndicator ¶
func (d *DefaultTypingIndicator) SupportsTypingIndicator() bool
SupportsTypingIndicator returns false (not supported by default)
type DingTalkBot ¶
type DingTalkBot struct {
DefaultTypingIndicator
// contains filtered or unexported fields
}
DingTalkBot implements BotAdapter interface for DingTalk using WebSocket long connection
func NewDingTalkBot ¶
func NewDingTalkBot(clientID, clientSecret string) *DingTalkBot
NewDingTalkBot creates a new DingTalk bot instance
func (*DingTalkBot) GetMessageHandler ¶
func (d *DingTalkBot) GetMessageHandler() func(BotMessage)
GetMessageHandler gets the message handler in a thread-safe manner
func (*DingTalkBot) SendMessage ¶
func (d *DingTalkBot) SendMessage(conversationID, message string) error
SendMessage sends a message to a DingTalk conversation
func (*DingTalkBot) SetMessageHandler ¶
func (d *DingTalkBot) SetMessageHandler(handler func(BotMessage))
SetMessageHandler sets the message handler in a thread-safe manner
func (*DingTalkBot) SetProxyManager ¶
func (d *DingTalkBot) SetProxyManager(mgr proxy.Manager)
SetProxyManager sets the proxy manager for the DingTalk bot
func (*DingTalkBot) Start ¶
func (d *DingTalkBot) Start(messageHandler func(BotMessage)) error
Start establishes WebSocket long connection to DingTalk and begins listening for messages
func (*DingTalkBot) Stop ¶
func (d *DingTalkBot) Stop() error
Stop closes the DingTalk WebSocket connection and cleans up resources
type DiscordBot ¶
type DiscordBot struct {
DefaultTypingIndicator
// contains filtered or unexported fields
}
DiscordBot implements BotAdapter interface for Discord
func NewDiscordBot ¶
func NewDiscordBot(token, channelID string) *DiscordBot
NewDiscordBot creates a new Discord bot instance
func (*DiscordBot) GetMessageHandler ¶
func (d *DiscordBot) GetMessageHandler() func(BotMessage)
GetMessageHandler gets the message handler in a thread-safe manner
func (*DiscordBot) SendMessage ¶
func (d *DiscordBot) SendMessage(channel, message string) error
SendMessage sends a message to a Discord channel
func (*DiscordBot) SetMessageHandler ¶
func (d *DiscordBot) SetMessageHandler(handler func(BotMessage))
SetMessageHandler sets the message handler in a thread-safe manner
func (*DiscordBot) SetProxyManager ¶
func (d *DiscordBot) SetProxyManager(mgr proxy.Manager)
SetProxyManager sets the proxy manager for the Discord bot
func (*DiscordBot) Start ¶
func (d *DiscordBot) Start(messageHandler func(BotMessage)) error
Start establishes connection to Discord and begins listening for messages
func (*DiscordBot) Stop ¶
func (d *DiscordBot) Stop() error
Stop closes the Discord connection and cleans up resources
type DiscordMessage ¶
type DiscordMessage interface {
ID() string
}
DiscordMessage represents a Discord message for our interface
type DiscordSessionInterface ¶
type DiscordSessionInterface interface {
AddHandler(handler interface{}) func()
Open() error
Close() error
ChannelMessageSend(channelID string, content string, options ...discordgo.RequestOption) (*discordgo.Message, error)
}
DiscordSessionInterface defines the interface we need from discordgo.Session This allows us to mock it in tests without depending on concrete types
type FeishuBot ¶
type FeishuBot struct {
// contains filtered or unexported fields
}
FeishuBot implements BotAdapter interface for Feishu (Lark) using WebSocket long connection
func NewFeishuBot ¶
NewFeishuBot creates a new Feishu bot instance
func (*FeishuBot) AddTypingIndicator ¶
AddTypingIndicator adds a typing reaction to a message
func (*FeishuBot) GetMessageHandler ¶
func (f *FeishuBot) GetMessageHandler() func(BotMessage)
GetMessageHandler gets the message handler in a thread-safe manner
func (*FeishuBot) RemoveTypingIndicator ¶
RemoveTypingIndicator removes the typing reaction from a message
func (*FeishuBot) SendMessage ¶
SendMessage sends a message to a Feishu chat
func (*FeishuBot) SetEncryptKey ¶
SetEncryptKey sets the encryption key for event verification
func (*FeishuBot) SetMessageHandler ¶
func (f *FeishuBot) SetMessageHandler(handler func(BotMessage))
SetMessageHandler sets the message handler in a thread-safe manner
func (*FeishuBot) SetProxyManager ¶
SetProxyManager sets the proxy manager for the Feishu bot
func (*FeishuBot) SetVerificationToken ¶
SetVerificationToken sets the verification token for event verification
func (*FeishuBot) Start ¶
func (f *FeishuBot) Start(messageHandler func(BotMessage)) error
Start establishes WebSocket long connection to Feishu and begins listening for messages
func (*FeishuBot) SupportsTypingIndicator ¶
SupportsTypingIndicator returns true as Feishu supports message reactions
type GatewayPayload ¶
type GatewayPayload struct {
OP int `json:"op"`
D interface{} `json:"d,omitempty"`
S *int `json:"s,omitempty"`
T string `json:"t,omitempty"`
}
GatewayPayload represents a WebSocket gateway message
type HelloData ¶
type HelloData struct {
HeartbeatInterval int `json:"heartbeat_interval"`
}
HelloData contains heartbeat_interval from OP Hello
type IdentifyData ¶
type IdentifyData struct {
Token string `json:"token"`
Intents int `json:"intents"`
Shard []int `json:"shard"`
}
IdentifyData contains identify payload
type QQBot ¶
type QQBot struct {
DefaultTypingIndicator
// contains filtered or unexported fields
}
QQBot implements BotAdapter interface for QQ Bot Platform (QQ群机器人开放平台) Official API: https://bots.qq.com
func (*QQBot) AddTypingIndicator ¶
AddTypingIndicator does nothing (not supported)
func (*QQBot) GetMessageHandler ¶
func (q *QQBot) GetMessageHandler() func(BotMessage)
GetMessageHandler gets the message handler in a thread-safe manner
func (*QQBot) RemoveTypingIndicator ¶
RemoveTypingIndicator does nothing (not supported)
func (*QQBot) SendMessage ¶
SendMessage sends a message to QQ (C2C private message)
func (*QQBot) SetMessageHandler ¶
func (q *QQBot) SetMessageHandler(handler func(BotMessage))
SetMessageHandler sets the message handler in a thread-safe manner
func (*QQBot) SetProxyManager ¶
SetProxyManager sets the proxy manager for the QQ bot
func (*QQBot) Start ¶
func (q *QQBot) Start(messageHandler func(BotMessage)) error
Start establishes connection to QQ gateway and begins listening for messages
func (*QQBot) SupportsTypingIndicator ¶
SupportsTypingIndicator returns false (QQ doesn't support typing indicators)
type QQGatewayResponse ¶
type QQGatewayResponse struct {
URL string `json:"url"`
}
QQGatewayResponse represents the gateway URL response
type QQTokenResponse ¶
type QQTokenResponse struct {
AccessToken string `json:"access_token"`
ExpiresIn string `json:"expires_in"` // API returns as string
}
QQTokenResponse represents the token response from QQ API
type SendMessageRequest ¶
type SendMessageRequest struct {
Content string `json:"content"`
MsgType int `json:"msg_type"`
MsgID string `json:"msg_id,omitempty"`
MsgSeq int `json:"msg_seq,omitempty"`
}
SendMessageRequest represents the request payload for sending messages
type SendMessageResponse ¶
type SendMessageResponse struct {
ID string `json:"id"`
}
SendMessageResponse represents the response from sending a message
type TelegramBot ¶
type TelegramBot struct {
DefaultTypingIndicator
// contains filtered or unexported fields
}
TelegramBot implements BotAdapter interface for Telegram using long polling
func NewTelegramBot ¶
func NewTelegramBot(token string) *TelegramBot
NewTelegramBot creates a new Telegram bot instance
func (*TelegramBot) GetMessageHandler ¶
func (t *TelegramBot) GetMessageHandler() func(BotMessage)
GetMessageHandler gets the message handler in a thread-safe manner
func (*TelegramBot) SendMessage ¶
func (t *TelegramBot) SendMessage(chatID, message string) error
SendMessage sends a message to a Telegram chat
func (*TelegramBot) SetMessageHandler ¶
func (t *TelegramBot) SetMessageHandler(handler func(BotMessage))
SetMessageHandler sets the message handler in a thread-safe manner
func (*TelegramBot) SetProxyManager ¶
func (t *TelegramBot) SetProxyManager(mgr proxy.Manager)
SetProxyManager sets the proxy manager for the Telegram bot
func (*TelegramBot) Start ¶
func (t *TelegramBot) Start(messageHandler func(BotMessage)) error
Start establishes long polling connection to Telegram and begins listening for messages
func (*TelegramBot) Stop ¶
func (t *TelegramBot) Stop() error
Stop closes the Telegram long polling connection and cleans up resources
type TextContent ¶
type TextContent struct {
Text string `json:"text"`
}
TextContent represents the JSON structure of Feishu text message content
type WeixinBot ¶ added in v0.1.2
type WeixinBot struct {
DefaultTypingIndicator
// contains filtered or unexported fields
}
func NewWeixinBot ¶ added in v0.1.2
func (*WeixinBot) AddTypingIndicator ¶ added in v0.1.2
func (*WeixinBot) RemoveTypingIndicator ¶ added in v0.1.2
func (*WeixinBot) SendMessage ¶ added in v0.1.2
func (*WeixinBot) SetProxyManager ¶ added in v0.1.2
func (*WeixinBot) Start ¶ added in v0.1.2
func (b *WeixinBot) Start(messageHandler func(BotMessage)) error