PHP Line Bot 開發入門:Webhook 設定與訊息回應機制完整說明

Published on: | Last updated:

今天要來聊聊 PHP Line Bot 開發…的核心

最近好像又蠻多人想玩玩看 LINE Bot,說真的,這東西的應用範圍超廣,從簡單的客服、訊息推播,到串接一堆奇奇怪怪的 AI 或資料庫,都能辦到。我自己是覺得,學會這個,等於幫你的服務開了一扇直接跟使用者對話的窗,蠻酷的。

不過,很多人,尤其是 PHP 的初學者,常常卡在第一關:那個叫做 Webhook 的東西到底是什麼鬼?為什麼我本機電腦跑得好好的,上傳到伺服器,LINE 後台一按 Verify 就沒反應?今天就來從頭到尾,用白話文把這整件事講清楚。這篇算是我的筆記兼草稿,可能有點亂,但保證都是實戰經驗。

先說結論,TL;DR

簡單講,開發一個最基本的 LINE 回應機器人,你只需要做三件事:

  1. 寫一支 PHP 程式,這支程式的任務是接收 LINE 伺服器丟過來的資料、然後決定要回什麼訊息。
  2. 把這支 PHP 程式,放到一台「全世界都連得到」的網路主機上,取得一個公開的網址(URL)。
  3. 把這個網址,貼到你的 LINE Developers 後台的「Webhook URL」欄位裡。

對,就這樣。整個核心概念就是這麼單純。但問題是,LINE 為了確保通訊是安全、可信的,所以在這個簡單的流程中加了一些驗證機制。這些「魔鬼細節」就是我們接下來要一個個拆解的部分。

到底什麼是 Webhook?用大白話解釋

我最喜歡用一個比喻:Webhook 就像是你點外送時,提供給外送平台的「你家地址」。

想像一下,LINE 的伺服器是外送平台的美食廣場,而你的 PHP 程式就是你家。當有使用者傳訊息給你的 LINE 官方帳號時,就等於有人在美食廣場下了一張訂單。LINE(外送平台)把這張訂單(使用者訊息)準備好之後,就會主動送到你提供給它的地址(你的 Webhook URL)。

你的 PHP 程式(你本人在家)收到外送員(LINE 的請求)後,打開餐點(解析資料),看看使用者點了什麼(傳了什麼訊息),然後你可能做點處理,最後跟外送員說「謝啦!」(回應一個 HTTP 200 OK 狀態碼),甚至準備一份回禮(要回傳的訊息)請他帶回去給客人。

關鍵在於「主動」。傳統的 API 是你(你的程式)要去問伺服器:「欸,有新東西嗎?」「欸,有新東西嗎?」,這叫輪詢 (Polling)。而 Webhook 是伺服器在有事件發生時,「主動」來敲你家的門。這樣效率高多了,也即時多了。

Webhook 運作流程示意圖
Webhook 運作流程示意圖

開發前的準備:帳號、環境、還有錢?

在開始寫程式碼之前,有些東西要先準備好。就像做菜一樣,先把食材跟廚具備齊。

  • LINE Developers 帳號:這個是廢話,但還是要講。你要先到 LINE Developers 網站,建立一個 Provider,然後再建立一個 Channel。選「Messaging API」類型的 Channel。建立完成後,你會進到一個後台,裡面有兩串非常重要的東西:Channel access token (long-lived)Channel secret。這兩串東西就是你程式的鑰匙,絕對不要外洩。
  • 可以跑 PHP 的主機:這就是最多人卡關的地方。再次強調,你不能用你電腦上的 XAMPP 或 MAMP 直接跑,因為 LINE 的伺服器找不到你。你需要一個公開的網址。有幾種選擇:
    • 正式主機(要花錢):租一台最便宜的雲端主機,比如 DigitalOcean, Linode, Vultr,或是直接用 AWS/GCP。一個月可能幾塊美金,你會有一個固定的 IP,可以綁定網域,最穩定。
    • 免費或測試用方案(通常有坑):有些虛擬主機商提供免費方案,但通常限制很多,或是有廣告。另一個超讚的選擇是 `ngrok`,它可以暫時把你的本機電腦變成一個公開伺服器,非常適合開發與除錯,我後面會專門講它。
    • Serverless 服務:像是 Heroku, Google Cloud Functions, AWS Lambda 等。這種更進階一點,但好處是你不用管理主機,不過設定上對新手來說門檻比較高。
  • PHP 環境與 Composer:你的主機上當然要有 PHP。版本我建議至少 7.4 以上,最好是 8.x。然後,拜託,拜託一定要用 Composer。Composer 是 PHP 的套件管理工具。LINE 官方已經把所有跟 LINE API 溝通的複雜工作,都打包成一個 SDK(軟體開發套件)了。我們只要用 Composer 一行指令 `composer require line/line-bot-sdk` 就能安裝,之後寫程式會輕鬆一百倍。千萬別想不開去自己手刻 HTTP 請求和簽章驗證,那根本是自虐。
  • SSL 憑證 (HTTPS):LINE 強制規定你的 Webhook URL 必須是 HTTPS 開頭。如果你是租用雲端主機自己架,記得要去申請免費的 Let's Encrypt 憑證。如果你用 ngrok 或是一些平台服務,它們通常會直接提供 HTTPS 網址。

