LIFF Plugin ฟีเจอร์ใหม่ที่จะช่วยเพิ่ม Productivity ในการพัฒนา LIFF App ของคุณ

Jirawatee
LINE Developers Thailand
4 min readJul 5, 2022

--

ในงาน LINE Developer Day ปีที่ผ่านมา มี session ที่พูดถึงการปรับปรุงประสบการณ์ในการพัฒนา LIFF app ให้สะดวกขึ้น ซึ่งหนึ่งในฟีเจอร์ที่ได้เปิดตัวใน session นั้นก็คือ LIFF Plugin ที่ผมเชื่อว่านักพัฒนาในบ้านเราหลายคนตั้งตารอคอย

LIFF Plugin คือฟีเจอร์ที่มีใน LIFF SDK ตั้งแต่ v2.19.0 เป็นต้นมา ที่ให้นักพัฒนาต่อยอดความสามารถให้ LIFF SDK ทำอะไรได้เพิ่มเติมมากกว่าฟังก์ชันพื้นฐานที่ทีม LIFF เตรียมมาให้ เช่นสร้าง plugin กับฟังก์ชันที่เราต้องเขียนประจำ หรือ สร้างและแชร์ plugin ที่ใช้ร่วมกันภายในทีม โดยการเลือกใช้งานจะมี 2 รูปแบบคือ

แบบ Official LIFF Plugins

คือ plugin ที่พร้อมใช้งานซึ่งถูกพัฒนาโดยทีม LIFF โดยในปัจจุบันจะมี 2 ตัวด้วยกัน

  • LIFF Mock ตัวช่วยที่จะทำให้คุณสามารถ Mock ช้อมูลจาก LIFF server เพื่อทำ Unit Test และ Performance Test กับ LIFF app ได้
  • LIFF Inspector ตัวช่วยที่จะทำให้คุณ Debug ตัว LIFF app บนมือถือของคุณส่งตรงเข้า Chrome DevTools

แบบสร้าง LIFF Plugins เอง

คือ การพัฒนา plugin ด้วยการสร้าง class หรือ object ขึ้นมาเอง แล้วติดตั้งเข้าไปใน LIFF SDK เพื่อเรียกใช้งานผ่าน liff object

ซึ่งในบทความนี้ ผมจะพาทุกคนมาพัฒนา LIFF Plugin แบบสร้าง LIFF Plugins เอง ถ้าพร้อมแล้วเราไปเริ่มกันเลย

โครงสร้างของ LIFF Plugin

LIFF Plugin ทั้งแบบที่เป็น class และ object จะมีส่วนประกอบหลักอยู่ด้วยกัน 2 อย่าง

name

เป็น property ที่ให้เรากำหนดชื่อ(string)ของ plugin สำหรับเรียกใช้งานผ่าน liff object ในรูปแบบliff.${value of the name property}

install()

ฟังก์ชันที่ใช้ติดตั้งตัว plugin โดยจะได้รับ argument มา 2 ตัวจากการ activate ตัว plugin ที่สามารถเรียกมาใช้ได้(แต่จะไม่เรียกมาใช้ก็ได้นะ)

  • context คือ argument ตัวแรกที่บรรจุ liff object(liff.xxx ที่เราใช้กัน เช่น liff.getOS()) และ hooks object(สำหรับ register callback มีอธิบายท้ายบทความ)
  • option คือ argument ตัวที่สอง ที่สามารถรับค่าจากการ activate ผ่านคำสั่ง liff.use() ในกรณีที่มีการแนบค่ามา แต่หากไม่มีการแนบมา ค่าเริ่มต้นของมันจะเป็น undefined

ซึ่งผลลัพธ์จากการ install() มันสามารถ return เป็น ฟังก์ชัน หรือ ค่าต่างๆ ก็ได้

class GreetPlugin {
constructor() {
this.name = "greet";
}

install(context, option) {}
}

การเรียกใช้งาน LIFF Plugin

การเรียกใช้งาน plugin เราจะต้องทำการ activate ตัว plugin ผ่านคำสั่ง liff.use(plugin, option) โดยสามารถระบุ argument เข้าไปได้ 2 ตัว

  • plugin คือ class หรือ object ที่เราสร้าง LIFF Plugin (required)
  • option คือ ค่าที่สามารถส่งไปให้ LIFF Plugin ตั้งแต่การ initial เลย (optional)

