# 如何不使用 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 通常會更有效率且穩健。