顯示具有 LINE 標籤的文章。 顯示所有文章
顯示具有 LINE 標籤的文章。 顯示所有文章

2024-12-30

【LINE Messaging API】主動傳送訊息(推播) 給多位使用者

類似主動傳訊息給 user,不過在傳訊類型定義為 multicast。要傳訊的目標對象是多位 user,所以 UserId 要存在陣列中。


 
<php?
date_default_timezone_set('Asia/Taipei');
$sRootDir = $_SERVER['DOCUMENT_ROOT'];
$channelAccessToken = '您的 channel Access Token';
$bodyMsg = file_get_contents('php://input');

// LINE 不會幫我們記錄, 所以要自己寫 log
// 這段不是必要, 只是方便自己除錯
$sLogfile = 'log_'.date('Ymd').'.log';    // 指定 log 檔名, 一天一個檔, 檔名格式為: log_yyyymmdd.log
$fp = fopen($sLogfile, "a+");
fwrite($fp , print_r(date('Y-m-d H:i:s').', Recive: '.$bodyMsg."\n", true));
fclose($fp);

...
...
// 取得 user id, 管道有很多, 此處不贅述
$arrUserId = ['...','...', ...];    ← 要推播的目標 UserId 存入陣列

$payload = [ 'to' => $arrUserId,
             'messages' => [
                               ['type' => 'text',
                                'text' => '恭喜! 您中了特獎!',
                               ]
                              ]
           ];
SendMsg($payload);


// 傳送訊息給指定使用者
function SendMsg($payload) {
    $ch = curl_init();
    // curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/message/push');
    ↓ 注意這裡要改成 multicast
    curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/message/multicast');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [  'Content-Type: application/json',
                                            'Authorization: Bearer ' . $GLOBALS['channelAccessToken']
                                        ]);
    $result = curl_exec($ch);
    curl_close($ch);
    // 寫 log
    $sLogfile = 'log_'.date('Ymd').'.log';
    $fp = fopen($sLogfile, "a+");
    fwrite($fp , print_r(date('Y-m-d H:i:s').', send message result: '.$result."\n", true));
    fclose($fp);
}
?>
 



相關筆記 ----


2024-01-14

【LINE】解除 LIFF 連動程式

點擊 主頁 → 右上角 (設定)齒輪










2023-12-07

【LINE Messaging API】主動傳送訊息給指定使用者

 
<php?
date_default_timezone_set('Asia/Taipei');
$sRootDir = $_SERVER['DOCUMENT_ROOT'];
$channelAccessToken = '您的 channel Access Token';
$bodyMsg = file_get_contents('php://input');

// LINE 不會幫我們記錄, 所以要自己寫 log
// 這段不是必要, 只是方便自己除錯
$sLogfile = 'log_'.date('Ymd').'.log';    // 指定 log 檔名, 一天一個檔, 檔名格式為: log_yyyymmdd.log
$fp = fopen($sLogfile, "a+");
fwrite($fp , print_r(date('Y-m-d H:i:s').', Recive: '.$bodyMsg."\n", true));
fclose($fp);

...
...
// 取得 user id, 管道有很多, 此處不贅述
$sUserId = ...;

$payload = [ 'to' => $sUserId,
             'messages' => [
                               ['type' => 'text',
                                'text' => '恭喜! 您中了特獎!',
                               ]
                              ]
           ];
SendMsg($payload);


// 傳送訊息給指定使用者
function SendMsg($payload)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/message/push');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [  'Content-Type: application/json',
                                            'Authorization: Bearer ' . $GLOBALS['channelAccessToken']
                                        ]);
    $result = curl_exec($ch);
    curl_close($ch);
    // 寫 log
    $sLogfile = 'log_'.date('Ymd').'.log';
    $fp = fopen($sLogfile, "a+");
    fwrite($fp , print_r(date('Y-m-d H:i:s').', send message result: '.$result."\n", true));
    fclose($fp);
}
?>
 



相關筆記 ----

