diff --git a/src/internal/bot/main.go b/src/internal/bot/main.go index 3b14da2..90e82d0 100644 --- a/src/internal/bot/main.go +++ b/src/internal/bot/main.go @@ -54,7 +54,9 @@ func (bot *Bot) Start() error { }) // Add handlers - bot.DiscordSession.AddHandler(bot.HandleReaction) + bot.DiscordSession.AddHandler(bot.HandleAddReaction) + bot.DiscordSession.AddHandler(bot.HandleRemoveReaction) + bot.DiscordSession.AddHandler(bot.HandleRemoveAllReaction) // Load session err = discord.Open() @@ -80,14 +82,35 @@ func (bot *Bot) Start() error { } // HandleReaction - Simply log it -func (bot *Bot) HandleReaction(discord *discordgo.Session, reaction *discordgo.MessageReactionAdd) { +func (bot *Bot) HandleAddReaction(discord *discordgo.Session, reaction *discordgo.MessageReactionAdd) { // Ignore Dyno user if reaction.UserID == dynoUserID { return } - err := bot.Db.LogEmojiUsage(reaction.GuildID, reaction.ChannelID, reaction.UserID, reaction.Emoji.Name) + err := bot.Db.LogEmojiUsage(reaction.GuildID, reaction.ChannelID, reaction.MessageID, reaction.UserID, reaction.Emoji.Name) if err != nil { slog.Error("Failed to log emoji usage", "err", err) } } + +// HandleRemoveReaction - Remove for user/message/emoji +func (bot *Bot) HandleRemoveReaction(discord *discordgo.Session, reaction *discordgo.MessageReactionRemove) { + // Ignore Dyno user + if reaction.UserID == dynoUserID { + return + } + + err := bot.Db.DeleteEmojiUsage(reaction.GuildID, reaction.ChannelID, reaction.MessageID, reaction.UserID, reaction.Emoji.Name) + if err != nil { + slog.Error("Failed to delete single emoji usage", "err", err) + } +} + +// HandleRemoveAllReaction - Remove all for message +func (bot *Bot) HandleRemoveAllReaction(discord *discordgo.Session, reaction *discordgo.MessageReactionRemoveAll) { + err := bot.Db.DeleteEmojiAll(reaction.GuildID, reaction.ChannelID, reaction.MessageID) + if err != nil { + slog.Error("Failed to delete all emoji usage for message", "err", err) + } +} diff --git a/src/internal/db/database.go b/src/internal/db/database.go index f96d7ab..24baef0 100644 --- a/src/internal/db/database.go +++ b/src/internal/db/database.go @@ -41,9 +41,10 @@ func (db *Database) runMigrations() (*Database, error) { "`id` INTEGER PRIMARY KEY AUTOINCREMENT, " + "`guild_id` TEXT, " + "`channel_id` TEXT, " + + "`message_id` TEXT, " + "`user_id` TEXT, " + "`emoji_id` TEXT, " + - "`timestamp` DATETIME, `viewed` INT DEFAULT 0" + + "`timestamp` DATETIME" + ")") if err != nil { return db, err @@ -54,6 +55,11 @@ func (db *Database) runMigrations() (*Database, error) { return db, err } + _, err = db.db.Exec("CREATE INDEX IF NOT EXISTS `idx_emoji_usage_message_id_user_id_emoji_id` ON `emoji_usage` (`message_id`, `user_id`, `guild_id`, `emoji_id`)") + if err != nil { + return db, err + } + _, err = db.db.Exec("CREATE INDEX IF NOT EXISTS `idx_emoji_usage_emoji_id,guild_id` ON `emoji_usage` (`guild_id`, `emoji_id`)") return db, err } diff --git a/src/internal/db/emoji_usage.go b/src/internal/db/emoji_usage.go index 020bae0..4c388c0 100644 --- a/src/internal/db/emoji_usage.go +++ b/src/internal/db/emoji_usage.go @@ -6,10 +6,30 @@ type EmojiMap struct { } // LogEmojiUsage - Log usage -func (db *Database) LogEmojiUsage(guildID, channelID, userID, emojiID string) error { +func (db *Database) LogEmojiUsage(guildID, channelID, messageID, userID, emojiID string) error { _, err := db.db.Exec( - "INSERT INTO `emoji_usage` (`guild_id`, `channel_id`, `user_id`, `emoji_id`, `timestamp`) VALUES (?,?,?,?, datetime())", - guildID, channelID, userID, emojiID, + "INSERT INTO `emoji_usage` (`guild_id`, `channel_id`, `message_id`, `user_id`, `emoji_id`, `timestamp`) VALUES (?,?,?,?,?, datetime())", + guildID, channelID, messageID, userID, emojiID, + ) + + return err +} + +// DeleteEmojiUsage - Delete for guild/channel/message/user +func (db *Database) DeleteEmojiUsage(guildID, channelID, messageID, userID, emojiID string) error { + _, err := db.db.Exec( + "DELETE FROM `emoji_usage` WHERE `guild_id` = ? AND `channel_id` = ? AND `message_id` = ? AND `user_id` = ? AND `emoji_id` = ?", + guildID, channelID, messageID, userID, emojiID, + ) + + return err +} + +// DeleteEmojiAll - Delete for whole message +func (db *Database) DeleteEmojiAll(guildID, channelID, messageID string) error { + _, err := db.db.Exec( + "DELETE FROM `emoji_usage` WHERE `guild_id` = ? AND `channel_id` = ? AND `message_id` = ?", + guildID, channelID, messageID, ) return err