🔔
S3イベント通知をトリガーにTeams投稿
S3にファイルが生成されたら、それをトリガーにTeamsに投稿するサンプル
実現すること
S3バケットの内容をCloudFrontで公開している状況で、S3にファイルが生成されたら、そのイベント通知をトリガーにしてCloudFrontのURLをTeamsに投稿して関係者にお知らせする!
実際には……
実際には、LambdaからMediaConvertキックしてストリーミング用の動画とそれを表示するHTMLを生成してS3に保存する処理があって、そのHTM生成をお知らせするために作ったものです、はい。
事前準備
- S3バケットの作成
- S3に紐づくCloudFrontディストリビューションの作成
- TeamsのIncoming WebhookのURL取得
Lambda (Python)
- TeamsのWebhook URL、CloudFrontのURLはLambdaの環境変数に設定しておく
- Teamsに通知するためのAdaptive Cardの内容のひな型は別ファイル(template.json)にしておき、Python側のコードを少しスッキリさせる
- Teamsの通知からすぐ開けるようにURLはハイパーリンクになるようにMarkDownにする
import json
import logging
import os
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError
import boto3
logger = logging.getLogger()
logger.setLevel(logging.INFO)
TEAMS_CHANNEL_WEBHOOK_URL = os.environ.get('TEAMS_CHANNEL_WEBHOOK_URL')
cloudfront_distribution = os.environ.get('cloudfront_distribution')
# template.json を読み込んでおく
with open("./template.json", 'r') as f:
template_message = json.load(f)
def lambda_handler(event, context):
# logger.info(event)
logger.info('Start processing')
# イベントからS3関連の部分のみ抜き出し
s3_info = event['Records'][0]['s3']
# S3の情報からCloudFrontのURLを生成
object_key = s3_info['object']['key']
url = cloudfront_distribution + '/' + object_key
# logger.info(url)
# template_message を読み込み、URL部分のみ書き換え
teams_message = template_message
teams_message['attachments'][0]['content']['body'][1]['items'][1]['text'] = '[{}]({})'.format(url, url)
logger.info(teams_message)
# メッセージをエンコードしてTeamsに投稿
req = Request(TEAMS_CHANNEL_WEBHOOK_URL, json.dumps(teams_message).encode('utf-8'))
try:
response = urlopen(req)
response.read()
logger.info("Message posted to MicrosoftTeams")
except HTTPError as e:
logger.error("Request failed: %d %s", e.code, e.reason)
except URLError as e:
logger.error("Server connection failed: %s", e.reason)
template.json
{
"type": "message",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.3",
"body": [
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"wrap": true,
"text": "S3ファイル生成、CloudFront公開のお知らせ",
"size": "Medium",
"weight": "Bolder"
}
]
},
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"text": "以下のCloudFrontのURLで公開しました。",
"wrap": true
},
{
"type": "TextBlock",
"wrap": true,
"text": ""
}
]
}
]
}
}
]
}
トリガー設定
S3のイベント通知を作成し、作成したLambda関数を送信先として指定する。
想定外の処理が発生しないように、プレフィックスでいわゆるフォルダっぽいものを指定したり、サフィックスで拡張子を .html にしぼっておきましょう。
振り返り
やっぱりLambda便利よなー、という感想。お手軽過ぎる。
AWSを使うときは、マネージドなPaaSとLambdaだけ使っていたい。
あと、現時点ではTeamsのIncoming Webhookがメンションに対応していないので、通知があまり機能しないのも悲しいところ。
TeamsユーザーのみなさんはBacklog入りして1年以上経つ以下のUserVoiceに投票いただきたい。
Discussion