【LINE Messaging API】以 user id 查詢 user name

 
<php?
date_default_timezone_set('Asia/Taipei');
$sRootDir = $_SERVER['DOCUMENT_ROOT'];
$channelAccessToken = '您的 channel Access Token';
$bodyMsg = file_get_contents('php://input');

// LINE 不會幫我們記錄, 所以要自己寫 log
// 這段不是必要, 只是方便自己除錯
$sLogfile = 'log_'.date('Ymd').'.log';    // 指定 log 檔名, 一天一個檔, 檔名格式為: log_yyyymmdd.log
$fp = fopen($sLogfile, "a+");
fwrite($fp , print_r(date('Y-m-d H:i:s').', Recive: '.$bodyMsg."\n", true));
fclose($fp);

$obj = json_decode($bodyMsg, true);
$payload = null;
$event = null;

foreach ($obj['events'] as &$event)
{
    switch($event['type'])
    {
        // 如果您有在 LINE 官方帳號後台設定 歡迎詞, 
        // user 加入好友後也會收到
        case 'follow':
            // user 加入好友後, 程式自己要做的事
            $userId = $event['source']['userId'];
            $sUsername = getUsername($sUser);
            break;
            
        ...
        ...
    }        
}

function getUsername($user_id) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://api.line.me/v2/bot/profile/$user_id");
    curl_setopt($ch, CURLOPT_HTTPHEADER, [  'Content-Type: application/json',
                                            'Authorization: Bearer ' . $GLOBALS['channelAccessToken']
                                        ]);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    $result = curl_exec($ch);
    curl_close($ch);

    if ($result===false) {
		// 查詢失敗, 
        return 'NG';
    }

    $data = json_decode($result, true);
    return $data["displayName"];
}
?>
 

2022-07-16

【PHP】LINE 官方帳號 以 Account link 綁定 網站/公司 既有會員

參考資料 ----
LINE Messaging API

有時候,您的公司在成立 LINE 官方帳號前,早就已經建立官網多時,這時我們希望能將 LINE 使用者與網站上的會員綁定,以提供會員更好的服務。
下圖是整個綁定的流程


先在官方帳號後方設定圖文選單,當使用者按下 選項 B 時,會送出 【綁定帳號】 給 LINE 機器人程式,接下來就開始綁定流程


按下選項 B,開始綁定流程


將使用者導至網站登入頁,輸入 帳號、密碼


完成驗證,重導至 LINE 綁定成功頁面







LINE 機器人程式
 
<?php
date_default_timezone_set('Asia/Taipei');
$channelAccessToken = '{blablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablabla}';
 
$bodyMsg = file_get_contents('php://input');

