前提
こちらの記事を参考にSlackとAWSの設定を行った。
https://qiita.com/G-awa/items/fc803c285cb560dab796
しかし、Slackの投稿に改行が含まれているとLambdaが起動しない。
API Gatewayの本文マッピングテンプレートでform-urlencoded形式からjson形式に変換する際、特定の文字をエスケープする必要があるようだ。
必要なエスケープは以下のとおり。
エスケープ表記 | 対象の文字 |
---|---|
\ | \ |
" | " |
\n | (キャリッジリターン) |
\r | (ラインフィード) |
\t | (タブ) |
対応
冒頭で提示した記事にある本文マッピングテンプレートの最後のブロックを以下のように変更する。
{
# foreach( $kvPair in $tokenisedEquals )
#set($kvTokenised = $kvPair.split("="))
"$util.urlDecode($kvTokenised[0])" : #if($kvTokenised[1].length() > 0)"$util.urlDecode($kvTokenised[1].replace("%5C", "%5C%5C").replace("%22", "%5C%22").replace("%0D", "%5Cr").replace("%0A", "%5Cn").replace("%09", "%5Ct"))"#{else}""#end#if( $foreach.hasNext ),#end
# end
}
別案
あるいはAPI GatewayでURLエンコードを行わず、Lambdaで行う方法もある。
その場合の本文マッピングテンプレートは、同じ箇所を以下のようにする。
{
# foreach( $kvPair in $tokenisedEquals )
#set($kvTokenised = $kvPair.split("="))
"$util.urlDecode($kvTokenised[0])" : #if($kvTokenised[1].length() > 0)"$kvTokenised[1]"#{else}""#end#if( $foreach.hasNext ),#end
# end
}
あとはLambda側の各言語のURIデコード処理を呼び出せばよい。
例えば、Node.jsの場合は以下のとおり。
index.js
exports.handler = (event, context, callback) => {
var text = decodeURIComponent(event.text.replace(/\+/g, '%20'));
// 以下省略
}