實作指引:我的第一個 PHP 回應機器人

好,假設你都準備好了。現在我們來寫程式。我們的目標很簡單:使用者傳什麼文字訊息給我們,我們就在前面加上「你說了:」,然後回傳給他。

首先,在你的專案資料夾,用 Composer 安裝 LINE Bot SDK:


composer require line/line-bot-sdk

然後,建立一個 PHP 檔案,比如叫做 `bot.php`。把下面的程式碼完整貼進去。


<?php
// 引入 Composer 的自動載入檔案
require_once __DIR__ . '/vendor/autoload.php';

// 從 LINE Developers 後台取得的 Channel Secret 和 Channel Access Token
$channelSecret = 'YOUR_CHANNEL_SECRET'; // 請替換成你的 Channel Secret
$channelAccessToken = 'YOUR_CHANNEL_ACCESS_TOKEN'; // 請替換成你的 Channel Access Token

// --- 基本設定完成,底下是主要邏輯 ---

// 建立一個 cURL HTTP 客戶端,負責發送請求
$httpClient = new \LINE\LINEBot\HTTPClient\CurlHTTPClient($channelAccessToken);
// 建立 LINE Bot 實例
$bot = new \LINE\LINEBot($httpClient, ['channelSecret' => $channelSecret]);

// 從請求中取得簽章和內容
$signature = $_SERVER['HTTP_X_LINE_SIGNATURE'];
$body = file_get_contents('php://input');

// 監聽 Webhook 事件
try {
    // 解析請求,同時會自動驗證簽章
    $events = $bot->parseEventRequest($body, $signature);
} catch(\LINE\LINEBot\Exception\InvalidSignatureException $e) {
    // 簽章驗證失敗
    error_log("Invalid signature");
    http_response_code(400);
    exit();
} catch(\LINE\LINEBot\Exception\InvalidEventRequestException $e) {
    // 事件請求格式錯誤
    error_log("Invalid event request");
    http_response_code(400);
    exit();
}

// 遍歷所有事件
foreach ($events as $event) {
    // 只處理文字訊息事件
    if ($event instanceof \LINE\LINEBot\Event\MessageEvent\TextMessageEvent) {
        // 取得使用者傳來的文字
        $userMessage = $event->getText();
        
        // 準備要回覆的訊息
        $replyMessage = '你說了:' . $userMessage;
        
        // 取得回覆令牌 (Reply Token)
        $replyToken = $event->getReplyToken();
        
        // 使用 replyText 方法回覆訊息
        try {
            $response = $bot->replyText($replyToken, $replyMessage);
            if (!$response->isSucceeded()) {
                error_log('Messages failed to send: ' . $response->getRawBody());
            }
        } catch (Exception $e) {
            error_log('Exception while sending message: ' . $e->getMessage());
        }
    }
}

// 告訴 LINE 伺服器,你已經成功處理了
echo "OK";
http_response_code(200);

把上面程式碼中的 `YOUR_CHANNEL_SECRET` 和 `YOUR_CHANNEL_ACCESS_TOKEN` 換成你自己的。然後把這個檔案上傳到你的主機。假設你的網域是 `example.com`,檔案放在根目錄,那你的 Webhook URL 就是 `https://example.com/bot.php`。把這個 URL 貼到 LINE Developers 後台的 Webhook URL 欄位,按下「Update」,然後再按一下旁邊的「Verify」。如果看到 Success,恭喜你,第一步成功了!

LINE Developers 後台的 Webhook 設定區
LINE Developers 後台的 Webhook 設定區

程式碼到底在幹嘛?一行一行拆解

