Try   HackMD

AI LINE Bot練功坊-L9 Message Type (3) Flex Message

匯入函式

from linebot.v3.messaging import (
    FlexMessage,
    FlexBubble,
    FlexImage,
    FlexMessage,
    FlexBox,
    FlexText,
    FlexIcon,
    FlexButton,
    FlexSeparator,
)

Flex Message 彈性訊息

LINE BOT 可以使用 Flex Message ( 彈性樣板訊息 ) 發送客製化的選單訊息,Flex Message 使用網頁 CSS3 的 Flex 語法,可以設計較豐富且多樣性的按鈕版型
而且不像 Template 在電腦版就無法運作,Flex Message 支援 「電腦版」

Flex Message 結構

Flex Message 是由三層結構組成
Container 容器 -> Block 區塊 -> Component 組件

內容及圖片參考 官方網站

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Reference:https://developers.line.biz/en/docs/messaging-api/using-flex-messages/

Container 容器

容器是 Flex Message 的最外層結構,有兩種類型可選

1.Bubble 2.Carousel
是包含一個訊息框的容器。 是包含多個 Bubble 的容器,可以橫向滑動
Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →
Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Block 區塊

Block區塊是組成 Bubble 的結構,分為四個部分

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Header: 顯示標題的區塊
Hero: 顯示主要圖片的區塊
Body: 顯示主要內容的區塊
Footer: 顯示按鈕或補充訊息的區塊

Component 組件

組件是 Flex Message 的最基本結構,類型很多如下

  1. Box: 定義介面的佈局,裡面可以包含其它組件
  2. Button: 按鈕
    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →
  3. Image: 圖片
    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →
  4. Icon: 文字前的圖標
    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →
  5. Text: 文字
    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →
  6. Span: 單行文字,可以指定不同的顏色、大小、粗細
    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →
  7. Separator: 分隔線,可製作水平或垂直的分隔線
    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →
  8. Filler: 可以在組件間插入空白區塊
    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →

Reference:https://developers.line.biz/en/docs/messaging-api/flex-message-elements/

Component 屬性

Bubble

  • direction 內容排列方向
    • ltr 從左至右
    • rtl 從右至左
  • size 調整 bubble 大小
    • giga
    • mega
    • kilo
    • hecto
    • deca
    • micro
    • nano
  • Action Type
    • postback
    • uri
    • message
    • datetimepicker

Header、Hero、Body、Footer

  • backgroundColor 背景顏色
  • seperator 分隔線
    • True
    • False
  • seperatorColor 分隔線顏色

