最新消息

[公告2014/05/30] 如有需要將部落格中,任何一篇文章的程式碼使用在商業用途,請與我聯繫。

[公告2015/04/26] Line版的 iInfo程式與投資應用 群組已上線想加入的朋友們,請先查看 "入群須知" 再與我聯繫 Line : aminwhite5168,加入請告知身分與回答 "入群須知" 的問題。

[公告2018/04/22] 台北 Python + Excel VBA 金融資訊爬蟲課程,課程如網頁內容 金融資訊爬蟲班:台北班 Python 金融資訊爬蟲、EXCEL VBA 金融資訊爬蟲

[公告2019/01/08] 請注意:我再次重申,部落格文章的程式碼,是要提供各位參考與學習,一旦網頁改版請自行修改,別要求東要求西要我主動修改,你們用我寫東西賺錢了、交差了,請問有分我一杯羹嗎?既然賺錢沒分我,請問有什麼理由要求我修改,如果沒能力改,就花錢來找我上課。

[公告2019/12/01] 若各位有 Excel VBA 案子開發需求,歡迎與我聯繫,可接案處理。

[公告2020/05/22] 頁面載入速度慢,起因為部分JS來源(alexgorbatchev.com)失效導致頁面載入變慢,目前已做調整,請多見諒。

2017年2月12日 星期日

Line Bot 入門與應用(1) --- Line Messaging API V2 + PHP 串接

這2天串接 Line bot V2版花了一些功夫,雖然官網有提供 PHP SDK可以使用,不過筆者還是喜歡跟人家用不同的方法完成,過程遇到幾個問題,將在文章中一一說明,這裡感謝 「Chatbot.tw 台灣聊天機器人開發者社團」中的小強、韋辰、Akito大大們的協助才有機會完成。
網路上很多文章都有介紹串接的方法,但似乎沒有將過程詳細記錄,內容只說順利完成的部分,確忽未說到過程中遇到的問題與解法,筆者將會以自身操作過程詳盡說明,以下步驟可能比較繁雜一些,請各位讀者耐著性子讀完。
關於官網提供的SDK有支援以下的語言,讀著們可依自己習慣的語言使用。
也可經由「LINE developers」 ->  「API Reference」 ->  「LINE SDK」


以下就開始介紹串接流程。
首先請各位讀者注意,由於Line機器人需要一個後端去處理與回覆使用者從Line傳送過來的訊息,簡單說就是要有Server主機與Domain Name,這部分可參考 Firebase Cloud Messaging (FCM) 入門到進階應用(4) --- 網頁安裝SSL憑證
以下關於機器人端的部分,筆者有需要在這裡做一說明,以免讀者看到後面都搞不清楚,關於Line 機器人在收到訊息後的處理,就是在我們的主機扮演機器人在處理使用者送過來的訊息,需要有什麼功能提供給使用者,皆由主機端處理,不是官方LINE Server主機在處理,這一點讀者要清楚。

Step 1. 到「 Line Messaging API 」官網申請Line機器人帳號,點選「開始使用Messaging API」按鈕。


Step 2. 登入後填寫帳戶資料,「綠色」圓點項目為必填的內容,這裡可以亂填後續登入後可以修改資料,只要符合每個輸入欄位的特徵就好。

Step 3. 資料填完送出後,見到以下畫面就可開始使用 Messaging API 服務

Step 4. 設定帳戶名稱、圖片與分類,設定完成後按下確認送出。

Step 5. 見到以下畫面就完成機器人帳戶申請,後面再去「 LINE@MANAGER」對機器人帳戶做相關設定。

PS:畫面中的連結大家都可以點進去查看。

Step 6. 點選「前往LINE@MANAGER」按鈕,在點選畫面中,見到 Bot設定狀態為關閉,表示API服務尚未起動,點取「開始使用API 按鈕」啟動API服務。

Step 7. 點選確認視窗,開始使用API,相對地該帳戶的其他功能也將無法使用了,所以建議各位讀者可以選擇其他帳號來測試使用,不然啟用API服務後該帳戶將無法使用原本功能。