// 寫 log
$sLogfile = './log/log_'.date('Ymd').'.log';
$fp = fopen($sLogfile, "a+");
fwrite($fp , print_r(date('Y-m-d H:i:s').', Recive: '.$bodyMsg."\n", true));
fclose($fp);


 
$obj = json_decode($bodyMsg, true);
$payload = null;
$event = null;
 
 
foreach ($obj['events'] as &$event)
{
    switch($event['type'])
    {
        // user 傳來訊息
        case 'message':
            $userId = $event['source']['userId'];
            // 取得 使用者傳來的訊息
            $msgUser = $event['message']['text'];
            // 判斷 client 端傳訊型態
            switch($event['message']['type'])
            {
                // 文字
                case 'text':
                {
                    switch($event['message']['text'])
                    {
                        ...
                        ...

                        case '【綁定帳號】':
                            // 1. 向 LINE 平台申請 link token
                            $ch = curl_init();
                            curl_setopt($ch, CURLOPT_URL,"https://api.line.me/v2/bot/user/$userId/linkToken");
                            curl_setopt($ch, CURLOPT_POST, true);
                            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
                            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
                            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                            curl_setopt($ch, CURLOPT_HTTPHEADER, [  'Content-Type: application/json',
                                                                    'Authorization: Bearer ' . $channelAccessToken
                                                                ]);
                            $result = curl_exec($ch);
                            curl_close($ch);
                            // 寫 log
                            $sLogfile = './log/log_'.date('Ymd').'.log';
                            $fp = fopen($sLogfile, "a+");
                            fwrite($fp , print_r(date('Y-m-d H:i:s').', LINE resule: '.$result."\n", true));
                            fclose($fp);

                            // 2. LINE 平台回覆 linkToken 給 機器人
                            $objResult = json_decode($result, true);
                            $linkToken = $objResult['linkToken'];
                            // 寫 log
                            $sLogfile = './log/log_'.date('Ymd').'.log';
                            $fp = fopen($sLogfile, "a+");
                            fwrite($fp , print_r(date('Y-m-d H:i:s').", decode json → linkToken = $linkToken \n", true));
                            fclose($fp);

                            // 3. 傳送 linking URL 給 LINE 平台
                            $payload = ["to" => $userId,
                                        "messages" => [
                                                        [ 
                                                            "type" => "template",
                                                            "altText" => "Account Link",
                                                            "template" => [
                                                                            "type" => "buttons",
                                                                            "text" => "綁定帳號",
                                                                            "actions" => [
                                                                                                [
                                                                                                    "type" => "uri",
                                                                                                    "label" => "登入",
                                                                                                    "uri" => "https://網址/line/link.php?linkToken=$linkToken"
                                                                                                ]
                                                                                            ]
                                                                        ]
                                                        ]
                                                    ]
                                    ];
                            $ch = curl_init();
                            curl_setopt($ch, CURLOPT_URL,"https://api.line.me/v2/bot/message/push");
                            curl_setopt($ch, CURLOPT_POST, true);
                            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
                            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
                            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
                            curl_setopt($ch, CURLOPT_HTTPHEADER, [  'Content-Type: application/json',
                                                                    'Authorization: Bearer ' . $channelAccessToken
                                                                ]);
                            $result = curl_exec($ch);
                            curl_close($ch);
                            // 寫 log
                            $sLogfile = './log/log_'.date('Ymd').'.log';
                            $fp = fopen($sLogfile, "a+");
                            fwrite($fp , print_r(date('Y-m-d H:i:s').', Redirect user resule: '.$result."\n", true));
                            fwrite($fp , print_r("encode payload = ".json_encode($payload)." \n", true));
                            fclose($fp);

                            // 4. LINE 平台將 user 導至網站登入頁面

                            exit;
                    }
                }
            }
            break;

        case 'accountLink':
            11. LINE 平台傳送 會員的 userId 給機器人
            $userId = $event['source']['userId'];
            $nonce = $event['link']['nonce'];
            
            12. 在資料庫找到 user, 並存入該會員的 LINE userId
            // 寫 log
            $sLogfile = './log/log_'.date('Ymd').'.log';
            $fp = fopen($sLogfile, "a+");
            fwrite($fp , print_r(date('Y-m-d H:i:s').', 藉由 nonce: '.$nonce." 在資料庫中找到使用者, 並存入 userId($userId), 完成綁定 \n", true));
            fclose($fp);
            exit;
    }
}
?>

 




網站登入程式 link.php
 
<?php
    // 在本例, 我們偷懶, 將 step 5 ~ 9 都寫在同一支程式
    // setp 5 在下方

    // 7. 驗證登入
    if(isset($_POST['token']))
    {   // user submit
        // 驗證登入資訊
        // 略, 偽裝 user 通過驗證
        $id = $_POST['id'];
        $pwd = $_POST['pwd'];
        $token = $_POST['token'];

        // 8. 產生 nonce 並存入資料庫, 以便後面流程連結 userId 用
        $nonce = base64_encode(random_bytes(16));

        // 9. 重導至綁定成功頁面
        echo "<script>
                location.href='https://access.line.me/dialog/bot/accountLink?linkToken=$token&nonce=$nonce'
            </script>";
        exit;
    }
?>
<html>
<body>
<?php
    // 5. user 引導至網站登入頁
    if(isset($_GET['linkToken']))
    {
        $linkToken = $_GET['linkToken'];
    }

    // 6. 顯示登入頁面
?>
<center>
    <form id="frmLogin" method="post" action="link.php" style="font-size:30pt;">
        <table border="0">
            <tr>
                <td><input type="hidden" id="hidToken" name="token" value="<?php    echo $linkToken;    ?>" /></td>
            </tr>
            <tr>
                <td><input type="text" id="txtID" name="id" maxlength="20" width="50" /></td>
            </tr>
            <tr>
                <td><input type="password" id="txtPwd" name="pwd" maxlength="20" width="50" /></td>
            </tr>
            <tr>
                <td><input type="submit" text="提交" />  <input type="reset" text="重填" /></td>
            </tr>
        </table>
    </form>
</center>
</body>
</html>
 

解除綁定相對簡單多了,因為 event 都會含 userId,所以藉由 userId 去資料庫找,將該會員的 userId 欄位清除即可。

2022-07-09

【PHP】LINE 回覆 imagemap 訊息

參考資料 ----
Imagemap message

Imagemap 可說是能玩很多花樣的訊息,也是較複雜的。您可以在圖片中設置點擊區,最多可以有 50 個(本例只設置 1 個點擊區),每個點擊區點擊後的反應也可不同。

例如:
我們的訊息要回覆下圖,並且設置 左上角 紅線框起的區為點擊區,點擊後跳轉至指定的網址。





 
 
<?php
// 因為網站是寄放在虛擬主機商那, 所以要指定時區
date_default_timezone_set('Asia/Taipei');
$channelAccessToken = '{從 LINE 官方帳號後台取得的 token}';
 
// 客戶端傳來的訊息
$bodyMsg = file_get_contents('php://input');

// 寫 log, 檔案在目前目錄下的 log 目錄內
// 檔名為 log_西元年月日.log, 一天一個檔
$sLogfile = './log/log_'.date('Ymd').'.log';
$fp = fopen($sLogfile, "a+");
fwrite($fp , print_r(date('Y-m-d H:i:s').', Recive: '.$bodyMsg."\n", true));
fclose($fp);

$obj = json_decode($bodyMsg, true);

foreach ($obj['events'] as &$event) 
{
   $userId = $event['source']['userId'];
   
    // 取得 使用者傳來的訊息
    $msgUser = $event['message']['text'];

    // 回傳 imagemap 訊息
    $payload = [ 'replyToken' => $event['replyToken'],
                'messages' => [ 
                                [
                                    "type" => "imagemap",
                                    "baseUrl" => "https://圖片網址/目錄/",    // 注意: 是目錄, 不是檔名, 上限 2000 字
                                    "altText" => "imagemap 訊息",     // 上限 400 字
                                    "baseSize" => ["width" => 1040,   // 固定值 1040
                                                    "height" => 585,   // 自行計算 您的圖片長寬比例換算成寬度為 1040 時的 高度值
                                                ],
                                    "actions" => [  // json 物件, 上限 50 個
                                                    // 轉換成 PHP 就成為 陣列
                                                    [
                                                        "type" => "uri",
                                                        "label" => "LINE 家族成員合照",    // 選擇性參數, 這是讓手機朗讀給視障人士的文字
                                                        "linkUri" => "https://要跳轉的目標網址/",
                                                        "area" => [
                                                                    "x" => 0,    // 紅框的左上角座標
                                                                    "y" => 0,    // 紅框的左上角座標
                                                                    "width" => 520,    // 紅框的右下角座標, 以最大尺寸的 1040 去計算設置
                                                                    "height" => 290    // 紅框的右下角座標, 以最大尺寸的 1040 去計算設置
                                                                ]
                                                    ]
                                                ]
                                ]
                            ]
            ];
            
    // Send reply API
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/message/reply');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [  'Content-Type: application/json',
                                            'Authorization: Bearer ' . $channelAccessToken
                                        ]);
    $result = curl_exec($ch);
    curl_close($ch);
}
?>
 
