受験・進路の相談を承ります(クリックorタップ)

【ChatGPT】LINEの音声メッセージで英会話がしたい!

趣味・Tips

ChatGPT API使ってみたい!と思い、こんなの作りました(一般公開はしてません)↓

誰かのなんかの役に立つかもしれないのでコードをあげときます。Pyhonで書きました。

プログラミングはど素人なので、おかしなことしてたら是非とも指摘していただきたいです。

やってること流れ

①ユーザーが音声メッセージ送る

②Whisperで音声メッセージのテキスト書き起こし

③Whisperで書き起こしたテキストをChatGPT APIに投げる

④ChatGPT APIの返答をユーザーに返す

(④’ChatGPTの音声をgTTSで音声ファイルにしてユーザーに返す)

 

④’は実装していませんが、技術的には可能です(コードにもコメントアウトして書いておきました)。

 

動画では返答がテキストで返されていますが、当初はChatGPTの返答を音声メッセージとしてユーザーに返し、それがリスニングできなかったら後からセリフを要求できるようにするという、リスニング学習っぽいことしようとしてました。

LINEで音声メッセージを送るには、音声ファイルをhttpsから始まるURLで指定する必要があり、サーバーにあげなきゃなので面倒で辞めました。

コード

import os
from flask import Flask, request, abort
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextSendMessage, AudioMessage, AudioSendMessage
from gtts import gTTS
import whisper
import openai

app = Flask(__name__)

#openAIの設定
openai.api_key=os.environ["OPEN_AI_KEY"]

# LINE Developersの設定
line_bot_api = LineBotApi(os.environ["CHANNEL_ACCESS_TOKEN"])
handler = WebhookHandler(os.environ["CHANNEL_SECRET"])

#Whisperモデル読み込み
model = whisper.load_model("base.en")

@app.route("/")
def test():
    return "OK"

@app.route("/callback", methods=["POST"])
def callback():
    # X-Line-Signatureを取得
    signature = request.headers["X-Line-Signature"]
    # リクエストのボディを取得
    body = request.get_data(as_text=True)

    # 署名の検証
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)
    return "OK"

@handler.add(MessageEvent, message=AudioMessage)
def handle_text_message(event):
    # 受信したボイスメッセージを取得
    message_id=event.message.id
    message_content = line_bot_api.get_message_content(message_id)
    geted_file_name=f"{message_id}.m4a"
    with open(geted_file_name, 'wb') as fd:
        for chunk in message_content.iter_content():
            fd.write(chunk)
   
    #Whisperでボイスメッセージを文字起こし
    result = model.transcribe(geted_file_name,language="en")

    #ChatGPTに文字起こししたメッセージを投げる
    res = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[
        {
            "role": "system",
            "content": "reply in English within 30 words"
        },
        {
            "role": "user",
            "content": result["text"]
        },
    ],
    )

    #ChatGPTの返答の中身確認用
    #print(res["choices"][0]["message"]["content"])

    #ChatGPTの返答を音声ファイルとしてローカル保存(※今回は未実装)
    #send_file_name=f"re{message_id}.m4a"
    #speech = gTTS(text=res["choices"][0]["message"]["content"], slow=False, lang='en', tld='co.uk')
    #speech.save(send_file_name)

    # テキストで返信
    line_bot_api.reply_message(
        event.reply_token,
        [
            TextSendMessage(text="You said: "+'"'+result["text"]+'"'),
            TextSendMessage(text=res["choices"][0]["message"]["content"])
        ]
    )

    # 音声ファイルで返信(※今回は未実装)
    # line_bot_api.reply_message(
    #     event.reply_token,
    #     AudioSendMessage(original_content_url=f"https://hogehoge/{send_file_name}")
    # )

    #ローカルの音声ファイルを削除
    os.remove(geted_file_name)
    #os.remove(send_file_name)

if __name__ == '__main__':
    app.run()

ちょっと説明。

必要なキーは以下の3つです。
OPEN_AI_KEY = “あなたのOpenAIのAPIキー”
CHANNEL_ACCESS_TOKEN = “あなたのLINEのチャンネルアクセストークン”
CHANNEL_SECRET = “あなたのLINEのチャンネルシークレットキー”

 

コードを書いたファイルと同じ階層に.envファイルを作り、そこにこの3行を追加してください。

 

それから、上のコードだと毎回のやりとりでChatGPTくんはリセットされるので文脈を理解した会話ができません。
本来、直近の会話2,3個も合わせてChatGPTに投げたほうがいいです。

 

 

また、ChatGPTの返答は長くなりがちなので、”role”: “system”の”content”で「30 words以内の英語で返答して」と指示しています。

ここを好きに変えたらもっと面白くなると思います。
ユーザーの送ってきた英語を添削するように指示している方もいらっしゃいました。

 

最後に、今回実装しなかった音声ファイルを返す部分については、前述の通りURLで指定する必要があるので少し面倒ですが、AudioSendMessageの部分でURLを適切に指定すればちゃんと送ってくれます。

コメント

タイトルとURLをコピーしました