LIFF เกิดขึ้นมาเพื่อเติมเต็มการใช้งาน LINE Chatbot ในเรื่องของการแสดงผล ที่บางอย่าง LINE Chatbot ไม่สามารถทำได้ เช่น การสร้างฟอร์มลงทะเบียนที่ซับซ้อน หรือการแสดงสินค้าจำนวนมากๆในห้องแชท โดย LIFF มาพร้อมกับเทคโนโลยีของเว็บ หรือเรียกให้เข้าใจง่ายๆว่า เป็นการสร้างเว็บในห้องแชทนั่นเอง
ความสามารถหลักของ LIFF คือการเข้าถึงข้อมูลพื้นฐานของผู้ใช้ที่เปิดใช้งาน เช่น userId, email, displayImage, pictureUrl, statusMessage โดยที่ผู้ใช้ไม่ต้องทำการ Login ใดๆ อีกทั้งยังสามารถส่งข้อความรูปแบบต่างๆในนามของผู้ใช้กลับไปที่ห้องแชทได้ เช่น Flex Message, Imagemap เป็นต้น
นอกจากนี้รองรับการใช้งานบน External Browser ซึ่งมาพร้อมกับ LINE Login ในการยืนยันตัวตนผู้ใช้ โดยที่นักพัฒนาไม่จำเป็นต้อง Implement ระบบ Authentication เอง
ใน Codelab นี้คุณจะได้เรียนรู้ฟังก์ชันพื้นฐานต่างๆ และการทำงานของ LIFF พร้อมทั้งลงมือสร้าง LIFF app ตัวแรก ที่รองรับการใช้งานทั้งในแอปพลิเคชัน LINE และ External Browser ขึ้นมา
ใน Codelab นี้เราจะพัฒนา LIFF app ด้วย StackBlitz ซึ่งเป็น Editor แบบออนไลน์ที่ไม่ต้องติดตั้งโปรแกรมใดๆ และเราสามารถแชร์ URL ของโปรเจคให้กับผู้อื่นได้ โดยโปรเจคที่แชร์ จะอนุญาตให้ผู้อื่นเข้าถึงโค้ดทั้งหมด แต่จะไม่สามารถแก้ไขโปรเจคของเราได้
เมื่อคุณ Folk โปรเจคเรียบร้อยแล้ว คุณจะได้ชื่อโปรเจคและ URL สำหรับการใช้งานของคุณ ซึ่งการแก้ไขใดๆก็ตามจากนี้ไปจะถูกบันทึกเก็บไว้ใน StackBlitz
จุดเริ่มขบวนสำหรับการพัฒนาแอปพลิเคชันต่างๆบนแพลทฟอร์มของ LINE คือคุณจะต้องสมัครเป็น LINE Developer ก่อน
Provider คือ superset ของแอปทั้งหลายที่เราจะพัฒนาขึ้นรวมถึง LIFF app ด้วย โดยการสร้างเพียงให้ระบุชื่อของ Provider ลงไป ซึ่งอาจจะตั้งเป็นชื่อตัวเอง, ชื่อบริษัท, ชื่อทีม หรือชื่อกลุ่มก็ได้
Channel คือ subset ของ Provider โดยมีอยู่ 3 รูปแบบ คือ LINE Login, Messaging API และ Clova Skill
หลังจากที่คุณมี Provider และ Channel เรียบร้อยแล้ว ขั้นตอนต่อไปก็คือการสร้าง LIFF app โดยให้เลือก channel ที่สร้างขึ้นมา แล้วไปยัง tab ที่ชื่อว่า LIFF จากนั้นกด Add
เมื่อกด Add เสร็จเรียบร้อย คุณก็จะได้ LIFF URL มาแล้ว
หลังจากที่คุณมี LIFF app แล้ว คราวนี้เราจะมาลงมือโค้ดกัน โดยการจะใช้งานคำสั่งต่างๆภายใน LIFF เราจะต้องเริ่มจากการ initialize ตัว LIFF app ขึ้นมาก่อน
index.html
ใน StackBlitz แล้ว Uncomment ตัว LIFF SDK ใน
<script src="https://static.line-scdn.net/liff/edge/2/sdk.js"></script>
index.js
แล้วเพิ่มคำสั่ง initialize ตัว LIFF app ด้วย LIFF ID ที่คุณได้จากขั้นตอนที่ 4 ในฟังก์ชัน main()
// Initialize LIFF app
await liff.init({ liffId: "YOUR-LIFF-ID" })
เพื่อให้มั่นใจว่าคุณสามารถเรียกใช้งานฟังก์ชันต่างๆใน LIFF app ได้แล้ว ดังนั้น ให้เพิ่มโค้ดชุดนี้ลงไป หลังจากการ initialize ตัว LIFF app เพื่อตรวจสอบว่า LIFF app ของเราสามารถแยก OS ที่เปิดใช้งานได้
// Try a LIFF function
switch (liff.getOS()) {
case "android": body.style.backgroundColor = "#d1f5d3"; break
case "ios": body.style.backgroundColor = "#eeeeee"; break
}
วิธีการเปิด LIFF app ให้เราเอา LIFF URL ที่ได้จากข้อ 4 ซึ่งมีลักษณะแบบนี้ https://liff.line.me/YOUR-LIFF-ID
หลังจากที่เราเรียกคำสั่ง liff.init()
ไปแล้ว ในกรณีที่เราเปิด LIFF app ในแอป LINE บน Android หรือ iOS ตัว LIFF จะทำการ Login ให้อัตโนมติ ซึ่งทำให้เราสามารถเข้าถึงข้อมูลของผู้ใช้ได้ทันทัน
index.html
ให้เราเพิ่มโค้ดนี้เข้าไปที่ section ที่ชื่อว่า profile
เพื่อแสดงผลข้อมูลพื้นฐานต่างๆของผู้ใช้<section id="profile">
<img id="pictureUrl" src="https://mokmoon.com/images/ic_liff.png">
<p id="userId"></p>
<p id="displayName"></p>
<p id="statusMessage"></p>
<p id="email"></p>
</section>
index.js
ให้เราสร้างฟังก์ชัน getUserProfile()
ขึ้นมา โดยให้เอาโค้ดชุดนี้ไปวางไว้ด้านล่างสุดของไฟล์async function getUserProfile() {
const profile = await liff.getProfile()
pictureUrl.src = profile.pictureUrl
userId.innerHTML = "<b>userId:</b> " + profile.userId
statusMessage.innerHTML = "<b>statusMessage:</b> " + profile.statusMessage
displayName.innerHTML = "<b>displayName:</b> " + profile.displayName
}
getUserProfile()
ที่บรรทัดล่างสุดของฟังก์ชัน main()
async function main() {
// ...
getUserProfile()
}
การจะขอเข้าถึง Email ของผู้ใช้เราจำเป็นจะต้องขอ permission
index.js
ใน StackBlitz ให้เพิ่มโค้ดบรรทัดนี้เข้าไปในฟังก์ชัน getUserProfile()
async function getUserProfile() {
// ...
email.innerHTML = "<b>email:</b> " + liff.getDecodedIDToken().email
}
หนึ่งในข้อดีของการพัฒนา LIFF ก็คือการที่ LINE Login ได้เข้ามา Integrate ร่วม ทำให้เราสามารถยืนยันตัวตนผู้ใช้งานได้ง่าย ไม่ต้องพัฒนาเรื่อง Authentication เอง และนอกจากนี้เรายังสามารถใช้งานฟีเจอร์ต่างๆบน External Browser ได้เทียบเท่ากับการใช้งาน LIFF ใน LINE(สมาร์ทโฟน)
เราจะตรวจสอบว่าผู้ใช้เปิด LIFF จาก LINE(สมาร์ทโฟน) หรือ External Browser เพื่อที่จะแสดงปุ่ม Log In และ Log Out ในกรณีที่ผู้ใช้เปิดด้วย External Browser
index.html
ให้เราเพิ่มโค้ด HTML เข้าไปที่ section ที่ชื่อว่า button
เพื่อแสดงปุ่มทั้งสอง(กรณีที่เปิดด้วย External Browser)<section id="button">
<button id="btnLogIn">Log In</button>
<button id="btnLogOut">Log Out</button>
</section>
index.js
ให้เอาโค้ดชุดนี้ไปเพิ่มที่ส่วนล่างสุดของฟังก์ชัน main()
async function main() {
// ...
if (!liff.isInClient()) {
btnLogIn.style.display = "block"
btnLogOut.style.display = "block"
}
}
หลังจากที่เราได้ปุ่ม Log In และ Log Out มาละ คราวนี้เราก็จะมาสร้าง listener ให้กับปุ่ม โดยให้เอาโค้ดชุดนี้ไปวางไว้ด้านล่างสุดของไฟล์ index.js
btnLogIn.onclick = () => {
liff.login()
}
btnLogOut.onclick = () => {
liff.logout()
window.location.reload()
}
คัดลอก URL ในช่องพรีวิวของ StackBlitz ไปเปิดใน browser แล้วลองกดปุ่ม Log In และ Log Out
index.js
เราจะแยกการแสดงผลปุ่ม Log In และ ปุ่ม Log Out ตามสถานะการ Log In liff.isLoggedIn()
โดยให้แก้ไขโค้ดในฟังก์ชัน main()
ตามนี้async function main() {
// ...
if (!liff.isInClient()) {
if (liff.isLoggedIn()) {
btnLogIn.style.display = "none"
btnLogOut.style.display = "block"
} else {
btnLogIn.style.display = "block"
btnLogOut.style.display = "none"
}
}
}
main()
ให้เราย้ายตำแหน่งเดิมของ getUserProfile()
ไปอยู่ใน 2 ตำแหน่งคือ ตำแหน่งที่เปิด LIFF ใน LINE(else สุดท้าย) และตำแหน่งที่ผู้ใช้ได้ Log In แล้ว(ใน block ของ liff.isLoggedIn()
)async function main() {
// ...
if (!liff.isInClient()) {
if (liff.isLoggedIn()) {
btnLogIn.style.display = "none"
btnLogOut.style.display = "block"
getUserProfile()
} else {
btnLogIn.style.display = "block"
btnLogOut.style.display = "none"
}
} else {
getUserProfile()
}
}
LIFF app สามารถส่งข้อความรูปแบบต่างๆใน LINE ไปยังห้องแชทที่ LIFF app ถูกเปิดขึ้นมาในนามเรา(ผู้ใช้งาน)ได้
<section id="button">
<button id="btnSend">Send Message</button>
<!-- ... -->
</section>
index.js
ให้เอาโค้ดชุดนี้ไปวางไว้ด้านล่างสุดของไฟล์async function sendMsg() {
if (liff.getContext().type !== "none" && liff.getContext().type !== "external") {
await liff.sendMessages([
{
"type": "text",
"text": "This message was sent by sendMessages()"
}
])
alert("Message sent")
}
}
Send Message
โดยให้เอาโค้ดชุดนี้ไปวางไว้ด้านล่างสุดของไฟล์ index.js
btnSend.onclick = () => {
sendMsg()
}
liff.sendMessages()
ไม่สามารถใช้งานได้ใน External Browser ดังนั้นเราจะแสดงปุ่มนี้ในกรณีที่เปิด LIFF จาก LINE(สมาร์ทโฟน) เท่านั้น async function main() {
if (!liff.isInClient()) {
// ...
} else {
btnSend.style.display = "block"
getUserProfile()
}
}
LIFF app สามารถแชร์ข้อความรูปแบบต่างๆใน LINE ไปยังเพื่อนหรือกลุ่ม ในนามเรา(ผู้ใช้งาน)ได้
<section id="button">
<button id="btnShare">Share Target Picker</button>
<!-- ... -->
</section>
index.js
ให้เราเพิ่มฟังก์ชัน shareMsg()
โดยให้เอาโค้ดชุดนี้ไปวางไว้ด้านล่างสุดของไฟล์async function shareMsg() {
await liff.shareTargetPicker([
{
type: "image",
originalContentUrl: "https://d.line-scdn.net/stf/line-lp/2016_en_02.jpg",
previewImageUrl: "https://d.line-scdn.net/stf/line-lp/2016_en_02.jpg"
}
])
}
Share Target Picker
โดยให้เอาโค้ดชุดนี้ไปวางไว้ด้านล่างสุดของไฟล์ index.js
btnShare.onclick = () => {
shareMsg()
}
liff.shareTargetPicker()
จะสามารถใช้ได้ในกรณีที่ผู้ใช้ Log In แล้ว ดังนั้นเราจะแสดงปุ่มนี้ 2 ตำแหน่งในฟังก์ชัน main()
async function main() {
if (!liff.isInClient()) {
if (liff.isLoggedIn()) {
btnShare.style.display = "block"
// ...
} else {
// ...
}
} else {
btnShare.style.display = "block"
// ...
}
}
ใน LIFF app เราเรียกใช้งานฟีเจอร์ในแอปของ LINE อย่าง QR Code Reader เพื่ออ่านค่าที่อยู่ใน QR code แล้วส่งค่านั้นกลับมายัง LIFF app ได้
Scan QR
ก็ให้เราเปิด toggle นั้นindex.html
ใน StackBlitz เพิ่มโค้ดชุดนี้ใน section ที่ชื่อ feature
<section id="feature">
<p id="code"></p>
</section>
button
<section id="button">
<button id="btnScanCode">Scan Code</button>
<!-- ... -->
</section>
index.js
ให้เราเพิ่มฟังก์ชัน scanCode()
โดยให้เอาโค้ดชุดนี้ไปวางไว้ด้านล่างสุดของไฟล์async function scanCode() {
const result = await liff.scanCodeV2()
code.innerHTML = "<b>Code: </b>" + result.value
}
Scan Code
โดยให้เอาโค้ดชุดนี้ไปวางไว้ด้านล่างสุดของไฟล์ index.js
btnScanCode.onclick = () => {
scanCode()
}
ในตัวอย่างนี้จะมีคำว่า LINE Developers Thailand อยู่ใน QR code ซึ่งเมื่ออ่านค่ามาได้แล้ว จะมีการส่งค่ากลับมาแสดงใน LIFF app ตรงส่วนที่เขียนว่า Code
ในบางกรณีที่คุณต้องการจะเปิดเว็บไซต์ภายนอก LIFF app คุณสามารถใช้ฟังก์ชัน liff.openWindow() เพื่อเปิดมันได้
index.html
ให้คุณเพิ่มปุ่ม Open Window โดยให้เพิ่มโค้ดชุดนี้ใน section ชื่อ button
<section id="button">
<button id="btnOpenWindow">Open Window</button>
</section>
index.js
btnOpenWindow.onclick = () => {
liff.openWindow({
url: window.location.href,
external: true
})
}
liff.openWindow()
นั้นสามารถใช้งานได้ทั้ง LINE(สมาร์ทโฟน) และ External Browser และไม่จำเป็นต้อง Log In เพื่อใช้งาน ดังนั้นให้เพิ่มโค้ดบรรทัดนี้ไว้ด้านล่างสุดของฟังก์ชัน main()
async function main() {
if (!liff.isInClient()) {
if (liff.isLoggedIn()) {
// ...
} else {
// ...
}
} else {
// ...
}
btnOpenWindow.style.display = "block"
}
นอกจากการกดปิด LIFF app ที่มุมขวาบนแล้ว เราก็ยังสามารถปิด LIFF app ด้วยโค้ดได้ด้วย โดยในตัวอย่างนี้ จะแทนที่ alert("Message sent")
ในฟังก์ชัน sendMsg()
ด้วย liff.closeWindow()
ในไฟล์ index.js
async function sendMsg() {
if (liff.getContext().type !== "none") {
await liff.sendMessages([
{
"type": "text",
"text": "This message was sent by sendMessages()"
}
])
liff.closeWindow()
}
}
เมื่อเรากดส่งข้อความกลับไปยังห้องแชทเรียบร้อย ตัว LIFF app ก็จะปิดตัวเองทันที
ในกรณีที่คุณใช้งาน LIFF ร่วมกับ Chatbot เราสามารถที่จะเชื่อมต่อทั้ง LIFF และ Chatbot เข้ากันได้ โดยผ่านฟีเจอร์ที่ชื่อ Linked LINE Official Account เนื่องจาก บางครั้งเราอาจต้องการให้ LIFF ทำงานร่วมกับ Chatbot เช่น เมื่อซื้อสินค้าผ่าน LIFF app เสร็จก็ให้ Chatbot ส่งใบเสร็จยืนยันการซื้อสินค้ากลับไป เพื่อแสดงถึงความถูกต้องและความน่าเชื่อถือ
นอกจากเราจะเชื่อมต่อ LIFF app เข้ากับ Chatbot ได้แล้ว เราก็ยังสามารถตรวจสอบสถานะระหว่างผู้ใช้กับ Chatbot ได้อีกด้วย ทั้งนี้เราอาจต้องการยืนยันว่าผู้ใช้รายนั้นๆ ได้เพิ่ม Chatbot ของเราไปแล้ว ก่อนที่จะดำเนินการในตอนถัดๆไป
index.html
ให้เราเพิ่มโค้ด HTML เข้าไปที่ section ที่ชื่อว่า feature <section id="feature">
<!-- ... -->
<p id="friendShip"></p>
</section>
index.js
ให้เอาโค้ดชุดนี้ไปวางไว้ด้านล่างสุดของไฟล์ และอย่าลืมแก้ไข BOT-ID
ให้เป็น ID ของ Bot ที่คุณได้เชื่อมต่อไว้async function getFriendship() {
let msg = "Hooray! You and our chatbot are friend."
const friend = await liff.getFriendship()
if (!friend.friendFlag) {
msg = "<a href=\"https://line.me/R/ti/p/@BOT-ID\">Follow our chatbot here!</a>"
}
friendShip.innerHTML = msg;
}
liff.getFriendship()
จะสามารถใช้ได้ในกรณีที่ผู้ใช้ Log In แล้ว ดังนั้นเราจะเรียกใช้ getFriendship()
ในกรณีที่เปิด LIFF ใน LINE(สมาร์ทโฟน) และในกรณีที่ผู้ใช้ได้ Log In แล้วในฟังก์ชัน main()
async function main() {
if (!liff.isInClient()) {
if (liff.isLoggedIn()) {
// ...
getFriendship()
} else {
// ...
}
} else {
// ...
getFriendship()
}
}
ยินดีด้วยครับ ถึงตรงนี้คุณก็มี LIFF app ตัวแรกเป็นของคุณเองแล้ว!!!