สร้าง Line bot เพื่อแสดงค่า PM 2.5 รอบ ๆ ตัวเราด้วย Node.js

วันนี้เราจะมาทำ Line bot ให้สามารถแสดงค่า PM 2.5 จากที่ต่าง ๆ รอบตัวเราโดยใช้การอ้างอิงจากสถานที่ที่เราเลือกกันครับ

ฟีเจอร์จากภาพด้านบนที่วันนี้เราจะมาทำกันคือ ผู้ใช้งานทำการกด Share Location ที่ตัวเองสนใจอยากดู จากนั้นตัวบอทจะไปดึงข้อมูลสถานีวัดต่าง ๆ ที่อยู่ใกล้สุด 5 สถานีมาแสดง และ สามารถกดดูย้อนหลัง 3 วันจากสถานีนั้นได้ว่ามีค่าเป็นเท่าไร?

ที่มา… ที่ไป…

พอดีช่วงวันศุกร์ที่ 5 เมษายน 2562 ทางบริษัท I GEAR GEEK เรายกทีมกันไปแชร์กับน้อง ๆ ของคณะวิทยาศาสตร์ สาขาเทคโนโลยีสารสนเทศคอมพิวเตอร์ มหาวิทยาลัยแม่โจ้ หัวข้อการสร้าง Line chatbot ด้วย Node.js และ Heroku ครับ

ซึ่งโจทย์ในบทความนี้ก็เลยเป็น Workshop เล็ก ๆ ที่นำไปแชร์ให้กับน้อง ๆ เพื่อทำให้เห็นภาพมากยิ่งขึ้นว่าจากการแนะนำเครื่องมือในช่วงแรก พอนำเอามาประกอบกันเป็น Chatbot จะถูกเอามาใช้ประโยชน์ได้อย่างไร


ดังนั้นทางมหาวิทยาลัย หรือ หน่วยงานไหนสนใจอยากติดต่อให้พวกเราไปแบ่งปันสามารถติดต่อได้ผ่านแฟนเพจ I GEAR GEEK ได้ครับ :)


กลับมาต่อกันที่โจทย์ที่จะให้น้อง ๆ ทำกัน พอดีมันประจวบเหมาะกับช่วงนี้พวกเราก็มองกันว่าตอนนี้สถานการณ์ PM 2.5 กำลังเป็นปัญหาหลักของคนทางภาคเหนือมีหลายคนให้ความสนใจในเรื่องนี้กัน พวกเราก็เลยหยิบเอาเรื่องนี้มาสร้างเป็นโจทย์ของ Workshop ครับ

แล้วก็ดั๊น… ไปบังเอิญมีท่านนึงทำคล้าย ๆ กันกับของเราเลย อิอิ ลองไปอ่านบทความของท่านนั้นได้เลยครับ


ก่อนลงมือทำ

ข้อมูลจากไหนดี?

เบื้องต้นผมใช้ข้อมูลมาจาก http://air4thai.pcd.go.th/webV2/ ครับ ซึ่งถ้าลองแกะ API ของเค้าจากหน้าแสดงแผนที่ เราก็จะได้ข้อมูลของแต่ละจุดมาแล้ว จากนั้นผมก็ทำการเขียน API ครอบไว้ เพื่อทำหน้าที่ในการตีวงหารัศมีที่ใกล้กับสถานี้แล้วส่งผลกับมา 5 สถานีเท่านั้น

API ที่ผมทำก็หน้าตาประมาณนี้ : https://fathomless-reaches-36581.herokuapp.com/api?lat=18.77769165814301&long=98.95345357232975

ตัวอย่างหน้าตาข้อมูล

อันนี้ผมเก็บข้อมูลสำรองไว้ครับ เผื่อวันนึงมีคนเข้ามาอ่านแล้ว API ด้านบนใช้งานไม่ได้ก็สามารถเอาไปใช้ทดสอบ Chatbot ตัวเองได้

ลิงค์ข้อมูลจำลอง : https://www.mocky.io/v2/5c5971d33200009f1eba3895

ถ้ายังไม่เคยสร้าง Line บอทเลย?

ให้ทำการสร้าง Account Line developer ขึ้นมาก่อนจากบทความด้านล่าง เพื่อให้ได้ตัว channelAccessToken กับ channelSecret มาใช้ในการเชื่อมต่อกับ Line messaging API


