DiscordのBotをC#で作った備忘録

最終更新日:2021/08/21

自分用メモなので常体。初心者なのでガバあります。許して。


Pythonjava等が主流らしい(?)けどC#で作った理由は以下の通り。

  • 使い慣れているから
  • Pythonを忘れたから
  • javaを知らないから
  • VisualStudioがそこにあったから

まともな理由がないけど、こんな感じ。そのうちPythonで作りたいとは思っている。

使用環境
Win10
Visual Studio2019
.Net Framework 4.7.2
C# 7.3

Botを登録する

ここからディスコのWebページに飛ぶ。
左の【DEVELOPER PORTAL】の[Applications]を押すと以下の画像のようになる。
f:id:ezakiprn:20210814153826j:plain
既にbotを作っていたら[My Applications]欄にあるはず。

右上の[New Application]と書いてある青いボタンを押す。
なんか出てくるので、適当に名前を付ける。
f:id:ezakiprn:20210814155021j:plain
[ICON]、[NAME]、[DESCRIPTION]は好きに設定する。
下にも[APPLICATION ID]等あるけど、使わないので無視。

左の【Bot】欄を押す。[Add Bot]を押すと以下のような画面になる。
f:id:ezakiprn:20210814155425j:plain
[ICON]の辺りにTOKENがあるので、コピーして保存しておく。
他人にバレないようにする。

公開したいなら[PUBLIC BOT]にチェックを入れる。


次に左にある【OAuth2】を押す。
f:id:ezakiprn:20210814160133j:plain
下に少しスクロールし、botにチェックを入れコピーをする。
その後[Add Redirect]ボタンを押すと何か入力できるものが出てくるのでペースト。

他にも何か機能を付けたかったらチェックを入れてもいいと思うけど、わからないので知らない。自分で調べて。

参考サイトでは[Client ID]をコピーするように書いてあるが、今回は必要ないのでどっちでもいい。

上記画像の②でコピーしたURLを適当に新しいタブを開いて貼り付ける。
『サーバーに追加』と表示されるので、追加したいサーバーにぶち込む。


ディスコードでの作業は終了。

Visual Studio

Visual Studioを開いて【新しいプロジェクトの作成】から【コンソールアプリ(.Net Framework)】を選択。プロジェクト名は好きに付ける。

NuGetから【Discord.Net x.x.x】をインストールする。

  1. 右の[ソリューション エクスプローラー]欄の「ソリューション」上で右クリックし、「ソリューションのNuGetパッケージの管理」を開く。
  2. 「参照」タブを選択し、検索欄に「Discord.Net」を入力する。
  3. 「Discord.Net」の最新の安定板を選択してインストール。

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 BotMakeTest1
{
    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 = "ODc1OTE0OTYyNjAwNjExODUx.YRcdYA.vSw2kt9pWH1uQNtb8OYjRZWl-xY";
            await commands.AddModulesAsync(Assembly.GetEntryAssembly(), services);
            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); }
            */

            var messages = new Messages();

            await context.Channel.SendMessageAsync(messages.Display(message));
        }

        /// <summary>
        /// コンソール表示処理
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        private Task Log(LogMessage msg)
        {
            Console.WriteLine(msg.ToString());
            return Task.CompletedTask;
        }
    }
}

ほとんどコピペ。
詳しいことは自分で調べてくれ。

「実行」、「実行できなかった場合」と書いてある箇所がコメントアウトしてあるが、なぜかコマンドが呼び出されなかったので泣きながらインスタンス生成した。
有識者がいたらご教授願いたい。

Messagesクラスにコマンドを渡して返ってきたものを表示するだけ。

これだけでVisual Studioで動かしている間はBotが動く。

Azureを使う

せっかくなので自分のPCで動かしていない間も使えるようにしたい。
Azure上でデプロイすればできるらしい。
参考はここ
最初に挙げたサイトも参考したが、ちょっと違っていたので困った。

Azure Portalに接続し、アカウントの作成もしくはログインをする。
ログインできるとサービス一覧が表示される。
一覧にある【リソース グループ】を選択(もしくは【リソースの作成】から「リソース グループ」を検索・作成)。
作成を選択で以下の画像のようになる。
f:id:ezakiprn:20210814230523j:plain
グループは自分のものだとわかれば多分いい。
リージョンは東日本とかあるから適当に設定する。
左下の【確認および作成】ボタンを押す。
Azureは多分これでOK。

参考サイトと結構違った原因は.Net Coreじゃなくて.Net Frameworkで作ってたかららしい。

またVisualStudioに戻る。

[ソリューションエクスプローラー]内の[プロジェクト]を右クリックし、[Azure WebJobとして公開]を選択。
そこから適当に進めていく。
App Serviceインスタンスがなかったら右の+を押したり、右上のアカウントを確認する。

発行できたら使えるようになってるはず。

ここを見て、リソースロックを使用してリソースを保護する。

以上。不備とかいろいろあると思うけどとりあえずここまで。
気が向いたら修正するはず。

常駐できてないんだけどなんで??????????

意見・アドバイスなどあったらTwitter@ezakiprnかコメントにお願いします。

参考にしたサイト
DiscordのBotをC#で作ってみる - Qiita
Botアカウント作成
Discord Botアカウント初期設定ガイド for Developer - Qiita
【C#】Discord .NETでbotを作る | AtriaSoft
DiscordBotをC#で作ってAzureで公開してみた - Qiita