หมายเหตุ: liff.use() สามารถเรียกใช้งานก่อนหรือหลัง liff.init() ก็ได้

ตัวอย่างแบบ Class

class GreetPlugin {
constructor() {
this.name = "greet";
}

install() {
return {
hello: this.hello,
goodbye: this.goodbye,
};
}

hello() {
console.log("Hello World!");
}

goodbye() {
console.log("Goodbye World!");
}
}

liff.use(new GreetPlugin());

liff.$greet.hello(); // Hello World!
liff.$greet.goodbye(); // Goodbye World!

ตัวอย่างแบบ Object

const hello = () => {
console.log("Hello World!");
};

const goodbye = () => {
console.log("Goodbye World!");
};

const greetPlugin = {
name: "greet",
install() {
return {
hello,
goodbye,
};
},
};

liff.use(greetPlugin);

liff.$greet.hello(); // Hello World!
liff.$greet.goodbye(); // Goodbye World!

ลองสร้าง LIFF Plugin ของตัวเอง

หลังจากเราได้เข้าใจโครงสร้างและการเรียกใช้งาน plugin แบบง่ายๆกันไปแล้ว ผมว่าเรามาลองสร้าง plugin ที่ดู advance มากขึ้น เพื่อให้เข้าใจและสามารถนำไปประยุกต์ใช้ได้กันดีกว่า โดยตัวอย่างที่ผมจะสร้างจะเป็น plugin สำหรับคำนวนดัชนีมวลกาย หรือที่ผมตั้งชื่อว่า BMI plugin

1. สร้าง BMIPlugin Class

1.1 กำหนดชื่อของ plugin สำหรับการเรียกใช้งานผ่าน liff object

constructor() {
this.name = "bmi";
}

1.2 รับค่า context และ option จากการ activate เพื่อนำไปใช้กับ localDate() และ return “ค่า” ซึ่งก็คือ today และ “ฟังก์ชัน” ซึ่งก็คือ greet และ cal จาก install()

install(context, option) {
return {
today: this.localDate(context.liff.getLanguage(), option.date),
greet: this.greeting,
cal: this.calculate
};
}

1.3 เพิ่ม 3 ฟังก์ชันที่จะใช้กับ plugin ตัวนี้

// เพื่อแปลงวันที่ตามภาษาที่ตั้งค่าไว้ที่แอป LINE
localDate(lang, date) {
// ...
}
// เพื่อแสดง displayName ของผู้ใช้ที่ Login
greeting(lang, profile) {
// ...
}
// คำนวนค่า BMI และบอกสัดส่วน
calculate(height, weight) {
// ...
}

ซึ่ง class นี้ผมได้สร้างไว้เป็นไฟล์ liff-bmi.js โดยจะมีโค้ดเต็มๆประมาณนี้ครับ

2. เรียกใช้งาน BMIPlugin Class

สำหรับขั้นตอนนี้ใครที่ยังไม่เคยสร้าง LIFF app มาก่อน แนะนำให้อ่านบทความด้านล่างนี้นะครับ ส่วนใครที่มีประสบการณ์แล้ว ไปลุยกันต่อเลย

2.1 เตรียม HTML Element ที่จะใช้งานในไฟล์ index.html

<h1>...</h1>
<h5>...</h5>
<input type="number" id="height" placeholder="Height in cm">
<input type="number" id="weight" placeholder="Weight in kg"
<button type="button">Calculate</button>
<h2>...</h2>

2.2 Import ตัว LIFF SDK และ BMIPlugin class

<script src="https://static.line-scdn.net/liff/edge/2/sdk.js"></script><script src="plugins/liff-bmi.js"></script>

2.3 ทำการ bind ตัว HTML Element

const h1Element = document.querySelector("h1");
const h2Element = document.querySelector("h2");
const h5Element = document.querySelector("h5");
const heightElement = document.querySelector("#height");
const weightElement = document.querySelector("#weight");
const btnElement = document.querySelector("button");

2.4 Activate ตัว BMIPlugin พร้อมแนบ object ที่มีค่า Date() เข้าไปเป็น option

