ส่งต่อ Webhook Event จาก Line ไปยัง Webhook ใน DialogFlow

02 June 2019 By Ninenik Narkdee
line messaging api line dialogflow forward webhook line bot sdk

คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ line messaging api line dialogflow forward webhook line bot sdk



ในตอนท้ายบทความที่ผ่านมา เราได้เกริ่นถึงแนวทางการใช้งาน Webhook URL 
ของ DialogFlow สำหรับใช้ในการจัดการข้อมูลประเภทข้อความ 
ที่ผู้ใช์พิมพ์เข้ามา กับ Webhook URL ที่เราใช้งาน Line Messaging API โดยมีแนวคิด
ที่ว่า เราต้องการใช้งาน DialogFlow จัดการข้อมูลการสนทนาระหว่างผู้ใช้กับ Bot ในลักษณะ
ของข้อมูลที่เป็นข้อความเป็นหลัก ส่วนเงื่อนไขข้อมูลอื่นๆ รวมถึงข้อความบางส่วนเราก็จะจัดการ
ด้วย Line bot SDK ที่ฝั่ง Server เหมือนเดิม (ทบทวนตอนที่แล้ว http://niik.in/925)
 
    จึงเป็นที่มาของเงื่อนไขตามลำดับดังนี้
       -  ผู้ใช้ส่งข้อความมายัง bot แล้ว 
       -  Line จะส่ง Webhook Event มาให้เราจัดการ ที่ Webhook URL ที่เรากำหนด 
       -  เราทำการตรวจสอบประเภทข้อมูลว่าเป็นข้อความหรือไม่ และไม่ใช้ข้อความในเงื่อนไขเพิ่มเติม
            - ถ้าเป็นข้อความ และไม่ใช่ข้อความในเงื่อนไขเพิ่มเติม
                ทำการส่งต่อ Webhook Event ไปยัง Webhook URL ของ DialogFlow เพื่อใช้งาน Agent 
                ในการตอบกลับ
            - ถ้าไม่ใช่ข้อความ หรือเป็นข้อความในเงื่อนไขเพิ่มเติม
                ให้ทำงานตามรูปแบบที่กำหนดใน Line Messaging API ตามการใช้งานที่ต้องการ
 
 

ค่า Headers และ Body จาก Line Server

    เนื่องจาก เราจะทำการส่งต่อค่าต่างๆ ที่ Line ส่งมาให้ เมื่อเกิด Webhook Event ดังนั้น ก่อนอื่นเราต้องรู้ก่อนว่า
Line ส่งข้อมูลอะไรมาให้เรา โดยใช้คำสั่ง PHP ดังนี้
$headers = getallheaders(); // ได้ค่า array ของส่วน Headers ทั้งหมดที่ Line ส่งมา
file_put_contents('headers.txt',json_encode($headers, JSON_PRETTY_PRINT)); 
file_put_contents('body.txt',file_get_contents('php://input')); // ส่วนของ body
    คำสั่งข้างต้น เราทำการสร้างไฟล์ headers.txt เพื่อเก็บค่า headers ที่ Line ส่งกลับมา
เราจะได้ไฟล์ลักษณะดังนี้ 
 
    ไฟล์ headers.txt
{
  "X-Line-Signature": "GjykqJLOWeD27c=",
  "Content-Type": "application/json;charset=UTF-8",
  "Cookie": "PHPSESSID=cs22q9d272vn0dm50um9m7",
  "Content-Length": "284",
  "Host": "www.ninenik.com",
  "Accept": "*/*",
  "User-Agent": "LineBotWebhook/1.0"
}
    สังเกตที่ค่า Host จะเป็นค่า Domain ของ server ที่เรากำหนด Webhook URL ดังนั้น ถ้าเราต้องทำการส่งต่อค่าเเหล่านี้
ไปยัง Webhook URL ของ DialogFlow เราต้องเปลี่ยนค่า Host ให้เป็น bots.dialogflow.com ก่อนถึงจะส่งค่าไป
 
    สำหรับไฟล์ body.txt จะเก็บส่วนของข้อมูล ที่ Line ส่งมาให้ หรือก็คือ Webhook Event จะได้ค่าประมาณนี้
 
    ไฟล์ body.txt
{
  "events": [
    {
      "type": "message",
      "replyToken": "65aa87f20aca4f77b51b81622fcf156f",
      "source": {
        "userId": "ค่า userID ของเรา",
        "type": "user"
      },
      "timestamp": 1559411554903,
      "message": {
        "type": "text",
        "id": "9968633708066",
        "text": "หวัดดี"
      }
    }
  ],
  "destination": "U7f0dae77aa11885f8df4b7c7c8774b1e"
}
 
    ในส่วนของ body ที่ Line ส่งกลับมาเมื่อเราส่งข้อความไปยัง bot จะเป็นลักษณะข้อความ JSON Data ตามรูปแบบด้านบน
ดังนั้น เราสามารถส่งต่อข้อความนี้ไปยัง Webhook ของ DialogFlow โดยไม่ต้องปรับแก้อะไร
 
 
 

การ Forward Webhook Event

    เมื่อเราได้แนวทางการส่งต่อ Webhook Event แล้วในขั้นตอนต่อไป ก็คือวิธีการส่งต่อ Webhook Event ที่ได้รับจาก Line
Server ไปยัง Webhook URL ของ DialogFlow ดังนี้
    ให้เราแก้ไขในส่วนของไฟล์ webhook ในที่นี้คือไฟล์ bot_action.php     
    (ทบทวนจากเนื้อหาเกี่ยวกับ Line Dev หรือ http://niik.in/897)
 
    จะขอจัดไฟล์ bot_action.php ให้แสดงเฉพาะส่วนจัดการ Event ประเภทต่างๆ ส่วนโค้ดประกอบอื่นๆ สามารถดูได้จากบทความ
ที่เกี่ยวข้องผ่านๆ มา
 
    ไฟล์ bot_action.php
<?php
///////////// ส่วนของการเรียกใช้งาน class ผ่าน namespace
use LINE\LINEBot;
use LINE\LINEBot\HTTPClient;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot\Event;
use LINE\LINEBot\Event\BaseEvent;
use LINE\LINEBot\Event\MessageEvent;
use LINE\LINEBot\Event\AccountLinkEvent;
use LINE\LINEBot\Event\MemberJoinEvent; 
use LINE\LINEBot\MessageBuilder;
use LINE\LINEBot\MessageBuilder\TextMessageBuilder;
use LINE\LINEBot\MessageBuilder\StickerMessageBuilder;
use LINE\LINEBot\MessageBuilder\ImageMessageBuilder;
use LINE\LINEBot\MessageBuilder\LocationMessageBuilder;
use LINE\LINEBot\MessageBuilder\AudioMessageBuilder;
use LINE\LINEBot\MessageBuilder\VideoMessageBuilder;
use LINE\LINEBot\ImagemapActionBuilder;
use LINE\LINEBot\ImagemapActionBuilder\AreaBuilder;
use LINE\LINEBot\ImagemapActionBuilder\ImagemapMessageActionBuilder ;
use LINE\LINEBot\ImagemapActionBuilder\ImagemapUriActionBuilder;
use LINE\LINEBot\MessageBuilder\Imagemap\BaseSizeBuilder;
use LINE\LINEBot\MessageBuilder\ImagemapMessageBuilder;
use LINE\LINEBot\MessageBuilder\MultiMessageBuilder;
use LINE\LINEBot\TemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\DatetimePickerTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\MessageTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\PostbackTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\UriTemplateActionBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateMessageBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ButtonTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\CarouselTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\CarouselColumnTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ConfirmTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ImageCarouselTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ImageCarouselColumnTemplateBuilder;
use LINE\LINEBot\QuickReplyBuilder;
use LINE\LINEBot\QuickReplyBuilder\QuickReplyMessageBuilder;
use LINE\LINEBot\QuickReplyBuilder\ButtonBuilder\QuickReplyButtonBuilder;
use LINE\LINEBot\TemplateActionBuilder\CameraRollTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\CameraTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\LocationTemplateActionBuilder;
use LINE\LINEBot\RichMenuBuilder;
use LINE\LINEBot\RichMenuBuilder\RichMenuSizeBuilder;
use LINE\LINEBot\RichMenuBuilder\RichMenuAreaBuilder;
use LINE\LINEBot\RichMenuBuilder\RichMenuAreaBoundsBuilder;
use LINE\LINEBot\Constant\Flex\ComponentIconSize;
use LINE\LINEBot\Constant\Flex\ComponentImageSize;
use LINE\LINEBot\Constant\Flex\ComponentImageAspectRatio;
use LINE\LINEBot\Constant\Flex\ComponentImageAspectMode;
use LINE\LINEBot\Constant\Flex\ComponentFontSize;
use LINE\LINEBot\Constant\Flex\ComponentFontWeight;
use LINE\LINEBot\Constant\Flex\ComponentMargin;
use LINE\LINEBot\Constant\Flex\ComponentSpacing;
use LINE\LINEBot\Constant\Flex\ComponentButtonStyle;
use LINE\LINEBot\Constant\Flex\ComponentButtonHeight;
use LINE\LINEBot\Constant\Flex\ComponentSpaceSize;
use LINE\LINEBot\Constant\Flex\ComponentGravity;
use LINE\LINEBot\MessageBuilder\FlexMessageBuilder;
use LINE\LINEBot\MessageBuilder\Flex\BubbleStylesBuilder;
use LINE\LINEBot\MessageBuilder\Flex\BlockStyleBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ContainerBuilder\BubbleContainerBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ContainerBuilder\CarouselContainerBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\BoxComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\ButtonComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\IconComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\ImageComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\SpacerComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\FillerComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\SeparatorComponentBuilder;
use LINE\LINEBot\MessageBuilder\Flex\ComponentBuilder\TextComponentBuilder;

// ส่วนของการทำงาน
if(!is_null($events)){

	//////////////////////////////// Join event ////////////////////////////////
	// ถ้า bot ถูก invite เพื่อเข้า Join Event ให้ bot ส่งข้อความใน GROUP ว่าเข้าร่วม GROUP แล้ว
	if(!is_null($eventJoin)){
		$textReplyMessage = "ขอเข้าร่วมด้วยน่ะ $sourceType ID:: ".$sourceId;
		$replyData = new TextMessageBuilder($textReplyMessage);                 
	}
	
	//////////////////////////////// Leave event ////////////////////////////////	
	// ถ้า bot ออกจาก สนทนา จะไม่สามารถส่งข้อความกลับได้ เนื่องจากไม่มี replyToken
	if(!is_null($eventLeave)){

	}	
	
	/////////////////////////////// Follow event /////////////////////////////////	
	// ถ้า bot ถูกเพื่มเป้นเพื่อน หรือถูกติดตาม หรือ ยกเลิกการ บล็อก
	if(!is_null($eventFollow)){
        $textReplyMessage = "ขอบคุณที่เป็นเพื่อน และติดตามเรา";        
        $replyData = new TextMessageBuilder($textReplyMessage);     			
	}
	
	///////////////////////////// Unfollow event ///////////////////////////////////	
	// ถ้า bot ถูกบล็อก หรือเลิกติดตาม จะไม่สามารถส่งข้อความกลับได้ เนื่องจากไม่มี replyToken
	if(!is_null($eventUnfollow)){

	}		
	
	///////////////////////////// Member join event ///////////////////////////////////	
	// ถ้ามีสมาชิกคนอื่น เข้ามาร่วมใน room หรือ group 
	// room คือ สมมติเราคุยกับ คนหนึ่งอยู่ แล้วเชิญคนอื่นๆ เข้ามาสนทนาด้วย จะกลายเป็นห้องใหม่
	// group คือ กลุ่มที่เราสร้างไว้ มีชื่อกลุ่ม แล้วเราเชิญคนอื่นเข้ามาในกลุ่ม เพิ่มร่วมสนทนาด้วย
	if(!is_null($eventMemberJoined)){
			$arr_joinedMember = $eventObj->getEventBody();
			$joinedMember = $arr_joinedMember['joined']['members'][0];
			if(!is_null($groupId) || !is_null($roomId)){
				if($eventObj->isGroupEvent()){
					foreach($joinedMember as $k_user=>$v_user){
						if($k_user=="userId"){
							$joined_userId = $v_user;
						}
					}						
					$response = $bot->getGroupMemberProfile($groupId, $joined_userId);
				}
				if($eventObj->isRoomEvent()){
					foreach($joinedMember as $k_user=>$v_user){
						if($k_user=="userId"){
							$joined_userId = $v_user;
						}
					}					
					$response = $bot->getRoomMemberProfile($roomId, $joined_userId);    
				}
			}else{
				$response = $bot->getProfile($userId);
			}
			if ($response->isSucceeded()) {
				$userData = $response->getJSONDecodedBody(); // return array     
				// $userData['userId']
				// $userData['displayName']
				// $userData['pictureUrl']
				// $userData['statusMessage']
				$textReplyMessage = 'สวัสดีครับ คุณ '.$userData['displayName'];     
			}else{
				$textReplyMessage = 'สวัสดีครับ ยินดีต้อนรับ';
			}
//        $textReplyMessage = "ยินดีต้อนรับกลับมาอีกครั้ง ".json_encode($joinedMember);
        $replyData = new TextMessageBuilder($textReplyMessage);     				
	}

	///////////////////////////// Member leave event ///////////////////////////////////	
	// ถ้ามีสมาชิกคนอื่น ออกจากก room หรือ group จะไม่สามารถส่งข้อความกลับได้ เนื่องจากไม่มี replyToken
	if(!is_null($eventMemberLeft)){
	
	}	

	//////////////////////////////// Account link event ////////////////////////////////
	// ถ้ามีกาาเชื่อมกับบัญชี LINE กับระบบสมาชิกของเว็บไซต์เรา
	if(!is_null($eventAccountLink)){
		// หลักๆ ส่วนนี้ใช้สำรหบัเพิ่มความภัยในการเชื่อมบัญตี LINE กับระบบสมาชิกของเว็บไซต์เรา 
        $textReplyMessage = "AccountLink ทำงาน ".$replyToken." Nonce: ".$eventObj->getNonce();
        $replyData = new TextMessageBuilder($textReplyMessage);   	  					
	}

	////////////////////////////// Postback Event //////////////////////////////////			
    // ถ้าเป็น Postback Event
    if(!is_null($eventPostback)){
        $dataPostback = NULL;
        $paramPostback = NULL;
        // แปลงข้อมูลจาก Postback Data เป็น array
        parse_str($eventObj->getPostbackData(),$dataPostback);
        // ดึงค่า params กรณีมีค่า params
        $paramPostback = $eventObj->getPostbackParams();
	
        // ทดสอบแสดงข้อความที่เกิดจาก Postaback Event
        $textReplyMessage = "ข้อความจาก Postback Event Data : DataPostback = ";        
        $textReplyMessage.= json_encode($dataPostback);
        $textReplyMessage.= " ParamPostback = ".json_encode($paramPostback);
        $replyData = new TextMessageBuilder($textReplyMessage);     
    }
	
	//////////////////////////// Message event //////////////////////////////////
    // ถ้าเป้น Message Event 
    if(!is_null($eventMessage)){
		
		// สร้างตัวแปรเก็ยค่าประเภทของ Message จากทั้งหมด 7 ประเภท
		$typeMessage = $eventObj->getMessageType();  
		//  text | image | sticker | location | audio | video | file  
		// เก็บค่า id ของข้อความ
		$idMessage = $eventObj->getMessageId();  		
		
		
		
		// ถ้าเป็นข้อความ
		if($typeMessage=='text'){
			$userMessage = $eventObj->getText(); // เก็บค่าข้อความที่ผู้ใช้พิมพ์
			
			switch($userMessage){
				case	 "test":
					$textReplyMessage = " คุณไม่ได้พิมพ์ ค่า ตามที่กำหนด";
					$replyData = new TextMessageBuilder($textReplyMessage);     				
					break;
				default:
					$url = "https://bots.dialogflow.com/line/<Agent-ID>/webhook";
					$headers = getallheaders();
		//			file_put_contents('headers.txt',json_encode($headers, JSON_PRETTY_PRINT));			
		//			file_put_contents('body.txt',file_get_contents('php://input'));
					$headers['Host'] = "bots.dialogflow.com";
					$json_headers = array();
					foreach($headers as $k=>$v){
						$json_headers[]=$k.":".$v;
					}
					$inputJSON = file_get_contents('php://input');
					// ส่วนของการส่งการแจ้งเตือนผ่านฟังก์ชั่น cURL
					$ch = curl_init();
					curl_setopt( $ch, CURLOPT_URL, $url);
					curl_setopt( $ch, CURLOPT_POST, 1);
					curl_setopt( $ch, CURLOPT_BINARYTRANSFER, true);
					curl_setopt( $ch, CURLOPT_POSTFIELDS, $inputJSON);
					curl_setopt( $ch, CURLOPT_HTTPHEADER, $json_headers);
					curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2); // 0 | 2 ถ้าเว็บเรามี ssl สามารถเปลี่ยนเป้น 2
					curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 1); // 0 | 1 ถ้าเว็บเรามี ssl สามารถเปลี่ยนเป้น 1
					curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
					curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
					$result = curl_exec( $ch );
					curl_close( $ch );
					exit;				
					break;
			}
		}
		
		
		
		// ถ้าเป็น image
		if($typeMessage=='image'){

		}				
		// ถ้าเป็น audio

		if($typeMessage=='audio'){

		}		
		// ถ้าเป็น video
		if($typeMessage=='video'){

		}	
		// ถ้าเป็น file
		if($typeMessage=='file'){
			$FileName = $eventObj->getFileName();
			$FileSize = $eventObj->getFileSize();
		}			
			
		// ถ้าเป็น image หรือ audio หรือ video หรือ file และต้องการบันทึกไฟล์
		if(preg_match('/image|audio|video|file/',$typeMessage)){			
			$responseMedia = $bot->getMessageContent($idMessage);
			if ($responseMedia->isSucceeded()) {
				// คำสั่ง getRawBody() ในกรณีนี้ จะได้ข้อมูลส่งกลับมาเป็น binary 
				// เราสามารถเอาข้อมูลไปบันทึกเป็นไฟล์ได้
				$dataBinary = $responseMedia->getRawBody(); // return binary
				// ดึงข้อมูลประเภทของไฟล์ จาก header
				$fileType = $responseMedia->getHeader('Content-Type');    
				switch ($fileType){
					case (preg_match('/^application/',$fileType) ? true : false):
//						$fileNameSave = $FileName; // ถ้าต้องการบันทึกเป็นชื่อไฟล์เดิม
						$arr_ext = explode(".",$FileName);
						$ext = array_pop($arr_ext);
						$fileNameSave = time().".".$ext;       						
						break;					
					case (preg_match('/^image/',$fileType) ? true : false):
						list($typeFile,$ext) = explode("/",$fileType);
						$ext = ($ext=='jpeg' || $ext=='jpg')?"jpg":$ext;
						$fileNameSave = time().".".$ext;
						break;
					case (preg_match('/^audio/',$fileType) ? true : false):
						list($typeFile,$ext) = explode("/",$fileType);
						$fileNameSave = time().".".$ext;                        
						break;
					case (preg_match('/^video/',$fileType) ? true : false):
						list($typeFile,$ext) = explode("/",$fileType);
						$fileNameSave = time().".".$ext;                                
						break;                                                      
				}
				$botDataFolder = 'botdata/'; // โฟลเดอร์หลักที่จะบันทึกไฟล์
				$botDataUserFolder = $botDataFolder.$userId; // มีโฟลเดอร์ด้านในเป็น userId อีกขั้น
				if(!file_exists($botDataUserFolder)) { // ตรวจสอบถ้ายังไม่มีให้สร้างโฟลเดอร์ userId
					mkdir($botDataUserFolder, 0777, true);
				}   
				// กำหนด path ของไฟล์ที่จะบันทึก
				$fileFullSavePath = $botDataUserFolder.'/'.$fileNameSave;
//				file_put_contents($fileFullSavePath,$dataBinary); // เอา comment ออก ถ้าต้องการทำการบันทึกไฟล์
				$textReplyMessage = "บันทึกไฟล์เรียบร้อยแล้ว $fileNameSave";
				$replyData = new TextMessageBuilder($textReplyMessage);
//				$failMessage = json_encode($fileType);				
//				$failMessage = json_encode($responseMedia->getHeaders());
//				$replyData = new TextMessageBuilder($failMessage);  					
			}else{
//				$failMessage = json_encode($idMessage.' '.$responseMedia->getHTTPStatus() . ' ' . $responseMedia->getRawBody());
// 				$failMessage  = json_encode((array)$eventObj); // ดูโครงสร้างข้อมูล
				$failMessage = "ไม่ต้องส่งข้อความใดๆ กลับ";
				$replyData = new TextMessageBuilder($failMessage);  		
				exit;
			}
		}
		// ถ้าเป็น sticker
		if($typeMessage=='sticker'){
			$packageId = $eventObj->getPackageId();
			$stickerId = $eventObj->getStickerId();
			$textReplyMessage = 'สวัสดีครับ คุณ '.$typeMessage;         
			$replyData = new TextMessageBuilder($textReplyMessage);      						
		}
		// ถ้าเป็น location
		if($typeMessage=='location'){
			$locationTitle = $eventObj->getTitle();
			$locationAddress = $eventObj->getAddress();
			$locationLatitude = $eventObj->getLatitude();
			$locationLongitude = $eventObj->getLongitude();
			$textReplyMessage = 'สวัสดีครับ คุณ '.$typeMessage;         
			$replyData = new TextMessageBuilder($textReplyMessage);      			
		}       
		
	}

}
?>
 
    เราจะดูเฉพาะในส่วนของ Message Event และดู MessageType ที่เป็น text
 
