Edited at

DiscordのBotをC#で作ってみる

More than 1 year has passed since last update.


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のステージ情報を教えてもらう


実装後のイメージ

WS000018.JPG

「.rl」とText Chatで入力すると、ルールとステージをランダムで表示するという簡単なBot


事前準備としてDiscordでBotの登録

※すでにディスコサーバを作成済みの手順です。


  • ディスコのWebページから More > Depelopers > My Apps を選択。 

  • もしくは、ここから

FireShot Capture 19 - Discord - Developer Documentat_ - https___discordapp.com_developers_docs_intro.png


  • 「New Apps」を押下する。

FireShot Capture 21 - Discord - My Apps - https___discordapp.com_developers_applications_me.png


  • 「App Name」にBotの名前を登録します。

  • 「App Icon」に画像ファイルを置くことで、アイコン化できます。

  • 「Create App」を押下します。

FireShot Capture 22 - Discord - Develope_ - https___discordapp.com_developers_applications_me_create.png


  • 「Create Bot User」を押下します。

FireShot Capture 23 - Discord - Developer Documentation_ - https___discordapp.com_developers_.png


  • 確認メッセージは、そのまま「Yes do it!」を押下します。

FireShot Capture 24 - Discord - Developer Documentation_ - https___discordapp.com_developers_.png


  • 「Public Bot」にチェックを入れます。

FireShot Capture 24 - Discord - Developer Documentation_ - https___discordapp.com_developers_.png


  • 「click to reveal」を押下します。

  • そこで、表示されるTokenをメモっておきます。

  • 画面最下部の「Save changes」を押下します。

FireShot Capture 29 - Discord - Developer Documentation_ - https___discordapp.com_developers_.png


  • 「Generate OAuth2 URL」を押下します。

FireShot Capture 26 - Discord - Developer Documentation_ - https___discordapp.com_developers_.png


  • 「Copy」を押下して、ブラウザで、そのURLを開きます。

  • この際、ClientIDをメモしておいてください。

FireShot Capture 27 - Discord - Developer Documentation_ - https___discordapp.com_developers_.png


  • Botを追加するサーバを選択し、「認証」を押下します。

  • 認証完了後、ブラウザを閉じます。

FireShot Capture 28 - アカウントへのアクセスを許可します_ - https___discordapp.com_oauth2_authorize.png


  • Discordを起動すると、作成したBotが表示されています。

WS000021.png


  • 自身のギアのアイコンから設定を開き > テーマ を選択します。

  • 開発者モードをトグルスイッチをオンにします。

WS000022.JPG


  • サーバのIDをコピーするのに、サーバーを右クリックし「IDのコピー」を選択しメモっておきます。

WS000023.JPG


準備完了!

これで、Botの準備ができたので、この後は、Visual Studioでの作業になります。

メモしたもの
場所
今回使用

ClientID
Discord WebページでメモしたClientID
×

Token
Discord WebページでメモしたToken

サーバーID
Discordアプリの画面左上の「IDをコピー」
×

今回の説明する機能まででは、○のものだけが必要です。


Visual Studio


プロジェクトの作成


  • Windowsクラシックデスクトップ > コンソールアプリ(.Net Framework) を選択して、「OK」を押下する。

WS000019.JPG


Nugetから「Discord.Net 1.0.2」インストール


  • 「プロジェクトエクスプローラ」>「参照設定」を右クリック >「NuGetパッケージ管理」

  • 「参照」タブを選択 > 検索欄に「Discord.Net」を入力します。

  • 「Discord.Net」を選択します。

  • 最新の安定版を選択して「インストール」ボタンを押下します。

WS000020.JPG


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;
}
}
}



作成完了!


  • ビルドを実行します。

WS000024.JPG


  • Discordで「.rl」コメントしてみると、Botがランダムで返してくれます。

WS000025.JPG


まとめ


  • NuGetにDiscord .Netがあるので、比較的簡単に作成することができました。

  • 他にもDiscordの機能をいろいろと触れそうですが、とっかかりとしては、まずまずでした。