Day 13:LINE Bot 客製化 Sender 與 Quick Reply 功能實作
4.4k 字,約 5 分鐘
2025 iThome 鐵人賽:Line Bot × NestJS:30 天開發日記。 原文發表於 iThome,也可以在下方留言。
前言
LINE Bot 所有回覆訊息類型都具備「共用屬性」功能,這些屬性帶來兩項重要的互動體驗提升:
- 官方帳號外觀客製化:透過自訂
icon 圖示和顯示名稱,讓官方帳號能夠靈活變換不同角色身份與用戶互動。這種功能類似角色扮演,可根據不同情境或用戶需求,打造專屬的對話角色,有效拉近與使用者的距離,創造更個人化的互動體驗。 - 快速回覆功能(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 官方帳號的設定,先前使用自訂名稱和頭像發送的訊息紀錄仍會保持原樣,不會被覆蓋更新。
快速回覆 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 官方帳號中實際應用,透過結合用戶個人設定,讓使用者能進行一定程度的客製化。這項功能的實作原理是將用戶的客製化設定儲存在資料庫中,雖然所有用戶使用的是同一個官方帳號,但每個人都能獲得不同的「專屬感」體驗。
留言
留言使用 GitHub 帳號登入(Giscus),留言會存在 GitHub Discussions。