Box

  • layout

    • vertical 垂直排列
      box, button, image, text, separator, and filler
    • horizontal 水平排列
      box, button, image, text, separator, and filler
    • baseline 水平排列
      icon, text, and filler

    baseline 與 horizontal 不同之處

    baseline 中的元件按同一基線垂直對齊,這意味著所有子元件都使用相同的基線,無論字型大小。 圖示元件的基線是圖示影象的底部。

    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →

    baseline 中的元件不能套用 gravityoffsetBottom 屬性

  • position

    • relative 相對配置
      可以設定父層元素為基準元素作絕對位移。
    • absolute 絕對配置
      以「自己原本顯示的位置為基準位置」來指定上下左右的偏移,且區塊原本的空間仍會保留不會消失。
  • flex 如果元件的位置屬性設定為相對(relative),則元件的寬度和高度由元件的 flex 屬性決定。

    horizontal box 中的寬度分配

    假設一個 horizontal box 有兩個元件,一個將 flex 屬性設定為 2,另一個設定為 3。 然後將可用寬度(horizontal box 的寬度)以二比三的比例劃分,並分配給每個元件。

    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →


    Vertical box 中的高度分配

    假設一個 horizontal box 有兩個 vertical boxes,第一個 box 佔用五行的文字,第二個 box 根據其 flex 屬性的值,以 2 : 3 的比例分配給兩個文字元件。

    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →

  • spacing 元件之間的間距

    本示例 Flex Message 有一個 horizontal box,其中三個 vertical boxes 作為子元件,間隔均為(md)。

    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →

  • margin 元件之間的邊距 (邊距屬性優先於間距屬性)

    本示例 Flex Message 有一個 horizontal box,其中三個 vertical boxes 作為子元件,間隔均為(md),第三個 vertical box 邊距屬性為 xxl。

    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →

  • width

  • height

  • maxWidth

  • maxHeight

  • backgroundColor

  • borderWidth

  • borderColor

  • cornerRadius

  • justifyContent 在父階層中設置幫助安排內容

    • flex-start
      這將從起點開始對所有項目進行排列。如果是水平,則將基於 bubble 給出的方向: ltr (從左至右)或 rtl (從右至左);反之若是垂直,則所有項目將從上至下進行排列。
    • center
      將所有項目排列在中心點。
    • flex-end
      這將從末端開始對所有項目進行排列。如果是水平,則將基於 bubble 給出的方向: ltr 從左至右)或 rtl (從右至左);反之若是垂直,則所有項目將從下至上進行排列。
    • space-between
      第一個與最後一個項目貼齊左右側的佈局,其餘項目平均分配到顯示畫面的中心。
    • space-around
      將每個項目之間的距離均勻地分配。
    • space-evenly
      平均劃分每個項目與訊息佈局的距離來進行排列。

    layout: vertical

    截圖 2024-04-24 00.47.36


    layout: horizontal & direction: ltr

    截圖 2024-04-24 00.47.21

  • alignItems 指定父階層中的項目更換排序方向

    • flex-start
      如果父階層水平排列,則所有項目將自上而下;如果父母垂直排列,則所有項目將從一開始(取決於 Bubble 的方向)。
    • center
      將所有項目排列在水平和垂直方向的中心點。
    • flex-end
      如果將父階層水平排列,則所有項目將從下至上;並且如果將父接成垂直排列,則所有項目將從末端排列(取決於 Bubble 的方向)。

    layout: vertical

    截圖 2024-04-24 00.50.18


    layout: horizontal & direction: ltr

    截圖 2024-04-24 00.50.08

  • Offset 偏移量

    • offsetTop
      將元件從元件原始位置的頂部邊緣向下移動。
    • offsetBottom
      將元件從元件原始位置的底部邊緣向上移動。
    • offsetStart
      將元件從文字開始的地方移開。 如果 bubble 的方向是 LTR,則向右移動。 如果是 RTL,則向左移動。
    • offsetEnd
      遠離文字結束的地方。 如果 bubble 的方向是 LTR,則向左移動。 如果是 RTL,則向右移動。

    offset1

    Offset when position is relative

    offset2

    Property Value
    position relative
    offsetTop 10px
    offStart 40px

    Offset when position is absolute

    offset3

    Property Value
    position absolute
    offsetTop 10px
    offBottom 20px
    offStart 40px
    offEnd 80px
  • Padding 元件內所有內容與元件自身的邊界

    • paddingAll
    • paddingTop
    • paddingBottom
    • paddingStart
    • paddingEnd

    padding

    Property Value
    paddingTop 20px
    paddingAll 80px
    paddingStart 40px
  • Background Type

    • linearGradient 線性漸變背景
      • angle
      • startColor
      • endColor
      • centerColor
      • centerPosition
      ​​​​​​​​{
      ​​​​​​​​  "type": "bubble",
      ​​​​​​​​  "body": {
      ​​​​​​​​    "type": "box",
      ​​​​​​​​    "layout": "vertical",
      ​​​​​​​​    "contents": [],
      ​​​​​​​​    "background": {
      ​​​​​​​​      "type": "linearGradient",
      ​​​​​​​​      "angle": "0deg",
      ​​​​​​​​      "startColor": "#ff0000",
      ​​​​​​​​      "endColor": "#0000ff"
      ​​​​​​​​    },
      ​​​​​​​​    "height": "200px"
      ​​​​​​​​  }
      ​​​​​​​​}
      

      Linear gradient at 45 degrees (Bottom-left to top-right)

      45d

      Linear gradient at 90 degrees (Left to right)

      90d

      Linear gradient at 180 degrees (Top to bottom)

      180d
  • Action Type


