使用 n8n 以及 OpenAI API 打造 ChatGPT Telegram 機器人
![使用 n8n 以及 OpenAI API 打造 ChatGPT Telegram 機器人](/content/images/size/w2000/2023/03/-------2023-03-12-130924.png)
當下最火紅的話題應該就是 ChatGPT,他是一個由 OpenAI 公司打造的智慧型聊天機器人,它跟傳統聊天機器人最大的差別就在於,它不是基於規則的一問一答的回覆方式,而是基於深度學習模型,而且能夠理解使用者對話的上下文關係的智慧型機器人,你可以像跟人類對話一樣去問它很多問題,他都能回答上。
![](https://openaicom.imgix.net/7f6c5b76-875f-455d-ac21-317aa984652e/chatgpt-og.jpg?auto=compress%2Cformat&fit=min&fm=jpg&q=80&rect=36%2C0%2C1152%2C1152)
網路上有很多例子,你甚至能叫 ChatGPT 去寫一篇小說出來、推薦你吃甚麼晚餐、甚至還能幫你寫 Code,還有各種很厲害的功能,各種細節有興趣的都可以到網路上搜尋相關的文章。
OpenAI API
當然,在 ChatGPT 網頁上就能直接使用這個機器人做對話,但如果你想要做一些進階應用,當然還是有 API 可以做串接會更方便做一些二次開發。
![](https://platform.openai.com/curl.png)
很幸運的是,前陣子 OpenAI 開放了 gpt-3.5-turbo 這個模型的 API 讓大家免費試用,額度為前三個月提供 18 USD 的 API 額度可以免費試用。
![](https://weii.dev/content/images/2023/03/image.png)
計費方式可以參考下面的連結,基本上用傳遞給 API 的文字數量做計費,以自己玩玩的用途,基本上用不太完。
![](https://openaicom.imgix.net/7ef54590-0045-4fb6-9f03-9643e08f0d94/stangel-2022-0423.jpg?auto=compress%2Cformat&fit=min&fm=jpg&q=80&rect=0%2C540%2C3840%2C2160)
前置準備
n8n 環境
首先大家需要有一個可以使用的 n8n 環境,細節之前的文章有介紹過,大家可以參考之前的文章。
![](https://weii.dev/content/images/2022/09/-------2022-09-17-021236.png)
想要快速開始的可以使用以下的 docker compose 檔案,裡面包含了稍後會用來儲存機器人 context 的 redis。
version: "3"
services:
n8n:
image: n8nio/n8n
restart: always
ports:
- 5678:5678
command:
- n8n
- start
- --tunnel
environment:
- NODE_ENV=production
- N8N_PORT=5678
- GENERIC_TIMEZONE=Asia/Taipei
volumes:
- n8n-data:/home/node/.n8n
redis:
image: redis
restart: always
ports:
- 6379:6379
volumes:
n8n-data: {}
OpenAI API Key
在使用 OpenAI Chat API 之前需要準備一把 API Key,為此請大家先到這邊註冊一個帳號。
![](https://platform.openai.com/curl.png)
接著登入後到平台右上角選 View API Keys
![](https://weii.dev/content/images/2023/03/image-1.png)
點選 Create new secret key 並把 API Key 保存好,這把Key 只能看到一次萬一搞丟了只能重新生成。
![](https://weii.dev/content/images/2023/03/image-2.png)
Telegram Bot Token
有寫過 Telegram Bot 的應該都會知道,所有的機器人都需要先到 BotFather 這個機器人發行一把 Token 之後跟 Telegram 平台互動都是靠這個 Token,大家可以到下面的連結開始發行 Token。
![](https://cdn1.telesco.pe/file/IdTEkICTOhrxsum6vfMo67ooqkle-emw9DZmVAMcLQ1IX-2JvCuFdGuS6gFOSqAWD3bVMTbTHmSfmdpf--cCZi-gal_ReFtDo8LuVBuBEifuphsYEzzDnF5jqKbVJvYbr4V0SzpXF_oqqCuBZq7gOuavXZj_z7VLK-3-fzlf8z7TVBxida98RdSNSP4eYEvS-WqI3nJDw7h4rv9mDaJ_KWtYDoER_lcEtwQOEW_s9CuX0ojxB4gcdz0uAP-1mnawtJ6VzBH_xt06xYOmi1LkRYyR7wMwNF4AjzqBXaFVS6AQi4hnHwW27CD1D9aydY6MbVWQe46NBqLZzjjpYcKzBA.jpg)
進入機器人後可以看到說明,解釋機器人的功能。
![](https://weii.dev/content/images/2023/03/image-3.png)
輸入 /newbot 指令,並指定一個不重複的機器人名稱,就可以拿到 Bot Token,記得有這把 Token 的人可以對機器人的 API 做呼叫,因此一定避免把 Token 分享給別人。
![](https://weii.dev/content/images/2023/03/image-4.png)
OpenAI Chat API 介紹
在前置作業做完後,簡單介紹一下如何串接,CahtGPT API,我們先到官方文件的網址。
如何發請求
![](https://platform.openai.com/curl.png)
文件旁有個 curl 指令,我們複製下來到自己喜歡的工具裡測試一下。
![](https://weii.dev/content/images/2023/03/image-5.png)
這裡我們用 Postman 做示範,選擇 import 把官方文件的 Curl 貼上後匯入。
![](https://weii.dev/content/images/2023/03/image-7.png)
接著到 Authorization 選擇 Bearer Token 貼上剛剛申請的 OpenAI API Key。
![](https://weii.dev/content/images/2023/03/image-6.png)
接著到 Body 的地方貼入以下請求,按下 Send 就可以得到 ChatGPT 的回答。
{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "system",
"content": "用繁體中文回答問題"
},
{
"role": "user",
"content": "你好"
}
]
}
![](https://weii.dev/content/images/2023/03/image-8.png)
重要請求參數說明
model
細節可以參考以下的文件,基本上都使用 gpt-3.5-turbo 就可以。
![](https://platform.openai.com/curl.png)
messages
傳遞給機器人的訊息,是一個 Array ,裡面可以把對話的歷史紀錄都傳給他,ChatGPT API 會依照對話歷史紀錄來確定對話的上下文,因此大家體會機器人可以依照你整段聊天的歷史來回答你的問題。Array 裡的每個歷史紀錄有三種 role 標籤。
system 代表的是對機器人的一種指示,例如範例中的 "用繁體中文回答問題" ,那麼機器人就會用繁體中文來回答問題,當然你也可以對它輸入,扮演一個很生氣地客服人員之類的指示,可以得到很有趣的效果。
user 代表的是使用者輸入的問題,這邊就不做解釋了。
assistant 代表的是 API 的回覆,也記得要攜帶到歷史紀錄中。
![](https://weii.dev/content/images/2023/03/image-9.png)
大家可以在 Postman 中手動的發請求,然後把 Array 攜帶歷史紀錄,體會一下機器人可以記住你的上下文的對話感受。
開始串接 n8n
下面是整個 n8n 的工作流的完整存檔大家可以下載後匯入,本文章就不一步一步帶大家來創立工作流,而是解釋一下重點的部分。
匯入
匯入方法也很簡單,先創建一個新的工作流之後。
![](https://weii.dev/content/images/2023/03/image-15.png)
在右上角選單選擇 Import from File... 匯入剛剛下載的工作流定義就能匯入完整的工作流。
![](https://weii.dev/content/images/2023/03/image-16.png)
匯入後會看到有很多紅色的驚嘆號圖示,那是因為缺少了各種跟外部系統溝通的 Token 接著來一一匯入。
![](https://weii.dev/content/images/2023/03/image-14.png)
設定 API Key & Bot Token
首先雙擊 Telegram Trigger 節點,選擇 Create New Credential 後貼上一開始申請的 Telegram Bot Token,按 Save 存檔後關閉彈窗。
如果看到其他 Telegram 節點還有紅色驚嘆號,點進去選擇剛剛存檔的 Token 就可以了。
![](https://weii.dev/content/images/2023/03/image-17.png)
![](https://weii.dev/content/images/2023/03/image-18.png)
![](https://weii.dev/content/images/2023/03/image-19.png)
雙擊 OpenAI 節點,選擇 Create New Credential 後貼上 API Key,按 Save 存檔後關閉彈窗。同時檢查 HTTP Request OpenAI API 節點也設定了 OpenAI API Key。
![](https://weii.dev/content/images/2023/03/image-20.png)
![](https://weii.dev/content/images/2023/03/image-21.png)
![](https://weii.dev/content/images/2023/03/image-22.png)
![](https://weii.dev/content/images/2023/03/image-23.png)
![](https://weii.dev/content/images/2023/03/image-24.png)
最後,進入 Redis Get Context 節點,新增 Redis 連線資訊,用文章內附的 docker compose 檔案啟動 n8n 的話照圖片上的填就行,如果是自己另外架的 Redis 就按照自己的設定填入。
![](https://weii.dev/content/images/2023/03/image-26.png)
![](https://weii.dev/content/images/2023/03/image-28.png)
![](https://weii.dev/content/images/2023/03/image-29.png)
最後,右上角存檔後,選 Active 把工作流啟動,接著 n8n 就會開始輪巡 Telegram 事件,就可以來跟機器人對話了。
![](https://weii.dev/content/images/2023/03/image-30.png)
可以試著先跟機器人說一些話,再問機器人之前對話中提到的內容,可以發現機器人可以根據之前對話的內容來回答問題。大功告成???
![](https://weii.dev/content/images/2023/03/image-31.png)
整體工作流介紹
大家可以先觀察工作流,可以簡單發現主要就分成兩個分支,下面這條分支主要是第一次對話時,因為沒有上下文所以使用內建的 OpenAI 節點做 API 呼叫後並把對話上下文存入 Redis 中。
而上面的分支是第二次以後的對話,從 Redis 中取出上下文,並把使用者該次的提問附加在上下文中,因為內建的 OpenAI 節點有一點缺陷,沒辦法傳遞 Array 型態的上下文,因此改用 HTTP Request 節點向 OpenAI 發請求。
![](https://weii.dev/content/images/2023/03/image-49.png)
第一次對話
![](https://weii.dev/content/images/2023/03/image-50.png)
首先看 Telegram Trigger 節點的內容,主要關心以下幾個欄位。
message.from.username 發訊息的使用名稱
message.chat.id 發訊息的聊天室 ID
message.text 訊息內容
![](https://weii.dev/content/images/2023/03/image-38.png)
接著的 IF /gpt 節點,則是判斷訊息內容是否為 /gpt 開頭的指令,並且指令後的內容非空才繼續往下執行。
![](https://weii.dev/content/images/2023/03/image-35.png)
接著的三個節點,分別為從 Redis 用聊天室 ID 以及使用者名稱作為 Key 取出上下文,由於是第一次對話,取出來沒有內容,因此在下一個 Code 節點就會照程式邏輯被填入空 Array,並在第三個節點判斷上下文陣列長度沒有大於 0 進入工作流下方分支。
![](https://weii.dev/content/images/2023/03/image-37.png)
![](https://weii.dev/content/images/2023/03/image-39.png)
![](https://weii.dev/content/images/2023/03/image-40.png)
接著來看在下方分支的第一個節點,用內建的 OpenAI 節點,傳入一個 system messages "用繁體中文回答",以及使用者輸入的聊天內容。
![](https://weii.dev/content/images/2023/03/image-43.png)
![](https://weii.dev/content/images/2023/03/image-44.png)
接著用聊天室 ID 以及使用者名稱作為 Key,並從前面的節點中分別把使用者的輸入,跟機器人的回答,組裝成一個 JSON Array 字串,塞進 Redis 中,並設定一小時的過期時間,這樣一小時內沒有任何對話的話機器人會自動忘記對話的上下文。
![](https://weii.dev/content/images/2023/03/image-45.png)
![](https://weii.dev/content/images/2023/03/image-46.png)
最後用 Telegram 節點發送機器人的回覆到使用者所在的聊天室。
![](https://weii.dev/content/images/2023/03/image-47.png)
第二次對話
前兩個節點內容跟第一次對話沒有差別,就不重複說明了,主要看第 3,4,5 個節點。
![](https://weii.dev/content/images/2023/03/image-51.png)
主要聊天室 ID 以及使用者名稱作為 Key 從 Redis 中取出之前聊天的上下文,必須注意這裡取出來的資料型態是 String,因此在下一個 Code 節點中,用 JSON.parse 函數解析成 Array 型態。
![](https://weii.dev/content/images/2023/03/image-52.png)
![](https://weii.dev/content/images/2023/03/image-53.png)
接著就命中了 IF 節點的長度大於 0 的條件,進入上方的分支。
![](https://weii.dev/content/images/2023/03/image-55.png)
![](https://weii.dev/content/images/2023/03/image-54.png)
上方分支的第一個節點,利用 Code 節點把使用者的訊息 push 到上下文 Array 中,並在下一個 HTTP Request 節點把完整的上下文傳入,來呼叫 OpenAI API。
![](https://weii.dev/content/images/2023/03/image-56.png)
![](https://weii.dev/content/images/2023/03/image-57.png)
接著第三個節點則把機器人的回答附加到歷史的上下文 Array 中,並在第四個節點存入 Redis 並設定一小時過期時間。最後把機器人的回覆利用 Telegram 節點發送到使用者說話的聊天室,這邊之前介紹過就不放截圖了。
![](https://weii.dev/content/images/2023/03/image-58.png)
![](https://weii.dev/content/images/2023/03/image-60.png)
結尾
這次透過 n8n 以及 OpenAI API 的整合完成了 ChatGPT Telegram 機器人,過程上沒有太多的開發,部屬也很方便,希望大家可以透過這個應用,能再次體會 n8n 的方便,並且有興趣的話可以給這個機器人增加更多功能,並在下方留言板歡迎大家討論。
感謝大家的支持!!!