背景
複数の Serverless アプリケーションで SlackBot を作成していた際に、
Slack のWebhook設定等を複数のアプリケーション間で持ち回すの面倒だったので、
SNS イベントで共通化できないか、という試みを。
Serverless アプリケーションのテストデプロイ
注意点はファイル名を dispatcher.js に設定すること。
serverless webpack を使用している場合は output 設定で出力ファイル名を調整する必要がある。
Slackにデータを送信する
SNS Trigger のLambdaイベントでは、 event.Records
に配列形式で次のようなフォーマットのデータが送られてくる。
{
"EventSource": "aws:sns",
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws:sns:xxxxxx",
"Sns": {
"Type": "Notification",
"MessageId": "xxxxxxxx",
"TopicArn": "arn:aws:sns:xxxxxxx",
"Subject": ".....",
"Message": ".....",
"Timestamp": "2016-12-29T17:30:12.629Z",
"SignatureVersion": "1",
"Signature": "xxxxxx.....",
"SigningCertUrl": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-xxxxxxx",
"UnsubscribeUrl": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:xxxxxxxx",
"MessageAttributes": {}
}
}
Slack ではコレを受け取ってイベント発行すれば良い。Message の中にJSON形式で channel
text
attachments
を受け取れるようにしておくと便利
配列で来るので Promise.all などを使って効率的に処理する。
SNS にデータを追加する
他のLambda から SNS へメッセージを発行するには TOPIC ARN の文字列さえあれば足る
serverless.yml
に次の記述を追加して…
provider:
environment:
SLS_TOPICARN: ${env:SLS_TOPICARN}
iamRoleStatements:
- Effect: Allow
Action:
- "sns:Publish"
Resource: ${env:SLS_TOPICARN}
コード側で次のような記述を加えればOK
const AWS = require('aws-sdk')
const sns = new AWS.SNS()
sns.publish({
Message:"....",
Subject: "....",
TopicArn: process.env.SLS_TOPICARN
}, done)