iT邦幫忙

2025 iThome 鐵人賽

DAY 24
1
Modern Web

Line Bot × NestJS:30 天開發日記系列 第 24

Day 24:LIFF 刮刮樂實戰體驗

  • 分享至 

  • xImage
  •  

2025 鐵人賽背景圖

前言

在了解 LIFF 的基礎設計流程後,本文將透過「刮刮樂」案例示範 LIFF API 的實際應用。從啟動時檢查權限與執行環境、確認用戶分享功能權限,到刮刮樂結束後發送訊息並關閉 LIFF,完整呈現 LIFF 在互動應用中的整合流程,幫助大家更清楚理解其實際運作方式。

本日程式碼的範例連結。本文著重於 LIFF API 的整合應用,以刮刮樂為例說明完整的互動流程,刮刮樂的視覺實作細節請參考範例程式碼。

實作目標

本次將打造一個互動式刮刮樂應用,具備以下功能

  • 建立行動裝置刮刮樂體驗:開發一個在行動裝置上運作流暢的刮刮樂網站,支援觸控操作
  • 社群分享機制:刮出獎項後,使用者可將中獎結果分享給 LINE 好友
  • 結果通知功能:自動將刮獎結果透過訊息發送至使用者的聊天室
  • 自動關閉流程:無論使用者是否進行分享操作,完成互動後皆會自動關閉 LIFF 視窗,返回聊天室介面

刮刮樂範例

完整功能影片

資料夾結構說明

本次在 components 目錄中建立了三個核心組件

  • ScratchCard.vue:使用 p5.js 實作刮刮樂互動效果,處理觸控刮除邏輯與視覺呈現
  • PrizeModal.vue:自訂模態框組件,當刮刮樂完全刮開時顯示中獎結果
  • Toast.vue:提示訊息組件,用於顯示分享成功訊息及錯誤提示

用戶裝置及權限驗證

使用到的 LIFF API

  • liff.isLoggedIn():檢查使用者目前是否已登入 LINE 帳號
  • liff.login():當使用者尚未登入時,引導至 LINE 登入畫面進行授權
  • liff.isInClient():檢查使用者是否在 LINE 內建瀏覽器中開啟
  • liff.getOS():取得使用者的作業系統類型,回傳值包含 iosandroidweb 三種
  • liff.isApiAvailable('shareTargetPicker'):檢查使用者的 LINE 版本是否支援分享功能。
/** 檢查並處理用戶登入狀態 */
const checkLoginStatus = (): void => {
  if (!liff.isLoggedIn()) {
    liff.login();
  }
};

/** 驗證用戶裝置及執行環境 */
const validateEnvironment = async (): Promise<boolean> => {
  const userOS = liff.getOS();
  if (!liff.isInClient() || userOS === 'web') {
    await showErrorDialog('請在 LINE 應用程式中開啟此活動');
    closeLiffWindow(3000);
    return false;
  }

  return true;
};

/** 檢查是否支援分享功能 */
const checkShareAvailability = (): boolean => {
  const isAvailable = liff.isApiAvailable('shareTargetPicker');

  if (!isAvailable) {
    showToast('提醒用戶!分享功能不可用', '需要更新 LINE 版本', 'error');
  }

  canShare.value = isAvailable;
  return isAvailable;
};

/** 初始化 LIFF */
const initializeLiff = async (): Promise<void> => {
  try {
    // 初始化 LIFF SDK
    await liff.init({ liffId: import.meta.env.VITE_LIFF_ID });

    // 檢查用戶登入狀態
    checkLoginStatus();

    // 驗證執行環境
    const isValidEnvironment = await validateEnvironment();
    if (!isValidEnvironment) {
      return;
    }

    // 檢查分享功能可用性
    checkShareAvailability();

  } catch (error) {
    console.error("LIFF 初始化失敗:", error);
    showResultMessage('初始化失敗', '請重新整理頁面', 'error');
  }
};

結果通知功能

當使用者刮開刮刮卡並抽中獎項時,系統會在顯示中獎訊息的同時,自動透過 LINE 聊天室發送通知訊息,讓使用者可以保存中獎記錄。

使用到的 LIFF API

  • liff.sendMessages():將中獎結果自動發送至當前 LINE 聊天室,訊息會顯示在與官方帳號的對話視窗中

App.vue script:

/** 發送 LINE 訊息 */
const sendLineMessage = async (message: string): Promise<void> => {
  await liff.sendMessages([
    {
      type: "text",
      text: `🎉 ${message}\n感謝您參與我們的活動!`
    }
  ]);
};

/** 處理刮刮卡完成事件 */
const handleScratchComplete = async (data: { progress: number; message: string }): Promise<void> => {
  try {
    await sendLineMessage(data.message);
    showPrizeMessage(data.message);
  } catch (error) {
    console.error('處理完成訊息時發生錯誤:', error);
    showToast('操作失敗', '請稍後再試', 'error');
  }
};

社群分享機制

透過 LIFF SDK 將中獎訊息即時分享到 LINE 聊天室,提升活動的社群擴散效果。

