yao/agent/robot/events/integrations/discord/gateway.go
Max 5333302055 Add Discord integration support in robot lifecycle
- Introduce Discord adapter in the robot lifecycle to enable integration with Discord events.
- Update the integration dispatcher to recognize and handle events from Discord.
- Modify the configuration structure to include settings for Discord integration.
- Enhance the integration parsing logic to support Discord configurations.
2026-03-02 07:53:49 +08:00

84 lines
1.7 KiB
Go

package discord
import (
"context"
"time"
"github.com/bwmarrin/discordgo"
dcapi "github.com/yaoapp/yao/integrations/discord"
)
const reconnectDelay = 5 * time.Second
// gatewayLoop starts the Discord WebSocket Gateway for a single bot.
// It automatically reconnects on failure.
func (a *Adapter) gatewayLoop(ctx context.Context, entry *botEntry) {
log.Info("discord gatewayLoop started robot=%s app=%s", entry.robotID, entry.appID)
for {
select {
case <-ctx.Done():
log.Info("discord gatewayLoop stopped robot=%s", entry.robotID)
return
case <-a.stopCh:
return
default:
}
err := a.runGateway(ctx, entry)
if err != nil {
log.Error("discord gateway disconnected robot=%s: %v, reconnecting in %s", entry.robotID, err, reconnectDelay)
}
select {
case <-ctx.Done():
return
case <-a.stopCh:
return
case <-time.After(reconnectDelay):
}
}
}
func (a *Adapter) runGateway(ctx context.Context, entry *botEntry) error {
session := entry.bot.Session()
session.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) {
a.onMessageCreate(ctx, entry, m)
})
if err := session.Open(); err != nil {
return err
}
// Block until context is cancelled or stop signal
select {
case <-ctx.Done():
case <-a.stopCh:
}
return session.Close()
}
func (a *Adapter) onMessageCreate(ctx context.Context, entry *botEntry, m *discordgo.MessageCreate) {
if m == nil || m.Author == nil {
return
}
// Ignore bot's own messages
if m.Author.Bot {
return
}
cm := dcapi.ConvertMessageCreate(m)
if cm == nil {
return
}
if cm.HasMedia() {
groups := []string{"discord", entry.robotID}
dcapi.ResolveMedia(ctx, cm, groups)
}
a.handleMessages(ctx, entry, []*dcapi.ConvertedMessage{cm})
}