概要
- Slackで
/tel_list
と打ったら緊急連絡先が出るようにする - serverless実装
構成図
- slackでtel_list打つ
- api gatewayがPOSTリクエスト受け取る
- 指定したlambdaを実行。そこでKMSでslackのtoken認証する
- lambdaでpython実行し、slackに結果を送る
内容
①apexでlambda関数を管理する
- ここではKMSのtokenがまだできてないので、コードは書きません
- apexの使い方やインストール等はこちらをご覧ください
$ mkdir apex_slack_tel_list && cd apex_slack_tel_list
$ apex init
Project name: apex_slack_tel_list
Project description: apex_slack_tel_list is able to show TEL list when anyone was in trouble
### 一度deployする
$ cd apex_slack_tel_list
$ apex deploy
②IAM(KMS)の設定
- IAM->暗号化キー->リージョンを選んでください->キーの作成
- エイリアス:apex_lambda_slack_tel_list
- キーマテリアルオリジン:KMS
- 次へ
- タグの追加はなしで次のステップへ
- apex_slack_tel_list_lambda_function
- キーの管理者が削除できるようにをチェック入れる
- 次のステップへ
- apex_slack_tel_list_lambda_function
- 次のステップへ
- 完了
- タグの追加はなしで次のステップへ
- 完了したらここのARN部分を控えてください。
-
arn:aws:kms:リージョン名:数字:key/key_id
となってます。
③IAMのroleにARNに対する権限追加
- IAM->ロール->apex_slack_tel_list_lambda_function->ポリシー名->編集
{
"Effect": "Allow",
"Action": [
"kms:Decrypt"
],
"Resource": [
"arn:aws:kms:ap-northeast-1:xxxxxxxxxx:key/xxxxxxxxxxxxx"
]
}
④SlackでSlashコマンドの登録
- slackのapp->Apps & Integration->Slashで検索->Add Configuration->
/tel_list
で登録- URL:https://xxxxxx.execute-api.xxxxxxx.amazonaws.com/prod/slack
- こちらはAPI Gatewayの設定が終わったら登録します。
- METHOD: POST
- Customize Name: 緊急連絡先一覧
- Show this command in the autocomplete listにチェック
- Description: 緊急連絡先一覧
- URL:https://xxxxxx.execute-api.xxxxxxx.amazonaws.com/prod/slack
- 登録が終わったらtokenを控えてください
⑤Slackのtokenを暗号化
$ aws kms encrypt --key-id arnに書いてるkey_id --plaintext="slackのtoken"
{
"KeyId": "arn:aws:kms:ap-northeast-1:xxxxxxxx:key/xxxxxxxxxxxx",
"CiphertextBlob": "暗号化されたtoken"
⑥apexでコードを書いてdeployする
$ vim functions/hello/main.py
# -*- coding: utf-8 -*-
import boto3
from base64 import b64decode
from urlparse import parse_qs
import logging
ENCRYPTED_EXPECTED_TOKEN = "暗号化されたtoken"
kms = boto3.client('kms')
expected_token = kms.decrypt(CiphertextBlob = b64decode(ENCRYPTED_EXPECTED_TOKEN))['Plaintext']
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def handle(event, context):
req_body = event['body']
params = parse_qs(req_body)
token = params['token'][0]
if token != expected_token:
logger.error("Request token (%s) does not match exptected", token)
raise Exception("Invalid request token")
tel_list = [
'sion:000-0000-0000',
'cojp:111-1111-1111',
]
format_tel_list = '\n'.join(tel_list)
return { "text": "```%s```" % (format_tel_list) }
### いらないファイルを削除し、最終的にはこんなディレクトリになります
$ tree
├── functions
│ └── hello
│ └── main.py
└── project.json
### deploy
$ cd apex_slack_tel_list
$ apex deploy
- lambdaからテストしてみましょう。成功するはずです。
⑦API GatewayでAPIを作成
- API GATEWAY->API->APIの作成
- 新しいAPI
- API名:apex_slack_tel_list
- 説明:lambda経由でslackで緊急連絡先を表示させてます
- 作成を押す
⑧リソースを作成する
- apex_slack_tel_list->アクション->リソースの作成
- リソース名:slack
- リソースパス:slack
- リソースの作成
⑨メソッドを作成する
- POST
- apex_slack_tel_list->アクション->メソッドの作成
- Lambda関数
- region: 選んでください
- Lambda関数: apex_slack_tel_list_hello
- 保存を押す
- slack/->出来上がったPOSTをクリック->統合リクエスト->本文マッピングテンプレート
- application/x-www-form-urlencoded
- テンプレートに書きを登録し保存。(今回は不要ですが、urlDecodeで日本語をPOSTしてもエラーが起きないようにしてます)
{ "body": $util.urlDecode($input.json("$")) }
⑩API-Gatewayのdeployする
- リソース->アクション->APIのdeploy
- デプロイされるステージにprod
- デプロイ
- 作成が終わったら、ステージ->prod->URLの呼び出し のurlを保存。
- これを先ほどのslackに登録してください。
⑪実際にslackで打ってみよう
/tel_list
- すると下記のように自分自身だけに緊急連絡先が表示されるかと思います。
最後に
- Hubot用にサーバを立てなくて良いし、serverless便利