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

สร้าง 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 ครับ

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

การพัฒนาไลน์แชทบอทเกี่ยวกับคุณภาพอากาศ
ในช่วงเวลานี้ ไม่มีอะไรที่ถูกพูดถึงมากที่สุดเกินกว่า ค่า PM2.5 หรือคุณภาพอากาศที่แย่ลงทุกวัน ทุกคนต่างๆ…
medium.com

ก่อนลงมือทำ

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

เบื้องต้นผมใช้ข้อมูลมาจาก 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 ตัวเองได้

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

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

Line chat bot x Firebase (Part 1 : Overview แบบยังไม่โค๊ด)
หลายคนคงรู้จัก chatbot มาบ้างเเล้วไม่ว่าจะเป็น simsimi หรือ Facebook chat bot ก็ตาม เเละวันนี้ครับผมจะพาคุณไปรู้จัก…
medium.com

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

เริ่มขั้นตอนแรกสุด เราต้องมาสร้าง 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 = 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 เพื่อทดสอบ LINE Bot
ปกติแล้ว เวลาที่เราเขียน Bot ในขั้นตอนการพัฒนา เราก็มักจะรัน Bot ใน localhost ก่อน ซึ่งมีปัญหาคือไม่สามารถรับ webhook…
medium.com

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

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

ให้คัดลอก Url : https://xxxx.ngrok.io ที่แสดงในส่วน Forwarding ไว้ แล้วทดลองเข้าจะพบว่าเราสามารถเข้าได้เหมือนตอนทดสอบเข้า 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 ครับ สามารถติดตามอ่านได้จากลิงค์ข้างล่างที่มีรายละเอียดค่อนข้างชัดเจนครับ

Getting Started on Heroku with Node.js | Heroku Dev Center
A step-by-step guide for deploying your first Node app and mastering the basics of Heroku
devcenter.heroku.com

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