slackのOutgoing Webhooksから受信する
Proxy統合ではなく、Lambda側のインタフェースを決めてしまう
/raspberrypi/{proxy+} を作成し、POSTのみ作成
/raspberrypi/speak で呼び出し、speakの場合、音声再生要求を投げる
Lambda関数を作成
実装はシンプル
https://github.com/nilesflow/Slack2RaspberryPi
下記等参考に
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html
query paramaterのtokenの値の検証のみ
tokenの値はコンソール上の環境変数に設定
Lambdaを登録しておく。
フォーマットは下記の形式
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format
Lambdaオーソライザー
ロールはLambda実行権限含むものを作成しておく
クエリパラメータにtokenを設定して認証させたいので、認証でLambdaリクエストオーソライザーを設定。
~検証とURLクエリ文字列パラメータを設定。
リクエストパスのproxyを入力しておく
・作成したLambdaを指定
・プロキシ統合は使わずに、呼び出し側ロジックはAPI Gateway側で吸収
・リクエストパラメータのproxyをマッピング
・Content-Type=application/x-www-form-urlencoded で送信される
・それ以外は厳しめに通過禁止に設定しておく
・マッピングテンプレートは次の通り
## slackのOutgoing Webhooksから下記の形式で送信される
## token=viK8ruCmEfBjd9u84MOEeTWo
## team_id=T0001
## team_domain=例
## channel_id=C2147483705
## channel_name=テスト
## timestamp=1355517523.000005
## user_id=U2147483697
## user_name=スティーブ
## text=googlebot: 身軽なツバメの対気速度はどのくらい?
## trigger_word=googlebot:## POSTパラメータの分割(A=x&B=y)
#set($aParams = $input.body.split(“&”))## path変数の分割
#set($aPaths = $input.params(‘proxy’).split(“/”))## 出力されるJSONデータの生成
{
##pathの次階層をactionとする
“action” : “$aPaths[0]”,## 必要なPOSTパラメータのみをマッピング
#foreach( $param in $aParams)
#set($hParam = $param.split(“=”))
#if( $hParam[0] == “text”)
“text” : “$util.urlDecode($hParam[1])”,
#end
#if( $hParam[0] == “user_name”)
“user” : “$util.urlDecode($hParam[1])”,
#end
#end## カンマ制御のためのダミー
“dummy” : null
}
Lambda側で定義される次の変数をマッピングしている
action
text
user
・統合レスポンスは200のみ設定
slackへ応答を返すには、200でレスポンスパラメータを返す必要があるため
マッピングテンプレートは次の通り
## for slack Outgoing Webhooks
## 全て200の単一フォーマットで返却
#set ($inputRoot = $input.path(‘$’))## Lambdaで正常に処理された場合
#if ($input.path(‘$.statusCode’) > 0)## 200の場合のフォーマット
#if ($input.path(‘$.statusCode’) == 200)
#set ($body = $util.parseJson($input.path(‘$.body’)))
{
“text” : “$body.message”
}## それ以外の場合のフォーマット
#else ## 200
#set ($body = $util.parseJson($input.path(‘$.body’)))
{
“text” : “$body.error: $body.error_description”
}
#end ## not 200## 例外等
#else ## statusCode
{
“text” : “$input.path(‘$.errorMessage’)”
}
#end ## not statusCode
Lambdaの応答の次のケース全てを200として返却する
・ステータスコード200:正常
・ステータスコード200以外:異常(Lambda実装コード中で認識したエラー)
・例外等それ以外:異常(Lambda実装コード中以外のエラーも含む)
・ゲートウェイのレスポンスで、API Gatewayで検出したエラーのレスポンスフォーマットを定義する
これも、SlackのOutgoing Webhooksのフォーマットに合わせておく。
400, 500も200で返すようにしておく。
メソッドレスポンスモデルは不要なのか。
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-method-settings-method-response.html
統合レスポンス、ゲートウェイのレスポンスでまかなえているようだった。