テレワーク孤立を解消する、なんでも相談Botをチャットに入れる方法

テレワークってなんか相談とか雑談とかしにくいですよね。
ちょっと困った時に気軽に話せる人がいない、アドバイザー・相談相手が欲しいって人いると思います。
この記事を読むと、秒でレスポンスをくれて、質問に答えてくれたり、解決方法を教えてくれる話し相手ができます。


# 完成形(gif)
![gamen_test1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2503518/f9861aa3-2e52-d38c-bcf1-96f8de906172.gif)


# 作り方

## 概要
![スクリーンショット 2022-05-12 13.18.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2503518/c3a7ed4d-983c-cb2c-a893-e2e2f9828d67.png)
|:--|

## OpenAI APIの使用方法
OpenAIが作成した汎用的に使える言語モデルの学習済みモデルのAPIを、簡単な登録をすることで使用できます。

### サインアップ

https://openai.com/api/

こちらのページにアクセスすると右上に「SIGN UP」ボタンがあります。
画面に従って登録を行ってください。Googleアカウント連携でサクッと登録が可能です。
### 料金
最初の三ヶ月間は体験用に使える$18の無料枠があるので、**クレジットカードの登録は初期登録に必要ありません。**
![スクリーンショット 2022-05-09 14.32.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2503518/87c06cd6-c269-c717-fcd7-c3e0a4c962e0.png)

[費用のページはこちら](https://openai.com/api/pricing/)


### デモを動かして遊んでみる

![スクリーンショット 2022-04-21 17.09.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2503518/0d87ffbc-3fe1-48a9-157a-812db73c1b7b.png)

[ブレインストーミング](https://beta.openai.com/playground/p/default-vr-fitness?model=text-davinci-002)

上記のURLを開いて以下のように入力して実行してみてください(要サインイン)。
右側のパラメータはデフォルトのままで大丈夫です。
```
Brainstorm {考えたい事柄について}:
```
実際にいくつかやってみた例を載せます。
緑でハイライトされた部分がAIが出力した文章です。

---

![スクリーンショット 2022-04-21 16.57.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2503518/2cec92d8-c082-6c9a-3cb9-85574c093be0.png)

↑いいですね。ちゃんと文章になっているだけでなく、常識的なアイデアですね。
2については、需要があるかはおいておいて、利用シーンとしては考えられるかもしれませんね。

---

![スクリーンショット 2022-04-21 16.59.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2503518/2e16dd4e-52a9-b964-583c-82b71061e269.png)

↑いいですね。文章が途中で切れてるのは、指定したトークンの長さが足りなかったようです。

---

いい感じに使えることがわかったので、この機能をチャットツールに導入したいと思います。
### APIキーの取得方法

右上のアイコンをクリックし、View API keysをクリックします。
![スクリーンショット 2022-04-21 16.38.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2503518/9f6207e3-1b29-b33d-67ab-144f240ee633.png)
|:--|

メニューの「API Keys」をクリックし、「Secret Key」をコピーします。
![スクリーンショット 2022-04-21 16.35.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2503518/c0aa1ca9-0656-b774-1eb6-2b6eb9c5cbe0.png)
|:--|

後々使用しますので、保存しておいてください。

## Rocket.Chatの設定

世の中にはSlackやMicrosoft Teamsなど、さまざまなチャットツールが存在しますが、今回はOSSのRocket.Chatを例に進めていきます。
Webhook連携でOpenAI APIを繋げる方法を解説しますので、実装の参考にしてください。

### Outgoing Webhookを設定する
Outgoing WebHook サービス連携を追加します。
以下の内容で選択してください。

| 項目                    | 値                                        | 
| ----------------------- | ----------------------------------------- | 
| イベントトリガー        | メッセージが送信されました                | 
| 有効                    | オン                                      | 
| 名前                    | brainstorm_bot                            | 
| チャンネル              | all_public_channels , all_direct_messages | 
| トリガーになる言葉      | brainstorm                                | 
| URLs                    | {空欄}                                    | 
| 投稿ユーザー            | rocket.cat                                | 
| エイリアス (オプション) | OpenAI Bot                                | 
| スクリプトを有効にする  | オン                                      | 

### スクリプト

スクリプトは以下を貼り付けます。
APIキーを書き換えてください。

```javascript
class Script {
  /**
   * @params {object} request
   */
  prepare_outgoing_request({ request }) {

    let match;
    const apiKey = '取得したAPIキー';

    // トリガーとなるワードの設定
    match = request.data.text.match(/^brainstorm/);

    // リクエストURLの設定
    request.url = "https://api.openai.com/v1/engines/text-davinci-002/completions";
    request.headers = {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    };

    // データの成形
    userInput = request.data.text;
    trimmedInput = userInput.replace(/brainstorm/g,'').replace(/　/g,'');
    data = {
      "prompt": `Brainstorm ${trimmedInput}:`, 
      "temperature": 0.5, 
      "max_tokens": 150,
      "top_p":1.0,
      "frequency_penalty":1,
      "presence_penalty":1
    };
    
    if (match) {
      return {
        url: request.url,
        headers: request.headers,
        method: 'POST',
        data: data
      };
    }
    
  }

  /**
   * @params {object} request, response
   */
  process_outgoing_response({ request, response }) {
    // パースが必要ない場合
    return {
      content: {
        text: response.content.choices[0].text,
        parseUrls: false
      }
    };
  }
}
```

POSTで`https://api.openai.com/v1/engines/text-davinci-002/completions`にデータを送って、返答をボットがチャットに送信するというスクリプトです。

返答は100-150文字ほどで返ってきます。もっと長文が欲しい方は、`max_tokens`の値を大きくしてください。

# テスト

![スクリーンショット 2022-05-11 17.56.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2503518/c5d38ac3-25d5-6533-54c5-51c105f4c41a.png)
|:--|

# 使ってみた感想
使ってみた感想として、
* なんでも聞ける相談相手ができて嬉しい
* たまに英語で返答してくるので困る

トリガーになる言葉を「ねえ」とかにするともっと自然に使えるかなと思います。