在我們的上一篇文章中,我們已經準備好了製作LINE Bot所需的各項工具。接下來,我們將一起來進行最基礎的Python與LINE的串接練習。透過這次的練習,我們將喚醒我們的機器人,並讓它展現最基本的回答功能。那麼,讓我們開始吧!
開啟Visual Studio Code
創建資料夾
首先,我們先創建要存放LINE機器人所需要的程式碼以及相關檔案的資料夾,在此我選擇一個路徑創建一個名為LINEBot的資料夾。
接著打開Visual Studio Code,點選左上角的「檔案」,接著點選「開啟資料夾」,並且選擇剛剛創建的LINEBot資料夾的路徑。
選擇好路徑後,我們必須創建2個基本的檔案,將滑鼠指標移至檔案總管並按下右鍵,選擇新增檔案,分別創建:
- app.py: 存放Linebot主程式檔
- requirements.txt: 要安裝的套件版本
創建完會如下圖這樣
編寫requirements.txt
我們接下來要修改的文件是requirements.txt。由於剛剛建立的Render是一個非常乾淨的環境,許多模組並未被預設安裝。這彷彿我們剛開始下載Python一樣,許多模組需要經由pip install進行額外安裝。而requirements.txt的作用就是告知Render,我們的檔案需要哪些模組的支援。
下面是我目前用到的模組,它們都是在我根據程式需求進行寫作的過程中逐一加入的。如果你想要確保模組在Render上的版本與本地端一致,別忘了加上「==版本號」。這種作法可以預防某些功能因為版本不同,在本地端與Render執行上的不一致。
flask==3.0.3
numpy==1.23.2
beautifulsoup4==4.6.3
requests==2.20.1
scipy
pandas==1.2.4
lxml==4.5.2
line-bot-sdk==3.11.0
datetime
matplotlib
gspread==4.0.1
oauth2client==4.1.3
pyimgur
mpl_finance
arrow
編寫app.py
接下來主程式檔app.py要寫的程式碼就比較多了唷!!
我們就分段來簡單說明一下
首先當然要先import所需要的模組,這邊都是為了讓pyhtont串接linebot所需要的一些line官方提供的模組
- Flask:這是一個用於建立 web 應用的 Python 框架。在這裡,它被用來創建一個可以接收和處理來自 LINE 的 HTTP 請求的 web 服務器。
- request:這是 Flask 框架中的一個模組,用於處理 HTTP 請求。
- abort:這是 Flask 框架中的一個函數,用於中止 HTTP 請求並返回一個錯誤碼。
- LineBotApi:這是 Line Bot SDK 中的一個類,提供了與 LINE 伺服器進行溝通的各種方法,例如發送訊息、回覆訊息等。
- WebhookHandler:這是 Line Bot SDK 中的一個類,用於處理來自 LINE 的 webhook 事件。當用戶在 LINE 上向你的 bot 發送訊息時,LINE 伺服器會發送一個 webhook 事件到你的服務器,WebhookHandler 就是用來處理這些事件的。
- InvalidSignatureError:這是 Line Bot SDK 中的一個異常類,當 webhook 事件的簽名不正確時會拋出這個異常。
- MessageEvent:這是 Line Bot SDK 中的一個類,表示一個訊息事件。當用戶向你的 bot 發送訊息時,你的服務器會收到一個 MessageEvent。
- TextMessage:這是 Line Bot SDK 中的一個類,表示一個文本訊息。你可以創建一個 TextMessage 對象並通過 LineBotApi 將它發送給用戶。
- TextSendMessage:這是 Line Bot SDK 中的一個類,表示一個要發送的文本訊息。你可以創建一個 TextSendMessage 對象並通過 LineBotApi 將它發送給用戶。
from flask import Flask, request, abort
from linebot import (
LineBotApi, WebhookHandler
)
from linebot.exceptions import (
InvalidSignatureError
)
from linebot.models import (
MessageEvent, TextMessage, TextSendMessage,
)
接下來我們就要將python跟line做結合,那要怎麼結合呢?
其實很簡單,首先輸入以下的程式碼,該段程式碼就是串接linebot的鑰匙,其中可以看到兩個值得注意的部分,分別為「你自己的token」以及「你自己的secret」,這兩段是要填入自己linebot的token以及secret,但這兩個部分該去哪裡取得呢?
app = Flask(__name__)
# 必須放上自己的Channel Access Token
line_bot_api = LineBotApi('你自己的token')
# 必須放上自己的Channel Secret
handler = WebhookHandler('你自己的secret')
進入以下畫面後,點選「Messaging API」,並且用滑鼠往下滑至底部。
最底部有一個名為「Channel access token」的部分,點選「Issue」便可產生一串代碼,此就是我們上方提到的token部分,將這段代碼複製起來,並且貼到程式碼中「 你自己的token」 的地方。
接下來回到最上方,點選「Basic settings」。
往下滑到「Channel secret」,一樣將代碼複製到程式碼中的 「你自己的secret」 上。
下一步,我們需要注意的是,由於我們使用的雲端服務是免費版,所以在我們長時間未使用時,雲端服務會進入休眠狀態。每次再度啟動都需要花費一些時間。因此,我習慣在開發階段時加上以下的一段程式碼。一但程式開始運行,該程式碼會主動告知我們,服務已經準備好了。這部分的細節,我們將在後續的教學中詳細介紹。現在先嘗試寫上看看。
line_bot_api.push_message('你自己的ID', TextSendMessage(text='你可以開始了'))
其中值得我們注意的是「
你自己的ID」的部分,該部分一樣回到剛剛的
LINE developer,在 Channel secret 下方有一個名為「
Your user ID」,一樣將該段代碼複製到程式碼中 「
你自己的ID」 的地方
輸入好token等驗證代碼後,就是要設置一個路由來接收和處理來自 LINE 伺服器的 webhook 事件。以下程式碼主要目的是為了設置一個 HTTP POST 的路由,用於接收和處理來自 LINE 伺服器的 webhook 事件。以下是詳細的步驟:
- @app.route("/callback", methods=['POST']):這一行是用來設置一個路由的。當有 HTTP POST 請求發送到你的伺服器的 "/callback" 路徑時,會調用下面的 callback() 函數。
- signature = request.headers['X-Line-Signature']:這一行是從 HTTP 請求的頭部獲取 「X-Line-Signature」的值。這個值是 LINE 伺服器為了驗證請求的合法性而添加的一個簽名。
- body = request.get_data(as_text=True):這一行是獲取 HTTP 請求的主體,也就是實際的訊息內容。
- app.logger.info("Request body: " + body):這一行是將請求主體的內容記錄到日誌中。
- handler.handle(body, signature):這一行是調用之前導入的 WebhookHandler的 handle() 方法,將請求主體和簽名作為參數傳入。handle() 方法會驗證簽名的合法性,並根據請求主體的內容處理 webhook 事件。
- 如果在處理 webhook 事件時發生了 InvalidSignatureError 異常,則調用 abort(400) 函數中止請求並返回一個 400 錯誤碼。
- 如果一切都正常,則返回 'OK' 字符串作為 HTTP 響應的主體。
# 監聽所有來自 /callback 的 Post Request
@app.route("/callback", methods=['POST'])
def callback():
# get X-Line-Signature header value
signature = request.headers['X-Line-Signature']
# get request body as text
body = request.get_data(as_text=True)
app.logger.info("Request body: " + body)
# handle webhook body
try:
handler.handle(body, signature)
except InvalidSignatureError:
abort(400)
return 'OK'
然而寫上程式碼後仍然沒有告訴程式碼我們要串接的Render在哪,因此,我們打開上篇教學中我們創建的Render雲端伺服器
我們需要的是該網頁的網址,所以將網址複製起來
接著將剛剛複製的網址貼上,並在後方加上「/callback」,最後按下「Update」進行更新
再來我們可以進行一些設定,像是第一個為「是否機器人加入群組」,預設為否,第二個為「機器人是否自動回覆訊息」,預設為是,但我們為了不讓機器人回覆不必要的罐頭訊息,因此我們要點選右方的「Edit」,進去進行修改
進去後往下看到進階設定的地方,我們要將「自動回應訊息」設為「停用」,這時順便檢查下方的「Webhook」是否為「啟用」
大致上串接的工作到這就算正式完成了,之後就不太需要進行變更了,我們就可以專注於撰寫功能程式碼即可
linebot功能程式碼
接下來,我們仍然要在app.py中進行主程式的撰寫
我們今天就先複製以下的程式碼進行測試看看,往後的教學會一一介紹有哪些linebot的功能程式碼
簡單說一下,該段程式碼就是我們輸入什麼內容,機器人就會原封不動的回傳給你一模一樣的功能
#訊息傳遞區塊
##### 基本上程式編輯都在這個function #####
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
message = event.message.text
line_bot_api.reply_message(event.reply_token,TextSendMessage(message))
而最後我們就必須執行程式碼,所以記得加上以下的程式碼,以表示執行
#主程式
import os if __name__ == "__main__":
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port)
記得以上的程式碼都要用「Ctrl + s」儲存後再上傳唷!!
上傳至github
當我們以上三個程式碼都編寫完畢後,我們接下來就要將這些程式碼上傳至github中
首先,先開啟我們上篇教學中創建的github資料夾,點選右上角的「Add file」,再點選「Upload files」
進去以後,點選畫面中間的「choose your files」,並選擇上述編寫程式碼的檔案,等到檔案都上傳完後,最後按下「commit changes」
上傳完的資料夾會顯示如下多出了3個檔案
接著回到heroku中,我們點選左上角的「Deploy」,並點選要用「GitHub」上傳的方式,如果剛剛有登入github,應該會顯示如下圖第3步驟的樣子,前方為你github的帳戶,如果沒有就自行登錄你的github帳戶,而後方輸入你創立的github資料夾,並按下search,這時應該會出現一個如圖第4步驟的路徑,這時按下右方的「Connect」進行串接
串接後,由於我們目前github中沒有其他分支版本,所以預設的版本就是main,如果往後有使用到分支再跟大家分享,這裡我們只需要按下「Deploy Branch」進行佈署
第一次佈署應該都會比較久一點,所有耐心等待一下,而佈署完成會出現如下圖的樣子,表示佈署成功
佈署完成後,這時我們先前用LINE加入的機器人就會突然說出一句「你可以開始了」,表示程式碼佈署成功,這時我們隨便輸入,像我輸入了「你好」,機器人也就會回覆「你好」,我輸入「我誰~~~~」,機器人一樣會回覆 「我誰~~~~」
結論
是不是開始覺得興奮啦!!今天我們學會了如何將python、github、heroku以及linebot進行串接,往後的程式碼教學只會著重在主程式(app.py)中的功能程式碼那部分,其餘皆為設定一次即可,大家就先熟悉如何熟練的串接各個平台,往後不斷更新程式碼後,仍然需要重複上傳與佈署等動作,有興趣的也可自行摸索各個平台的一些功能唷!!