【サービス終了2022/03/01 Hacobune】Discord Bot起動してみた

# 追記: 2022/03/01にサービス提供終了します:cry:

とても悲しいですが、2022年3月1日（火）にサービスが終了するみたいです:cry:
この記事からHacobuneを使われた方には大変申し訳ないですが、他サービスへの移行をお願いします。

https://www.sakura.ad.jp/information/announcements/2022/01/31/1968208892/

Discord Botについて紹介もしてるため記事は残して置きますが、Hacobuneではなく他のコンテナサービスで起動をお願いします。
他サービスで起動する方法について今後作成します。

# 概要

さくらインターネットの**Hacobune**というサービスで**DiscordのBotを運用**しています。この**起動手順**についてまとめます。
Hacobuneは今はβ版のお試し期間なので**無料**で使えます。**すごく簡単**なのでお試しください。
Node.jsとTypeScript、Dockerで作成した私のGithubレポジトリで環境を構築していきます。

https://www.sakura.ad.jp/information/announcements/2021/08/12/1968207782/

## できるようになること

- DiscordのBotを**Hacobune**で起動できる
- node, typescriptの**DiscordBot開発**のベースを作ることができる

## 必要なもの

1. **Hacobuneのアカウント**
  - 以下のマニュアルを参考にアカウントを作成してください
     - https://manual.c1.hacobuneapp.com/docs
2. **Dockerで動作するDiscord BotのGithub Repository**
  - 今回はサンプルとして私のレポジトリを使用します。Node.jsとTypeScriptで開発しましたので参考にしてください。
     - https://github.com/nodokamome/discord-bot-template 
3. **Discord Botアカウント、およびそのトークン**
  - 作成の方法と自分のサーバーへの追加方法は以下を参考にしてください。
     - Discord.jsの公式ドキュメント https://discordjs.guide/preparations/setting-up-a-bot-application.html#creating-your-bot
     - 私の個人ブログ記事 https://blog.nodokamome.com/discord/discord-add-bot/

# サンプルプロジェクト・ソース

今回は私のDiscord Botテンプレートで説明します。
テストされる際はこちらをforkやcloneしてお試しください。

https://github.com/nodokamome/discord-bot-template

