今天繼續搭配 LIFF 的文件研究 Line LIFF App line-liff-v2-starter 的範例
<title>LIFF Starter</title>
設置 LIFF App 的標題window.onload = function() {
const useNodeJS = true; // if you are not using a node server, set this value to false
const defaultLiffId = ""; // change the default LIFF value if you are not using a node server
// DO NOT CHANGE THIS
let myLiffId = "";
// if node is used, fetch the environment variable and pass it to the LIFF method
// otherwise, pass defaultLiffId
if (useNodeJS) {
fetch('/send-id')
.then(function(reqResponse) {
return reqResponse.json();
})
.then(function(jsonResponse) {
myLiffId = jsonResponse.id;
initializeLiffOrDie(myLiffId);
})
.catch(function(error) {
document.getElementById("liffAppContent").classList.add('hidden');
document.getElementById("nodeLiffIdErrorMessage").classList.remove('hidden');
});
} else {
myLiffId = defaultLiffId;
initializeLiffOrDie(myLiffId);
}
};
Developing a LIFF app 講述了如何開發一個 LIFF app,裡面有幾個章節跟今天的範例有關:
Setting the title of the LIFF app
可以看到 public/index.html 裡用 HTML TAG <title>LIFF Starter</title>
設置 LIFF Starter 為 LIFF App 的標題
Integrating the LIFF SDK with the LIFF app
<!DOCTYPE html>
...(略)
<script charset="utf-8" src="https://static.line-scdn.net/liff/edge/2/sdk.js"></script>
<script src="liff-starter.js"></script>
</body>
</html>
Calling the LIFF API
initializeLiff(myLiffId);
liff.init()
initializing-liff-app ,若初始化成功則繼續執行 initializeApp();
initializeApp();
displayLiffData();
使用 LIFF SDK 取得並顯示 LIFF APP 環境基本資訊displayIsInClientInfo();
判斷是不是用 Line 開啟 LIFF APP,並控制相關顯示registerButtonHandlers();
註冊按鈕 click event handlers/**
* Check if myLiffId is null. If null do not initiate liff.
* @param {string} myLiffId The LIFF ID of the selected element
*/
function initializeLiffOrDie(myLiffId) {
if (!myLiffId) {
document.getElementById("liffAppContent").classList.add('hidden');
document.getElementById("liffIdErrorMessage").classList.remove('hidden');
} else {
initializeLiff(myLiffId);
}
}
/**
* Initialize LIFF
* @param {string} myLiffId The LIFF ID of the selected element
*/
function initializeLiff(myLiffId) {
liff
.init({
liffId: myLiffId
})
.then(() => {
// start to use LIFF's api
initializeApp();
})
.catch((err) => {
document.getElementById("liffAppContent").classList.add('hidden');
document.getElementById("liffInitErrorMessage").classList.remove('hidden');
});
}
/**
* Initialize the app by calling functions handling individual app components
*/
function initializeApp() {
displayLiffData();
displayIsInClientInfo();
registerButtonHandlers();
// check if the user is logged in/out, and disable inappropriate button
if (liff.isLoggedIn()) {
document.getElementById('liffLoginButton').disabled = true;
} else {
document.getElementById('liffLogoutButton').disabled = true;
}
}
displayLiffData();
使用 LIFF SDK 取得並顯示 LIFF APP 環境基本資訊/**
* Display data generated by invoking LIFF methods
*/
function displayLiffData() {
document.getElementById('browserLanguage').textContent = liff.getLanguage();
document.getElementById('sdkVersion').textContent = liff.getVersion();
document.getElementById('lineVersion').textContent = liff.getLineVersion();
document.getElementById('isInClient').textContent = liff.isInClient();
document.getElementById('isLoggedIn').textContent = liff.isLoggedIn();
document.getElementById('deviceOS').textContent = liff.getOS();
}
接著就讓我們來看看範例程式的每一個按鈕 click 做了什麼事情:
/**
* Register event handlers for the buttons displayed in the app
*/
function registerButtonHandlers() {
// button handlers...
}
Opening a URL 開啟一個網頁,可以在 Line 內建瀏覽器呼叫,也可以在外部瀏覽器呼叫
// openWindow call
document.getElementById('openWindowButton').addEventListener('click', function() {
liff.openWindow({
url: 'https://line.me',
external: true
});
});
Closing the LIFF app 關閉現在開啟中的 LIFF APP,在外部瀏覽器時無效
// closeWindow call
document.getElementById('closeWindowButton').addEventListener('click', function() {
if (!liff.isInClient()) {
sendAlertIfNotInClient();
} else {
liff.closeWindow();
}
});
Sending messages to the current chat screen 發送訊息到聊天室 (必須要 InClient & 使用者要許可權限才能成功發送)
// sendMessages call
document.getElementById('sendMessageButton').addEventListener('click', function() {
if (!liff.isInClient()) {
sendAlertIfNotInClient();
} else {
liff.sendMessages([{
'type': 'text',
'text': "You've successfully sent a message! Hooray!"
}]).then(function() {
window.alert('Message sent');
}).catch(function(error) {
window.alert('Error sending message: ' + error);
});
}
});
Get user profile LIFF SDK 可以取得 access token 用舊有 Line Login 方式取得 User Profile,也可以直接 Call LIFF SDK 取得 User Profile
// get access token
document.getElementById('getAccessToken').addEventListener('click', function() {
if (!liff.isLoggedIn() && !liff.isInClient()) {
alert('To get an access token, you need to be logged in. Please tap the "login" button below and try again.');
} else {
const accessToken = liff.getAccessToken();
document.getElementById('accessTokenField').textContent = accessToken;
toggleAccessToken();
}
});
// get profile call
document.getElementById('getProfileButton').addEventListener('click', function() {
liff.getProfile().then(function(profile) {
document.getElementById('userIdProfileField').textContent = profile.userId;
document.getElementById('displayNameField').textContent = profile.displayName;
const profilePictureDiv = document.getElementById('profilePictureDiv');
if (profilePictureDiv.firstElementChild) {
profilePictureDiv.removeChild(profilePictureDiv.firstElementChild);
}
const img = document.createElement('img');
img.src = profile.pictureUrl;
img.alt = 'Profile Picture';
profilePictureDiv.appendChild(img);
document.getElementById('statusMessageField').textContent = profile.statusMessage;
toggleProfileData();
}).catch(function(error) {
window.alert('Error getting profile: ' + error);
});
});
Sending messages to a user's friend (share target picker) 如果可以使用 shareTargetPicker 功能的話就出現按鈕,可以利用這個功能分享訊息給朋友 (Line Developers Console 也要允許使用 shareTargetPicker)
document.getElementById('shareTargetPicker').addEventListener('click', function () {
if (liff.isApiAvailable('shareTargetPicker')) {
liff.shareTargetPicker([{
'type': 'text',
'text': 'Hello, World!'
}]).then(
document.getElementById('shareTargetPickerMessage').textContent = "Share target picker was launched."
).catch(function (res) {
document.getElementById('shareTargetPickerMessage').textContent = "Failed to launch share target picker.";
});
} else {
document.getElementById('shareTargetPickerMessage').innerHTML = "<div>Share target picker unavailable.<div><div>This is possibly because you haven't enabled the share target picker on <a href='https://developers.line.biz/console/'>LINE Developers Console</a>.</div>";
}
});
效果如示意圖:
Performing a login process 在外部瀏覽器時實現 Line 登入/登出的功能
// login call, only when external browser is used
document.getElementById('liffLoginButton').addEventListener('click', function() {
if (!liff.isLoggedIn()) {
// set `redirectUri` to redirect the user to a URL other than the front page of your LIFF app.
liff.login();
}
});
// logout call only when external browse
document.getElementById('liffLogoutButton').addEventListener('click', function() {
if (liff.isLoggedIn()) {
liff.logout();
window.location.reload();
}
});
實現的流程如下圖:
以上~這樣就把 LIFF SDK 的功能看完了 80% 左右,有很多實用的功能 (例如判斷是不是 OA 好友,判斷登入環境等,尤其是直接取得 User Profile 是最方便實用的功能)
花時間了解 LIFF SDK 的功能後,接下來就是要修改範例程式碼,讓驗證碼小幫手能使用 LIFF 完成一些互動功能囉~