Skip to content

Commit 93115da

Browse files
Merge pull request #260 from Unity-Developer-Community/feat/misc-fixes
Feat: Misc Fixes & Recruitment Service
2 parents a5a46a7 + 4e71eb5 commit 93115da

File tree

6 files changed

+56
-19
lines changed

6 files changed

+56
-19
lines changed

DiscordBot/Extensions/UserExtensions.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ public static bool HasRoleGroup(this IUser user, SocketRole role)
1515
}
1616
public static bool HasRoleGroup(this IUser user, ulong roleId)
1717
{
18-
return user is SocketGuildUser guildUser && guildUser.Roles.Any(x => x.Id == roleId);
18+
var guildUser = user as IGuildUser;
19+
if (guildUser == null)
20+
return false;
21+
return guildUser.RoleIds.Any(x => x == roleId);
1922
}
2023

2124
// Returns the users DisplayName (nickname) if it exists, otherwise returns the username

DiscordBot/Program.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class Program
2424
private IServiceProvider _services;
2525

2626
private UnityHelpService _unityHelpService;
27+
private RecruitService _recruitService;
2728

2829
public static void Main(string[] args) =>
2930
new Program().MainAsync().GetAwaiter().GetResult();
@@ -68,7 +69,7 @@ private async Task MainAsync()
6869
_isInitialized = true;
6970

7071
_unityHelpService = _services.GetRequiredService<UnityHelpService>();
71-
_services.GetRequiredService<RecruitService>();
72+
_recruitService = _services.GetRequiredService<RecruitService>();
7273
}
7374
return Task.CompletedTask;
7475
};

DiscordBot/Services/FeedService.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace DiscordBot.Services;
99

1010
public class FeedService
1111
{
12+
private const string ServiceName = "FeedService";
1213
private readonly DiscordSocketClient _client;
1314

1415
private readonly BotSettings _settings;
@@ -72,13 +73,12 @@ private async Task<SyndicationFeed> GetFeedData(string url)
7273
var client = new HttpClient();
7374
var response = await client.GetStringAsync(url);
7475
response = Utils.Utils.SanitizeXml(response);
75-
XmlReader reader = new XmlTextReader(new StringReader(response));
76+
var reader = XmlReader.Create(new StringReader(response));
7677
feed = SyndicationFeed.Load(reader);
7778
}
7879
catch (Exception e)
7980
{
80-
LoggingService.LogToConsole(e.ToString(), LogSeverity.Error);
81-
await _logging.LogAction($"Feed Service Error: {e.ToString()}", true, true);
81+
LoggingService.LogToConsole( $"[{ServiceName} Feed failure: {e.ToString()}", ExtendedLogSeverity.LowWarning);
8282
}
8383

