From fdfbb0f426e441627df4a6d2d29feb065de1758f Mon Sep 17 00:00:00 2001 From: Grimm Date: Fri, 29 Nov 2024 12:27:56 -0800 Subject: [PATCH] update: toggle notifications - Separate live and post notifications - Allow enabling/disabling live or post notifications - Update /list command to show notification status --- README.md | 5 ++- internal/bot/bot.go | 10 +++-- internal/bot/commands.go | 34 +++++++++++++++++ internal/bot/handlers.go | 72 ++++++++++++++++++++++++++++++++++-- internal/database/databse.go | 2 + migrate.py | 12 +++--- 6 files changed, 118 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 50a284e..c6b6f1d 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,10 @@ ## TODO: +- [ ] Hack together way to provide roles based on sub/follow per server - [x] Fix following logic to still add if account has no pfp and just let it be empty in the embed -- [ ] Possibly separate live and post notification - - [ ] Allow enabling and disabling one or the other +- [x] Possibly separate live and post notification + - [x] Allow enabling and disabling one or the other ## Running The Bot Yourself diff --git a/internal/bot/bot.go b/internal/bot/bot.go index a0500d9..a679e1d 100644 --- a/internal/bot/bot.go +++ b/internal/bot/bot.go @@ -84,7 +84,7 @@ func (b *Bot) monitorUsers() { } defer tx.Rollback() - rows, err := tx.Query("SELECT guild_id, user_id, username, notification_channel, last_post_id, last_stream_start, mention_role, avatar_location, avatar_location_updated_at, live_image_url FROM monitored_users") + rows, err := tx.Query("SELECT guild_id, user_id, username, notification_channel, last_post_id, last_stream_start, mention_role, avatar_location, avatar_location_updated_at, live_image_url, posts_enabled, live_enabled FROM monitored_users") if err != nil { return err } @@ -102,9 +102,11 @@ func (b *Bot) monitorUsers() { AvatarLocation string AvatarLocationUpdatedAt int64 LiveImageURL string + PostsEnabled bool + LiveEnabled bool } - err := rows.Scan(&user.GuildID, &user.UserID, &user.Username, &user.NotificationChannel, &user.LastPostID, &user.LastStreamStart, &user.MentionRole, &user.AvatarLocation, &user.AvatarLocationUpdatedAt, &user.LiveImageURL) + err := rows.Scan(&user.GuildID, &user.UserID, &user.Username, &user.NotificationChannel, &user.LastPostID, &user.LastStreamStart, &user.MentionRole, &user.AvatarLocation, &user.AvatarLocationUpdatedAt, &user.LiveImageURL, &user.PostsEnabled, &user.LiveEnabled) if err != nil { log.Printf("Error scanning row: %v", err) continue @@ -136,7 +138,7 @@ func (b *Bot) monitorUsers() { } } - if streamInfo.Response.Stream.Status == 2 && streamInfo.Response.Stream.StartedAt > user.LastStreamStart { + if user.LiveEnabled && streamInfo.Response.Stream.Status == 2 && streamInfo.Response.Stream.StartedAt > user.LastStreamStart { _, err = tx.Exec(` UPDATE monitored_users SET last_stream_start = ? @@ -168,7 +170,7 @@ func (b *Bot) monitorUsers() { continue } - if len(postInfo) > 0 && postInfo[0].ID != user.LastPostID { + if user.PostsEnabled && len(postInfo) > 0 && postInfo[0].ID != user.LastPostID { _, err = tx.Exec(` UPDATE monitored_users SET last_post_id = ? diff --git a/internal/bot/commands.go b/internal/bot/commands.go index 9d6cbed..83e6fe2 100644 --- a/internal/bot/commands.go +++ b/internal/bot/commands.go @@ -65,6 +65,40 @@ func (b *Bot) registerCommands() { }, }, }, + { + Name: "toggle", + Description: "Toggle notifications for a model", + Options: []*discordgo.ApplicationCommandOption{ + { + Type: discordgo.ApplicationCommandOptionString, + Name: "username", + Description: "Fansly username", + Required: true, + }, + { + Type: discordgo.ApplicationCommandOptionString, + Name: "type", + Description: "Notification type to toggle", + Required: true, + Choices: []*discordgo.ApplicationCommandOptionChoice{ + { + Name: "Posts", + Value: "posts", + }, + { + Name: "Live", + Value: "live", + }, + }, + }, + { + Type: discordgo.ApplicationCommandOptionBoolean, + Name: "enabled", + Description: "Enable or disable notifications", + Required: true, + }, + }, + }, } _, err := b.Session.ApplicationCommandBulkOverwrite(b.Session.State.User.ID, "", commands) diff --git a/internal/bot/handlers.go b/internal/bot/handlers.go index a8bf005..f0fed0a 100644 --- a/internal/bot/handlers.go +++ b/internal/bot/handlers.go @@ -30,6 +30,8 @@ func (b *Bot) interactionCreate(s *discordgo.Session, i *discordgo.InteractionCr b.handleListCommand(s, i) case "setliveimage": b.handleSetLiveImageCommand(s, i) + case "toggle": + b.handleToggleCommand(s, i) } } @@ -143,7 +145,7 @@ func (b *Bot) respondToInteraction(s *discordgo.Session, i *discordgo.Interactio func (b *Bot) handleListCommand(s *discordgo.Session, i *discordgo.InteractionCreate) { // Fetch monitored users for the current guild rows, err := b.DB.Query(` - SELECT username, notification_channel, mention_role + SELECT username, notification_channel, mention_role, posts_enabled, live_enabled FROM monitored_users WHERE guild_id = ? `, i.GuildID) @@ -155,8 +157,11 @@ func (b *Bot) handleListCommand(s *discordgo.Session, i *discordgo.InteractionCr var monitoredUsers []string for rows.Next() { - var username, channelID, roleID string - err := rows.Scan(&username, &channelID, &roleID) + var ( + username, channelID, roleID string + postsEnabled, liveEnabled bool + ) + err := rows.Scan(&username, &channelID, &roleID, &postsEnabled, &liveEnabled) if err != nil { log.Printf("Error scanning row: %v", err) continue @@ -174,7 +179,23 @@ func (b *Bot) handleListCommand(s *discordgo.Session, i *discordgo.InteractionCr } } - userInfo := fmt.Sprintf("- %s (Channel: %s, Role: %s)", username, channelInfo, roleInfo) + // Create status indicators + postStatus := "✅" + if !postsEnabled { + postStatus = "❌" + } + liveStatus := "✅" + if !liveEnabled { + liveStatus = "❌" + } + + userInfo := fmt.Sprintf("- %s\n • Channel: %s\n • Role: %s\n • Posts: %s\n • Live: %s", + username, + channelInfo, + roleInfo, + postStatus, + liveStatus, + ) monitoredUsers = append(monitoredUsers, userInfo) } @@ -235,6 +256,49 @@ func (b *Bot) handleSetLiveImageCommand(s *discordgo.Session, i *discordgo.Inter b.editInteractionResponse(s, i, fmt.Sprintf("Live image for %s has been set successfully.", username)) } +func (b *Bot) handleToggleCommand(s *discordgo.Session, i *discordgo.InteractionCreate) { + options := i.ApplicationCommandData().Options + username := options[0].StringValue() + notifiType := options[1].StringValue() + enabled := options[2].BoolValue() + + var column string + switch notifiType { + case "posts": + column = "posts_enabled" + case "live": + column = "live_enabled" + default: + b.respondToInteraction(s, i, "Invalid notification type") + return + } + + query := fmt.Sprintf(` + UPDATE monitored_users + SET %s = ? + WHERE guild_id = ? AND username = ? + `, column) + + result, err := b.DB.Exec(query, enabled, i.GuildID, username) + if err != nil { + b.respondToInteraction(s, i, fmt.Sprintf("Error updating settings: %v", err)) + return + } + + rowsAffected, _ := result.RowsAffected() + if rowsAffected == 0 { + b.respondToInteraction(s, i, fmt.Sprintf("User %s not found", username)) + return + } + + status := "enabled" + if !enabled { + status = "disabled" + } + + b.respondToInteraction(s, i, fmt.Sprintf("%s notifications %s for %s", notifiType, status, username)) +} + // Add this new helper function func (b *Bot) editInteractionResponse(s *discordgo.Session, i *discordgo.InteractionCreate, content string) { _, err := s.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{ diff --git a/internal/database/databse.go b/internal/database/databse.go index 22c00a3..385535e 100644 --- a/internal/database/databse.go +++ b/internal/database/databse.go @@ -36,6 +36,8 @@ func createTables() { avatar_location TEXT, avatar_location_updated_at INTEGER, live_image_url TEXT, + posts_enabled BOOLEAN DEFAULT 1, + live_enabled BOOLEAN DEFAULT 1, PRIMARY KEY (guild_id, user_id) ) `) diff --git a/migrate.py b/migrate.py index 35b4423..9c29617 100644 --- a/migrate.py +++ b/migrate.py @@ -1,5 +1,4 @@ import sqlite3 -# import time # Connect to the old and new databases old_conn = sqlite3.connect("bot-old.db") @@ -20,6 +19,8 @@ avatar_location TEXT, avatar_location_updated_at INTEGER, live_image_url TEXT, + posts_enabled BOOLEAN DEFAULT 1, + live_enabled BOOLEAN DEFAULT 1, PRIMARY KEY (guild_id, user_id) ) """) @@ -33,13 +34,10 @@ new_cursor.execute( """ INSERT INTO monitored_users - (guild_id, user_id, username, notification_channel, last_post_id, last_stream_start, mention_role, avatar_location, avatar_location_updated_at, live_image_url) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + (guild_id, user_id, username, notification_channel, last_post_id, last_stream_start, mention_role, avatar_location, avatar_location_updated_at, live_image_url, posts_enabled, live_enabled) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, - ( - *record, - None, - ), # Add all existing fields from old record, plus None for live_image_url + (*record[:10], 1, 1), # Take first 10 fields from record, add two boolean flags ) # Commit the changes and close the connections