[記錄] 用 php+MySql 編寫 Line 機器人

Line 機器人現在越來越廣泛應用,工作上也有聽到長官想要同事去研究來寫。雖然後來不了了之XD 因為訊息量太大需要$$業主跟部門都不想出!不過因為沒有真的需要,所以自己就一直都沒有去研究。

然後 ami 大大發了這個噗
https://www.plurk.com/p/ntd5bn

01
ami大大的需求!

剛好是假日,我就開始研究了XD

ami 大大的需求有四項:

  1. 輸入日期補登字數功能
  2. 每天自動提醒是否填坑功能(這個比較難,可能要研究一下)
  3. 最好可以自訂輸入的google表單的功能(這個不難,難在表單要開權限給程式端,所以好像也沒辦法給使用者輸入…)
  4. 讚美句+++ XDDD

不過因為我打算用 php+mysql 來寫機器人的反應動作,所以需求的第三項就可以跳過了XD

因為我幾乎從頭到尾也都是參考網路上的教學,所以這篇不會有太詳細的內容,但會記錄我參考的網址,還有遇到的一些問題的解決方法。

寫這個機器人,最重要的就是(1) 申請、設定機器人 (2) 當用戶輸入內容之後,要把資料接收到然後進行分析,再寫入資料庫 (3) 設定排程去主動發送訊息。這篇大概就是以這幾個步驟為主

申請、設定機器人

其實這個應該不大需要講,主要是從 https://developers.line.biz/console/ 開始進行註冊。這部份就不多說,網路上找找都會有很多申請方法!

資料分析

機器人資料分析的 Webhook 需要放在 SSL 的環境中,因為我自己的網站空間是有 SSL 的,所以就直接利用。如果有網頁空間但沒有 SSL ,可以考慮免費的 Let’s Encrypt

這次寫接收資訊最有用的一篇,是:Line Bot 開發教學,基礎範例程式碼 (PHP) – 輕量版 LINEBotTiny.php

應該說,作者的 git hub 上有提供了完整範例的檔案,只要替換掉自己機器人的 Channel access token 跟 Channel secret,基本上就可以運作了。非常感謝作者!讓我省了很多摸索的時間!而且範例中提供了很多種類的回應方式,都可以直接參考!

因為這個機器人主要是要收到用戶輸入字數,然後要把用戶跟字數都存到資料庫中。字數還好,用戶 id 這個就比較難取得了。

範例中有對應接受 event 的程式碼,於是我就把接收到的訊息抓下來,看一下究竟怎麼抓到用戶 id。

