[Line Bot] Messaging Api 回話機器人 (PHP)

主程式

/* 輸入申請的Line Developers 資料  */
	$channel_id = "{Channel ID}";
	$channel_secret = "{Channel Secret}";
	$channel_access_token = "{Channel Access Token}";

	$myURL = "https://Your Domain/update/"


//  當有人發送訊息給bot時 我們會收到的json
// 	{
// 	  "events": 
// 	  [
// 		  {
// 			"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
// 			"type": "message",
// 			"timestamp": 1462629479859,
// 			"source": {
// 				 "type": "user",
// 				 "userId": "U206d25c2ea6bd87c17655609a1c37cb8"
// 			 },
// 			 "message": {
// 				 "id": "325708",
// 				 "type": "text",
// 				 "text": "Hello, world"
// 			  }
// 		  }
// 	  ]
// 	}
	 
	 
	// 將收到的資料整理至變數
	$receive = json_decode(file_get_contents("php://input"));
	
	// 讀取收到的訊息內容
	$text = $receive->events[0]->message->text;
	
	// 讀取訊息來源的類型 	[user, group, room]
	$type = $receive->events[0]->source->type;
	
	// 由於新版的Messaging Api可以讓Bot帳號加入多人聊天和群組當中
	// 所以在這裡先判斷訊息的來源
	if ($type == "room")
	{
		// 多人聊天 讀取房間id
		$from = $receive->events[0]->source->roomId;
	} 
	else if ($type == "group")
	{
		// 群組 讀取群組id
		$from = $receive->events[0]->source->groupId;
	}
	else
	{
		// 一對一聊天 讀取使用者id
		$from = $receive->events[0]->source->userId;
	}
	
	// 讀取訊息的型態 [Text, Image, Video, Audio, Location, Sticker]
	$content_type = $receive->events[0]->message->type;
	
	// 準備Post回Line伺服器的資料 
	$header = ["Content-Type: application/json", "Authorization: Bearer {" . $channel_access_token . "}"];
	
	// 回覆訊息
	reply($content_type, $text);

發送訊息Function

function reply($content_type, $message) {
	 
	 	global $header, $from, $receive;
	 	
		$url = "https://api.line.me/v2/bot/message/push";
		
		$data = ["to" => $from, "messages" => array(["type" => "text", "text" => $message])];
		
		switch($content_type) {
		
			case "text" :
				$content_type = "文字訊息";
				$data = ["to" => $from, "messages" => array(["type" => "text", "text" => $message])];
				break;
				
			case "image" :
				$content_type = "圖片訊息";
				$message = getObjContent("jpeg");   // 讀取圖片內容
				$data = ["to" => $from, "messages" => array(["type" => "image", "originalContentUrl" => $message, "previewImageUrl" => $message])];
				break;
				
			case "video" :
				$content_type = "影片訊息";
				$message = getObjContent("mp4");   // 讀取影片內容
				$data = ["to" => $from, "messages" => array(["type" => "video", "originalContentUrl" => $message, "previewImageUrl" => $message])];
				break;
				
			case "audio" :
				$content_type = "語音訊息";
				$message = getObjContent("mp3");   // 讀取聲音內容
				$data = ["to" => $from, "messages" => array(["type" => "audio", "originalContentUrl" => $message[0], "duration" => $message[1]])];
				break;
				
			case "location" :
				$content_type = "位置訊息";
				$title = $receive->events[0]->message->title;
				$address = $receive->events[0]->message->address;
				$latitude = $receive->events[0]->message->latitude;
				$longitude = $receive->events[0]->message->longitude;
				$data = ["to" => $from, "messages" => array(["type" => "location", "title" => $title, "address" => $address, "latitude" => $latitude, "longitude" => $longitude])];
				break;
				
			case "sticker" :
				$content_type = "貼圖訊息";
				$packageId = $receive->events[0]->message->packageId;
				$stickerId = $receive->events[0]->message->stickerId;
				$data = ["to" => $from, "messages" => array(["type" => "sticker", "packageId" => $packageId, "stickerId" => $stickerId])];
				break;
				
			default:
				$content_type = "未知訊息";
				break;
	   	}
		
		$context = stream_context_create(array(
		"http" => array("method" => "POST", "header" => implode(PHP_EOL, $header), "content" => json_encode($data), "ignore_errors" => true)
		));
		file_get_contents($url, false, $context);
	}

 取得檔案內容(適用於video、audio、image)

