DenoとCowardでDiscordBotを作ってみる

# お知らせ
Cowardはアーカイブされました。今後更新される可能性はありません。この記事を見て作ってみようとしている方は、別のフレームワークを使用してください。
また、既に使用している場合でも、早急に移行することを推奨します。
https://github.com/itjk/coward

# はじめに
最近、「Deno」なるものを知ったので「もしやDiscord APIのラッパーあるんじゃね」と思ったらやっぱりすでにいろいろな物がありました。
今回はDenoとDiscord APIのラッパー「Coward」でDiscordBotを作ってみます。

# 前提条件
* 事前にDenoはインストールしておいてください。Macなら`brew install deno`でインストールできます。
* Denoはv1.0.2を使用しています。
* Cowardはv0.2.0を使用しています。
* 私自身DenoやTypeScript等の知識が余りありません。ご了承ください。

# 作ってみる
**注意:Bot作成を飛ばしていますがすでに様々な記事で解説されているので、検索してみてください。**
では早速ですが作ってみましょう。とりあえずCowardの[README.md](https://github.com/fox-cat/coward/blob/master/README.md)の"Ping-Pong Example"をコピペして使ってみます。

```typescript:main.ts
import { Client } from "https://deno.land/x/coward/mod.ts";

let client = new Coward("TOKEN");

client.evt.ready.attach(() => {console.log("Bot is ready!")});

client.evt.messageCreate.attach(async ({message}) => {
    if(message.content == "!ping") {
        await client.postMessage(message.channel.id, "Pong!");
    }
});

client.connect();
```

結果:
![スクリーンショット 2020-05-28 15.40.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457036/2daf3b6a-14fa-7b9b-0798-025d217c1fec.png)

<details>
<summary>could not connect to websocketが発生する場合</summary>
![スクリーンショット 2020-05-28 16.24.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457036/b0a5526a-3648-3d24-f6c0-2feefe569003.png)
そのまま`deno run main.ts`と実行すると、エラーが発生する場合があります。
その場合は、実行するコマンドに`--allow-net`を追加してみてください。
Denoではセキュリティー周りがちょっと厳しいのでちゃんと許可しないと動いてくれません。
</details>

# もっと色々やってみる
## 例1:指定された語句の場合返答する
例) 「こんにちは」に対して「こんにちは！」と返答する。

```typescript:main.ts
    if(message.content == "こんにちは") {
        client.postMessage(message.channel.id, "こんにちは！");
        return;
    }
```

## 例2:指定された語句が含まれていた場合返答する
例) 「やば」が含まれるメッセージに対して「さすがに驚きました...」と返答

```typescript:main.ts
    if(message.content.match(/やば/)) {
        client.postMessage(message.channel.id, "さすがに驚きました...");
        return;
    }
```

## 例3:指定された語句が含まれていた場合リアクションする
例）「悲しい」が含まれていた場合😭とリアクションする
`message.id`でメッセージのID、`message.channel.id`でチャンネルIDが取得できます。

```typescript:main.ts
    if(message.content.match(/悲しい/)) {
        client.putReaction(message.channel.id, message.id, "😭");
        return;
    }
```

# 実行してみる
今までのコードをまとめて実行してみます。

```typescript:main.ts
import { Client } from "https://deno.land/x/coward@v0.2.0/mod.ts";

let client = new Client("TOKEN");

client.evt.ready.attach(() => {console.log("Bot is ready!")});

client.evt.messageCreate.attach(async({message}) => {
    if(message.content == "!ping") {
        client.postMessage(message.channel.id, "Pong!");
        return;
    }

    if(message.content == "こんにちは") {
        client.postMessage(message.channel.id, "こんにちは！");
        return;
    }

    if(message.content.match(/やば/)) {
        client.postMessage(message.channel.id, "さすがに驚きました...");
        return;
    }

    if(message.content.match(/悲しい/)) {
        client.putReaction(message.channel.id, message.id, "😭");
        return;
    }
});

client.connect();
```

![スクリーンショット 2020-05-28 16.15.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457036/901b50d3-ecc9-34b7-a5bc-eb9fbdf65540.png)
無事動きました:relaxed:

# まとめ
ということで、今回はDenoとCowardでDiscordBotを作ってみました。
とはいえ、まだCowardも始まったばかりですし、他にも様々なラッパーがあります。今後も注意深く見守っていきたいと思っています。
ここまで読んでいただきありがとうございました。以上です。
**追記**:今回の記事で書いたコードをGitHubにアップロードしました。ぜひご利用ください。(需要あるかわかりませんが)
https://github.com/seraimu/deno-coward-demo

# 参考

- https://qiita.com/cryptocoin_harumaki/items/5d8c503e02093eca1f9b
- https://github.com/fox-cat/coward/blob/master/examples/ping-pong/bot.ts
- https://doc.deno.land/https/deno.land/x/coward/mod.ts