每當朋友或家人要聚餐時,是不是總要花很長的時間尋找評價不錯的餐廳?不但要確認營業時間、消費價格及地點,還要觀看許多的美食文章才有辦法決定,這時候如果有人能夠明確提供幾間符合條件且有人氣的餐廳作為選擇,想必會省事許多。
 
所以筆者開發了一個美食的LINE Bot小作品,透過對談的方式瞭解使用者所要尋找的餐廳條件後,利用Python網頁爬蟲取得目前正在營業的五間最高人氣餐廳資料,回覆給使用者作為參考。
 
為了要讓想學習的您能夠由淺入深,瞭解其中的實作過程,所以將會分成三篇文章來進行教學。
 
2020/06/30補充說明
而在進行實作前,先來看一下LINE Bot主要的執行架構,如下圖:
python_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 PlatformLINE Bot的溝通橋樑。
而本文就先以最基本的使用者發送什麼訊息,LINE Bot就回應什麼訊息為例,讓讀者體會其中的運作方式,整體架構如下圖:
python_line_bot

LINE Bot的部分,使用Django框架來進行建置,並且透過Messaging API回應Text(文字)訊息。在下一篇文章中,將會加入Python網頁爬蟲,取得美食網站的資訊回應給使用者。

本文的實作步驟包含:
  • 建立Provider
  • 建立Messaging API channel
  • 設定LINE Bot憑證
  • 開發LINE Bot應用程式
  • 安裝Ngrok
  • 設定LINE Webhook URL

一、建立Provider

要開發LINE Bot前,首先需建立一個Provider,也就是服務提供者,主要用來讓LINE官方能夠識別這個LINE Bot是誰提供的,可以是個人、公司或服務名稱等。
前往LINE Developers,「使用LINE帳號登入」後,會看到如下圖的畫面,輸入姓名及電子郵件即可,目的在於讓開發人員同意使用規範與聯絡使用:
python_line_bot
完成帳戶的建立,就會看到開發者控制台,如下圖:
python_line_bot
其中的三個圖示說明了開發流程,分別為「建立服務提供者(Provider)「建立頻道(Channel)「連結應用程式(APP)
第一步驟就是建立服務提供者(Provider),所以點擊「Create a new provider」,在按鈕下方就會出現輸入框,如下圖:
python_line_bot
這邊可以輸入姓名、公司或服務名稱等,LINE並沒有限定,點擊「Create」按鈕後,就會來到第二步驟,建立頻道(Channel)的畫面,如下圖:
python_line_bot

二、建立Messaging API channel

各位可以把頻道(Channel)想像是服務提供者(Provider)所建立的LINE帳號,藉此和使用者互動與傳遞訊息。
 
由於本文所建立的LINE Bot主要以傳訊息為主,所以選擇「Create a Messaging API channel。接著,會看到基本資料的輸入畫面,截取部分如下圖:
python_line_bot
python_line_bot
其中的Channel iconLINE帳號的大頭貼,之後的「Privacy policy URL」「Terms of use URL」可選擇性填寫,沒有的話保持空白即可。建立成功後,就可以看到如下畫面:
python_line_bot
最後的步驟就是要將這個頻道(Channel)與自己開發的應用程式連結,所以其中有兩個憑證會使用到,如下:
  • Channel secret(頻道密碼):位於Basic settings頁籤中,如下圖:
python_line_bot
  • Channel access token(頻道憑證):位於Messaging API頁籤中,要按下右方的「Issue」按鈕才會出現,如下圖:
python_line_bot

三、設定LINE Bot憑證

本文將以Django框架為例,利用Python來建置LINE Bot應用程式(APP)。首先,透過以下指令安裝會使用到的Python套件
  1. $ pip install django
  2.  
  3. $ pip install linebotsdk
  4.  
  5. $ pip install beautifulsoup4
  6.  
  7. $ pip install requests
