public async Task HandleMessageReceivedAsync(SocketMessage message) { var shiftCodesSettings = _settings.ShiftCodes; if (shiftCodesSettings != null && shiftCodesSettings.IsRepostEnabled && shiftCodesSettings.SourceChannelId.GetValueOrDefault() == message.Channel.Id && message.Author.IsBot && shiftCodesSettings.SourceUserId == message.Author.Id) { var guild = (message.Channel as SocketGuildChannel)?.Guild; if (guild == null) { throw new Exception("Can't get the Guild from the message's channel."); } var destinationChannel = guild.GetTextChannel(_settings.ShiftCodes.RepostChannelId.GetValueOrDefault()); if (destinationChannel == null) { _logger.LogError( "Can't find a channel with ID {repostChannelId} to repost the SHiFT code message. Check the ID in the config.", _settings.ShiftCodes.RepostChannelId.GetValueOrDefault()); return; } var hasExpiry = ExpiredCodesHelpers.TryGetExpirationDateFromMessage(message, _logger, out var embed, out var expiry); var content = message.Content; if (hasExpiry) { content += $"\nThis code expires {expiry.ToDiscordMessageTs(TimestampFormat.LongDateTime)} " + $"({expiry.ToDiscordMessageTs(TimestampFormat.RelativeTime)})."; } await destinationChannel.SendMessageAsync(content, embed : embed); if (_settings.ShiftCodes.DeleteMessageInSourceChannelAfterRepost.GetValueOrDefault()) { await Task.Delay(Constants.DelayAfterCommand); await message.DeleteAsync(); } } }
public async Task RunTaskAsync(DiscordSocketClient client, IReadOnlyDictionary <string, object> taskSettings, CancellationToken cancellationToken) { if (client is null) { throw new ArgumentNullException(nameof(client)); } if (taskSettings is null) { throw new ArgumentNullException(nameof(taskSettings)); } try { var guildIdStr = (string)taskSettings[SettingsKeyGuildId] ?? throw new Exception( $"Setting with key \"{nameof(SettingsKeyGuildId)}\" missing from {nameof(DeleteExpiredShiftCodesTask)} settings."); var guildId = ulong.Parse(guildIdStr); var guild = client.GetGuild(guildId); var channelIdStr = (string)taskSettings[SettingsKeyChannelId] ?? throw new Exception( $"Setting with key \"{nameof(SettingsKeyChannelId)}\" missing from {nameof(DeleteExpiredShiftCodesTask)} settings."); var channelId = ulong.Parse(channelIdStr); var channel = guild.GetTextChannel(channelId); taskSettings.TryGetValue(SettingsKeyReportToChannelId, out var reportToChannelIdVal); var reportToChannelIdStr = reportToChannelIdVal as string; SocketTextChannel?reportToChannel = null; if (!string.IsNullOrEmpty(reportToChannelIdStr)) { var reportToChannelId = ulong.Parse(reportToChannelIdStr); reportToChannel = guild.GetTextChannel(reportToChannelId); } var messages = (await channel.GetMessagesAsync(BatchSize) .FlattenAsync()) .ToList(); if (messages.Any()) { var messagesToDelete = ExpiredCodesHelpers.GetMessagesWithExpiredCodes(messages, _logger); var plural = messagesToDelete.Count == 1 ? "" : "s"; _logger.LogInformation("Found {count} message{s} with expired codes to delete.", messagesToDelete.Count, plural); // Only messages < 14 days old can be bulk deleted. var bulkDeletableMessages = new List <IMessage>(); var singleDeletableMessages = new List <IMessage>(); foreach (var message in messagesToDelete) { var bulkDeleteCutoff = DateTimeOffset.Now.AddMinutes(5).AddDays(-14); if (message.Timestamp >= bulkDeleteCutoff) { bulkDeletableMessages.Add(message); } else { singleDeletableMessages.Add(message); } } if (bulkDeletableMessages.Any()) { await channel.DeleteMessagesAsync(bulkDeletableMessages); await Task.Delay(Constants.DelayAfterCommandMs); } foreach (var singleDeletableMessage in singleDeletableMessages) { await channel.DeleteMessageAsync(singleDeletableMessage); await Task.Delay(Constants.DelayAfterCommandMs); } if (messagesToDelete.Count > 0 && reportToChannel != null) { await reportToChannel.SendMessageAsync($"Deleted {messagesToDelete.Count} expired code{plural} in {channel.ToMessageRef()}."); await Task.Delay(Constants.DelayAfterCommandMs); } } } catch (Exception e) { _logger.LogError(e, "Error trying to prune expired messages :("); } }