DiscordClient/DiscordDelete/Program.cs
2024-06-18 20:20:47 +02:00

142 lines
4.8 KiB
C#

using CommandLine;
using DiscordClient;
using DiscordDelete;
using Microsoft.Extensions.Configuration;
IConfiguration configuration = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile("config.json", true)
.AddXmlFile("config.xml", true)
.Build();
string? token = configuration.GetSection("Token").Value;
if (token is null)
{
Console.WriteLine("Token has not been found in any form of configuration.");
return;
}
DiscordContext db = new DiscordContext();
DiscordUserClient client = new DiscordUserClient(token);
static async Task TooManyRequestsDelay()
{
int seconds = 60;
Console.WriteLine($"Too many requests. Sleeping for extra {seconds} seconds.");
await Task.Delay(TimeSpan.FromSeconds(seconds));
}
int finalCode = await CommandLine
.Parser.Default.ParseArguments<DeleteOptions, ScanOptions>(args)
.MapResult(
async (DeleteOptions opt) =>
{
foreach (
Message message in db
.Messages
// Skip ones that are already deleted.
.Where(message => message.LastHttpCode != 204)
// Skip BadRequest (such as archived thread).
.Where(message => message.LastHttpCode != 400)
// Skip NotFound.
.Where(message => message.LastHttpCode != 404)
)
{
// If required data is null, continue to next message.
if (message.MessageId is null || message.ChannelId is null)
continue;
HttpResponseMessage response = await client.DeleteMessage(
message.ChannelId,
message.MessageId
);
message.LastHttpCode = (int)response.StatusCode;
Console.WriteLine(
$"{(response.IsSuccessStatusCode ? "" : "")} {message.Id} - Deleting {message.MessageId} - {response.StatusCode}"
);
if (response.StatusCode == System.Net.HttpStatusCode.TooManyRequests)
{
await TooManyRequestsDelay();
}
db.Update(message);
await db.SaveChangesAsync();
await Task.Delay(TimeSpan.FromSeconds(2));
}
return 0;
},
async (ScanOptions opt) =>
{
if (opt.Author is null)
{
Console.WriteLine("Author ID is null. Default to this user being author.");
opt.Author = client.MyDiscordId;
}
int totalMessages = 1;
int offset = 0;
while (offset < totalMessages)
{
var searchResponse = opt.GuildId is null
? await client.GetChannelMessages(opt.ChannelId, offset, opt.Author)
: await client.SearchGuildMessages(opt.GuildId, offset, opt.Author);
Console.WriteLine(
$"Scan code at offset {offset}: {searchResponse.HttpResponse.StatusCode}."
);
if (!searchResponse.HttpResponse.IsSuccessStatusCode)
{
continue;
}
if (
searchResponse.HttpResponse.StatusCode
== System.Net.HttpStatusCode.TooManyRequests
)
{
await TooManyRequestsDelay();
continue;
}
if (searchResponse.DeserializedData is null)
return 2;
totalMessages = searchResponse.DeserializedData.TotalMessages;
IEnumerable<Message> newMessages =
searchResponse.DeserializedData.Messages.SelectMany(message =>
message.Select(messagePart => new Message
{
ChannelId = messagePart.ChannelId,
MessageId = messagePart.Id,
Content = messagePart.Content
})
);
foreach (var newMessage in newMessages)
{
if (!db.Messages.Any(message => message.MessageId == newMessage.MessageId))
await db.AddAsync(newMessage);
}
await db.SaveChangesAsync();
offset += searchResponse.DeserializedData.Messages.Length;
Console.WriteLine(
$"Written {searchResponse.DeserializedData.Messages.Length} messages. {offset} / {totalMessages}"
);
await Task.Delay(TimeSpan.FromSeconds(2));
}
return 0;
},
errs => Task.FromResult(0)
);