どうも!@ufoo68です。今回2回目の投稿になります。@keigo1450さんよりバトンパスをもらっての投稿となります。前日のものはかなり実用的で新卒の私はすごく勉強になりました。
そんな私の方は、また作ってみた系になります。
はじめに
この記事が投稿されている頃、今頃私はラスベガスにいることでしょう。ということでAWS関係のことを書こうと思います(そのためにソリューションアーキテクト-アソシエイトとりました)。
あとこの記事は、自分がreinvent中にQiitaを書くというチャレンジで社内のアドベントカレンダーに登録しました。作ったものですが、Slack上で以下のコマンド
/set_money hoge
/check_money
を叩いてカジノの勝ち金を見れるSlackBotを作りました。本当はカジノの戦略考えるBotとか考えましたが、時間と私の知識力により断念。。。
CDKとは
AWS CDKとは、ざっくりと説明すると、AWSのリソース関係のアーキテクチャの構築とか、デプロイとかをプログラム言語で記述できる便利なツールです。詳しい理解はこのチュートリアルを進めるとわかってくるかと思います。
また、このCDKを使ったIoT的なSlackBotを作る記事はすでに公開されています。今回はそれをベースに簡単なおうむ返しSlackBotを作ってみました。
ソースはここで公開しております。
実装
まずは以下のコマンドでテンプレートを準備します
cdk init cdk-slack-bot --language typed
あとはサンプルコードに以下を付け足したり修正したりします。
import cdk = require('@aws-cdk/core')
import lambda = require('@aws-cdk/aws-lambda')
import apigw = require('@aws-cdk/aws-apigateway')
import dynamodb = require('@aws-cdk/aws-dynamodb')
export class CdkSlackBotStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props)
const table = new dynamodb.Table(this, 'Money', {
partitionKey: { name: 'path', type: dynamodb.AttributeType.STRING }
})
const bot = new lambda.Function(this, 'BotHandler', {
runtime: lambda.Runtime.NODEJS_8_10,
code: lambda.Code.asset('lambda'),
handler: 'bot.handler',
environment: {
HITS_TABLE_NAME: table.tableName
}
})
table.grantReadWriteData(bot);
new apigw.LambdaRestApi(this, 'Endpoint', {
handler: bot
})
}
}
import * as QueryString from 'querystring'
import { DynamoDB } from 'aws-sdk'
exports.handler = async function (event: any) {
const query = QueryString.parse(event.body)
const dynamo = new DynamoDB()
switch (query.command) {
case '/set_money':
if (query.user_name !== 'myname') return {
statusCode: 200,
headers: { "Content-Type": "text/plain" },
body: 'You are not me'
}
await dynamo.updateItem({
TableName: process.env.HITS_TABLE_NAME as string,
Key: { path: { S: 'money' } },
UpdateExpression: 'SET money = :num',
ExpressionAttributeValues: { ':num': { N: query.text as string } }
}).promise()
return {
statusCode: 200,
headers: { "Content-Type": "text/plain" },
body: 'Set your total money'
}
case '/check_money':
const money = await dynamo.getItem({
TableName: process.env.HITS_TABLE_NAME as string,
Key: { path: { S: 'money' } }
}).promise()
return {
statusCode: 200,
headers: { "Content-Type": "text/plain" },
body: `勝ち分は、${money.Item!.money.N}ドルです。`
}
default:
return {
statusCode: 200,
headers: { "Content-Type": "text/plain" },
body: 'invalid command'
}
}
}
使ったのはlambda
, dynamodb
, apigateway
の3つになります。かなり雑な実装ですが、一応私しかset_money
できないようにガードをかけました(簡単にハックされるとは思いますが)。
さいごに
一応このBotは社内Slackのワークスペースにこっそり入れたのでcheck_money
で私の勝ち分を確認することができます。まあ、今の所マイナスですが。。。
さて、明日も@keigo1450さんの投稿です。お楽しみに!