接著,建立Django專案應用程式資料庫遷移(Migration),其中詳細的觀念可以點擊連結參考之前所寫的部落格文章。如下指令
  1. $ djangoadmin startproject mylinebot . #建立Django專案
  2.  
  3. $ python manage.py startapp foodlinebot #建立Django應用程式
  4.  
  5. $ python manage.py migrate #執行資料遷移(Migration)
這時候的專案架構如下圖:
python_line_bot
開啟專案主程式下的settings.py檔案,增加LINE Developers上所取得的兩個憑證設定,來LINE頻道(Channel)進行連結,如下範例
  1. LINE_CHANNEL_ACCESS_TOKEN = ‘Messaging API的Channel access token’
  2.  
  3. LINE_CHANNEL_SECRET = ‘Basic settings的Channel Secret’
並且,在INSTALL_APPS的地方,加上剛剛所建立的Django應用程式(APP)如下範例
  1. # Application definition
  2. INSTALLED_APPS = [
  3. ‘django.contrib.admin’,
  4. ‘django.contrib.auth’,
  5. ‘django.contrib.contenttypes’,
  6. ‘django.contrib.sessions’,
  7. ‘django.contrib.messages’,
  8. ‘django.contrib.staticfiles’,
  9. ‘foodlinebot.apps.FoodlinebotConfig’,
  10. ]

四、開發LINE Bot應用程式

設定完成後,開啟Django應用程式(APP)views.py檔案,這邊就是撰寫LINE Bot接收訊息後,所要執行的運算邏輯,這邊先以使用者發送什麼訊息,就回覆什麼訊息為例,來測試Django應用程式(APP)能夠成功的和LINE頻道(Channel)進行連結,如下範例
  1. from django.shortcuts import render
  2. from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden
  3. from django.views.decorators.csrf import csrf_exempt
  4. from django.conf import settings
  5.  
  6. from linebot import LineBotApi, WebhookParser
  7. from linebot.exceptions import InvalidSignatureError, LineBotApiError
  8. from linebot.models import MessageEvent, TextSendMessage
  9.  
  10. line_bot_api = LineBotApi(settings.LINE_CHANNEL_ACCESS_TOKEN)
  11. parser = WebhookParser(settings.LINE_CHANNEL_SECRET)
  12.  
  13.  
  14. @csrf_exempt
  15. def callback(request):
  16.  
  17. if request.method == ‘POST’:
  18. signature = request.META[‘HTTP_X_LINE_SIGNATURE’]
  19. body = request.body.decode(‘utf-8’)
  20.  
  21. try:
  22. events = parser.parse(body, signature) # 傳入的事件
  23. except InvalidSignatureError:
  24. return HttpResponseForbidden()
  25. except LineBotApiError:
  26. return HttpResponseBadRequest()
  27.  
  28. for event in events:
  29. if isinstance(event, MessageEvent): # 如果有訊息事件
  30. line_bot_api.reply_message( # 回復傳入的訊息文字
  31. event.reply_token,
  32. TextSendMessage(text=event.message.text)
  33. )
  34. return HttpResponse()
  35. else:
  36. return HttpResponseBadRequest()
這邊幾個地方說明一下,第10、11行為取得settings.py中的LINE Bot憑證來進行Messaging API的驗證。
 
而在callback檢視函式中,當偵測到使用者有傳入的事件,就會透過Python迴圈進行讀取(第28行),如果其中有訊息事件(第29行),則回覆使用者所傳入的文字(第30~33行)。
 
接下來就要設定這個LINE Bot應用程式(APP)的連結網址,所以在Django應用程式(APP)下建立一個urls.py檔案,加入以下的網址設定
  1. from django.urls import path
  2. from . import views
  3.  
  4. urlpatterns = [
  5. path(‘callback’, views.callback)
  6. ]
而為了要將這個Django應用程式(APP)的網址也加入到專案主程式中,所以,在Django專案主程式下的urls.py檔案中,加入以下的網址設定
  1. from django.contrib import admin
  2. from django.urls import path, include
  3.  
  4. urlpatterns = [
  5. path(‘admin/’, admin.site.urls),
  6. path(‘foodlinebot/’, include(‘foodlinebot.urls’)) #包含應用程式的網址
  7. ]

