Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update sample projects #2823

Merged
merged 3 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions docs/guides/concepts/samples/events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@

public class Program
{
private DiscordSocketClient _client;
static void Main(string[] args) => new Program().MainAsync().GetAwaiter().GetResult();

public async Task MainAsync()
private static DiscordSocketClient _client;
public static async Task MainAsync()
{
// When working with events that have Cacheable<IMessage, ulong> parameters,
// you must enable the message cache in your config settings if you plan to
Expand All @@ -27,7 +25,7 @@ public async Task MainAsync()
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`.
var message = await before.GetOrDownloadAsync();
Expand Down
16 changes: 4 additions & 12 deletions docs/guides/dependency_injection/samples/program.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
public class Program
{
private readonly IServiceProvider _serviceProvider;

public Program()
{
_serviceProvider = CreateProvider();
}

static void Main(string[] args)
=> new Program().RunAsync(args).GetAwaiter().GetResult();

private static IServiceProvider _serviceProvider;

static IServiceProvider CreateProvider()
{
var collection = new ServiceCollection();
//...
return collection.BuildServiceProvider();
}

async Task RunAsync(string[] args)
static async Task Main(string[] args)
{
//...
_serviceProvider = CreateProvider();
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
public class Program
{
public static Task Main(string[] args) => new Program().MainAsync();

public async Task MainAsync()
public static async Task Main()
{
}
}
4 changes: 2 additions & 2 deletions docs/guides/getting_started/samples/first-bot/client.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
private DiscordSocketClient _client;
private static DiscordSocketClient _client;

public async Task MainAsync()
public static async Task Main()
{
_client = new DiscordSocketClient();

Expand Down
6 changes: 2 additions & 4 deletions docs/guides/getting_started/samples/first-bot/complete.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
public class Program
{
private DiscordSocketClient _client;
private static DiscordSocketClient _client;

public static Task Main(string[] args) => new Program().MainAsync();

public async Task MainAsync()
public async Task Main()
{
_client = new DiscordSocketClient();
_client.Log += Log;
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/getting_started/samples/first-bot/logging.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
private Task Log(LogMessage msg)
private static Task Log(LogMessage msg)
{
Console.WriteLine(msg.ToString());
return Task.CompletedTask;
Expand Down
4 changes: 2 additions & 2 deletions docs/guides/getting_started/samples/first-bot/message.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
public async Task MainAsync()
public static async Task Main()
{
// ...
_client.MessageReceived += MessageReceived;
// ...
}

private async Task MessageReceived(SocketMessage message)
private static async Task MessageReceived(SocketMessage message)
{
if (message.Content == "!ping")
{
Expand Down
30 changes: 11 additions & 19 deletions docs/guides/getting_started/samples/first-bot/structure.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,7 @@
class Program
{
// Program entry point
static 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()
static async Task Main(string[] args)
{
_client = new DiscordSocketClient(new DiscordSocketConfig
{
Expand Down Expand Up @@ -58,8 +44,14 @@ private Program()

// Setup your DI container.
_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,
// pass them as parameters into this method as needed.
Expand Down Expand Up @@ -110,7 +102,7 @@ private static Task Log(LogMessage message)
return Task.CompletedTask;
}

private async Task MainAsync()
private static async Task MainAsync()
{
// Centralize the logic for commands into a separate method.
await InitCommands();
Expand All @@ -125,7 +117,7 @@ await _client.LoginAsync(TokenType.Bot,
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.
// Module classes MUST be marked 'public' or they will be ignored.
Expand All @@ -140,7 +132,7 @@ private async Task InitCommands()
_client.MessageReceived += HandleCommandAsync;
}

private async Task HandleCommandAsync(SocketMessage arg)
private static async Task HandleCommandAsync(SocketMessage arg)
{
// Bail out if it's a System Message.
var msg = arg as SocketUserMessage;
Expand Down
4 changes: 2 additions & 2 deletions docs/guides/getting_started/samples/project.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Discord.Net" Version="2.0.0" />
<PackageReference Include="Discord.Net" Version="3.13.0" />
</ItemGroup>

</Project>
182 changes: 87 additions & 95 deletions samples/BasicBot/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,117 +4,109 @@
using System.Threading;
using System.Threading.Tasks;

namespace BasicBot
namespace BasicBot;

// 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
// framework, rather than handling them yourself, like we do in this sample.
//
// You can find samples of using the command framework:
// - Here, under the TextCommandFramework sample
// - At the guides: https://discordnet.dev/guides/text_commands/intro.html
//
// You can find samples of using the interaction framework:
// - Here, under the InteractionFramework sample
// - At the guides: https://discordnet.dev/guides/int_framework/intro.html
class Program
{
// 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
// framework, rather than handling them yourself, like we do in this sample.
//
// You can find samples of using the command framework:
// - Here, under the TextCommandFramework sample
// - At the guides: https://discordnet.dev/guides/text_commands/intro.html
//
// You can find samples of using the interaction framework:
// - Here, under the InteractionFramework sample
// - At the guides: https://discordnet.dev/guides/int_framework/intro.html
class Program
// Non-static readonly fields can only be assigned in a constructor.
// If you want to assign it elsewhere, consider removing the readonly keyword.
private static DiscordSocketClient _client;

// Discord.Net heavily utilizes TAP for async, so we create
// an asynchronous context from the beginning.
public static async Task Main(string[] args)
{
// Non-static readonly fields can only be assigned in a constructor.
// If you want to assign it elsewhere, consider removing the readonly keyword.
private readonly DiscordSocketClient _client;

// Discord.Net heavily utilizes TAP for async, so we create
// an asynchronous context from the beginning.
static void Main(string[] args)
=> new Program()
.MainAsync()
.GetAwaiter()
.GetResult();

public Program()
// Config used by DiscordSocketClient
// 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
{
// Config used by DiscordSocketClient
// Define intents for the client
var config = new DiscordSocketConfig
{
GatewayIntents = GatewayIntents.AllUnprivileged | GatewayIntents.MessageContent
};

// It is recommended to Dispose of a client when you are finished
// using it, at the end of your app's lifetime.
_client = new DiscordSocketClient(config);

// Subscribing to client events, so that we may receive them whenever they're invoked.
_client.Log += LogAsync;
_client.Ready += ReadyAsync;
_client.MessageReceived += MessageReceivedAsync;
_client.InteractionCreated += InteractionCreatedAsync;
}
GatewayIntents = GatewayIntents.AllUnprivileged | GatewayIntents.MessageContent
};

public async Task MainAsync()
{
// Tokens should be considered secret data, and never hard-coded.
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.
// It is recommended to Dispose of a client when you are finished
// using it, at the end of your app's lifetime.
_client = new DiscordSocketClient(config);

await _client.StartAsync();
// Subscribing to client events, so that we may receive them whenever they're invoked.
_client.Log += LogAsync;
_client.Ready += ReadyAsync;
_client.MessageReceived += MessageReceivedAsync;
_client.InteractionCreated += InteractionCreatedAsync;

// Block the program until it is closed.
await Task.Delay(Timeout.Infinite);
}

private Task LogAsync(LogMessage log)
{
Console.WriteLine(log.ToString());
return Task.CompletedTask;
}
// Tokens should be considered secret data, and never hard-coded.
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.

// The Ready event indicates that the client has opened a
// connection and it is now safe to access the cache.
private Task ReadyAsync()
{
Console.WriteLine($"{_client.CurrentUser} is connected!");
await _client.StartAsync();

return Task.CompletedTask;
}
// Block the program until it is closed.
await Task.Delay(Timeout.Infinite);
}

// This is not the recommended way to write a bot - consider
// reading over the Commands Framework sample.
private async Task MessageReceivedAsync(SocketMessage message)
{
// The bot should never respond to itself.
if (message.Author.Id == _client.CurrentUser.Id)
return;
private static Task LogAsync(LogMessage log)
{
Console.WriteLine(log.ToString());
return Task.CompletedTask;
}

// The Ready event indicates that the client has opened a
// connection and it is now safe to access the cache.
private static Task ReadyAsync()
{
Console.WriteLine($"{_client.CurrentUser} is connected!");

return Task.CompletedTask;
}

// This is not the recommended way to write a bot - consider
// reading over the Commands Framework sample.
private static async Task MessageReceivedAsync(SocketMessage message)
{
// The bot should never respond to itself.
if (message.Author.Id == _client.CurrentUser.Id)
return;

if (message.Content == "!ping")
{
// Create a new ComponentBuilder, in which dropdowns & buttons can be created.
var cb = new ComponentBuilder()
.WithButton("Click me!", "unique-id", ButtonStyle.Primary);

// Send a message with content 'pong', including a button.
// This button needs to be build by calling .Build() before being passed into the call.
await message.Channel.SendMessageAsync("pong!", components: cb.Build());
}
if (message.Content == "!ping")
{
// Create a new ComponentBuilder, in which dropdowns & buttons can be created.
var cb = new ComponentBuilder()
.WithButton("Click me!", "unique-id", ButtonStyle.Primary);

// Send a message with content 'pong', including a button.
// This button needs to be build by calling .Build() before being passed into the call.
await message.Channel.SendMessageAsync("pong!", components: cb.Build());
}
}

// For better functionality & a more developer-friendly approach to handling any kind of interaction, refer to:
// https://discordnet.dev/guides/int_framework/intro.html
private async Task InteractionCreatedAsync(SocketInteraction interaction)
// For better functionality & a more developer-friendly approach to handling any kind of interaction, refer to:
// https://discordnet.dev/guides/int_framework/intro.html
private static async Task InteractionCreatedAsync(SocketInteraction interaction)
{
// 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 (interaction is SocketMessageComponent component)
{
// 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 (interaction is SocketMessageComponent component)
{
// Check for the ID created in the button mentioned above.
if (component.Data.CustomId == "unique-id")
await interaction.RespondAsync("Thank you for clicking my button!");

else
Console.WriteLine("An ID has been received that has no handler!");
}
// Check for the ID created in the button mentioned above.
if (component.Data.CustomId == "unique-id")
await interaction.RespondAsync("Thank you for clicking my button!");

else
Console.WriteLine("An ID has been received that has no handler!");
}
}
}
2 changes: 1 addition & 1 deletion samples/BasicBot/_BasicBot.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Discord.Net.WebSocket" Version="3.10.0"/>
<PackageReference Include="Discord.Net.WebSocket" Version="3.13.0"/>
</ItemGroup>

</Project>
Loading