ลองเล่น Flex Message แบบใหม่ แหกคอก LINE Messaging API

ไม่รู้จะเริ่มต้นจากตรงไหนก่อนดี เอาเป็นว่าสรุปกระบวนการที่ได้ลอง Flex Message แล้วกัน ซึ่งมันเป็นการแสดงผลข้อความแบบใหม่ ที่เราสามารถออกแบบได้อิสระมากขึ้น และใส่สิ่งต่างๆ ลงไปในข้อความที่โพสใน LINE ได้อย่างสะใจ

TLDR; โดยรายละเอียดการขายทั้งหมด อ่านได้ที่บล๊อคนี้เลยจ้า
https://medium.com/linedevth/ฉีกกฎการแสดงผลข้อความแบบเดิมๆใน-line-messaging-api-ด้วย-flex-message-4ad4370562f

โครงสร้างภายในของ Flex Message จะประกอบไปด้วย 3 ชั้น ดังนี้

  1. Container
  2. Block
  3. Component

Ref: https://developers.line.me/en/docs/messaging-api/flex-message-elements/

ดูรูปนี้จะเข้าใจง่าย ปริ้นไว้เวลาสร้าง block ได้เลย (ก๊อบรูปเขามา)

Container

คือ top-level ของ Flex Message เรียกง่ายๆ ว่าชุดข้อความที่เราจะส่ง มันต้องอยู่ในนี้เด้อ

{
    "to": "userId or groupId",
    "messages": [{
        "type": "flex",
        "altText": "This is a Flex Message",
        "contents": {
            // container here
        }
    }]
}

ซึ่งใน container นี้จะมีอยู่ 2 รูปแบบ คือ Bubble และ Carousel ดังภาพตัวอย่างด้านล่าง (ที่ก๊อบมา)

  • Bubble เป็นข้อความเดียว หรือ การ์ดใบเดียว
  • Carousel เป็นการ์ดหลายๆ ใบ ที่เราสามารถเลื่อนซ้ายขวาได้ หรือมันก็คือ Carousel template นั่นแหละ แต่เราสามารถกำหนดรูปแบบมันเองได้ยังไงละ เช่น ยัด Bubble ไปหลายๆชุด

Block

เป็นโครงสร้างชั้นกลางของ Flex Message แบ่งออกเป็น 4 ส่วน และในการสร้างข้อความเราสามารถระบุบางส่วนหรือทุกส่วนก็ได้ ซึ่งในแต่ละส่วน มันจะเรียงลำดับแบบนี้เสมอ ไม่ว่าเราจะใส่ ข้อมูลส่วนไหนก่อนก็ตาม (ผมลองสลับเอา body ขึ้นก่อน เอา hero ไว้สุดท้าย มันก็จะกลับมาเรียงแบบ หัว ไหล่ ตูด เหมือนเดิมทุกครั้ง) และ เราจะใส่ block ได้เพียงประเภทเดียว จะใส่ body ครั้งไม่ได้ หากเราจะแสดงแบบ 2 body จะใช้วิธีสร้าง box แยกเองได้

  • Header เป็นส่วนแสดงหัวข้อ
  • Hero เป็นส่วนแสดงรูปภาพ cover (รองรับการแสดงผลแบบ image component เท่านั้น)
  • Body เป็นส่วนแสดงเนื้อหาหลัก จะแบ่งเป็น column ก็ได้ ตามใจเลยด้วยการใส่ box เข้าไป
  • Footer เป็นส่วนแสดงข้อมูลเพิ่มเติม หรือ ปุ่มที่เราสามารถใส่ action เข้าไปได้อีก

Objects for the block style

เราสามารถใส่พื้นหลังให้กับแต่ละ block ได้ด้วยนะ ด้วย style: {backgroundColor: "#hexadecimal "}

Component

เป็นโครงสร้างชั้นในสุดของ Flex Message ประกอบไปด้วย 2 กลุ่ม คือ กลุ่ม component สำหรับสร้างข้อความและ สำหรับการปรับแต่ง layout

กลุ่ม component สำหรับสร้างข้อความ

  • Button สำหรับสร้างปุ่มกด โดยมี Property ที่สามารถใช้ได้ ดังนี้  typeaction, flex, margin, height, style, color, gravity
  • Icon สำหรับสร้างรูปภาพไอค่อน {type, url, margin, size, aspectRatio}
  • Image สำหรับสร้างรูปภาพ {type, url, flex, margin, align, gravity, size, aspectRatio, aspectMode, backgroundColor, action}
  • Text สำหรับสร้างข้อความ {type, text, flex, margin, size, align, gravity, wrap, weight, color}

