ことの発端
- POSを開発しているチーム所属なので導入店舗が増えれば管理も増えてくる。
- クレジット決済端末を交換したい時とかに、いちいちCLIでDynamoDBをみていた。
- めんどくさい of the day。
どうでもいいこと
- Node: 知りません。
- TypeScript: 美味しいの?
- lambda: チョットワカル
- Qiita: 通勤してる時にちょっと見る。
- 某パズルゲーム: ランク994(2019/04/24)
- 昨年ランク1000行けなかったのが悔しい。
では、参る。
- slackのスラッシュコマンドで作りました。
- すでにあるものに付け加えたので、slackから値を受け取りたい等はお調べください。
-
今回slackから渡ってくるサブコマンドは、3つあります。
エラーハンドリングは社内でしか使いわないので、しません。
TypeScriptです。
男は黙ってconst
post to slack #1
sample.ts
import * as AWS from "aws-sdk"
import * as url from "url"
const docClient = new AWS.DynamoDB.DocumentClient();
import * as url from "url"
は呼ばれたチャンネルに返却するためです。
参考資料: AWS JavaScript SDK DynamoDB - 公式ドキュメント
post to slack #2
main functionの内部です。
sample.ts
const resURL = url.parse(query.response_url)
const partitionKey = query.text.split(" ")[1];
let params
if (query.text.split(" ")[2] && query.text.split(" ")[2] !== "") {
const sortKey = query.text.split(" ")[2]
params = {
TableName: TABLE_NAME,
ProjectionExpression: '#pk, row2, row3, row4, row5, row6',
KeyConditionExpression: '#pk = :partKey AND row1 = :sortKey',
ExpressionAttributeNames: { '#pk': PRIMARY_KEY },
ExpressionAttributeValues: {
':partKey': partitionKey,
':sortKey': sortKey
},
}
} else {
params = {
TableName: 'TABLE_NAME',
ProjectionExpression: '#pk, row2, row3, row4, row5, row6',
KeyConditionExpression: '#pk = :partKey',
ExpressionAttributeNames: { '#pk': PRIMARY_KEY },
ExpressionAttributeValues: { ':partKey': partitionKey },
Limit: 10,
}
}
-
TableName
: DynamoDBの使用するテーブル名 -
ProjectionExpression
: DynamoDBから取ってきたい列。 <- なくてもいい。 -
KeyConditionExpression
: クエリ部分 -
ExpressionAttributeNames
: クエリする際のprimaryKeyと思えばいいはず。 -
ExpressionAttributeValues
:ExpressionAttributeNames
の値 -
Limit
: DynamoDBから取得する最大数。
if内はslackからくる引数が2つの場合。(1つだけ抽出)
else内は引数が1つの場合。(PRIMARY_KEYの列を抽出)
post to slack #3
sample.ts
docClient.query(params, (err, data: any) => {
if (err) {
console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
} else {
const array = data.Items.map(i => {
const output = {
item1: i.row2
item2: i.row3,
item3: i.row4,
item4: i.row5,
item5: i.row6,
}
return output
});
let fields = [{
title: String,
value: ``,
short: true
}];
fields.splice(0, 1) // 空の連想配列を取り除く
for (const i of array) {
const text = ` item1: ${i.item1}\n item2: ${i.item2}\n item3: ${i.item3}\n item4: ${i.item4}\n`
fields.push({
title: i.item5,
value: "```" + text + "```",
short: true
})
}
post to slack #4に続く
TypeScriptなのにany使ってます。ごめんなさい。
- 必要な物だけを使いたかったので
ProjectionExpression
を記述しました。 - Slack Attachments ドキュメント
- 仕上がりはこんな感じにしました。
- fieldsを使用することで、slackのスペースを有効に使えます。
- fields部分の処理をforですることで複数に対応しています。
- 1回の処理で枠1つのfieldsを作り、arrayの要素分作成します。
- 複数にする際はfor文でできます。
post to slack #4
sample.ts
const attachments = [
{
fallback: "通知:tada:",
color: "#439FE0",
title: "タイトル + partitionKey",
fields: fields,
mrkdwn_in: ["text"],
}];
postSlackBot(resURL, attachments) //自前の関数です。
}
});
-
fallback
: 通知。シュココのところです。 -
color
: 色 - title: タイトル
-
fields
: #3で作ったfields
自前の関数はありますが、slackに表示する記事はたくさんあると思うので、検索してみてください。
おわり。
以上で、DynamoDBから取得し、整形までのフローです。
もっとよくできるとかあれば、コメントいただければと思います。