Skip to content

Commit

Permalink
Updated with slash commands
Browse files Browse the repository at this point in the history
  • Loading branch information
PizzaConsole committed Jun 6, 2023
1 parent 29972c6 commit db7d734
Show file tree
Hide file tree
Showing 3 changed files with 291 additions and 11 deletions.
277 changes: 277 additions & 0 deletions Commands/SlashCommands.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
using CsvHelper;
using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.Interactivity.Extensions;
using DSharpPlus.SlashCommands;
using System.Globalization;
using System.Threading.Channels;
using static DSharpPlus.Entities.DiscordEmbedBuilder;

namespace PoisnCopy;

public class SlashCommands : ApplicationCommandModule
{
[SlashCommand("copychannel", "Copy a channel")]
public async Task CopyChannel(InteractionContext ctx)
{
try
{
await ctx.DeferAsync();

var textChannels = ctx.Guild.Channels
.Where(i => i.Value.Type == ChannelType.Text)
.ToList();
List<string> messages = new() { "Here is your list of channels:" };

foreach (var txtChan in textChannels)
{
messages.Add($"`{txtChan.Value.Id}-{txtChan.Value.Name}`");
}

messages.Add("**--Thats all of the channels!--**");
messages.Add(
$"Copy command: `/loadchannel` server_id:`{ctx.Guild.Id}` channel_id:`###`"
);
messages.Add(
$"Export command: `/exportchannel` server_id:`{ctx.Guild.Id}` channel_id:`###`"
);
await ctx.EditResponseAsync(
new DiscordWebhookBuilder().WithContent(string.Join("\n", messages))
);
}
catch (Exception e)
{
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent(e.Message));
return;
}
}

[SlashCommand("loadchannel", "Load a copied channel")]
public async Task LoadChannel(
InteractionContext ctx,
[Option("server_id", "Originating Server ID")] string server_id,
[Option("channel_id", "Channel ID")] string channel_id,
[Option("new_channel_name", "The name of the new channel to create")]
string new_channel_name
)
{
try
{
var chanParsed = ulong.TryParse(channel_id, out ulong chan_id);

if (!chanParsed)
{
await ctx.CreateResponseAsync("Invalid Channel ID");

return;
}

var serverParsed = ulong.TryParse(server_id, out ulong serv_id);

if (!serverParsed)
{
await ctx.CreateResponseAsync("Invalid Server ID");

return;
}

var guild = await ctx.Client.GetGuildAsync(serv_id);
var selectedChannel = guild.GetChannel(chan_id);

await ctx.CreateResponseAsync("Collecting messages...");

await ctx.Channel.TriggerTypingAsync();
var messag = await selectedChannel.GetMessagesAsync();

var messCopy = messag.ToList();
var more = await selectedChannel.GetMessagesAsync(100);

while (more.Count > 0)
{
messCopy.AddRange(more);
await Task.Delay(800);
more = await selectedChannel.GetMessagesBeforeAsync(more.LastOrDefault().Id, 100);
}

await ctx.EditResponseAsync(
new DiscordWebhookBuilder().WithContent("Organizing messages...")
);

messCopy.Reverse();

await ctx.EditResponseAsync(
new DiscordWebhookBuilder().WithContent("Creating channel...")
);

var newChan = await ctx.Guild.CreateChannelAsync(
new_channel_name,
selectedChannel.Type
);

await ctx.EditResponseAsync(
new DiscordWebhookBuilder().WithContent(
$"Posting {messCopy.Count} messages... (this could take awhile)"
)
);

foreach (var mes in messCopy)
{
if (!string.IsNullOrEmpty(mes.Content))
{
var whAu = new EmbedAuthor
{
Name = mes.Author.Username,
IconUrl = mes.Author.AvatarUrl
};
var what = new DiscordEmbedBuilder
{
Description = mes.Content,
Author = whAu,
Timestamp = mes.Timestamp
};

await newChan.SendMessageAsync(what);
await Task.Delay(800);
}

if (mes.Attachments.Count > 0)
{
foreach (var att in mes.Attachments)
{
var whAu = new EmbedAuthor
{
Name = mes.Author.Username,
IconUrl = mes.Author.AvatarUrl
};
var what = new DiscordEmbedBuilder
{
ImageUrl = att.Url,
Author = whAu,
Timestamp = mes.Timestamp
};

await newChan.SendMessageAsync(what);
await Task.Delay(800);
}
}
}

await ctx.FollowUpAsync(
new DiscordFollowupMessageBuilder().WithContent($"{newChan.Name} copy complete!")
);
}
catch (Exception e)
{
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent(e.Message));
return;
}
}

