每當朋友或家人要聚餐時,是不是總要花很長的時間尋找評價不錯的餐廳?不但要確認營業時間、消費價格及地點,還要觀看許多的美食文章才有辦法決定,這時候如果有人能夠明確提供幾間符合條件且有人氣的餐廳作為選擇,想必會省事許多。
所以筆者開發了一個美食的LINE Bot小作品,透過對談的方式瞭解使用者所要尋找的餐廳條件後,利用Python網頁爬蟲取得目前正在營業的五間最高人氣餐廳資料,回覆給使用者作為參考。
為了要讓想學習的您能夠由淺入深,瞭解其中的實作過程,所以將會分成三篇文章來進行教學。
2020/06/30補充說明
而在進行實作前,先來看一下LINE Bot主要的執行架構,如下圖:
使用者透過LINE發送訊息時,LINE Platform將會進行接收,並且傳遞至我們所開發的LINE Bot執行邏輯運算後,透過LINE所提供的Messaging API回應訊息給LINE Platform,最後再將訊息傳遞給使用者。
其中Messaging API(Application Programming Interface),就是LINE官方定義的回應訊息標準介面,包含Text(文字)、Sticker(貼圖)、Video(影片)、Audio(聲音)及Template(樣板)訊息等,完整的說明可以參考LINE的官方文件。
所以在我們的LINE Bot回應訊息時,就要依據Messaging API定義的規範,傳入相應的參數後,Messaging API就會回應使用者相對的訊息類型。簡單來說,就是LINE Platform與LINE Bot的溝通橋樑。
而本文就先以最基本的使用者發送什麼訊息,LINE Bot就回應什麼訊息為例,讓讀者體會其中的運作方式,整體架構如下圖:
本文的實作步驟包含:
- 建立Provider
- 建立Messaging API channel
- 設定LINE Bot憑證
- 開發LINE Bot應用程式
- 安裝Ngrok
- 設定LINE Webhook URL
一、建立Provider
要開發LINE Bot前,首先需建立一個Provider,也就是服務提供者,主要用來讓LINE官方能夠識別這個LINE Bot是誰提供的,可以是個人、公司或服務名稱等。
前往LINE Developers,「使用LINE帳號登入」後,會看到如下圖的畫面,輸入姓名及電子郵件即可,目的在於讓開發人員同意使用規範與聯絡使用:
第一步驟就是建立服務提供者(Provider),所以點擊「Create a new provider」,在按鈕下方就會出現輸入框,如下圖:
二、建立Messaging API channel
各位可以把頻道(Channel)想像是服務提供者(Provider)所建立的LINE帳號,藉此和使用者互動與傳遞訊息。
由於本文所建立的LINE Bot主要以傳訊息為主,所以選擇「Create a Messaging API channel」。接著,會看到基本資料的輸入畫面,截取部分如下圖:
其中的Channel icon為LINE帳號的大頭貼,之後的「Privacy policy URL」及「Terms of use URL」可選擇性填寫,沒有的話保持空白即可。建立成功後,就可以看到如下畫面:
- Channel secret(頻道密碼):位於Basic settings頁籤中,如下圖:
三、設定LINE Bot憑證
本文將以Django框架為例,利用Python來建置LINE Bot應用程式(APP)。首先,透過以下指令安裝會使用到的Python套件:
$ pip install django $ pip install line-bot-sdk $ pip install beautifulsoup4 $ pip install requests
$ django-admin startproject mylinebot . #建立Django專案 $ python manage.py startapp foodlinebot #建立Django應用程式 $ python manage.py migrate #執行資料遷移(Migration)
這時候的專案架構如下圖:
LINE_CHANNEL_ACCESS_TOKEN = 'Messaging API的Channel access token' LINE_CHANNEL_SECRET = 'Basic settings的Channel Secret'
並且,在INSTALL_APPS的地方,加上剛剛所建立的Django應用程式(APP),如下範例:
# Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'foodlinebot.apps.FoodlinebotConfig', ]
四、開發LINE Bot應用程式
設定完成後,開啟Django應用程式(APP)的views.py檔案,這邊就是撰寫LINE Bot接收訊息後,所要執行的運算邏輯,這邊先以使用者發送什麼訊息,就回覆什麼訊息為例,來測試Django應用程式(APP)能夠成功的和LINE頻道(Channel)進行連結,如下範例:
from django.shortcuts import render from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden from django.views.decorators.csrf import csrf_exempt from django.conf import settings from linebot import LineBotApi, WebhookParser from linebot.exceptions import InvalidSignatureError, LineBotApiError from linebot.models import MessageEvent, TextSendMessage line_bot_api = LineBotApi(settings.LINE_CHANNEL_ACCESS_TOKEN) parser = WebhookParser(settings.LINE_CHANNEL_SECRET) @csrf_exempt def callback(request): if request.method == 'POST': signature = request.META['HTTP_X_LINE_SIGNATURE'] body = request.body.decode('utf-8') try: events = parser.parse(body, signature) # 傳入的事件 except InvalidSignatureError: return HttpResponseForbidden() except LineBotApiError: return HttpResponseBadRequest() for event in events: if isinstance(event, MessageEvent): # 如果有訊息事件 line_bot_api.reply_message( # 回復傳入的訊息文字 event.reply_token, TextSendMessage(text=event.message.text) ) return HttpResponse() else: return HttpResponseBadRequest()
這邊幾個地方說明一下,第10、11行為取得settings.py中的LINE Bot憑證來進行Messaging API的驗證。
而在callback檢視函式中,當偵測到使用者有傳入的事件,就會透過Python迴圈進行讀取(第28行),如果其中有訊息事件(第29行),則回覆使用者所傳入的文字(第30~33行)。
接下來就要設定這個LINE Bot應用程式(APP)的連結網址,所以在Django應用程式(APP)下建立一個urls.py檔案,加入以下的網址設定:
from django.urls import path from . import views urlpatterns = [ path('callback', views.callback) ]
而為了要將這個Django應用程式(APP)的網址也加入到專案主程式中,所以,在Django專案主程式下的urls.py檔案中,加入以下的網址設定:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('foodlinebot/', include('foodlinebot.urls')) #包含應用程式的網址 ]
五、安裝Ngrok
LINE Bot應用程式(APP)都完備後,接下來就要讓網址能夠公開(Public)且具有HTTPS,LINE頻道(Channel)才有辦法連結。
這時候除了可以將LINE Bot應用程式(APP)部署到像Heroku雲端平台,擁有對外公開的HTTPS網址外,還可以使用一個非常強大的工具-Ngrok。
Ngrok簡單來說,就是能夠將你本機的IP埠號(http://127.0.0.1:8000),對應到一個隨機產生的HTTPS網址,並且這個HTTPS網址是對外公開的(Public)的,這時候外部使用者只要透過這個HTTPS網址,就能夠存取本機所運行的服務,是不是非常的強大阿。
首先,前往Ngrok官網,如下圖:
依據作業系統進行下載即可,而這邊要特別注意的是,在下方會有專屬於你的憑證(Token),如下圖:
$ ngrok authtoken <YOUR TOKEN>
接著,就可以透過Ngrok,將本機的埠號對外公開,以本文為例,Django在本機運行的埠號為8000,所以輸入以下的指令:
$ ngrok http 8000
執行結果
Ngrok就會隨機產生一個HTTPS的網址,只要把這個網址填入LINE Webhook URL,以及LINE Bot應用程式(APP) settings.py檔案中的ALLOWED_HOSTS,如下範例,LINE頻道(Channel)就能夠與LINE Bot應用程式(APP)互相連結:
ALLOWED_HOSTS = [ 'cf3fb14f6910.ngrok.io' #允許的網域名稱 ]
接著,利用以下的指令執行LINE Bot應用程式(APP):
$ python manage.py runserver
六、設定LINE Webhook URL
2020/06/30補充說明
在一般的網路世界中,用戶端(Client)會發送請求(Request)給伺服器端(Server),處理完商業邏輯後,就會回傳結果(Response)給用戶端(Client),如下圖:
而Webhook機制就是除了擁有上面一般請求(Request)的流程外,還能夠主動推播訊息給用戶端(Client),即便用戶端(Client)沒有向伺服器端(Server)發送請求(Request),所以Webhook機制讓用戶端(Client)與伺服器端(Server)成了雙向的溝通,如下圖:
LINE Webhook URL位於LINE Developers開發者控制台的Messaging API頁籤中,如下圖:
範例中,在Ngrok的網址後面,記得要加上LINE Bot應用程式(APP)的網址,這樣LINE頻道(Channel)才有辦法請求(Request)。除此之外,下方的「Use webhook」要啟用。
這邊點擊「Verify」進行驗證,如果發生錯誤,而LINE Bot應用程式(APP)的終端機(Terminal)中卻沒有出現問題的話,則無需擔心,還是可以繼續往下實作。
由於本文所開發的LINE Bot應用程式(APP)會自動回覆訊息,而無需LINE官方回覆,所以在下方的「Auto-reply messages」,點擊「Edit」,如下圖:
七、小結
本文為基本的LINE Bot實作過程,在下一篇文章中,將會加入Python網頁爬蟲,依據使用者所傳入的需求,爬取知名美食網站的資料,回覆給使用者。希望本文的教學有幫助到您,歡迎分享給身邊在學習LINE Bot的朋友。
有想要看的教學內容嗎?歡迎利用以下的Google表單讓我知道,將有機會成為教學文章,分享給大家😊
python manage.py startapp foodlinebot
回覆刪除File "manage.py", line 16
) from exc
^
SyntaxError: invalid syntax
請問要如何解決?
試試看使用以下指令:
刪除python3 manage.py startapp foodlinebot
大大您好
回覆刪除我現在想要runserver的情況下 會出現下面的錯誤
C:\Users\AlphaLin\bot>python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
.
.
.
.(一堆錯誤代碼)
path('dblinebot/', include('dblinebot.urls')),
NameError: name 'include' is not defined
我以為是我的電腦沒有裝include害的 所以我就
C:\Users\AlphaLin\bot>pip install include
Requirement already satisfied: include in c:\python38\lib\site-packages (0.2.2)
然後還是出現一樣的錯誤
請問是可能哪邊有錯?
謝謝
另外 我試著把webhook更新上去 Verify之後 結果會出現 The webhook returned an HTTP status code other than 200
刪除然後再ngrok下面會出現 POST /dblinebot/callback 502 Bad Gateway 的錯誤
是因為我上面的問題導致 下面這個問題嗎?
ALPHAGXX您好:
刪除include()是Django內建的方法,不是套件,用來讓Django結合專案中各個應用程式的網址設定(urls.py)。檢查一下您的Django專案主程式下的urls.py檔案中,是否有引用include()方法,如下:
from django.urls import path, include
引用後,就不會出現NameError: name 'include' is not defined的錯誤,也就不會導致ngrok的502 Bad Gateway(找不到網址)錯誤。
希望以上有解決您的問題,如果沒有,歡迎至Learn Code With Mike粉絲專頁私訊我,將會協助您解決,謝謝 :)
這個錯誤解決了 可是又有錯誤發生了XD
刪除server跑起來了
然後我按了Line Developer 的Verify之後
他出現這個問題
The webhook returned an HTTP status code other than 200
ngrok
POST /dblinebot/callback 500 Internal Server Error
LINEBOT server
Internal Server Error: /dblinebot/callback
linebot.exceptions.LineBotApiError: LineBotApiError: status_code=400, request_id=5ead826d-cb29-43d1-908f-05366221be0a, error_response={"details": [{"message": "May not be empty", "property": "messages[0].text"}], "message": "The request body has 1 error(s)"}, headers={'Server': 'openresty', 'Content-Type': 'application/json', 'x-line-request-id': '5ead826d-cb29-43d1-908f-05366221be0a', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block', 'x-frame-options': 'DENY', 'Content-Length': '118', 'Expires': 'Thu, 01 Oct 2020 11:33:20 GMT', 'Cache-Control': 'max-age=0, no-cache, no-store', 'Pragma': 'no-cache', 'Date': 'Thu, 01 Oct 2020 11:33:20 GMT', 'Connection': 'close'}
[01/Oct/2020 19:33:19] "POST /dblinebot/callback HTTP/1.1" 500 84333
是還有哪邊有問題呢= =?
ALPHAGXX您好:
刪除應該是訊息不能為空值的關係所導致,請您將ngrok及LINEBOT server跑起來,直接使用LINE傳送訊息試試看 :)
大大你好
刪除我傳送訊息後出現
Bad Request: /foodlinebot/callback
[12/Oct/2020 16:00:45] "POST /foodlinebot/callback HTTP/1.1" 400 66635
ngrok也出現400 Bad Request
請問是哪裡可能出錯?
謝謝
可以檢查一下LINE Develops的Webhook URL是否有正確配對Django專案主程式及應用程式的urls.py檔案設定,也確認一下settings.py檔案中的LINE_CHANNEL_ACCESS_TOKEN及LINE_CHANNEL_SECRET設定,另外,line-bot-sdk記得安裝。
刪除希望以上有解決您的問題,如果還有其它疑問,歡迎至Learn Code With Mike粉絲專頁私訊我,將會協助您解決,謝謝 :)
您好,請問上面的問題解決了嗎?我是用flask架的,access_token和secret都對,但line還是一直回我400...
刪除您好,可以檢查一下專案的LINE Bot應用程式網址與LINE Webhook URL是否有正確設定,以及專案ALLOW_HOSTS的部分要設定ngrok的https網址,並且有安裝line-bot-sdk套件,最後試著用手機發送訊息,如果以上皆正確還是無法接收訊息,可以參考以下的文章,部署到Heroku雲端平台,來進行測試會較為準確:
刪除https://www.learncodewithmike.com/2020/07/python-line-bot-deploy-to-heroku.html
希望以上對您有所幫助 :)
你好,請問我在
回覆刪除下載的檔案解壓縮,並且執行後,需要輸入以下的指令進行驗證:
$ ngrok authtoken
這個步驟發生錯誤
命令語法不正確.
請問 如何解決?
您好,$ ngrok authtoken指令之後是否有貼上您的Token(憑證)呢?
刪除我的Line Bot不會自動回覆我打的訊息,請問是哪部分出問題呢?
回覆刪除歡迎將問題或程式碼截圖,到Learn Code With Mike粉絲專頁發訊息給我,將會協助您解決,謝謝 :)
刪除我也經解決這個問題,謝謝您的回覆!
刪除我的Django應用程式(APP)的views.py檔案中,"from linebot import LineBotApi, WebhookParser"以及下面兩行會出現錯誤訊息,"Unable to import 'linebot'"。請問可能哪裡有問題嗎
刪除您好,請問是否有利用以下指令安裝LINE Bot SDK呢?
刪除$ pip install line-bot-sdk
還是會出現"Unable to import 'linebot'"��
刪除你好 我在Webhook URL 驗證時 發生錯誤訊息An error occurred when sending the webhook, 而在我的ngrok.exe命令列中收到 POST /footlinebot/callback 在Line機器人收不到它的回覆 想知道有什麼問題 謝謝.
回覆刪除您好,請問ngrok中POST /footlinebot/callback之後所顯示的HTTP狀態碼是多少呢? Django專案這邊的Terminal視窗中是否有顯示什麼錯誤訊息?
刪除