Compare commits

...

4 Commits

3 changed files with 51 additions and 26 deletions

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"strconv"
"strings" "strings"
"github.com/velour/catbase/bot/msg" "github.com/velour/catbase/bot/msg"
@ -22,6 +23,9 @@ type Discord struct {
event bot.Callback event bot.Callback
emojiCache map[string]string emojiCache map[string]string
// store IDs -> nick and vice versa for quick conversion
uidCache map[string]string
} }
func New(config *config.Config) *Discord { func New(config *config.Config) *Discord {
@ -32,6 +36,7 @@ func New(config *config.Config) *Discord {
d := &Discord{ d := &Discord{
config: config, config: config,
client: client, client: client,
uidCache: map[string]string{},
} }
return d return d
} }
@ -117,7 +122,11 @@ func (d *Discord) sendMessage(channel, message string, meMessage bool, args ...i
//st, err := d.client.ChannelMessageSend(channel, message) //st, err := d.client.ChannelMessageSend(channel, message)
if err != nil { if err != nil {
log.Error().Err(err).Msg("Error sending message") log.Error().
Interface("data", data).
Str("channel", channel).
Err(err).
Msg("Error sending message")
return "", err return "", err
} }
@ -145,26 +154,32 @@ func (d *Discord) GetEmojiList() map[string]string {
return emojis return emojis
} }
// Who gets the users in the guild
// Note that the channel ID does not matter in this particular case
func (d *Discord) Who(id string) []string { 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{} users := []string{}
for _, u := range ch.Recipients { for name, _ := range d.uidCache {
users = append(users, u.Username) users = append(users, name)
} }
return users return users
} }
func (d *Discord) Profile(id string) (user.User, error) { func (d *Discord) Profile(id string) (user.User, error) {
if _, err := strconv.Atoi(id); err != nil {
if newID, ok := d.uidCache[id]; ok {
id = newID
} else {
return user.User{}, fmt.Errorf("invalid ID snowflake: %s", id)
}
}
u, err := d.client.User(id) u, err := d.client.User(id)
if err != nil { if err != nil {
log.Error().Err(err).Msg("Error getting user") log.Error().Err(err).Msg("Error getting user")
return user.User{}, err return user.User{}, err
} }
return *d.convertUser(u), nil user := d.convertUser(u)
d.uidCache[user.Name] = user.ID
return *user, nil
} }
func (d *Discord) convertUser(u *discordgo.User) *user.User { func (d *Discord) convertUser(u *discordgo.User) *user.User {
@ -215,6 +230,9 @@ func (d *Discord) Serve() error {
} }
func (d *Discord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { func (d *Discord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
// if we haven't seen this user, we need to resolve their nick before continuing
author, _ := d.Profile(m.Author.ID)
if m.Author.ID == s.State.User.ID { if m.Author.ID == s.State.User.ID {
return return
} }
@ -228,11 +246,9 @@ func (d *Discord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreate
tStamp, _ := m.Timestamp.Parse() tStamp, _ := m.Timestamp.Parse()
author := d.convertUser(m.Author)
msg := msg.Message{ msg := msg.Message{
ID: m.ID, ID: m.ID,
User: author, User: &author,
Channel: m.ChannelID, Channel: m.ChannelID,
ChannelName: ch.Name, ChannelName: ch.Name,
Body: text, Body: text,

View File

@ -383,7 +383,10 @@ func (p *BeersPlugin) pullUntappd() ([]checkin, error) {
var beers Beers var beers Beers
err = json.Unmarshal(body, &beers) err = json.Unmarshal(body, &beers)
if err != nil { if err != nil {
log.Error().Err(err) log.Error().
Str("body", string(body)).
Err(err).
Msg("could not unmarshal")
return []checkin{}, err return []checkin{}, err
} }
return beers.Response.Checkins.Items, nil return beers.Response.Checkins.Items, nil

View File

@ -54,15 +54,16 @@ func (p *GoalsPlugin) mkDB() {
func (p *GoalsPlugin) registerCmds() { func (p *GoalsPlugin) registerCmds() {
p.handlers = bot.HandlerTable{ p.handlers = bot.HandlerTable{
{Kind: bot.Message, IsCmd: true, {Kind: bot.Message, IsCmd: true,
Regex: regexp.MustCompile(`(?i)^register (?P<type>competition|goal) for (?P<who>[[:punct:][:alnum:]]+) (?P<what>[[:punct:][:alnum:]]+) (?P<amount>[[:digit:]]+)?`), Regex: regexp.MustCompile(`(?i)^register (?P<type>competition|goal) for (?P<who>[[:punct:][:alnum:]]+) (?P<what>[^\s]+) (?P<amount>[[:digit:]]+)?`),
HelpText: "Register with `%s` for other people", HelpText: "Register with `%s` for other people",
Handler: func(r bot.Request) bool { Handler: func(r bot.Request) bool {
log.Debug().Interface("values", r.Values).Msg("trying to register a goal")
amount, _ := strconv.Atoi(r.Values["amount"]) amount, _ := strconv.Atoi(r.Values["amount"])
p.register(r.Conn, r.Msg.Channel, r.Values["type"], r.Values["what"], r.Values["who"], amount) p.register(r.Conn, r.Msg.Channel, r.Values["type"], r.Values["what"], r.Values["who"], amount)
return true return true
}}, }},
{Kind: bot.Message, IsCmd: true, {Kind: bot.Message, IsCmd: true,
Regex: regexp.MustCompile(`(?i)^register (?P<type>competition|goal) (?P<what>[[:punct:][:alnum:]]+) (?P<amount>[[:digit:]]+)?`), Regex: regexp.MustCompile(`(?i)^register (?P<type>competition|goal) (?P<what>[^\s]+) (?P<amount>[[:digit:]]+)?`),
HelpText: "Register with `%s` for yourself", HelpText: "Register with `%s` for yourself",
Handler: func(r bot.Request) bool { Handler: func(r bot.Request) bool {
amount, _ := strconv.Atoi(r.Values["amount"]) amount, _ := strconv.Atoi(r.Values["amount"])
@ -84,14 +85,14 @@ func (p *GoalsPlugin) registerCmds() {
return true return true
}}, }},
{Kind: bot.Message, IsCmd: true, {Kind: bot.Message, IsCmd: true,
Regex: regexp.MustCompile(`(?i)^check (?P<type>competition|goal) for (?P<who>[[:punct:][:alnum:]]+) (?P<what>[[:punct:][:alnum:]]+)`), Regex: regexp.MustCompile(`(?i)^check (?P<type>competition|goal) for (?P<who>[[:punct:][:alnum:]]+) (?P<what>[^\s]+)`),
HelpText: "Check with `%s` for other people", HelpText: "Check with `%s` for other people",
Handler: func(r bot.Request) bool { Handler: func(r bot.Request) bool {
p.check(r.Conn, r.Msg.Channel, r.Values["type"], r.Values["what"], r.Values["who"]) p.check(r.Conn, r.Msg.Channel, r.Values["type"], r.Values["what"], r.Values["who"])
return true return true
}}, }},
{Kind: bot.Message, IsCmd: true, {Kind: bot.Message, IsCmd: true,
Regex: regexp.MustCompile(`(?i)^check (?P<type>competition|goal) (?P<what>[[:punct:][:alnum:]]+)`), Regex: regexp.MustCompile(`(?i)^check (?P<type>competition|goal) (?P<what>[^\s]+)`),
HelpText: "Check with `%s` for yourself", HelpText: "Check with `%s` for yourself",
Handler: func(r bot.Request) bool { Handler: func(r bot.Request) bool {
p.check(r.Conn, r.Msg.Channel, r.Values["type"], r.Values["what"], r.Msg.User.Name) p.check(r.Conn, r.Msg.Channel, r.Values["type"], r.Values["what"], r.Msg.User.Name)
@ -134,6 +135,7 @@ func (p *GoalsPlugin) deregister(c bot.Connector, ch, kind, what, who string) {
} }
func (p *GoalsPlugin) check(c bot.Connector, ch, kind, what, who string) { func (p *GoalsPlugin) check(c bot.Connector, ch, kind, what, who string) {
log.Debug().Msgf("checking goal in channel %s", ch)
if kind == "goal" { if kind == "goal" {
p.checkGoal(c, ch, what, who) p.checkGoal(c, ch, what, who)
return return
@ -193,8 +195,15 @@ func (p *GoalsPlugin) checkGoal(c bot.Connector, ch, what, who string) {
if err == nil && user.ID != "" { if err == nil && user.ID != "" {
id = user.ID id = user.ID
nick = user.Name nick = user.Name
} else {
log.Error().Err(err).Msg("no user returned for goal check")
} }
log.Debug().
Str("nick", nick).
Str("id", id).
Str("what", what).
Msg("looking for item")
item, err := counter.GetUserItem(p.db, nick, id, what) item, err := counter.GetUserItem(p.db, nick, id, what)
if err != nil { if err != nil {
p.b.Send(c, bot.Message, ch, fmt.Sprintf("I couldn't find any %s", what)) p.b.Send(c, bot.Message, ch, fmt.Sprintf("I couldn't find any %s", what))
@ -313,15 +322,12 @@ func (p *GoalsPlugin) update(r bot.Request, u counter.Update) {
log.Error().Err(err).Msgf("could not get goal for %#v", u) log.Error().Err(err).Msgf("could not get goal for %#v", u)
return return
} }
chs := p.cfg.GetArray("channels", []string{})
c := p.b.DefaultConnector() c := p.b.DefaultConnector()
for _, g := range gs { for _, g := range gs {
for _, ch := range chs {
if g.Kind == "goal" { if g.Kind == "goal" {
p.checkGoal(c, ch, u.What, u.Who) p.checkGoal(c, r.Msg.Channel, u.What, u.Who)
} else { } else {
p.checkCompetition(c, ch, u.What, u.Who) p.checkCompetition(c, r.Msg.Channel, u.What, u.Who)
}
} }
} }
} }