目次
サーバーレスとDevOpsに注力中。AWSを使った効率的なインフラ構築が得意です。
AWS Lambda は API Gateway のバックエンドとして設定することができます。Slack API から実行するためのエンドポイントを API Gateway で用意することによって、Hubot 等を用いない Serverless な Slack 連携が可能になります。AWS コンソールを利用した具体的な設定およびサンプルコードを示します。
関連するドキュメント
- Slack から Lambda に HTTP POST する方式の選択
- Lambda をバックエンドにした API Gateway の設定方法
Slack 側の設定
利用形態の選択
Slack API には Slack App という箱を作成してその枠組みの中で設定を管理する利用方法と、Slack API 単体で利用する方法の二つがあります。前者は比較的新しい仕様であり、ドキュメントも別々になっています。例えば Slack に外部から通知する Incoming Webhooks の最新のドキュメントはこちらにあり、昔のドキュメントはこちらにあります。Outgoing Webhooks のように、新しい Slack App の枠組みの中では利用できない API も存在しますが、これは Events API で代替可能です。本ページでは Slack App 内で利用する API を考えることにします。
API の選択
AWS Lambda はイベントドリブンな処理を行うサービスであるため、常時接続が必要な WebSocket を利用した Slack API は利用できません。そこで、Slack 内から特定の条件下で AWS Lambda に HTTP POST が発生する Slack API を利用します。2017/11/14 現在のところ Slash Commands, Events API, Outgoing Webhooks が該当しますが、Outgoing Webhooks は前述のとおり Slack App 内で利用できないため今回は考えないことにします。
Slash Commands を利用する場合の設定
- ログインした状態で Your Apps の「Create New App」をクリックして新規 Slack App を作成します。
- Slack App の画像や説明、開発メンバーの「Collaborators」設定を行います。
- 「Basic Information」から Slash Commands を設定します。
- Request URL には HTTP POST 先となる API Gateway のエンドポイントを設定します。API Gateway は未設定のため、とりあえず仮の URL を入力しておきます。
- Escape channels, users, and links sent to your app など、必要に応じて設定します。
- 後で Lambda に設定する「Basic Information」の App Credentials / Verification Token の値を確認します。
- HTTP POST の body における
token
として Slack から Lambda に送信されます。Lambda はこの値をもとに Slack からのリクエストであることを確認します。
- HTTP POST の body における
- 「Install your app to your workspace」から workspace に Slack App をインストールします。
/{コマンド名}
が利用できることを確認します。
Events API を利用する場合の設定
Slash Commands の場合と同様に Slack App を作成してから、Event Subscriptions 項目で HTTP POST 先となる Request URL や送信したいイベント種別を設定します。Slash Commands の場合と異なり適当な URL を設定することはできず、Slack からの challenge リクエストに適切なフォーマットで応答できるエンドポイントを設定しなければなりません。そのため、後述の AWS 設定を先に行う必要があります。本ページでは Slash Commands を扱うことにします。より複雑な処理を行いたい場合は Events API のドキュメントを読んで対応します。その際には以下のようなことに注意します。
- Event 種別 message.channels, message.groups, message.im, message.mpim を購読すると投稿されたメッセージを取得できます。
- Bot 自身からの投稿に対する Event を無視するためには
subtype
bot_message を利用します。 - Slash Commands の場合と同様に
token
やteam_id
を認証に利用します。 - 同じ
event_id
の HTTP POST が最大 3 回 (直後、1分後、5分後) 送られてくるため、重複して処理しないように工夫する必要があります。X-Slack-Retry-Reason
ヘッダーの値を確認してリトライがなされた原因を確認します。解消できない場合X-Slack-No-Retry: 1
として HTTP POST にレスポンスを返すとリトライを抑制できます。- Slack からの HTTP POST における
X-Slack-Retry-Num
ヘッダーの値が 1,2,3 となっていることを利用して重複処理を回避できます。 - 簡易的には
event_id
やevent_time
で重複処理を回避することもできます。
AWS 側の設定
Slack からのリクエストに含まれる各種情報を文字列化して返すだけの Lambda 関数を作ってみます。
- Lambda 実行時に利用する IAM を作成します。「AWS service」一覧から
Lambda
を選択して、ポリシーは CloudWatch Logs 出力が必要なためAWSLambdaBasicExecutionRole
を付与します。 - Lambda 関数を Author from scratch から先程の IAM を設定して作成します。
- 以下のようなソースコードを index.js に記載して保存します。
slack-echo-command
という名称の、nodejs に関する Lambda blueprint から引用して簡略化したものです。 - Triggers から API Gateway を選択して追加します。Lambda 関数内で認証するため Security は Open にします。
- Api Gateway コンソールの Stages → prod から確認できる Invoke URL をもとに、Slack で仮に入力した URL を更新します。
- Slack から
/コマンド名
を入力してレスポンスが返ることを確認します。 - Slack API は 3 秒でタイムアウトします。Lambda 関数がメモリにロードされていない場合は起動に時間がかかります。起動時間によるタイムアウトを回避するためにはCloudWatch イベントで Lambda を 5 分毎に定期実行するのが簡単です。
index.js
'use strict';
const qs = require('querystring');
const token = 'Slack App で確認した値'; // KMS で暗号化した方が安全です。
exports.handler = (event, context, callback) => {
const params = qs.parse(event.body);
const requestToken = params.token;
if (requestToken !== token) {
console.error(`Request token (${requestToken}) does not match expected`);
return callback('Invalid request token');
}
const user = params.user_name;
const command = params.command;
const channel = params.channel_name;
const commandText = params.text;
callback(null, {
statusCode: '200',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(`${user} invoked ${command} in ${channel} with the following text: ${commandText}`)
});
};
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。
関連記事
- AWS EC2 インスタンスの選定方法準仮想化と完全仮想化 AWS のインスタンスタイプが準仮想化と完全仮想化のどちらの仮想化技術を採用したハードウェアであるかによって、使用できる AMI (OS) が異なるのは以下の理由によります。 準仮想化 ParaVirtualization (PV) において OS は自分が仮想化用のハードウェア上で動作していることを知っています。つまり仮想化用にカスタマイズされた専用の OS が必要になりま...
- OpenVPN で二つの VPC をつなぐための設定インターネット VPN (Virtual Private Network) には二拠点間の通信を暗号化する方式によって IPsec-VPN や SSL-VPN などがあります。OpenVPN は SSL-VPN の実装のひとつです。AWS VPC を二つ用意してそれらを OpenVPN で接続してみます。 VPC の構成 myvpc-1 (10.1.0.0/16) mysubnet-1-1 (10...
- Windows Server EC2 インスタンスへの CAL インストールWindows サーバを AWS EC2 インスタンスとして起動した後は、RDP 接続が必要となります。RDP 接続を行なうためには Remote Desktop Services (RDS) ライセンスが必要となります。 Windows Server のライセンスは、管理用途の RDS 接続を許可しています。その際に RDS ライセンスは不要です。ただし、[同時接続数が 2 という制限があります...
- AWS Lambda の基本的な使い方AWS Lambda はイベントドリブンな「関数」を登録できるサービスです。例えば S3 に画像がアップロードされたときにサムネイル用のサイズに加工する処理が記述された関数を登録できます。基本的な使い方をまとめます。 事前準備 関数の登録はブラウザで AWS コンソールにログインして行うこともできますが、本ページでは AWS C
- AWS 落穂拾い (Data Engineering)Kinesis Kinesis Streams データは 3 AZ にレプリケーションされます。Amazon Kinesis Data Streams FAQs 24 時間 (既定値) から 1 年までデータ保持できます。[Changing the Data Retention Period](https://docs.aws.amazon