en ja en pl en nl ja de ja ja ja ja ja ja zh ja ja ja ja ja en ja ja ja ja ja ja ja ja en ja ja ja ja ja zh ja zh ja en ja ja ja ja ja ja ja ja ja ja ja ja ja pl nl ja de ja ja nb ja ja nb ja ja nb ja ja en ja ja ja ja ja en ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja jbo en en ja nl nb en ko it en it it it en fr it ja ja en la fi ja it it it pt it de en ja en en it fr it en it nb it ja ja ja ja en ja ja ja ja ja ja ja ja ja
API Gateway + LambdaでSlackのCustom Commandを作る - Sanwa Systems Tech Blog
SlackのCustom Commandsは、言ってみればユーザーの操作に応じてWebサーバーにリクエストを送り、ごく短時間で終わる処理をしてもらってその結果を受け取るものです。少なければ1日数回、どんなに多くても1日に数百回のこのコマンドのためだけにWebサーバーを用意して24時間待ち受けを行うなんて無駄なことはしたくありません。API Gateway + Lambdaならこのような目的にぴったりで、EC2のt1.microインスタンスなどよりもずっと安価です。
上述の記事のように、まずはCustom Commandを新規に作成し、トークンを取得します。URLは未定なので未設定のまま置いておきます。
まずLambdaを実行するためのロールを作ります(既にあるなら不要です)。今回はCloudWatchに対する権限(読み取り専用で十分)が必要です。Slackから渡されるトークンはコードに埋め込むことにしましたが、もしDynamoDBで管理するのであればDynamoDBの読み取り権限も必要になります。
単にCloudWatchのメトリクスを取得して返すだけの簡単なコードになりました。response_typeにin_channelを入れておくと、コマンドの実行結果を他のユーザーも見ることができるようになります。8行目にあるxxxxxxxxxxxxxxxxxxxxxxxxはSlackから与えられたトークンで置き換えます。
"use strict"; var AWS = require("aws-sdk"); var cloudwatch = new AWS.CloudWatch(); exports.handler = function(event, context) { if (event.token !== "xxxxxxxxxxxxxxxxxxxxxxxx") { context.fail("トークンが変です"); return; } cloudwatch.describeAlarms({StateValue: "ALARM"}, function(err, data) { if (err) { console.log(err, err.stack); context.succeed(err); } else { if (data.MetricAlarms.length === 0) { context.succeed({response_type: "in_channel", text: `状態がALARMの監視項目はありません。`}); return; } context.succeed({ response_type: "in_channel", text: `状態がALARMの監視項目が${data.MetricAlarms.length}件あります。`, attachments : data.MetricAlarms.map(x => { return { color : "#FF8888", text : [ `名前: ${x.AlarmName}`, `内容: ${x.AlarmDescription}`, `状態: ${x.StateReason}`, `ALARMになった時刻: ${x.StateUpdatedTimestamp}` ].join("\n") }; }) }); return; } }); }
念のためパラメーターのtokenだけセットしてテスト実行してみましょう。どちらかの結果が戻ってくれば成功です。
API Gatewayの準備
まずAPI Gatewayのトップ画面で「Create API」ボタンを押し、New APIを選んで新規APIを作ります。名前は変えられないので慎重に行きましょう。
Resources作成
要するにURL設計です。Create Resourceで好きなだけ階層を掘り、掘ったところでCreate Methodを選んでGETやPOSTを作ります。それぞれのメソッドごとに別々の処理が作れます。
今回はGETでSlackに呼び出してもらうことにします。これだけ作ったら、
Integration Typeとして"Lambda Function"を選び、先ほど作成したLambda functionを選択します。
Method Execution設定
ここからはAPI GatewayとLambdaをどのように繋げるかを設定していきます。つまり、全体として
API Gatewayは外部からのリクエストを受け取る
Lambdaはパラメーターとして1件のJSONオブジェクトを受け取り、1件のJSONオブジェクトを返す関数
API Gatewayは何らかのデータをレスポンスとして返す
という処理の流れがあるわけですが、1→2, 2→3の間には何らかの変換ルールが必要です(後者ではもともとJSONをそのまま返すというルールが設定されています)。これを設定します。
Method Request設定
API呼び出し元から与えられる想定のパラメーターを設定します。数が多いのですがぽちぽち入力します(今回はtokenだけでも構いません)。
Method Request設定
Body Mapping Templatesの設定で、API呼び出し元から与えられたパラメーターをどのような形でLambda functionに渡すかを決めます。
{ "channel_name" : "$input.params('channel_name')", "user_id" : "$input.params('user_id')", "command" : "$input.params('command')", "text" : "$input.params('text')", "team_id" : "$input.params('team_id')", "token" : "$input.params('token')", "channel_id" : "$input.params('channel_id')", "team_domain" : "$input.params('team_domain')", "response_url" : "$input.params('response_url')", "user_name" : "$input.params('user_name')", "apiId" : "$context.apiId" }
テスト実行しましょう。tokenにトークンを入力してテストボタンを押します。先ほどLambdaを実行したときと同様の結果が返ってくれば成功です。
これで動作に問題ないことが確認できたのでデプロイします。これでURLが決まります。
Slackに戻り、必要に応じて項目の設定を行います。
URLの設定(API Gatewayで決まったもの。これは必須)
Customize Name(BOTが発言するときの名前。分かりやすい名前にしましょう)
Customize Icon(BOTが発言するときのアイコン。Custom Emojiは使えないので、使いたければ画像ファイルを再度アップロードする必要があります)
Autocomplete help textの設定(Show this command in the autocomplete listにチェックを入れるとオートコンプリートが使えるようになります
これでもう終わりです。ブラウザからでもスマホからでも、コマンドを実行するだけでAWSのAPIが実行されて結果が得られるようになりました。
実に簡単にCustom Commandが、それもサーバーレスで実現できました。ややこしいことはAWSが引き受けてくれるので、サーバーが落ちたらどうしようといったことを考える必要がありません。お手軽で効果がある、コストパフォーマンスの高いコードはどんどん書いていきたいものですね。それでは。
nurenezumi 2016-06-14 16:27
Analytics の内容を Slack でグラフ表示
こんにちは、久しぶりに和朗です。 サービススタート時など、Go…
AWS LambdaからGoogle APIを呼び出す
こんにちは、AWS担当のwakです。間が空いてしまったので、今回…
Twilioを使ってWeb API経由で電話をかける(前編)
こんにちは、AWS担当のwakです。 【インデックス(予定)】 Clo…
AWS LambdaのパラメータをDynamoDBで管理する
こんにちは、AWS担当のwakです。前回に続きAWS Lambdaの話をし…
AWS LambdaでWebサイトの死活監視を行ってSlackに結果を流す
こんにちは、AWS担当のwakです。前回に続きAWS Lambdaの話をし…
« SGMLReader + XPathでスクレイピングする SlackのSlash Commandで既存システムから… »