discord.js で Bot を作成して Heroku で永続稼働させる

# 環境
- macOS Mojave 10.14.3

# 事前準備
## Homebrew のインストール
https://qiita.com/naente_dev/items/1195ff834c65be4be5a6

## nodebrew および Node.js のインストール
https://qiita.com/kyosuke5_20/items/c5f68fc9d89b84c0df09
こちらの記事を参考に導入しました。

## Discord Bot の登録
[Discord Developer Portal](https://discordapp.com/developers/applications/) ページにアクセスします。
![FireShot Capture 028 - Discord Developer Portal — My Applications - discordapp.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/743e49ac-a2c9-5759-9149-982840523d2d.png)
 **New Application** ボタンをクリックします。
![FireShot Capture 029 - Discord Developer Portal — My Applications - discordapp.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/7ea29815-4e07-97bd-d6b6-2cf0a2b18d19.png)
**NAME** 欄に任意のアプリケーション名を入力して **Create** ボタンをクリックします。
![FireShot Capture 030 - Discord Developer Portal — My Applications - discordapp.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/9e510ca0-795c-937e-cf58-c4df3e6d4dc9.png)
アプリケーションの作成に成功すると **General Information** ページにリダイレクトされます。
左側の **SETTINGS** メニューから **Bot** を選択します。
![FireShot Capture 031 - Discord Developer Portal — My Applications - discordapp.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/450ea73f-1daa-709c-6c17-268432acce52.png)
**Add Bot** をクリックします。
![FireShot Capture 032 - Discord Developer Portal — My Applications - discordapp.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/01300a63-8f0d-2c6b-6803-7e71f8dc59ab.png)
**Yes, do it!** をクリックします。
![FireShot Capture 033 - Discord Developer Portal — My Applications - discordapp.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/0dbefbb0-06db-9608-3d37-23d646788835.png)
Bot が追加されました。

**TOKEN** 欄の **Copy** ボタンをクリックして、Bot のトークンをコピーします。
開発時に使用するので、どこかに控えておきます。

続いて、左側の **SETTINGS** メニューから **OAuth2** を選択します。
![FireShot Capture 034 - Discord Developer Portal — My Applications - discordapp.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/e4d7b1af-96eb-620e-37c6-ec63c43ce0e3.png)
**OAuth2 URL Generator** - **SCOPE** 欄にある **bot** のチェックボックスを選択すると
オーソライズ URL が表示されるのでコピーして、アクセスします。
![FireShot Capture 035 - アカウントへのアクセスを許可します - discordapp.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/c4bd5810-7ef0-55ca-8acc-4114a67177c8.png)
Bot を追加したいサーバーを選択して **認証** ボタンをクリックします。


Bot を追加できるのは自身が管理者権限を所持しているサーバーに限定されます。
権限の無いサーバーは一覧に表示されません。
<img width="538" alt="スクリーンショット 2019-10-20 11.28.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/11eb28bc-1677-d51b-394d-45a613d1b721.png">
<img width="235" alt="スクリーンショット 2019-10-20 11.29.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/1400f5e9-00ee-12ce-248d-73c3e8d18dd3.png">
サーバーに Bot が追加されましたが、この時点ではまだオフラインです。


# 開発
例として `MyDiscordBot` というディレクトリを作成して、その中で開発を進めていきます。

```bash
$ mkdir MyDiscordBot
$ cd MyDiscordBot/
```

## discord.js のインストール

https://discord.js.org/

```bash
$ npm install discord.js
略
+ discord.js@11.5.1
added 7 packages from 6 contributors and audited 7 packages in 2.183s
found 0 vulnerabilities
```

成功するとカレントディレクトリ内に
`discord.js` および依存ライブラリを含む `node-modules` ディレクトリと
`package-lock.json` ファイルが作成されます。

## コーディング

`MyDiscordBot` ディレクトリの直下へ `index.js` を作成します。

以下、公式リファレンスに記載されている `ping` と発言すると `Pong!` とリプライしてくれる Bot の
コードとなります。
（トークン部分のみ定数化しました）

```javascript:MyDiscordBot/index.js
const Discord = require('discord.js');
const client = new Discord.Client();
const BOT_TOKEN = '***********************************************************';

client.on('ready', () => {
    console.log(`Logged in as ${client.user.tag}!`);
});

client.on('message', msg => {
    if (msg.content === 'ping') {
        msg.reply('Pong!');
    }
});

client.login(BOT_TOKEN);
```

`BOT_TOKEN` には [Discord Developer Portal](https://discordapp.com/developers/applications/) ページで取得した Bot のトークンを
設定してください。


## Node.js ローカルサーバーで Bot を起動

```bash
$ node index.js
Logged in as Application Name#0000!
```
<img width="235" alt="スクリーンショット 2019-10-20 12.54.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/b2f561d0-d766-d643-6689-7d580864574a.png">
Bot がオンラインになりました。

<img width="545" alt="スクリーンショット 2019-10-20 12.57.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/2268856b-172d-5a10-c94f-7843ba9ede63.png">
`ping` と発言すると `Pong!` とリプライしてくれます。


# デプロイ

このままでは自身の端末で Bot を起動している時のみしか利用できない為、
今回は Heroku にデプロイしてみます。

## Heroku を利用した永続起動
https://qiita.com/InkoHX/items/590b5f15426a6e813e92

こちらの記事を参考に Heroku への登録〜デプロイまでを実施しました。

### 補足

```bash:
$ git push heroku origin --force
```

[デプロイしよう](https://qiita.com/InkoHX/items/590b5f15426a6e813e92#%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%81%97%E3%82%88%E3%81%86)の箇所に記載されている上記のコマンドではプッシュできなかった為、
下記コマンドで対応しました。

```bash:
$ git push heroku master --force
```

## Heroku タイムゾーンの設定
Heroku のデフォルトタイムゾーンは UTC（協定世界時）ですので
日本時間と 9時間の遅れがあります。

タイマー処理など時刻に関する処理を実装する予定があれば JST（日本標準時）に変更しておきましょう。

https://qiita.com/ikemura23/items/52ab8a5d260c7ee4d42b

こちらの記事を参考に設定させていただきました。


## Heroku コマンド抜粋

```bash
$ heroku ps
```
dyno 無料分の残時間や使用時間、Web/Worker の稼働状態を確認できます。

```bash
$ ps:scale worker=0
```
Worker dyno のスケール数を 0 にできます。

```bash
$ ps:scale worker=1
```
Worker dyno のスケール数を 1 にできます。