在上例,我們想將圖片置於
https://www.example.com/imagemap/ 這個目錄內,原圖為大小 430*260
可以利用如 Gimp 這類的影像處理軟體縮放原圖,複製出 寬度為 240px, 300px, 460px, 700px, 1040px 這 5 種尺寸的圖片,圖片格式限定 JPG 或 PNG,並且檔名分別 240, 300, 460, 700, 1040,有無副檔名則其次,如下圖:
由此也可知,imagemap 的圖片是以目錄名為主
一定要有 5 張,不然 LINE 不會有回應;LINE 會依據使用者的裝置解析度,自動顯示尺寸最適合的圖片。

altText 則是在 聊天列表 或 手機訊息列 所顯示的文字,如下圖
雖然這篇筆記是在探索 回覆訊息 的機制及功能,但也可應用於推播訊息。

在 actions 有個屬性 label,官網說當您在
"設定" → "無障礙設定" 
啟用了 "隨選朗讀",則當視障朋友點擊這張圖片的指定區域時,手機會朗讀 label 的文字,不過我沒試出來。


回覆 imagemap 訊息



在本例,點擊後,直接在 LINE 裡跳轉至 tw.yahoo.com,並沒有另外開啟瀏覽器 app。


imagemap 也可以內嵌影片
 
<?php
// 因為網站是寄放在虛擬主機商那, 所以要指定時區
date_default_timezone_set('Asia/Taipei');
$channelAccessToken = '{從 LINE 官方帳號後台取得的 token}';
 
// 客戶端傳來的訊息
$bodyMsg = file_get_contents('php://input');

// 寫 log, 檔案在目前目錄下的 log 目錄內
// 檔名為 log_西元年月日.log, 一天一個檔
$sLogfile = './log/log_'.date('Ymd').'.log';
$fp = fopen($sLogfile, "a+");
fwrite($fp , print_r(date('Y-m-d H:i:s').', Recive: '.$bodyMsg."\n", true));
fclose($fp);

$obj = json_decode($bodyMsg, true);

foreach ($obj['events'] as &$event) 
{
   $userId = $event['source']['userId'];
   
    // 取得 使用者傳來的訊息
    $msgUser = $event['message']['text'];

    // 回傳 video imagemap 訊息
    $payload = [ 'replyToken' => $event['replyToken'],
                 'messages' => [ 
                                [
                                    "type" => "imagemap",   // 必要參數
                                    "baseUrl" => "https://www.whalin.com.tw/line/imagemap/",    // 必要參數, 上限 2000 字
                                    "altText" => "imagemap 訊息",     // 必要參數, 上限 400 字
                                    "baseSize" => ["width" => 1040,   // 必要參數, 固定值 1040
                                                    "height" => 585,   // 自行計算 您的圖片長寬比例換算成寬度為 1040 時的 高度值
                                                ],
                                    "video" => [    // 影片格式: mp4, 檔案大小不可超過 200MB
                                                    "originalContentUrl" => "https://影片網址/blabla.mp4", // 字串長度上限 2000 字, 
                                                    "previewImageUrl" => "https://預覽圖網址/pre.png",    // 預覽圖, 格式限 JPEG/PNG, 檔案大小不可超過 1MB, 字串長度上限 2000 字, 
                                                    "area" => [
                                                                "x" => 260,
                                                                "y" => 130,
                                                                "width" => 520,
                                                                "height" => 292
                                                    ],
                                                    "externalLink" => [
                                                                        "linkUri" => "https://網址",    // 字串長度上限 1000 字, 支援 http, https, line, tel 協定
                                                                        "label" => "影片播畢後標籤"
                                                                    ],
                                                ],
                                    "actions" => [  // json 物件, 上限 50 個
                                                    // 轉換成 PHP 就成為 陣列
                                                    [
                                                        "type" => "uri",
                                                        "label" => "LINE 家族成員合照",
                                                        "linkUri" => "https://要跳轉的目標網址/",
                                                        "area" => [
                                                                    "x" => 0,
                                                                    "y" => 0,
                                                                    "width" => 520,
                                                                    "height" => 290
                                                                ]
                                                    ]
                                                ]
                                ]
                            ]
            ];
            
    // Send reply API
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/message/reply');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [  'Content-Type: application/json',
                                            'Authorization: Bearer ' . $channelAccessToken
                                        ]);
    $result = curl_exec($ch);
    curl_close($ch);
}
?>
 