上面的程式碼看起來好像有點長,但其實結構很清晰。我們來拆解一下:

  1. 引入與設定:一開始就是引入 Composer 的 `autoload.php`,這樣我們才能使用 SDK 裡的類別。然後設定好我們的金鑰。
  2. 建立 Bot 實例:`$httpClient` 和 `$bot` 這兩行,就是用 SDK 建立一個機器人物件。你可以把它想像成召喚出一個能幫你跟 LINE 溝通的僕人,並且把金鑰交給他。
  3. 接收與驗證(最關鍵):`$_SERVER['HTTP_X_LINE_SIGNATURE']` 是在讀取 LINE 請求裡的一個特殊 HTTP 標頭,裡面包含了簽章。`file_get_contents('php://input')` 則是讀取請求的「本體 (Body)」,也就是 LINE 傳來的主要資料,格式是 JSON。
  4. `$bot->parseEventRequest(...)`:這是整個程式的心臟。SDK 的這個方法會幫我們做兩件大事:第一,用你的 Channel Secret 和請求的 Body,去計算出一個簽章,然後跟 LINE 送來的 `X-Line-Signature` 比對,確保請求真的是 LINE 發的,而不是被偽造的。第二,如果簽章正確,它會把那一大坨 JSON 字串,解析成一個個 PHP 物件,方便我們後續處理。我把它放在 `try...catch` 裡面,是因為如果驗證失敗,SDK 會拋出例外 (Exception),我們需要捕捉它並記錄錯誤,然後結束程式。
  5. 事件迴圈:LINE 一次請求可能會包含多個事件(例如使用者在群組裡發言,機器人同時收到加入群組事件和訊息事件)。所以我們用 `foreach` 來一個個處理。
  6. 判斷事件類型:`if ($event instanceof \LINE\LINEBot\Event\MessageEvent\TextMessageEvent)` 這一行很重要。LINE 會傳來各種事件,像是使用者加你好友 (`FollowEvent`)、貼了貼圖 (`StickerMessageEvent`) 等等。我們這裡用 `instanceof` 來判斷「這個事件是不是一個文字訊息事件?」,是的話才處理。
  7. 取得訊息與回覆:`$event->getText()` 可以拿到使用者傳的文字內容。`$event->getReplyToken()` 則是拿到一個「回覆權杖」。這個權杖很重要,它是我們回覆該則訊息的唯一憑證,而且只能用一次,用過就失效。最後,`$bot->replyText($replyToken, $replyMessage)` 就是把我們的回覆內容,連同這個權杖,交給 SDK 去送出。
  8. 回應 200 OK:最後的 `http_response_code(200);` 是在告訴 LINE 伺服器:「我收到你的請求了,而且也成功處理完畢了。」這個步驟一定要做,不然 LINE 會覺得你的 Webhook 有問題,然後一直重試,最後把它停用。

SDK vs. 手刻,到底差在哪?

我一直強調要用 SDK,有些人可能不信邪。我們來做個簡單的比較,你就會知道為什麼了。這不是嚴謹的學術分析,比較像是我個人的心得分享啦。

特性 使用 LINE Bot SDK 從零開始手刻 (Bare Metal)
開發速度 真的很快。你下載完,大概半小時內就能做出第一個 echo bot。心思可以完全放在你的應用邏輯上。 光是研究 LINE 的 API 文件、搞懂簽章演算法、用 cURL 發送正確的 HTTP 標頭,可能就要花掉半天甚至一天。
程式碼複雜度 超低。你看我們上面的範例,核心邏輯就那幾行。SDK 把髒活都做完了。 極高。你需要自己用 `hash_hmac('sha256', $body, $channelSecret, true)` 算簽章,然後 `base64_encode`,再跟傳來的比對。回覆訊息時要自己組 JSON,還要設定 `Authorization: Bearer {TOKEN}` 標頭。超麻煩。
可靠性與維護 相對高。官方會跟著 API 的改動去更新 SDK,有 bug 也會修。你只要 `composer update` 就好。 完全看你自己的功力。哪天 LINE API 小改版,你的程式可能就掛了,你還得自己花時間 debug。
學習曲線 平緩。你只需要學會怎麼呼叫 SDK 提供的方法就行了。 陡峭。你需要對 HTTP 協定、RESTful API、JSON 格式、HMAC 加密演算法都有一定的了解。
我的碎碎念 沒什麼好說的,就用吧。把時間花在更有價值的地方。 除非你是想深入了解底層原理,或是參加什麼鐵人賽想挑戰自我,不然真的...放過自己吧。

本地開發與除錯救星:ngrok

好了,理論跟實作都講了,現在來講實戰中最有用的工具:`ngrok`。

前面提過,你的程式需要一個公開網址,但開發過程中,你總不可能改一行程式碼,就用 FTP 上傳一次到主機吧?效率太低了。`ngrok` 就是為了解決這個問題而生的。