Discord Bot開発の記事ではないので深くは説明しないですが、[discord.js](https://discord.js.org/)というnpmライブラリで開発をしています。

```
  ├ src/
  |  └ index.ts             // DiscordBotの動作を記載するファイル。
  |
  ├ .dockerignore           // 軽量なDockerImageを作成するときに使うファイル。node_moduleと.gitが書いてあれば良いと思います。
  ├ .Dockerfile             // DiscordBotのDockerImageを作成するために使うファイル。Hacobuneを使うにはこれが必須です。
  ├ .package.json           // nodeを使うためのファイル
  └ .tsconfig.json          // TypeScriptを書くためのファイル

// .gitignore, README.md, package-lock.json は説明不要と思い省略しています
```

### ソース説明

`index.ts`と`Dockerfile`だけ記載します。他のファイルは私のレポジトリリンクから参照できます。
特に説明することもないですね。

この書き方であればTSでなくても良いと思いますがTemplateなのでとりあえずTSにしてます。
Botの動作は`!ping`がチャンネルで入力されたときに`pong`を返すようにしました。

```typescript:index.ts
import { Client } from 'discord.js';
import { config } from 'dotenv';

config();

(function main() {
  const client = new Client();

  client.on('message', async (message) => {
    if (message.author.bot) return;

    if (message.content === '!ping') {
      message.channel.send('pong');
    }
  });

  client.once('ready', () => {
    console.log('Connected to Discord successfully!');
  });
  client.login(process.env.DISCORD_TOKEN);
})();
```

カッコつけてbuildとruntime用を分けてImageを作成してます。特に意味はないですが軽量化されている気がします。
Botのための特別なことはしておらず、ビルドして実行しているだけなのでご自由に変更してください。

```dockerfile:Dockerfile
# ----------
# build(tscを実行してjsを作る)用のstage
# ----------
FROM node:14 AS build

WORKDIR /build
COPY . .
RUN npm install
RUN npm run build

# ----------
# runtime用のstage
# 必要なファイルは dist/, node_modules/, package.json, package-lock.json のみ
# ----------

FROM node:14

WORKDIR /usr/src/app
COPY package*.json ./
# ランタイムに必要な依存パッケージのみインストールし、同時にnpmのcacheファイルを削除する
RUN npm install --production --cache /tmp/empty-cache && rm -rf /tmp/empty-cache

ENV TZ=Asia/Tokyo
# --fromで前半で記述したAS buildと命名した中間イメージから必要なファイルのみ抽出する事ができる(distディレクトリにtsコンパイル結果であるjsファイルが出力されている)
COPY --from=build /build/dist ./dist

CMD [ "npm", "start" ]
```

# Github連携でHacobuneにDiscord Bot導入

1. **プロジェクト**から**Discord Bot用プロジェクト**を**新規作成**する。
今回はテストなのでDiscord Botという名前と適当な説明を入力し、**作成**ボタンをクリックします。
![hacobune01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/d40d50b0-1e5b-986e-8c26-ec171436430a.png)
![hacobune02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/b22368da-b35c-b75c-1ae5-d4b3b33b9342.png)
![hacobune03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/b21943b1-2bb9-ca83-4409-bebc23138fcf.png)

1. **アプリケーション**からDiscord Botのアプリケーションを**新規作成**する。
今回は**Github連携**でソースを取得するので、**必要な情報を入力**し、**Github**をクリックしてDiscord Bot用の**Repository**を選択します。
![hacobune04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/d9c7f143-b351-9a61-1734-6151be3f257d.png)
![hacobune05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/9f391c47-80ff-aef1-3d5b-b6c02bc863af.png)
1. Botの起動に**.env**ファイルが必要なので**設定ファイル**から追加します。
設定ファイルのモーダルに**事前に用意**した**Discord BotのToken**を入力し、**作成**ボタンをクリック。
入力する内容は以下の形式で入力します。もしご自身のプロジェクトで他にも環境変数があるのであればこちらから追加してください。
```DISCORD_TOKEN=コピーしたDiscordのBot Token```
![hacobune06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/06a6594a-aefb-da3f-b26b-8805f091e62d.png)
![hacobune07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/8f2ca028-33e4-b8cf-0644-bcffebbc5be7.png)
**作成**ボタンをクリックすると、入力したファイルが追加されていることがわかります。もし**Tokenを変更したい**場合は、**編集**から**変更**できます。
![hacobune08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/d75800fc-3d37-6e84-4c5d-1ea15904e4fc.png)
1. **その他は変更せず**に**作成**ボタンをクリック。
今回はリソースプランをフリーで作成していますが、もしBotからのレスポンスが遅いと感じた場合は上位のプランに変更することをおすすめします。
![hacobune09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/6d2adc63-558d-8805-aa7d-877c8a955fc9.png)
1. **追加したbotのアプリケーション**から**ログ**をクリックし、ビルドとアプリケーションのログを確認します。。
Dockerのビルドをリアルタイムで確認できますので、何かエラーがあればここから確認してください。
`Successfully`とビルドが成功したら、**アプリケーションログ**をクリックしてブラウザをリロードしてください。
`Connected to Discord successfully!`と表示されて、ビルド完了しステータスが稼働中になっているはずです。
![hacobune10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/e4c63903-1427-d9fc-1807-78ed0b21f27b.png)
![hacobune11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/e3b4eea7-6f0e-a024-3170-b5a8bfa1c641.png)
![hacobune12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/614828e7-aecb-6574-2e45-4c349d29accd.png)
![hacobune13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/23128dc6-9f2a-7f93-37e9-cf2cccdacf2d.png)
1. **Botを招待したDiscordチャンネル**のオンラインステータスを確認し、追加した**Botアカウントがオンライン**になっていれば**成功**です。
![hacobune14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/92dc2cca-c307-cf81-196d-e4c24a13eed5.png)

# 起動確認

オンラインが確認できるチャンネルで`!ping`とメッセージを入力するとボットから`pong`と返信があることがわかります。
これで**Hacobune**での**Discord Botの起動が成功**しました。
![bot-test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901444/04917ae6-7ebf-07a6-8483-17f2535d450d.gif)

# まとめ

Dockerで動くBot環境があれば簡単にHacobuneで環境を用意できます。
今なら無料で試すことができるのでDiscord Bot開発をしている人はぜひ試してください。

https://www.sakura.ad.jp/information/announcements/2021/08/12/1968207782/