はじめに
参加しているDiscordサーバーでイベントがあり、Discord上で順番管理のようなピンポイントのツールがあると良いということになったため、勉強がてら年末年始に作ってみることにした。(公開が半年後になっていますがご容赦ください)
まずはDiscord.net公式のサンプルBOTまでです
-
使用環境
Windows11,C#,Discord.Net -
イベントのルール
大部屋にてボスN人と挑戦者M人が待機しており、挑戦者はボスN人全員にN連勝すると達成者ロールを付与される。
N=3、M=10くらい
ボスの前で挑戦者が順番待ちし、対戦が終われば挑戦者が対戦結果を運営に報告する。 -
やりたいこと
この順番待ちを運営に申請する形で処理していたので、次回からDiscord内でBotにチャットすることで申請順の自動割り当てするかなというイメージ。
可能であれば対戦結果の報告もBotにチャットして報告したらどこかに書き込みたいなーの気持ち。
サンプルのDiscord Botを作る
何にも知らないので、Discord.NetのGetting Startedを参考にDiscordBotを作成してみる。
まずはBotを作成する
何はなくとも Discord Developer PortalからBotを作成。
無事に自分のサーバーに着陸したらしい。
C#プログラムを準備する
次にこのBotに対してDiscord.Netを利用したプログラムから接続していきたい。
コンソールプロジェクトを非同期タスクを返却するMainメソッドで作成すればよいらしい。
Main関数を非同期化、ロギング関数を追加
using Discord;
namespace PinPonBot
{
public class Program
{
public static async Task Main()
{
}
private static Task Log(LogMessage msg)
{
Console.WriteLine(msg.ToString());
return Task.CompletedTask;
}
}
}
Botと接続する
接続に当たり、DiscordSockedClientの利用とログイベントのフックを行う。
// 利用するソケット変数
private static DiscordSocketClient _client;
public static async Task Main()
{
// ソケットの生成。タスクごとにクライアントを生成する。
_client = new DiscordSocketClient();
// Log関数をフックする
_client.Log += Log;
}
tokenをDiscordDevelopperPortalのBotページから取得する
tokenを用いてプログラム上からログインする
public static async Task Main()
{
// ソケットの生成。タスクごとにクライアントを生成する。
_client = new DiscordSocketClient();
// Log関数をフックする
_client.Log += Log;
var token = "***";
await _client.LoginAsync(TokenType.Bot, token);
await _client.StartAsync();
// アプリケーションの終了までタスクをブロック。
await Task.Delay(-1);
}
コマンドを追加する
次に、コマンドを受け付けられるようにする必要がある。
Creating your first slash commands.を参考にスラッシュコマンドを追加していくとよさそうなので手順に従い進める。
guildId(=サーバーID)が必要になるらしい。
サーバーID、チャンネルIDなどはDiscordのサポートに従い確認した。
コマンドの構築ができたら、次はコマンド入力時の対応を作りこむ。
Responding to interactions.の手順に従い進める。
スラッシュコマンドが作成できた。
//~中略~
// Redeyイベントをフックする
_client.Ready += Client_ReadyAsync;
//~中略~
private static async Task Client_ReadyAsync()
{
// guild(サーバー)用のコマンド
var guild = _client.GetGuild(_guildId);
var guildCommand = new SlashCommandBuilder();
guildCommand.WithName("first-command");
guildCommand.WithDescription("This is my first guild slash command!");
// globalコマンド
var globalCommand = new SlashCommandBuilder();
globalCommand.WithName("first-global-command");
globalCommand.WithDescription("This is my first global slash command");
// ビルダーからコマンドを構成する
try
{
// guildIdが必要なのでguildからコールする
await guild.CreateApplicationCommandAsync(guildCommand.Build());
// guildが不要なのでSocketClientからコールする
await _client.CreateGlobalApplicationCommandAsync(globalCommand.Build());
}
catch (HttpException exception)
{
// エラー
var json = JsonConvert.SerializeObject(exception.Errors, Formatting.Indented);
Console.WriteLine(json);
}
}
以上でサンプルの作成は完了とする。