- 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.
84 lines
1.7 KiB
Go
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})
|
|
}
|