# LINE Chatbot 開發手札 - LIFF

## 關於版本

LIFF, LINE Front-end Framework, 是LINE加值客製化的其中之一。現在(20201年5月) LIFF的版本發展到第二版，LIFF v2，第二版與第一版落差很大。我們重點只放在第二版。會談這一點是因為網上關於LIFF的討論文章仍有一定以上比例其實是LIFF v1的文章。

## 入門參考文章

這篇文是比較完整且有應用的，有提到重點。LIFF的重點在應用：

一、透過 LINE 整合登入。\
二、取得使用者公開的資訊。\
三、取得系統環境參數。

{% embed url="<https://www.letswrite.tw/liff-init/>" %}

LIFF 的登入機制，即 LIFF URL，是可以帶入Query 參數的。

{% embed url="<https://engineering.linecorp.com/zh-hant/blog/new-liff-url-infomation/>" %}

當然，一切的基準仍以官網為主。

{% embed url="<https://developers.line.biz/en/docs/liff/developing-liff-apps/>" %}

## LIFF 登入

其中LIFF登入機制，算是比較難的部份。它至少會轉址二次，有路徑參數的話會轉址三次。1) 轉到LINE OAuth UI page，2) 轉到 LIFF URL page，3) 再轉址到目的地 page。

下圖是官方的登入機制循序圖(Sequence Diagram)。

![](https://1542098896-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MELfcKhs_sQAlJasLM9%2F-MaQrYHke1iWJhqoHyr2%2F-MaQxAZgSFt50PlgY5eO%2Fimage.png?alt=media\&token=e333c79f-62a2-4803-8031-28e1bac87650)

簡化如下，

```javascript
liff.init 
// 初始化LIFF API，
// 很特別的是，若進入時URL有夾帶轉址資訊則將會自動轉址。

liff.get環境參數
// 初始化LIFF後就可以取得一些環境參數，如：
// liff.getLanguage();
// liff.getVersion();
// liff.getOS();
// liff.getLineVersion();
// liff.isInClient();

if(liff.isLoggedIn) {
  // 必需是登入狀態才能取得使用者公開的個資
  liff.getProfile
} else {
  // 導入 LINE OAuth 登入程序，至少轉址二次。
  // ※ 成功的話將會再導回此頁，且此時的狀態是已登入LIFF了。
  liff.login
}
```

## 程式碼紀錄

{% code title="\_LIFF\_scripts.cshtml" %}

```aspnet
@* 開發發環境是 MVC5 *@
@* for LIFF init & login & redirect-in *@
@{
    String LIFF_ID = ConfigurationManager.AppSettings["LIFF_ID"] ?? "";
    String salesId = Request.Params["salesId"] ?? "";
}

<script charset="utf-8" src="https://static.line-scdn.net/liff/edge/2/sdk.js"></script>
<script>
    $(function () {
        /**
        * Initialize LIFF
        * param {string} myLiffId The LIFF app ID of the selected element
        */
        function initializeLiff(liffId)
        {
            liff.init({ liffId: liffId }).then(() => {
                // start to use LIFF's api
                console.log('LIFF init 成功',)
                initializeApp();
            }).catch((err) => {
                console.log('LIFF init 失敗!', err);
                document.getElementById("liffAppContent").classList.add('hidden');
                document.getElementById("liffInitErrorMessage").classList.remove('hidden');
            });
        }

        function initializeApp()
        {
            //// Redirect to another page after the returned Promise object has been resolved
            //location.replace("https://line.me/{liffId}/path");

            if (!liff.isLoggedIn())
            {
                console.log('LIFF 未登入',)
                const redirectUri = window.location.href;
                liff.login({ redirectUri });
                // 若登入LIFF成功，將會再 redirect Uri 回到此頁面。
                return;
            }

            liff.getProfile().then(data => {
                console.log('lineProfile', data);
                // to refresh UI
                var form = $('form');
                $(form).find('#lineId').val(data.userId);
                $(form).find('#lineDisplayName').val(data.displayName);
                $(form).find('#salesId').val('@salesId');
                $(form).find('#liff_displayName').html(data.displayName);
            });
        }

        // Document is ready
        var liffId = '@LIFF_ID';
        initializeLiff(liffId);
    });
</script>

```

{% endcode %}

EOF
