2
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

【LINE WORKS】Flexible Template API をいじり倒してみた

提供されてからずいぶんと経ってしまいましたが、ようやくいじり倒す機会がやってきましたよ!ヾ(´∀`)ノ

LINE WORKS Developers - Flexible Template

525.png

CSS 要素が満載のデザイン性バリ高な機能。
馬を描いたら友人に「4本脚で立っているのが奇跡だな」と言われた私には荷が重いかもしれませんが頑張ります( ^ω^)

Flexible Template の使い方

Flexible Template と言えどメッセージ送信 API の一部なので、認証方法や Request URL はメッセージ送信 API と同じ。
慣れ親しんだやつらなので安心ですね(^_-)-☆
LINE WORKS Developers - メッセージ送信

content パラメータの中身を Flexible Template の構成で書いてあげれば良いわけです。
なーんだ、簡単じゃん!(*‘∀‘)

…フラグですよ( ゚Д゚)

メッセージ送信(Flexible Template)のコード

まずはサンプルコードを見てみましょう。

{
  "accountId": "admin@example.com",
  "content": {
    "type": "flex",
    "altText": "this is a flexible template",
    "contents": {
      "type": "bubble",
      "body": {
        "type": "box",
        "layout": "vertical",
        "contents": [
          {
            "type": "text",
            "text": "hello"
          },
          {
            "type": "text",
            "text": "world"
          }
        ]
      }
    }
  }
}

お、なんだなんだ。大したことないじゃないですか!(*´Д`)

"type": "flex" を指定して Flexible Template を使うぞーと宣言。
"altText": "this is a flexible template" はポップアップ通知で表示する内容みたいですね。
1620809442.png

"contents": {} 最後に contents を Flexible に指定してあげれば良いわけですよ!

なんだ、やっぱりかんたーんじゃないですか♪

……フラグですよ( ゚Д゚)

Flexible Template の構成

LINE WORKS Developers - Flexible Template の要素

公式ドキュメントを読むと詳しく書いてありますが、ざっくり図にするとこんな感じ。

contener.png

コンテナの中にブロックがあって、それぞれのブロックの中にコンポーネントが入る、と。
なんだかネストが激しくなりそうですが、まぁ、それは仕方ないですね。

では、コンテナの書き方を見ていきましょーヾ(´∀`)ノ

コンテナ

LINE WORKS Developers - コンテナ

コンテナは バブル (bubble)カルーセル (carousel) の2種類があるようです。

どうやら カルーセル (carousel) はバブルの集合体のようなので、バブルを攻略できれば良いわけですね!
ふふふ、見えたぞ、天王山!(`・ω・´)

それでは、バブルのサンプルコードを見ていきましょう。

{
  "type": "bubble",
  "header": {
    "type": "box",
    "layout": "vertical",
    "contents": [
      {
        "type": "text",
        "text": "Text Component",
        "weight": "bold"
      }
    ],
    "paddingAll": "10px",
    "paddingStart": "15px"
  },
  "hero": {
    "type": "image",
    "url": "https://i.ibb.co/RbvxLhg/Image-Component.png",
    "size": "full",
    "aspectMode": "cover",
    "aspectRatio": "2:1"
  },
  "body": {
    "type": "box",
    "layout": "vertical",
    "contents": [
      {
        "type": "box",
        "layout": "horizontal",
        "contents": [
          {
            "type": "box",
            "layout": "vertical",
            "contents": [
              {
                "type": "image",
                "url": "https://i.ibb.co/4dTjScT/Image.png",
                "size": "lg"
              }
            ],
            "borderWidth": "2px",
            "borderColor": "#90909050",
            "width": "93px",
            "height": "93px"
          },
          {
            "type": "box",
            "layout": "vertical",
            "contents": [
              {
                "type": "separator",
                "color": "#909090"
              },
              {
                "type": "text",
                "text": "Text Component 01"
              },
              {
                "type": "separator",
                "color": "#909090"
              },
              {
                "type": "text",
                "text": "Text Component 02"
              },
              {
                "type": "separator",
                "color": "#909090"
              }
            ],
            "height": "100px",
            "margin": "md",
            "spacing": "lg"
          }
        ]
      },
      {
        "type": "box",
        "layout": "horizontal",
        "contents": [
          {
            "type": "box",
            "layout": "vertical",
            "contents": [
              {
                "type": "image",
                "url": "https://i.ibb.co/4dTjScT/Image.png",
                "size": "lg"
              }
            ],
            "borderWidth": "2px",
            "borderColor": "#90909050",
            "width": "93px",
            "height": "93px"
          },
          {
            "type": "box",
            "layout": "vertical",
            "contents": [
              {
                "type": "separator",
                "color": "#909090"
              },
              {
                "type": "text",
                "text": "Text Component 03"
              },
              {
                "type": "separator",
                "color": "#909090"
              },
              {
                "type": "text",
                "text": "Text Component 04"
              },
              {
                "type": "separator",
                "color": "#909090"
              }
            ],
            "height": "100px",
            "margin": "md",
            "spacing": "lg"
          }
        ],
        "margin": "md"
      }
    ]
  },
  "footer": {
    "type": "box",
    "layout": "vertical",
    "contents": [
      {
        "type": "button",
        "action": {
          "type": "uri",
          "label": "Button Component",
          "uri": "http://linecorp.com/"
        },
        "height": "sm",
        "style": "link"
      }
    ]
  }
}