五、安裝Ngrok

LINE Bot應用程式(APP)都完備後,接下來就要讓網址能夠公開(Public)且具有HTTPSLINE頻道(Channel)才有辦法連結。
 
這時候除了可以將LINE Bot應用程式(APP)部署到像Heroku雲端平台,擁有對外公開的HTTPS網址外,還可以使用一個非常強大的工具-Ngrok
 
Ngrok簡單來說,就是能夠將你本機的IP埠號(http://127.0.0.1:8000),對應到一個隨機產生的HTTPS網址,並且這個HTTPS網址是對外公開的(Public)的,這時候外部使用者只要透過這個HTTPS網址,就能夠存取本機所運行的服務,是不是非常的強大阿。
 
首先,前往Ngrok官網,如下圖:
python_line_bot
點擊「Get started for free」後,會需要註冊一個帳戶,接著就會看到如下圖的畫面:
python_line_bot
依據作業系統進行下載即可,而這邊要特別注意的是,在下方會有專屬於你的憑證(Token),如下圖:
python_line_bot
將下載的檔案解壓縮,並且執行後,需要輸入以下的指令進行驗證
  1. $ ngrok authtoken <YOUR TOKEN>
接著,就可以透過Ngrok,將本機的埠號對外公開,以本文為例,Django在本機運行的埠號為8000,所以輸入以下的指令
  1. $ ngrok http 8000
執行結果
python_line_bot
Ngrok就會隨機產生一個HTTPS的網址,只要把這個網址填入LINE Webhook URL,以及LINE Bot應用程式(APP) settings.py檔案中的ALLOWED_HOSTS,如下範例,LINE頻道(Channel)就能夠與LINE Bot應用程式(APP)互相連結:
  1. ALLOWED_HOSTS = [
  2. ‘cf3fb14f6910.ngrok.io’ #允許的網域名稱
  3. ]
接著,利用以下的指令執行LINE Bot應用程式(APP):
  1. $ python manage.py runserver

六、設定LINE Webhook URL

2020/06/30補充說明
在一般的網路世界中,用戶端(Client)會發送請求(Request)給伺服器端(Server),處理完商業邏輯後,就會回傳結果(Response)給用戶端(Client),如下圖:
python_line_bot


而Webhook機制就是除了擁有上面一般請求(Request)的流程外,還能夠主動推播訊息給用戶端(Client),即便用戶端(Client)沒有向伺服器端(Server)發送請求(Request),所以Webhook機制讓用戶端(Client)與伺服器端(Server)成了雙向的溝通,如下圖:
python_line_bot
LINE Webhook URL位於LINE Developers開發者控制台的Messaging API頁籤中,如下圖:
python_line_bot
點擊「Edit」,輸入剛剛Ngrok所產生的HTTPS網址,如下圖:
python_line_bot
範例中,在Ngrok的網址後面,記得要加上LINE Bot應用程式(APP)的網址,這樣LINE頻道(Channel)才有辦法請求(Request)。除此之外,下方的「Use webhook」要啟用。
 
這邊點擊「Verify」進行驗證,如果發生錯誤,而LINE Bot應用程式(APP)的終端機(Terminal)中卻沒有出現問題的話,則無需擔心,還是可以繼續往下實作。
 
由於本文所開發的LINE Bot應用程式(APP)會自動回覆訊息,而無需LINE官方回覆,所以在下方的「Auto-reply messages」,點擊「Edit」,如下圖:
 
python_line_bot
 

設定自動回應訊息為「停用」,如下圖:

 
python_line_bot
最後,掃描Messaging API頁籤中的QR code,加入好友後就可以對LINE Bot傳送訊息,執行結果如下圖:
python_line_bot

Source: [Python+LINE Bot教學]6步驟快速上手LINE Bot機器人