Step 8. 啟動API服務後,就會出現API相關的設定了,將 Webhook傳訊 勾選「允許」,按下「儲存」按鈕,記得將該帳號新增到 LINE 中,這樣後面才能用來測試。



Step 9. 點選狀態上的 「LINE Developers」 連結,以取得傳送用的Token(Channel Access Token)與傳送封包使用的解密金鑰 (Channel Secret)。


Step 10. 這裡還有一個地方需要設定,就是「Webhook URL」,說明一下,「Webhook URL」指的是 Line Server主機傳送訊息通知我們主機的連結,簡單說就是我們主機在網路上的URL,連結這是以檔案類型存在,就像網站的網頁一樣,如index.php、index.htm、index.asp、default.htm等,如果檔名是不是index開頭而是別的名稱,那就請將檔名與URL一起填在「Webhook URL」中。讀者們可至官網提供的SDK下載相關的檔案進行設定。
筆者將URL設定 https://www.iinfo.idv.tw/line/,這裡要注意,是「https」,不是「http」,不清楚原因的可至 Firebase Cloud Messaging (FCM) 入門到進階應用(4) --- 網頁安裝SSL憑證 文章了解。後面將介紹如何在主機的line資料中的檔案編寫。
設定好 Webhook URL,按下旁邊VERIFY按鈕 進行驗證,如可以成功連結,相會顯示綠色SUCCESS字樣,表示Line主機與我們主機串接成功。

筆者在一開始網站驗證時,出現紅字「SSL certificate is invalid.」沒順利成功。

經由「SSL Checker」確認後,才知道SSL沒有安裝成功,Google了一下才知道原來是中繼憑證CA沒有安裝,導致LINE驗證不過。

重新安裝中繼憑證與在 apache2\conf\extra\httpd-ssl.conf 中設定中繼憑證路徑後,重啟apapche,即可讓Line驗證通過。


Step 11. 設定白名單IP與mask,因為LINE Server只對所指定的白名單IP與mask發送訊息,這樣我們的主機端才能收到Line server送來的內容。

到了這裡已完成環境設定了,接下來開始編寫PHP程式碼與Line進行溝通驗證。
開啟一個文字檔案,將輸入以下程式碼並存成 Index.php,放在前面文章中常提到的 usbwebserver 的 root/line路徑下。
<?php
$access_token ='你的Channel Access Token';
//define('TOKEN', '你的Channel Access Token');

$json_string = file_get_contents('php://input');
$json_obj = json_decode($json_string);

$event = $json_obj->{"events"}[0];
$type  = $event->{"message"}->{"type"};
$message = $event->{"message"};
$reply_token = $event->{"replyToken"};
        
$post_data = [
  "replyToken" => $reply_token,
  "messages" => [
    [
      "type" => "text",
      "text" => $message->{"text"}
    ]
  ]
]; 

$ch = curl_init("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_POSTFIELDS, json_encode($post_data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Authorization: Bearer '.$access_token
    //'Authorization: Bearer '. TOKEN
));
$result = curl_exec($ch);
curl_close($ch); 
?>
第5行:接收LINE Server送過來的訊息。
第6行:將JSON進行解碼動作。
第8~11行:處理JSON內容。
第23~34行:訊息傳送到LINE上。

開始進行與 Line機器人溝通。
這畫面裡有2個問題,讓我們依序解決。
1. 發現每次發送訊息,機器人都會回應「很抱歉,這個帳號沒有辦法對用戶個別回覆」,這是因為在 Line後台的自動回應預設被設定起來的緣故,要取消自動回應才不會再見到這訊息。

2. 以下訊息顯示需要在手機上才能查看,該訊息為手機驗證訊息,需透過手機進行驗證。
在手機上點選同意按鈕。


到這裡感覺應該可以跟機器人溝通了,但以上過程看似沒什麼問題,卻遇到無法在機器人的Line中看見訊息,故在PHP程式碼中加入Log來Debug。
<?php
$access_token ='你的Channel Access Token';
//define('TOKEN', '你的Channel Access Token');

$json_string = file_get_contents('php://input');