2022-07-05

【PHP】LINE 回覆地理位置訊息

參考資料 ----
Location message

 
<?php
// 因為網站是寄放在虛擬主機商那, 所以要指定時區
date_default_timezone_set('Asia/Taipei');
$channelAccessToken = '{從 LINE 官方帳號後台取得的 token}';
 
// 客戶端傳來的訊息
$bodyMsg = file_get_contents('php://input');

// 寫 log, 檔案在目前目錄下的 log 目錄內
// 檔名為 log_西元年月日.log, 一天一個檔
$sLogfile = './log/log_'.date('Ymd').'.log';
$fp = fopen($sLogfile, "a+");
fwrite($fp , print_r(date('Y-m-d H:i:s').', Recive: '.$bodyMsg."\n", true));
fclose($fp);

$obj = json_decode($bodyMsg, true);

foreach ($obj['events'] as &$event) 
{
   $userId = $event['source']['userId'];
   
    // 取得 使用者傳來的訊息
    $msgUser = $event['message']['text'];

    // 回傳 地址位置訊息
    $payload = [ 'replyToken' => $event['replyToken'],
                'messages' => [ 
                                [
                                    "type" => "location",
                                    "title" => "高捷紅線美麗島站",
                                    "address" => "高雄市新興區中正四路3號",
                                    "latitude" => 22.631392,
                                    "longitude" => 120.301803
                                ]
                            ]
            ];
            
    // Send reply API
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/message/reply');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [  'Content-Type: application/json',
                                            'Authorization: Bearer ' . $channelAccessToken
                                        ]);
    $result = curl_exec($ch);
    curl_close($ch);
}
?>
 

 
相關筆記 ----

2022-07-02

【PHP】LINE 回覆影片訊息

參考資料 ----
Video message

 
<?php
// 因為網站是寄放在虛擬主機商那, 所以要指定時區
date_default_timezone_set('Asia/Taipei');
$channelAccessToken = '{從 LINE 官方帳號後台取得的 token}';
 
// 客戶端傳來的訊息
$bodyMsg = file_get_contents('php://input');

// 寫 log, 檔案在目前目錄下的 log 目錄內
// 檔名為 log_西元年月日.log, 一天一個檔
$sLogfile = './log/log_'.date('Ymd').'.log';
$fp = fopen($sLogfile, "a+");
fwrite($fp , print_r(date('Y-m-d H:i:s').', Recive: '.$bodyMsg."\n", true));
fclose($fp);

$obj = json_decode($bodyMsg, true);

foreach ($obj['events'] as &$event) 
{
   $userId = $event['source']['userId'];
   
    // 取得 使用者傳來的訊息
    $msgUser = $event['message']['text'];

    // 回覆 影片 訊息
    $payload = [ 'replyToken' => $event['replyToken'],
                'messages' => [ 
                                [
                                    "type" => "video",
                                    "originalContentUrl" => "https://完整網址/原始影片檔檔名.mp4",    // 大小不可超過 200M
                                    "previewImageUrl" => "https://完整網址/預覽圖檔檔名.png",   // 限 jpg 或 png, 大小不可超過 1M
                                    "trackingId" => "myid"  // 選擇性參數, 只可輸入 英數字 及 .=,+*()%$&;:@{}!?<>[] 這幾個符號
                                                            // 官網是說當回覆有帶這個參數時, 客戶端看完影片時會通知 webhook
                                ]
                            ]
            ];
            
    // Send reply API
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/message/reply');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [  'Content-Type: application/json',
                                            'Authorization: Bearer ' . $channelAccessToken
                                        ]);
    $result = curl_exec($ch);
    curl_close($ch);
}
?>
 


