Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8704

[AWS ChatBot]朝会のファシリテーターを決めて!

$
0
0

現職場では、デイリースタンドアップとして、朝会を実施している。
そして、いつも開始日時になると、

「え、今日・・・司会担当・・・だれ・・・?」

とTheWordになる。
※TheWord ・・・ リモート会議において、 無音が続き、最初に話した人がファシリテーターをしなければいけない空間のこと

一応、SlackBotを使用して、それとなく機械的にファシリテーターを指名しているのだが、

「この人お休みだよ〜」 や 「昨日もやったんですけど〜」 とか

いちいち面倒臭い。

よし。朝会のファシリテーターをいい感じ(前回当たった人は当たらない、スムーズに再抽選ができる、自分が選ばれない)に決めるToolを作ろう。

はじめに

コミュニケーションToolはSlack
プラットフォームはAWSとする。

構成

全体構成はこんな感じ。
構成.png

朝会の担当者をランダムに選択し、Slackに通知するTool。
実行トリガーは2種類存在する。
1. CloudWathEventsから定期的(朝会の始まる5分前)に実行
2. Slack→AWS ChatBotから実行

DynamoDBではファシリテーター担当履歴を管理。
(現時点では直近の担当者しか保存していない。)

構築

AWS

ChatBot以外はCloudFormationで構築。
IAM等のユーザーは事前に発行しておくこと。
ソースコード

Lambda

Node.jsで実装。
コード全体とは以下の通り。