LINE ShareTargetPicker 分享功能

使用到的 LIFF API

  • liff.shareTargetPicker():開啟 LINE 的分享選擇器,讓使用者可以主動選擇要分享的聊天室或好友。可以在分享訊息中包含 LIFF URL,當其他使用者點擊連結後,被引導加入對應的官方帳號並參與活動

在 shareTargetPicker 的 callback 函數中,應避免使用 alert()、confirm() 等會阻塞執行緒的方法,這可能導致 LIFF 在部分裝置上無法正常運作。因此本次實作皆採用自訂組件來顯示提示訊息。

shareTargetPicker callback 避免阻塞

使用 shareTargetPicker 功能前,要確認以下兩項條件

  • 使用者必須已登入 LINE 帳號
  • 已在 LINE Developers 控制台的 LIFF 應用設定中啟用相關設定

LINE Developers 控制台的 LIFF 應用設定中啟用 shareTargetPicker

shareTargetPicker 支援發送的訊息類型(這部分與 sendMessages 相同)

  • 六種基礎訊息:text、image、video、audio、location、sticker
  • Template Message:buttons、confirm、輪播等樣板訊息
  • Flex Message:高度客製化訊息

只有 imageaudiovideo 訊息可以透過 external 參數標記來源為 LIFF

App.vue template:

  <div id="app">
    <!-- 刮刮樂組件 -->
    <ScratchCard @onCompleted="handleScratchComplete" />

    <!-- 中獎彈窗 -->
    <PrizeModal :show="showModal" :message="prizeMessage" :canShare="canShare" @share="handleShare"
      @close="handleClose" />

    <!-- 結果提示 -->
    <Toast :show="showToastVisible" :title="toastTitle" :text="toastText" :type="toastType" />
  </div>

App.vue script:

/** 分享訊息到 LINE */
const shareToLine = async (message: string): Promise<void> => {
  const liffUrl = `https://liff.line.me/${import.meta.env.VITE_LIFF_ID}`;

  await liff.shareTargetPicker([
    {
      type: "text",
      text: message
    },
    {
      type: "template",
      altText: "刮刮卡活動邀請",
      template: {
        type: "buttons",
        text: "你也來挑戰刮刮卡吧!",
        actions: [
          {
            type: "uri",
            label: "立即參加抽獎",
            uri: liffUrl
          }
        ]
      }
    }
  ]);
};

/** 處理分享按鈕點擊事件 */
const handleShare = async () => {
  showModal.value = false;

  try {
    await shareToLine(prizeMessage.value);
    showToast('分享成功!', '訊息已分享到 LINE');
  } catch (error) {
    console.error('分享失敗:', error);
    showToast('分享失敗', '請稍後再試', 'error');
  } finally {
    closeLiffWindow(1500); // 延遲關閉視窗
  }
};

自動關閉流程

不論使用者是否完成分享,或是直接點擊關閉按鈕,系統都能順利關閉 LIFF 視窗並返回 LINE 聊天室,提供流暢的使用體驗。

使用到的 LIFF API

  • liff.closeWindow():關閉當前 LIFF 瀏覽器視窗,讓使用者返回 LINE 聊天室介面
/** 關閉 LIFF 視窗 */
const closeLiffWindow = (delay: number = 2000): void => {
  setTimeout(() => {
    liff.closeWindow();
  }, delay);
};

LIFF 與官方帳號的連結配置

當需要重新觸發 LIFF 授權畫面時,可以透過以下步驟取消既有的應用程式連結

  • 開啟 LINE 應用程式
  • 前往「主頁」→「設定」→「我的帳號」
  • 點選「連結中的應用程式」
  • 找到已綁定 LINE Login 的頻道並取消連結

完成上述步驟後,下次點選 LIFF 連結時就會重新顯示授權畫面。

LINE Login 頻道綁定官方帳號

在 LINE Developers Console 中,將 Login 頻道與 LINE 官方帳號進行綁定,建立兩者之間的關聯性。

Login 頻道綁定 LINE 官方帳號

LIFF 應用程式加好友選項

在 LIFF 應用程式設定中,可以配置「加好友選項」(Add friend option),讓使用者在授權時可以同步加入官方帳號為好友。

LIFF 加好友綁定官方帳號

LIFF 授權畫面呈現

啟用 LIFF 選項後,使用者在首次開啟 LIFF 應用時,授權畫面會顯示「加入好友」的選項,讓使用者可以一併將官方帳號加為好友。

LIFF 授權加官方帳號畫面

透過這些設定,可以在使用者首次開啟 LIFF 應用時,引導他們加入官方帳號,有助於提升官方帳號的好友數量與後續互動機會。

本日結語

相對於昨天的基礎應用,今天的實作聚焦在單一完整的互動功能上。這個刮刮卡應用可以直接整合到 LINE 圖文選單中,讓使用者點擊後立即參與抽獎,刮開後的中獎結果會自動發送到聊天室,創造即時且有趣的互動體驗。


上一篇
Day 23:LIFF 網頁應用開發入門
系列文
Line Bot × NestJS:30 天開發日記24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言