เรามาเริ่มกันเลยดีกว่าครับ

เริ่มขั้นตอนแรกสุด เราต้องมาสร้าง Rich menu กันก่อนครับ
Rich menu คืออะไร? ก็คือเมนูตอนแรกที่เราจะเห็นเมื่อเข้าไปใน line bot ของเราแล้วมันจะเด้งมาเลยแสดงบนข้อความที่ส่งของผู้ใช้งาน ถ้าจากโจทย์ที่เราอยากทำก็คือเมนูแบบนี้ เพื่อให้ผู้ใช้สามารถกดเลือกได้ว่าต้องการทำอะไรกับบอทของเรา

1) เข้าสู่ระบบไปที่ https://admin-official.line.me/
2) จากนั้นเลื่อนลงมาเรื่อย ๆ จะเห็น Account ที่เราสร้างไว้ ให้กดเข้าไปที่นั่น

3) เลื่อนไปทางด้านซ้ายจะเห็นเมนู ริชเมนู (ภาษาไทย)

4) กด “สร้างใหม่” จากนั้นให้ตั้งชื่อ และ เลือกวันที่แสดงให้เป็นวันปัจจุบันถึงอนาคต (Rich menu สามารถแสดงเป็นช่วงเวลาได้ด้วย) โดยเลือก template ดังภาพด้านล่าง ซึ่งทางไลน์ได้ fix ขนาดของตัว template ไว้แล้ว เราต้องดีไซน์เมนูตาม layout ที่กำหนดไว้เท่านั้นครับ

  • จากนั้นให้อัพโหลดไฟล์รูปเมนูที่เราเตรียมไว้ที่นี่ >> ไฟล์รูป Rich menu
  • ให้กดที่ tab สีเขียวด้านซ้ายมือตรง “ระบุ” เพื่อใส่ action ให้กับปุ่มตาม layout ของไฟล์ที่เราเลือกไว้ในขั้นตอนแรก
  • ใส่ข้อมูลของแต่ละลิงค์ดังนี้
ลิงค์ : line://nv/location (เพื่อเปิดการใช้งานแผนที่) — https://developers.line.biz/en/docs/messaging-api/using-line-url-scheme/#opening-the-location-screen
http://air4thai.pcd.go.th/webV2/aqi_info.php
https://www.facebook.com/PCD.go.th

ต้องระวังด้วย… หาก rich menu ให้ตรวจสอบด้วยว่าส่วนของ “การแสดง” ตอนนี้ิได้เลือกเป็น “แสดง” ไหม และ “ระยะเวลาการแสดง” ต้องอยู่ในช่วงของวันปัจจุบัน

เมื่อทดลองเล่นในมือถือเราจะได้เห็นเมนูเด้งขึ้นมาแล้ว เมื่อกดปุ่มต่าง ๆ ก็สามารถเล่นได้ตามลิงค์ที่เราใส่ไว้ตอนแรกครับ


มาดู Code ของเรากันต่อ

ขั้นตอนต่อไปให้ทำการ clone code จาก https://github.com/igeargeek/chatbot-cpe-cmu2019 ได้เลยครับ

  1. จากนั้นให้เข้าไปที่โฟลเดอร์ 03-pm2.5-bot ให้ทำการคัดลอกไฟล์ .env.example เป็น .env
  2. แก้ไขค่าของ channelAccessToken และ channelSecret ใน .env
channelAccessToken = xxx
channelSecret = xxx
apiUrl = https://fathomless-reaches-36581.herokuapp.com/api

โดยเข้าไปที่ https://developers.line.biz จากนั้นเข้าไปที่ Provider ที่เราสร้างไว้ในตอนแรกสุด

จากนั้นให้เลือก tab แรกคือ “Channel settings”

เลื่อนลงมาเรื่อย ๆ ในหัวข้อ Channel secret และ Channel access token (หากยังไม่เคยสร้างให้กด Issue ใหม่ได้เลยเพื่อสร้าง Key)โดยนำสองค่านี้ไปใส่แทน xxx ใน .env ที่เราสร้างไว้ในขั้นตอนก่อนหน้านี้ เพื่อใช้ในการยืนยันตัวกับ Line ให้เราสามารถเรียกใช้งาน Messaging API ได้

