ChatGPTっぽいLINEbotの作り方

# はじめに
chatGPTをLINEから使えたらめちゃくちゃ便利だよなと思い作ってみることにしました。しかし2023年1月19日時点でchatGPTのAPIは提供開始されていません。そこでOpenAIが提供するgpt-3のAPIを使用して、chatGPTっぽいチャットボットを開発してみることにしました。
## 使用するもの
- OpenAI API
OpenAIは現在５つのAPIを提供しているのですが、今回使用するのは文章生成を行ってくれるText Completionです
- LINE Messaging API
- GAS
サーバーを立てることなくお手軽に利用できるので今回はgasを使用します。
## 完成品
こんな感じでこちらのメッセージに対して自然な日本語で返答してくれます。
![S__26616074.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917966/dcff9c0a-a726-9cc6-08c2-761e84a334ce.jpeg)


## 作成手順
### OpenAIのアカウント作成とAPIキーの発行
以下の記事を参考にアカウントの作成とAPIキーの発行を行ってください。
https://auto-worker.com/blog/?p=6988

### LINE Business IDの発行とMessaging APIのAPIキーの発行
以下の記事を参考にしてください
https://auto-worker.com/blog/?p=5117
webhookを使いたいのであいさつメッセージと応答メッセージはオフにしておいてください。
![スクリーンショット_20230120_003119.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917966/5af6aad0-e538-14ad-bb2f-6c3d9ae6c588.png)


### GASを使った実装
#### まずはGoogleドライブからGoogleAppsScriptの新規プロジェクトを作成してください
![スクリーンショット_20230120_003518.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917966/554c3685-897b-b899-2273-f49567af6e09.png)

#### 次にOpenAIのAPIキーとMessaging APIのAPIキーをスクリプトプロパティに設定します。プロパティ名はお好きな名前を設定してください。
![スクリーンショット_20230120_004211.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917966/cd0d5b4d-527d-9dd3-1268-30abe75f649a.png)

#### 最後に実際にコードを書いていきます。作成するファイルはopenAIAPI.gsとlineAPI.gsの２つです。ファイル名はお好きな名前を設定してください。
```gas:openAIAPI.gs
function requestCompletion(message) {
  //スクリプロプロパティに設定したopenaiのapiキーを取得
  const api_key = ScriptProperties.getProperty('OpenAIAPI');
  //文章生成AIのAPIのurl
  const api_url = 'https://api.openai.com/v1/completions';
  //文章生成AIに投げるテキストを定義
  const prompt = message;
  //OpenAIのapiリクエストに必要なヘッダー情報を設定
  let headers = {
    'Authorization':'Bearer ' + api_key,
    'Content-type':'application/json',
    'X-Slack-No-Retry':1
  };
  //文章生成で利用するモデルやトークン上限プロンプトをオプションに設定
  let options = {
    'muteHttpExceptions':true,
    'headers':headers,
    'method':'POST',
    'payload':JSON.stringify({
      'model':'text-davinci-003',
      'max_tokens':1024,
      'temperature':0.6,
      'prompt':prompt
    })
  };
  //openAIの文章生成にapiリクエストを送り結果を変数に格納
  const response = JSON.parse(UrlFetchApp.fetch(api_url,options).getContentText());
  console.log(response.choices[0]);
  //レスポンスに謎の改行が含まれているので空文字で置き換える
  let result = response.choices[0].text.replace(/\n/g, "");
  console.log(result);
  return result;
}
```
GPT-3には性能や速度の異なるいくつかのモデルが用意されています。今回はその中でも最も高性能なtext-davinci-003を使用しています。他のモデルと比べてより高品質でより長い出力、より良い命令追従性を得られるそうです。他のモデルについても知りたい方はこちらの記事を見てみてください。
https://note.com/npaka/n/nef372ec2e33a
またtemperatureの値は0~1の間で設定することができます。1に近づくほど、バラエティに富んだ回答を返してくれますが、その分情報の正確性は失われます。逆に0に近づくほど、回答の創造性が減少する代わりに情報の正確性は向上するそうです。今回は0.6で設定してみました。詳しくはopenAIのドキュメントを参照してください。
https://beta.openai.com/docs/quickstart/adjust-your-settings

```gas:lineAPI.gs
function doPost(e) {

  var reply_token= JSON.parse(e.postData.contents).events[0].replyToken;
  if (typeof reply_token === 'undefined') {
    return;
  }
  //応答メッセージのurl
  var url = 'https://api.line.me/v2/bot/message/reply';
  //チャンネルアクセストークン
  var channel_token = ScriptProperties.getProperty('LINEAPI'); 
  ///webhookで取得したjsonデータをオブジェクト化
  var receive_data = JSON.parse(e.postData.contents).events[0];
  //ユーザーが投稿したメッセージを取得
  var receive_message = receive_data.message.text;
  //ユーザーが投稿したメッセージを引数として、openAIAPIを使用し応答メッセージを用意
  var reply_text = requestCompletion(receive_message);
  var messages = [{
    'type': 'text',
    'text': reply_text,
  }];
  let payload = {
    'replyToken': reply_token,
    'messages': messages
  };

  let options = {
    'headers': {"Authorization" : "Bearer " + channel_token},
    'contentType' : 'application/json',
    'method': 'post',
    'payload': JSON.stringify(payload)
  };

  UrlFetchApp.fetch(url,options);
  
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
```

コードの実装が終わったら新しいデプロイからウェブアプリを選択してデプロイしてください。デプロイが完了したらウェブアプリのURLをコピーしてLINE Messaging APIの設定ページに行き、webhook URLの欄に先程のURLを貼り付けてください。

![スクリーンショット_20230120_010230.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917966/5fbef4ff-700d-77bc-5867-72d2c41605d0.png)

以上で実装は完了です！

## さいごに
Open AIのAPIを実際に触ってみた感想としては、とても簡単に実装できてめちゃくちゃ便利！！って感じでした。今回使用したもの以外にもコード補完や画像生成のAPIも提供しているらしいので、それも使って何か作ってみたいなと思いました。
この記事に不備や誤っている情報等ありましたら、教えていただけますと幸いです。
最後まで読んでいただきありがとうございました！！