今天想使用之前串接的 LINE 機器人來賣eSIM 發現不會動了,原來是改版了
https://github.com/line/line-bot-sdk-php
首先,這是官方的 github ,有大部分的教學文件
接下來發現 NAS 似乎無法使用建議的安裝方式
composer require linecorp/line-bot-sdk
而且目前該API 需要 php 8.1 以上的版本
Requirements
PHP 8.1 or later
這邊使用macbook 來先下指令
mkdir line
cd line
vi composer.json
內容填入
{
"require": {
"linecorp/line-bot-sdk": "^11.0",
"line/openapi": "^1.0"
}
}
來指定版本(這應該是非必要的)
composer require linecorp/line-bot-sdk
之後將會在line 資料夾內得到一個vendor的資料夾

到此最麻煩的一步已經處理完畢。
接下來到NAS 上安裝php 8.1 以上的版本,並指定到webhook 的服務上即可。
這是簡單的lineHook.php,可以直接拿來串接,autoload.php 會幫忙處理幾乎所有串接的東西,下方use 的部分需要根據需求自行加上
<?php
require_once __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Client;
use LINE\Clients\MessagingApi\Configuration;
use LINE\Clients\MessagingApi\Api\MessagingApiApi;
use LINE\Clients\MessagingApi\Model\ReplyMessageRequest;
use LINE\Clients\MessagingApi\Model\TextMessage;
use LINE\Clients\MessagingApi\Model\ImageMessage;
use LINE\Clients\MessagingApi\Model\TemplateMessage;
use LINE\Clients\MessagingApi\Model\ButtonsTemplate;
use LINE\Clients\MessagingApi\Model\PostbackAction;
use LINE\Clients\MessagingApi\Model\ConfirmTemplate;
use LINE\Clients\MessagingApi\Model\URIAction;
use LINE\Clients\MessagingApi\Model\MessageAction;
use LINE\Clients\MessagingApi\Model\CarouselTemplate;
use LINE\Clients\MessagingApi\Model\CarouselColumn;
use LINE\Constants\MessageType;
$channelSecret = "你的channelSecret";
$channelToken = "你的channelToken";
// 設定 HTTP 客戶端和配置
$client = new Client();
$config = new Configuration();
$config->setAccessToken($channelToken);
$messagingApi = new MessagingApiApi($client, $config);
// 接收並驗證 webhook 請求
$signature = $_SERVER['HTTP_' . 'X_LINE_SIGNATURE'];
$body = file_get_contents('php://input');
// 簡單驗證 signature (手動檢查)
$hash = hash_hmac('sha256', $body, $channelSecret, true);
$signatureCheck = base64_encode($hash);
if ($signature !== $signatureCheck) {
error_log("Invalid signature");
http_response_code(400);
exit;
}
// 解析事件 (手動處理 JSON)
$events = json_decode($body, true);
if (isset($events['events'])) {
foreach ($events['events'] as $event) {
$tmpMsg = "";
if ($event['type'] === 'message' && $event['message']['type'] === 'text') { //文字訊息
$replyToken = $event['replyToken'];
$text = $event['message']['text'];
$tmpMsg = "你所輸入的: ".$text;
// 準備回覆訊息
$message[] = new TextMessage([
'type' => 'text',
'text' => $tmpMsg
]);
$request = new ReplyMessageRequest([
'replyToken' => $replyToken,
'messages' => $message
]);
// 發送回覆
try {
$response = $messagingApi->replyMessage($request);
error_log("Reply succeeded");
} catch (\LINE\Clients\MessagingApi\ApiException $e) {
error_log("Reply failed: " . $e->getCode() . " " . $e->getResponseBody());
}
}
else if ($event['type'] === 'postback') {
$replyToken = $event['replyToken'];
$data = $event['postback']['data']; // e.g. "plan=A"
$userId = $event['source']['userId'] ?? "NO"; // 取得 userId
$message = array();
$replyText = "你選的選項".$data;
$message[] = new TextMessage([
'type' => 'text',
'text' => $replyText
]);
$request = new ReplyMessageRequest([
'replyToken' => $replyToken,
'messages' => $message
]);
try {
$response = $messagingApi->replyMessage($request);
error_log("Reply succeeded");
} catch (\LINE\Clients\MessagingApi\ApiException $e) {
error_log("Reply failed: " . $e->getCode() . " " . $e->getResponseBody());
}
}
else if($event['type'] === 'follow'){ //加為好友觸發
// 準備回覆訊息
$message = new TextMessage([
'type' => 'text',
'text' => '您好,這裡是QuantoShop eSIM 自助機器人\n請輸入您所要查詢的 Order ID'
]);
$request = new ReplyMessageRequest([
'replyToken' => $replyToken,
'messages' => [$message]
]);
// 發送回覆
try {
$response = $messagingApi->replyMessage($request);
error_log("Reply succeeded");
} catch (\LINE\Clients\MessagingApi\ApiException $e) {
error_log("Reply failed: " . $e->getCode() . " " . $e->getResponseBody());
}
}
}
}
?>
目前這個版本我可以做到直接回應、主動傳送訊息,但是免費的主動傳送一個月只有200則。
附上我的vendor資料夾,這應該可以直接拿來用。
以下是 Carousel 可用的範例
function createCarouselMessage_Country($plans){
$message = array();
if(count($plans) == 0){
$message[] = new TextMessage([
'type' => 'text',
'text' => '目前沒有任何方案'
]);
}else{
$columnAry = array();
for($i = 0;$i < count($plans); $i++){
$column = new CarouselColumn();
$column->setThumbnailImageUrl("https://quantoyo.com/國家.png");
$column->setImageBackgroundColor("#F0F0F0");
$column->setTitle($plans[$i]['location']);
$column->setText('請選擇方案類型');
$column->setActions([
new PostbackAction([
'type' => 'postback',
'label' => "流量型方案",
'data' => $plans[$i]['locationCode']
])
]);
$columnAry[] = $column;
if(count($columnAry) == 10){ //Carousel 最多10個
break;
}
}
// 建立 Carousel Template
$carousel = new CarouselTemplate();
$carousel->settype('carousel');
$carousel->setColumns($columnAry);
// 加入要發送的訊息陣列
$message[] = new TemplateMessage([
'type' => 'template',
'altText' => '請選擇國家',
'template' => $carousel
]);
}
return $message;
}
以下是 Template 可用範例
function createTemplateMessage_Country($plans){
$message = array();
if(count($plans) == 0){
$message[] = new TextMessage([
'type' => 'text',
'text' => '目前沒有任何方案'
]);
}else{
$locationMsgAry = array();
$plansMsgAry = array();
for($i = 0;$i < count($plans); $i++){
$tmpPostback = new PostbackAction([
'type' => 'postback',
'label' => limitStr($plans[$i]['location'],20),
'data' => $plans[$i]['locationCode']
]);
$plansMsgAry[] = $tmpPostback;
if(count($plansMsgAry) == 4 || $i == count($plans) -1){
$locationMsgAry[] = $plansMsgAry;
$plansMsgAry = array();
}
}
for($i = 0;$i < count($locationMsgAry); $i++){
$message[] = new TemplateMessage([
'type' => 'template',
'altText' => '請選擇國家',
'template' => new ButtonsTemplate([
'type' => 'buttons',
'title' => '國家選擇',
'text' => '請選擇你要的國家:',
'actions' => $locationMsgAry[$i]
])
]);
if(count($message) > 4)break;
}
}
return $message;
}