[SlashCommand("exportchannel", "Export a copied channel")]
public async Task ExportChannel(
InteractionContext ctx,
[Option("server_id", "Originating Server ID")] string server_id,
[Option("channel_id", "Channel ID")] string channel_id
)
{
try
{
var chanParsed = ulong.TryParse(channel_id, out ulong chan_id);

if (!chanParsed)
{
await ctx.CreateResponseAsync("Invalid Channel ID");

return;
}

var serverParsed = ulong.TryParse(server_id, out ulong serv_id);

if (!serverParsed)
{
await ctx.CreateResponseAsync("Invalid Server ID");

return;
}

var guild = await ctx.Client.GetGuildAsync(serv_id);
var selectedChannel = guild.GetChannel(chan_id);

await ctx.CreateResponseAsync("Collecting messages...");

await ctx.Channel.TriggerTypingAsync();
var messag = await selectedChannel.GetMessagesAsync();

var messCopy = messag.ToList();
var more = await selectedChannel.GetMessagesAsync(100);

while (more.Count > 0)
{
messCopy.AddRange(more);
await Task.Delay(800);
more = await selectedChannel.GetMessagesBeforeAsync(more.LastOrDefault().Id, 100);
}

await ctx.EditResponseAsync(
new DiscordWebhookBuilder().WithContent("Organizing messages...")
);

messCopy.Reverse();
var messageExports = new List<MessageExport>();

await ctx.EditResponseAsync(
new DiscordWebhookBuilder().WithContent(
$"Exporting {messCopy.Count} messages... (this could take awhile)"
)
);

foreach (var mes in messCopy)
{
if (!string.IsNullOrEmpty(mes.Content))
{
var textMessage = new MessageExport
{
AuthorName = mes.Author.Username,
IconUrl = mes.Author.AvatarUrl,
MessageConent = mes.Content,
Timestamp = mes.Timestamp.ToString("o")
};
messageExports.Add(textMessage);
}

if (mes.Attachments.Count > 0)
{
foreach (var att in mes.Attachments)
{
var imageMessage = new MessageExport
{
AuthorName = mes.Author.Username,
IconUrl = mes.Author.AvatarUrl,
MessageConent = att.Url,
Timestamp = mes.Timestamp.ToString("o")
};
messageExports.Add(imageMessage);
}
}
}

using var memStream = new MemoryStream();
using var writer = new StreamWriter(memStream);
using var csv = new CsvWriter(writer, CultureInfo.InvariantCulture);
csv.WriteRecords(messageExports);
await writer.FlushAsync();
memStream.Position = 0;
var fileMessage = new DiscordFollowupMessageBuilder().WithContent(
$"{selectedChannel.Name} export complete!"
);
fileMessage.AddFile($"{selectedChannel.Name}-export.csv", memStream, true);

await ctx.FollowUpAsync(fileMessage);
}
catch (Exception e)
{
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent(e.Message));
return;
}
}
}
1 change: 1 addition & 0 deletions PoisnCopy.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

<ItemGroup>
<PackageReference Include="CsvHelper" Version="30.0.1" />
<PackageReference Include="DSharpPlus.SlashCommands" Version="4.4.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
Expand Down
24 changes: 13 additions & 11 deletions Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using DSharpPlus.Interactivity;
using DSharpPlus.Interactivity.Enums;
using DSharpPlus.Interactivity.Extensions;
using DSharpPlus.SlashCommands;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

Expand All @@ -21,8 +22,6 @@ internal class Program
private CommandsNextExtension _commands;
private InteractivityExtension _interactivity;

/* Use the async main to create an instance of the class and await it(async main is only available in C# 7.1 onwards). */

private static async Task Main(string[] args) => await new Program().InitBot(args);

private async Task InitBot(string[] args)
Expand Down Expand Up @@ -54,9 +53,9 @@ private async Task InitBot(string[] args)
_interactivity = _discord.UseInteractivity(
new InteractivityConfiguration()
{
PaginationBehaviour = PaginationBehaviour.WrapAround, // What to do when a pagination request times out
PaginationDeletion = PaginationDeletion.DeleteMessage, // How long to wait before timing out
Timeout = TimeSpan.FromSeconds(30) // Default time to wait for interactive commands like waiting for a message or a reaction
PaginationBehaviour = PaginationBehaviour.WrapAround,
PaginationDeletion = PaginationDeletion.DeleteMessage,
Timeout = TimeSpan.FromSeconds(30)
}
);

Expand All @@ -68,21 +67,24 @@ private async Task InitBot(string[] args)
StringPrefixes = new List<string>
{
_config.GetValue<string>("discord:CommandPrefix")
}, // Load the command prefix(what comes before the command, eg "!" or "/") from our config file
},
Services = services,
EnableDms = false
}
);
var slash = _discord.UseSlashCommands();

slash.RegisterCommands<SlashCommands>();

Console.WriteLine("[info] Loading command modules..");

var type = typeof(IModule); // Get the type of our interface
var type = typeof(IModule);
var types = AppDomain.CurrentDomain
.GetAssemblies() // Get the assemblies associated with our project
.SelectMany(s => s.GetTypes()) // Get all the types
.Where(p => type.IsAssignableFrom(p) && !p.IsInterface); // Filter to find any type that can be assigned to an IModule
.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p) && !p.IsInterface);

var typeList = types as Type[] ?? types.ToArray(); // Convert to an array
var typeList = types as Type[] ?? types.ToArray();
foreach (var t in typeList)
{
_commands.RegisterCommands(t);
Expand Down

0 comments on commit db7d734

Please sign in to comment.