# 如何不使用 SDK 直接呼叫 LINE Messaging API (以 Python 為例)
本文件旨在說明如何不依賴任何官方 SDK,直接透過 HTTP 請求與 LINE Messaging API 進行互動。這對於理解 API 底層運作、在不支援 SDK 的環境中開發,或是進行簡單的腳本整合非常有幫助。
我們將以 Python 的 `requests` 函式庫為例,示範如何傳送一個最基本的文字訊息。
---
## 1. 前置準備
在開始之前,請確保你已經擁有:
1. **一個 LINE Developers 帳號**:如果沒有,請至 [LINE Developers Console](https://developers.line.biz/console/) 註冊。
2. **一個 Messaging API 的 Channel**:在 Console 中建立一個提供者 (Provider),然後在該提供者下建立一個 Messaging API 的 Channel。
3. **Channel Access Token (長期)**:這是呼叫 API 所需的憑證。你可以在 Channel 的 "Messaging API" 分頁中找到並發行它。
4. **你的 User ID**:為了測試 **Push Message**,你需要一個目標對象的 User ID。最簡單的方式是將你的機器人帳號加為好友,然後傳送任何訊息給它。接著,你需要設定 Webhook 來接收這個訊息事件,從中取得你的 User ID。
---
## 2. 核心概念:Push Message
「主動傳送訊息」(Push Message) 是指由機器人主動發送訊息給用戶,不需要用戶先有互動。
* **HTTP 方法**:`POST`
* **API 端點 (Endpoint)**:`https://api.line.me/v2/bot/message/push`
* **HTTP Headers**:
* `Content-Type`: `application/json`
* `Authorization`: `Bearer {你的 Channel Access Token}`
* **Request Body (Payload)**:一個 JSON 物件,用來描述訊息的接收者 (`to`) 和內容 (`messages`)。
---
## 3. 步驟詳解:傳送 Push Message
### 3.1 準備必要資訊
* `YOUR_CHANNEL_ACCESS_TOKEN`: 從你的 LINE Developers Console 複製。
* `YOUR_USER_ID`: 你想要傳送訊息對象的 User ID。
### 3.2 撰寫 Python 程式碼
**Body (Payload) 的結構:**
```json
{
"to": "YOUR_USER_ID",
"messages": [
{
"type": "text",
"text": "Hello, world!"
}
]
}
```
---
## 4. 完整 Python 範例 (Push Message)
```python
import requests
import json
ACCESS_TOKEN = 'YOUR_CHANNEL_ACCESS_TOKEN'
USER_ID = 'YOUR_USER_ID'
PUSH_API_URL = 'https://api.line.me/v2/bot/message/push'
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {ACCESS_TOKEN}'
}
payload = {
'to': USER_ID,
'messages': [{'type': 'text','text': '這是一則來自 Python 的 Push Message!'}]
}
try:
response = requests.post(PUSH_API_URL, headers=headers, data=json.dumps(payload))
response.raise_for_status()
print('Push Message 傳送成功!')
except requests.exceptions.RequestException as e:
print('Push Message 傳送失敗:', e)
```
---
## 5. 如何執行
1. **安裝 `requests`**:`pip install requests`
2. **儲存檔案**:將範例程式碼儲存為 `.py` 檔案。
3. **替換變數**:填入你的 `ACCESS_TOKEN` 和 `USER_ID`。
4. **執行腳本**:`python <your_script_name>.py`
---
## 6. 如何回覆訊息 (Reply Message)
「回覆訊息」(Reply Message) 是針對用戶傳來的特定訊息進行回應。這與可以隨時傳送的 Push Message 不同。
**核心差異:**
* **API 端點**:`https://api.line.me/v2/bot/message/reply`
* **認證方式**:使用 `replyToken` 而不是 `to`。
* `replyToken`:當用戶傳送訊息到你的聊天機器人時,LINE 會透過 Webhook 事件傳送一個 `replyToken` 給你。這個 Token 是 **一次性** 且有 **時效性** 的,只能用來回覆該則訊息一次。
**Body (Payload) 的結構:**
```json
{
"replyToken": "從 Webhook 取得的 Reply Token",
"messages": [
{
"type": "text",
"text": "感謝您的訊息!"
}
]
}
```
**範例程式碼 (概念)**
你無法直接執行此腳本,因為 `replyToken` 必須從真實的 Webhook 事件中動態取得。這段程式碼展示了在一個 Web 框架 (如 Flask 或 FastAPI) 中處理回覆的邏輯。
```python
# (這是一個概念性範例,假設在一個 Web 伺服器環境中)
# 假設你從 LINE Webhook 收到了這樣的 JSON body
webhook_event = {
"events": [
{
"type": "message",
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA", # 範例 Token
"message": {
"type": "text",
"id": "14320195349999",
"text": "你好"
}
}
]
}
# 取得 replyToken
reply_token = webhook_event['events'][0]['replyToken']
# --- 準備回覆請求 ---
REPLY_API_URL = 'https://api.line.me/v2/bot/message/reply'
ACCESS_TOKEN = 'YOUR_CHANNEL_ACCESS_TOKEN'
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {ACCESS_TOKEN}'
}
payload = {
'replyToken': reply_token,
'messages': [{'type': 'text', 'text': '這是一則 Reply Message!'}]
}
# --- 發送回覆 ---
try:
response = requests.post(REPLY_API_URL, headers=headers, data=json.dumps(payload))
response.raise_for_status()
print('Reply Message 傳送成功!')
except requests.exceptions.RequestException as e:
print('Reply Message 傳送失敗:', e)
```
---
## 7. 如何引用訊息 (Quote Message)
引用訊息是 Reply Message 的一項附加功能,可以讓用戶清楚地看到你的回覆是針對哪一則訊息。
要使用此功能,你需要在回覆的 `messages` 物件中,加上 `quoteToken` 欄位。
* `quoteToken`:與 `replyToken` 一樣,`quoteToken` 也來自於 Webhook 事件中的 `message` 物件。它代表了用戶傳來的那則訊息的引用標識。
**Body (Payload) 結構 (帶有引用):**
```json
{
"replyToken": "從 Webhook 取得的 Reply Token",
"messages": [
{
"type": "text",
"text": "這是對你那句話的回覆。",
"quoteToken": "從 Webhook 取得的 Quote Token"
}
]
}
```
**範例程式碼 (概念)**
```python
# (接續上一個 Webhook 範例)
# 從 Webhook 事件中同時取得 replyToken 和 quoteToken
webhook_event = webhook_event['events'][0]
reply_token = webhook_event['replyToken']
quote_token = webhook_event['message']['quoteToken'] # quoteToken 在 message 物件內
# --- 準備帶有引用的回覆請求 ---
payload = {
'replyToken': reply_token,
'messages': [
{
'type': 'text',
'text': '我正在引用你的訊息來回覆!',
'quoteToken': quote_token
}
]
}
# --- 發送回覆 ---
try:
response = requests.post(REPLY_API_URL, headers=headers, data=json.dumps(payload))
response.raise_for_status()
print('帶引用的 Reply Message 傳送成功!')
except requests.exceptions.RequestException as e:
print('Reply Message 傳送失敗:', e)
```
---
## 8. 進階:傳送不同類型的訊息
不論是 Push 還是 Reply Message,你都可以傳送文字以外的訊息類型,只需修改 `messages` 陣列的內容即可。
**範例:傳送貼圖**
```python
{
"type": "sticker",
"packageId": "11537",
"stickerId": "52002734"
}
```
> **提示**:你可以在 [貼圖列表文件](https://developers.line.biz/en/docs/messaging-api/sticker-list/) 中找到可用的 `packageId` 和 `stickerId`。
---
## 9. 關於接收 Webhook 事件
本文件中的 Reply Message 和 Quote Message 都強烈依賴 Webhook 來取得必要的 `replyToken` 和 `quoteToken`。
簡單來說,你需要:
1. 準備一個公開的 HTTPS 伺服器端點 (URL)。
2. 在 LINE Developers Console 中設定你的 Webhook URL。
3. 當有事件發生時,LINE 平台會對你的 URL 發送一個 `POST` 請求。
4. 你的伺服器需要解析這個請求的 JSON 內容,並 **驗證簽名 (Signature)** 以確保請求來自 LINE。簽名驗證需要使用你的 **Channel Secret**。
手動處理 Webhook(特別是簽名驗證)比傳送訊息要複雜得多,這也是官方 SDK 主要的價值所在。
---
## 10. 重要注意事項:傳送圖片訊息中的 URL 有中文字時
當你嘗試透過 LINE Messaging API 傳送圖片訊息的 URL時,請務必對該 URL 進行 **URL 編碼 (URL Encoding)**。如果未經編碼且URL裡有中文子時,LINE 平台可能無法正確解析該 URL,導致訊息無法成功傳送或顯示異常。
這在傳送可點擊的連結或指定資源位置時尤其重要。大多數程式語言都內建了 URL 編碼的工具函式。
### 圖片訊息中的 URL 編碼
當你在傳送**圖片訊息 (Image Message)** 時,其 `originalContentUrl` 和 `previewImageUrl` 也必須是經過編碼的有效 URL。
**Body (Payload) 的結構:**
```json
{
"type": "image",
"originalContentUrl": "編碼後的圖片 URL",
"previewImageUrl": "編碼後的預覽圖片 URL"
}
```
**範例程式碼 (概念)**
```python
from urllib.parse import quote
# 原始的圖片 URL
raw_image_url = "https://example.com/images/my cat photo.jpg"
raw_preview_url = "https://example.com/images/preview/my cat photo.jpg"
# 對 URL 進行編碼
encoded_image_url = quote(raw_image_url, safe='/:')
encoded_preview_url = quote(raw_preview_url, safe='/:')
# --- 準備圖片訊息的 payload ---
payload = {
'to': USER_ID,
'messages': [
{
"type": "image",
"originalContentUrl": encoded_image_url,
"previewImageUrl": encoded_preview_url
}
]
}
# --- 發送請求 ---
# response = requests.post(PUSH_API_URL, headers=headers, data=json.dumps(payload))
```
**重點**:
* `quote` 函式會將特殊字元 (如空格、`?`, `=`, `&`) 轉換為 `%` 開頭的格式。
* `safe='/:,'` 參數可以避免對 URL 的協定 (`https://`) 和路徑分隔符 (`/`) 等本身合法的字元進行編碼。
* 若不進行編碼,像 URL 中的**空格**或特殊查詢參數,可能會被 LINE 的伺服器誤判,導致 URL 無法存取、圖片載入失敗,最終使您的 API 請求失敗。
---
## 11. 總結
**直接呼叫 API 的優點:**
* **輕量**:不需要安裝整個 SDK,只依賴基本的 HTTP 客戶端。
* **彈性**:可以在任何支援 HTTP 請求的語言或環境中使用。
* **透明**:能清楚了解 API 的底層運作方式。
**直接呼叫 API 的缺點:**
* **繁瑣**:需要手動組合 JSON、設定 Headers。
* **錯誤處理**:需要自行處理 HTTP 錯誤、API 回應的錯誤碼等。
* **Webhook 複雜**:手動實作 Webhook 的簽名驗證相對複雜且容易出錯。
對於僅需傳送簡單通知的腳本,直接呼叫 API 是一個非常好的選擇。但若要開發功能完整的聊天機器人,使用官方 SDK 通常會更有效率且穩健。