Button

  • flex
  • position
  • margin
  • height
  • style
    • link
    • primary
    • secondary
  • color
  • gravity

    使用 gravity 屬性,垂直對齊 text, image, 或 button

    gravity
  • scaling
    如果縮放屬性設定為 true,您可以根據 LINE 應用程式的字型大小設定自動縮放字型大小和圖示大小。
  • adjustMode
    如果您為按鈕和文字元件的 adjustMode 屬性 shrink-to-fit,文字的字型大小將自動縮小以適應。

stf

  • Offset
  • Action

Image

  • flex
  • position
  • url
  • margin
  • align

    使用 align 屬性,水平對齊 text, 或 image

    ho
  • gravity
  • size
  • aspectRatio 圖片長寬比
  • aspectMode
    • cover
    • fit
  • backgroundColor
  • animated
    • True
    • False
  • Offset
  • Action

Icon

  • position
  • url
  • margin
  • size
  • scaling
  • aspectRatio
  • Offset

Text

  • text
  • flex
  • margin
  • size
  • lineSpacing 行距
  • color
  • weight
    • regular
    • bold
  • style
    • normal
    • italic
  • decoration
    • none
    • underline 底線
    • line-through 刪除線
  • position
  • align
  • gravity
  • wrap 過長的文字自動換至下一行
    • True
    • False
  • scaling
  • maxLines
  • adjustMode
  • Offset
  • Action Type

Span

  • text
  • size
  • color
  • weight
  • style
  • decoration

Separator

  • margin
  • color

Filter

  • flex

Reference:https://developers.line.biz/en/docs/messaging-api/flex-message-layout/

Flex Message 設計(flex-simulator)

官方有推出輔助工具 Flex-Simulator ,可以直接在網頁上製作 Flex Message
需登入LINE Developers 帳戶

image
設計工具主要分成三個區塊:

  • 左邊的區塊:預覽畫面 ( 傳送到 LINE 的訊息長相 )
  • 中間的區塊:Flex Message 的樹狀清單結構
  • 右邊的區塊:點擊中間區塊清單裡的元件,出現對應可以修改的屬性或參數

image
LINE官方也有提供的一些免費模板,可以根據需求改寫裡面的參數,設計成理想中的訊息

製作 Flex 的步驟:

你可以點右上角的「Showcase」從官方提供的模板修改寫裡面的參數,改成想要得樣式,再匯出