當 user 看完影片時, server 這邊收到的通知內容如下
 
"destination":"bla1bla1bla1bla1bla1bla1bla1bla1bla1bla1",
"events":[{ "type":"videoPlayComplete",
            "videoPlayComplete":{"trackingId":"myid"},
            "webhookEventId":"bla2bla2bla2bla2bla2bla2bla2bla2bla2bla2",
            "deliveryContext":{"isRedelivery":false},
            "timestamp":1656748409328,
            "source":{"type":"user",
                     "userId":"bla3bla3bla3bla3bla3bla3bla3bla3bla3bla3"
                    },
            "replyToken":"bla4bla4bla4bla4bla4bla4bla4bla4bla4bla4",
            "mode":"active"
        }]
        
至於能做什麼用途, 就自行發揮想像力吧
 

【PHP】LINE 回覆圖片訊息

參考資料 ----
Image message

 
<?php
// 因為網站是寄放在虛擬主機商那, 所以要指定時區
date_default_timezone_set('Asia/Taipei');
$channelAccessToken = '{從 LINE 官方帳號後台取得的 token}';
 
// 客戶端傳來的訊息
$bodyMsg = file_get_contents('php://input');

// 寫 log, 檔案在目前目錄下的 log 目錄內
// 檔名為 log_西元年月日.log, 一天一個檔
$sLogfile = './log/log_'.date('Ymd').'.log';
$fp = fopen($sLogfile, "a+");
fwrite($fp , print_r(date('Y-m-d H:i:s').', Recive: '.$bodyMsg."\n", true));
fclose($fp);

$obj = json_decode($bodyMsg, true);

foreach ($obj['events'] as &$event) 
{
   $userId = $event['source']['userId'];
   
    // 取得 使用者傳來的訊息
    $msgUser = $event['message']['text'];

    // 回傳 圖片訊息, 限 jpg 或 png
    $payload = [ 'replyToken' => $event['replyToken'],
                 'messages' => [ 
                                [
                                    "type" => "image",
                                    // 網址必須是 https, 網址字串長度不可超過 2000 字
                                    "originalContentUrl" => "https://完整網址/原始圖檔檔名.png", // 圖片不可超過 10M
                                    "previewImageUrl" => "https://完整網址/預覽圖檔檔名.png"      // 圖片不可超過 1M
                                ]
                            ]
            ];
            
    // Send reply API
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/message/reply');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [  'Content-Type: application/json',
                                            'Authorization: Bearer ' . $channelAccessToken
                                        ]);
    $result = curl_exec($ch);
    curl_close($ch);
}
 
?>
預覽圖



原始圖









【PHP】LINE 回覆貼圖訊息

參考資料 ----
List of available stickers

也可回覆貼圖, 只不過限於 LINE 官方的貼圖
 
<?php
// 因為網站是寄放在虛擬主機商那, 所以要指定時區
date_default_timezone_set('Asia/Taipei');
$channelAccessToken = '{從 LINE 官方帳號後台取得的 token}';
 
// 客戶端傳來的訊息
$bodyMsg = file_get_contents('php://input');

// 寫 log, 檔案在目前目錄下的 log 目錄內
// 檔名為 log_西元年月日.log, 一天一個檔
$sLogfile = './log/log_'.date('Ymd').'.log';
$fp = fopen($sLogfile, "a+");
fwrite($fp , print_r(date('Y-m-d H:i:s').', Recive: '.$bodyMsg."\n", true));
fclose($fp);

$obj = json_decode($bodyMsg, true);

