iT邦幫忙

2025 iThome 鐵人賽

DAY 13
0
Modern Web

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

Day 13:LINE Bot 客製化 Sender 與 Quick Reply 功能實作

  • 分享至 

  • xImage
  •  

2025 鐵人賽背景圖

前言

LINE Bot 所有回覆訊息類型都具備「共用屬性」功能,這些屬性帶來兩項重要的互動體驗提升:

  1. 官方帳號外觀客製化:透過自訂 icon 圖示顯示名稱,讓官方帳號能夠靈活變換不同角色身份與用戶互動。這種功能類似角色扮演,可根據不同情境或用戶需求,打造專屬的對話角色,有效拉近與使用者的距離,創造更個人化的互動體驗。
  2. 快速回覆功能(Quick Reply):提供預設的選項按鈕,讓使用者能夠透過點選方式快速回應,無需手動輸入文字。

接下來,我們把共用屬性整合到六大基礎回覆類型中,讓 LINE Bot 更加個性化!

本日程式碼的範例連結

自定義官方帳號外觀 - 以 Text 舉例

當加入 sender 屬性後,可以客製化 LINE Bot 的頭像及顯示名稱。需要注意的是,這個功能僅會改變對話中的縮圖顯示,使用者無法點開官方帳號查看完整的頭像圖片詳細資訊。

sender 主要參數:

  • name(可選):自訂 LINE Bot 顯示名稱
  • iconUrl(可選):自訂 LINE Bot 對話中顯示的 icon 縮圖。圖片連結必須使用 HTTPS 協定,建議提供 1:1 比例的圖片以避免變形。

Step 1:修改 TextMessageReq 型別,新增 Sender 屬性

line-message/types/text-message.ts

import { Sender } from '@line/bot-sdk';

export interface TextMessageReq {
  text: string;
  emoji?: {
    index: number;
    productId: ProjectIds[number];
    emojiId: Emojis[number];
  };
  sender?: Sender;
}

Step 2:修改 createTextMessage 方法,增加 sender 參數支援

處理方式與 emoji 相同,所有選填參數都可以使用這種條件性展開的模式來處理

當開發者提供 sender 資訊時,系統會自動套用自訂的官方帳號外觀來發送訊息。

  createTextMessage(textMessageReq: TextMessageReq): TextMessage {
    // 解構新增 sender 物件
    const { text, emoji, sender } = textMessageReq;

    let modifiedText = text;

    if (emoji) {
      const emojiIndex = emoji.index;
      const placeholderChar = '~';
      const textArr = Array.from(text.padStart(emojiIndex, placeholderChar));
      textArr.splice(emojiIndex, 0, '$ ');
      modifiedText = textArr.join('');
    }

    const textMessage: TextMessage = {
      type: MessageType.Text,
      text: modifiedText,
      ...(emoji && {
        emojis: [
          {
            index: emoji.index,
            productId: emoji.productId,
            emojiId: emoji.emojiId,
          },
        ],
      }),
      ...(sender && { sender }), // 條件性加入 sender 屬性,用於客製化官方帳號外觀
    };

    return textMessage;
  }

Step 3 提供 Sender 客製化 LINE Bot 發送資訊

line-webhook/line-webhook.service.ts

const messageEventHandlerMap = {
  text: (message) =>
    this.lineMessageService.createTextMessage({
      text: message.text,
      emoji: {
        index: 0,
        productId: '5ac21c4e031a6752fb806d5b',
        emojiId: '006',
      },
      // 自訂發送者名稱及頭像
      sender: {
        name: '狗狗助理',
        iconUrl: 'https://res.cloudinary.com/dseg0uwc9/image/upload/w_1000,ar_1:1,c_fill,g_auto,e_art:hokusai/v1753953684/2025%20IT%20%E9%90%B5%E4%BA%BA%E8%B3%BD/dog_icon_grxcsl.jpg',
      },
    }),
} satisfies Partial<MessageEventHandlerMap>;

成果展示

即使後續改變了 LINE Bot 官方帳號的設定,先前使用自訂名稱和頭像發送的訊息紀錄仍會保持原樣,不會被覆蓋更新。

LINE Bot 自定義頭像及名稱

快速回覆 Quick Reply - 以 Text 為例

Quick Reply 功能主要在提升使用者體驗,讓使用者無需手動輸入,僅需點擊即可觸發對應功能。此功能在早期版本中僅限於行動裝置使用,電腦版無法正常顯示。目前在行動裝置跟電腦上都可以看到囉。

Quick Reply 的核心參數為 action,用於定義點擊後的執行動作。最基本的應用場景是自動發送預設訊息。這個 action 概念與圖文選單(Rich Menu)相似,都是透過定義動作來響應使用者操作。

Quick Reply 主要參數:

  • action(必填):定義點擊後的執行動作
  • imageUrl(選填):快速回覆按鈕的 icon 圖示

Step 1:修改 TextMessageReq 型別,加上 quickReplyItems 屬性

新增 quickReplyItems 屬性來支援快速回覆功能。為簡化開發體驗,將 type 從型別定義中移除,改由 createTextMessage 函式統一處理。

line-message/types/text-message.ts

import { Sender, QuickReplyItem } from '@line/bot-sdk';

export interface TextMessageReq {
  text: string;
  emoji?: {
    index: number;
    productId: ProjectIds[number];
    emojiId: Emojis[number];
  };
  sender?: Sender;
  quickReplyItems?: Omit<QuickReplyItem, 'type'>[];
}

Step 2:修改 createTextMessage 增加 quickReplyItems 參數

quickReplyItems 最多只能放置 13 個按鈕

LINE 官方的 Quick Reply 參數使用 items 命名,對初學者較不直觀。為提升程式碼可讀性,改用更具語意的 quickReplyItems 參數命名,讓開發者更清楚理解其用途。

line-message/line-message.service.ts

  createTextMessage(textMessageReq: TextMessageReq): TextMessage {
    // 解構新增 quickReplyItems 物件
    const { text, emoji, sender, quickReplyItems } = textMessageReq;

    let modifiedText = text;

    // 處理 emoji 替換位置的問題
    if (emoji) {
      const emojiIndex = emoji.index;
      const placeholderChar = '~';
      const textArr = Array.from(text.padStart(emojiIndex, placeholderChar));
      textArr.splice(emojiIndex, 0, '$ ');
      modifiedText = textArr.join('');
    }

    const textMessage: TextMessage = {
      type: MessageType.Text,
      text: modifiedText,
      ...(emoji && {
        emojis: [
          {
            index: emoji.index,
            productId: emoji.productId,
            emojiId: emoji.emojiId,
          },
        ],
      }),
      ...(sender && { sender }),
      ...(quickReplyItems && {
        quickReply: { 
          items: quickReplyItems.map((quickReplyItem) => ({
            type: 'action',
            ...quickReplyItem,
          })),
        },
      }),
    };

    return textMessage;
  }

Step 3 提供 quickReplyItems 協助使用者快速回覆

imageUrl 為選填參數,即使不提供此參數也可以正常使用 Quick Reply 功能。

Quick Reply Action 主要參數(以 message action 為例):

  • label:顯示在快速回覆按鈕上的文字
  • text:使用者點擊後實際發送的訊息內容

line-webhook/line-webhook.service.ts

const messageEventHandlerMap = {
  text: (message) =>
        this.lineMessageService.createTextMessage({
          text: message.text,
          emoji: {
            index: 0,
            productId: '5ac21c4e031a6752fb806d5b',
            emojiId: '006',
          },
          sender: {
            name: '狗狗助理 v2',
            iconUrl:
              'https://res.cloudinary.com/dseg0uwc9/image/upload/w_1000,ar_1:1,c_fill,g_auto,e_art:hokusai/v1753953684/2025%20IT%20%E9%90%B5%E4%BA%BA%E8%B3%BD/dog_icon_grxcsl.jpg',
          },
          quickReplyItems: [
            {
              imageUrl: 'https://res.cloudinary.com/dseg0uwc9/image/upload/w_1000,ar_1:1,c_fill,g_auto,e_art:hokusai/v1753953684/2025%20IT%20%E9%90%B5%E4%BA%BA%E8%B3%BD/dog_icon_grxcsl.jpg',
              action: {
                type: 'message',
                label: '天氣',
                text: '天氣',
              },
            },
            // 略
          ],
        })
} satisfies Partial<MessageEventHandlerMap>;

成果展示

點擊快速回覆按鈕後,系統會自動發送對應的文字訊息。若在 Quick Reply Item 中設定 imageUrl 參數,圖示會顯示在按鈕旁邊。

LINE Quick Reply 成果展示

本日結語

客製化官方帳號名稱功能目前已在部分 LINE 官方帳號中實際應用,透過結合用戶個人設定,讓使用者能進行一定程度的客製化。這項功能的實作原理是將用戶的客製化設定儲存在資料庫中,雖然所有用戶使用的是同一個官方帳號,但每個人都能獲得不同的「專屬感」體驗。


上一篇
Day 12:LINE Bot Image、Video、Audio、Location 訊息回覆
下一篇
Day 14:LINE Bot Template Message 訊息回覆
系列文
Line Bot × NestJS:30 天開發日記14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言