Help us understand the problem. What is going on with this article?

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の機能をいろいろと触れそうですが、とっかかりとしては、まずまずでした。
HAGITAKO
社内SEとして17年くらい 最近では、管理職のため仕事での使用頻度は少なくなってきてます。 社内新規案件のプロトタイプが主なコードを触るくらい。 WPF大好きです。
https://corp.tsukui.net/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away