Σ(゚Д゚)

ななな、なんじゃこりゃー!(゚Д゚)

はい!フラグ回収きましたー♪(^_-)-☆

長すぎ!スクロールするの大変!わけわからんですよもう!(; ・`д・´)

心が折れかけたあなた!私も同感です。
そこで、少し見方を変えてみましょう。

コンテナはブロックの集合体

いっぺんに全部見るからいけないのです。
ブロックの集まりがコンテナなんだから、まずはブロックを攻略すればいいんですよ!(`・ω・´)キリッ

ブロックは全部で4種類。

  • header
  • hero
  • body
  • footer

header とかはなんとなくわかるんですが hero ってなんだろう。
傷だらけのやつだろうか。誰でもそうなんだよってやつだろうか。

とかなんとか考えながらググってみたところ、HTML 界隈ではヒーローイメージとかいう当たり前の言葉だったんですね。恥ずかしい(*ノωノ)
恥をかいた分、しっかり覚えました。

脱線したので話を戻します。

ブロックは1つでも指定すればいいので、最初は簡単に body だけでも良さそうですね。
そして body の中に何を入れるかと言うと、ボックスというコンポーネントを入れるようです。

ブロックの中にはコンポーネントを入れる

LINE WORKS Developers - ボックス

ブロックの中にはコンポーネントを入れるんですが、ボックスでレイアウトとかを定義して細かいボタンやらテキストやらのコンテンツを入れるので、それはつまり

ブロック = ボックス

って考えても良いかと。
いや、厳密に言うと違うんですけど、イメージ的に自分がわかりやすそうだったので。

何はともあれ、このボックスちゃんを攻略すれば Flexible Template を攻略したも同然ですよ!( ゚Д゚)

ボックスの中に入れるコンテンツは7種類

  • ボックス
  • ボタン
  • 画像
  • テキスト
  • セパレータ
  • フィラー
  • スペーサー(未推奨)

よく使うのは、ボタン、画像、テキスト、セパレータあたりでしょうか。

ボックスの中にボックスを入れるのは、もう延々とマトリョーシカのごとく面倒そうなので、最初はやらなくてもいいですね!( ゚Д゚)

コンテンツを組み合わせてボックスを作る!

じゃー、実際に作ってみましょうかね!

なるべく最小限な感じで、ボタン、画像、テキスト、セパレータを使って作ってみました。(*‘∀‘)

messageBody.json
{
    "accountId": "xxx@yyy-zzz",
    "content": {
        "type": "flex",
        "altText": "This is a Flex Message from the Demon King",
        "contents": {
            "type": "bubble",
            "body": {
                "type": "box",
                "layout": "vertical",
                "backgroundColor": "#000000",
                "spacing": "md",
                "contents": [{
                    "type": "image",
                    "url": "https://xxxx.com/xxxx.png"
                },{
                    "type": "text",
                    "text": "お前に世界の半分をやろう...",
                    "color": "#dc143c",
                    "weight": "bold"
                },{
                    "type": "separator"
                },{
                    "type": "button",
                    "style": "secondary",
                    "color": "#c0c0c0",
                    "action": {
                        "type": "message",
                        "label": "全部よこせ。",
                        "text": "Yes!"
                    }
                },{
                    "type": "button",
                    "style": "secondary",
                    "color": "#c0c0c0",
                    "action": {
                        "type": "message",
                        "label": "元から全てオレの物だ。",
                        "text": "No!"
                    }
                }]
            }
        }
    }
}

1620896732.png