foreach ($obj['events'] as &$event) 
{
   $userId = $event['source']['userId'];
   
    // 取得 使用者傳來的訊息
    $msgUser = $event['message']['text'];

    // 回傳貼圖訊息
    $payload = [ 'replyToken' => $event['replyToken'],
                'messages' => [ // 一次最多可回覆 5 張貼圖, 若超過 5 張, 程式就掛了, 不會有任何回應
                                [ 'type' => 'sticker',
                                  'packageId' => '446',
                                  'stickerId' => '1988'
                                ],
                                [ 'type' => 'sticker',
                                  'packageId' => '789',
                                  'stickerId' => '10855'
                                ],
                                [ 'type' => 'sticker',
                                  'packageId' => '8525',
                                  'stickerId' => '16581290'
                                ],
                                [ 'type' => 'sticker',
                                  'packageId' => '6136',
                                  'stickerId' => '10551376'
                                ],
                                [ 'type' => 'sticker',
                                  'packageId' => '6325',
                                  'stickerId' => '10979904'
                                ]
                            ]
            ];
            
    // Send reply API
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/message/reply');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [  'Content-Type: application/json',
                                            'Authorization: Bearer ' . $channelAccessToken
                                        ]);
    $result = curl_exec($ch);
    curl_close($ch);
}
 
?>






2022-06-30

【PHP】LINE 回覆文字訊息

參考資料 ----
List of available LINE emojis

文字訊息也可包含 emoji(顏文字), 只不過限於 LINE 官方的 emoji
 
<?php
// 因為網站是寄放在虛擬主機商那, 所以要指定時區
date_default_timezone_set('Asia/Taipei');
$channelAccessToken = '{從 LINE 官方帳號後台取得的 token}';
 
// 客戶端傳來的訊息
$bodyMsg = file_get_contents('php://input');

// 寫 log, 檔案在目前目錄下的 log 目錄內
// 檔名為 log_西元年月日.log, 一天一個檔
$sLogfile = './log/log_'.date('Ymd').'.log';
$fp = fopen($sLogfile, "a+");
fwrite($fp , print_r(date('Y-m-d H:i:s').', Recive: '.$bodyMsg."\n", true));
fclose($fp);

$obj = json_decode($bodyMsg, true);

foreach ($obj['events'] as &$event) 
{
   $userId = $event['source']['userId'];
   
    // 取得 使用者傳來的訊息
    $msgUser = $event['message']['text'];

    // 回覆含 emoji 的文字訊息
    // $ 的位置就是 emoji 的位置, 作用類似格式化輸出
    // 在本例, 2 個 $ 的位置分別為 0, 8
    $msgReply = '$含 emoji$ 的文字訊息';
    
    $payload = [ 'replyToken' => $event['replyToken'],
                'messages' => [  // 一次最多可回覆 5 則訊息, 若超過 5 則, 程式就掛了, 不會有任何回應
                                ['type' => 'text',
                                'text' => $msgReply,
                                'emojis' => [   [
                                                    "index"=> 0,    // emoji 在文字串的位置, 一定要和 $msgReply 中的 $ 的位置一致, 不然整個訊息都不會回覆
                                                    "productId" => "5ac1bfd5040ab15980c9b435",
                                                    "emojiId" => "001"
                                                ],
                                                [
                                                    "index" => 8,
                                                    "productId" => "5ac1bfd5040ab15980c9b435",
                                                    "emojiId" => "005"
                                                ]
                                        ]
                                ],
                                [   'type' => 'text',
                                    'text' => '文字訊息 2'
                                ],
                                [   'type' => 'text',
                                    'text' => '文字訊息 3'
                                ],
                                [   'type' => 'text',
                                    'text' => '文字訊息 4'
                                ],
                                [   'type' => 'text',
                                    'text' => '文字訊息 5'
                                ]
                            ]
            ];
            
    // Send reply API
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/message/reply');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [  'Content-Type: application/json',
                                            'Authorization: Bearer ' . $channelAccessToken
                                        ]);
    $result = curl_exec($ch);
    curl_close($ch);
}
 
?>