Skip to content

Commit 57e090b

Browse files
Add 'channels' option to /tracking add (#236)
* Add 'channels' option to /tracking add Allows filtering tracking to specific channels * Account for threads * Use regex to match any number of spaces when parsing channel list & trim * Account for missing "trackingChannels" key in db * Accept review suggestion Co-authored-by: Erisa A <[email protected]> --------- Co-authored-by: Erisa A <[email protected]>
1 parent db92550 commit 57e090b

File tree

2 files changed

+120
-12
lines changed

2 files changed

+120
-12
lines changed

Commands/InteractionCommands/TrackingInteractions.cs

+79-1
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,89 @@ internal class TrackingInteractions : ApplicationCommandModule
77
public class TrackingSlashCommands
88
{
99
[SlashCommand("add", "Track a users messages.")]
10-
public async Task TrackingAddSlashCmd(InteractionContext ctx, [Option("member", "The member to track.")] DiscordUser discordUser)
10+
public async Task TrackingAddSlashCmd(InteractionContext ctx, [Option("member", "The member to track.")] DiscordUser discordUser, [Option("channels", "Optional channels to filter to. Use IDs or mentions, and separate with commas or spaces.")] string channels = "")
1111
{
1212
await ctx.DeferAsync(ephemeral: false);
13+
14+
var channelsUpdated = false;
15+
16+
// Resolve list of filter channels
17+
List<ulong> filterChannels = new();
18+
if (!string.IsNullOrEmpty(channels))
19+
{
20+
channels = Regex.Replace(channels, ", +", ",").Trim(); // "#general-chat, #lounge" ~> "#general-chat,#lounge" & trim
21+
var channelIds = channels.Split(' ', ',');
22+
foreach (var channel in channelIds)
23+
{
24+
// skip some common obviously-invalid entries
25+
if (channel == "" || channel == " ")
26+
continue;
27+
28+
// If this is a channel mention, get the ID first
29+
var channelId = channel.Replace("<#", "").Replace(">", "");
30+
31+
if (ulong.TryParse(channelId, out var id))
32+
{
33+
if (!filterChannels.Contains(id))
34+
filterChannels.Add(id);
35+
}
36+
else
37+
{
38+
// Invalid ID; couldn't parse as ulong
39+
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Error} I couldn't parse \"{channel}\" as a channel ID or mention! Please double-check it and try again."));
40+
return;
41+
}
42+
}
43+
}
44+
45+
// If we were passed nothing, filterChannels remains an empty List. Otherwise, it is populated with the parsed channel IDs
46+
47+
// Compare to db; if there is a mismatch, replace whatever is already in the db with what was passed to this command
48+
if (Program.db.HashExists("trackingChannels", discordUser.Id))
49+
{
50+
var dbChannels = Program.db.HashGet("trackingChannels", discordUser.Id).ToString();
51+
string cmdChannels;
52+
if (filterChannels.Count < 1)
53+
{
54+
// No channels were passed. If there are any in the db, remove them
55+
if (await Program.db.HashExistsAsync("trackingChannels", discordUser.Id))
56+
{
57+
await Program.db.HashDeleteAsync("trackingChannels", discordUser.Id);
58+
channelsUpdated = true;
59+
}
60+
}
61+
else
62+
{
63+
cmdChannels = JsonConvert.SerializeObject(filterChannels);
64+
if (dbChannels != cmdChannels)
65+
{
66+
// Passed channels do not match db channels, update db
67+
var newChannels = JsonConvert.SerializeObject(filterChannels);
68+
await Program.db.HashSetAsync("trackingChannels", discordUser.Id, newChannels);
69+
channelsUpdated = true;
70+
}
71+
}
72+
}
73+
else
74+
{
75+
// No channels in db; just add whatever was passed
76+
// If nothing was passed, don't add anything
77+
if (filterChannels.Count > 0)
78+
{
79+
var newChannels = JsonConvert.SerializeObject(filterChannels);
80+
await Program.db.HashSetAsync("trackingChannels", discordUser.Id, newChannels);
81+
channelsUpdated = true;
82+
}
83+
}
1384

1485
if (Program.db.SetContains("trackedUsers", discordUser.Id))
1586
{
87+
if (channelsUpdated)
88+
{
89+
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Success} Successfully updated tracking for {discordUser.Mention}!"));
90+
return;
91+
}
92+
1693
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Error} This user is already tracked!"));
1794
return;
1895
}
@@ -51,6 +128,7 @@ public async Task TrackingRemoveSlashCmd(InteractionContext ctx, [Option("member
51128
}
52129

53130
await Program.db.SetRemoveAsync("trackedUsers", discordUser.Id);
131+
await Program.db.HashDeleteAsync("trackingChannels", discordUser.Id);
54132

55133
var channelId = Program.db.HashGet("trackingThreads", discordUser.Id);
56134
DiscordThreadChannel thread = (DiscordThreadChannel)await ctx.Client.GetChannelAsync((ulong)channelId);

Events/MessageEvent.cs

+41-11
Original file line numberDiff line numberDiff line change
@@ -142,19 +142,26 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe
142142
{
143143
if (Program.db.SetContains("trackedUsers", message.Author.Id))
144144
{
145-
DiscordThreadChannel relayThread;
146-
147-
if (trackingThreadCache.ContainsKey(message.Author.Id))
148-
{
149-
relayThread = trackingThreadCache[message.Author.Id];
150-
}
151-
else
145+
// Check current channel against tracking channels
146+
var trackingChannels = await Program.db.HashGetAsync("trackingChannels", message.Author.Id);
147+
if (trackingChannels.HasValue)
152148
{
153-
relayThread = (DiscordThreadChannel)await client.GetChannelAsync((ulong)await Program.db.HashGetAsync("trackingThreads", message.Author.Id));
154-
trackingThreadCache.Add(message.Author.Id, relayThread);
149+
var trackingChannelsList = JsonConvert.DeserializeObject<List<ulong>>(trackingChannels);
150+
if (trackingChannelsList.Count > 0)
151+
{
152+
// This user's tracking is filtered to channels; check the channel before relaying the msg to the tracking thread
153+
var channels = JsonConvert.DeserializeObject<List<ulong>>(trackingChannels);
154+
if (channels.Contains(channel.Id) || channels.Contains(channel.Parent.Id))
155+
{
156+
await RelayTrackedMessageAsync(client, message);
157+
}
158+
}
159+
else
160+
{
161+
// This user's tracking is not filtered to channels, so just relay the msg to the tracking thread
162+
await RelayTrackedMessageAsync(client, message);
163+
}
155164
}
156-
var _ = await relayThread.SendMessageAsync(await DiscordHelpers.GenerateMessageRelay(message.BaseMessage, true, true));
157-
158165
}
159166

160167
if (!isAnEdit && channel.IsPrivate && Program.cfgjson.LogChannels.ContainsKey("dms"))
@@ -938,6 +945,29 @@ public static async Task<bool> InviteCheck(DiscordInvite? invite, MockDiscordMes
938945
return false;
939946
}
940947
}
948+
949+
private static async Task RelayTrackedMessageAsync(DiscordClient client, DiscordMessage message)
950+
{
951+
await RelayTrackedMessageAsync(client, new MockDiscordMessage(message));
952+
}
953+
private static async Task RelayTrackedMessageAsync(DiscordClient client, MockDiscordMessage message)
954+
{
955+
DiscordThreadChannel relayThread;
956+
957+
if (trackingThreadCache.ContainsKey(message.Author.Id))
958+
{
959+
relayThread = trackingThreadCache[message.Author.Id];
960+
}
961+
else
962+
{
963+
relayThread = (DiscordThreadChannel)await client.GetChannelAsync(
964+
(ulong)await Program.db.HashGetAsync("trackingThreads", message.Author.Id));
965+
trackingThreadCache.Add(message.Author.Id, relayThread);
966+
}
967+
968+
var _ = await relayThread.SendMessageAsync(
969+
await DiscordHelpers.GenerateMessageRelay(message.BaseMessage, true, true));
970+
}
941971

942972
}
943973
}

0 commit comments

Comments
 (0)