1
1

ChatGPTを利用して会話ができるLINEbotを作る

Last updated at Posted at 2024-02-16

概要

今回はchatgptを組み込んで、文章生成をしてくれるlinebotを作ったので、その作り方をこの記事にまとめました。

今回参考にしたのはこちらの記事

制作環境

Windows
python3.11
pip24.0

大体の流れ

  1. OpenAIからキーをゲット
  2. LINEのBotを作ってキーをゲット
  3. Lambdaに関数を作る

Openaiからkeyを入手

こちらのリンクから入手できる。

詳しいやり方は
https://qiita.com/kenichiro_ayaki/items/afff43e78e75b0ae8d8a
こちらの記事を参考にしていただきたい。

Lineのプロバイダ、チャネルを作る

Line Developersを開いてプロバイダを作る。

スクリーンショット 2024-02-13 145921.png

その後は新規チャネルを作成からbot用のチャネルを作る(今回私が作ったのはgpt-linebot2)

image.png

必須項目をうめる
image.png

チャネルアクセストークンを取得する

image.png
アクセストークンはチャネルを開いてmessaging APIタグから生成できる。

lambda関数の作成、設定

新しいlambda関数を作成する

スクリーンショット 2024-02-13 150753.png
関数名は任意に設定する(今回私はgpt-linebot2とした)
また、関数URLの有効化は必須なのでわすれないように。

Requestsモジュールを使うためのLayerを追加

関数を開いて、レイヤーの追加を選択すると新しくレイヤーを作成できる。
スクリーンショット 2024-02-13 151123.png

環境変数の設定

Lambdaの環境変数に下記を設定しておく

・LINE_CHANNEL_ACCESS_TOKEN
・LINE_CHANNEL_SECRET
・LINE_REPLY_ENDPOINT
・OPENAI_API_KEY
・OPENAI_COMPLETIONS_ENDPOINT

スクリーンショット 2024-02-13 151408.png

LINE側のWebhook URLを設定する

設定の関数URLタグから得られる関数のURLを
image.png
line developersのmessaging APIの所のWebhook URLに張り付ける。

lambdaのタイムアウトを伸ばす

OpenAPIのレスポンスは結構遅いので、とりあえず1分にしておく。
image.png

lamndaのコード

以下のコードをlambda_functionに張り付ける

Python
import os
import json
import base64
import requests

LINE_CHANNEL_SECRET = os.getenv('LINE_CHANNEL_SECRET')
LINE_CHANNEL_ACCESS_TOKEN = os.getenv('LINE_CHANNEL_ACCESS_TOKEN')
LINE_REPLY_ENDPOINT = os.getenv('LINE_REPLY_ENDPOINT')
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
OPENAI_COMPLETIONS_ENDPOINT = os.getenv('OPENAI_COMPLETIONS_ENDPOINT')

def line_reply(reply_token, response):
    Authorization = 'Bearer {}'.format(LINE_CHANNEL_ACCESS_TOKEN)
    headers = {
        'Content-Type': 'application/json; charset=UTF-8',
        'Authorization': Authorization
    }
    data = {
        "replyToken": reply_token,
        "messages": [{
            "type": "text",
            "text": response
        }]
    }
    print("Request data:", json.dumps(data, indent=2))
    
    r = requests.post(LINE_REPLY_ENDPOINT, headers=headers, data=json.dumps(data))
    print('LINE response: {}'.format(r.json()))



def openai_completions(prompt):
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer {}'.format(OPENAI_API_KEY)
    }
    data = {
        "model": "gpt-3.5-turbo",
        "messages": [{"role": "user", "content": prompt}],
        "max_tokens": 512,
        "top_p": 1,
        "temperature": 0.5,
        "frequency_penalty": 0,
        "presence_penalty": 0
    }
    
    try:
        print('OpenAI request: {}'.format(prompt))
        openai_response = requests.post(OPENAI_COMPLETIONS_ENDPOINT, headers=headers, data=json.dumps(data))
        print('OpenAI response: {}'.format(openai_response.json()))
        return openai_response.json()['choices'][0]['message']['content']
    except Exception as e:
        print(f'Error:{e}')
        return 'OpenAIが壊れてました😢'
            
def lambda_handler(event, context):
    try:
        # 'isBase64Encoded'をチェック
        if event.get('isBase64Encoded', False):
            body_str = base64.b64decode(event.get('body', '')).decode('utf-8')
        else:
            body_str = event.get('body', '')
        
        body = json.loads(body_str) if body_str else {}
        events = body.get('events', [])
        if events:
            message = events[0]['message']['text']
            reply_token = events[0]['replyToken']
            openai_response = openai_completions(message)
            line_reply(reply_token, openai_response)
            
        return {'statusCode': 200, 'body': json.dumps('Message processed successfully.')}
    except Exception as e:
        print(f"Error processing the event: {e}")
        return {'statusCode': 500, 'body': json.dumps('Internal server error.')}


(引用元:https://github.com/michitomo/openai-line-bot/blob/main/basic_openai_completions.py)

このコードは
1.OpenAIのRequest Bodyのcontent:promptにLINEからのメッセージを与え、OpenAIへのリクエストを生成する

2.レスポンスをLINEに返す
という感じです

OpenAIのAPIは結構よく壊れてるので、エラーハンドリングを入れておく。
(Error出力はcloud watchでprint(f'Error:{e}')の部分を確認する)

実行

実際にbotを使用するにはチャネルのmessaging apiからQRコードをlineで読み込むとbotを追加できます。
スクリーンショット 2024-02-13 152831.png

また、メッセージありがとうございます!このアカウントでは・・・
という部分は、line developersのapi message設定から応答メッセージを無効にすることで解決できる。
image.png

実行してみると...
image.png
うまくいくとこんな感じ。

まとめ

今回はLinebotにchatgptを組み合わせてみた。
どうやらDynamoDBを使うことでよりステートフルに会話を成り立たせることができるらしいので、機会があれば試してみようと思う。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1