สร้าง 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
- ลิงค์ของ code api : https://github.com/nitipatl/pm2.5-air4thai-api
ถ้ายังไม่เคยสร้าง 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 ของไฟล์ที่เราเลือกไว้ในขั้นตอนแรก
- ใส่ข้อมูลของแต่ละลิงค์ดังนี้
ต้องระวังด้วย… หาก rich menu ให้ตรวจสอบด้วยว่าส่วนของ “การแสดง” ตอนนี้ิได้เลือกเป็น “แสดง” ไหม และ “ระยะเวลาการแสดง” ต้องอยู่ในช่วงของวันปัจจุบัน
เมื่อทดลองเล่นในมือถือเราจะได้เห็นเมนูเด้งขึ้นมาแล้ว เมื่อกดปุ่มต่าง ๆ ก็สามารถเล่นได้ตามลิงค์ที่เราใส่ไว้ตอนแรกครับ
มาดู Code ของเรากันต่อ
ขั้นตอนต่อไปให้ทำการ clone code จาก https://github.com/igeargeek/chatbot-cpe-cmu2019 ได้เลยครับ
- จากนั้นให้เข้าไปที่โฟลเดอร์ 03-pm2.5-bot ให้ทำการคัดลอกไฟล์ .env.example เป็น .env
- แก้ไขค่าของ 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 ที่ได้มีโอกาสทดลองทำมาแบ่งปันในครั้งถัดไปครับ