Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

[Vue]初探LIFF的一些筆記-開發篇

內容目錄

初探LIFF的一些筆記

最近因為chatGPT很紅因素,很多人將chatGPT與line整合一起,在玩這類專案時剛好碰到了line的API服務於是認識到LIFF,今天花點時間整理關於開發LIFF遇到的狀況。
LIFF ( LINE Front-end Framework ) 是Line推出的一種前端框架,可以將功能與Line直接整合,藉此取得使用者user資料、進行部分操作。
用這玩意能完美的與Line bot連動,透過使用 Line Login 或 Account Link 的網站進行使用者資料串接,進而製作更全面性的整合行銷服務。
我用Vue3進行串接開發,使用setup script。

使用LIFF

請參考LIFF的一些筆記-申請篇

載入

使用LIFF SDK可以直接用CDN引入

<script src="https://static.line-scdn.net/liff/edge/2/sdk.js"></script>

在Vue話,我是先透過npm安裝

npm install vue-router@next @line/liff

使用Vue3的setup script,載入SDK

<script setup>
import liff from "@line/liff";
</script>

後面就可以直接用囉。

初始化

啟動 LIFF 前需要先初始化(init),在 Vue 的話就在 Mounted 實作這件事情。

onMounted(async () => {
  liff
  .init({
    liffId: "<LIFF ID>", // 從LIFF頁面中拿到的ID
  })
  .then(() => { 
  //做你想要做的
  })
  .catch((err) => {
    console.log(err.code, err.message);
  });
})

登入與登出

登入後的redirectUri最好是跟LIFF頁面上設定的Callback URL相同,當然你可以依照需求轉到你要的地方。

if(!sysdata.isLoggedIn) {
    liff.login({
      redirectUri: window.location.href //登入後轉址到需要的地方
    });
  }

登出就比較單純

 if(sysdata.isLoggedIn) {
    liff.logout();
    window.location.reload(); // 登出後重整一次頁面
  }

取得基本資訊

我將取得資訊跟初始化寫在一起,範例如下。

  • 打開頁面中的使用語系(lang)
  • LIFF SDK 的版本
  • 目前 LIFF 是否是在 LINE App 中開啟
  • 使用者有沒有登入 LINE 帳號
  • 使用者的作業系統:web、android、ios
  • 使用者用的 LINE App 版本

    onMounted(async () => {
    liff
    .init({
    liffId: "", // 從LIFF頁面中拿到的ID
    })
    .then(() => {
    sysdata.language = liff.getLanguage(); // String。引用 LIFF SDK 的頁面,頁面中的 lang 資料
    sysdata.version = liff.getVersion(); // String。取得LIFF SDK 的版本
    sysdata.isInClient = liff.isInClient(); // Boolean。回傳是否由 LINE App 存取
    sysdata.isLoggedIn = liff.isLoggedIn(); // Boolean。檢查使用者是否登入 LINE 帳號狀態。true 時,可呼叫需要 Access Token 的 API
    sysdata.os = liff.getOS(); // String。取得使用者的作業系統:ios、android、web
    sysdata.lineVersion = liff.getLineVersion(); // 使用者的 LINE 版本
    console.log(sysdata.language,sysdata.version,sysdata.isInClient,sysdata.isLoggedIn,sysdata.os,sysdata.lineVersion);
    
    })
    .catch((err) => {
    console.log(err.code, err.message);
    });
    })

    這邊要再講一下,申請完LIFF後會有個原來的Endpoint URL和LIFF上的LIFF URL,兩邊的LIFF SDK都會作用,但取得的權限不同(見下段落),如果需要在LINE做一些操作,最好使用LIFF URL給使用者打開。

取得使用者資訊

取得使用者資訊使用這個api,取得後可以檢查使用者賦予的權限和一些資料,必須要使用者必須登入才能使用。

userdata.context = liff.getContext();

回傳有以下幾種資料

  • type: utou(一對一聊天)、group(群組)、room(多人聊天室)、external(外部,通常是瀏覽器)、none(除以上外)。
  • viewType:compact、tall、full。目前視窗的尺寸,可以在LIFF中設定。
  • userId、groupId、roomId:不同的 type 會有不同的 ID。
  • availability.shareTargetPicker.permission:能不能使用 shareTargetPicker 功能,可以在LIFF中打開。
  • availability.shareTargetPicker.minVer:使用 shareTargetPicker 功能的需求版本是多少。

這邊就要提醒一下,Endpoint URL和LIFF URL打開來得到的使用者資訊是不同的,前者type為external後者為utou(如果是bot聊天)。

取得使用者公開資料

必須要使用者必須登入才能使用。回傳資料有四個:userId、暱稱、照片的圖片位置、狀態消息。除了userId外皆屬於完全公開資訊。

liff.getProfile()
    .then(function(profile) {
    userdata.profile = profile;
    console.log(userdata.profile);
});

取得使用者 email

必須要使用者必須登入才能使用。也必須先在LIFF打開權限,並且使用者登入時需授權。

還要打開LIFF的Scopes權限(email*)

 const user = liff.getDecodedIDToken();
    userdata.user = user

發送訊息

使用者必須登入才能使用,分為對自己和對其他人。要先打開LIFF的Scopes權限(chat_message.write),並且使用者在登入時要授權。

對自己發送

只能在Line APP才能使用此功能,而且需要一對一聊天室,使用者資料的type須為utou,如果為group、room沒測試不知道能不能使用。external則不行。

const sendMessegeToSelf = () => {
  // 傳送訊息給自己
  // type 的可用值說明:https://developers.line.biz/en/reference/liff/#send-messages
  liff.sendMessages([
    {
      type: 'text',
      text: <發送訊息>
    }
  ])
  .then(res => window.alert(res.status))
  .catch(error => window.alert(error));
}

對其他人發送

type為external也可以使用,但記得要先開啟shareTargetPicker

const sendMessegeToOther = () => {
  // 傳送訊息給朋友
  // 發訊息的可用參數:https://developers.line.biz/en/reference/liff/#share-target-picker
  if(sysdata.isLoggedIn && liff.isApiAvailable('shareTargetPicker')) {
    liff.shareTargetPicker([
      {
        type: "text",
        text: <發送訊息>
      }
    ])
    .then(res => window.alert(res.status))
    .catch(error => window.alert(error))
  }
}

QRcode

很多人都會介紹,但IOS目前不能用,所以先筆記一下

liff.scanCode()
  .then(function(res) {
    console.log(res);
  })
  .catch(function(error) {
    console.log(error);
  });