index.js
'use strict'constrequestPromise=require('request-promise')constAWS=require('aws-sdk')constdynamodb=newAWS.DynamoDB.DocumentClient({region:'ap-northeast-1'})letslackPostOption={url:'https://slack.com/api/chat.postMessage',method:'POST',qs:{token:process.env.SLACK_TOKEN,channel:process.env.SLACK_CHANNEL,text:'',username:'ぼくのいうことはぜったい'},json:true}exports.handler=async()=>{returnnewPromise((resolve,reject)=>{Promise.resolve().then(()=>{// 直近のファシリテーターを取得returngetLatestFacilitator()}).then((latestFacilitator)=>{// ランダムに取得(直近を除く)returngetFacilitator(latestFacilitator)}).then((facilitator)=>{// 直近のファシリテーターを登録returnputLatestFacilitator(facilitator)}).then((facilitator)=>{// Slackに通知returnpostSlack(facilitator)}).then(()=>{resolve('Finish')}).catch(reject)})}constgetLatestFacilitator=()=>{constparam={TableName:'FacilitatorHistory',Key:{status:'latest'}}returnnewPromise((resolve,reject)=>{dynamodb.get(param,(err,data)=>{if(err)reject(err)resolve(data.Item?data.Item.member:'')})})}constgetFacilitator=(latestFacilitator)=>{returnnewPromise((resolve,reject)=>{constmemberList=process.env.MEMBER.split(',')constget=()=>{constfacilitator=memberList[Math.floor(Math.random()*memberList.length)]if(latestFacilitator==facilitator){get()return}resolve(facilitator)}get()})}constputLatestFacilitator=(facilitator)=>{returnnewPromise((resolve,reject)=>{varparam={TableName:'FacilitatorHistory',Item:{status:'latest',member:facilitator}}dynamodb.put(param,(err,data)=>{if(err)reject(err)resolve(facilitator)})})}constpostSlack=(facilitator)=>{returnnewPromise((resolve,reject)=>{slackPostOption.qs.text=`きょうのあさかいは <${facilitator}> だ。`requestPromise(slackPostOption).then(resolve).catch(reject)})}

内容

本来なら並列にできる部分もあるが、わかりやすく直列化している。

流れとしては
1. 直近のファシリテーターを取得
2. ファシリテーターをランダムに取得(直近のファシリテーターは除く)
3. Slackに担当者を通知
4. 2.で選ばれたファシリテーターを登録
といったシンプルなもの。
2.のファシリテーター取得ロジック部分で担当者ごとに重みをつけて、選ばれやすさを制御したり、自身だけ選ばれづらくするなどのイカサマはできそう。

CloudFormation

一部内容がベタが記されている部分があるので、使用する際には修正する必要がある。

template.yml
AWSTemplateFormatVersion:2010-09-09Resources:MorningFacilitatorFunction:Type:AWS::Lambda::FunctionProperties:Code:./release/app.zipFunctionName:MorningFacilitatorFunctionHandler:index.handlerRuntime:nodejs12.x# Lambdaの実行ロールRole:{lambda arn}MemorySize:128Timeout:30Environment:Variables:TZ:Asia/Tokyo# カンマ区切りでファシリテーター候補のSlackユーザーIDを定義MEMBER:'@yamada,@yamamoto,@yamashita,@yamagami,@yamsuda'# 各種Slackの情報SLACK_TOKEN:{slack api token}SLACK_CHANNEL:{slack channel}FacilitatorHistory:Type:AWS::DynamoDB::TableProperties:TableName:FacilitatorHistoryAttributeDefinitions:-AttributeName:statusAttributeType:SKeySchema:-AttributeName:statusKeyType:HASHProvisionedThroughput:ReadCapacityUnits:3WriteCapacityUnits:3FacilitatorEventsRule:Type:AWS::Events::RuleProperties:Name:FacilitatorEventsRule# 朝会開始時間5分前(GMTなのでJST変換すると+9時間)ScheduleExpression:cron(55 0 * * ? *)State:ENABLEDTargets:-Arn:!GetAttMorningFacilitatorFunction.ArnId:lambdaMorningFacilitatorPermission:Type:AWS::Lambda::PermissionProperties:Action:lambda:InvokeFunctionFunctionName:!RefMorningFacilitatorFunctionPrincipal:events.amazonaws.comSourceArn:!GetAttFacilitatorEventsRule.Arn

デプロイする際は、AWS CLIを使用。
毎回入力するのは面倒なため、shを作成

deploy.sh
#!/bin/sh# ソースコードをアーカイブrm-fr release &&mkdir release
zip -r app.zip index.js node_modules > /dev/null 2>&1
mv app.zip release/

# 必要な情報はベタがきするか、shの引数で対応AWS_IAM_USER_NAME=$1AWS_ACCESS_KEY_ID=$2AWS_SECRET_ACCESS_KEY=$3AWS_DEFAULT_REGION=$4AWS_S3_BUCKET=$5AWS_STACK=$6

aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID--profile$AWS_IAM_USER_NAME
aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY--profile$AWS_IAM_USER_NAME
aws configure set region $AWS_DEFAULT_REGION--profile$AWS_IAM_USER_NAME

aws cloudformation package --template-file template.yml --s3-bucket$AWS_S3_BUCKET--s3-prefix`date'+%Y%m%d%H%M%S'`--output-template-file output.yml --profile$AWS_IAM_USER_NAME
aws cloudformation deploy --region$AWS_DEFAULT_REGION--template-file output.yml --stack-name$AWS_STACK--profile$AWS_IAM_USER_NAME

AWS Chatbot

AWS Chatbotのコンソールを開き、チャットクライアント「Slack」を選択し、クライアントを設定を押下。
スクリーンショット 2020-07-22 14.55.16.png

権限を求められるので、許可する。
スクリーンショット 2020-07-22 14.56.05.png

新しいチャンネルを設定。
スクリーンショット 2020-07-22 14.58.40.png

各種任意の値を入力し登録。
screencapture-us-east-2-console-aws-amazon-chatbot-home-2020-07-22-15_02_56.png

以上でAWS側の設定は完了。

Slack

メンバーが揃っているチャンネルで、@awsさんをインバイトする。

/invite @aws

このように表示されればOK。
スクリーンショット 2020-07-22 15.22.48.png

SlackからLambdaの実行。

@aws lambda invoke --function-name MorningFacilitatorFunction --region ap-northeast-1

すると、ファシリテーターが指名される。
スクリーンショット 2020-07-22 15.27.03.png

ただ、毎回このようなコマンドを入力するのは効率が悪いので、Slackワークフロー登録する。

Slackワークフロー

ワークフロービルダーを開く。
スクリーンショット 2020-07-22 15.31.16.png

作成を押下して、適当な名前を入力。
※ 伸ばし棒が入らない・・・
スクリーンショット 2020-07-22 15.32.36.png

ショートカットを選択、作成。
チャンネル名はメンバーが揃っているチャンネルを選択。
スクリーンショット 2020-07-22 15.32.49.png
スクリーンショット 2020-07-22 15.33.25.png

ステップを追加し、メッセージを送信を選択。
68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3330303433302f62646265323338632d656633302d373332392d306630352d3337386435383331643434662e706e67.png
スクリーンショット 2020-07-22 15.33.46.png

メッセージの送信先に「ワークフローを開始したチャンネル」
メッセージテキストに@aws lambda invoke --function-name MorningFacilitatorFunction --region ap-northeast-1を入力。
スクリーンショット 2020-07-22 15.34.16.png

保存、そして公開。
スクリーンショット 2020-07-22 15.34.23.png

これでワークフロー登録完了。

ショートカットから起動することが可能。
スクリーンショット 2020-07-22 15.45.44.png

運用してみよう

カタカタカタ...

「...ふぅ。」

「おっとそろそろ朝会だなぁ。」

「今日の担当は・・・?」

スクリーンショット 2020-07-22 15.51.15.png

「病弱太郎か。あれ?あいつ今日病気で休みだったよな・・」

「しょうがない。選ぶか。」

「ショートカットから...えい」

スクリーンショット 2020-07-22 15.55.32.png

まとめ

正直、AWSでやるにはオーバースペック感が否めない。笑
とわ言え、

  • 朝会前のTheWordが少なくなる(かも?)
  • 興味のあったAWS Chatbotをさわれた

のでよかったかと。

AWS Chatbotは触ってみて、無限の可能性を感じた。
SlackトリガーでAWSのServiceを使用できるので、CI/CDを全てAWS上で構築することができれば、SlackOnlyで業務が回りそう。


Viewing all articles
Browse latest Browse all 8704

Trending Articles