$file = fopen("C:\\Line_log.txt", "a+");
fwrite($file, $json_string."\n"); 
$json_obj = json_decode($json_string);

$event = $json_obj->{"events"}[0];
$type  = $event->{"message"}->{"type"};
$message = $event->{"message"};
$reply_token = $event->{"replyToken"};
        
$post_data = [
  "replyToken" => $reply_token,
  "messages" => [
    [
      "type" => "text",
      "text" => $message->{"text"}
    ]
  ]
]; 
fwrite($file, json_encode($post_data)."\n");

$ch = curl_init("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_POSTFIELDS, json_encode($post_data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Authorization: Bearer '.$access_token
    //'Authorization: Bearer '. TOKEN
));
$result = curl_exec($ch);
fwrite($file, $result."\n");  
fclose($file);
curl_close($ch); 
?>
從 Line_log.txt中見到的問題是「可以接收來自LINE官網驗證的訊息,卻無法從本機傳送訊息至LINE帳號中」。

問題處理過程中找了很多人問,都沒能找出有效的解決方法,後來由「 Chatbot.tw 台灣聊天機器人開發者社團」中的小強大大提供的方法,在PHP程式碼中加入以下程式碼後,就可以成功接收到Line機器人的回應。
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
筆者後來上網找了一下為什麼需要這樣設定的原因,有興趣的朋友可以參考 「Mailgun心得筆記」有介紹,在PHP crul上設定SSL的說明。
最後程式碼:
<?php
$access_token ='你的Channel Access Token';
//define('TOKEN', '你的Channel Access Token');

$json_string = file_get_contents('php://input');

$file = fopen("C:\\Line_log.txt", "a+");
fwrite($file, $json_string."\n"); 
$json_obj = json_decode($json_string);

$event = $json_obj->{"events"}[0];
$type  = $event->{"message"}->{"type"};
$message = $event->{"message"};
$reply_token = $event->{"replyToken"};
        
$post_data = [
  "replyToken" => $reply_token,
  "messages" => [
    [
      "type" => "text",
      "text" => $message->{"text"}
    ]
  ]
]; 
fwrite($file, json_encode($post_data)."\n");

$ch = curl_init("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, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Authorization: Bearer '.$access_token
    //'Authorization: Bearer '. TOKEN
));
$result = curl_exec($ch);
fwrite($file, $result."\n");  
fclose($file);
curl_close($ch); 
?>
執行結果:

這裡還有個問題要說明,要能成功與LINE機器人溝通,白名單IP後面的mask的設定很要注意,必須在24~30的範圍中,筆者就全部都設定。

PS:根據筆者經驗「白名單IP」可以不填,填了反而要注意更多IP的設定,但「Webhook URL」一定要填。

以上內容屬於一問一答的回覆訊息(Reply message)模式。

說明一下如何與解讀從LINE傳進來的JSON訊息內容:
{"events":[
            {
             "type":"message",
             "replyToken":"ec386fad29f54c608b4ec0690e66a8fc",
             "source":{
                        "userId":"Uebcff71dc4b1xxxxxaa4ffoooooooooo",
                        "type":"user"
                      },
            "timestamp":1486890420086,
            "message":{
                       "type":"text",
                       "id":"5636293333777",
                       "text":"987"
                      }
            }
          ]
}
第4行:當使用發送訊息給機器人後,機器人收到JSON訊息後,從訊息裡將replyToken的值抓出來,透過replyToken才能將訊息回覆給使用者,每次訊息裡的 replyToken值都會不同,所以要注意。
第5行:訊息來源的類型,分User、Group、Room共3種。

第6行:userId為機器人主動發訊息(Push message)給使用者才會用到的ID。

PS:官網上的方案介紹是針對機器人從Line官網後台發送訊息(Push message)數量而定的方案,如果是用程式去做回覆訊息(Reply message)與發訊息(Push message)均不在此範圍,這裡不做廣告推薦介紹。

第8行:timestamp為訊息接收的時間。
第9~13行:為訊息內容、種類。

到此為LINE機器人串接,如有相關問題,請與讀者聯繫,後續筆者就將與盤後資訊與交易資訊做串接應用。

參考資料: