今更Slackで遊ぶために、新しいカスタム絵文字の追加を報告させてみた

# 実装に至った流れ
前社では社内SNSにSlackを用いています。治安の悪い絵文字が追加されると登録した人が自ら宣伝しない限り気づく人が少ないのですが、
宣伝されると、お祭りのように絵文字で騒ぐあの感じが結構好きなので、登録されたらすぐにでも騒ぎたくて作りました。

そもそもbotちゃんを作った経験は全くなかったのですが、`Event Subscriptions`で簡単に実装できると聞いたのでさらっと作っちゃいました。

#実装に必要なものと実装の流れ

## 必要なもの
- 外部からアクセスできるサーバ（URLがみれりゃなんでもいい)
- 時間(無知でも１時間程度でできました）
- やる気

## 流れ

1. Slackの管理画面からアプリケーションを追加
2. 外部から発言するためのWebhook URLを作成
3. Eventを登録して、その際に呼び出されるURLを設定
4. 呼び出されるURLのプログラムを実装

終わり！:muscle::stuck_out_tongue_closed_eyes:

SlackはAPIが豊富なので実装も簡単で、
request bodyにはめられているjsonを読み込んだり、
Slack指定のURLを叩いたりするだけでしたいことが一瞬でできるみたいです！


#いざ実装
今回作るものは以下です。

  誰かがカスタム絵文字を登録する
->Slackがイベントを検知して用意してあるURLを呼び出してくれる
->呼び出されURLからbotに#randomにて新しい絵文字が追加されたと発言する

## １）Slackの管理画面からアプリケーションを追加
何をするかっていうと、APIを利用するためにまずはアプリケーションというものを作ります。

1. まず絵文字検知したいWorkspaceにログインしている状態で以下にアクセスします。  
https://api.slack.com/apps
2. <img width="144" alt="スクリーンショット 2018-09-20 18.37.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/38c4c055-de02-2d62-fef1-3c673c1ebf3b.png">を選択して、表示されたポップアップを以下を参考に入力して**[Create App]**！  
<img width="564" alt="スクリーンショット 2018-09-20 18.39.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/b4b0de2f-a550-abbd-cc9d-f83ca6176596.png">
3. Basic Informationというページに遷移しましたね。基本的な設定はこちらに表示されている通りに進めれば問題なくできると思います！  
<img width="981" alt="スクリーンショット 2018-09-20 18.51.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/b87c8d65-d3f1-068d-20c8-3dc109844910.png">


## ２）外部から発言するためのWebhook URLを作成
1. **[Add features and functionality]**を押して、**[Incoming Webhooks]**を選択してください。(もちろん、サイドバーからの移動でも同じページです)  
2. 遷移した先で、`Activate Incoming Webhooks`と書かれている右のtoggle<img width="77" alt="スクリーンショット 2018-09-20 18.58.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/0c69dd77-5a85-bbf1-6d0d-3e8a232f434b.png">をクリックして、<img width="73" alt="スクリーンショット 2018-09-20 18.58.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/c856c15b-1612-c114-65ee-7b43caf3a3d7.png">になったら下へスクロールし、<img width="260" alt="スクリーンショット 2018-09-20 19.00.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/b0550178-2b73-45e7-6972-eac8c0d155bc.png">もクリック!　　
3. 開いたページでは、絵文字を検知した時に呟かせるチャンネルを選んでください。  
<img width="508" alt="スクリーンショット 2018-09-20 19.00.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/897c1f5e-277a-00dc-0aef-77d1c0149c3b.png">  

これで、呟く準備は完了です！ 
表示されているコマンドを叩くと選択したチャンネルで発言されると思います！  

```
# urlの部分を先ほど追加したwebhook URLに変更して使ってください
curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, World!"}' https://hooks.slack.com/services/AAAAAAAAA/BBBBBBBBB/XXXXXXXXXXXXXXXXXXXXXXXX
```
こんな風に該当チャンネルで表示されると思います！
<img width="515" alt="スクリーンショット 2018-09-20 19.11.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/0e0490ba-8112-7a9d-e7d6-a9a33304ee85.png">

## ３）Eventを登録して、その際に呼び出されるURLを設定
1. サイドバーから**[Event Subscriptions]**をクリックして、先ほどと同じようにtoggleをoffからonに。  
いろんな項目が表示されましたが、触るのは２つだけです `Request URL`と`Subscribe to Workspace Events`だけです。
2. まずは、`Subscribe to Workspace Events`を設定しましょう。これが、発火元です。今回でいうと、「カスタム絵文字が登録されたら」の部分です。残念ながら、「登録」だけというイベントはないので、カスタム絵文字に何か変更があったら、というイベントを指定しましょう。  
<img width="177" alt="スクリーンショット 2018-09-20 19.25.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/dc76d75a-6a1f-75d4-8115-87c0c8439edc.png">
を押して、`emoji_changed`を選択してください。
3.今度は発火後にアクセスするURLの設定をします。`Request URL`にプログラムをのせるURLを設定してください。  
ここで記入した後、エラーが出ましたか？ 実は、SlackからURLの確認のためのアクセスが行われていたのです。  
<img width="701" alt="スクリーンショット 2018-09-20 20.24.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/819ab135-6275-80a1-5bcb-cb3832c562ac.png"><br>
このSlackの確認でしなければいけないことは簡単で、Request Bodyにある`challenge`をそのまま返却すればいいだけです。詳しくは[こちらに記載](https://api.slack.com/events/url_verification)されています。プログラムの準備ができたら、**[Retry]**を押して再度確認させましょう！<br><br>
以下は私の使ったものです。

```php
<?php
$body = file_get_contents('php://input');
$json = json_decode($body, true);

// 必要ないかもしれないが、一応Content-type指定
header('Content-type: text/plain; charset=utf-8');
echo $json['challenge'];
exit;
```
確認がうまくいくと以下のように表示されます。
<img width="694" alt="スクリーンショット 2018-09-20 20.41.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/c406d911-0c60-2e45-728d-6ac060d65195.png">
3. 設定を終えたら、画面下部の<img width="126" alt="スクリーンショット 2018-09-20 20.43.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/0dd45837-2fa0-2bd4-ca8e-f0513163d375.png">をクリックしてください！
4. 画面が更新されると、以下が表示されると思います。（されない場合は画面を更新してください)  
アプリケーションの権限を追加したので、再度Workspaceの許可を得ないといけなくなったよー、的なことです。書かれている通り、**[click here]**をクリックして、権限を許可しましょう。
<img width="872" alt="スクリーンショット 2018-09-20 21.27.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/a268dcc6-8231-8400-317e-d58a46d22f11.png">  


さて、これで絵文字に何かしら変更があった時に、設定したURLへ情報が送られるようになりました!


## ４）呼び出されるURLのプログラムを実装
あとは簡単、プログラムを実装するだけです。
その前に、`emoji_changed`というイベントはどのようなパラメータを送ってくれるのでしょうか、確認しましょう。
APIドキュメント: https://api.slack.com/events/emoji_changed

ふむふむ、以下のようなデータが来るみたいです

```json
{
    "type": "emoji_changed",
    "subtype": "add",
    "name": "picard_facepalm",
    "value": "https://my.slack.com/emoji/picard_facepalm/db8e287430eaa459.gif",
    "event_ts" : "1361482916.000004"
}
```
`subtype`にaddかremoveが入る。
`name`が登録した絵文字の名前。つまり:emoji_name:で絵文字が表示できる。
`value`には登録された絵文字の画像urlか、エイリアスなら、`alias:{元の絵文字の名前}`が来るみたい。
では、新しい絵文字だけ検知するには`subtype`が`add`で、`value`が`alias:`で始まらないもののみ処理すれば良さそうですね。簡単そうだ。

気をつけるところといえば、実際に来るRequest Bodyは以下のような形なので、PHPで受け取る時はevent以下だけを見るようにしてください。

```json
{
    "token": "XXXXXXXXXXXX",
    "team_id": "XXXXXX",
    "api_app_id": "XXXXXX",
    "event": {
        "type": "emoji_changed",
        "subtype": "add",
        "name": "emoji_name",
        "value": "https:\/\/emoji.slack-edge.com\/BBBBBB\/emoji_name\/XXXXXXXX.jpg",
        "event_ts": "1537445467.000100"
    },
    "type": "event_callback",
    "authed_teams": ["XXXXXX"],
    "event_id": "XXXXXXXX",
    "event_time": 1537445467
}
```


ひとまず、私の利用したPHPです。

```php
<?php
$body = file_get_contents('php://input');
$json = json_decode($body, true);

// 気休めパラメータチェック
if ($json === false || empty($json['event'])) exit;

// 登録でない、もしくはエイリアスの追加の場合は何もしない
if (strpos($json['event']['subtype'], 'add') === false
 || strpos($json['event']['value'], 'alias:') !== false) exit;

$emoji = $json['event']['name'];
$msg = "新たな絵文字だよ！\n【{$emoji}】:{$emoji}:\n";
$msg_json = json_encode(['text' => $msg]);

// 悪い子なのでexec()とか使っちゃいます
// urlに関しては(2)で発行したWebhook URLです！
exec("curl -X POST -H 'Content-type: application/json' --data '". $msg_json. "' https://hooks.slack.com/services/XXXX/XXXXX/XXXXXXXXXXXX);
exit;
```

では、いざ、カスタム絵文字を追加してみてください。指定したチャンネルへ投稿があるはずです！
<img width="528" alt="スクリーンショット 2018-09-20 21.56.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/c9e18271-1414-c92b-4e0b-1e91998ae0e4.png">
やった！成功です！:relaxed:

# 余談: botちゃんの画像がイケてないから変えちゃいたい
もちろん、変えられます。
サイドバーの[Basic Information]へ移動して、ページ下の方の`Display Information`で変更できます。
<img width="755" alt="スクリーンショット 2018-09-20 21.59.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/84532/ce8f291c-a12f-2701-9694-68fb69dca3f7.png">



以上です！　かしこ:laughing: