mirror of https://github.com/velour/catbase.git
148 lines
3.1 KiB
Go
148 lines
3.1 KiB
Go
package discord
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/velour/catbase/bot/msg"
|
|
|
|
"github.com/bwmarrin/discordgo"
|
|
"github.com/rs/zerolog/log"
|
|
"github.com/velour/catbase/bot"
|
|
"github.com/velour/catbase/bot/user"
|
|
"github.com/velour/catbase/config"
|
|
)
|
|
|
|
type Discord struct {
|
|
config *config.Config
|
|
client *discordgo.Session
|
|
|
|
event bot.Callback
|
|
|
|
emojiCache map[string]string
|
|
}
|
|
|
|
func New(config *config.Config) *Discord {
|
|
client, err := discordgo.New("Bot " + config.Get("DISCORDBOTTOKEN", ""))
|
|
if err != nil {
|
|
log.Fatal().Err(err).Msg("Could not connect to Discord")
|
|
}
|
|
d := &Discord{
|
|
config: config,
|
|
client: client,
|
|
}
|
|
return d
|
|
}
|
|
|
|
func (d *Discord) RegisterEvent(callback bot.Callback) {
|
|
d.event = callback
|
|
}
|
|
|
|
func (d Discord) Send(kind bot.Kind, args ...interface{}) (string, error) {
|
|
|
|
switch kind {
|
|
case bot.Message:
|
|
st, err := d.client.ChannelMessageSend(args[0].(string), args[1].(string))
|
|
return st.ID, err
|
|
default:
|
|
log.Error().Msgf("discord.Send: unknown kind, %+v", kind)
|
|
return "", errors.New("unknown message type")
|
|
}
|
|
}
|
|
|
|
func (d *Discord) GetEmojiList() map[string]string {
|
|
if d.emojiCache != nil {
|
|
return d.emojiCache
|
|
}
|
|
guidID := d.config.Get("discord.guildid", "")
|
|
if guidID == "" {
|
|
}
|
|
e, err := d.client.GuildEmojis(guidID)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("could not retrieve emojis")
|
|
return map[string]string{}
|
|
}
|
|
emojis := map[string]string{}
|
|
for _, e := range e {
|
|
emojis[e.ID] = e.Name
|
|
}
|
|
return emojis
|
|
}
|
|
|
|
func (d *Discord) Who(id string) []string {
|
|
ch, err := d.client.Channel(id)
|
|
if err != nil {
|
|
log.Error().Err(err).Msgf("Error getting users")
|
|
return []string{}
|
|
}
|
|
users := []string{}
|
|
for _, u := range ch.Recipients {
|
|
users = append(users, u.Username)
|
|
}
|
|
return users
|
|
}
|
|
|
|
func (d *Discord) Profile(id string) (user.User, error) {
|
|
u, err := d.client.User(id)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Error getting user")
|
|
return user.User{}, err
|
|
}
|
|
return *convertUser(u), nil
|
|
}
|
|
|
|
func convertUser(u *discordgo.User) *user.User {
|
|
return &user.User{
|
|
ID: u.ID,
|
|
Name: u.Username,
|
|
Admin: false,
|
|
Icon: u.Avatar,
|
|
}
|
|
}
|
|
|
|
func (d *Discord) Serve() error {
|
|
log.Debug().Msg("starting discord serve function")
|
|
|
|
d.client.Identify.Intents = discordgo.MakeIntent(discordgo.IntentsGuilds |
|
|
discordgo.IntentsGuildMessages)
|
|
|
|
err := d.client.Open()
|
|
if err != nil {
|
|
log.Debug().Err(err).Msg("error opening client")
|
|
return err
|
|
}
|
|
|
|
log.Debug().Msg("discord connection open")
|
|
|
|
d.client.AddHandler(d.messageCreate)
|
|
|
|
sc := make(chan os.Signal, 1)
|
|
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
|
|
<-sc
|
|
|
|
log.Debug().Msg("closing discord connection")
|
|
|
|
// Cleanly close down the Discord session.
|
|
return d.client.Close()
|
|
}
|
|
|
|
func (d *Discord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|
log.Debug().Msgf("discord message: %+v", m)
|
|
if m.Author.ID == s.State.User.ID {
|
|
return
|
|
}
|
|
|
|
msg := msg.Message{
|
|
User: convertUser(m.Author),
|
|
Channel: m.ChannelID,
|
|
ChannelName: m.ChannelID,
|
|
Body: m.Content,
|
|
Time: time.Now(),
|
|
}
|
|
|
|
d.event(d, bot.Message, msg)
|
|
}
|