2025 django 串接 LINE Messaging API

Posted by Young on 2025-07-26
Estimated Reading Time 5 Minutes
Words 1.2k In Total

1. 安裝套件

1
pip install line-bot-sdk python-decouple python-dotenv

記得更新 requirements.txt,在正式主機上部署時記得下載,別像我很笨的卡在回傳 502 error,結果 systemctl 一看才發現是 No module named 'linebot'

1
pip freeze > requirements.txt

2. LINE Developer Console & LINE Official Account Manager 設定

前往 LINE Developers Console 建立新的 Provider 或使用現有的

create_provider

Provider 新增完畢後,現在要用 LINE Messaging API,要先去 LINE Official Account Manager 建立官方帳號然後啟用 Messaging API,已經無法在 LINE Developers Console 直接啟用 Messaging API 了

manager_setting

manager_message_api

然後回到 LINE Developers Console,記錄以下資訊:

  • Channel Secret
  • Channel Access Token

3. 設定 LINE 的 Webhook URL

這邊是等等會再後端的 urls.py自己命名的 url,我的是

1
https://yourdomain.com/api/line-bot/webhook/

Django 後端

建立 line_bot apps

1
2
cd backend/
python manage.py startapp line_bot

新增 LINE Bot App 到 INSTALLED_APPS

1
2
3
4
5
6
7
8
9
# backend/crm_backend/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
...
# Local apps
'customers',

'line_bot', # 新增 LINE Bot app
]

設定 ALLOWED_HOSTS

1
2
# backend/crm_backend/settings.py
ALLOWED_HOSTS = ['yourdomain.com', 'localhost', '127.0.0.1']

建立 apps.py

1
2
3
4
5
6
# backend/line_bot/apps.py
from django.apps import AppConfig

class LineBotConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'line_bot'

Webhook 串接測試

views

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# backend/line_bot/views.py
...

# 載入專案根目錄的 .env 檔案
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
ENV_FILE = PROJECT_ROOT / '.env'
load_dotenv(ENV_FILE)

from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError, LineBotApiError
from linebot.models import MessageEvent, TextMessage, TextSendMessage

# 設置日誌
logger = logging.getLogger(__name__)

# LINE Bot 設定 - 從環境變數讀取
LINE_CHANNEL_SECRET = os.getenv('LINE_CHANNEL_SECRET')
LINE_CHANNEL_ACCESS_TOKEN = os.getenv('LINE_CHANNEL_ACCESS_TOKEN')

# 驗證環境變數是否存在
if not LINE_CHANNEL_SECRET or not LINE_CHANNEL_ACCESS_TOKEN:
logger.error("LINE Bot 環境變數未設置!請檢查 .env 檔案")
raise ValueError("LINE Bot 環境變數未設置")

line_bot_api = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(LINE_CHANNEL_SECRET)


@csrf_exempt
@require_POST
def webhook(request):
"""LINE Bot Webhook 處理器"""

# 獲取請求內容
body = request.body.decode('utf-8')
signature = request.META.get('HTTP_X_LINE_SIGNATURE', '')

# 記錄接收到的請求
logger.info(f"收到 LINE Webhook 請求: {body}")
logger.info(f"Signature: {signature}")

try:
# 驗證簽名並處理事件
handler.handle(body, signature)
except InvalidSignatureError:
logger.error("無效的簽名")
return HttpResponseBadRequest("Invalid signature")
except Exception as e:
logger.error(f"處理 Webhook 時發生錯誤: {str(e)}")
return HttpResponseBadRequest(f"Error: {str(e)}")

return HttpResponse("OK")


@handler.add(MessageEvent, message=TextMessage)
def handle_text_message(event):
"""處理文字訊息"""
user_id = event.source.user_id
user_message = event.message.text

# 記錄收到的訊息
logger.info(f"收到使用者 {user_id} 的訊息: {user_message}")
# 簡單的回應邏輯
reply_message = f"您好!我收到了您的訊息:「{user_message}」"

try:
# 回覆訊息
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=reply_message)
)
logger.info(f"成功回覆訊息給使用者 {user_id}")

except LineBotApiError as e:
logger.error(f"回覆訊息時發生錯誤: {e.message}")


def test_connection(request):
"""測試連接的簡單端點"""
return HttpResponse("LINE Bot 服務運行中!")

LINE_CHANNEL_SECRET 跟 LINE_CHANNEL_ACCESS_TOKEN 可直接在 LINE Developers Console 的 Basic settings 跟 Messaging API 頁面找到

token

url 配置

1
2
3
4
5
6
7
8
9
10
# backend/line_bot/urls.py
from django.urls import path
from . import views

app_name = 'line_bot'

urlpatterns = [
path('webhook/', views.webhook, name='webhook'), # LINE Bot Webhook 處理器
path('test/', views.test_connection, name='test'), # 最基本的連接測試
]

更新專案主 urls 配置

1
2
3
4
5
6
7
8
9
10
# backend/crm_backend/urls.py

...

urlpatterns = [
path('admin/', admin.site.urls),
...
path('api/line-bot/', include('line_bot.urls')), # 新增 LINE Bot 路由
]

接下來可以直接去 Terminal 測試以下 API,若成功的話,應會在 Terminal 中看到:「LINE Bot 服務運行中!」 的回應

1
2
# 測試基本連接
curl https://yourdomain.com/api/line-bot/test/

基本的測試過了,接下來就可以測帶有 body 跟 signature 的 Webhook 處理器測試,最後部署至正式環境再用真實的 webhook url 測試,基本上正式的過了,就可以直接到 LINE 去傳訊息看看是否有成功回覆 handle_text_message 的 reply_message:

成功畫面:

reply_success

講解一下 執行流程

  1. 當我們在 LINE 上傳送訊息時, LINE 平台會發送 HTTP POST 到 webhook URL
  2. Django urls.py 會將請求路由到 webhook 函數
  3. webhook() 驗證簽名(確保來自 LINE)後,呼叫 handler.handle(),將請求交給 handler.handle() 處理
  4. handler 解析事件,發現是 TextMessage
  5. 自動調用 handle_text_message() 函數
  6. handle_text_message() 生成回應並透過 LINE API 回覆

常見問題

1. 301 Moved Permanently 錯誤

問題: HTTP 請求被重定向到 HTTPS
解決: 確保使用 HTTPS URL 進行所有請求

2. Invalid Signature 錯誤

問題: Channel Secret 不正確或環境變數未正確載入
解決:

  • 檢查 .env 檔案路徑
  • 確認 Channel Secret 正確

3. LINE Bot 無回應

問題: Webhook 設定錯誤或程式碼異常
解決:

  • 檢查 Django logs
  • 確認 Webhook URL 正確
  • 測試 /api/line-bot/test/ 端點

4. CSRF 錯誤

問題: Django CSRF 保護阻擋 LINE Webhook
解決: 使用 @csrf_exempt 裝飾器(已包含在範例中)


若您覺得這篇文章對您有幫助,歡迎分享出去讓更多人看到⊂◉‿◉つ~


留言版