slackにdynamoDBから情報を取得して、整形まで。[投稿は、ご自身で。]

# ことの発端
- POSを開発しているチーム所属なので導入店舗が増えれば管理も増えてくる。
- クレジット決済端末を交換したい時とかに、いちいちCLIでDynamoDBをみていた。
    - めんどくさい of the day。


# どうでもいいこと
- Node: 知りません。
- TypeScript: 美味しいの？
- lambda: ﾁｮｯﾄﾜｶﾙ
- Qiita: 通勤してる時にちょっと見る。
- 某パズルゲーム: ランク994(2019/04/24)
    - 昨年ランク1000行けなかったのが悔しい。

# では、参る。
- slackのスラッシュコマンドで作りました。
    - **すでにあるものに付け加えたので、slackから値を受け取りたい等はお調べください。**
- 今回slackから渡ってくるサブコマンドは、3つあります。
    - [1]: どのコマンド使うか。 <- 必須。
    - [2]: dynamoDBの `primary key` となるもの(今回は文字列4桁) <- 必須。
    - [3]: dynamoDBの `sort key` となるもの(こちらも文字列4桁) <- なくてもいい。
<img width="741" alt="Pasted_Image_2019_04_24_19_02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104403/061e15ab-e05f-f4e0-c148-8b70041f6648.png">

- エラーハンドリングは社内でしか使いわないので、しません。
- 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](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html) - 公式ドキュメント

# 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つの場合。(１つだけ抽出)
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に続く

```
#### :warning:TypeScriptなのにany使ってます。ごめんなさい。
- 必要な物だけを使いたかったので `ProjectionExpression` を記述しました。
- [Slack Attachments](https://api.slack.com/docs/message-attachments) ドキュメント
- <img width="583" alt="Pasted_Image_2019_04_25_15_27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104403/d4fc37b2-b6ed-e0ef-d0e5-ebdf022e67ff.png">
仕上がりはこんな感じにしました。
- 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から取得し、整形までのフローです。

もっとよくできるとかあれば、コメントいただければと思います。