自主的20%るぅる

各々が自主的に好き勝手書くゆるふわ会社ブログ

SlackのIncoming/OutgoingなWebhookでChatOpsと言い張るなにかを作った話(Outgoing Webhook編)

実装編だよ〜

さてさて、前回書いた計画編の内容を元に、実装を進めていくことにしましょう。

じゃあ作り始めよ〜!

さて、下ごしらえが終わったところで、コーディングとかして実際のシステムを作っていきましょう。

色々なやり方があるので、とりあえずサクッと作れそうな方法で作っていきます。

未知なる力に目覚めてもらう

まずは、未知なる力に目覚めてもらう必要があります。

Slackの特定チャンネルで発言があったことをサーバさんにも知ってもらわないと話が進みませんからね。

具体的には、SlackのOutgoing Webhookを使ってみることにします。

まずは使えるようにしよう!

権限を持ったユーザでログインして、https://www.slack.com/apps/A0F7VRG6Q-outgoing-webhooksにアクセス。

一度も使ったことがなければ、「Sign in to install」とか書いてある緑のボタンがあるのでそれをポチッとな!

使ったことがあったりすれば、「Add Configuration」って緑のボタンがあるのでそれをポチッと!

するとこんな画面になったりするはずなので、「Add Outgoing WebHooks integration」って書いてある緑のボタンをクリック!

pic01_resized

設定画面!

するとこんな感じの設定画面が出てきます。上半分が説明、下半分が設定項目ですね。

pic02_resized

各設定項目を個別に見てみませぅ。

項目名 必須 説明
Channel Yes コイツを有効にするチャンネルを指定。Anyなら全チャンネル。
Trigger Word(s) Yes コイツをキックするきっかけとなる魔法の言葉。複数設定したければcommaで区切ればOK。
URL(s) Yes キックされたときにPOSTするURL。複数指定したければ、1行1URLとなるように書けばOK。
Token Yes POSTされる値に含まれるトークン。自分のSlack Teamからキックされたことを確認したいときに使うとよさげ。当然ヒミツにしておく。
Descriptive Label No Integrationの一覧画面で識別するためのアレ。書かなくてもいいけど、書いとかないと数が増えたとき泣きを見る。
Customize Name No こいつのユーザ名。何でもOK。デフォルトのままでもOK
Customize Icon No コイツのアイコン。画像をアップロードするか絵文字を指定することも可。デフォルトのままでもOK。
Preview Message この設定でどんな感じになるかのプレビュー。確認して置くと吉。

一言で言えば、「Channel」で指定したチャンネルで、「Trigger Word(s)」に指定されたワードを検知したら、「URL(s)」で指定されたURLにPOSTされてくる……って仕組みですね。

具体的にはこんな感じのデータがPostされてくるので、「URL(s)」に指定されたURLではこれらをうまいこと使ってアレすればOk。

token=abcdefghijklmnopqrstuvwxyz
team_id=T1234
team_domain=example
channel_id=C123456789
channel_name=test
timestamp=1355517523.000005
user_id=U123456789
user_name=Steve
text=googlebot: What is the air-speed velocity of an unladen swallow?
trigger_word=googlebot:

紋章が刻まれし左手に封印された漆黒の龍(ドラゴン)をたたき起こす

Slackの方はできたので、SlackからのPostデータを受け取る側を作りましょう。言語は何でもいいんですけど、私はPHPで作ってみました。

<?php
// 各種設定を保持
define('TOKEN', 'abcdefghijklmnopqrstuvwxyz');
define('ACCEPT_TEAM', 'T1234');
define('ACCEPT_CHANNEL', 'C123456789');

define('PATH_DEPLOY', '/tmp/deploy');

// POSTデータが送られてきたときのみ処理
if (isset($_POST) and !empty($_POST)) {
    // セキュリティチェック(簡単にね(;´Д`))
    if ($_POST['token'] == TOKEN and $_POST['team_id'] == ACCEPT_TEAM and $_POST['channel_id'] == ACCEPT_CHANNEL) {
        // キーワード設定に応じて処理を変える
        switch ($_POST['trigger_word']) {
            case 'deploy':
                // 先行タスクが実行されてないときだけ実行
                clearstatcache(true);
                if (!file_exists(PATH_DEPLOY)) {
                    // デプロイ要求ファイルを作成してメッセージを作成
                    touch(PATH_DEPLOY);
                    $text = '<@' . $_POST['user_id'] . '|' . $_POST['user_name'] . '>さんからの要求に従ってデプロイをリクエストしたよ!';
                } else {
                    $text = '<@' . $_POST['user_id'] . '|' . $_POST['user_name'] . '>さんからデプロイ依頼を貰ったけど、今実行中だから無理だよ!';
                }
                break;

            default: // NO OP
                $text = null;
                break;
        }

        // Slack側に突き返すメッセージを生成
        if ($text) {
            $payload = ['text' => $text];
            echo json_encode($payload);
        }
    }
}

簡単に流れを整理しておきますと……。

  1. Postデータが存在するかをチェック
  2. SlackからPostされたかを、token、team_id、channel_idでチェック
  3. triger_wordが既知のものかをチェック
  4. すでにデプロイが進行中かをチェック
  5. デプロイしてもOKな状況ならデプロイ指示ファイルを作成
  6. Slackにお返事メッセージを送りつける

まあ、こんな感じです。

これで、Slackのメッセージに応じて、サーバさんとお話しできるようになりました!やったね!

後半に続くんぢゃ!

さてさて、長くなってしまったので今回はこの辺で。

唐突に出てきた「デプロイ指示ファイル」の謎についても次回ご説明しますね〜。

Let’s share this article!

{ 関連記事 }

{ この記事を書いた人 }

アバター画像
Yuta Hayakawa

2016年6月入社。2020年12月より取締役に就任しました。

普段は東京本社で管理職のお仕事したり、広報的役割としてテキスト書いたり動画作ったりするのが最近のお仕事。

自称「社内システムチーム統括」として、社内システムチームの面々を見守りつつ毎日を過ごしています。

プライベート面では、音楽やコンピュータ関連、ゴルハム&ジャンハム関係、ゲーム関係が興味あるポイント。

あと、我が子可愛い。

記事一覧