AWS SAMでSlackにメッセージを投稿するアプリを作る
Slackにメッセージを送信する仕組みを使い回せるように作りたかったので、SAM触るついでにざっくりと組んでみました。 Slackのtoken取得 Slack APIから取得します。[Start Building]をクリ […]
目次
Slackにメッセージを送信する仕組みを使い回せるように作りたかったので、SAM触るついでにざっくりと組んでみました。
Slackのtoken取得
Slack APIから取得します。[Start Building]をクリックしましょう。
ワークスペースとアプリ名を聞かれるので、入力します。ログインしてないワークスペースは表示されないので、ログインしてからリトライします。
アプリの基本設定
[Basic Information]で諸々設定画面でてきます。Add features and functionality
では、[Permissions]を選択しましょう。すると[OAuth & Permissions]というページに移動します。[Scopes]でchat:write:bot
とchat:write:user
を追加しましょう。
[Save Changes]をクリックすると、[Install App to Workspace]がアクティブになるので、有効化します。認証画面に遷移するので、内容を確認してAuthorizeしましょう。
このあとOAuth Access Token
が表示されているのを確認したら、事前準備は完了です。
SAMでスタックを準備する
続いてSlackへの投稿処理を実行するバックエンドを用意します。最低限必要なファイルは以下のようにして準備しておきます。
$ mkdir slack-lambda && cd slack-lambda
$ npm init -y
$ touch index.js template.yml
Slack SDK(Node.js)をインストール
$ npm i -S @slack/client
CloudFormationを書く
SAMでリソースの定義を書きます。SlackのトークンとチャンネルをLambda内に環境変数で入れるようにして、使い回せるようにしておきましょう。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: 'Post message to Slack'
Resources:
HelloSAM:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs6.10
Environment:
Variables:
SLACK_TOKEN: !Ref SlackToken
SLACK_CHANEL: !Ref SlackChanel
Parameters:
SlackToken:
Type: String
SlackChanel:
Type: String
Lambdaのソースを書く
あとは実行する処理をまとめます。
const { WebClient } = require('@slack/client')
const handler = (event, context, callback) => {
const { SLACK_TOKEN, SLACK_CHANEL } = process.env
if (!SLACK_TOKEN || !SLACK_CHANEL) return callback(new Error('slack token or channel is undefined'))
const { message, attachments } = event
if (!message) return callback(new Error('Message is undefined.'))
const web = new WebClient(SLACK_TOKEN)
const param = {
channel: SLACK_CHANEL,
text: message
}
if (attachments) param.attachments = attachments
web.chat.postMessage(param)
.then((res) => {
return callback(null, {
event,
result: res.ts
})
})
.catch(error => {
console.log(error)
return callback(error)
})
}
module.exports.handler = handler
SAMでAWSにデプロイする
以下の3ステップでデプロイします。(2回目からはaws s3 mb
は不要)。3 つ目のコマンドで、はじめに取得したtokenと投稿を送るチャンネルを指定しましょう。
# デプロイバケットの作成
$ aws s3 mb s3://YOUR_ORIGINAL_BUCKET_NAME --region us-east-1
# デプロイパッケージの作成
$ aws cloudformation package --template-file ./template.yml --output-template-file template-output.yml --s3-bucket YOUR_ORIGINAL_BUCKET_NAME
# デプロイ
$ aws cloudformation deploy --template-file ./sam-output.yml --stack-name hello-sam --region us-east-1 \
--parameter-overrides SlackToken='xoxa-xxxxxxxxxx' SlackChanel='#random'
Lambdaを実行する
あとは実行するだけです。
# Lambdaのfunction名を探す
$ aws lambda list-functions --region us-east-1 | jq '.Functions[].FunctionName' | grep sam
"hello-sam-HelloSAM-XXXX"
# Lambdaの実行
$ aws --region us-east-1 lambda invoke --function-name "hello-sam-HelloSAM-XXXX" --payload '{"message": "hello"}' result.json && cat result.json | jq .
{
"StatusCode": 200
}
{
"event": {
"message": "hello"
},
"result": "1525754269.000138"
}
## リッチな投稿版
$ aws --region us-east-1 lambda invoke --function-name "hello-sam-HelloSAM-XXXXX" --payload '{ "message": "hello slack",
"attachments": [
{
"fallback": "Required plain-text summary of the attachment.",
"color": "#36a64f",
"author_name": "Bobby Tables",
"author_link": "https://flickr.com/bobby/",
"author_icon": "https://flickr.com/icons/bobby.jpg",
"title": "Slack API Documentation",
"title_link": "https://api.slack.com/",
"text": "Optional text that appears within the attachment",
"fields": [
{
"title": "Priority",
"value": "High",
"short": false
}
],
"image_url": "https://my-website.com/path/to/image.jpg",
"thumb_url": "https://example.com/path/to/thumb.png",
"footer": "Slack API",
"footer_icon": "https://platform.slack-edge.com/img/default_application_icon.png",
"ts": 123456789
}
]
}' result.json && cat result.json | jq .
こんな感じで投稿されるようになります。
今後とか
自分でなにかSlackにメッセージ飛ばしたくなった時に「とりあえずこのLambdaければいいよ」というのがあれば楽かなというので作りました。
SAMだとAWS Serverless Application Repositoryに登録して簡単にデプロイできるようにすることもできるみたいなので、時間があればそちらも試してみます。
ソースコード
GitHubにおいてます。
https://github.com/hideokamoto/lambda-to-slack
SAM詳しい人とか、フィードバックくださいm(_ _)m