มาเขียน LINE BOT ด้วย PHP กัน EP.3

ว้าวววว และแล้วก็มาถึง EP.3 กันแล้วนะครับ สำหรับการเขียน LINE BOT ด้วย ภาษา PHP แบบบ้านๆ มาดูกันเลยครับว่า สัปดาห์นี้ผมจะพาทำอะไรกันต่อ

ก่อนที่จะไปกันต่อผมแนะนำให้อ่านบทความของพี่ตี๋ เพื่อทำความเข้าใจเกี่ยวกับประเภทข้อมูลแต่ละแบบที่รับได้ผ่าน LINE Webhook ก่อนนะครับ

วันนี้สิ่งที่ผมจะพาทุกท่านไปทำก็คือ การดึงข้อมูลรูปจากคนที่ส่งรูปเข้ามาใน BOT นั่นเองงง ซึ่งจากที่ผมได้รับฟังปัญหามาจากหลายๆท่าน จะติดปัญหาว่า Response ที่ได้รับมาจาก Webhook นั้นได้มาเป็น id แล้วผมจะไปดึงรูปมาได้อย่างไร วันนี้มีคำตอบครับ ถ้าพร้อมแล้วไปกันเลยยยย (เลยอยุ่ไกลนะ จะไปจริงๆหรือ ><”)

PART 1 — แนะนำ API

วันนี้ API พระเอกของเราคือ API Get Content นั่นเอง

ซึ่งข้อมูลสำคัญที่เราจำเป็นจะต้องใช้นั่นก็คือ messageId ส่วนวิธีการได้มานั้นไปดูที่ Part ต่อไปได้เลยครับ

PART 2— ตามล่าหา messageId

ใน Part นี้เราจะมาตามล่าหา messageId กันครับ ถ้าใครยังไม่ทราบ messageId นั้นจะแฝงมากับ ข้อมูลที่เราได้มาจาก LINE webhook นั่นเอง

{
"events":[{
"type":"message",
"replyToken":"7b5cfb01246b47bdade9df50b74ab423",
"source":{
"userId":"U2ce6383e081ce4ccdfb9114c70305a7a",
"type":"user"
},
"timestamp":1563441326368,
"message":{
"type":"image",
"id":"10233900215452",
"contentProvider":{
"type":"line"
}
}
}],
"destination":"Ue106743187234c78044f9cab5d5510ae"
}

ถ้าเราสังเกต เราจะเห็นชุดข้อมูลที่อยู่ใน “message”

"message":{
"type":"image",
"id":"10233900215452",
"contentProvider":{
"type":"line"
}
}

ซึ่งในชุดข้อมูลนี้จะประกอบไปด้วย

type : ส่วนนี้คือประเภทของ message
id : ส่วนนี้คือ messageId ที่เรากำลังตามหานั่นเอง
contentProvider : ส่วนนี้คือข้อมูล provider ที่ส่งเข้ามานั่นเอง

PART 3— ได้เวลา coding

มาเริ่มกันที่เขียน function getContent กันก่อน โดย function นี้เราก็จะใช้วิธีการเหมือนเดิม ก็คือใช้ PHP CURL ในการเชื่อมต่อและรับค่าข้อมูลรูปภาพ กลับมา

function getContent($datas)
{
$datasReturn = [];
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.line.me/v2/bot/message/".$datas['messageId']."/content",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_POSTFIELDS => "",
CURLOPT_HTTPHEADER => array(
"Authorization: Bearer ".$datas['token'],
"cache-control: no-cache"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if($err){
$datasReturn['result'] = 'E';
$datasReturn['message'] = $err;
}else{
$datasReturn['result'] = 'S';
$datasReturn['message'] = 'Success';
$datasReturn['response'] = $response;
}
return $datasReturn;
}

ใน function getContent ผมจะทำการเขียน return ข้อมูลกลับไปด้วยถ้าหากมี error ที่ได้รับมาจาก LINE ก็จะทำการ return error นั้นกลับไป แต่ถ้าไม่มี error เราจะทำการ return ข้อมูล response ที่ได้กลับมาจาก LINE กลับไป

หลังจากที่เราทำการสร้าง function getContent แล้ว ต่อมาเราจะทำการกำหนด folder ที่เราจะให้นำรูปไปเก็บโดยใช้ วิธีการ define ไว้ในตัวแปร UPLOAD_DIR

define('UPLOAD_DIR', 'tmp_image/');

ต่อมาก็กำหนดตัวแปรที่จำเป็นต้องใช้

$datas = file_get_contents('php://input');
$deCode = json_decode($datas,true);
$LINEDatas['token'] = "<YOUR-CHANNEL-ACCESS-TOKEN>";
$messageType = $deCode['events'][0]['message']['type'];

$datas : ตัวแปรนี้จะเก็บข้อมูลที่ได้จา่ก webhook ของ LINE ในรูปแบบ json
$deCode : แปลงข้อมูลจาก json ให้เป็น array ด้วยคำสั่ง json_decode และเก็บข้อมูลไว้ที่ตัวแปรนี้
$LINEDatas[‘token’] : เก็บข้อมูล LINE Token
$messageType : เก็บข้อมูลประเภทของ Message

หลังจากนั้นผมจะเขียน if เอาข้อมูลเฉพาะที่เป็นประเภทรูปภาพเท่านั้น

if($messageType == 'image'){
$LINEDatas['messageId'] = $deCode['events'][0]['message']['id'];
}

$LINEDatas[‘messageId’] : จะเก็บข้อมูล messageId

หลังจากนั้นเราจะทำการเรียกใช้ function getContent และเก็บข้อมูลที่ return กลับมาจาก function getContent ไว้ในตัวแปร $results

if($messageType == 'image'){
$LINEDatas['messageId'] = $deCode['events'][0]['message']['id'];
$results = getContent($LINEDatas);
}

หลังจากนั้นผมจะเขียน if เพื่อจับข้อมูลที่ return มาจาก function getContent เฉพาะที่สำเร็จเท่านั้น

if($messageType == 'image'){
$LINEDatas['messageId'] = $deCode['events'][0]['message']['id'];
$results = getContent($LINEDatas);
if($results['result'] == 'S'){
$file = UPLOAD_DIR . uniqid() . '.png';
}
}

$file : เก็บข้อมูล path ที่ต้องการนำรูปภาพไปเก็บ

หลังจากนั้นเราจะใช้คำสั่ง file_put_contents เพื่อทำการย้ายไฟล์ แบบนี้

if($messageType == 'image'){
$LINEDatas['messageId'] = $deCode['events'][0]['message']['id'];
$results = getContent($LINEDatas);
if($results['result'] == 'S'){
$file = UPLOAD_DIR . uniqid() . '.png';
file_put_contents($file, $data);
}
}

ได้เวลาลองของจริงกันแล้วววว

ไฟล์มาแว้ววว ไหนเปิดดูหน่อยซิ

สวยงาม ถ้าทำได้แบบนี้แล้วก็เอาไปเลย 10 กระโหลก

สำหรับใครที่รูปยังไม่เข้านะครับ ให้ลองไปตั้ง permission ของ folder ที่เราจะทำการเก็บข้อมูลรูปไว้ ให้เป็น 775 แบบนี้ครับ

แล้วถ้าใครตั้ง 775 แล้วก็ยังไม่ได้อีกก็ให้ลองตั้งเป็น 777 ดูก่อนนะครับเพื่อเช็คว่าสามารถย้ายไฟล์ไปไว้ที่ folder ได้หรือไม่

และนี่คือ code ทั้งหมดของวันนี้

เป็นอย่างไรกันบ้างครับกับ EP ที่ 3 ผมหวังว่าเพื่อนๆ จะสนุกกับการเขียน Code และ LINE Chatbot นะครับ ถ้าหากว่าอยากให้ผมมาสอนเขียนหรือช่วยในส่วนไหน สามารถ Comment มาได้เลยนะครับ แล้วพบกันใหม่สัปดาห์หน้า

ตอนนี้ LINE Developer เรามีแฟนเพจแล้วนะจ๊ะอย่าลืมไปกด LIKE กันด้วยนะ

https://www.facebook.com/LINEDEVTH

ส่วนใครที่ยังไม่ได้เข้าร่วมกลุ่มกับเรา คลิ๊กที่นี่ได้เลย

https://www.facebook.com/groups/LINEDEVTH

Resources

Developer console
https://developers.line.biz/en/

Messaging API Document
https://developers.line.biz/en/docs/messaging-api/

Messaging API Reference
https://developers.line.biz/en/reference/messaging-api/

--

--

Closing the distance. Our mission is to bring people, information and services closer together

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store