SlackでリアクションBotをつくろう！（GAS）

# はじめに
Slack でリアクションBotをつくろうとしたら思いの外ハマったので備忘録。 
GAS を使います！

# 成果物
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ゴリラの後に１５種類のうんちをつけるBotができたよ😆 <a href="https://t.co/REtkoDYgfd">pic.twitter.com/REtkoDYgfd</a></p>&mdash; am10 (@am103141592) <a href="https://twitter.com/am103141592/status/1262645544389734400?ref_src=twsrc%5Etfw">May 19, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

我々の Slack はうんち絵文字が充実している:smirk: 
すぐにゴリラリアクションを消せばだれがうんち付けたかは迷宮入りになる。。。 （うんちリアクションは Bot が付けたことになります）

# つくりかた
## 手順
1. GAS作成（公開してURLメモ）
2. Slack App作成（権限設定してトークンメモ）
3. GAS修正（トークン付与、Bot実装）
4. Slackチャンネルにアプリ追加

## 1. GAS作成（公開してURLメモ）
<img width="300" alt="gas_1" src="https://user-images.githubusercontent.com/34936885/82292706-540eb800-99e6-11ea-887c-2a1889f58804.png">

上記のようにGASプロジェクトを新規作成して下記コードを記述して保存する。

```js
function doPost(e){
  var json = JSON.parse(e.postData.getDataAsString());
  return ContentService.createTextOutput(json.challenge);
}
```

公開 -> ウェブアプリケーションとして導入... で下記のように設定し Deploy して表示される Current web app URL をコピーしておく。

<img width="300" alt="gas_2" src="https://user-images.githubusercontent.com/34936885/82292730-5b35c600-99e6-11ea-9d38-1fc8034bcaf9.png">

