flex-html-render
v1.1.2
Published
將 HTML 字串轉換為 LINE Flex Message JSON 結構的工具
Downloads
665
Maintainers
Readme
flex-html-render
flex-html-render 是一個將 HTML 字串轉換為 LINE Flex Message JSON 結構的工具,方便開發者以 HTML 標記語法設計 Flex Message,並自動轉換為 LINE Messaging API 所需的格式。
Demo 頁面
特色
- 以 HTML 字串描述 Flex Message 結構
- 自動解析 HTML 並轉換為 Flex Message JSON
- 支援多種 Flex Message 元素
- 易於整合於 Node.js 或前端專案
安裝
npm install flex-html-render使用方式
import convertHtmlToFlexMessage from 'flex-html-render';
const htmlString = `
<bubble>
<body>
<box layout="vertical">
<text>這是一個 Flex Message</text>
</box>
</body>
</bubble>
`;
const flexMessage = convertHtmlToFlexMessage(htmlString);
console.log(JSON.stringify(flexMessage, null, 2));
// 將產生的 JSON 放入 LINE Messaging API 的訊息結構中
const message = {
type: 'flex',
altText: 'Flex Message',
contents: flexMessage[0] // 因為 convertHtmlToFlexMessage 回傳陣列,取第一個元素
};注意:此套件產生的 JSON 物件應放置在 LINE Messaging API 中 type 為 flex 的訊息物件的 contents 區塊內。詳細請參考 LINE Flex Message 官方文件。
API
convertHtmlToFlexMessage(htmlString)
- 參數:
htmlString(string) - Flex Message 對應的 HTML 字串 - 回傳:Flex Message JSON 物件陣列
- 說明:此函數將 Flex Message HTML 字串轉為 JSON 結構,可用於編輯或顯示目的
convertJsonToHtml(json)
- 參數:
json(object) - Flex Message JSON 物件 - 回傳:對應的格式化 HTML 字串
- 說明:此函數將 Flex Message JSON 結構轉為 HTML 字串,可用於編輯或顯示目的
支援的 Flex Message 元素
本工具支援大部分 LINE Flex Message 元素,包括:
- bubble
- carousel
- box
- text
- image
- video
- button
- icon
- separator
詳細 Flex Message 元素與屬性請參考 LINE 官方文件。
標籤類型說明 (types.js)
容器標籤 (Container Tags)
<bubble>- Flex Message 的基本容器,只能包含 top-level 區塊標籤<carousel>- 輪播容器,只能包含<bubble>標籤,最多 12 個
頂層區塊標籤 (Top-level Section Tags)
這些標籤只能直接放在 <bubble> 內,且每個只能有一個子元素:
<header>- 標題區塊<hero>- 英雄圖區塊<body>- 主體內容區塊<footer>- 頁尾區塊
元件標籤 (Component Tags)
<box>- 容器元件,需指定layout屬性(vertical、horizontal、baseline)<text>- 文字元件,可包含多個<span>子元素<span>- 文字片段元件,只能有一個文字子節點<image>- 圖片元件,需指定url屬性<video>- 影片元件,必須包含一個<box>或<image>作為altContent<icon>- 圖示元件,需指定url屬性<separator>- 分隔線元件<button>- 按鈕元件,必須包含一個<action>子元素
便捷標籤 (Convenience Tags)
這些是對常用設定的簡寫標籤:
<div>,<article>- 等同於<box><baseline>- 等同於<box layout="baseline"><row>- 等同於<box layout="horizontal"><vertical>- 等同於<box layout="vertical"><strong>- 自動設定weight="bold"的文字標籤<space size="n">- 產生 n 個空格的 span 元件(預設 size=1)
特殊功能標籤
<action>- 動作設定標籤,必須放在需要添加動作的元件內(如<button>、<box>、<image>等)<background>- 背景設定標籤,只能放在 Box 相關標籤內(<box>、<baseline>、<row>、<vertical>)<style>- 樣式設定標籤,只能放在 top-level 區塊標籤內(<header>、<hero>、<body>、<footer>)
特殊標籤使用規則
1. <bubble> 容器規則
<bubble> 只能包含 top-level 區塊標籤(header、hero、body、footer),不能直接包含其他元件。
<!-- ✅ 正確 -->
<bubble>
<header>
<box layout="vertical">
<text>標題</text>
</box>
</header>
<body>
<box layout="vertical">
<text>內容</text>
</box>
</body>
</bubble>
<!-- ❌ 錯誤 - 不能直接包含 box -->
<bubble>
<box layout="vertical">
<text>內容</text>
</box>
</bubble>2. <action> 使用規則
<action> 標籤必須放在需要添加互動行為的元件內部,會自動從子元素中提取並設定為該元件的 action 屬性。
<!-- 按鈕必須包含 action -->
<button>
<action type="uri" uri="https://example.com" />
</button>
<!-- Box 元件添加點擊動作 -->
<box layout="vertical">
<text>點擊這個 Box</text>
<action type="uri" uri="https://example.com" />
</box>
<!-- Image 元件添加點擊動作 -->
<image url="https://example.com/image.png">
<action type="uri" uri="https://example.com" />
</image>3. <background> 使用規則
<background> 標籤只能放在 Box 相關標籤內(<box>、<baseline>、<row>、<vertical>),用於設定背景。
<!-- ✅ 正確 - 在 box 內使用 -->
<box layout="vertical">
<background type="linearGradient" angle="90deg" startColor="#ff0000" endColor="#0000ff" />
<text>有漸層背景的 Box</text>
</box>
<!-- ✅ 正確 - 在 vertical 內使用 -->
<vertical>
<background type="linearGradient" angle="0deg" startColor="#ffff00" endColor="#00ff00" />
<text>有背景的垂直容器</text>
</vertical>
<!-- ❌ 錯誤 - 不能在 text 內使用 -->
<text>
<background type="linearGradient" angle="0deg" startColor="#ffff00" endColor="#00ff00" />
文字
</text>4. <style> 使用規則
<style> 標籤只能放在 top-level 區塊標籤內(<header>、<hero>、<body>、<footer>),用於設定該區塊的樣式屬性,如背景色等。各區塊標籤只能有一個 <style> 子元素。最終會整合為一個 styles 屬性到 bubble 的 JSON 結構中。
<!-- ✅ 正確 - 在 header 內使用 -->
<header>
<style backgroundColor="#ff0000" />
<box layout="vertical">
<text>有背景色的標題</text>
</box>
</header>
<!-- ❌ 錯誤 - 不能在 box 內使用 -->
<box layout="vertical">
<style backgroundColor="#ff0000" />
<text>文字</text>
</box>5. <strong> 使用方式
<strong> 標籤會自動轉換為 <text weight="bold">,用於顯示粗體文字。
<box layout="vertical">
<strong>這是粗體文字</strong>
<text>這是一般文字</text>
</box>6. <space> 使用方式
<space> 標籤用於在文字中插入空格,可透過 size 屬性指定空格數量。
<text>
<span>Hello</span>
<space size="3" />
<span>World</span>
</text>7. 便捷 Box 標籤(<baseline>、<row>、<vertical>)
這些標籤是 <box> 的簡寫形式,省去了 layout 屬性的設定。
<!-- baseline: 基線對齊佈局 -->
<baseline>
<text>左側文字</text>
<text>右側文字</text>
</baseline>
<!-- row: 水平佈局 -->
<row>
<image url="https://example.com/icon.png" />
<text>橫向排列</text>
</row>
<!-- vertical: 垂直佈局 -->
<vertical>
<text>第一行</text>
<text>第二行</text>
</vertical>8. <carousel> 使用規則
<carousel> 只能包含 <bubble> 子元素,且最多 12 個。
<carousel>
<bubble>
<body>
<box layout="vertical">
<text>第一個 Bubble</text>
</box>
</body>
</bubble>
<bubble>
<body>
<box layout="vertical">
<text>第二個 Bubble</text>
</box>
</body>
</bubble>
</carousel>9. <video> 使用規則
<video> 必須包含一個 <box> 或 <image> 作為 altContent(影片無法播放時的替代內容)。
<video url="https://example.com/video.mp4" previewUrl="https://example.com/preview.jpg">
<image url="https://example.com/alt-image.jpg" />
</video>完整範例
<bubble>
<header>
<style backgroundColor="#f0f0f0" />
<vertical>
<background type="linearGradient" angle="90deg" startColor="#667eea" endColor="#764ba2" />
<strong>商品資訊</strong>
</vertical>
</header>
<body>
<vertical>
<image url="https://example.com/product.jpg" aspectRatio="4:3" size="full" />
<baseline>
<text>價格:</text>
<space size="2" />
<strong>NT$ 1,000</strong>
</baseline>
<separator />
<text>這是商品的詳細說明文字</text>
</vertical>
</body>
<footer>
<row>
<button>
<action type="uri" uri="https://example.com/buy" label="立即購買" />
</button>
</row>
</footer>
</bubble>範例
const html = `
<bubble>
<body>
<box layout="vertical">
<text color="#ff0000">Hello, Flex!</text>
<image url="https://example.com/image.png" />
</box>
</body>
</bubble>
`;
const result = convertHtmlToFlexMessage(html);
console.log(result);注意事項
- 請確保 HTML 結構正確,否則可能無法正確轉換。
- 轉換後的 JSON 結構請依照 LINE Flex Message 規範 使用。
授權
MIT License