它是一個小程式,可以在你的 Windows、Mac 或 Linux 電腦上執行。它的作用是在你的電腦和 ngrok 的雲端伺服器之間,建立一個安全的通道。然後,它會給你一個公開的、隨機的 `https://` 網址。所有送到這個公開網址的請求,都會被安全地轉發到你本機電腦指定的某個連接埠(port)。

使用方法超簡單:

  1. 去 ngrok 官網下載對應你作業系統的程式。
  2. 解壓縮後,打開終端機 (Terminal) 或命令提示字元 (cmd)。
  3. 假設你用 XAMPP,你的本地網站跑在 80 port。你就輸入指令:`./ngrok http 80`
  4. 執行後,畫面上就會出現一個 `Forwarding` 的網址,長得像 `https://random-string.ngrok.io`。

這個 `https://random-string.ngrok.io` 就是你現在的公開網址了!把這個網址後面加上你的 PHP 檔名(例如 `https://random-string.ngrok.io/linebot/bot.php`),貼到 LINE Developers 後台的 Webhook URL,你就可以直接在你自己的電腦上修改程式、存檔,然後用手機傳訊息給 LINE Bot,馬上看到結果。超方便!

更有用的是,`ngrok` 的終端機畫面會即時顯示所有通過它的 HTTP 請求,包括標頭和內容。如果你的 Webhook 沒反應,你可以直接看到 LINE 到底有沒有送請求過來、送了什麼內容、你的程式回應了什麼狀態碼 (是 200 還是 500 Internal Server Error),一目了然,是除錯神器。

對了,這邊也要提一下官方文件跟我們實際開發的差異。LINE 官方的英文文件會把 Webhook 驗證失敗的原因條列得非常清楚,像是 `The request body does not match the signature.`。但在我們開發者社群,尤其是在台灣的論壇或臉書社團,你通常只會看到大家哀嚎「簽章驗不過」、「收不到東西」、「一片空白」。 這就是理論與實務的差距,官方文件給你標準答案,但社群的經驗分享才告訴你實際會踩到哪些坑,像是檔案權限、PHP 錯誤日誌沒開等等。所以,官方文件要看,社群的討論也要多爬。

ngrok 執行中的終端機畫面
ngrok 執行中的終端機畫面

常見的坑與修正

最後,整理幾個我剛開始玩的時候踩過,也看過很多人問的坑:

  • Verify 按下去沒反應或失敗:LINE 後台的 Verify 按鈕,它送過來的請求是「不包含任何事件」的。所以你的 `foreach ($events as $event)` 迴圈根本不會執行。如果你的程式邏輯沒寫好,可能會因為 `$events` 是空的而報錯。確保你的程式在沒有任何事件時,也能正常地回應一個 HTTP 200。我上面的範例程式碼在結尾處有處理這點。
  • Channel Access Token 填錯:LINE Developers 後台有兩種 Access Token,一種是短期的,一種是長期的 (long-lived)。請務必是點「issue」按鈕產生那一個長期的。
  • PHP 錯誤訊息被關閉:在正式的伺服器環境,`display_errors` 通常是預設關閉的,這是好的安全實踐。但你在開發時,這會讓你很痛苦,因為程式出錯了你只會看到一片空白或 500 錯誤。請學會去看伺服器的 `error_log` 檔案,所有的 PHP 錯誤訊息都會記錄在那裡。
  • 檔案權限問題:如果你有寫入 log 檔的程式碼,或是 Composer 的 `vendor` 資料夾權限不對,都可能導致 Web Server (Apache/Nginx) 無法讀取或寫入檔案,進而產生 500 錯誤。

差不多就是這樣了。LINE Bot 的開發入門,最難的真的就是 Webhook 這第一哩路。一旦你打通了這關,後面就是海闊天空,可以開始玩各種有趣的應用了。希望這篇有點雜亂的草稿對你有幫助。

看完這篇,你第一個想做的 LINE Bot 是什麼功能?是做個記帳機器人、天氣預報、還是串接 ChatGPT 來聊天?在下面留言分享你的點子吧!

Related to this topic:

Comments

  1. Guest 2025-07-19 Reply
    咦,為啥一定要用 PHP 弄 LINE Bot 啊?聽起來好像有點複雜耶。難道沒有更簡單的方法嗎?我對程式不太在行,想知道新手真的能快速上手嗎?
  2. Guest 2025-05-23 Reply
    欸學長,這篇 LINE Bot 教學看起來有點單調耶!能不能分享一下實際開發的血淚史?我對 PHP 這塊還滿好奇的,不知道有沒有更深入的實戰經驗可以交流?
撥打專線 LINE免費通話