BotkitでAWSのリソースを取得する

Botkitの簡単な使い方をAWSのAPIとTypeScriptを使って説明します。
今回はSlack連携はせず、簡単なWebエンドポイントを作って確認します。

サンプルリポジトリをおいて置くので、気になる人はCloneして使ってみてください 👌

- https://github.com/fnaoto/botkit-typescript-aws-sample

## Botkitの始め方

まずはBotkitをTypeScriptで使えるようにします。

```shell
## ライブラリのインストール

$ yarn add botkit # yarnの代わりにnpm使ってもOKです
$ yarn add typescript
$ yarn add botbuilder-adapter-web
$ yarn add aws-sdk

## tsconfigの作成

$ npx tsc --init
```

tsconfigはこんな感じに修正します。
詳しくはこちらの記事を参照ください。
- https://qiita.com/ryokkkke/items/390647a7c26933940470

```json
// tsconfig.json
{
  "compilerOptions": {
    "module": "esnext",
    "target": "esnext",
    "moduleResolution": "node"
  },
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules"
  ]
}
```

package.jsonは以下のように修正します。

```json
// package.json
{
  "scripts": {
    "start": "node dist/index.js", // jsを実行
    "build": "npx tsc --outDir ./dist ./src/index.ts" // tsファイルをjsにトランスパイル
  },
  "dependencies": {
    // 割愛
  }
}
```

## TypeScriptでBotkitのサンプルを作成

srcディレクトリとindex.tsを作成

```
$ mkdir src
$ touch src/index.ts
```

サンプルコードを作成します。
参考URLはこちら
- https://botkit.ai/docs/v4/platforms/web.html

```ts
// src/index.ts
import { Botkit } from "botkit";
import { WebAdapter } from "botbuilder-adapter-web";

const adapter = new WebAdapter; // botbuilder-adapter-webからadapterを作成

const controller = new Botkit({
  adapter: adapter, // 作成したadapterをBotkitの初期化時に渡す
});

controller.on("test", async (bot, msg) => { // イベントのフィルター、`type: test`で返信
  await bot.reply(msg, "I received an text: " + msg.text); // 受け取った`text:`の内容を返す
});
```

Botkitは本体とAdapterでライブラリが分かれています。
Botkitを初期化する際に、slackやwebなどのアダプタを渡してあげることで機能追加が可能です。

ここで、簡単なテストを実行

```shell
# jsファイルを生成
$ yarn build

# botkitを実行、待ち状態になる
$ yarn start

# 別のターミナル or シェルを起動
# Botkitにリクエストを送る
$ curl -X POST \
    -H "Content-Type: application/json" \
    -d '{
          "type": "test",
          "text": "ok bokujyou",
          "channel": "websocket",
          "user": "user"
        }' \
    http://localhost:3000/api/messages

# 以下のレスポンスが返ってくればOK
[{"type":"message","text":"I received an event: ok bokujyou"}]
```

## AWSリソースをBotkitで呼び出す

今回は簡単にCodeBuildのプロジェクト一覧を呼び出してみます。

ソースの作成

```
$ mkdir -p src/aws
$ touch src/aws/CodeBuild.ts
```

TypeScriptのコード
(本当はreturnの処理で、返り値とかinterfaceとか書きたいけど今回は省略)

```ts
// src/aws/CodeBuild.ts
import * as AWS from "aws-sdk"; // ライブラリをインポート

const codebuild = () => { // classのインスタンスを作成
  return new AWS.CodeBuild; // classを生成
};

// CodeBuildのプロジェクト一覧をAWSから取得して返す関数
const CodeBuildListProjects = () => { // 何も受け取らないLambda処理
  return codebuild().listProjects().promise(); // 非同期処理(コールバック)
};

export { CodeBuildListProjects } // 別ファイルでimportするためにexportしておく
```

```ts
// src/index.ts
import { Botkit } from "botkit";
import { WebAdapter } from "botbuilder-adapter-web";
import { CodeBuildListProjects } from "./aws/CodeBuild"; // import

const adapter = new WebAdapter;

const controller = new Botkit({
  adapter: adapter,
});

controller.on("test", async (bot, msg) => {
  await bot.reply(msg, "I received an event: " + msg.text);
});

// 追加
controller.on("codebuild", async (bot, msg) => {
  // CodeBuildListProjectsを実行
  await bot.reply(msg, await CodeBuildListProjects()); // 非同期処理なのでawaitを忘れない
});
```

確認してみる

```shell
$ yarn build
$ yarn start

# AWSの認証鍵を環境変数に設定

$ export AWS_ACCESS_KEY_ID=<>
$ export AWS_SECRET_ACCESS_KEY=<>
$ export AWS_REGION=<>

## もしくは

$ export AWS_PROFILE=<>

# リクエスト

$ curl -X POST \
    -H "Content-Type: application/json" \
    -d '{
          "type": "codebuild",
          "text": "test",     
          "channel": "websocket",
          "user": "user"
        }' \
    http://localhost:3000/api/messages

# [<CodeBuildのプロジェクト一覧>] が返ってくるはず
```

## まとめ

Botkitを使うとかなり簡単にAPIぽいものが出来上がります。
ここには書いていませんが、slackを使ってデプロイをchatbot的に実行できたりします。
ちょっと敷居が高いかなと思っている方も、ぜひ気軽に遊んでみましょう 🎉