このページではSlackで特定のチャンネルでの自分宛のメッセージを受信時に対して自動的に応答するボットのためのAPIをServerlessで実装することを目的としています。
Slack APIの設定はこちらから
ソースコードはこちら
作りたいもの
特定のチャンネルで自分にメンションが来たメッセージに対して、「了解」と返信するボット
ここでは、返信するのはボットですが、ユーザが返信をしているように見せます。
Serverlessのインストール&AWS認証情報登録
# インストール
npm install -g serverless
# AWS認証情報の登録
serverless config credentials --provider aws --key {access_key} --secret {secret_key}
python3のテンプレートを使用する
sls create -t aws-python3 -p test-api
serverless.yml
service: lambda-api
frameworkVersion: '2'
provider:
name: aws
runtime: python3.8
region: ap-northeast-1
iamRoleStatements:
- Effect: "Allow"
Action:
- s3:ListBucket
- s3:GetObject
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- "arn:aws:s3::*"
functions:
slack_bot:
handler: handler.handler
memorySize: 2048
timeout: 60
environment: ${self:custom.environment.${self:provider.stage}}
events:
- http:
path: api/lambda-api
method: post
- schedule:
name: periodic_execution_5min # コールドスタート対策として,5分ごとにCloudWatchでアクセス
description: 'periodic_execution'
rate: rate(5 minutes)
input: '{"cron":"cron"}'
enabled: true
plugins:
- serverless-python-requirements
custom:
defaultStage: dev
environment:
dev: ${file(env/.dev.yml)} # 環境変数の設定先
pythonRequirements:
dockerizePip: true
handler.py
try:
import unzip_requirements
except ImportError:
pass
import json, requests, os
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
SLACK_USER_ACCESS_TOKEN = os.environ['SLACK_USER_ACCESS_TOKEN']
TARGET_CHANNEL = os.environ['TARGET_CHANNEL']
ME = os.environ['ME']
TARGET_CHANNEL = '' # 監視するチャンネルのID
ME = '' # 自分宛のメッセージを監視
def handler(event, context):
logging.info(event)
if 'cron' in event: # コールドスタート対策でCloudWatchからの定期的な呼び出しに対応
return {
'statusCode': 200,
'body': 'cron'
}
if 'challenge' in event['body']: # Event Subscriptionsでエンドポイント登録時に必要
body = json.loads(event['body'])
logging.info(body)
return {
'statusCode': 200,
'body': body['challenge']
}
body = json.loads(event['body'])
if 'event' in event['body']:
if body['event']['channel']==TARGET_CHANNEL:
channel = body['event']['channel']
text = body['event']['text']
threadTs = body['event']['ts']
if ME in text:
postReply(channel, '了解', threadTs)
return {
'statusCode': 200,
'body': text
}
return {
'statusCode': 200,
'body': 'end'
}
def postReply(channel, text, threadTs):
url = 'https://slack.com/api/chat.postMessage'
headers = {
'Authorization': 'Bearer ' + SLACK_USER_ACCESS_TOKEN
}
params = {
'channel': channel,
'as_user': True,
'text': text,
'thread_ts' : threadTs
}
res = requests.post(url, params=params, headers=headers)
logging.info(res.json())
環境変数の設定
User OAuth Tokenを指定する
SLACK_USER_ACCESS_TOKEN: xoxp-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
TARGET_CHANNEL: '{対象とするチャンネルのID}'
ME: '{受信者のID}'
デプロイ
serverless-python-requirementsをインストールしておく
npm install --save serverless-python-requirements
dockerを起動しておく
sls deploy
コメント