function getObjContent($filenameExtension){
		
	global $channel_access_token, $receive;
	
	$objID = $receive->events[0]->message->id;
	$url = 'https://api.line.me/v2/bot/message/'.$objID.'/content';
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HTTPHEADER, array(
		'Authorization: Bearer {' . $channel_access_token . '}',
	));
	
	$json_content = curl_exec($ch);
	curl_close($ch);

	if (!$json_content) {
		return false;
	}
	
	$fileURL = './update/'.$objID.'.'.$filenameExtension;
	$fp = fopen($fileURL, 'w');
	fwrite($fp, $json_content);
	fclose($fp);
		
	if ($filenameExtension=="mp3"){
	    //使用getID3套件分析mp3資訊
		require_once("getID3/getid3/getid3.php");
		$getID3 = new getID3;
		$fileData = $getID3->analyze($fileURL);
		//$audioInfo = var_dump($fileData);
		$playSec = floor($fileData["playtime_seconds"]);
		$re = array($myURL.$objID.'.'.$filenameExtension, $playSec*1000);
		return $re;
	}
	return $myURL.$objID.'.'.$filenameExtension;
}

完整程式碼:GitHub

Share This:

13 則迴響

  1. 您好,感謝您的分享,不過我使用這份code,發送密語到該機器人,他並沒有任何回應,請問是什麼原因?
    p.s我在webhook url那裡verify有過

    chad
  2. 對不起.我有申請了一個網站了.HTTPS也有.但是我直接把您的檔案發佈到我的網站空間去.
    也設定好.三個參數.
    $channel_id =
    $channel_secret =
    $channel_access_token
    在留言給LINE機器人時,看LINE有登入的記錄.但是都不回應.可否跟您請益.小弟已經研究好久了.都試不出來.不知那有問題.

    董鋒義
    1. 你可以先在你LINE developers管理平台(就是你設定callback網址的地方)看到Webhook URL的區塊 右邊有個VERIFY的按鈕 可以先檢查看看CALLBACK有沒有問題
      先確定是不是這個問題這樣我會比較好知道你的狀況 希望有幫助到您 歡迎繼續討論 =)

      杰哥不要
    1. $myURL = “https://Your Domain/update/”
      這行程式碼你必須先完成兩間事情
      1.在你網站根目錄中,必須要有update這個資料夾
      2.要把你的網域名稱取代掉,假設你的網域名稱為XXX.com,那你的這行程式碼就要改成這樣:$myURL = “https://XXX.com/update/”

      所以Domin是你的網域名稱,而update才是你要新增的資料夾喔

      杰哥不要
  3. 您好,感謝你的分享。
    想請教php的Linebot有沒有辦法做到「一問一答」的效果呢?

    類似這樣:
    user:「我要留言。」
    bot:「請輸入你的大名。」

    user:「王大明」
    bot:「請輸入你的留言內容。」

    user:「……(略)」
    bot:「留言程序完成,感謝使用。」

    我想到的一個方式是:設置一個變數來記錄問到第幾個問題。
    但是似乎每一次bot被啟動,變數都會被重置呢。

    R
    1. 我沒有做過這個功能,但如果你有將對話紀錄記錄到資料庫中的話,你只要用user_id就可以查出該用戶之前傳過的對話,然後加以判斷就可以做到你所說的功能了

      杰哥不要

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *