前置準備

當然就是去 Line Developers 申請一個 Messaging API,申請完成後,會得到 Channel secret (在 Basic Setting 頁面) 跟 Channel access token (long-lived) (在 Messaging API 頁面最下方). 然後在 Webhook settings 輸入回應的網址,例如:https://6eba8e52d2c7.ngrok.io/api/linebot,若是 localhost 測試,參考 讓你的 localhost 也有實際的 domain 對外使用,注意要用 https 才可以。

安裝SDK

#官方提供的SDK
composer require linecorp/line-bot-sdk

安裝 SDK 的時候會報錯,說 PHP 未支援 socket 功能,XAMPP 預設是關閉著,請修改 php.ini 將 extension=sockets 的 ; 號註解移除,並重新啟動 Apache。

建立一個回應的 API Route

這邊我是放在 api.php 這邊,這樣可以不用在 VerifyCsrfToken.php 設定排除

//LineBot Hooks
Route::post('/linebot', 'API\LineBotController@hooks');

建立 API controller

php artisan make:controller API/LineBotController --api

寫一個簡單的 200 回應,測試是否正常連線

public function hooks(Request $request)
{
    //直接回應200測試
    retrun response('測試', 200);
}

回到 Line Developers 的 Messaging API 頁面按 Verify 按鈕測試看是否有正常連線。

LineBotController

<?php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use LINE\LINEBot;
use LINE\LINEBot\Constant\HTTPHeader;
use LINE\LINEBot\SignatureValidator;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot\MessageBuilder\TextMessageBuilder;
use Exception;

class LineBotController extends Controller
{
    public function hooks(Request $request)
    {
        $lineAccessToken = env('LINE_CHANNEL_ACCESS_TOKEN'); //前面申請到的Channel acess token(long-lived)
        $lineChannelSecret = env('LINE_CHANNEL_SECRET');//前面申請到的Channel secret
        $httpClient = new CurlHTTPClient ($lineAccessToken);
        $lineBot = new LINEBot($httpClient, ['channelSecret' => $lineChannelSecret]);

        //驗證 signature
        $signature = $request->headers->get(HTTPHeader::LINE_SIGNATURE);
        if (!SignatureValidator::validateSignature($request->getContent(), $lineChannelSecret, $signature)) {
            return;
        }

        try {
            //將request內容取出
            $events = $lineBot->parseEventRequest($request->getContent(), $signature);
            foreach ($events as $event) {
                $replyToken = $event->getReplyToken(); //返回的Token
                $text = $event->getText();// 得到使用者輸入
                $lineBot->replyText($replyToken, $text);// 回復使用者輸入
                //$textMessage = new TextMessageBuilder("你好");
                //$lineBot->replyMessage($replyToken, $textMessage);
            }
        } catch (Exception $e) {
            return;
        }
        return;
    }
}

這樣就是一個簡單的複製回話的機器人,剩下的應用就自由發揮囉。機器人可以依據使用者的輸入回復文字、貼圖或圖片。

//接收到的 header
{
    "user-agent":["LineBotWebhook\/1.0"],
    "accept":["*\/*"],
    "content-type":["application\/json; charset=utf-8"],
    "x-line-signature":["Q\/MAgholdGBSSDdMycs4eWCjcsRQ1RipY4k2C1AC\/\/E="],
    "content-length":["305"],
    "connection":["close"],
    "host":["codinglab.rvt.idv.tw"],
    "x-forwarded-port":["443"],
    "x-forwarded-proto":["https"],
    "x-real-ip":["124.155.171.242"],
    "x-forwarded-by":["192.168.0.10"],
    "x-correlation-id":["2baa6d40-24f2-467c-97fb-7b228ff1ad7f"]
}


//接收到的 request
{
    "events":[{
        "type":"message",
        "replyToken":"949d624908f840ba880716bc567edca9",
        "source":{
            "userId":"U11c6e8b9d679ff492c27d67357901b89",
            "type":"user"
        },
        "timestamp":1604667396352,
        "mode":"active",
        "message":{
            "type":"text",
            "id":"12984614151808",
            "text":"\u6e2c\u8a66"
        }
    }],
    "destination":"Uc815befefc4f61b0a16451f087a019bf"
}
最後修改日期: 2020 年 11 月 6 日