From 272f289fb60aa2f73c162ad8cb4895a0afc95741 Mon Sep 17 00:00:00 2001 From: Noikoio Date: Mon, 13 May 2019 23:27:26 -0700 Subject: [PATCH] Add rudimentary custom announcement feature There is some room for improvement. Namely, custom placement of the birthday list. Moderator help message was edited to fit the 1024 character constraint. --- BirthdayBot/BackgroundWorker.vb | 53 ++++++++++--------- BirthdayBot/BirthdayBot.vbproj | 4 +- BirthdayBot/Data/GuildSettings.vb | 31 +++++++++-- BirthdayBot/UserInterface/HelpInfoCommands.vb | 19 +++---- BirthdayBot/UserInterface/ManagerCommands.vb | 14 +++++ 5 files changed, 83 insertions(+), 38 deletions(-) diff --git a/BirthdayBot/BackgroundWorker.vb b/BirthdayBot/BackgroundWorker.vb index 31f3403..c6d7c41 100644 --- a/BirthdayBot/BackgroundWorker.vb +++ b/BirthdayBot/BackgroundWorker.vb @@ -97,11 +97,13 @@ Class BackgroundWorker Dim users As IEnumerable(Of GuildUserSettings) Dim role As SocketRole = Nothing Dim channel As SocketTextChannel = Nothing + Dim announceMsg As String SyncLock _bot.KnownGuilds If Not _bot.KnownGuilds.ContainsKey(guild.Id) Then Return 0 Dim gs = _bot.KnownGuilds(guild.Id) tz = gs.TimeZone users = gs.Users + announceMsg = gs.AnnounceMessage If gs.AnnounceChannelId.HasValue Then channel = guild.GetTextChannel(gs.AnnounceChannelId.Value) If gs.RoleId.HasValue Then role = guild.GetRole(gs.RoleId.Value) @@ -133,7 +135,7 @@ Class BackgroundWorker End Try If announceNames.Count <> 0 Then ' Send out announcement message - Await BirthdayAnnounceAsync(guild, channel, announceNames) + Await BirthdayAnnounceAsync(announceMsg, channel, announceNames) End If Return announceNames.Count @@ -225,36 +227,39 @@ Class BackgroundWorker ''' Makes (or attempts to make) an announcement in the specified channel that includes all users ''' who have just had their birthday role added. ''' - Private Async Function BirthdayAnnounceAsync(g As SocketGuild, c As SocketTextChannel, names As IEnumerable(Of SocketGuildUser)) As Task + Private Async Function BirthdayAnnounceAsync(ByVal announceMsg As String, + c As SocketTextChannel, + names As IEnumerable(Of SocketGuildUser)) As Task + + Const DefaultAnnounce = "Please wish a happy birthday to our esteemed member(s):" If c Is Nothing Then Return ' TODO streamline this whole thing once a customizable message is implemented. ' Plan: "{custommessage}\n{namedisplay}" Dim result As String - If names.Count = 1 Then - ' Single birthday. No need for tricks. - Dim name = BirthdayAnnounceFormatName(names(0)) - result = $"Please wish a happy birthday to our esteemed member, **{name}**." - Else - ' Build sorted name list - Dim namestrings As New List(Of String) - For Each item In names - namestrings.Add(BirthdayAnnounceFormatName(item)) - Next - namestrings.Sort(StringComparer.OrdinalIgnoreCase) - - Dim namedisplay As New StringBuilder() - Dim first = True - For Each item In namestrings - If Not first Then - namedisplay.Append(", ") - End If - first = False - namedisplay.Append(item) - Next - result = $"Please wish a happy birthday to our esteemed members: {namedisplay.ToString()}." + If announceMsg Is Nothing Then + announceMsg = DefaultAnnounce End If + announceMsg = announceMsg.TrimEnd() + + ' Build sorted name list + Dim namestrings As New List(Of String) + For Each item In names + namestrings.Add(BirthdayAnnounceFormatName(item)) + Next + namestrings.Sort(StringComparer.OrdinalIgnoreCase) + + Dim namedisplay As New StringBuilder() + Dim first = True + For Each item In namestrings + If Not first Then + namedisplay.Append(", ") + End If + first = False + namedisplay.Append(item) + Next + result = announceMsg + " " + namedisplay.ToString() Try Await c.SendMessageAsync(result) diff --git a/BirthdayBot/BirthdayBot.vbproj b/BirthdayBot/BirthdayBot.vbproj index 0df48ca..7765d14 100644 --- a/BirthdayBot/BirthdayBot.vbproj +++ b/BirthdayBot/BirthdayBot.vbproj @@ -4,8 +4,8 @@ Exe BirthdayBot netcoreapp2.0 - 0.6.1 - 0.6.1.0 + 0.7.0 + 0.7.0.0 Noikoio Discord bot for birthday reminders. diff --git a/BirthdayBot/Data/GuildSettings.vb b/BirthdayBot/Data/GuildSettings.vb index 842bed7..6eb4e4f 100644 --- a/BirthdayBot/Data/GuildSettings.vb +++ b/BirthdayBot/Data/GuildSettings.vb @@ -16,6 +16,7 @@ Friend Class GuildSettings Private _modRole As ULong? Private _tz As String Private _moderated As Boolean + Private _announceMsg As String Private _userCache As Dictionary(Of ULong, GuildUserSettings) Private _roleWarning As Boolean @@ -103,6 +104,15 @@ Friend Class GuildSettings End Get End Property + ''' + ''' Gets the guild-specific birthday announcement message. + ''' + Public ReadOnly Property AnnounceMessage As String + Get + Return _announceMsg + End Get + End Property + ' Called by LoadSettingsAsync. Double-check ordinals when changes are made. Private Sub New(reader As DbDataReader, dbconfig As Database) _db = dbconfig @@ -118,6 +128,7 @@ Friend Class GuildSettings _tz = If(reader.IsDBNull(3), Nothing, reader.GetString(3)) _moderated = reader.GetBoolean(4) If Not reader.IsDBNull(5) Then _modRole = CULng(reader.GetInt64(5)) + _announceMsg = If(reader.IsDBNull(6), Nothing, reader.GetString(6)) ' Get user information loaded up. Dim userresult = GuildUserSettings.GetGuildUsersAsync(dbconfig, GuildId) @@ -253,6 +264,11 @@ Friend Class GuildSettings Await UpdateDatabaseAsync() End Function + Public Async Function UpdateAnnounceMessageAsync(message As String) As Task + _announceMsg = message + Await UpdateDatabaseAsync() + End Function + #Region "Database" Public Const BackingTable = "settings" Public Const BackingTableBans = "banned_users" @@ -265,7 +281,8 @@ Friend Class GuildSettings "channel_announce_id bigint null, " + "time_zone text null, " + "moderated boolean not null default FALSE, " + - "moderator_role bigint null" + + "moderator_role bigint null, " + + "announce_message text null" + ")" c.ExecuteNonQuery() End Using @@ -287,7 +304,7 @@ Friend Class GuildSettings Using db = Await dbsettings.OpenConnectionAsync() Using c = db.CreateCommand() ' Take note of ordinals for use in the constructor - c.CommandText = "select guild_id, role_id, channel_announce_id, time_zone, moderated, moderator_role " + + c.CommandText = "select guild_id, role_id, channel_announce_id, time_zone, moderated, moderator_role, announce_message " + $"from {BackingTable} where guild_id = @Gid" c.Parameters.Add("@Gid", NpgsqlDbType.Bigint).Value = guild c.Prepare() @@ -322,7 +339,8 @@ Friend Class GuildSettings "channel_announce_id = @ChannelId, " + "time_zone = @TimeZone, " + "moderated = @Moderated, " + - "moderator_role = @ModRole " + + "moderator_role = @ModRole, " + + "announce_message = @AnnounceMsg " + "where guild_id = @Gid" c.Parameters.Add("@Gid", NpgsqlDbType.Bigint).Value = GuildId With c.Parameters.Add("@RoleId", NpgsqlDbType.Bigint) @@ -354,6 +372,13 @@ Friend Class GuildSettings .Value = DBNull.Value End If End With + With c.Parameters.Add("@AnnounceMsg", NpgsqlDbType.Text) + If AnnounceMessage IsNot Nothing Then + .Value = AnnounceMessage + Else + .Value = DBNull.Value + End If + End With c.Prepare() Await c.ExecuteNonQueryAsync() End Using diff --git a/BirthdayBot/UserInterface/HelpInfoCommands.vb b/BirthdayBot/UserInterface/HelpInfoCommands.vb index 859ae53..31fed47 100644 --- a/BirthdayBot/UserInterface/HelpInfoCommands.vb +++ b/BirthdayBot/UserInterface/HelpInfoCommands.vb @@ -47,21 +47,22 @@ Friend Class HelpInfoCommands .Name = "Commands for server managers and bot moderators", .Value = $"{mpfx}role (role name or ID)`" + vbLf + - " » Configures the role to apply to users having birthdays." + vbLf + + " » Sets the role to apply to users having birthdays. **Required for bot function.**" + vbLf + $"{mpfx}channel (channel name or ID)`" + vbLf + - " » Configures the channel to use for announcements. Leave blank to disable." + vbLf + + " » Sets the channel to use for announcements. Leave blank to disable." + vbLf + + $"{mpfx}message (message)`" + vbLf + + " » Sets a custom announcement message. The names of those celebrating birthdays are appended to it." + vbLf + $"{mpfx}modrole (role name or ID)`" + vbLf + - " » Sets the designated role for bot moderators. Moderators can access `bb.config` and `bb.override`." + vbLf + + " » Sets the designated role for bot moderators, granting them access to `bb.config` and `bb.override`." + vbLf + $"{mpfx}zone (time zone name)`" + vbLf + - " » Sets the default time zone for all dates that don't have their own zone set." + vbLf + - $" »» See `{CommandPrefix}help-tzdata`. Leave blank to set to UTC." + vbLf + + " » Sets the default time zone for users without their own zone." + vbLf + + $" »» See `{CommandPrefix}help-tzdata`. Leave blank to set to default." + vbLf + $"{mpfx}block/unblock (user mention or ID)`" + vbLf + " » Prevents or allows usage of bot commands to the given user." + vbLf + $"{mpfx}moderated on/off`" + vbLf + - " » Prevents or allows usage of bot commands to all users excluding managers." + vbLf + - $"{cpfx}override (user mention or ID) (command)`" + vbLf + - " » Performs a command on behalf of the given user." + vbLf + - " »» Command may be either `set`, `zone`, or `remove` plus appropriate parameters." + " » Prevents or allows usage of bot commands to everyone excluding moderators." + vbLf + + $"{cpfx}override (user mention or ID) (command w/ parameters)`" + vbLf + + " » Performs certain commands on behalf of another given user." } Dim helpNoManager As New EmbedBuilder diff --git a/BirthdayBot/UserInterface/ManagerCommands.vb b/BirthdayBot/UserInterface/ManagerCommands.vb index ba9a13c..a495f69 100644 --- a/BirthdayBot/UserInterface/ManagerCommands.vb +++ b/BirthdayBot/UserInterface/ManagerCommands.vb @@ -23,6 +23,7 @@ Friend Class ManagerCommands {"role", AddressOf ScmdRole}, {"channel", AddressOf ScmdChannel}, {"modrole", AddressOf ScmdModRole}, + {"message", AddressOf ScmdAnnounceMsg}, {"zone", AddressOf ScmdZone}, {"block", AddressOf ScmdBlock}, {"unblock", AddressOf ScmdBlock}, @@ -260,6 +261,19 @@ Friend Class ManagerCommands Await reqChannel.SendMessageAsync($":white_check_mark: Moderated mode has been turned {parameter}.") End If End Function + + ' Sets/unsets custom announcement message. + Private Async Function ScmdAnnounceMsg(param As String(), reqChannel As SocketTextChannel) As Task + If param.Length <> 2 Then + Await reqChannel.SendMessageAsync(GenericError) + Return + End If + + SyncLock Instance.KnownGuilds + Instance.KnownGuilds(reqChannel.Guild.Id).UpdateAnnounceMessageAsync(param(1)).Wait() + End SyncLock + Await reqChannel.SendMessageAsync(":white_check_mark: The birthday announcement message has been updated.") + End Function #End Region ' Execute command as another user