liff.use(new BMIPlugin(), { date: new Date()});

2.5 แสดงวันที่ตามภาษาที่ตั้งค่าไว้ในแอป LINE

h5Element.innerHTML = liff.$bmi.today;

2.6 เพิ่ม event listener ให้ btnElement เพื่อคำนวนหาค่า BMI

btnElement.onclick = () => {
h2Element.innerHTML = liff.$bmi.cal(heightElement.value, weightElement.value);
}

2.7 Initial ตัว LIFF app และดึง user profile ส่งไปหา plugin เพื่อแสดงผลข้อความทักทายตามภาษาที่ผู้ใช้ตั้งค่าไปในแอป LINE

const main = async() => {
await liff.init({liffId: "YOUR-LIFF-ID"});
const profile = await liff.getProfile();
h1Element.innerHTML = liff.$bmi.greet(liff.getLanguage(),profile);
}
main();

โค้ดทั้งหมดของไฟล์ index.html (แถมการรองรับ External Browser)

ใครถึงตรงนี้แล้วก็ไป deploy ให้เรียบร้อย(อย่าลืมไปอัพเดท Endpoint URL ของ LIFF detail ใน LINE Developers console) แล้วมาดูผลลัพธ์กันครับ

ตัวอย่าง https://liff.line.me/1653575653-y90Q19AP

Bonus: รู้จักกับ Hook

Hook คือ argument ตัวหนึ่งที่เราสามารถเรียกออกมาจาก context ที่รับมาใน install() โดยหน้าที่ของตัวมันคือให้เราสามารถ pre-registered callback เพื่อที่จะรันคำสั่งต่างๆเมื่อเกิด event ได้ โดย hook ใน LIFF Plugin จะมีอยู่ 2 ประเภท

Hooks for LIFF API

คือ hook ที่จะทำงานกับฟังก์ชันใน LIFF SDK โดยตรง ซึ่งในปัจจุบันยังทำงานได้กับ liff.init() เท่านั้น โดยสามารถ register เพื่อรอ callback ก่อนที่จะ init (before hook) และเมื่อ init เสร็จแล้วได้ (after hook) โดยผมได้เขียนตัวอย่างที่ต่อยอดจาก BMIPlugin ไว้ให้แล้ว ใครสนใจก็สามารถ clone ไปลองเล่นดูกันได้ครับ

Hook for other LIFF plugins

คือ hook ที่จะทำงานกับ LIFF plugins ตัวอื่นๆ โดยเราสามารถ register เพื่อรอ callback กับฟังก์ชันต่างๆที่เราสนใจได้ โดยจะมีการใช้ฟังก์ชัน call() เพื่อ fire ตัว hook ใครสนใจสามารถศึกษาเพิ่มเติมได้จาก doc ของ LINE ด้านล่างนี้เลย

สรุป

ถือว่าสิ้นสุดการรอคอยจริงๆกับ LIFF Plugin ใครที่สนใจต่อยอดความสามารถของ LIFF SDK ทั้งการสร้าง plugin กับงานที่เราต้องทำเป็นประจำ เช่น การ validate ข้อมูล, การทำงานกับ API หรือ การสร้าง plugin เพื่อใช้กันในทีมแบบ single code-based น่าจะถูกใจและมี productivity เพิ่มขึ้นแน่นอน

หวังว่าบทความนี้จะทำให้ผู้อ่านเข้าใจวิธีการสร้าง LIFF Plugin และสามารถนำไปใช้ประโยชน์ได้ ถ้าใครทำ plugin ดีๆก็อย่าลืมเอาไปแบ่งปันกันใน community นะครับ

ท้ายนี้ถ้าคุณชอบบทความนี้ก็ฝากกด Clap เป็นกำลังใจให้ผม หากมันเป็นประโยชน์ก็ฝากกด Share ให้เพื่อนของคุณ และเพื่อที่คุณจะไม่พลาดบทความถัดๆไปก็ฝากกดติดตามตัว Publication ไว้ด้วยนะครับ สำหรับวันนี้ต้องขอตัวลาไปก่อน แล้วพบกันใหม่บทความหน้าครับ

--

--

Jirawatee
LINE Developers Thailand

Technology Evangelist at LINE Thailand / Google Developer Expert in Firebase