Update sample projects & samples in docs (#2823)
* update them all * more docs * moar docs
This commit is contained in:
@@ -3,10 +3,8 @@ using Discord.WebSocket;
|
|||||||
|
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
private DiscordSocketClient _client;
|
private static DiscordSocketClient _client;
|
||||||
static void Main(string[] args) => new Program().MainAsync().GetAwaiter().GetResult();
|
public static async Task MainAsync()
|
||||||
|
|
||||||
public async Task MainAsync()
|
|
||||||
{
|
{
|
||||||
// When working with events that have Cacheable<IMessage, ulong> parameters,
|
// When working with events that have Cacheable<IMessage, ulong> parameters,
|
||||||
// you must enable the message cache in your config settings if you plan to
|
// you must enable the message cache in your config settings if you plan to
|
||||||
@@ -27,7 +25,7 @@ public class Program
|
|||||||
await Task.Delay(-1);
|
await Task.Delay(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task MessageUpdated(Cacheable<IMessage, ulong> before, SocketMessage after, ISocketMessageChannel channel)
|
private static async Task MessageUpdated(Cacheable<IMessage, ulong> before, SocketMessage after, ISocketMessageChannel channel)
|
||||||
{
|
{
|
||||||
// If the message was not in the cache, downloading it will result in getting a copy of `after`.
|
// If the message was not in the cache, downloading it will result in getting a copy of `after`.
|
||||||
var message = await before.GetOrDownloadAsync();
|
var message = await before.GetOrDownloadAsync();
|
||||||
|
|||||||
@@ -1,14 +1,6 @@
|
|||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
private readonly IServiceProvider _serviceProvider;
|
private static IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
public Program()
|
|
||||||
{
|
|
||||||
_serviceProvider = CreateProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Main(string[] args)
|
|
||||||
=> new Program().RunAsync(args).GetAwaiter().GetResult();
|
|
||||||
|
|
||||||
static IServiceProvider CreateProvider()
|
static IServiceProvider CreateProvider()
|
||||||
{
|
{
|
||||||
@@ -17,8 +9,8 @@ public class Program
|
|||||||
return collection.BuildServiceProvider();
|
return collection.BuildServiceProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task RunAsync(string[] args)
|
static async Task Main(string[] args)
|
||||||
{
|
{
|
||||||
//...
|
_serviceProvider = CreateProvider();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
public static Task Main(string[] args) => new Program().MainAsync();
|
public static async Task Main()
|
||||||
|
|
||||||
public async Task MainAsync()
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
private DiscordSocketClient _client;
|
private static DiscordSocketClient _client;
|
||||||
|
|
||||||
public async Task MainAsync()
|
public static async Task Main()
|
||||||
{
|
{
|
||||||
_client = new DiscordSocketClient();
|
_client = new DiscordSocketClient();
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
private DiscordSocketClient _client;
|
private static DiscordSocketClient _client;
|
||||||
|
|
||||||
public static Task Main(string[] args) => new Program().MainAsync();
|
public async Task Main()
|
||||||
|
|
||||||
public async Task MainAsync()
|
|
||||||
{
|
{
|
||||||
_client = new DiscordSocketClient();
|
_client = new DiscordSocketClient();
|
||||||
_client.Log += Log;
|
_client.Log += Log;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
private Task Log(LogMessage msg)
|
private static Task Log(LogMessage msg)
|
||||||
{
|
{
|
||||||
Console.WriteLine(msg.ToString());
|
Console.WriteLine(msg.ToString());
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
public async Task MainAsync()
|
public static async Task Main()
|
||||||
{
|
{
|
||||||
// ...
|
// ...
|
||||||
_client.MessageReceived += MessageReceived;
|
_client.MessageReceived += MessageReceived;
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task MessageReceived(SocketMessage message)
|
private static async Task MessageReceived(SocketMessage message)
|
||||||
{
|
{
|
||||||
if (message.Content == "!ping")
|
if (message.Content == "!ping")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,21 +10,7 @@ using Discord.WebSocket;
|
|||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
// Program entry point
|
// Program entry point
|
||||||
static Task Main(string[] args)
|
static async Task Main(string[] args)
|
||||||
{
|
|
||||||
// Call the Program constructor, followed by the
|
|
||||||
// MainAsync method and wait until it finishes (which should be never).
|
|
||||||
return new Program().MainAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly DiscordSocketClient _client;
|
|
||||||
|
|
||||||
// Keep the CommandService and DI container around for use with commands.
|
|
||||||
// These two types require you install the Discord.Net.Commands package.
|
|
||||||
private readonly CommandService _commands;
|
|
||||||
private readonly IServiceProvider _services;
|
|
||||||
|
|
||||||
private Program()
|
|
||||||
{
|
{
|
||||||
_client = new DiscordSocketClient(new DiscordSocketConfig
|
_client = new DiscordSocketClient(new DiscordSocketConfig
|
||||||
{
|
{
|
||||||
@@ -58,9 +44,15 @@ class Program
|
|||||||
|
|
||||||
// Setup your DI container.
|
// Setup your DI container.
|
||||||
_services = ConfigureServices();
|
_services = ConfigureServices();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static DiscordSocketClient _client;
|
||||||
|
|
||||||
|
// Keep the CommandService and DI container around for use with commands.
|
||||||
|
// These two types require you install the Discord.Net.Commands package.
|
||||||
|
private static CommandService _commands;
|
||||||
|
private static IServiceProvider _services;
|
||||||
|
|
||||||
// If any services require the client, or the CommandService, or something else you keep on hand,
|
// If any services require the client, or the CommandService, or something else you keep on hand,
|
||||||
// pass them as parameters into this method as needed.
|
// pass them as parameters into this method as needed.
|
||||||
// If this method is getting pretty long, you can seperate it out into another file using partials.
|
// If this method is getting pretty long, you can seperate it out into another file using partials.
|
||||||
@@ -110,7 +102,7 @@ class Program
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task MainAsync()
|
private static async Task MainAsync()
|
||||||
{
|
{
|
||||||
// Centralize the logic for commands into a separate method.
|
// Centralize the logic for commands into a separate method.
|
||||||
await InitCommands();
|
await InitCommands();
|
||||||
@@ -125,7 +117,7 @@ class Program
|
|||||||
await Task.Delay(Timeout.Infinite);
|
await Task.Delay(Timeout.Infinite);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InitCommands()
|
private static async Task InitCommands()
|
||||||
{
|
{
|
||||||
// Either search the program and add all Module classes that can be found.
|
// Either search the program and add all Module classes that can be found.
|
||||||
// Module classes MUST be marked 'public' or they will be ignored.
|
// Module classes MUST be marked 'public' or they will be ignored.
|
||||||
@@ -140,7 +132,7 @@ class Program
|
|||||||
_client.MessageReceived += HandleCommandAsync;
|
_client.MessageReceived += HandleCommandAsync;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HandleCommandAsync(SocketMessage arg)
|
private static async Task HandleCommandAsync(SocketMessage arg)
|
||||||
{
|
{
|
||||||
// Bail out if it's a System Message.
|
// Bail out if it's a System Message.
|
||||||
var msg = arg as SocketUserMessage;
|
var msg = arg as SocketUserMessage;
|
||||||
|
|||||||
@@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Discord.Net" Version="2.0.0" />
|
<PackageReference Include="Discord.Net" Version="3.13.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ using System;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace BasicBot
|
namespace BasicBot;
|
||||||
{
|
|
||||||
// This is a minimal, bare-bones example of using Discord.Net.
|
// This is a minimal, bare-bones example of using Discord.Net.
|
||||||
//
|
//
|
||||||
// If writing a bot with commands/interactions, we recommend using the Discord.Net.Commands/Discord.Net.Interactions
|
// If writing a bot with commands/interactions, we recommend using the Discord.Net.Commands/Discord.Net.Interactions
|
||||||
@@ -22,20 +22,15 @@ namespace BasicBot
|
|||||||
{
|
{
|
||||||
// Non-static readonly fields can only be assigned in a constructor.
|
// Non-static readonly fields can only be assigned in a constructor.
|
||||||
// If you want to assign it elsewhere, consider removing the readonly keyword.
|
// If you want to assign it elsewhere, consider removing the readonly keyword.
|
||||||
private readonly DiscordSocketClient _client;
|
private static DiscordSocketClient _client;
|
||||||
|
|
||||||
// Discord.Net heavily utilizes TAP for async, so we create
|
// Discord.Net heavily utilizes TAP for async, so we create
|
||||||
// an asynchronous context from the beginning.
|
// an asynchronous context from the beginning.
|
||||||
static void Main(string[] args)
|
public static async Task Main(string[] args)
|
||||||
=> new Program()
|
|
||||||
.MainAsync()
|
|
||||||
.GetAwaiter()
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
public Program()
|
|
||||||
{
|
{
|
||||||
// Config used by DiscordSocketClient
|
// Config used by DiscordSocketClient
|
||||||
// Define intents for the client
|
// Define intents for the client
|
||||||
|
// Note that GatewayIntents.MessageContent is a privileged intent, and requires extra setup in the developer portal.
|
||||||
var config = new DiscordSocketConfig
|
var config = new DiscordSocketConfig
|
||||||
{
|
{
|
||||||
GatewayIntents = GatewayIntents.AllUnprivileged | GatewayIntents.MessageContent
|
GatewayIntents = GatewayIntents.AllUnprivileged | GatewayIntents.MessageContent
|
||||||
@@ -50,10 +45,8 @@ namespace BasicBot
|
|||||||
_client.Ready += ReadyAsync;
|
_client.Ready += ReadyAsync;
|
||||||
_client.MessageReceived += MessageReceivedAsync;
|
_client.MessageReceived += MessageReceivedAsync;
|
||||||
_client.InteractionCreated += InteractionCreatedAsync;
|
_client.InteractionCreated += InteractionCreatedAsync;
|
||||||
}
|
|
||||||
|
|
||||||
public async Task MainAsync()
|
|
||||||
{
|
|
||||||
// Tokens should be considered secret data, and never hard-coded.
|
// Tokens should be considered secret data, and never hard-coded.
|
||||||
await _client.LoginAsync(TokenType.Bot, Environment.GetEnvironmentVariable("token"));
|
await _client.LoginAsync(TokenType.Bot, Environment.GetEnvironmentVariable("token"));
|
||||||
// Different approaches to making your token a secret is by putting them in local .json, .yaml, .xml or .txt files, then reading them on startup.
|
// Different approaches to making your token a secret is by putting them in local .json, .yaml, .xml or .txt files, then reading them on startup.
|
||||||
@@ -64,7 +57,7 @@ namespace BasicBot
|
|||||||
await Task.Delay(Timeout.Infinite);
|
await Task.Delay(Timeout.Infinite);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task LogAsync(LogMessage log)
|
private static Task LogAsync(LogMessage log)
|
||||||
{
|
{
|
||||||
Console.WriteLine(log.ToString());
|
Console.WriteLine(log.ToString());
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
@@ -72,7 +65,7 @@ namespace BasicBot
|
|||||||
|
|
||||||
// The Ready event indicates that the client has opened a
|
// The Ready event indicates that the client has opened a
|
||||||
// connection and it is now safe to access the cache.
|
// connection and it is now safe to access the cache.
|
||||||
private Task ReadyAsync()
|
private static Task ReadyAsync()
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{_client.CurrentUser} is connected!");
|
Console.WriteLine($"{_client.CurrentUser} is connected!");
|
||||||
|
|
||||||
@@ -81,7 +74,7 @@ namespace BasicBot
|
|||||||
|
|
||||||
// This is not the recommended way to write a bot - consider
|
// This is not the recommended way to write a bot - consider
|
||||||
// reading over the Commands Framework sample.
|
// reading over the Commands Framework sample.
|
||||||
private async Task MessageReceivedAsync(SocketMessage message)
|
private static async Task MessageReceivedAsync(SocketMessage message)
|
||||||
{
|
{
|
||||||
// The bot should never respond to itself.
|
// The bot should never respond to itself.
|
||||||
if (message.Author.Id == _client.CurrentUser.Id)
|
if (message.Author.Id == _client.CurrentUser.Id)
|
||||||
@@ -102,7 +95,7 @@ namespace BasicBot
|
|||||||
|
|
||||||
// For better functionality & a more developer-friendly approach to handling any kind of interaction, refer to:
|
// For better functionality & a more developer-friendly approach to handling any kind of interaction, refer to:
|
||||||
// https://discordnet.dev/guides/int_framework/intro.html
|
// https://discordnet.dev/guides/int_framework/intro.html
|
||||||
private async Task InteractionCreatedAsync(SocketInteraction interaction)
|
private static async Task InteractionCreatedAsync(SocketInteraction interaction)
|
||||||
{
|
{
|
||||||
// safety-casting is the best way to prevent something being cast from being null.
|
// safety-casting is the best way to prevent something being cast from being null.
|
||||||
// If this check does not pass, it could not be cast to said type.
|
// If this check does not pass, it could not be cast to said type.
|
||||||
@@ -117,4 +110,3 @@ namespace BasicBot
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Discord.Net.WebSocket" Version="3.10.0"/>
|
<PackageReference Include="Discord.Net.WebSocket" Version="3.13.0"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ using Discord.WebSocket;
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace InteractionFramework.Attributes
|
namespace InteractionFramework.Attributes;
|
||||||
{
|
|
||||||
internal class DoUserCheck : PreconditionAttribute
|
internal class DoUserCheck : PreconditionAttribute
|
||||||
{
|
{
|
||||||
public override Task<PreconditionResult> CheckRequirementsAsync(IInteractionContext context, ICommandInfo commandInfo, IServiceProvider services)
|
public override Task<PreconditionResult> CheckRequirementsAsync(IInteractionContext context, ICommandInfo commandInfo, IServiceProvider services)
|
||||||
@@ -14,8 +14,6 @@ namespace InteractionFramework.Attributes
|
|||||||
if (context.Interaction is not SocketMessageComponent componentContext)
|
if (context.Interaction is not SocketMessageComponent componentContext)
|
||||||
return Task.FromResult(PreconditionResult.FromError("Context unrecognized as component context."));
|
return Task.FromResult(PreconditionResult.FromError("Context unrecognized as component context."));
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// The approach here entirely depends on how you construct your custom ID. In this case, the format is:
|
// The approach here entirely depends on how you construct your custom ID. In this case, the format is:
|
||||||
// unique-name:*,*
|
// unique-name:*,*
|
||||||
|
|
||||||
@@ -30,9 +28,6 @@ namespace InteractionFramework.Attributes
|
|||||||
? Task.FromResult(PreconditionResult.FromSuccess())
|
? Task.FromResult(PreconditionResult.FromSuccess())
|
||||||
: Task.FromResult(PreconditionResult.FromError("User ID does not match component ID!"));
|
: Task.FromResult(PreconditionResult.FromError("User ID does not match component ID!"));
|
||||||
|
|
||||||
else
|
|
||||||
return Task.FromResult(PreconditionResult.FromError("Parse cannot be done if no userID exists."));
|
return Task.FromResult(PreconditionResult.FromError("Parse cannot be done if no userID exists."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
using Discord;
|
using Discord;
|
||||||
using Discord.Interactions;
|
using Discord.Interactions;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace InteractionFramework.Attributes
|
namespace InteractionFramework.Attributes;
|
||||||
{
|
|
||||||
public class RequireOwnerAttribute : PreconditionAttribute
|
public class RequireOwnerAttribute : PreconditionAttribute
|
||||||
{
|
{
|
||||||
public override async Task<PreconditionResult> CheckRequirementsAsync(IInteractionContext context, ICommandInfo commandInfo, IServiceProvider services)
|
public override async Task<PreconditionResult> CheckRequirementsAsync(IInteractionContext context, ICommandInfo commandInfo, IServiceProvider services)
|
||||||
@@ -16,12 +13,11 @@ namespace InteractionFramework.Attributes
|
|||||||
{
|
{
|
||||||
case TokenType.Bot:
|
case TokenType.Bot:
|
||||||
var application = await context.Client.GetApplicationInfoAsync().ConfigureAwait(false);
|
var application = await context.Client.GetApplicationInfoAsync().ConfigureAwait(false);
|
||||||
if (context.User.Id != application.Owner.Id)
|
return context.User.Id != application.Owner.Id
|
||||||
return PreconditionResult.FromError(ErrorMessage ?? "Command can only be run by the owner of the bot.");
|
? PreconditionResult.FromError(ErrorMessage ?? "Command can only be run by the owner of the bot.")
|
||||||
return PreconditionResult.FromSuccess();
|
: PreconditionResult.FromSuccess();
|
||||||
default:
|
default:
|
||||||
return PreconditionResult.FromError($"{nameof(RequireOwnerAttribute)} is not supported by this {nameof(TokenType)}.");
|
return PreconditionResult.FromError($"{nameof(RequireOwnerAttribute)} is not supported by this {nameof(TokenType)}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,13 +1,7 @@
|
|||||||
using Discord.Interactions;
|
using Discord.Interactions;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace InteractionFramework
|
namespace InteractionFramework;
|
||||||
{
|
|
||||||
public enum ExampleEnum
|
public enum ExampleEnum
|
||||||
{
|
{
|
||||||
First,
|
First,
|
||||||
@@ -17,4 +11,3 @@ namespace InteractionFramework
|
|||||||
[ChoiceDisplay("Twenty First")]
|
[ChoiceDisplay("Twenty First")]
|
||||||
TwentyFirst
|
TwentyFirst
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ using System;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace InteractionFramework
|
namespace InteractionFramework;
|
||||||
{
|
|
||||||
public class InteractionHandler
|
public class InteractionHandler
|
||||||
{
|
{
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
@@ -34,6 +34,9 @@ namespace InteractionFramework
|
|||||||
|
|
||||||
// Process the InteractionCreated payloads to execute Interactions commands
|
// Process the InteractionCreated payloads to execute Interactions commands
|
||||||
_client.InteractionCreated += HandleInteraction;
|
_client.InteractionCreated += HandleInteraction;
|
||||||
|
|
||||||
|
// Also process the result of the command execution.
|
||||||
|
_handler.InteractionExecuted += HandleInteractionExecute;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LogAsync(LogMessage log)
|
private async Task LogAsync(LogMessage log)
|
||||||
@@ -41,12 +44,9 @@ namespace InteractionFramework
|
|||||||
|
|
||||||
private async Task ReadyAsync()
|
private async Task ReadyAsync()
|
||||||
{
|
{
|
||||||
// Context & Slash commands can be automatically registered, but this process needs to happen after the client enters the READY state.
|
// Register the commands globally.
|
||||||
// Since Global Commands take around 1 hour to register, we should use a test guild to instantly update and test our commands.
|
// alternatively you can use _handler.RegisterCommandsGloballyAsync() to register commands to a specific guild.
|
||||||
if (Program.IsDebug())
|
await _handler.RegisterCommandsGloballyAsync();
|
||||||
await _handler.RegisterCommandsToGuildAsync(_configuration.GetValue<ulong>("testGuild"), true);
|
|
||||||
else
|
|
||||||
await _handler.RegisterCommandsGloballyAsync(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HandleInteraction(SocketInteraction interaction)
|
private async Task HandleInteraction(SocketInteraction interaction)
|
||||||
@@ -59,6 +59,8 @@ namespace InteractionFramework
|
|||||||
// Execute the incoming command.
|
// Execute the incoming command.
|
||||||
var result = await _handler.ExecuteCommandAsync(context, _services);
|
var result = await _handler.ExecuteCommandAsync(context, _services);
|
||||||
|
|
||||||
|
// Due to async nature of InteractionFramework, the result here may always be success.
|
||||||
|
// That's why we also need to handle the InteractionExecuted event.
|
||||||
if (!result.IsSuccess)
|
if (!result.IsSuccess)
|
||||||
switch (result.Error)
|
switch (result.Error)
|
||||||
{
|
{
|
||||||
@@ -77,5 +79,17 @@ namespace InteractionFramework
|
|||||||
await interaction.GetOriginalResponseAsync().ContinueWith(async (msg) => await msg.Result.DeleteAsync());
|
await interaction.GetOriginalResponseAsync().ContinueWith(async (msg) => await msg.Result.DeleteAsync());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task HandleInteractionExecute(ICommandInfo commandInfo, IInteractionContext context, IResult result)
|
||||||
|
{
|
||||||
|
if (!result.IsSuccess)
|
||||||
|
switch (result.Error)
|
||||||
|
{
|
||||||
|
case InteractionCommandError.UnmetPrecondition:
|
||||||
|
// implement
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ using InteractionFramework.Attributes;
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace InteractionFramework.Modules
|
namespace InteractionFramework.Modules;
|
||||||
{
|
|
||||||
// Interaction modules must be public and inherit from an IInteractionModuleBase
|
// Interaction modules must be public and inherit from an IInteractionModuleBase
|
||||||
public class ExampleModule : InteractionModuleBase<SocketInteractionContext>
|
public class ExampleModule : InteractionModuleBase<SocketInteractionContext>
|
||||||
{
|
{
|
||||||
@@ -97,4 +97,3 @@ namespace InteractionFramework.Modules
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,20 +7,20 @@ using System;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace InteractionFramework
|
namespace InteractionFramework;
|
||||||
{
|
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
private readonly IConfiguration _configuration;
|
private static IConfiguration _configuration;
|
||||||
private readonly IServiceProvider _services;
|
private static IServiceProvider _services;
|
||||||
|
|
||||||
private readonly DiscordSocketConfig _socketConfig = new()
|
private static readonly DiscordSocketConfig _socketConfig = new()
|
||||||
{
|
{
|
||||||
GatewayIntents = GatewayIntents.AllUnprivileged | GatewayIntents.GuildMembers,
|
GatewayIntents = GatewayIntents.AllUnprivileged | GatewayIntents.GuildMembers,
|
||||||
AlwaysDownloadUsers = true,
|
AlwaysDownloadUsers = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
public Program()
|
public static async Task Main(string[] args)
|
||||||
{
|
{
|
||||||
_configuration = new ConfigurationBuilder()
|
_configuration = new ConfigurationBuilder()
|
||||||
.AddEnvironmentVariables(prefix: "DC_")
|
.AddEnvironmentVariables(prefix: "DC_")
|
||||||
@@ -34,15 +34,7 @@ namespace InteractionFramework
|
|||||||
.AddSingleton(x => new InteractionService(x.GetRequiredService<DiscordSocketClient>()))
|
.AddSingleton(x => new InteractionService(x.GetRequiredService<DiscordSocketClient>()))
|
||||||
.AddSingleton<InteractionHandler>()
|
.AddSingleton<InteractionHandler>()
|
||||||
.BuildServiceProvider();
|
.BuildServiceProvider();
|
||||||
}
|
|
||||||
|
|
||||||
static void Main(string[] args)
|
|
||||||
=> new Program().RunAsync()
|
|
||||||
.GetAwaiter()
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
public async Task RunAsync()
|
|
||||||
{
|
|
||||||
var client = _services.GetRequiredService<DiscordSocketClient>();
|
var client = _services.GetRequiredService<DiscordSocketClient>();
|
||||||
|
|
||||||
client.Log += LogAsync;
|
client.Log += LogAsync;
|
||||||
@@ -59,16 +51,6 @@ namespace InteractionFramework
|
|||||||
await Task.Delay(Timeout.Infinite);
|
await Task.Delay(Timeout.Infinite);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LogAsync(LogMessage message)
|
private static async Task LogAsync(LogMessage message)
|
||||||
=> Console.WriteLine(message.ToString());
|
=> Console.WriteLine(message.ToString());
|
||||||
|
|
||||||
public static bool IsDebug()
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
|
||||||
<PackageReference Include="Discord.Net.Interactions" Version="3.10.0" />
|
<PackageReference Include="Discord.Net.Interactions" Version="3.13.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
using Discord.Interactions;
|
using Discord.Interactions;
|
||||||
using Discord.WebSocket;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ShardedClient.Modules
|
namespace ShardedClient.Modules;
|
||||||
{
|
|
||||||
// A display of portability, which shows how minimal the difference between the 2 frameworks is.
|
// A display of portability, which shows how minimal the difference between the 2 frameworks is.
|
||||||
public class InteractionModule : InteractionModuleBase<ShardedInteractionContext>
|
public class InteractionModule : InteractionModuleBase<ShardedInteractionContext>
|
||||||
{
|
{
|
||||||
@@ -15,4 +14,3 @@ namespace ShardedClient.Modules
|
|||||||
await RespondAsync(msg);
|
await RespondAsync(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ShardedClient.Modules
|
namespace ShardedClient.Modules;
|
||||||
{
|
|
||||||
// Remember to make your module reference the ShardedCommandContext
|
// Remember to make your module reference the ShardedCommandContext
|
||||||
public class PublicModule : ModuleBase<ShardedCommandContext>
|
public class PublicModule : ModuleBase<ShardedCommandContext>
|
||||||
{
|
{
|
||||||
@@ -14,4 +14,3 @@ namespace ShardedClient.Modules
|
|||||||
await ReplyAsync(msg);
|
await ReplyAsync(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,20 +8,14 @@ using System;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ShardedClient
|
namespace ShardedClient;
|
||||||
{
|
|
||||||
// This is a minimal example of using Discord.Net's Sharded Client
|
// This is a minimal example of using Discord.Net's Sharded Client
|
||||||
// The provided DiscordShardedClient class simplifies having multiple
|
// The provided DiscordShardedClient class simplifies having multiple
|
||||||
// DiscordSocketClient instances (or shards) to serve a large number of guilds.
|
// DiscordSocketClient instances (or shards) to serve a large number of guilds.
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
public static async Task Main(string[] args)
|
||||||
=> new Program()
|
|
||||||
.MainAsync()
|
|
||||||
.GetAwaiter()
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
public async Task MainAsync()
|
|
||||||
{
|
{
|
||||||
// You specify the amount of shards you'd like to have with the
|
// You specify the amount of shards you'd like to have with the
|
||||||
// DiscordSocketConfig. Generally, it's recommended to
|
// DiscordSocketConfig. Generally, it's recommended to
|
||||||
@@ -36,8 +30,8 @@ namespace ShardedClient
|
|||||||
// when you are finished using it, at the end of your app's lifetime.
|
// when you are finished using it, at the end of your app's lifetime.
|
||||||
// If you use another dependency injection framework, you should inspect
|
// If you use another dependency injection framework, you should inspect
|
||||||
// its documentation for the best way to do this.
|
// its documentation for the best way to do this.
|
||||||
using (var services = ConfigureServices(config))
|
await using var services = ConfigureServices(config);
|
||||||
{
|
|
||||||
var client = services.GetRequiredService<DiscordShardedClient>();
|
var client = services.GetRequiredService<DiscordShardedClient>();
|
||||||
|
|
||||||
// The Sharded Client does not have a Ready event.
|
// The Sharded Client does not have a Ready event.
|
||||||
@@ -58,9 +52,8 @@ namespace ShardedClient
|
|||||||
|
|
||||||
await Task.Delay(Timeout.Infinite);
|
await Task.Delay(Timeout.Infinite);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private ServiceProvider ConfigureServices(DiscordSocketConfig config)
|
private static ServiceProvider ConfigureServices(DiscordSocketConfig config)
|
||||||
=> new ServiceCollection()
|
=> new ServiceCollection()
|
||||||
.AddSingleton(new DiscordShardedClient(config))
|
.AddSingleton(new DiscordShardedClient(config))
|
||||||
.AddSingleton<CommandService>()
|
.AddSingleton<CommandService>()
|
||||||
@@ -70,16 +63,15 @@ namespace ShardedClient
|
|||||||
.BuildServiceProvider();
|
.BuildServiceProvider();
|
||||||
|
|
||||||
|
|
||||||
private Task ReadyAsync(DiscordSocketClient shard)
|
private static Task ReadyAsync(DiscordSocketClient shard)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Shard Number {shard.ShardId} is connected and ready!");
|
Console.WriteLine($"Shard Number {shard.ShardId} is connected and ready!");
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task LogAsync(LogMessage log)
|
private static Task LogAsync(LogMessage log)
|
||||||
{
|
{
|
||||||
Console.WriteLine(log.ToString());
|
Console.WriteLine(log.ToString());
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ using System;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ShardedClient.Services
|
namespace ShardedClient.Services;
|
||||||
{
|
|
||||||
public class CommandHandlingService
|
public class CommandHandlingService
|
||||||
{
|
{
|
||||||
private readonly CommandService _commands;
|
private readonly CommandService _commands;
|
||||||
@@ -69,4 +69,3 @@ namespace ShardedClient.Services
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
using Discord;
|
using Discord;
|
||||||
using Discord.Interactions;
|
using Discord.Interactions;
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ShardedClient.Services
|
namespace ShardedClient.Services;
|
||||||
{
|
|
||||||
public class InteractionHandlingService
|
public class InteractionHandlingService
|
||||||
{
|
{
|
||||||
private readonly InteractionService _service;
|
private readonly InteractionService _service;
|
||||||
@@ -50,13 +51,15 @@ namespace ShardedClient.Services
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _hasRegistered = false;
|
||||||
|
|
||||||
private async Task ReadyAsync(DiscordSocketClient _)
|
private async Task ReadyAsync(DiscordSocketClient _)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
// ShardReady is called for each shard; to avoid getting ratelimited we only want to register commands once.
|
||||||
await _service.RegisterCommandsToGuildAsync(1 /* implement */);
|
if (!_hasRegistered)
|
||||||
#else
|
{
|
||||||
await _service.RegisterCommandsGloballyAsync();
|
await _service.RegisterCommandsGloballyAsync();
|
||||||
#endif
|
_hasRegistered = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
|
||||||
<PackageReference Include="Discord.Net" Version="3.10.0" />
|
<PackageReference Include="Discord.Net" Version="3.13.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ using System.IO;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using TextCommandFramework.Services;
|
using TextCommandFramework.Services;
|
||||||
|
|
||||||
namespace TextCommandFramework.Modules
|
namespace TextCommandFramework.Modules;
|
||||||
{
|
|
||||||
// Modules must be public and inherit from an IModuleBase
|
// Modules must be public and inherit from an IModuleBase
|
||||||
public class PublicModule : ModuleBase<SocketCommandContext>
|
public class PublicModule : ModuleBase<SocketCommandContext>
|
||||||
{
|
{
|
||||||
@@ -66,4 +66,3 @@ namespace TextCommandFramework.Modules
|
|||||||
public Task GuildOnlyCommand()
|
public Task GuildOnlyCommand()
|
||||||
=> ReplyAsync("Nothing to see here!");
|
=> ReplyAsync("Nothing to see here!");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using TextCommandFramework.Services;
|
using TextCommandFramework.Services;
|
||||||
|
|
||||||
namespace TextCommandFramework
|
namespace TextCommandFramework;
|
||||||
{
|
|
||||||
// This is a minimal example of using Discord.Net's command
|
// This is a minimal example of using Discord.Net's command
|
||||||
// framework - by no means does it show everything the framework
|
// framework - by no means does it show everything the framework
|
||||||
// is capable of.
|
// is capable of.
|
||||||
@@ -22,17 +22,13 @@ namespace TextCommandFramework
|
|||||||
{
|
{
|
||||||
// There is no need to implement IDisposable like before as we are
|
// There is no need to implement IDisposable like before as we are
|
||||||
// using dependency injection, which handles calling Dispose for us.
|
// using dependency injection, which handles calling Dispose for us.
|
||||||
static void Main(string[] args)
|
public static async Task Main(string[] args)
|
||||||
=> new Program().MainAsync().GetAwaiter().GetResult();
|
|
||||||
|
|
||||||
public async Task MainAsync()
|
|
||||||
{
|
{
|
||||||
// You should dispose a service provider created using ASP.NET
|
// You should dispose a service provider created using ASP.NET
|
||||||
// when you are finished using it, at the end of your app's lifetime.
|
// when you are finished using it, at the end of your app's lifetime.
|
||||||
// If you use another dependency injection framework, you should inspect
|
// If you use another dependency injection framework, you should inspect
|
||||||
// its documentation for the best way to do this.
|
// its documentation for the best way to do this.
|
||||||
using (var services = ConfigureServices())
|
await using var services = ConfigureServices();
|
||||||
{
|
|
||||||
var client = services.GetRequiredService<DiscordSocketClient>();
|
var client = services.GetRequiredService<DiscordSocketClient>();
|
||||||
|
|
||||||
client.Log += LogAsync;
|
client.Log += LogAsync;
|
||||||
@@ -48,16 +44,15 @@ namespace TextCommandFramework
|
|||||||
|
|
||||||
await Task.Delay(Timeout.Infinite);
|
await Task.Delay(Timeout.Infinite);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private Task LogAsync(LogMessage log)
|
private static Task LogAsync(LogMessage log)
|
||||||
{
|
{
|
||||||
Console.WriteLine(log.ToString());
|
Console.WriteLine(log.ToString());
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ServiceProvider ConfigureServices()
|
private static ServiceProvider ConfigureServices()
|
||||||
{
|
{
|
||||||
return new ServiceCollection()
|
return new ServiceCollection()
|
||||||
.AddSingleton(new DiscordSocketConfig
|
.AddSingleton(new DiscordSocketConfig
|
||||||
@@ -72,4 +67,3 @@ namespace TextCommandFramework
|
|||||||
.BuildServiceProvider();
|
.BuildServiceProvider();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ using System;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace TextCommandFramework.Services
|
namespace TextCommandFramework.Services;
|
||||||
{
|
|
||||||
public class CommandHandlingService
|
public class CommandHandlingService
|
||||||
{
|
{
|
||||||
private readonly CommandService _commands;
|
private readonly CommandService _commands;
|
||||||
@@ -72,4 +72,3 @@ namespace TextCommandFramework.Services
|
|||||||
await context.Channel.SendMessageAsync($"error: {result}");
|
await context.Channel.SendMessageAsync($"error: {result}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ using System.IO;
|
|||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace TextCommandFramework.Services
|
namespace TextCommandFramework.Services;
|
||||||
{
|
|
||||||
public class PictureService
|
public class PictureService
|
||||||
{
|
{
|
||||||
private readonly HttpClient _http;
|
private readonly HttpClient _http;
|
||||||
@@ -17,4 +17,3 @@ namespace TextCommandFramework.Services
|
|||||||
return await resp.Content.ReadAsStreamAsync();
|
return await resp.Content.ReadAsStreamAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
|
||||||
<PackageReference Include="Discord.Net.Commands" Version="3.10.0" />
|
<PackageReference Include="Discord.Net.Commands" Version="3.13.0" />
|
||||||
<PackageReference Include="Discord.Net.Websocket" Version="3.10.0" />
|
<PackageReference Include="Discord.Net.Websocket" Version="3.13.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -2,23 +2,20 @@ using Discord;
|
|||||||
using Discord.Webhook;
|
using Discord.Webhook;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace WebHookClient
|
namespace WebHookClient;
|
||||||
{
|
|
||||||
// This is a minimal example of using Discord.Net's Webhook Client
|
// This is a minimal example of using Discord.Net's Webhook Client
|
||||||
// Webhooks are send-only components of Discord that allow you to make a POST request
|
// Webhooks are send-only components of Discord that allow you to make a POST request
|
||||||
// To a channel specific URL to send a message to that channel.
|
// To a channel specific URL to send a message to that channel.
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
public static async Task Main()
|
||||||
=> new Program().MainAsync().GetAwaiter().GetResult();
|
|
||||||
|
|
||||||
public async Task MainAsync()
|
|
||||||
{
|
{
|
||||||
// The webhook url follows the format https://discord.com/api/webhooks/{id}/{token}
|
// The webhook url follows the format https://discord.com/api/webhooks/{id}/{token}
|
||||||
// Because anyone with the webhook URL can use your webhook
|
// Because anyone with the webhook URL can use your webhook
|
||||||
// you should NOT hard code the URL or ID + token into your application.
|
// you should NOT hard code the URL or ID + token into your application.
|
||||||
using (var client = new DiscordWebhookClient("https://discord.com/api/webhooks/123/abc123"))
|
using var client = new DiscordWebhookClient("https://discord.com/api/webhooks/123/abc123");
|
||||||
{
|
|
||||||
var embed = new EmbedBuilder
|
var embed = new EmbedBuilder
|
||||||
{
|
{
|
||||||
Title = "Test Embed",
|
Title = "Test Embed",
|
||||||
@@ -30,5 +27,3 @@ namespace WebHookClient
|
|||||||
await client.SendMessageAsync(text: "Send a message to this webhook!", embeds: new[] { embed.Build() });
|
await client.SendMessageAsync(text: "Send a message to this webhook!", embeds: new[] { embed.Build() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Discord.Net.Webhook" Version="3.10.0" />
|
<PackageReference Include="Discord.Net.Webhook" Version="3.13.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user