กลุ่ม component สำหรับการปรับแต่ง layout

  • Box เป็นเหมือนกับ tag <div> ใน html น่ะแหละว่ากันง่ายๆ เอาไว้จัดวาง layout ของ flex message ที่เราสร้าง ซึ่งมันสามารถซ้อนๆ กันได้หลายชั้น โดยมี Property ที่ใช้ได้ดังนี้ type, layout, contents, flex, spacing, margin  ซึ่ง component ข้อความเราจะอยู่ใน property contents :{ Array of objects } นี่เอง โดยถ้า property layout เป็น vertical หรือ horizontal ภายในสามารถบรรจุ box, button, filler, image, separator และ text ได้ แต่หาก layout เป็น baseline จะสามารถบรรจุ filler, icon และ text ได้เท่านั้น
  • Filler เป็นกองหนุนช่วยเสริมส่วนที่ว่าง สมมุติจะออกแบบให้ body มี 3 box แต่ต้องการเว้นตรงกลางไว้ ก็ใส้ type filter ไปได้เลยจบ
  • Separator เป็นเส้นคั่นระหว่าง component ได้ทั้งแนวตั้งและแนวนอน คล้ายหน้าที่ของ tag <hr> นั้นแหละ property ที่กำหนดได้ มี {type, margin, color}
  • Spacer เป็นช่องว่าง ที่คล้ายๆ กับ Filler แต่มันจะไม่ได้ทำตัวเป็น box มันจะคล้ายๆ top,bottom -margin,-padding มากกว่า โดยมีกำหนดระยะห่างได้ด้วย property {type, size}

อธิบายเรื่องการใช้ flex layout

แบบรวบรัด คือ flex ให้เราจำไว้ว่า การแสดงผลทั้งหมดคือ 100% ซึ่ง flex ตามภาพด้านล่าง คือ flex: 2 และ flex: 3 มันจะเท่ากับ 40% และ 60% จาก 100% หรือถ้าใส่ 0 แต่ว่าใน component นั้นมีข้อความอยู่ มันก็จะแสดงด้วย flex 1 หรือ เบียดเท่าที่จะเบียดได้

ref: https://developers.line.me/en/docs/messaging-api/flex-message-layout/

หากใส่ flex: 0 จะเกิดอะไรขึ้น ในกรณีที่ใส่เป็น 0 แล้ว content ข้อความมันเยอะ มันก็จะเบียด component อื่นแบบนี้เลย component อื่นจะถูกซ่อนไปโดนปริยาย

การจัด Alignment ของ components

  • align ใช้กับการจัดแนวนอน โดยใช้ start, center, end 
  • gravity ใช้กับการจัดแนวตั้ง โดยใช้  top, center, bottom
  • spacing ใช้กับการจัดขนาดการเว้นวาง xs, sm, md, lg, xl, xxl
  • margin ใช้คล้าย spacing เลย แต่มันมี none คือไม่ต้องเว้น none, xs, sm, md, lg, xl, xxl

ตัวอย่างที่ลองทำเล่นบน Flex Message Simulator

Flex Message Simulator
https://developers.line.me/console/fx/

ซึ่งตอนที่ทำ ใช้แก้ในแบบ YAML จะง่ายกว่ามานั่งแก้ในแบบ JSON แต่เวลาส่ง จะ copy แบบ JSON ไปใช้งาน

