Cloud FunctionsとSlash_commandでSlackからConnpassの情報を取得する

# はじめに
エンジニアが参加する外部勉強会といえば、多くはTechPlayやConnpassなどから探して応募しているのではないでしょうか。

参加イベントが増えてくると、各イベント詳細画面に行くのがめんどくさかったりします。
また、上司や先輩、よくイベントで見かける人などがどんなイベントにいっているのか気になったりもしますが、この辺もわざわざ追うのはめんどうです。

ということで、スラッシュコマンドを使って、いつでも最新の参加状況を人ごとにSlackから一覧取得できるようにしました。

# 作成手順
## Slash Command
まずは[こちら](https://pptdev.slack.com/apps)からSlash Commandを検索します。
すると、以下のような画面に行くかと思います。

![スクリーンショット 2018-04-11 1.53.05.png](https://qiita-image-store.s3.amazonaws.com/0/203817/e107ae8f-2b62-12e3-0147-0d85b3ba092e.png)

`Add Configration`から各種設定を行います。

Integration Settingsで主に利用する項目は以下の通りです。

- Command ・・・ 実際にSlack上で打つコマンド(今回は`/connpass`とします)
- URL ・・・ コマンド実行時に送られるWebhook(後で作成するCloud FunctionsのURLを入れます)
- Methods ・・・ POST/GET(POSTにします)
- Token ・・・ プログラム作成時に認証用に利用します、メモしておきましょう
-  Customize Name ・・・ Slackに表示されるBotの名前です
-  Customize Icon ・・・ Slackに表示されるBotのアイコンです



## Cloud Functions
Slash Commandの設定が終わったら、次は実際にコードを書いていきます。
サーバレスに作りたいので、GCPのCloud Functionsを利用します。

Cloud Functionsへのデプロイ方法は大きく3つあります。
- インラインエディタ
- Cloud Storageのzip
- Cloud Sourceレポジトリ

サクッと作るにはインラインエディタを用いると良いのですが、今回はモジュールを利用したいのでzipでデプロイしていきます。

### ディレクトリ構成
```
|- node_modules/
|- index.js
|- package-lock.json
└ package.json
```
### ソースコード
connpass　APIのnode SDKを作っている方がいるのでそちらを利用しました。

```index.js
const BOT_TOKEN = '(SlashCommandのToken)';
const connpass = require("connpass");

exports.getConnpass = (req, res) => {
    let returnMessage;

    if(req.body.token === BOT_TOKEN) {
        let text = "";
        //今月と来月のイベントのみに絞り込み
        const now = new Date();
        const thisMonth = ('0000' + now.getFullYear()).slice(-4) + ('00' + (now.getMonth()+1)).slice(-2);
        const nextMonth = ('0000' + now.getFullYear()).slice(-4) + ('00' + (now.getMonth()+2)).slice(-2);
        //検索したい人のユーザIDとSlack上への表示名を記入
        const users = [
            {id: 'userId1', name: '山本さん'},
            {id: 'userId2', name: '伊藤さん'},
            {id: 'userId3', name: '鈴木さん'},
            {id: 'userId4', name: '吉田さん'}
        ];
        getEvent(0);

        function getEvent(i) {
            connpass.get({order : 2, ym : `${thisMonth}, ${nextMonth}`, nickname : users[i].id})
                .then((result) =>{
                    text += `${users[i].name}\n`;
                    result.events.forEach((event) => {
                        text += `${ event.started_at.slice(0, 10) } : <${event.event_url}|${event.title}> \n`;
                    });

                    if(++i < users.length) {
                        getEvent(i);
                    } else {
                        //Slackに返すオブジェクト
                        returnMessage = {
                            'response_type': 'in_channel',
                            'text': text
                        };
                        res.status(200).send(returnMessage)
                    }
                })
                .catch((error) => {
                    console.log(error);
                });
        }


    } else {
        returnMessage = { 'text': '認証情報が異なります'};
        res.status(400).send(returnMessage);
    }
};
```

Slackへの投稿はオブジェクトの`text`フィールドの値がメッセージとして表示されます。
また、`response_type`で`in_channel`を指定するとBotの返信が全体公開となり、`response_type`をつけない場合はスラッシュコマンドを打った本人のみが見えるメッセージとなります。


### デプロイ

⑴ 上記の4つのファイル/ディレクトリを圧縮してzipにします。

⑵ [こちら](https://cloud.google.com/functions/docs/)から、ログインし、「コンソール」 → 「Cloud Functions」と移動します。

⑶ 関数の作成を行います。以下のものをそれぞれ設定します。
- 名前
- 割り当てられるメモリ
- トリガー(httpトリガーにします)
- ソースコード(zipアップロードを選択します)
- zipファイル(圧縮したzipをアップロード)
- ステージバケット(zipファイルを置く場所を選択してください)
- 実行する関数(exports.xxxxxの部分です。今回の例だとgetConnpassです。)

⑷ 設定完了したら、保存して閉じます。
デプロイが完了するまで数分かかるかもしれません。

⑸ 最後に、トリガーとなるURLをスラッシュコマンドのURLに記入して終了です。

# 動作確認 
これで、Slack上でスラッシュコマンドを叩けばBotが返してくれるようになるはずです。

![スクリーンショット 2018-04-11 2.56.17.png](https://qiita-image-store.s3.amazonaws.com/0/203817/b132bfdd-c5d3-e6ad-aabb-bc46d48f4175.png)

スラッシュコマンドはこういった欲しい時にだけ見に行くめんどうな情報取得には結構使えそうな印象です。
勤怠入力などにも使えそうですね。