如果想要從零開始做的話:

  1. 點擊網頁右上角的「NEW」,選擇Container建立一個包含訊息框的 Bubble or Carousel類型
  2. 點選想要修改的Block 區塊
  3. 點擊中間清單的元件後,就能從上方的「+」號,加入額外的元件
    image

    如:設定標題文字及背景顏色、新增圖片(設定圖片連結與大小)、新增文字(設定字體大小、粗細和對齊方式)、新增平行線(新增分隔線,並設定邊距)、新增按鈕(設定連結及按鈕樣式、添加連結到網站、或撥打電話

測試 Flex Message

點擊右上方的 Send 按鈕後,會出現 Register destination 的按鈕,繼續點擊後會出現 QRCode,掃描 QRCode 加入好友就能測試

image
image

用Python 傳 Flex Message

首先先將官方模擬器的資料複製,點選右上角的複製JSON內容,編寫完基本指令後在「contents」之處將複製的JSON內容貼上

Flex Message 範例

image
首先,程式碼建立一個 URL,這個 URL 是用來指向一個圖片資源的

FlexBubble()是一個物件,其屬性包括 direction(排列方向)、hero(主要圖像)、body(內容區域)、footer(底部區域)

  • contents 是用來容納各種 Flex 元件的容器
  • hero:主圖像是一張圖片,其中包含 URL、尺寸、比例、顯示模式等屬性
  • body:內容區域包含了標題、評分、詳細資訊等內容,使用了不同的 Flex 元件來組合顯示
  • footer:底部區域包含了一個連結到電話的按鈕和一個連結到網站的按鈕,使用了 FlexButton 元件

最後,使用 line_bot_api.reply_message 函式回覆訊息,設定了回覆的內容為一個 FlexMessage,其中的內容就是前面建立的 FlexBubble 物件

Python程式碼

url = request.url_root + '/static/Logo.jpg'
url = url.replace("http", "https")
app.logger.info("url=" + url)

bubble = FlexBubble(
    direction='ltr',
    hero=FlexImage(
        url=url,
        size='full',
        aspect_ratio='20:13',
        aspect_mode='cover',
        action=URIAction(uri='https://www.facebook.com/NTUEBIGDATAEDU', label='label')
    ),
    body=FlexBox(
        layout='vertical',
        contents=[
            # title
            FlexText(text='教育大數據', weight='bold', size='xl'),
            # review
            FlexBox(
                layout='baseline',
                margin='md',
                contents=[
                    FlexIcon(size='sm', url="https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png"),
                    FlexIcon(size='sm', url="https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png"),
                    FlexIcon(size='sm', url="https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png"),
                    FlexIcon(size='sm', url="https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png"),
                    FlexIcon(size='sm', url="https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png"),
                    FlexText(text='5.0', size='sm', color='#999999', margin='md', flex=0)
                ]
            ),
            # info
            FlexBox(
                layout='vertical',
                margin='lg',
                spacing='sm',
                contents=[
                    FlexBox(
                        layout='baseline',
                        spacing='sm',
                        contents=[
                            FlexText(
                                text='Place',
                                color='#aaaaaa',
                                size='sm',
                                flex=1
                            ),
                            FlexText(
                                text='Da\'an District, Taipei ',
                                wrap=True,
                                color='#666666',
                                size='sm',
                                flex=5
                            )
                        ],
                    ),
                    FlexBox(
                        layout='baseline',
                        spacing='sm',
                        contents=[
                            FlexText(
                                text='Time',
                                color='#aaaaaa',
                                size='sm',
                                flex=1
                            ),
                            FlexText(
                                text="10:00 - 23:00",
                                wrap=True,
                                color='#666666',
                                size='sm',
                                flex=5,
                            ),
                        ],
                    ),
                ],
            )
        ],
    ),
    footer=FlexBox(
        layout='vertical',
        spacing='sm',
        contents=[
            # callAction
            FlexButton(
                style='link',
                height='sm',
                action=URIAction(label='CALL', uri='tel:000000'),
            ),
            # separator
            FlexSeparator(),
            # websiteAction
            FlexButton(
                style='link',
                height='sm',
                action=URIAction(label='WEBSITE', uri='https://www.facebook.com/NTUEBIGDATAEDU')
            )
        ]
    ),
)

line_bot_api.reply_message(
    ReplyMessageRequest(
        reply_token=event.reply_token,
        messages=[FlexMessage(alt_text="hello", contents=bubble)]
    )
)

Reference:https://developers.line.biz/en/reference/messaging-api/#flex-message

Youtube 課程影片

關於我們

image 國立臺北教育大學 教育大數據微學程

先修微課程

🤖 AI LineBot 練功坊系列課程
從入門到精通,學習如何開發並應用 LINE Bot,讓你輕鬆掌握最前沿的聊天機器人技術。

👨‍💻 Python 初學小教室
針對零基礎學員設計,循序漸進地教授 Python 基本語法及實作技巧,幫助你快速上手。

📊 統計學小教室
系統講解統計學理論及其應用,適合想要提升數據分析能力的學習者。

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →
Facebook
Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →
Instagram
Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →
Threads
Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →
YouTube
Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →
Line官方帳號

相關教材連結

◀◀◀ L08 Message Type(2) Template Message ◀◀◀
▶▶▶ L10 Message Type(4) Imagemap Message ▶▶▶