あ、これ、割と作るの楽しいですね。(*´Д`)

えっと、今回は簡単に Body ひとつで納めましたが、本当は hero とか使い分けた方がいいのかな?

軽く解説しますね。

画像コンポーネント

body の一番上が画像になっています。

{
  "type": "image",
  "url": "https://xxxx.com/xxxx.png"
}

画像は透過PNGなのですがこのコンポーネントでは背景色は設定できないみたいです。
LINE WORKS Developers - 画像

なので、body の設定で背景を黒にしました。

テキスト コンポーネント

次に魔王のセリフですね。
文字色は血染めのクリムゾンにしてみました(何

{
  "type": "text",
  "text": "お前に世界の半分をやろう...",
  "color": "#dc143c",
  "weight": "bold"
}

これ、デフォルトだと文字数多すぎると省略されちゃうみたいです。
いっぱい書きたい方は wrap または maxLines パラメータを使用すると全文字表示できるようです。
LINE WORKS Developers - テキスト

セパレータ コンポーネント

境界線ですね。ボーダー。
特になくてもいいんですが、明確にセリフを分けるときにはあった方がわかりやすいですよね!

{
  "type": "separator"
}

あ、今回特に指定しませんでしたが、色は変えられるみたいですよ( ゚Д゚)
LINE WORKS Developers - セパレーター

ボタン コンポーネント

ボタンですね。押すと色々と起きるやつ。
ボタンを押したあとどんな動きをするかは Action Objects で設定します。

{
  "type": "button",
  "style": "secondary",
  "color": "#c0c0c0",
  "action": {
      "type": "message",
      "label": "全部よこせ。",
      "text": "Yes!"
  }
}

style パラメータでボタンの形を変えられます。
と、言ってもまだ3パターンしかないようです。
これからバリエーション増えるのかな?

primary
primary.png
secondry
secondry.png
link
link.png

link はボタンっぽくはしてくれないみたいですね。
LINE WORKS Developers - ボタン

ボックスの中にボックスを入れてさらにボックスを…

最期に、マトリョーシカ状態にチャレンジしてみましょう!ヾ(´∀`)ノ

あ、今回もコード長いので見たい方はクリックして広げてみてくださいね。
{
    "accountId": "xxxx@xxxxxx",
    "content": {
        "type": "flex",
        "altText": "This is a Flex Message",
        "contents": {
            "type": "bubble",
            "body": {
                "type": "box",
                "layout": "vertical",
                "spacing": "md",
                "contents": [{
                    "type": "image",
                    "url": "https://1.bp.blogspot.com/-DXwO_MFUgkM/UZ2VFQc90MI/AAAAAAAATuQ/Q0Qk05Ut9JE/s800/matryoshkas.png"
                },{
                    "type": "text",
                    "text": "マトリョーシカ 1",
                    "color": "#008000",
                    "weight": "bold"
                },{
                    "type": "separator"
                },{
                    "type": "box",
                    "layout": "horizontal",
                    "spacing": "md",
                    "contents": [{
                        "type": "image",
                        "url": "https://1.bp.blogspot.com/-DXwO_MFUgkM/UZ2VFQc90MI/AAAAAAAATuQ/Q0Qk05Ut9JE/s800/matryoshkas.png"
                    },{
                        "type": "text",
                        "text": "マトリョーシカ 2",
                        "wrap": true,
                        "color": "#008000",
                        "weight": "bold"
                    },{
                        "type": "separator"
                    },{
                        "type": "box",
                        "layout": "vertical",
                        "spacing": "md",
                        "contents": [{
                            "type": "image",
                            "url": "https://1.bp.blogspot.com/-DXwO_MFUgkM/UZ2VFQc90MI/AAAAAAAATuQ/Q0Qk05Ut9JE/s800/matryoshkas.png"
                        },{
                            "type": "text",
                            "text": "マトリョーシカ 3",
                            "wrap": true,
                            "color": "#008000",
                            "weight": "bold"
                        },{
                            "type": "separator"
                        },{
                            "type": "box",
                            "layout": "horizontal",
                            "contents": [{
                                "type": "image",
                                "url": "https://1.bp.blogspot.com/-DXwO_MFUgkM/UZ2VFQc90MI/AAAAAAAATuQ/Q0Qk05Ut9JE/s800/matryoshkas.png"
                            },{
                                "type": "text",
                                "text": "マト 4",
                                "wrap": true,
                                "color": "#008000",
                                "weight": "bold"
                            },{
                                "type": "separator"
                            }]
                        }]
                    }]
                }]
            }
        }
    }
}

1621394362.png

これ、延々とできますね。

1621394764.png

と、思いましたが8マトリョーシカ目で画面からはみ出てしまいましたね。
まぁ、何事にも節度と言うものがありますからね!( ゚Д゚)

おわりに

ここまでお付き合いいただきありがとうございました。

さぁ、最下層についたぞ!と、思いきやさらに下層があるなんて。。。
こだわり始めたら底なし沼クラス。
しかしその分、細部までこだわれる玄人志向。(●з●)

将来性の高い、デザイン性に富んだ機能だと思いました!
少しはデザインの勉強もしようかな?

最期に、私の描いた馬を貼っておきます。
ではまた!(^^)/

uma.png

参考にさせていただきましたm(_ _)m

LINE WORKS Developers

かわいいフリー素材集 いらすとや

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
2
Help us understand the problem. What are the problem?