{
  "type": "bubble",
  "styles": {
    "footer": {
      "backgroundColor": "#42b3f4"
    }
  },
  "header": {
    "type": "box",
    "layout": "horizontal",
    "contents": [
      {
        "type": "box",
        "layout": "baseline",
        "contents": [
          {
            "type": "icon",
            "size": "xxl",
            "url": "https://scontent.fbkk7-2.fna.fbcdn.net/v/t1.0-1/p200x200/22814542_1962234637127047_1607260544847069468_n.png?_nc_cat=0&oh=2a303227c24dfab9e71a405b6d594d50&oe=5BC3965D"
          }
        ]
      },
      {
        "type": "box",
        "layout": "vertical",
        "flex": 5,
        "contents": [
          {
            "type": "text",
            "text": "โรงพยาบาลอ่างทอง",
            "weight": "bold",
            "color": "#aaaaaa",
            "size": "md",
            "gravity": "top"
          },
          {
            "type": "text",
            "text": "ขอขอบพระคุณ",
            "weight": "bold",
            "color": "#aaaaaa",
            "size": "lg",
            "gravity": "top"
          }
        ]
      }
    ]
  },
  "hero": {
    "type": "image",
    "url": "https://scontent.fbkk7-2.fna.fbcdn.net/v/t1.0-9/35076722_2227987830551725_330757188106584064_n.jpg?_nc_cat=0&oh=0f5fa137c5bd65f109a40439afcd59eb&oe=5BB566B6",
    "size": "full",
    "aspectRatio": "16:9",
    "aspectMode": "cover",
    "action": {
      "type": "uri",
      "uri": "http://bit.ly/2JGBRKv"
    }
  },
  "body": {
    "type": "box",
    "layout": "vertical",
    "contents": [
      {
        "type": "text",
        "margin": "sm",
        "text": "คุณกานต์สินี ไหลสงวนงาม",
        "weight": "bold",
        "size": "md",
        "wrap": true
      },
      {
        "type": "box",
        "layout": "vertical",
        "margin": "xs",
        "contents": [
          {
            "type": "box",
            "layout": "baseline",
            "spacing": "sm",
            "contents": [
              {
                "type": "text",
                "text": "บริจาคเงินจำนวน ๑๘๐,๐๐๐ บาท เพื่อซื้อครุภัณฑ์ทางการแพทย์ ใช้ในโรงพยาบาลอ่างทอง โดยมีนายแพทย์พงษ์นรินทร์ ชาติรังสรรค์ผู้อำนวยการโรงพยาบาลอ่างทอง เป็นผู้รับมอบ",
                "wrap": true,
                "color": "#666666",
                "size": "sm",
                "flex": 6
              }
            ]
          }
        ]
      },
      {
        "type": "text",
        "margin": "md",
        "text": "วันที่ 12 มิ.ย. 2561",
        "size": "sm",
        "color": "#adadad"
      }
    ]
  },
  "footer": {
    "type": "box",
    "layout": "vertical",
    "spacing": "sm",
    "contents": [
      {
        "type": "button",
        "style": "link",
        "color": "#FFFFFF",
        "height": "sm",
        "action": {
          "type": "uri",
          "label": "อ่านต่อ...",
          "uri": "http://bit.ly/2JGBRKv"
        }
      }
    ]
  }
}

ทดลองส่งข้อความแบบ Flex Message

เมื่อได้ container มาแล้วก็อย่ารอช้า ซัดเลย โดย ใช้ Send Push Message นี่แหละ ซึ่งสิ่งที่เราต้องมีก็คือ

  • สร้าง Create new channel ของเรา เพื่อให้ได้ channel access token มา
  • userId, groupId ที่ได้จาก webhook event object. ไม่ใช่ LINE ID แต่มันจะเป็นชุดข้อความประมาณนี้ "groupId": "Ca56f94637c...", "userId": "U4af4980629...""roomId": "Ra8dbf4673c..."

ซึ่ง format จะเป็นแบบภาพด้านล่างนี้ เราเอา ข้อความแบบ flex จะต่างจาก message เดิมๆ นิดหน่อย

นำข้อความมาส่งด้วย Postman เจ้าเดิม

ข้อความที่ส่งแล้ว

สรุป

คู่มือข้างต้นที่อ้างอิงไว้ อธิบายได้ดี ครบถ้วนแล้ว ไม่เลยทำให้ง่ายขึ้นเวลาอ่าน API DOC เราจะเข้าใจ “องค์ประกอบ” ของสิ่งที่เราจะใช้ ก่อนที่เราจะลด ลัด ตัดทอนมัน ซึ่งเหมือนกับเป็น best practice ก่อนที่เราจะขับรถ เราควรศึกษากฏจราจรด้วย ไม่ใช่ขึ้นรถแล้วขับมันออกไปเลย ซึ่งตัว flex message มันค่อนข้างยืดหยุ่น และสามารถสร้างสรรค์รูปแบบข้อความใหม่ๆ ได้ เพื่อให้เหมาะกับ content ที่เราใช้นำเสนอ ให้ครบกับการใช้งานของระบบเรามากที่สุด เป็นอีกหนึ่งรูปแบบที่ดีที่ดี

แต่ ณ วันที่ผมเขียนนี้ LINE Bot Designer  ยังไม่มี component นี้นะครับ เรายังต้อง code กันเองไปก่อน ใน Flex Message Simulator แต่ถ้าสร้างได้ 1 template แล้ว มันจะใช้กันได้ ยาวววๆ

ส่งการบ้าน สวยงามตามท้องเรื่อง