正在載入索引…

Day 12:LINE Bot Image、Video、Audio、Location 訊息回覆

3.0k 字,約 3 分鐘

2025 iThome 鐵人賽:Line Bot × NestJS:30 天開發日記。 原文發表於 iThome,也可以在下方留言。

文章目錄
  1. 前言
    1. Image Message 訊息封裝及處理
      1. Step 1:定義 Image Message 型別
      2. Step 2:新增 createImageMessage 函式生成圖片訊息
      3. Step 3:封裝 LINE Image Message 訊息處理流程
      4. 成果展示
    2. Video、Audio Message 傳輸格式差異說明
      1. Video Message 型別
      2. 成果展示
      3. Audio Message 型別
      4. 成果展示
    3. Location Message 訊息封裝及處理
      1. Location Message 流程處理
      2. 成果展示
    4. 本日結語

前言

Day 11 文章中,我們針對 LINE Bot 可以回覆的Text及Sticker基礎型別進行了封裝,不僅新增了 line-message.ts模組,還讓開發者可以用最少的參數產生 LINE Message 所需要的格式。

今天我們會繼續完成剩餘的四種基礎型別 Image、Video、Audio 及 Location,讓 LINE Bot 可以根據收到的基礎型別回應對應的基礎型別。

本文使用的圖片、音訊及影片檔案均採用 Cloudinary 作為主要檔案儲存服務,利用其可快速產生 HTTPS 公開連結的特性,與 LINE Bot 應用結合。

本日程式碼的範例連結

Image Message 訊息封裝及處理

在處理媒體類型的相關訊息時,我們會發現參數大多分為兩類:預覽用途和實際傳輸的媒體資訊。這部分封裝相對簡單,唯一需要注意的是,不論是預覽用途或實際傳輸的媒體資訊,都必須使用經過 HTTPS 加密驗證的連結才能正常運作。

Step 1:定義 Image Message 型別

避免使用者輸入非 HTTPS URL

line-message/types/image-message.js

ts
type HttpsURL = `https://${string}`;

export type ImageMessageReq = {
  originalContentUrl: HttpsURL;
  previewImageUrl: HttpsURL;
};

Step 2:新增 createImageMessage 函式生成圖片訊息

Image 訊息需要預覽圖片連結(previewImageUrl)和點擊後顯示的完整圖片連結(originalContentUrl)

line-message/line-message.service

ts
createImageMessage(imageMessageReq: ImageMessageReq): ImageMessage {
    const { originalContentUrl, previewImageUrl } = imageMessageReq;

    const imageMessage: ImageMessage = {
      type: MessageType.Image,
      originalContentUrl,
      previewImageUrl,
    };

    return imageMessage;
}

Step 3:封裝 LINE Image Message 訊息處理流程

當接收到圖片訊息時,回覆圖片訊息

line-webhook/line-webhook.service.ts

ts
const messageEventHandlerMap = {
      image: () =>
        this.lineMessageService.createImageMessage({
          previewImageUrl:
            'https://res.cloudinary.com/dseg0uwc9/image/upload/v1752220509/2025%20IT%20%E9%90%B5%E4%BA%BA%E8%B3%BD/569400594147311960.jpg',
          originalContentUrl:
            'https://res.cloudinary.com/dseg0uwc9/image/upload/v1752220509/2025%20IT%20%E9%90%B5%E4%BA%BA%E8%B3%BD/569400594147311960.jpg',
        }),
    } satisfies Partial<MessageEventHandlerMap>;

成果展示

Video、Audio Message 傳輸格式差異說明

  • 封裝方式與 Image 幾乎相同,主要差異在於必填參數的細節處理,以下將重點說明各自的不同之處

Video Message 型別

僅支援 mp4 格式,檔案大小上限為 200 MB

需要提供兩個核心參數:

  • 完整影片檔案的 HTTPS 連結(originalContentUrl)
  • 預覽圖片的 HTTPS 連結 (previewImageUrl)

line-message/types/video-message.ts

ts
type HttpsURL = `https://${string}`;

export type VideoMessageReq = {
  originalContentUrl: HttpsURL;
  previewImageUrl: HttpsURL;
};

成果展示

Audio Message 型別

僅支援 mp3 或 m4a 格式,檔案大小上限為 200 MB

需要提供兩個關鍵參數:

  • 音訊檔案的 HTTPS 連結(originalContentUrl)
  • 音訊播放時長,單位為毫秒(duration)

如果設定的播放時長超過音訊檔案的實際長度,播放器會在音訊結束後自動停止,而不會播放到設定的完整時長!

line-message/types/audio-message.ts

ts
type HttpsURL = `https://${string}`;

export type AudioMessageReq = {
  originalContentUrl: HttpsURL;
  duration: number;
};

成果展示

Location Message 訊息封裝及處理

座標訊息通常可以搭配官方帳號向使用者提供店家位置資訊,使用者點擊後就能直接開啟 Google Maps 查看具體位置。

Location Message 流程處理

Location Message 需要提供四個核心參數

  • 地點標題(title)
  • 地點地址(address)
  • 緯度座標(latitude)
  • 經度座標(longitude)

建議經緯度可以直接透過 Google 地圖取得!針對想要分享的地址地標點選右鍵,就可以看到緯度及經度資訊。

line-message / line-message.service

緯度合法值範圍為 -90 至 90,經度合法值範圍為 -180 至 180,針對使用者傳入參數進行有效區間的判斷與修正

ts
createLocationMessage(
  locationMessageReq: LocationMessageReq,
): LocationMessage {
  const { title, address, latitude, longitude } = locationMessageReq;
  
  // 經緯度有效區間判斷
  const minLatitude = -90;
  const maxLatitude = 90;
  const minLongitude = -180;
  const maxLongitude = 180;
  
  const locationMessage: LocationMessage = {
    type: MessageType.Location,
    title,
    address,
    latitude: Math.max(Math.min(latitude, maxLatitude), minLatitude),
    longitude: Math.max(Math.min(longitude, maxLongitude), minLongitude),
  };
  return locationMessage;
}

成果展示

本日結語

目前我們已經把 LINE Bot 的六種基礎回覆方式都介紹過了,看起來其實比想像中單純許多。剛開始接觸時,可能會覺得文件功能繁雜,但只要仔細閱讀,就能逐步理解各種類型所需的參數與特性,在合適的情境中使用即可。

另外,我目前還沒看過官方帳號回覆語音訊息,也一時想不到合適的應用場景,如果你有想法,歡迎和我分享。

留言

留言使用 GitHub 帳號登入(Giscus),留言會存在 GitHub Discussions。