PICK UP

Slack APIを使ってプッシュ通知を受け取ろう

LAB

山崎 康平

弊社では社内のコミュニケーション手段としてSlackを使用しています。
(弊社でのSlack紹介記事はこちら
最近は弊社メンバー以外でも「Slack使ってるよ」という話題をよく耳にしますので、着実にユーザ数が増えてきてるように感じます。

Slackは単にチャットができるだけではなく外部サービスとの強力な連携機能(Integrations)やAPIを備えていますので、チャットの通知機能(Mac・iOS・Android用アプリやChromeデスクトップ通知)とAPIを組み合わせることで、スマートフォンのアプリ等を作ることなく簡単にプッシュ通知の仕組みを作る事ができます。
このように様々な可能性を秘めているSlackのAPIですが、検索してみても意外と解説をしている記事が少ないのでサンプルソース(PHP5.2以上)を交えてご紹介したいと思います。

Slack Integrationsとは

integrations

Slack Integrations(以下Integrations)とはSlackと他のWebサービスを連携する機能のことです。
例えばIntergrationを使うと下記のようなことが可能になります。

  • GitHubでpullリクエストを受けたったらSlackに通知
  • Travis CIでテストに失敗したらSlackに通知
  • Nagiosが本番サーバの異常を検知したらSlackに通知
  • IFTTTのレシピで、スマホが社内のWiFiに接続したらSlackに通知
  • Hubotを育ててSlack上で特定のメッセージ(コマンド)でバッチ処理を実行

※無料枠のSlackで使用できるIntegrationsはチームで5個までとなります。(2014年10月20日現在)

欲張りな人向けに

Integrationsで連携できるサービスは60種類あります。(2014年10月20日現在)
これだけでも十分過ぎるぐらい豊富に用意されているのですが、下記のような理由で満足しきれない人もいるんじゃないでしょうか。

  • 普段愛用しているサービスがIntegrationsで用意されてないんだけど…
  • 用意されているIntegrationsだと満足できない!(僕はまだ感じたこと無いですが…)
  • 独自に作成したシステム上でSlack通知を組み込みたい!
  • Slack上に投稿されたメッセージを受け取ってプログラムをキックしたい!

有名なサービスやオープンソース(例えばRedmine等)であれば、サードパーティ製のプラグインが既に公開されている可能性があり簡単にSlackとの連携ができるかもしれませが、マイナーなサービスであったり独自のシステムとなるとそうもいきません…。

ならば作るしかない!

Slackでは上記のような要望に応えるために、独自にIntegrationsを作成する強力な仕組みが多数用意されています。

上から順にざっくりまとめてみました。

名称 概要
Amazon SQS Slack上のパブリックなチャンネルへの投稿内容をSQSへ送信 (SQSの用意、キューから取り出す処理を実装する必要あり)
Hammock PHP製のIntegrationsサーバ(各自サーバ構築する必要あり)ローカル環境にサーバを構築すれば内部のネットワーク上で動作するサービスにフックすることができるインテグレーションをHammockのプラグインとして追加することが可能
Incoming WebHooks Slackが発行するURLへPOSTするとSlackにメッセージが投稿される (チャンネル・ユーザ名・アイコン画像の指定可能)
Outgoing WebHooks Slackへ指定したメッセージが投稿されると、指定したURLに投稿内容がPOSTされる (POSTされるサーバ・システムを実装する必要あり)また、決められた形式(json)のレスポンスを返すことで同時にSlack上へ投稿することも可能
Slack API メッセージの投稿に加え、ファイルのアップロード・チーム情報やチャンネル情報の取得等が利用可能
Slackbot 「Incoming WebHooks」の簡易版(メッセージの内容とチャンネルの指定のみ可能)
Slash Commands 「/」から始まる命令を予め設定しておき、命令が投稿されると指定したURLに投稿内容がPOSTされる (POSTされるサーバ・システムを実装する必要あり)

実践してみよう

前置きが長くなりましたが、いよいよ本題です。
Slack APIと題していますが、今回は使う機会が最も多いと思われる「Incoming WebHooks」「Outgoing WebHooks」「Slack API」の3つの機能についてご紹介します。
(反響があれば他の機能も紹介するかも…)

Incoming WebHooks の使い方

おそらく最も需要のある機能じゃないでしょうか。
「Incoming WebHooks」を利用すると、外部のシステムからSlack上へコメントの投稿ができます。

Incoming WebHooks を始める

無題クリップ_101614_063909_PM

まずは「Incoming WebHooks」を選択し

無題クリップ_101614_064256_PM

投稿するChannelを選びます。
(ここで選んだChannelはChannel未指定の場合にだけ適応されるものなので、適当に選んでしまって問題ありません。)

スクリーンショット_101614_065531_PM

最後にURL(Token)が発行されるので、このURLにメッセージを添えてPOSTでリクエストするとSlackに投稿することができます。

※「Incoming WebHooks」を作成する度にSlack無料枠のIntegration数が1つ消費されますので、不要なIntegration(Incoming WebHooks)は随時削除することをおすすめいたします。

パラメータ

POST時に送信するパラメータは下記になります。
(厳密にはpayloadというパラメータに対して下記パラメータ郡をjson形式で送信します。)

パラメータ名 概要
text メッセージ(必須)
username 投稿者(サービス)名
icon_url 投稿者名のアイコン画像のURL
icon_emoji 投稿者名のアイコン
channel 「#」または「@」から始まるChannel名

「text」は「<URL|リンク名>」の形式で記載しておくことで該当URLのテキストリンクを設置することができます。
「icon_url」と「icon_emoji」は一方のみ指定可能で、両方指定した場合は「icon_emoji」が優先的に使用されるようです。
また、「icon_emoji」で指定できる絵文字はこちらの一覧が参考になると思います。

サンプルソース

おそらくパラメータの説明よりも、実際のサンプルソースを見ていただいた方が分かりやすいんじゃないでしょうか。
参考になるかはわかりませんが、サンプルをご用意いたしましたので是非ご活用下さい。

投稿結果

無題クリップ_101614_075321_PM

他にもURLをシェアした際に下部に表示されるリンク先概要のエリアを独自に作成するような機能もありますが、今回の「Incoming WebHooks」の解説はここまでにいたします。

Outgoing WebHooks の使い方

「Outgoing WebHooks」はSlack上でのメッセージを監視して指定したサーバのプログラムをキックすることができます。
ただし「Outgoing WebHooks」には、特定の単語を設定してその単語が投稿に含まれていた時だけしか使用できない制限がありますのでご注意ください。(しかも前方一致のようです。。)
もし制限なくメッセージを取得したい場合は「Amazon SQS」の連携を使用することで回避できそうです。
(まだそこまで試せていないです。。)

Outgoing WebHooks を始める

無題クリップ_101614_085847_PM

「Incoming WebHooks」同様にまずは「Outgoing WebHooks」を選択します。

無題クリップ_101614_090102_PM

特に気にせず次へ

スクリーンショット_101614_090526_PM

最後に「監視するChannel」「対象とする単語」「キックするサーバのURL」を設定します。
(サーバは外部からアクセスできる必要があります。)

これでSlack側の準備が整いました。
※「Incoming WebHooks」同様、「Outgoing WebHooks」を作成する度にSlack無料枠のIntegration数が1つ消費されますのでご注意下さい。

POSTされるパラメータ

「Outgoing WebHooks」では、プログラムをキックする際に下記のパラメータが送信されます。
天気取得のサンプルプログラムでは、「text」パラメータに「今日」「明日」「明後日」が含まれているかを判別して、返却するメッセージを出し分けしています。

  • token
  • team_id
  • channel_id
  • channel_name
  • timestamp
  • user_id
  • user_name
  • text
  • trigger_word

ちなみに、「Outgoing WebHooks」でリクエストしてきたSlackのクライアントは
「Slackbot (+https://api.slack.com/robots)」
というUserAgentでアクセスしてきますので、もしBasic認証等で穴を空ける必要がある場合等はこのUAのパラメータを利用することができると思います。

「Outgoing WebHooks」でキックされた結果の出力

「Outgoing WebHooks」でキックされたプログラムで何かしらの処理(今回は天気の取得)をおこなった後、その結果をどこかに出力したい場合があると思います。
Slackで投稿したのですから、当然結果もSlack上で確認できれば楽ですよね。

まず思いつくのは、先ほどの「Incoming WebHooks」を「Outgoing WebHooks」でキックされたプログラム上で実行することだと思いますが、プログラムのレスポンスに「Incoming WebHooks」のpayloadと同じパラメータをjson形式で返却することで、わざわざPOSTリクエストを投げることなく「Incoming WebHooks」と同様にSlack上に投稿することができるのです!
(Channelが未指定の場合はSlack上で投稿したChannelに投稿されます。)

サンプルプログラムをキック

今回用意したサンプルプログラムは少し実践的なもので、Slackで「天気」と投稿すると東京の天気を教えてくれるものを用意しました。
また、「天気 今日」「天気 明日」「天気 明後日」と投稿すると詳細な天気を確認することもできます。
(天気取得のAPIにはLivedoor Weather Web Serviceを利用しています。)
※そんなのHubotで!とか言わないw

投稿結果

Slack

「Incoming WebHooks」と比べると使いドコロが難しい「Outgoing WebHooks」ですが、独自のプログラムを実行させることができるので、できることの幅が大きく広がると思います。
「Outgoing WebHooks」についての解説は以上になります。

Slack API の使い方

最後になりましたが、Slack APIの解説になります。
「Incoming WebHooks」「Outgoing WebHooks」と説明してきて既にお腹いっぱいの人もいると思いますが、できることの可能性を一番秘めているのがこの「Slack API」です。

Slack APIって?

「Slack API」は「Outgoing WebHooks」のようにSlackの投稿に応じてプログラムをキックするような仕組みはありませんが、「Incoming WebHooks」のようにプログラムからSlackに投稿することができます。
(そういう意味では「Incoming WebHooks」の上位互換にあたると考えられます。)

「Slack API」で主にできることは下記の3つになります。

  • 認証(OAuth2を用いたアクセストークンの取得・シングルサインオン)
  • 取得(投稿内容検索やチーム・チャンネル・ユーザ等の情報取得)
  • 操作(メッセージの投稿・更新・削除やチーム・チャンネル・ユーザ等の設定変更)

(Slack APIの全メソッドはこちらに記載されています。)

SlackはSNSではないのでチーム・チャンネル・ユーザの取得・操作のメソッドを利用する機会があまり思い付きませんが、独自のサービスからファイルのアップロード等が利用できるのは利用の幅が広がると思います。
弊社に設置している監視カメラはまさにファイルのアップロードに活用しています。

※Slack APIは現在「Preview Release」版となります。(2014年10月20日現在)
今後の正式リリース等で仕様が変わってくる可能性がありますのでご注意下さい。

Slack API を始める

Slack APIを使用するには2種類の方法があります。

  • アプリケーションを作成してOAuth2経由でトークンを取得しAPIを使用
  • 固定トークンを発行してAPIを使用

今回は簡単に使い始めれる固定トークンを利用した方法をご紹介いたします。

まずは下記URLにアクセスしてトークンの発行をおこないます。
https://api.slack.com/

スクリーンショット_101714_064828_PM

「Create token」をクリックするとTokenが発行されますので、こちらの値を控えておきましょう。
トークンはユーザ単位(チーム毎)に発行されるので、個人で管理するようにする必要があります。

早速投稿だ

まずは「Incoming WebHooks」と同じ使い方を試してみます。
チャットを投稿するにはchat.postMessageのメソッドを利用します。

上記のリファレンスを見て気付いた人もいると思いますが、パラメータの内容は「Incoming WebHooks」と酷似しています。
実は「chat.postMessage」と「Incoming WebHooks」でできることはほとんど同じです。

「chat.postMessage」の方が少しパラメータの種類が少し豊富ですが、実装上異なる箇所が2点あります。

  1. メソッドへのアクセスはGET(「Incoming WebHooks」はPOST)
  2. Channelの指定がChannelID(「Incoming WebHooks」はChannel名)

ここさえ抑えておけば「Slack API」は怖くありません!

ChannelIDって?

ここで初めて出てきた単語ですが、「Slack API」ではChannelの指定にChannel名ではなくChannelIDを利用するようです。 ChannelIDは普段表面上で使用されることがないパラメータで、本来API経由で取得する必要があるようですが、実は簡単に取得する方法もありますのでご紹介させていただきます。

無題クリップ_101714_080737_PM

投稿画面でChannelIDを調べたいチャンネルメニュー内の「Add a service integration」を選択すると

スクリーンショット_101714_084801_PM

ブラウザ上で上記のようなURLへ遷移します。
URL内の「channel_id」パラメータがChannelIDに該当しますので、こちらを控えておくようにいたしましょう。

サンプルソース(chat.postMessage)

先ほど取得した「Token」「ChannelID」を使用すれば「Incoming WebHooks」とほぼ同じソースでSlackへの投稿が可能です。

投稿結果

スクリーンショット_101714_090850_PM

サンプルソース(files.upload)

「Incoming WebHooks」でできることならわざわざ「Slack API」を使う必要はありませんが、例えばSlackにファイルをアップロードする必要がある場合は「Slack API」を使う必要があります。

基本は「chat.postMessage」と大差ありませんが、こちらもサンプルをご用意しましたのでご活用下さいませ。
注意点としては「Content-Type: multipart/form-data」ヘッダの指定してPOSTすることと、ファイル名の先頭に「@」を付ける必要があることぐらいでしょうか。

投稿結果

スクリーンショット_101714_093321_PM

ローカルのファイルパスだけ少し気をつける必要がありますが、意外と簡単にファイルのアップロードが出来ました。
取得系のメソッドの説明もしようと思いましたが、ファイルのアップロードが問題なくできれば公式リファレンスを読みながら容易に実装できると思いますので、今回は省略させていただきます。

最後に

予想以上に長文となってしまいましたが最後までお読みいただきありがとうございます。
(さて、何人が最後までお読み頂いているやら・・・)
当初Slackはちょっとコジャレたチャットツールと言う感覚で使用していましたが、社内でも「鍵の解錠通知」や「監視カメラの通知」等でガッツリ活用しています!
この記事を見て新たにSlackに興味を持って頂いたり、これからはAPIも使ってみようというかなという人が増えれば記事を書いた甲斐があります。(そして日本語記事を豊富にして僕を楽させて下さいw)
もし記事の内容に不明点や間違いなどあれば、はてブのコメント等でご指摘いただければ幸いです。。