ทำแชทบอท ด่วนจี๋ ไปรษณีย์จ๋า กับ Sunday Codelabs 3 กับ LINE Developers Thailand
หลังจากที่พลาด Sunday Codelabs สองครั้งแรกเพราะชนกับค่าย TMRW Creators Camp 2021 ที่จัดเวลาเดียวกันพอดี รอบนี้ว่างแล้วไม่พลาดแน่นอน
ก่อนอื่นเราได้ทำการเตรียมพร้อมทั้งหมด โดยได้ไปดู codelab มาก่อนล่วงหน้า ว่าต้องเตรียมอะไรบ้าง เวลาทำจะได้ลื่นๆ แต่คุณกอล์ฟพิมพ์ไวมาก แอบตามไม่ทันเลยค่ะ 555555555555 ก็เลยแนะนะว่า อ่านมาก่อนก็ดีน้าา เพราะตอน Flex Message ใครมันจะก้อปทันกัน 555
ไลฟ์สามารถดูได้ที่นี่เลยจ้า
.
"ด่วนจี๋ ไปรษณีย์จ๋า" คือบังเอิญกดทีวีแล้วไปเจอการ์ตูนช่องนึงฉาย แล้วตัวละครพูดคำนี้พอดีเลย555555
ไลฟ์มีการเตรียมคนดูก่อนถึงเวลา พอถึงเวลาปุ๊ป พี่ตี๋พี่แทนมาเลยจ้า และสักพักได้เปิดตัวคนมา coding โชว์พวกเราในวันนี้ เขาคือคุณกอล์ฟ LINE API Expert หรือเรียกย่อๆว่า LAE คนล่าสุดของไทย ที่ได้ตำแหน่งนี้ก่อนโควิด ข้อดีคือจะได้เล่นของใหม่ๆก่อนใคร ในตอนนี้คือ LINE Mini App และถ้าโควิดหมดไปก็จะได้ไปงานที่ญี่ปุ่นด้วยเนอะ
ในวันนี้ เราจะได้ LINE Chatbot ที่สามารถตรวจสอบ tracking จากไปรษณีย์ไทย ว่าตอนนี้ของอยู่ที่ไหนแล้ว และสามารถดู status แต่ละตัวได้ และดูชื่อผู้รับลงไปได้ ซึ่งเพิ่มเข้ามาจาก codelab จ้า
เริ่มต้นที่สร้าง LINE OA ขึ้นมา เริ่มตั้งแต่สร้าง provider จากนั้นมา new channel ถ้าเลือก categories ไม่ถูกเลือกหมวดการศึกษาได้ ซึ่งขั้นตอนนี้ไวมาก จากนั้นได้ LINE Chatbot มา 1 ตัว
ต่อมาปิด auto reply message โดยไป disable ทิ้งไป
และเราเพิ่มเพื่อนกับบอทไว้ก่อนเลย เดี๋ยวเรา coding แล้วมาทดสอบกัน
จากนั้นมาเตรียมของทำโปรแกรมให้บอทกัน โดยเราสร้างโปรเจกใน Firebase โดยคุณกอล์ฟใช้ชื่อว่า ThailandPostTrack ปรากฏว่าชื่อไม่ซํ้าจ้า เยี่ยมเลย
บอทตัวนี้เราเรียก API นอก Google เนอะ อ่ะมีทั้ง LINE แล้วก็ API ของไปรษณีย์ไทย จึงต้อง update project เป็น Blaze Plan เสียก่อน ก็คือผูกบัตรเครดิตก่อน
แต่ถ้าไม่มีบัตรเครดิตหล่ะ? เราสามารถใช้ Firebase Emulator Suite ได้นะทุกคน โดยเราทำบล็อกแยกก่อนหน้านี้ไปนิดนึง แต่ในวันนี้มี tips and trick เยอะ เยอะเกินกว่าบล็อกนี้ที่เขียนไว้ด้วยอ่ะ
ต่อมาติดตั้งอะไรต่างๆกันเถอะ เริ่มที่ติดตั้ง firebase เลย
sudo npm install -g firebase-tools
ที่ต้อง sudo
เพราะว่าเผื่อต้องขอสิทธิ์อะไรงี้ ต่อมา check Firebase version เพื่อ make sure ว่าติดตั้งไปเมื่อกี้เรียบร้อยแล้วนะ
firebase --version
จากนั้นทำการ login กันเลย และเราต้องตรวจสอบว่า account ตรงกับที่เราสร้าง Firebase project เมื่อกี้ไหมนะ
firebase login
สร้าง folder ของโปรเจก ซึ่งในที่นี้จะชื่อว่า thailandposttrack
ตามชื่อใน Firebase เนอะ
mkdir thailandposttrack
แล้วก็ทำการ init project โดยเลือกใช้ตัว Function และ Emulator เพราะเราใช้ Firebase Emulator Suite ในการทดสอบใน local ก่อนจ้า เอ้ออ เพิ่งรู้ว่าทำในนี้ได้เลยง่ายๆ ไม่ต้องทำ firebase.json
เอง
โดยเราจะ run Firebase Emulator Suite กับ Clouds Function for Firebase แล้วตั้ง port ที่เราจะใช้คือ 5001
ใช้ Emulator UI เพื่อ check log ต่างๆ
เรื่องภาษา จริงๆคุณกอล์ฟแนะนำว่าใช้ typescript เพราะปลอดภัยกว่า แต่ในตอนนี้ใช้ javasscript ไปก่อนเนอะ
เมื่อกระบวนการเหล่านี้เรียบร้อยแล้ว เราจะทำการทดสอบโดยการลอง run ใน function ที่เป็นไฟล์เปล่าก่อน คือ เอา comment code ใน index.js
ออกนั่นแหละ จากนั้นลองใช้ Firebase Emulator Suite กันเล้ยย
firebase emulators:start
คั่นด้วยคำถามพี่ตี๋ codelab ไหนในนี้ อันไหนเป็นอันล่าสุด ทุกคนโดนแกงกันหมดนึกว่าอันที่ทำอยู่นี้ แต่จริงๆเป็นอันนี้จ้า Handle Non-Text Event with Dialogflow
เมื่อเรารัน Firebase Emulator Suite เราจะพบว่า มันจะ default ที่ us-central1
ให้เลย ซึ่งไกลจากบ้านเรามาก ดังน้านน เราเข้าไป check ที่ website นี้ดูก่อนจ้าว่า server ของ Google มีที่ไหนบ้าง และที่ไหนใกล้เราสุด ซึ่งใกล้สุดคือสิงคโปร asia-southeast1
แต่ด้วยความที่ตัว server ของ LINE น่าจะอยู่ที่ญี่ปุ่น ก็เลยเลือก asia-northeast1
ที่โตเกียวนั่นเอง
ดังนั้นเปลี่ยน region ในโค้ดของเรา และทำการ start emulator ใหม่ด้วยน้าา
ต่อมาใช้เจ้า เอ็น-จี-ค๊อก ngrok เพื่อทำการมุดท่อนั่นเอง เข้าไปที่ website แล้วทำการ download และ install ได้เลยย และเราสามารถเปลี่ยน region ใน ngrok ได้ด้วยนะ คือปกติอ่ะ จะไปที่ United States (us)
เราสามารถเปลี่ยนไปที่อื่นได้ด้วย เช่นในที่นี้ไปญี่ปุ่น ก็พิมพ์ command line ว่า
ngrok http 5001 -region=jp
เราก็ไปญี่ปุ่นทิพย์แล้ว (เอ๊ะ ใช่เหรอ)
สามารถดู log ได้ว่า bot ทำงานได้จริงไหม และสิ่งที่เราต้องการใช้จาก request ที่เราได้จากข้อความที่ user พิมพ์ ก็จะมี type
, message
และ replyToken
ต่อมาไปสร้าง account ในเว็บไปรษณีย์ไทย
จากนั้นก็ไปเอา token มาซึ่ง UI แย่มาก ต้องกดปุ่มและยืนยันก่อนถึงจะได้ เราจะมีโควต้าใช้ได้วันละ 1000 requests นะ
แล้วสร้าง class ใหม่ ชื่อว่า thailandpost.js
โดยตัว API ของทางไปรษณีย์ไทยที่ใช้นั้น จะเป็นดังนี้
getToken
คือการนำ token API ของเรา ทำการ authen เพื่อให้ได้ authen token ออกมา ซึ่งเวลาเราใส่ token ใน header จะเป็นBearer
แล้วตามด้วย token แต่อันนี้เป็นคำว่าToken
แทนง่ะ
GetItems
เป็นการตรวจสอบสถานะของเลขพัสดุนั้นๆ จะใช้ token ที่ได้จากgetToken
มาใช้งานนะ
ส่วน RequestItems
จะได้ไฟล์ให้ download กลับมาจ้า
ดังนั้นเราจึงสร้างไฟล์ thailandpost.js
เพื่อใช้งาน API ต่างๆ ดังนี้
ต่อมาสร้าง Flex Message เพื่อนำมาใช้งานแสดงผลสถานะการส่งพัสดุ ใช้ Flex Message Simulator ในการออกแบบ สุดท้ายก็จะได้ json เอามาใช้ต่อเนอะ แต่อันนี้เป็นหน้าเว็บเนอะ และบังคับ login ด้วย LINE Account นิดนึง
ขั้นตอนนี้เนี่ยย เอาจริงๆ ข้ามไปเยอะมากเลย เพราะว่าคุณกอล์ฟทำรอไว้ก่อนแล้วไง แต่จะมีเพิ่มมาจาก codelab ตรงเรื่องของชื่อผู้ส่งนั่นเอง สร้างไฟล์ชื่อว่า msgTemplate.js
ทั้งหมดจะเป็นแบบนี้
- ถ้า user กรอกเลขพัสดุแล้วไม่มีข้อมูล จะให้ส่ง text message ไป จะอยู่ใน
trackNotFound
- มีการตัด body มาเป็น
trackBody
ออกจากตัว body หลัก แล้วจะถูกใส่ในแต่ละ column ในtrackHeader
จ้า - ตรงชื่อผู้รับ กลับไปดู document ของ API ไปรษณีย์ไทย จะมี status ต่างๆ โดย status item 501 คือ นำจ่ายสำเร็จ นั่นเอง จึงนำ
detail.receiver_name
มาแสดงได้จ้า
"text": (detail.status === "501") ? `ผู้รับ คุณ${detail.receiver_name}` : " "
- และมีการใส่สีแต่ละ status item ไว้ด้วย โดย status item 501 คือ นำจ่ายสำเร็จ จะแสดงพื้นหลังเป็นสีเขียว, status item 201 คือ อยู่ระหว่างการขนส่ง จะแสดงพื้นหลังเป็นสีเหลือง และอื่นๆเป็นสีเทา
"backgroundColor": (detail.status === "501") ? "#6BFF6B" : (detail.status === "201") ? "#FCFEC9" : "#EEEEEE"
เมื่อเราได้ message ที่จะส่งเรียบร้อยแล้ว ทำการปั้น body เพื่อทำการส่งข้อความไปให้ user โดยสร้างไฟล์ lineHelper.js
ขึ้นมาเพื่อทำสิ่งนี้
เราสามารถดูรายละเอียดการทำ Reply Messages ได้ใน document ของ LINE ได้เลย ซึ่งคุณกอล์ฟก็สอนวิธีอ่านเจ้า curl ต่างๆเนอะ
curl -v -X POST https://api.line.me/v2/bot/message/reply \
อันนี้จะเห็นได้ว่า เราต้องส่ง methodPOST
ไปที่https://api.line.me/v2/bot/message/reply
-H
ก็คือ header โดยเราจะใส่ไป 2 สิ่ง คือ'Content-Type: application/json'
และ'Authorization: Bearer {channel access token}'
-d
คือ data parameter ในที่นี้คือ ส่งเป็น response body เข้าไปด้วย มีหลักๆ 2 อย่างคือreplyToken
ที่เอามาจากตอนที่เราได้รับข้อความจาก user และmessage
อันนี้คือข้อความที่เราจะส่งให้ user นั่นเอง
และกลับมาที่ index.js
จริงๆเราแอบเล่าข้ามไป เพราะเดี๋ยวจะอธิบายตรงนี้แหละว่าโค้ดมีอะไรบ้าง
request.body.events[0]
อันนี้ get event ออกมาก่อน โดยเราจะใช้ 3 ตัว คือreplyToken
,message
,type
if (type === "message" && message.type === "text")
เราต้อง check ก่อนว่ามันเป็น message ที่เป็น text จริงๆ ไม่งั้นถ้า user ส่งสติ๊กเกอร์หรืออื่นๆมา มันจะพังเพราะ get text ออกมาไม่ได้เน้อconst barCode = message.text;
เอา text ที่ได้ออกมาใช้ โดยอันนี้จะเอามา check สถานะของพัสดุนี้- มี
async
ข้างนอก ก็ต้องมีawait
ด้านใน คือรอให้เรียก API เสร็จก่อนconst trackResult = await thailandpost.getItems(barCode);
ถึงจะทำงานได้ const items = trackResult["response"]["items"][barCode];
เราเอาresponse.items.barCode
ที่ได้จาก API มาใช้งานต่อในการส่ง message ไปหา user
let payload = null;
ประกาศตัวแปรpayload
ไว้ เพื่อเอาไปส่ง message นี่แหละ- ถ้า
items.length <= 0
ก็ให้ส่งmsgTemplate.trackNotFound()
กลับไป - ถ้ามีของให้ทำการวนลูปเพื่อสร้าง Flex Message จ้า
let body = [];
items.forEach((row) => {
body.push(msgTemplate.trackBody(row))
});
payload = msgTemplate.trackHeader(barCode, body)
await lineApp.reply(replyToken, payload);
ได้ของแล้ว ทำการส่งออกไปให้ user เลยจ้าresponse.send("Hello from Firebase!").end()
สุดท้ายทำการส่ง response ไปยัง Cloud Functions for Firebase แหละ ใช้end()
เพื่อความปลอดภัย
สุดท้าย ก่อน deploy หรือเอาโค้ดขึ้น github เราจะต้องทำการซ่อน key โดยใช้ Environment Configuration ก่อนเนอะ เพื่อความปลอดภัย โดยพิมพ์คำสั่งประมาณนี้
firebase functions:config:set thailandpost.tokenkey="YOUR_TOKEN_NA"
อันนี้แอบมีความลุ้นๆนิดนึง เพราะพี่ๆจำ command ไม่ได้แหละ แหะๆ
เวลาเราจะดู token ทั้งหมดก็สามารถพิมพ์ command นี้ได้จ้า
firebase functions:config:get
จากนั้นทำการ deploy ขึ้นไป ถ้าเราทำ Environment Configuration เราจะต้อง deploy อีก 1 รอบน้าา
firebase deploy --only functions
การ deploy ในตอนนี้จะนานกว่าปกตินิดนึง เพราะฝั่ง Google Clouds เอา code ไป pack เป็น server container เพื่อนำไป build เป็น 1 instant นั่นเอง และมีการ spin up / down ตามเวลาที่คนเล่นน้อย เล่นเยอะ
แต่การใช้ Environment Configuration ก็จะติดปัญหา คือ พอ deploy ไปปุ๊ป พอเราจะเพิ่ม feature หรือปรับแก้อะไรเพิ่มใน local พบว่ามัน error หล่ะสิ ทำยังไงดีนะ หาวิธีก็ไม่ได้ แต่ในไลฟ์นี้ มีคำตอบ
ให้พิมพ์ command ไปดังนี้ เพื่อนำ config ต่างๆ ลงมาเก็บไว้ใน local นั่นเอง
cd functions
firebase functions:config:get > .runtimeconfig.json
ทีนี้ก็ใช้ได้แล้วหล่ะนะ
หลังจากนั้นก็ปั่นบอทใน local ส่งชิงหน้ากากผ้า ไม่รู้จะได้ไหม ฮืออออ เจอว่าเรา deploy ไปแล้วบอทไม่ตอบ เพราะ ลืม npm install
ก่อน ฮืออออ และใช้ชื่อว่า webhook ตามเขางาย แต่พอตอบได้คือแอบรอนานเพราะไกลไปหน่อย 555
สรุป Tips & Trick ที่ได้
- เราสามารถเพิ่ม Emulator ได้ในตอน
firebase init
ได้เลย - ดู region Google server ที่ใกล้ที่สุดได้ที่เว็บนี้เลย gcping
- สามารถเปลี่ยนที่มุดใน ngrok ได้ด้วยคำสั่ง
ngrok http 5001 -region=jp
- การประกาศตัวแปรใน javascript จะมี 2 แบบหลักๆ คือ
let
ใช้ประกาศตัวแปรที่สามารถเปลี่ยนค่าได้ และconst
เป็นตัวแปรที่เราไม่ต้องการให้มันเปลี่ยนค่าได้นั่นเอง - เราสามารถใช้ Environment Configuration ใน local ได้แล้วนะ เพียงแค่พิมพ์คำสั่ง
firebase functions:config:get > .runtimeconfig.json
โดย.runtimeconfig.json
จะต้องอยู่ใน folder ที่ชื่อว่าfunctions
นะ ไม่งั้นมันก็โวยวายว่าหาไม่เจอเน้ออ
สุดท้ายหล่ะจ้า
แถมคลิป TikTok นิดนึง ไถๆมาแล้วไปเจออันนี้ คือพ่อค้าแม่ค้าออนไลน์ติดปัญหาคือร้านขายดีมากๆ แต่กรอกเลข tracking จากบิลยากเว่อร์ เพราะส่งออร์เดอร์แต่ละทีบิลอย่างยาวถูกม่ะ ทางเว็บไปรษณีย์ไทยเลยมี feature ให้ user กรอกเลขบิลแล้วจะได้เลข tracking ของทั้งหมดที่ส่งไปให้ลูกค้า ซึ่งก็สมัครสมาชิกก่อนเหมือนตอนเราใช้ API เขานั่นแหละ เผื่อใครอยากเอาไปต่อยอดได้จ้า โย่วว
@amuse.stuff พูดเลยว่าโง่มานาน เค้าทำแบบนี้ได้ด้วยยย ชั้นนี่อยากจะเป็นบ้า กรอกจนมือหงิกแล้ว ตอนนี้สบายมากเลยค่า555555555 ##voiceeffects ##amusestuff
♬ WHAT WOULD YOU DO? (feat. Pink Sweat$) - HONNE
download แอพอ่านบล็อกใหม่ของเราได้ที่นี่
ติดตามข่าวสารและบทความใหม่ๆได้ที่
และช่องทางใหม่ใน Twiter จ้า