DiscordのBotをRaspberry Pi3で動かす

#DiscordのBotをRaspberry Pi3で動かす
Qiita初投稿、たまに絵描いたりゲームしたりプログラム書いてる0x11歳です。

周りの友人とSlackで連絡を取り合おうとしてもDiscordのほうがやってる人多い...
ということで最近の連絡ツールはDiscordを使ってます。
そこで便利コマンドをみんなで使うためにRaspberry Pi3で常時稼働してるDiscordのBotを作ってみました。

##準備
とりあえず必要なものを準備しましょう
####必要
・VisualStudio
・Raspberry Pi3
・microSDカード
・microUSB Type-B(AC-DCアダプター)
・XRDP

##Discord.NetでBotを作る
まずはBotの登録をします
以下にアクセスしてください
https://discordapp.com/developers/applications/

NewApplication
↓
名前を入れたらBotからAdd Bot
↓
OAuth2でbotだけ選択してURLをコピー
↓
リンクに飛ぶと自分のサーバーセレクト画面が出てくるのでサーバーを選択
↓
サーバーに招待して登録完了

##プログラムを作る
まずは必要なものをインストールします

#####VisualStudioでコンソールソフトウェア(.Net Core)を作成

#####NuGetパッケージをインストール
Discord.Netは最初からインストールされてないのでNuGetパッケージをインストールします
ソリューションエクスプローラーでプロジェクトを右クリック
↓
NuGetパッケージの管理
↓
参照にDiscordと入力するとDiscord.Netが出てくるのでインストール

#####コードを書く

```cs
using System;
using System.Threading.Tasks;
using System.Reflection;
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using Microsoft.Extensions.DependencyInjection;

namespace DiscordBot
{
    class Program
    {
        public static DiscordSocketClient client;
        public static CommandService commands;
        public static IServiceProvider services;

        static void Main(string[] args) => new Program().Setup().GetAwaiter().GetResult();

        private async Task Setup()
        {
            client = new DiscordSocketClient();
            commands = new CommandService();
            services = new ServiceCollection().BuildServiceProvider();
            client.MessageReceived += Command;
            client.UserJoined += join;
            client.UserLeft += left;
            client.Log += Log;

            await commands.AddModulesAsync(Assembly.GetEntryAssembly(), services);
            await client.LoginAsync(TokenType.Bot, "トークンは登録したページのBotページでコピー");
            await client.StartAsync();

            await Task.Delay(-1);
        }

        private async Task Command(SocketMessage messageP)
        {
            //pass by reference value
            var argPos = 0;
            var message = messageP as SocketUserMessage;
            Console.WriteLine("{0} {1}:{2}", message.Channel.Name, message.Author.Username, message);

            //メッセージが空白の場合
            if (message == null)
                return;

            //コマンドの先頭文字を指定
            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); }
            GC.Collect();//必要なさそうだけど一応GC(ほんとに要らないかも)
        }

        public async Task join(SocketGuildUser user)
        {
            var channel = client.GetChannel(/*/チャンネルID/*/) as SocketTextChannel;
            await channel.SendMessageAsync($"Welcome {user.Mention}!!!");
        }

        public async Task left(SocketGuildUser user)
        {
            var channel = client.GetChannel(/*/チャンネルID/*/) as SocketTextChannel;
            await channel.SendMessageAsync($"{user} Bye...");
        }

        private Task Log(LogMessage log)
        {
            Console.WriteLine(log.ToString());
            return Task.CompletedTask;
        }
        
    }
}
```

クラス Message.csをプロジェクトに追加

```cs
using System;
using System.Threading.Tasks;
using Discord.Commands;
using System.Net.Http;

namespace DiscordBot
{
    public class Messages : ModuleBase
    {
        [Command("お腹すいた")]
        public async Task Time() => await ReplyAsync("ご飯食べろ");
    }
}

```

これでプロジェクトは完成です
実行するとDiscordBotとして動くはずです

#####発行
ソリューションエクスプローラーのプロジェクトを右クリックから発行
設定でarmを選択した状態で発行してください(Raspberry Piはarmなので)

##Raspberry Piの設定
ラズパイにRaspbianをインストールします
インストール方法はいくらでも載っているので調べてみてください

#####XRDPのインストール

```
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install xrdp
```
これだけです
以下のコマンドでipアドレスを確認

```
ifconfig
```
や


```
ip a
```

日本語は今回扱わないのでオプションは省きます
Windowsのリモートデスクトップでipを入力
↓
user:pi
pass:ラズパイのパスワード
を入力してリモートできるようになります

ツールのインストール

```
sudo apt-get install curl libunwind8 gettext
```

Coreインストール

```
curl -sSL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/release/2.2.0/dotnet-runtime-latest-linux-arm.tar.gz
```

ランタイムのインストール

```
sudo mkdir -p /opt/dotnet && sudo tar zxf dotnet.tar.gz -C /opt/dotnet
```

実行可能に

```
sudo ln -s /opt/dotnet/dotnet /usr/local/bin
```

発行したパッケージをラズパイにコピーしてファイルで以下を実行
デスクトップなら

```
cd /home/pi/Desktop/DiscordBot
```

コピー先で権限付与

```
chmod 755 -R publish
```

パッケージ内で実行

```
./DiscordBot
```

実行してDiscordで
-お腹すいた
と入力するとご飯食べろと帰ってくるはずです

これで放置しとけばポート開放等なしでAPIを実行しっぱなしにできます

##最後に
正直ラズパイあんまいじってないのでにわか知識です( 一一)
今回のは別にRaspberry Piがなくても動くのでその他のOSのサーバーをお持ちであればそちらでも使えます！
C#をお使いの方ならいろんな機能を付けられると思うのでどんどんコード追加しましょう(≧▽≦)


わかりにくいとこなどあれば
https://twitter.com/mayu___cs
までどうぞ！

HPからDiscordに参加できるのでこちらもどうぞ!
http://www.mayu-cs.xyz


参考リンク
https://discord.foxbot.me/docs/index.html
https://dotnet.microsoft.com/download