iT邦幫忙

2021 iThome 鐵人賽

DAY 15
0
自我挑戰組

從無到有打造驗證碼共享的 Line 機器人系列 第 15

應用 LINE Front-end Framework 輕鬆建立互動 (3)

  • 分享至 

  • xImage
  •  

今天繼續搭配 LIFF 的文件研究 Line LIFF App line-liff-v2-starter 的範例

public 底下的靜態檔案

  • public
    • index.html
      1. 利用 <title>LIFF Starter</title> 設置 LIFF App 的標題
      2. 採用 CDN 方式引入 Line LIFF SDK
    • liff-starter.js
      主要使用 LIFF SDK 的檔案,是我們今天研究的重點
      開頭的這部分程式碼,就是昨天有提到的利用 route 去獲取環境變數 LIFF_ID,然後將拿回來的 myLiffId 丟到 `initializeLiffOrDie(myLiffId);` 進行 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);
          }
      };
      
    • style.css
      網頁的 css 排版設置

Developing a LIFF app

Developing a LIFF app 講述了如何開發一個 LIFF app,裡面有幾個章節跟今天的範例有關:

  1. Setting the title of the LIFF app
    可以看到 public/index.html 裡用 HTML TAG <title>LIFF Starter</title> 設置 LIFF Starter 為 LIFF App 的標題

  2. Integrating the LIFF SDK with the LIFF app

    • Specify the CDN path
      範例底下的 public/index.html 正是使用這種方法引入 LIFF SDK
      <!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>
      
    • Use the npm package
      如果有使用 npm package 或其他打包工具進行開發,可以使用這種方式引入 LIFF SDK
  3. Calling the LIFF API

    • Initializing the LIFF app
      初始化 LIFF APP 的部分,在範例程式碼分成以下三段:
      1. 如果 myLiffId 不為 null 才繼續進行初始化 initializeLiff(myLiffId);
      2. call LIFF SDK liff.init() initializing-liff-app ,若初始化成功則繼續執行 initializeApp();
      3. initializeApp();
        • displayLiffData(); 使用 LIFF SDK 取得並顯示 LIFF APP 環境基本資訊
          displayLiffData
        • 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;
        }
    }
    
    • Getting the environment in which the LIFF app is running
      • 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();
      }
      

registerButtonHandlers()

接著就讓我們來看看範例程式的每一個按鈕 click 做了什麼事情:

/**
* Register event handlers for the buttons displayed in the app
*/
function registerButtonHandlers() {
    // button handlers...
}

openWindow

Opening a URL 開啟一個網頁,可以在 Line 內建瀏覽器呼叫,也可以在外部瀏覽器呼叫

// openWindow call
document.getElementById('openWindowButton').addEventListener('click', function() {
    liff.openWindow({
        url: 'https://line.me',
        external: true
    });
});

closeWindow

Closing the LIFF app 關閉現在開啟中的 LIFF APP,在外部瀏覽器時無效

// closeWindow call
document.getElementById('closeWindowButton').addEventListener('click', function() {
    if (!liff.isInClient()) {
        sendAlertIfNotInClient();
    } else {
        liff.closeWindow();
    }
});

sendMessages

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

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);
    });
});

shareTargetPicker

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>";
    }
});

效果如示意圖:
shareTargetPicker

Performing a login process

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();
    }
}); 

實現的流程如下圖:
Performing a login process

以上~這樣就把 LIFF SDK 的功能看完了 80% 左右,有很多實用的功能 (例如判斷是不是 OA 好友,判斷登入環境等,尤其是直接取得 User Profile 是最方便實用的功能)

花時間了解 LIFF SDK 的功能後,接下來就是要修改範例程式碼,讓驗證碼小幫手能使用 LIFF 完成一些互動功能囉~


上一篇
應用 LINE Front-end Framework 輕鬆建立互動 (2)
下一篇
Line Bot 發送文字訊息外的格式 (Message types)
系列文
從無到有打造驗證碼共享的 Line 機器人30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言