【Node.js】ChatGPT（GPT-3.5-turbo）のLINEBotを作ってみた




## 1. まず最初に

### 1-1. 動作確認済み環境

OS: macOS Ventura

※Windowsも基本同じですが、ターミナルのコマンドが違う場合あります。
<br>

### 1-2.準備事項

#### 1-2-1. Node.js インストール

https://nodejs.org/ja

#### 1-2-2. LINE Developers の登録

こちら参照
https://qiita.com/tatsuya1970/items/34ce62b53162eb69c809#2-line-developers-%E3%81%AE%E7%99%BB%E9%8C%B2%E7%84%A1%E6%96%99

#### 1-2-3. OpenAIの登録

こちらを参照
https://qiita.com/tatsuya1970/items/34ce62b53162eb69c809#4-openai-%E7%99%BB%E9%8C%B2-%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AE%E6%96%B9%E3%81%AF18%E3%83%89%E3%83%AB%E3%81%BE%E3%81%A7%E7%84%A1%E6%96%99

<br>

## 2. LINE Developers

### 2-1. 初期設定
LINE Developersを開き、ログインします。
→ https://developers.line.biz/ja/

[![Image from Gyazo](https://i.gyazo.com/a16d92cc3d6c42a290c7cd695ce797fe.jpg)](https://gyazo.com/a16d92cc3d6c42a290c7cd695ce797fe)

LINEアカウントでログイン
[![Image from Gyazo](https://i.gyazo.com/2e84068fbb8888b2c01c99085215ea6c.png)](https://gyazo.com/2e84068fbb8888b2c01c99085215ea6c)

新規プロバイダーを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/af5d048e-9267-308a-30ad-3227c19b1ab8.png)

※すでにアカウントを持ってる方はこの画面
[![Image from Gyazo](https://i.gyazo.com/7c655f0e965c425ccbfc8704561f0b96.png)](https://gyazo.com/7c655f0e965c425ccbfc8704561f0b96)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/326356b3-7be3-bf40-6c82-9484249d9125.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/f785604e-1119-915a-db8c-48ddea4ea534.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/93d7fb4b-8667-9194-669f-28fae1b26d32.png)

チャネルの種類：Messaging API
プロバイダー: さっき作ったやつ
会社・事業所の所在地：　入力
チャネルアイコン：　持参したアイコン画像を入れよう
チャネル名：　チャットボットの名前です。
チャネル説明：　チャットボットの説明
大業種：入力
小業種：入力
メールアドレス：入力
プライバシーポリシーURL ：今回は入力不要
サービス利用規約URL ：　今回は入力不要
・LINE公式アカウント利用規約 の内容に同意します
・LINE公式アカウントAPI利用規約 の内容に同意します
にチェックをいれて、
作成をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/67798617-f48a-b58b-6408-47c1c68a262a.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/e81c48e9-ec73-c60c-f1ea-de0d9c5385b7.png)

LINEボットの設定ができました。

[![Image from Gyazo](https://i.gyazo.com/3b738ad7103e754a4893af418061a328.png)](https://gyazo.com/3b738ad7103e754a4893af418061a328)

<br>

### 2-2. Messaging APIの設定

Messaging API 設定

[![Image from Gyazo](https://i.gyazo.com/b1772966495b6cd028f43f6231e3dcbf.png)](https://gyazo.com/b1772966495b6cd028f43f6231e3dcbf)

QRコードがでてきます。
[![Image from Gyazo](https://i.gyazo.com/39811a358d2f4480d48c64e3655bcb43.png)](https://gyazo.com/39811a358d2f4480d48c64e3655bcb43)

スマホのLINEで、このQRコードを読んでください。

LINEボットができてますね。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/5af93702-fce3-2323-4292-bc0b31793a59.jpeg" width="50%">


### 2-3. チャネルアクセストーンなど


QRコードのあるページの一番下の
「チャネルアクセストークン」＞発行
[![Image from Gyazo](https://i.gyazo.com/827d4ffae92714bf4c11b8842da3288f.png)](https://gyazo.com/827d4ffae92714bf4c11b8842da3288f)

このチャネルアクセトークンをどこかに控える
[![Image from Gyazo](https://i.gyazo.com/b81b6f8efb24b8ddb8cec378d8090da4.png)](https://gyazo.com/b81b6f8efb24b8ddb8cec378d8090da4)

「チャネル基本設定」タブの下方にある「チャネルシークレット」をどこかに控える。
[![Image from Gyazo](https://i.gyazo.com/7f54671976a2570e737440c7082aba44.png)](https://gyazo.com/7f54671976a2570e737440c7082aba44)
[![Image from Gyazo](https://i.gyazo.com/28ddabcc2c487b2ce5193f1c31118ad8.png)](https://gyazo.com/28ddabcc2c487b2ce5193f1c31118ad8)




## 3. OpenAI 

OpenAIのページへ
https://openai.com/api/

[Get Started]
[![Image from Gyazo](https://i.gyazo.com/6b2bc6c20e7467e0b392f6138076bcd5.png)](https://gyazo.com/6b2bc6c20e7467e0b392f6138076bcd5)

"Verify you are human"と表示されたら、ボタンをクリックします。
<img src="https://i.gyazo.com/62aa216cf79e091a80983bddb2f1d0b1.png" width="50%">


Log in
<img src="https://i.gyazo.com/c03a36c1c2c9abba34d5079a2c8225d2.png" width="50%">


メールアドレスをいれて、[Continue]
<img src="https://i.gyazo.com/7f826f448fbacd6fccf20d5701e1a21b.png" width="50%">


パスワードをいれて、[Continue]
<img src="https://i.gyazo.com/ba52b5a2cbe34935bc62f8e24001f4fb.png" width="50%">


こんな画面になる。
右上の「personal」をクリック
[![Image from Gyazo](https://i.gyazo.com/659725cd230ad8eb9592170400fdd20d.png)](https://gyazo.com/659725cd230ad8eb9592170400fdd20d)

「View API keys」をクリック
[![Image from Gyazo](https://i.gyazo.com/791759527f5cbe754908d1843858443a.png)](https://gyazo.com/791759527f5cbe754908d1843858443a)

「＋ Create new secret key」をクリック
[![Image from Gyazo](https://i.gyazo.com/5a197c7e5f90e9fa09d760af46df7d63.png)](https://gyazo.com/5a197c7e5f90e9fa09d760af46df7d63)

APIキーが生成される。
下図の緑色のコピーボタンを押して、「OK」
[![Image from Gyazo](https://i.gyazo.com/fa767b8ec9332afeab213f55584ef127.png)](https://gyazo.com/fa767b8ec9332afeab213f55584ef127)

このAPIキーはどこかに控えておく。


## 4. Node.js

ターミナル画面で以下のコマンドを入力

```
$ mkdir chatgpt
$ cd chatgpt
$ npm init -y
```

環境変数を使うため dotenvをインストール
```
$ npm install --save dotenv
```

同じフォルダに .envを作る
```
$ touch .env
```

.env に以下を入力
```.env
OPENAI_API_KEY="OpenAIのAPI"
LINE_CHANNEL_SECRET="LINE Messaging API　のチャネルシークレット"
LINE_CHANNEL_ACCESS_TOKEN="LINE Messaging API　のチャネルアクセストークン"
```

パッケージをインストール
```
$ npm install openai
$ npm install @line/bot-sdk express
$ npm install axios
```

実行プログラム app.js を作成
```
$ touch app.js
```

app.js に以下のコードを入力
```app.js
'use strict';

require("dotenv").config();

const OpenAI = require('openai');
const openai = new OpenAI({
    apiKey: process.env.OPENAI_API_KEY,
  });

const express = require('express');
const axios = require('axios');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;

const config = {
    channelSecret: process.env.LINE_CHANNEL_SECRET,
    channelAccessToken: process.env.LINE_CHANNEL_ACCESS_TOKEN
};

const app = express();

app.get('/', (req, res) => res.send('Hello LINE BOT!(GET)')); //ブラウザ確認用(無くても問題ない)
app.post('/webhook', line.middleware(config), (req, res) => {


    console.log(req.body.events[0].message.text);
    const lineMes = req.body.events[0].message.text;

    const client = new line.Client(config);

    async function handleEvent(event) {
        if (event.type !== 'message' || event.message.type !== 'text') {
            return Promise.resolve(null);
        }

        const completion = await openai.chat.completions.create({
            model: "gpt-3.5-turbo",
            messages: [{ role: "user", content: lineMes  }],
        });
     
        
        const res = completion.choices[0].message.content;

        return client.replyMessage(event.replyToken, 
            {
              type: 'text',
              text:  res
            }
        );
    }

    Promise
    .all(req.body.events.map(handleEvent))
    .then((result) => res.json(result));
});

app.listen(PORT);
console.log(`Server running at ${PORT}`);
```

## 5. 動作テスト

### 5-1. ngrok

正式にデプロイする前に、ローカルサーバーで試すためにngrokを使う。

ngrokをインストール
```
$ npm install -g ngrok
```

ngrokを起動
```
$ ngrok http 3000
```

```
ngrok by @inconshreveable                                                                              (Ctrl+C to quit)
                                                                                                                       
Session Status                online                                                                                   
Account                       TATSUYA  (Plan: Free)                                                            
Update                        update available (version 2.3.41, Ctrl-U to update)                                      
Version                       2.3.35                                                                                   
Region                        United States (us)                                                                       
Web Interface                 http://127.0.0.1:4040                                                                    
Forwarding                    http://35fe-2405-6587-a0-900-40cd-ffa7-63a9-d348.ngrok.io -> http://localhost:3000       
Forwarding                    https://35fe-2405-6587-a0-900-40cd-ffa7-63a9-d348.ngrok.io -> http://localhost:3000      
                                                                                                                       
Connections                   ttl     opn     rt1     rt5     p50     p90                                              
                              34      0       0.00    0.00    3.57    5.53                                             
                                                                                                                       
HTTP Requests                                                                 
```

ここの
https://35fe-2405-6587-a0-900-40cd-ffa7-63a9-d348.ngrok.io
がローカールサーバーのアドレス。
どこかに控えとく。
なお、ngrokが起動するたびにこのアドレスは変わる。


### 5-2. Webhook設定（LINE Developers）

LINE Developers
Messaging API設定 > WebhookURL > 編集
[![Image from Gyazo](https://i.gyazo.com/8cdccedf6f02484529f61d2e3fd82e5d.png)](https://gyazo.com/8cdccedf6f02484529f61d2e3fd82e5d)

ここに先ほどのアドレスをペーストし、末尾に /webhook を付けたし、
更新ボタン
[![Image from Gyazo](https://i.gyazo.com/c0bd2f100c17a72d4d6af0c052dbe67c.png)](https://gyazo.com/c0bd2f100c17a72d4d6af0c052dbe67c)


Webhook の利用をオン（緑色）
[![Image from Gyazo](https://i.gyazo.com/50f741b290501936410d4020e84eb20f.png)](https://gyazo.com/50f741b290501936410d4020e84eb20f)


その下の応答メッセージの「編集」をクリック
[![Image from Gyazo](https://i.gyazo.com/823bb127cb5d9b548b96b5b98956679d.png)](https://gyazo.com/823bb127cb5d9b548b96b5b98956679d)

別タブが開き、応答メッセージをオフにする。
[![Image from Gyazo](https://i.gyazo.com/9b51451de56c5c2dd95937477c350837.png)](https://gyazo.com/9b51451de56c5c2dd95937477c350837)


### 5-3. テスト

app.js を実行（ローカルサーバーを立ち上げ）する。
```
$ node app.js
```

スマホのLINEでなにか呟いて、
反応があれば、OK

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/2d4fa546-ff99-08e9-0104-8b48a3e455ed.jpeg" width="60%">

<br><br>

なお、このままではローカルサーバーが動作しているときでないと使えません。
ずっと使いたい場合は、Herokuなどでデプロイしてください。


<br><br>



（参考サイト）
https://platform.openai.com/docs/api-reference/introduction

https://qiita.com/youtoy/items/84384ad7a742ea1ce8f5