DiscordのBotをC#で作ってみる
開発環境
- Visual Studio 2017 (C#)
- Discord.Net 1.0.2
初めに
スプラトゥーン2のAPIをコールするBotを@otuhs_dさんが作成されたのをみて、自分のチーム用に何かできないかを考えました。
そこで、チーム内プライベートマッチでルールとステージをランダムで決定できるものをC#コンソールアプリで作ってみました。
参考
@otuhs_d
さんの記事
Splatoon2チーム向けDiscord Bot『Roboty』を公開しました
DiscordのBotにSplatoon2のステージ情報を教えてもらう
実装後のイメージ
「.rl」とText Chatで入力すると、ルールとステージをランダムで表示するという簡単なBot
事前準備としてDiscordでBotの登録
※すでにディスコサーバを作成済みの手順です。
- ディスコのWebページから More > Depelopers > My Apps を選択。
- もしくは、ここから
- 「New Apps」を押下する。
- 「App Name」にBotの名前を登録します。
- 「App Icon」に画像ファイルを置くことで、アイコン化できます。
- 「Create App」を押下します。
- 「Create Bot User」を押下します。
- 確認メッセージは、そのまま「Yes do it!」を押下します。
- 「Public Bot」にチェックを入れます。
- 「click to reveal」を押下します。
- そこで、表示される
Tokenをメモ
っておきます。 - 画面最下部の「Save changes」を押下します。
- 「Generate OAuth2 URL」を押下します。
- 「Copy」を押下して、ブラウザで、そのURLを開きます。
- この際、ClientIDをメモしておいてください。
- Botを追加するサーバを選択し、「認証」を押下します。
- 認証完了後、ブラウザを閉じます。
- Discordを起動すると、作成したBotが表示されています。
- 自身のギアのアイコンから設定を開き > テーマ を選択します。
- 開発者モードをトグルスイッチをオンにします。
- サーバのIDをコピーするのに、サーバーを右クリックし「IDのコピー」を選択しメモっておきます。
準備完了!
これで、Botの準備ができたので、この後は、Visual Studioでの作業になります。
メモしたもの | 場所 | 今回使用 |
---|---|---|
ClientID | Discord WebページでメモしたClientID | × |
Token | Discord WebページでメモしたToken | ○ |
サーバーID | Discordアプリの画面左上の「IDをコピー」 | × |
今回の説明する機能まででは、○のものだけが必要です。
Visual Studio
プロジェクトの作成
- Windowsクラシックデスクトップ > コンソールアプリ(.Net Framework) を選択して、「OK」を押下する。
Nugetから「Discord.Net 1.0.2」インストール
- 「プロジェクトエクスプローラ」>「参照設定」を右クリック >「NuGetパッケージ管理」
- 「参照」タブを選択 > 検索欄に「Discord.Net」を入力します。
- 「Discord.Net」を選択します。
- 最新の安定版を選択して「インストール」ボタンを押下します。
Messagesクラスを作成
- コメントを受けとった処理を作成します。
:Messages.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord.Commands;
using System.Collections.Generic;
namespace Splatoo2ConsoleApp
{
public class Messages : ModuleBase
{
/* ルール列挙 */
Dictionary<int, string> rule = new Dictionary<int, string>()
{
{0, "ナワバリ"},
{1, "エリア"},
{2, "ホコ"},
{3, "ヤグラ"},
{4, "アサリ"},
};
/* ステージ列挙 */
Dictionary<int, string> stage = new Dictionary<int, string>()
{
{0, "バッテラストリート" },
{1 , "フジツボスポーツクラブ"},
{2 , "ガンガゼ野外音楽堂"},
{3 , "チョウザメ造船"},
{4 , "海女美術大学"},
{5 , "コンブトラック"},
{6 , "マンタマリア号"},
{7 , "ホッケふ頭"},
{8 , "タチウオパーキング"},
{9 , "エンガワ河川敷"},
{10, "モズク農園"},
{11, "Bバスパーク"},
{12, "デボン海洋博物館"},
{13, "ザトウマーケット"},
{14, "ハコフグ倉庫"},
{15, "アロワナモール"}
};
/// <summary>
/// [rl]というコメントが来た際の処理
/// </summary>
/// <returns>Botのコメント</returns>
[Command("rl")]
public async Task rl()
{
Random random = new System.Random();
int randomRule = random.Next(5);
int randomStage = random.Next(16);
string Messages = "次の試合のルールは、\n ・**" + rule[randomRule].ToString() + "**\n\n";
Messages += "次の試合のステージは、\n ・**" + stage[randomStage].ToString() + "**\n";
await ReplyAsync(Messages);
}
}
}
Program.csクラスを作成
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord.Commands;
using Discord.WebSocket;
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
using Discord;
namespace Splatoo2ConsoleApp
{
class Program
{
public static DiscordSocketClient client;
public static CommandService commands;
public static IServiceProvider services;
static void Main(string[] args) => new Program().MainAsync().GetAwaiter().GetResult();
/// <summary>
/// 起動時処理
/// </summary>
/// <returns></returns>
public async Task MainAsync()
{
client = new DiscordSocketClient();
commands = new CommandService();
services = new ServiceCollection().BuildServiceProvider();
client.MessageReceived += CommandRecieved;
client.Log += Log;
string token = "メモしたTokeを指定";
await commands.AddModulesAsync(Assembly.GetEntryAssembly());
await client.LoginAsync(TokenType.Bot, token);
await client.StartAsync();
await Task.Delay(-1);
}
/// <summary>
/// メッセージの受信処理
/// </summary>
/// <param name="msgParam"></param>
/// <returns></returns>
private async Task CommandRecieved(SocketMessage messageParam)
{
var message = messageParam as SocketUserMessage;
Console.WriteLine("{0} {1}:{2}", message.Channel.Name, message.Author.Username, message);
if (message == null) { return; }
// コメントがユーザーかBotかの判定
if (message.Author.IsBot) { return; }
int argPos = 0;
// コマンドかどうか判定(今回は、「.」で判定)
if (!(message.HasCharPrefix('.', ref argPos) || message.HasMentionPrefix(client.CurrentUser, ref argPos))) { return; }
var context = new CommandContext(client, message);
// 実行
var result = await commands.ExecuteAsync(context, argPos, services);
//実行できなかった場合
if (!result.IsSuccess) { await context.Channel.SendMessageAsync(result.ErrorReason); }
}
/// <summary>
/// コンソール表示処理
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
private Task Log(LogMessage msg)
{
Console.WriteLine(msg.ToString());
return Task.CompletedTask;
}
}
}
作成完了!
- ビルドを実行します。
- Discordで「.rl」コメントしてみると、Botがランダムで返してくれます。
まとめ
- NuGetに
Discord .Net
があるので、比較的簡単に作成することができました。 - 他にもDiscordの機能をいろいろと触れそうですが、とっかかりとしては、まずまずでした。