## 2. Slack App作成（権限設定してトークンメモ）
[Slack API](https://api.slack.com/apps?new_app=1) にアクセスして Create New App をクリックして App Name と Workspace を入力する。

Event Subscriptions のページを開き Enable Events を ON にする。Request URL に先程コピーした URL を入力する。問題なければ下記のように Verified と表示される。

<img width="500" alt="slack_1" src="https://user-images.githubusercontent.com/34936885/82321231-7c5edc80-9a0f-11ea-8c35-03f52b8c851e.png">

Subscribe to bot events で Add Bot User Event をクリックし、reaction_added を追加して Save Changes をクリックする。

<img width="300" alt="slack_2" src="https://user-images.githubusercontent.com/34936885/82292829-84565680-99e6-11ea-9c12-61b0557e9978.png">

OAuth & Permissions のページを開き Bot Token Scopes に reactions:write を追加して Install App to Workspace をクリックする。（reactions:read も無ければ追加する）

<img width="300" alt="slack_3" src="https://user-images.githubusercontent.com/34936885/82292855-8ddfbe80-99e6-11ea-9b66-1fed57f9a6c7.png">

Bot User OAuth Access Token が表示されるのでコピーしておく。

<img width="300" alt="slack_4" src="https://user-images.githubusercontent.com/34936885/82292900-a3ed7f00-99e6-11ea-978a-5dcc5003b291.png">

## 3. GAS修正（トークン付与、Bot実装）
GASを下記のように修正する。

```js
function doPost(e){
  // 追加のトリガーとなるemoji
  var reaction_torigger_emoji = "gorilla";
  var json = JSON.parse(e.postData.getDataAsString());
  var event = json.event;
  if (event.type === "reaction_added") {
    if (reaction_torigger_emoji.indexOf(event.reaction) >= 0) {
      addReaction(event.item);
    }
  }
  return ContentService.createTextOutput(json.challenge);
}

function addReaction(item){
  var token = PropertiesService.getScriptProperties().getProperty('SLACK_ACCESS_TOKEN');
  var method = 'post';
  var url = 'https://slack.com/api/reactions.add?' + 'token=' + token + '&channel=' + item.channel + '&timestamp=' + item.ts + '&name=';
 
  var payload = {};
  var params = {
    'method': method,
    'payload': payload
  };
  // 追加対象のemoji
  var reaction_emojis = [
    "fucking_apple", "fucking_google", "fucking_docomo",
    "fucking_emojidex", "fucking_facebook", "fucking_htc",
    "fucking_joypixels", "fucking_lg", "fucking_messenger",
    "fucking_mozilla", "fucking_ms", "fucking_openmoji",
    "fucking_softbank", "fucking_twitter", "fucking_whatsapp"
  ];
  for (var i = 0; i < reaction_emojis.length; i++) {
    Utilities.sleep(1000);
    UrlFetchApp.fetch(url + reaction_emojis[i], params);
  }
}
```

ファイル -> プロジェクトのプロパティ -> スクリプトのプロパティから下記のように先程コピーしたトークンを追加する。

<img width="300" alt="gas_3" src="https://user-images.githubusercontent.com/34936885/82293005-c8e1f200-99e6-11ea-831e-137ee865f4b1.png">

ファイル -> 版を管理... -> Save new version でバージョンを追加する。 
公開 -> ウェブアプリケーションとして導入... -> Project version に追加したバージョンを設定して更新する。
許可画面が表示されるので適宜許可設定を行う。

## 4. Slackチャンネルにアプリ追加
Slackを開いてアプリを追加したいチャンネルの詳細 -> アプリ追加から作成したアプリを追加する。

<img width="150" alt="slack5" src="https://user-images.githubusercontent.com/34936885/82293208-2d9d4c80-99e7-11ea-9339-c99d2ef4f9d6.png">

完成！！:tada:

# ハマりポイント
色々ハマったポイントがあるのでそれぞれの解決策です。

## Event Subscriptionsがちゃんとできているかわからない
最初まったくリアクションしてくれなくて Slack のリアクションを GAS で本当に受けているのか？:thinking:となりました。 
下記のように Slack でリアクションしたときに doPost のログが表示されれば Event Subscriptions の設定は問題ありません:clap: 
表示 -> Stackdriver Logging -> Apps Script ダッシュボードを開いてフィルタをクリアをクリックすると下記のように doPost が呼ばれていることが確認できます。

<img width="400" alt="log" src="https://user-images.githubusercontent.com/34936885/82293159-152d3200-99e7-11ea-8f21-f4195c66d3cf.png">

## reactions.add APIが機能しているかわからない
reactions.add API でトークンや他のパラメータの設定などが正しいのか？となり調べてみると私の場合はこの設定が良くなかったみたいです:grimacing:

とりあえず GAS とは別で API を試してみるのが良さそうです。リアクション追加の API に必要なのは下記パラメーターです。

* token: アクセストークン
* channel: 投稿するチャンネルID
* timestamp: 投稿した時刻
* name: 追加するリアクション

必要なパラメータを取得するため Slack で適当なメッセージのリンクをコピーします。URLは下記のようになっているはずです。 

```
https://[ワークススペース名].slack.com/archives/[チャンネルID]/p[投稿時刻]
```

「投稿時刻」はエポックマイクロ秒で記載されており、これを小数点付きのエポック秒に変換する必要があるようです。

ex. 1234567890123456 => 1234567890.123456

※ 参考：[[Slack]API経由でreaction (add emoji)](https://qiita.com/taumu/items/59cf09fc06300946de8d#url%E3%81%AB%E5%BF%85%E8%A6%81%E6%83%85%E5%A0%B1%E3%81%8C%E8%A8%98%E8%BC%89%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%AE%E3%81%A7%E3%83%91%E3%83%BC%E3%82%B9%E3%81%99%E3%82%8B)

ターミナルで下記コマンドを実行し、指定のメッセージにゴリラリアクションがつけば成功です:clap:

```
curl -X POST 'https://slack.com/api/reactions.add?token=xxxx-xxxxxxxxx-xxxx&channel=[チャンネルID]&timestamp=[投稿時刻]&name=gorilla'
```

パラメータは JSON で送信するのかと思ったらクエリストリングじゃないとエラーになるようでした。。。

### エラー色々
* missing_charset: パラメータをJSONで送っているなど
* channel_not_found: チャンネルにアプリ追加していないなど
* not_authed: トークンが違うなど

詳しくは[ドキュメント https://api.slack.com/methods/reactions.add](https://api.slack.com/methods/reactions.add)をどうぞ

# おまけ
下記記事を参考にすると簡単にオリジナルコマンドが作成できます！ 
[Slash CommandsとGASでSlackのオリジナルコマンドをつくる](https://qiita.com/chikuwa111/items/7a1a349b82318a5861cc)

わたしは `/punch` で約 100 種類のパンチが打てるコマンドを作成しました！！

![punch](https://user-images.githubusercontent.com/34936885/82294396-09426f80-99e9-11ea-989f-4e5faf4dc909.gif)

# さいごに
GAS を使うと気軽にSlackで遊べるので大変良いです:laughing:
みんなも GAS と Slack で遊ぼう！ 
（Twitterの埋め込みをやってみたかった:sunglasses:）

# 参考
* [Slackで特定のスタンプ(リアクション)に反応するサーバレスボットをGASで作成してみた](https://qiita.com/tez/items/babf47f94c7d3f6f2ce6)
* [[Slack]API経由でreaction (add emoji)](https://qiita.com/taumu/items/59cf09fc06300946de8d)