開始
要開始製作Line機器人前,我們先瞭解本篇文章會需要使用到的平台。
- Line Developers:創建Line機器人。
- OpenAI:取得OpenAI API 的 secret key,讓機器人對話。
- Google Cloud Functions:Python程式碼的部署平台,生成供LineBot使用的webhook。
- Firebase:建立即時資料庫,讓機器人可以取得對話紀錄,進行有連續性、有記憶的對話。
Line Bot創建
Step.1 進入Line Developers創建一隻機器人
Step.2 設定機器人基本資料
一些必填的填一下就好~
- Channel type :設定為 Messaging API (一定要!)
- Provider:如果已經有了可以用以前的,沒有使用過可以新建立一個
- 其他選項可以大致填一下
- 機器人大頭貼可以上傳自己設定好的照片
- Privacy policy URL、Terms of use URL:這兩個可以不用填
Step.3 獲得機器人的Channel secret、Channel access token
建立完機器人後,可以在那個機器人的Basic Setting頁面中找到Channel secret、在Messaging API頁面中找到 Channel access toke,這兩個東西會在程式中使用到。
如果按ISSUE、REISSUE,Line會重新給你secret和access token,記得要在程式中修改,不然程式會連接不到機器人。
P.S. Allow bot to join group chats、Auto-reply messages、Greeting messages可以依照需求修改。這邊先改為Disabled。
Step.4 完成機器人設定
好了!那我們先將機器人放到一邊,之後部署完程式再將URL貼回Messaging API頁面中的Webhook URL。
Firebase
Step.1 開始
點選「Get Start」。
Step.2 建立專案
點選「新增專案」。
第二步的選項要打開Google Analytics喔~
Step.3 進入Realtime database
進入Realtime Database之後,建立資料庫。
這邊要選鎖定模式,建立完資料庫再修改。
當你看到的畫面和下圖一樣時,就完成資料庫建立。
會看到有一串URL:https://XXX.firebaseio.com/
這就是在程式中可以設定資料儲存位置的URL,先把它放到旁邊,等等會用到。
但還沒結束!!我們需要讓它設定成可以從外部寫入。
Step.4 更改規則
在「規則」的地方,把false都改成true,出現紅字是正常的,把提醒關掉就好。
那這樣就完成Firebase Realtime Database的設定了!
Google Cloud Functions
Step.0 淺談Google Cloud
Google Cloud 是一系列由Google提供的雲端運算服務,包括:雲端運算、資料儲存、資料分析及機器學習等。使用 Google Cloud Functions的優點在於它不需要另架伺服器和環境,在小型的機器人使用上也有一定的免費額度可以使用,而且只有實際使用時才計算額度,對於只是想要試做看看的開發者而言相對友善。
Step.1 開始
點選網站頁面上的「控制台」或「開始試用」。
啟用Google Cloud Functions需要綁定個人信用卡,如需要綁定教學的請參考這裡。
Step.2 進入Cloud Functions建立專案
在選單中尋找Cloud Functions,如果找不到它的話,可以看看「無伺服器」這個分類下有沒有。
然後點選「建立專案」。
Step.3 建立函式
環境設定為第一代。地區可以設定為asia-east1台灣
觸發條件設定為HTTP,並且允許未經驗證的叫用,再按儲存。
點開「執行階段、建構作業、連線和安全性設定」,往下滑新增「執行階段環境變數」
新增四個環境變數:
- OPENAI_API_KEY:(在OpenAI獲得的secret key)
- LINE_BOT_TOKEN:(在Line Developers獲得的Channel access token)
- LINE_BOT_SECRET:(在Line Developers獲得的Channel secret)
- FIREBASE_URL:(在Firebase獲得的URL)
注意:變數名稱要和上方一模一樣,歡迎複製貼上,數值要貼自己的!!
按下一步,更改程式碼。
執行階段更改為「Python3.8」。進入點改成「linebot」。
在main.py貼上下方程式碼:
from linebot import LineBotApi, WebhookHandler
from linebot.models import TextSendMessage
import json
import os
from firebase import firebase
import openai
# 使用環境變量讀取憑證
openai.api_key = os.getenv('OPENAI_API_KEY')
token = os.getenv('LINE_BOT_TOKEN')
secret = os.getenv('LINE_BOT_SECRET')
firebase_url = os.getenv('FIREBASE_URL')
def linebot(request):
body = request.get_data(as_text=True)
json_data = json.loads(body)
try:
line_bot_api = LineBotApi(token)
handler = WebhookHandler(secret)
signature = request.headers['X-Line-Signature']
handler.handle(body, signature)
event = json_data['events'][0]
tk = event['replyToken']
user_id = event['source']['userId']
msg_type = event['message']['type']
fdb = firebase.FirebaseApplication(firebase_url, None)
user_chat_path = f'chat/{user_id}'
chat_state_path = f'state/{user_id}'
chatgpt = fdb.get(user_chat_path, None)
if msg_type == 'text':
msg = event['message']['text']
if chatgpt is None:
messages = []
else:
messages = chatgpt
if msg == '!清空':
reply_msg = TextSendMessage(text='對話歷史紀錄已經清空!')
fdb.delete(user_chat_path, None)
else:
messages.append({"role": "user", "content": msg})
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
max_tokens=128,
temperature=0.5,
messages=messages
)
ai_msg = response.choices[0].message.content.replace('\n', '')
messages.append({"role": "assistant", "content": ai_msg})
reply_msg = TextSendMessage(text=ai_msg)
# 更新firebase中的對話紀錄
fdb.put_async(user_chat_path, None , messages)
line_bot_api.reply_message(tk, reply_msg)
else:
reply_msg = TextSendMessage(text='你傳的不是文字訊息呦')
line_bot_api.reply_message(tk, reply_msg)
except Exception as e:
detail = e.args[0]
print(detail)
return 'OK'
在requirements.txt貼上下方套件需求:
# Function dependencies, for example:
# package>=version
line-bot-sdk
requests
openai==0.28
git+https://github.com/ozgur/python-firebase
注意:不用再新增Flask套件,因為Cloud Functions本來就是Flask框架!
修改完成,就開始部署!
(每次部署都需要億點時間,等它從繞圈變成綠勾勾就部署完成了)
Step.4 完成
部署完成後,可以在「觸發條件」中找到「觸發網址」,再把這個複製下來貼回LineBot。
回到Line Developers,找到你的機器人,進入Messaging API,把Use webhook打開,把觸發網址貼到Webhook URL,再按Verify,顯示Success就完成了!
成果查看
在firebase裡面也有儲存對話紀錄。
那我們就完成了有記憶的對話機器人!
Debug方向
這邊提供了一些錯誤的修正方式,如果發生錯誤可以試試看。
- Line的webhook verify後是success的,但是機器人沒有回應。
→ 程式錯誤,檢查程式是否有錯誤,環境變數是否正確設定。 - Cloud Functions的紀錄顯示Line的secret或access token認證不過。
→ 可能複製的時候按到issue,更改到secret或access token,再重新複製後更改程式的環境變數。 - 機器人對話一直是簡體中文。
→ 這是OpenAI的模型問題,不是程式問題(如果要改可以另外增加第三方軟體,完成翻譯成繁體中文的功能),可以在剛開始對話的時候,請機器人使用繁體中文。