8484
// Return the feed, empty feed if null to prevent additional checks for null on return
@@ -97,8 +97,8 @@ private async Task HandleFeed(FeedData feedData, ForumNewsFeed newsFeed, ulong c
9797
var channel = _client.GetChannel(channelId) as IForumChannel;
9898
if (channel == null)
9999
{
100-
await _logging.LogAction($"Feed Service Error: Channel {channelId} not found", true, true);
101-
LoggingService.LogToConsole($"Feed Service Error: Channel {channelId} not found", LogSeverity.Error);
100+
await _logging.LogAction($"[{ServiceName}] Error: Channel {channelId} not found", true, true);
101+
LoggingService.LogToConsole($"[{ServiceName}] Error: Channel {channelId} not found", LogSeverity.Error);
102102
return;
103103
}
104104
foreach (var item in feed.Items.Take(MaximumCheck))
@@ -110,7 +110,7 @@ private async Task HandleFeed(FeedData feedData, ForumNewsFeed newsFeed, ulong c
110110
// Title
111111
var newsTitle = string.Format(newsFeed.TitleFormat, item.Title.Text);
112112
if (newsTitle.Length > 90)
113-
newsTitle = newsTitle.Substring(0, 95) + "...";
113+
newsTitle = newsTitle[..90] + "...";
114114

115115
// Confirm we haven't posted this title before
116116
if (_postedFeeds.Contains(newsTitle))
@@ -126,8 +126,8 @@ private async Task HandleFeed(FeedData feedData, ForumNewsFeed newsFeed, ulong c
126126
var summary = Utils.Utils.RemoveHtmlTags(item.Summary.Text);
127127
newsContent = "**__Summary__**\n" + summary;
128128
// Unlikely to be over, but we need space for extra local info
129-
if (newsContent.Length > Constants.MaxLengthChannelMessage - 100)
130-
newsContent = newsContent.Substring(0, Constants.MaxLengthChannelMessage - 100) + "...";
129+
if (newsContent.Length > Constants.MaxLengthChannelMessage - 400)
130+
newsContent = newsContent[..(Constants.MaxLengthChannelMessage - 400)] + "...";
131131
}
132132
// If a role is provided we add to end of title to ping the role
133133
var role = _client.GetGuild(_settings.GuildId).GetRole(roleId ?? 0);
@@ -140,7 +140,7 @@ private async Task HandleFeed(FeedData feedData, ForumNewsFeed newsFeed, ulong c
140140
// The Post
141141
var post = await channel.CreatePostAsync(newsTitle, ForumArchiveDuration, null, newsContent, null, null, AllowedMentions.All);
142142
// If any tags, include them
143-
if (newsFeed.IncludeTags != null && newsFeed.IncludeTags.Count > 0)
143+
if (newsFeed.IncludeTags is { Count: > 0 })
144144
{
145145
var includedTags = new List<ulong>();
146146
foreach (var tag in newsFeed.IncludeTags)
@@ -157,7 +157,7 @@ private async Task HandleFeed(FeedData feedData, ForumNewsFeed newsFeed, ulong c
157157
catch (Exception e)
158158
{
159159
LoggingService.LogToConsole(e.ToString(), LogSeverity.Error);
160-
await _logging.LogAction($"Feed Service Error: {e.ToString()}", true, true);
160+
await _logging.LogAction($"[{ServiceName}] Error: {e.ToString()}", true, true);
161161
}
162162
}
163163

DiscordBot/Services/Recruitment/RecruitService.cs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class RecruitService
2929
private Color WarningMessageColor => new (255, 255, 100);
3030
private Color EditedMessageColor => new (100, 255, 100);
3131

32-
private const int TimeBeforeDeletingForumInSec = 30;
32+
private const int TimeBeforeDeletingForumInSec = 60;
3333
private const string _messageToBeDeleted = "Your thread will be deleted in %s because it did not follow the expected guidelines. Try again after the slow mode period has passed.";
3434

3535
private const int MinimumLengthMessage = 120;
@@ -97,6 +97,7 @@ public RecruitService(DiscordSocketClient client, ILoggingService logging, BotSe
9797

9898
// Subscribe to events
9999
_client.ThreadCreated += GatewayOnThreadCreated;
100+
_client.MessageReceived += GatewayOnMessageReceived;
100101

101102
ConstructEmbeds();
102103

@@ -138,7 +139,7 @@ private async Task GatewayOnThreadCreated(SocketThreadChannel thread)
138139

139140
Task.Run(async () =>
140141
{
141-
if (thread.AppliedTags.Count == 0)
142+
if (!DoesThreadHaveAValidTag(thread))
142143
{
143144
await ThreadHandleNoTags(thread);
144145
return;
@@ -191,6 +192,27 @@ private async Task GatewayOnThreadCreated(SocketThreadChannel thread)
191192
}
192193
});
193194
}
195+
196+
private async Task GatewayOnMessageReceived(SocketMessage message)
197+
{
198+
var thread = message.Channel as SocketThreadChannel;
199+
// check if channel is a thread in a forum
200+
if (thread == null)
201+
return;
202+
203+
if (!thread.IsThreadInChannel(_recruitChannel.Id))
204+
return;
205+
if (message.Author.IsUserBotOrWebhook())
206+
return;
207+
if (message.Author.HasRoleGroup(ModeratorRole))
208+
return;
209+
210+
// Sanity process, delete any new messages that aren't written from the thread owner, moderators or bots.
211+
if (message.Author.Id != thread.Owner.Id)
212+
{
213+
await message.DeleteAsync();
214+
}
215+
}
194216

195217
#endregion // Thread Creation
196218

@@ -241,8 +263,11 @@ private async Task GrantEditPermissions(SocketThreadChannel thread)
241263
await parentChannel.AddPermissionOverwriteAsync(thread.Owner, new OverwritePermissions(sendMessages: PermValue.Allow));
242264

243265
// We give them a bit of time to edit their post, then remove the permission
244-
await message.DeleteAfterSeconds((_editTimePermissionInMin * 60) + 5);
266+
await message.DeleteAfterSeconds((_editTimePermissionInMin * 60) + 2);
245267
await parentChannel.RemovePermissionOverwriteAsync(thread.Owner);
268+
269+
// Lock the thread so anyone else can't post even when they have edit permissions
270+
await thread.ModifyAsync(x => x.Locked = true);
246271
}
247272

248273
#endregion // Basic Handlers for posts
@@ -347,6 +372,12 @@ private bool IsThreadUsingMoreThanOneTag(SocketThreadChannel thread)
347372

348373
return clashingTagCount > 1;
349374
}
375+
376+
private bool DoesThreadHaveAValidTag(SocketThreadChannel thread)
377+
{
378+
var tags = thread.AppliedTags;
379+
return tags.Contains(_tagIsHiring.Id) || tags.Contains(_tagWantsWork.Id) || tags.Contains(_tagUnpaidCollab.Id);
380+
}
350381

351382
private async Task DeleteThread(SocketThreadChannel thread)
352383
{

DiscordBot/Services/ReminderService.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ public class ReminderService
2828
private readonly BotCommandsChannel _botCommandsChannel;
2929
private bool _hasChangedSinceLastSave = false;
3030

31-
private int _maxUserReminders = 5;
32-
31+
private const int _maxUserReminders = 10;
32+
3333
public ReminderService(DiscordSocketClient client, ILoggingService loggingService, BotSettings settings)
3434
{
3535
_client = client;
@@ -160,7 +160,9 @@ private async Task CheckReminders()
160160
// If channel is null we get the bot command channel, and send the message there
161161
channel ??= _client.GetChannel(_botCommandsChannel.Id) as SocketTextChannel;
162162
var user = _client.GetUser(reminder.UserId);
163-
if (user != null)
163+
if (user == null) continue;
164+
165+
if (channel != null)
164166
await channel.SendMessageAsync(
165167
$"{user.Mention} reminder: \"{reminder.Message}\"");
166168
}

DiscordBot/Utils/StringUtil.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace DiscordBot.Utils;
55
public static class StringUtil
66
{
77
private static readonly Regex CurrencyRegex =
8-
new (@"(?:\$\s*\d+|\d+\s*\$|\d*\s*(?:USD|£|pounds|€|EUR|euro|euros|GBP))", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
8+
new (@"(?:\$\s*\d+|\d+\s*\$|\d*\s*(?:USD|£|pounds|€|EUR|euro|euros|GBP|円|YEN))", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
99
private static readonly Regex RevShareRegex = new (@"\b(?:rev-share|revshare|rev share)\b", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
1010

1111
// a string extension that checks if the contents of the string contains a limited selection of currency symbols/words

0 commit comments

Comments
 (0)