สรุปบทเรียนการสร้าง LIFF จาก LINE x Skooldio [PART 2]

Thachaparn Bunditlurdruk
incubate.co.th
Published in
5 min readMay 12, 2020

หลังจากเตรียมอุปกรณ์พร้อมแล้ว และได้รู้จัก LIFF แล้ว ในพาร์ทนี้ก็จะเป็นสรุปการใช้ฟังก์ชั่นต่าง ๆ ของ LIFF กัน

OUTLINE

  • พาร์ทที่ 1
    — รีวิวปัญหาที่เจอตอนเรียน
    — บทเรียนที่ 1: บทเกริ่นนำ
    — บทเรียนที่ 2: สิ่งที่ต้องมีในการสร้าง LIFF
  • พาร์ทที่ 2
    — บทเรียนที่ 3: สร้าง LIFF App ใน LINE
  • พาร์ทที่ 3
    — บทเรียนที่ 4: Tricks and tips for happy coding

บทเรียนที่ 3: สร้าง LIFF App ใน LINE

บทนี้ก็จะเป็นการสอนการเรียกใช้ LIFF และใช้ฟังก์ชั่นต่าง ๆ ที่เป็นประโยชน์ของ LIFF ที่เกริ่นมาแล้วก่อนหน้านี้ เช่น ดึงข้อมูลผู้ใช้ แนะนำ bot หรือการแสกน QR code

1. Setting up LIFF app

เริ่มแรกคือต้องอัพโหลด LIFF SDK มาก่อน ซึ่งลิ้งก์ที่สอนในคอร์สอาจจะไม่อัพเดทเท่ากับปัจจุบันที่มีการเปลี่ยนแปลง API ไปนิดหน่อย ตามประกาศนี้ ที่เปลี่ยนไปเพื่อแก้ปัญหา liff ล่มเมื่อเวอร์ชั่นเปลี่ยน

2. Initializing LIFF app

ก่อนจะใช้ฟังก์ชั่นใด ๆ ของ LIFF เราจะต้องทำการ init ก่อนเสมอ โดยมี LIFF-ID เป็นพารามิเตอร์ ซึ่ง LIFF ID ก็หาได้จาก LIFF URL เลย https://liff.line.me/{LIFF-ID}

3. Getting LIFF Environment

ในพาร์ทนี้มีการใช้ 5 ฟังก์ชั่น ได้แก่

  • liff.getOS() : บอกว่าอยู่บนแพล็ตฟอร์มใด iOS, android, web
  • liff.getLanguage(): บอกภาษาของเครื่องผู้ใช้
  • liff.getVersion(): บอกเวอร์ชั่นของ liff
  • liff.getAccessToken(): บอก access token แบบชั่วคราว เมื่อ LIFF ถูกปิด เจ้า token นี้ก็จะหายไป
  • liff.isInClients(): บอกว่าผู้ใช้เปิดจากแอพ LINE ไหม ช่วยให้เราสามารถสร้าง feature ที่เหมาะในแต่ละแพล็ตฟอร์มได้

จากโค๊ด การดึงข้อมูลหลัก ๆ อยู่แค่ที่เรียกฟังก์ชั่นของ liff ส่วนโค๊ดตัวอื่น ๆ คือการนำค่าที่ดึงได้ไปแสดงผลใน html tag เฉย ๆ

4. Getting a basic profile

ในการดึงข้อมูลผู้ใช้ของฟังก์ชั่น getProfile() จะได้ promise object ที่รวมข้อมูลผู้ใช้ไว้ เลยใช้ await แล้วเก็บข้อมูลใส่ตัวแปร profile โดยใน promise object จะมี

  • pictureUrl: ได้ url ของรูปโปรไฟล์ผู้ใช้
  • userId: Id ผู้ใช้
  • statusMessage: สเตตัสของผู้ใช้ ถ้าไม่มีข้อความอะไรจะขึ้นว่า undefined
  • displayName: ชื่อที่ผู้ใช้ตั้ง

แต่ในตอนต้น ถ้ายังไม่ได้ใส่ฟังก์ชั่น login() เข้าไปสำหรับ external browser ก็จะไม่มีข้อมูลใด ๆ แสดงออกมาได้

ส่วนข้อมูล email จะมีความพิเศษกว่าข้อมูลอื่น ๆ นิดหนึ่ง เพราะต้องขอ permission จากผู้ใช้เพิ่ม และเป็นข้อมูลที่เก็บไว้ใน openID ลองมาดูวิธีในข้อถัดไปกัน

5. Getting user email

การจะได้ email ผู้ใช้มานั้น เราต้องไปเข้าไปขอใช้ OpenID Connect ก่อน โดยเข้าไปที่การตั้งค่าของ LIFF แล้วเลือกแถบ Basic Setting เมื่อกด apply เขาก็จะให้เราอ่านข้อตกลง และแนบรูปภาพของ Consent ที่อธิบายว่าเราจะเอาอีเมลผู้ใช้ไปทำอะไร จากนั้นรีเฟรชหนึ่งครั้ง แล้วไปแก้ไขการตั้งค่า Scope ในแถบ LIFF แล้วเลือก openid กับ email

ในส่วนของโค๊ดในไฟล์ index.html ที่แสดงไปเมื่อข้อที่แล้วจะเห็นว่า email ไม่ได้อยู่ใน promise object ของ getProfile() แต่อยู่ใน openID ซึ่ง LINE ก็ใจดี๊ใจดีที่รวมโค๊ดเอาไว้ decode มาให้แล้วที่ liff.getDecodedIDToken() ซึ่งจะคืนค่าเป็น payload ที่มี email อยู่ในนั้น

เมื่อลอง deploy แล้วกดเข้าไปที่ลิ้งก์ LIFF จะพบหน้าของ permission กลับมาอีกครั้ง เพื่อขอเก็บ email

อ่านเพิ่มเติมหัวข้อนี้ได้ ที่นี่

6. Getting and understanding the context

ฟังก์ชั่นต่อมา คือ getContext() ที่จะบอกเราว่า LIFF ถูกเปิดอยู่ในบริบทแบบไหน โดยสามารถบอกประเภทห้องที่ LIFF ถูกเปิด เช่น 1-on-1, room, group พร้อม ID ของห้องนั้น ๆ และยังสามารถบอกขนาด(viewType)ของ LIFF ได้ด้วย ซึ่งข้อมูลทั้งหมดนี้จะได้มาถ้ามีการเปิดผ่านแอพ LINE เท่านั้น

7. Sending messages on behalf of the user

อีกหนึ่งความสามารถของ LIFF คือสามารถส่งข้อความกลับเข้าห้องแชทในฐานะผู้ใช้เองได้ด้วย โดยเราต้องไปตั้งค่าที่ LINE developer Console ตรงส่วนของ Scope ในหน้า LIFF ตามรูปด้านล่าง

ในส่วนของฟังก์ชั่นสำหรับส่งข้อความ คือ liff.sendMessages() โดยมี list ของ message object เป็นพารามิเตอร์ ไม่เพียงแต่สติ๊กเกอร์ แต่ข้อความชนิดอื่น ๆ ก็สามารถส่งได้ ยกเว้น imageMap แค่ปรับแต่ง payload ใหม่เท่านั้น ในคอร์สเรียนนี้เราจะเอาฟังก์ชั่น sendMessages() ไปเป็น action สำหรับ onClick ของปุ่ม Send Message เมื่อกดปุ่มนี้สติ๊กเกอร์ก็จะถูกส่งเข้าห้องแชทที่ LIFF เปิดอยู่นั่นเอง

  • 1 message สามารถมีได้สูงสุด 5 bubbles (Message Object)
  • จะส่งข้อความได้ต้องเปิด LIFF จากห้องแชทเท่านั้น เลยมี if (liff.getContext().type !== “none”) มาดักไว้

8. Bot Link

แล้วก็มาถึงการแนะนำ LINE OA หรือแชทบอท ในกรณีที่ผู้ใช้ยังไม่เป็นเพื่อน เราสามารถให้แนะนำให้เขาแอดบอทเราได้ทุกครั้งที่เปิด LIFF โดยจะมีวิธีแนะนำสองแบบ คือ แบบ normal เบา ๆ ในหน้าของ permission ต่าง ๆ กับแบบ aggressive ที่จะเด้งขึ้นมาเต็มหน้าหลังหน้า permission

ส่วนวิธีการก็ไม่มีโค๊ดซักกะบรรทัด แค่ไปตั้งค่าใน Console ของ LIFF ตัวที่เราอยากจะผูก ซึ่งบอทที่ผูกได้จะต้องอยู่ใต้ provider เดียวกันเท่านั้น

9. Getting Friendship

ฟังก์ชั่น liff.getFriendship() จะคืน Promise object มี property ชื่อ friendFlag ซึ่งเป็น Boolean บอกว่าผู้ใช้เป็นเพื่อนกับบอทหรือยัง ฟังก์ชั่นนี้มีประโยชน์เวลาที่เราอยากทำกิจกรรมการขายได้ครบวงจรมากขึ้น เช่น เปิด LIFF สั่งซื้อสินค้าใน LIFF แล้วอยากจะส่งใบเสร็จเข้าห้องแชท ็ผู้ใช้จะต้องเป็นเพื่อนกับเรา (bot) ก่อน เราถึงจะส่งข้อความเข้าห้องแชทให้เขาได้ ซึ่งถ้ายังไม่เป็นเพื่อน เราก็ส่งข้อความไปถามว่าจะ add friend เลยไหม ถ้าผู้ใช้ตกลงก็จะเด้งไปหน้า add friend เลย แต่ถ้าคราวนี้ยังไม่ addครั้งหน้าที่เปิด LIFF ก็จะโดนตื๊อใหม่

10. Opening URL in the in-app browser or external browser