抓到的內容範例如下圖:(也可以參考公式API資料:LINE Developers

01
收到的訊息內容(點擊可放大)

主要就有看到一行是:”userId”: “U4af4980629…” 在 source 節點下。所以照著程式範例的寫法,取得 ID 的程式碼就是:

$getsource = $event[‘source’];
$usr_id = $getsource[‘userId’];

請放在 $client = new LINEBotTiny($channelAccessToken, $channelSecret); 這行之後。

取得這個之後就沒什麼問題了!有 userId 之後,就可以根據不同用戶記錄資料,並且回應各自的資料統計回去給用戶。

資料庫的設定也跳過不說。接下來是分析用戶輸入的資料,基本上考慮到電腦版也方便使用(尤其大家寫稿都用電腦),所以圖形選單或是按鈕就不考慮了(電腦版不支援),所以基本上幾乎都是使用到文字訊息的部份。

先決定好需要存哪些資訊,然後設定好一些制式的指令,比如說要記錄今天的字數,我的設定是「今日 142」,要補登的話是「補 2020-05-03 100」,怎麼設定就是各人喜好,我是把「動作」放第一個,後面才是自己決定的參數內容。

接收到文字訊息事件之後,要分析資料內容就不難了,就是切切貼貼比對比對而已,會寫 php 的人對這個都沒難度,不然就是用 google 也可以找到方法!當然別忘了也要寫防呆的訊息,避免亂測試造成資料庫存了一堆垃圾,影響到後續的統計資料等等。

排程發訊息

需求中有想要每天定時發提醒記錄、寫文的訊息,這個功能分成兩部分:(1) 主動發訊息給所有人 (2) 定時 

因為決定也是要用 php 去執行發訊息這個功能(這樣才方便取得自己資料庫記錄的所有人的 userId),網路上找找找之後參考了這篇:用 PHP 實現 Line Message API 接收系統訊息

有看的朋友應該就會發現,是的,這位作者也有範例提供!我拿來參考的是中後半段的 push.php。這次要改的地方比較多,把原本取得 Id 的方式改成我自己的資料庫,並存成 array,組合訊息也依照時間不同(每天兩次,早上跟晚上),要另外擷取各個用戶前一天跟當天的字數登記總和。

不過這倒是不算難,因為是獨立的 php 程式,就跟之前的程式放一起,使用已經寫好的 function 就可以了。

難的是「如何能夠排程執行這隻 php」。這個花了我好多時間去做測試!找了很久,最後發現網站空間中有提供crontab 這個功能,這是利用網站的伺服器定期執行指令的功能。

這雖然在 cPanel 上有設定介面,但要輸入的指令我也是測試了好久,最後終於測試出來是:「wget -q 要執行的網頁網址」,定時的時間設定我的空間是有介面用選的。

wget 其實是抓取網頁資料,但這時候也等於是執行該網頁內容,取巧來使用。指令的參數可以參考這個頁面:wget 指令Linux – crontab排程啟動本地PHP網頁

01
我的網頁空間中的 Crontab job 設定畫面

 

其他及最後成果

記錄一下其他算滿有用的資料:

line sticker 編號:https://devdocs.line.me/files/sticker_list.pdf
可以使用的預設貼圖就這些,要填寫的話要參考這個。

在輸入文字訊息回應之後,我還加了隨機鼓勵話語跟隨機的貼圖,覺得很難被發現但玩得很愉快。

我的成果圖如下,接下來就是等一些朋友幫我測試之後就開給朋友用啦!

這篇其實也真的沒寫到什麼,大概就是把我覺得有用的參考網頁給記錄下來,下次要改的話就可以使用了!

[記錄] 用 php+MySql 編寫 Line 機器人
測試的畫面
訂閱
提醒
guest

14 Comments
最舊
最新 最多投票
Inline Feedbacks
View all comments
Hank

想請問,最近剛接觸line bot用php開發,今日 100 或是 補2020…這種的關鍵字,資料和動作之間是怎麼用程式去區隔的呢?

Hank

哦!大概了解!那想請問連接php資料庫的程式你是寫在每個function裡還是直接寫在example.php那個統一連接呢?另外想問方便留甚麼聯絡方式能更即時的詢問你嗎?(FB、LINE等等)可能會想要多跟你請教程式的問題

Hank

好的,我剛剛在測試的時候發現有錯誤,給你看一下我多加的這幾段程式碼,再麻煩你幫我看一下!

localhost.png
Hank

這是編譯錯誤的

userid.png
Hank

好的,我目前打算先把整體LINE的功能做完再來研究資料庫QQ,請問我照著你的切割下去分析之後,為甚麼會沒有回覆呢?

$strMsg = $message['text']; //取得輸入的字串
$str_sec = explode(" ",trim($strMsg)); //切成array(用" "隔開)
$msg_header = $str_sec[0];//首字
if (strtolower($$msg_header['text']) == "tdee"){
  $client->replyMessage(array(
    'replyToken' => $event['replyToken'],
    'messages' => array(
      array(
        'type' => 'text', // 訊息類型 (文字)
        'text' => '請輸入年齡' // 回復訊息
      )
    )
  ));
}
Hank

不好意思,我解決了!但我還是想問一下 我把$msg_header在丟回去給$message[‘text’],雖然是成功,會不會有bug的疑慮呢?

Hank

請問一下這兩段取得userID的程式,抓出來的id是字串嗎?

$getsource = $event[‘source’];
$usr_id = $getsource[‘userId’];

我在測試寫進資料庫的時候會出現錯誤,後來我把寫進資料庫的程式碼單獨拉出來,
user id我用隨便一個字串去代替,執行後是可以成功新增資料的,所以我在想是不是userID格式的問題
我後來也有測試用$usr_id去作加好友之後馬上回覆,也是跑不出來,請問怎麼解決呢?
下面是我寫進資料庫的程式碼

$client = new LINEBotTiny($channelAccessToken, $channelSecret);
$getsource = $event['source'];
$usr_id = $getsource['userId'];
require_once 'dbtools.inc.php';
$link = create_connection();//建立資料連結
$sql = "SELECT * FROM user where linid = '{$usr_id}'";
$result = execute_sql($link, "energey3_db", $sql);
mysqli_error($link);
if(mysqli_num_rows($result) > 0)
{
	mysqli_free_result($result);
}
else
{
	mysqli_free_result($result);
	
	$sql = "INSERT INTO user (lineid) VALUES('{$usr_id}')";
	$result = execute_sql($link, "energey3_db", $sql);
}
mysqli_close($link);
Hank
PHP Warning:  mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in /home2/energey3/public_html/example_bot.php on line 57

PHP Warning:  mysqli_free_result() expects parameter 1 to be mysqli_result, boolean given in /home2/energey3/public_html/example_bot.php on line 63

 Request failed: {"message":"The request body has 1 error(s)","details":[{"message":"May not be empty","property":"messages[0].text"}]}

第一個和第二個錯誤是寫進資料庫出現的錯誤
第三個是我測試用$usr_id去在加入好友這個動作時回覆userID