应用 LINE Front-end Framework 轻松建立互动 (3)

今天继续搭配 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 完成一些互动功能罗~


<<:  【LeetCode】Backtracking

>>:  [01] 所以是哪个 P ? 前言

详解资料仓库的实施步骤,实战全解!(2)

建立资料仓库是一个解决企业资料问题应用的过程,是企业资讯化发展到一定阶段必不可少的一步,也是发展资...

Python 做自动化编译 相关指令汇整

有些公司因为历史原因 在Build react,vue,npm等相关专案 需经过 前置的处理作业 这...

[Java Day09] 3.2. switch

教材网址 https://coding104.blogspot.com/2021/06/java-s...

大共享时代系列_026_第三方物流(Third-Party logistics,3PL)

仓储+物流,术有专攻,让专业的来~ 降低电商营运时要租赁仓储、开发库存系统等的门槛~ 通通外包给第三...

鬼故事 - 这东西真烂

鬼故事 - 这东西真烂 Credit: Corentin Penloup 灵感来源:https://...