<?php

// ถ้าเป็นข้อความ
if($typeMessage=='text'){
	$userMessage = $eventObj->getText(); // เก็บค่าข้อความที่ผู้ใช้พิมพ์
	
	switch($userMessage){
		case	 "test":
			$textReplyMessage = " คุณไม่ได้พิมพ์ ค่า ตามที่กำหนด";
			$replyData = new TextMessageBuilder($textReplyMessage);     				
			break;
		default:
			$url = "https://bots.dialogflow.com/line/<Agent-ID>/webhook";
			$headers = getallheaders();
//			file_put_contents('headers.txt',json_encode($headers, JSON_PRETTY_PRINT));			
//			file_put_contents('body.txt',file_get_contents('php://input'));
			$headers['Host'] = "bots.dialogflow.com";
			$json_headers = array();
			foreach($headers as $k=>$v){
				$json_headers[]=$k.":".$v;
			}
			$inputJSON = file_get_contents('php://input');
			// ส่วนของการส่งการแจ้งเตือนผ่านฟังก์ชั่น cURL
			$ch = curl_init();
			curl_setopt( $ch, CURLOPT_URL, $url);
			curl_setopt( $ch, CURLOPT_POST, 1);
			curl_setopt( $ch, CURLOPT_BINARYTRANSFER, true);
			curl_setopt( $ch, CURLOPT_POSTFIELDS, $inputJSON);
			curl_setopt( $ch, CURLOPT_HTTPHEADER, $json_headers);
			curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2); // 0 | 2 ถ้าเว็บเรามี ssl สามารถเปลี่ยนเป้น 2
			curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 1); // 0 | 1 ถ้าเว็บเรามี ssl สามารถเปลี่ยนเป้น 1
			curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
			curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
			$result = curl_exec( $ch );
			curl_close( $ch );
			exit; // เมื่อส่งค่าไปที่อื่นแล้ว ไม่จำเป็นต้องทำคำสั่งที่อยู่ด้านล่าง				
			break;
	}
}
		
?>
    พิจารณาแต่ละส่วน เมื่อผู้ใช้ส่งข้อความที่เป็น text มา เราจะใช้การตรวจสอบเงื่อนไขด้วย switch() เพื่อพิจารณาว่า
ข้อความหลัก ที่ส่งมา จะถูกส่งต่อไปยัง Webhook URL ของ DialogFLow  โดยเรายังต้องการใช้งาน API กับบางข้อความ
เช่นในตัวอย่างด้านบน ถ้าส่งข้อความว่า "test" มา ก็จะเป็นการใช้งาน Line Messaging API ที่เรากำหนดเองตอบกลับผู้ใช้
แต่ถ้าเป็นข้อความอื่นๆ ให้ส่งต่อไปยัง DialogFlow
    เราสามารถเพิ่ม case เงื่อนไขเพิ่มเติมตามต้องการ กับบางข้อความ โดยอาจจะใช้ในรูปแบบ Regular Expression ในการ
ตรวจสอบก็ได้ เช่น 
case	 (preg_match('/:$/',trim($userMessage)) ? true : false):
	$textReplyMessage = " พร้อมรับคำสั่ง";
	$replyData = new TextMessageBuilder($textReplyMessage);     				
	break;						
case	 "test":
	$textReplyMessage = " คุณไม่ได้พิมพ์ ค่า ตามที่กำหนด";
	$replyData = new TextMessageBuilder($textReplyMessage);     				
	break;
    สำหรับในส่วนของการ Forward Webhook Event ให้เราแก้ไข URL เป็น Webhook URL ของ DialogFLow ของเรา
สังเกตว่า เราทำการแก้ไขในส่วนของ ค่า Host ให้เป็น Domain ของ DialogFlow และทำการจัดรูปแบบ headers ก่อนใน
ไปใช้งานใน curl ฟังก์ชั่น เพื่อส่งค่า 
// กำหนด Webhook URLใน DialogFLow Agnet ของเรา 
$url = "https://bots.dialogflow.com/line/<Agent-ID>/webhook";
$headers = getallheaders(); // ค่า Headers ที่ Line ส่งมาให้
$headers['Host'] = "bots.dialogflow.com"; // แก้ไขค่าเป็น Domain ของ  DialogFlow
$json_headers = array(); // สร้างตัวแปร array เพื่อจัดรูปแบบการกำหนด header ใช้ใน curl ฟังก์ชั่น
foreach($headers as $k=>$v){
	$json_headers[]=$k.":".$v;
}
$inputJSON = file_get_contents('php://input'); // เก็นส่วนของ body ไว้ในตัวแปร
    เท่านี้เราก็สามารถใช้งาน DialogFLow ไปพร้อมๆ กับใช้งาน Line Messaging API ที่จัดการผ่าน Server ของเราซึ่ง
มีความยืดหยุ่นและรองรับการทำงานที่หลากหลายได้
 
 
 

ทดสอบการ Forward Webhook Event

    ก่อนทดสอบอย่าลืมว่า ตอนนี้เราใช้ Webhook URL ของ Server เราเป็นหลัก ดังนั้นใน Line Dev console ก็ต้องแก้ไข
เป็น Webhook URL จาก server ของเรา 
 
 

 
 
    ทดสอบการทำงาน
 
 

 
 
    เริ่มต้นเราพิมพ์ข้อความว่า "test" ซึ่งเป็นข้อความที่เข้าเงื่อนไข ที่เรากำหนด Bot ตอบกลับผ่าน API ของเรา ต่อด้วยเราพิมพ์
คำว่า "หวัดดี :" สังเกตว่าเราต่อท้ายด้วย (:) ทั้งนี้เพื่อทดสอบให้เข้าเงื่อนไขการใช้ Regular Expression ซึ่งมีประโยชน์มากหาก
เราต้องการให้ข้อความตรงเงื่อนไขตามรูปแบบที่กำหนด แทนการกำหนดเป็นข้อความๆ ในเงื่อนไขที่สองนี้ Bot ก็ยังตอบกลับผ่าน 
API เหมือนเดิม ต่อไปข้อความที่สาม เราพิมพ์ไปว่า "หวัดดี" ตอนนี้ปรากฏว่าไม่เข้าเงื่อนไขข้อความที่กำหนด จึงไปสู่เงื่อนไขค่า
default คือทำการส่งข้อมูลไปใช้งานกับ Webhook URL ของ DialogFLow  ข้อความที่ตอบกลับมาเป็นข้อความจาก Agent ใน
ฝั่ง DialogFlow 
    จะเห็นว่าเราใช้ประโยชน์จากแนวทางนี้ ทำให้การสนทนากับ Line Bot รองรับการทำงานที่ครอบคลุม และสะดวกมากขึ้น เช่น