3. กลับมาที่โฟลเดอร์ 03-pm2.5-bot ให้ทำการสั่งคำสั่งดังต่อไปนี้

npm i ติดตั้ง dependency ต่าง ๆ ที่เราใช้งาน

npm run start เพื่อรันทดสอบดูผลการเชื่อมต่อกับ Line

ทดลองเข้าหน้า http://localhost:4000 หากขึ้นข้อความว่า “03-pm2.5-bot” ก็เป็นอันเรียบร้อยแล้วครับในขั้นตอนนี้


ขั้นตอนสุดท้าย

เชื่อมต่อ Line เข้ากับ API ของเราที่เขียนด้วย Node.js ครับ
1. วันนี้เราจะใช้ ngrok ช่วย ซึ่งเป็นเครื่องมือเทพที่ทำให้เราสามารถได้โดเมนแบบ SSL ที่ชี้มายังเครื่องเราแบบง่าย ๆ 
รายละเอียดการใช้งาน ngrok สามารถติดตามได้ที่นี่ครับ เขียนไว้ค่อนข้างละเอียดเลย

แต่สำหรับคนที่ยาวไปไม่อ่าน ถ้าติดตั้งเรียบร้อยแล้ว ให้มาต่อกับเราครับ อิอิ

ngrok http 4000 นี่คือการสั่งให้สามารถเข้ามายังเครื่องเราได้ผ่าน port 4000

ให้คัดลอก Url : https://xxxx.ngrok.io ที่แสดงในส่วน Forwarding ไว้ แล้วทดลองเข้าจะพบว่าเราสามารถเข้าได้เหมือนตอนทดสอบเข้า http://localhost:4000 เด๊ะ ๆ

2. ผูก Line เข้ากับ API ของเรา โดยกลับไปที่ https://developers.line.biz มองหา Provider ของเราแล้วไปยัง tab “Channel settings” เหมือนขั้นตอนที่เรานำเอา accessToken มาใช้งานในขั้นตอนก่อนหน้านี้
เลื่อนไปดูยังส่วนนี้

ให้ตั้งค่า Use webhooks เป็น enable
Webhook URL
ให้ใส่ Url ที่เราได้จาก ngrok แต่ตัวอย่างของผลเป็น heroku ถ้ากรอกก็จะเป็น xxxx.ngrok.io/webhook แทน

  • ตรงนี้ต้องลอง refresh หน้าของ Setting อีกทีนึง บางครั้งการตั้งค่าไม่เปลี่ยน อาจจะทำให้ Line ไม่ส่งข้อความเข้า API ของเรา

ตั้งค่าข้อความตอบกลับอัตโนมัติ และ ข้อความเริ่มต้น เป็น disabled


เมื่อทดสอบใช้งาน Bot ของเรา จะพบว่าสามารถทำงานได้ตามที่คาดหวังไว้ครับ ที่นี้เราต้องกลับมาดูที่โค๊ดของ Bot ตัวนี้กันครับ เรามาดูกันที่ server.js ในโฟลเดอร์ 03-pm2.5-bot

ตรงส่วนนี้คือการตรวจสอบว่าข้อความที่ผู้ใช้ส่งมาเป็น location หรือ หมุดพิกัด ที่ผู้ใช้เลือกหลังจากกดเมนูเปิดแผนที่ จากนั้นทำการเรียกใช้ฟังก์ชั่น handleLocationEvent ต่อ

สำหรับฟังก์ชั่นนี้จะทำการดึงข้อมูลสภาพอากาศจาก API มาแสดงในรูปแบบของ Carousel template (https://developers.line.biz/en/docs/messaging-api/message-types/#carousel-template)


สำหรับการนำเอา API นี้ขึ้นไปยัง Server ผมก็คงจะแนะนำให้ทดลองของ Heroku ครับ สามารถติดตามอ่านได้จากลิงค์ข้างล่างที่มีรายละเอียดค่อนข้างชัดเจนครับ


บทความนี้ก็ขอจบเพียงเท่านี้ครับ ในอนาคตผมจะนำเอา Dialogflow ที่ได้มีโอกาสทดลองทำมาแบ่งปันในครั้งถัดไปครับ