นอกจากการส่งข้อความ และดูข้อมูลผู้ใช้แล้ว LIFF ยังสามารถสั่งเปิดหน้าต่างไปยัง URL อื่น ๆ ได้ด้วยฟังก์ชั่น liff.openWindow() โดยมีพารามิเตอร์ 2 ตัว คือ

  • url: ลิ้งก์ที่อยากจะเปิด เป็น string
  • external: เป็น boolean โดย
    — true: external browser
    — false: in-app browser

จากคอร์สเรียน openWindow() จะถูกเรียกเมื่อกดปุ่ม Open Window เหมือนการส่งข้อความในข้อ 7

11. Opening QR code reader and getting the string back to LIFF

อีกฟังก์ชั่นที่ว้าว คือ liff.scanCode() ใช้สั่งเปิดกล้องเพื่อ แสกน QR code แล้วคืนค่าที่อ่านได้กลับมาเป็น string จากตัวอย่างด้านล่างได้ทดลองทำ 2 แบบ คือ อ่าน QR code ที่คืน URL string กลับมา ก็จะเอาไปเปิดใน in-app browser เลย และแสดง string ใน HTML ที่เตรียมไว้ แต่ถ้า string ไม่ใช่ URL มันก็จะ error เปิดหน้าต่างไม่ได้ แต่ก็ยังแสดงค่าใน HTML อยู่ดี

12. Closing the LIFF app

คือฟังก์ชั่นที่สั่งให้ปิด LIFF เองโดยที่ ผู้ใช้ไม่ได้เป็นคนกดปิด ฟังก์ชั่นนี้จะมีประโยชน์เช่น ตอนที่เราอยากจะส่งใบเสร็จให้ลูกค้าเห็นในห้องแชท หลังชำระเงินเสร็จก็สั่งปิด LIFF ด้วยฟังก์ชั่น liff.closeWindow() ได้เลย ซึ่งในคอร์สจะปิดเมื่อฟังก์ชั่น close() ถูกเรียกตอนกดปุ่ม close

นอกจากนี้การสั่งปิด LIFF ยังเป็นการยกเลิก access token ที่เปิดขึ้นมาตอน init ด้วย

13. Checking login status and Performing login with LINE Login

ฟังก์ชั่นที่เจ๋งอีกอัน คือ liff.isLoggedIn() เพื่อดูว่าผู้ใช้ login หรือยัง ซึ่งโดยปกติถ้าเปิดผ่าน LINE ก็จะ login อัตโนมัติอยู่แล้ว แต่ถ้าเปิดจากข้างนอก เราอาจะต้องเพิ่ม liff.login() เพิ่ม ซึ่งแค่คำสั่งนี้คำสั่งเดียวก็ล็อกอินเรียบร้อย ทำให้สามารถใช้ฟังก์ชั่นดึงข้อมูลอื่น ๆ ได้เหมือนกับเปิดใน LINE เป็นเรื่องดี ๆ จากการที่ LIFF ผนวกเข้ากับ LINE Login

14. Logging out

ล็อกอินไปแล้วก็ต้องมีการล็อกเอาท์ โดยใช้เเค่คำสั่ง liff.logout() ก็เรียบร้อย แต่เวลาผู้ใช้เห็น เขาจะไม่รู้ว่า logout แล้ว เพราะหน้า UI มันเหมือนเดิม เลยต้องเติมโค๊ด js อีกบรรทัดเข้าไป window.location.reload() เพื่อให้มัน refresh หน้าใหม่กลับมาหน้าเตรียม login เหมือนเดิม

15. Sharing message to selected friends or groups

ฟังก์ชั่น liff.shareTargetPicker() เป็นฟังก์ชั่นใหม่ ตั้งแต่ LINE เวอร์ชั่น 10.3.0 มันสามารถส่งข้อความไปที่ห้องแชทได้เหมือน liff.sendMessages() เลย แต่เจ๋งกว่าตรงที่สามารถส่งไปนอกห้องแชทที่ LIFF ไม่ได้เปิดอยู่ได้ ทั้งเพื่อน ทั้งกลุ่ม ทั้งห้อง ได้หมดเลย ที่สำคัญสามารถแชร์จาก external browser ได้ด้วย โดยต้องออกไปตั้งค่าที่แถบ LIFF ของ LINE Login Channel ก่อนตามรูปเลย

ส่วนของโค๊ดก็ถอดแบบมากจาก liff.sendMessages() เช่นกันที่ส่งข้อความได้หลายรูปแบบ จำกัดไม่เกิน 5 bubbles ต่อ 1 ข้อความ

อ่านเรื่อง share target picker เพิ่มได้ ที่นี่

ต่อไป พาร์ทที่ 3
— บทเรียนที่ 4: ฺTricks and tips for happy coding

กลับ พาร์ทที่ 1
— บทเรียนที่ 1: บทเกริ่นนำ
— บทเรียนที่ 2: สิ่งที่ต้องมีในการสร้าง LIFF

--

--

Thachaparn Bunditlurdruk
incubate.co.th

An Arts graduate who’s trying to challenge herself with programming