กรณีที่เราต้องการส่งข้อความแบบ Flex Message ซึ่งจำเป็นต้องใช้ข้อมูลที่อัพเดทใน server ของเราตอบกลับไปยังผู้ใช้ เราก็
สามารถใช้งาน API จัดการทุกอย่างที่ฝั่ง server ของเราได้เลย  หรือแม้แต่กรณีที่ผู้ใช้ส่งรูปภาพมา เราก็สามารถ
ที่จะทำการบันทึกไฟล์รูปผ่าน API ของเราได้ ซึ่งถ้าหากเราใช้ Webhook URL ของ DialogFlow เป็นหลัก เราจะไม่สามารถจัดการ
กับข้อความรูปแบบอื่นๆ นอกจาก text ได้
    ไม่เพียงแต่สะดวกในการจัดการฝั่ง API ของเราเท่านั้น ในฝั่ง DialogFlow เราก็ยังสะดวกในการจัดการกับรุปแบบข้อความตอบ
กลับที่ทำโดย Agent ด้วย 
    หวังว่าแนวทางนี้จะเป็นประโยชน์ในการนำไปประยุกต์ใช้งาน หากมีแนวทางหรือการใช้งาน DialogFlow เพิ่มเติม อาจจะได้นำ
มาแนะนำเพิ่มเติมในลำดับต่อๆ ไป


อย่าลืมกด Like กด Share เป็นกำลังใจ ในการสร้างบทความใหม่ๆ น่ะครับ







เนื้อหาที่เกี่ยวข้อง



Tags:: forward webhook line dialogflow line messaging api line bot sdk




เนื้อหาพิเศษ เฉพาะสำหรับสมาชิก

กรุณาล็อกอิน เพื่ออ่านเนื้อหาบทความ

ยังไม่เป็นสมาชิก

สมาชิกล็อกอิน



หริอ ล็อกอิน ด้วย Facebook




URL สำหรับอ้างอิง











เว็บไซต์ของเราให้บริการเนื้อหาบทความสำหรับนักพัฒนา โดยพึ่งพารายได้เล็กน้อยจากการแสดงโฆษณา โปรดสนับสนุนเว็บไซต์ของเราด้วยการปิดการใช้งานตัวปิดกั้นโฆษณา (Disable Ads Blocker) ขอบคุณครับ