118 lines
3.1 KiB
Go
118 lines
3.1 KiB
Go
package connectors
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/bwmarrin/discordgo"
|
|
"github.com/mudler/LocalAgent/core/agent"
|
|
"github.com/mudler/LocalAgent/pkg/xlog"
|
|
)
|
|
|
|
type Discord struct {
|
|
token string
|
|
defaultChannel string
|
|
}
|
|
|
|
// NewDiscord creates a new Discord connector
|
|
// with the given configuration
|
|
// - token: Discord token
|
|
// - defaultChannel: Discord channel to always answer even if not mentioned
|
|
func NewDiscord(config map[string]string) *Discord {
|
|
return &Discord{
|
|
token: config["token"],
|
|
defaultChannel: config["defaultChannel"],
|
|
}
|
|
}
|
|
|
|
func (d *Discord) AgentResultCallback() func(state agent.ActionState) {
|
|
return func(state agent.ActionState) {
|
|
// Send the result to the bot
|
|
}
|
|
}
|
|
|
|
func (d *Discord) AgentReasoningCallback() func(state agent.ActionCurrentState) bool {
|
|
return func(state agent.ActionCurrentState) bool {
|
|
// Send the reasoning to the bot
|
|
return true
|
|
}
|
|
}
|
|
|
|
func (d *Discord) Start(a *agent.Agent) {
|
|
|
|
Token := d.token
|
|
// Create a new Discord session using the provided bot token.
|
|
dg, err := discordgo.New(Token)
|
|
if err != nil {
|
|
xlog.Info("error creating Discord session,", err)
|
|
return
|
|
}
|
|
|
|
// Register the messageCreate func as a callback for MessageCreate events.
|
|
dg.AddHandler(d.messageCreate(a))
|
|
|
|
// In this example, we only care about receiving message events.
|
|
dg.Identify.Intents = discordgo.IntentsGuildMessages | discordgo.IntentsDirectMessages | discordgo.IntentMessageContent
|
|
|
|
// Open a websocket connection to Discord and begin listening.
|
|
err = dg.Open()
|
|
if err != nil {
|
|
xlog.Info("error opening connection,", err)
|
|
return
|
|
}
|
|
|
|
go func() {
|
|
xlog.Info("Discord bot is now running. Press CTRL-C to exit.")
|
|
<-a.Context().Done()
|
|
dg.Close()
|
|
xlog.Info("Discord bot is now stopped.")
|
|
}()
|
|
}
|
|
|
|
// This function will be called (due to AddHandler above) every time a new
|
|
// message is created on any channel that the authenticated bot has access to.
|
|
func (d *Discord) messageCreate(a *agent.Agent) func(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|
return func(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|
// Ignore all messages created by the bot itself
|
|
// This isn't required in this specific example but it's a good practice.
|
|
if m.Author.ID == s.State.User.ID {
|
|
return
|
|
}
|
|
interact := func() {
|
|
//m := m.ContentWithMentionsReplaced()
|
|
content := m.Content
|
|
|
|
content = strings.ReplaceAll(content, "<@"+s.State.User.ID+"> ", "")
|
|
xlog.Info("Received message", "content", content)
|
|
job := a.Ask(
|
|
agent.WithText(
|
|
content,
|
|
),
|
|
)
|
|
if job.Error != nil {
|
|
xlog.Info("error asking agent,", job.Error)
|
|
return
|
|
}
|
|
|
|
xlog.Info("Response", "response", job.Response)
|
|
_, err := s.ChannelMessageSend(m.ChannelID, job.Response)
|
|
if err != nil {
|
|
xlog.Info("error sending message,", err)
|
|
}
|
|
}
|
|
|
|
// Interact if we are mentioned
|
|
for _, mention := range m.Mentions {
|
|
if mention.ID == s.State.User.ID {
|
|
go interact()
|
|
return
|
|
}
|
|
}
|
|
|
|
// Or we are in the default channel (if one is set!)
|
|
if d.defaultChannel != "" && m.ChannelID == d.defaultChannel {
|
|
go interact()
|
|
return
|
|
}
|
|
}
|
|
}
|