1
/
5

LINE Messaging APIでリッチメニューを作成・表示させる方法

こんにちは。dotDでmeepaの開発を担当している前田です。


meepa | 子どもの本当の好きに出会う 課外活動マッチングサービス
meepaは「子どもの本当の好きに出会う」を目指して、幼稚園・保育園・学童などで子どもたちが様々な体験の機会を得られるように、園と課外活動提供者をマッチングするサービスです。
https://meepa.io/

今回は、LINE公式アカウントのトーク画面に表示される、カスタマイズ可能なメニューである「リッチメニュー」の作成・表示方法について解説します。
LINE Messaging APIのリッチメニューのドキュメントがわかりづらいと感じたため、この記事を書きました。

この記事が、リッチメニュー作成に手こずっている方の助けになれば幸いです。

▼目次

  • 作るもの
  • 使用ツール
  • リッチメニューの作成・表示手順
  • ①リッチメニューを作成する
  • ②リッチメニューに画像をつける
  • ③LINE公式アカウントでリッチメニューが表示されるように設定する
  • まとめ

作るもの

                   meepaのリッチメニュー

meepaで実際に使っているリッチメニューを作成します。

使用ツール

リッチメニューを作成・表示させるには、LINE Messaging APIが用意しているリッチメニューAPIを叩く必要があります。

APIを叩くのはcurlでやってもいいですが、Postmanを使うのがオススメです。
直感的に使えますし、APIリクエストを保存できるのでとても便利です。

Postman API Platform | Sign Up for Free
Postman is an API platform for building and using APIs. Postman simplifies each step of the API lifecycle and streamlines collaboration so you can create better APIs-faster.
https://www.postman.com/

リッチメニューの作成・表示手順

流れとしては、以下になります。

①リッチメニューを作成する
②リッチメニューに画像をつける
③LINE公式アカウントでリッチメニューが表示されるように設定する

1つずつ見ていきます。

①リッチメニューを作成する

- エンドポイント
- https://api.line.me/v2/bot/richmenu

- HTTPメソッド
- POST

- リクエストヘッダー
- Authorization
- Bearer {channel access token}
- Content-Type
- application/json

- リクエストボディ
{
"size": {
"width": 900,
"height": 600
},
"selected": false,
"name": "meepa(β版)",
"chatBarText": "メニュー",
"areas": [
{
"bounds": {
"x": 0,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "レコメンドを受け取る",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 225,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "予約を確認する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 450,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "登録内容を変更する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 675,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "ジャンルを変更する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 0,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "お気に入りを確認する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 225,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "クレジット数を確認する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 450,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "uri",
"uri": "xxx"
}
},
{
"bounds": {
"x": 675,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "お問い合わせ",
"data": "method=xxx"
}
}
]
}

- レスポンス
{
"richMenuId": "{richMenuId}"
}- エンドポイント
- https://api.line.me/v2/bot/richmenu

- HTTPメソッド
- POST

- リクエストヘッダー
- Authorization
- Bearer {channel access token}
- Content-Type
- application/json

- リクエストボディ
{
"size": {
"width": 900,
"height": 600
},
"selected": false,
"name": "meepa(β版)",
"chatBarText": "メニュー",
"areas": [
{
"bounds": {
"x": 0,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "レコメンドを受け取る",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 225,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "予約を確認する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 450,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "登録内容を変更する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 675,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "ジャンルを変更する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 0,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "お気に入りを確認する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 225,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "クレジット数を確認する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 450,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "uri",
"uri": "xxx"
}
},
{
"bounds": {
"x": 675,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "お問い合わせ",
"data": "method=xxx"
}
}
]
}

- レスポンス
{
"richMenuId": "{richMenuId}"
}

リクエストボディの以下JSONの`bounds`がわかりづらいと思うので、こちらを詳細に解説します。

  "areas": [
{
"bounds": {
"x": 0,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "レコメンドを受け取る",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 225,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "予約を確認する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 450,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "登録内容を変更する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 675,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "ジャンルを変更する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 0,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "お気に入りを確認する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 225,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "クレジット数を確認する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 450,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "uri",
"uri": "xxx"
}
},
{
"bounds": {
"x": 675,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "お問い合わせ",
"data": "method=xxx"
}
}
] "areas": [
{
"bounds": {
"x": 0,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "レコメンドを受け取る",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 225,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "予約を確認する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 450,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "登録内容を変更する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 675,
"y": 0,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "ジャンルを変更する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 0,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "お気に入りを確認する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 225,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "クレジット数を確認する",
"data": "method=xxx"
}
},
{
"bounds": {
"x": 450,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "uri",
"uri": "xxx"
}
},
{
"bounds": {
"x": 675,
"y": 300,
"width": 225,
"height": 300
},
"action": {
"type": "postback",
"displayText": "お問い合わせ",
"data": "method=xxx"
}
}
]

`areas`はリッチメニューエリアを指していて、`bounds`はリッチメニューエリアの1つのエリア(リッチメニュー小エリアとします)を指しています。
meepaのリッチメニューでは、リッチメニュー小エリアが8つあるので、`bounds`は8つあります。

`bounds`の`width`と`height`はリッチメニュー小エリアの幅と高さを指しています。meepaのリッチメニュー小エリアはいずれも幅225px高さ300pxになっています。
`x`と`y`は座標を指しています。座標は以下のように左上を(0, 0)とします。そして、①から順番に`bounds`を指定していきます。

                   meepaのリッチメニュー

②リッチメニューに画像をつける

- リッチメニューの画像の要件
- 画像フォーマット:JPEGまたはPNG
- 画像の幅サイズ(ピクセル):800以上、2500以下
- 画像の高さサイズ(ピクセル):250以上
- 画像のアスペクト比(幅/高さ):1.45以上
- 最大ファイルサイズ:1MB

- エンドポイント
- https://api-data.line.me/v2/bot/richmenu/{richMenuId}/content

- パスパラメータ
- richMenuId

- HTTPメソッド
- POST

- リクエストヘッダー
- Authorization
- Bearer {channel access token}
- Content-Type
- image/jpegまたはimage/png

- リクエストボディ
- 画像

- レスポンス
{}- リッチメニューの画像の要件
- 画像フォーマット:JPEGまたはPNG
- 画像の幅サイズ(ピクセル):800以上、2500以下
- 画像の高さサイズ(ピクセル):250以上
- 画像のアスペクト比(幅/高さ):1.45以上
- 最大ファイルサイズ:1MB

- エンドポイント
- https://api-data.line.me/v2/bot/richmenu/{richMenuId}/content

- パスパラメータ
- richMenuId

- HTTPメソッド
- POST

- リクエストヘッダー
- Authorization
- Bearer {channel access token}
- Content-Type
- image/jpegまたはimage/png

- リクエストボディ
- 画像

- レスポンス
{}

パスパラメータには、①リッチメニューを作成する でレスポンスとして返ってきたrichMenuIdを指定します。

③LINE公式アカウントでリッチメニューが表示されるように設定する

- エンドポイント
- https://api.line.me/v2/bot/user/all/richmenu/{richMenuId}

- パスパラメータ
- richMenuId

- HTTPメソッド
- POST

- リクエストヘッダー
- Authorization
- Bearer {channel access token}

- レスポンス
{}- エンドポイント
- https://api.line.me/v2/bot/user/all/richmenu/{richMenuId}

- パスパラメータ
- richMenuId

- HTTPメソッド
- POST

- リクエストヘッダー
- Authorization
- Bearer {channel access token}

- レスポンス
{}

ここのパスパラメータにも、①リッチメニューを作成する でレスポンスとして返ってきたrichMenuIdを指定します。

まとめ

今回は、リッチメニューの作成・表示方法について解説しました。
私は、以前リッチメニューを作成するときに、`bounds`がわかりづらいと感じたため、`bounds`の指定方法にフォーカスして、リッチメニューの作成・表示方法の記事を書きたいと思っていました。
同じところでつまづいている方もきっといると思うので、この記事がリッチメニュー作成のご参考になれば大変嬉しく思います!

最後に、dotDでは、新しい事業を共に作っていくためのエンジニアのメンバーを募集しています!
少しでも興味を持ってくださった方はお気軽にご連絡ください!!


Web Engineer
子どもが本当の好きと出会うためのプラットフォーム!立ち上げエンジニア募集!
【世の中に新しい価値を生み出し続ける事業創造ファーム】 私たちdotDは、デジタルを活用した新しい事業を数多く作り出すことによって社会の基盤になることを目指す「事業創造ファーム」です。 ・社員の問題意識を起点に様々な事業を通じて社会課題解決にチャレンジする「自社事業」 ・大企業とのコラボレーションで社会的インパクトを創出する「共創事業」 の2つのやり方で、複数のプロジェクトに並行して取り組み、 試行錯誤を繰り返しながら、世の中に新しい価値を生み出すことに挑戦しています。 ■自社事業例:愛犬とオーナーに、「次の幸せ」を届けるプラットフォーム「onedog」 ・世界7億世帯、22兆円マーケットと呼ばれるペットテックの領域でペットテックプラットフォームonedogを提供しています。最初からグローバルマーケットを取りに行き、単純なアプリではなくその先のプラットフォーム戦略を見据えたビジネスを推進しています。 ・onedogはグッドデザイン賞を受賞しています。 ■共創事業例:クルマの鍵屋だからできた安心安全のデジタルキー TOKAI RIKA 「Digitalkey」 ・クルマから始まり、生活で利用する様々な「鍵」をデジタル化し、それらが繋がることで未来のスマートシティを支えるサービスです。クルマ以外のモビリティ、オフィスなどの建物、駐車場などもデジタルキー化し、物理的な「鍵」のないシームレスで便利・安全な社会の実現を目指します。 ・dotDはTOKAI RIKA Digitalkeyを、構想策定から開発、セールス・マーケティング、カスタマーサクセスまで一貫して、共同事業として運営しています。 今回は、自社事業プロジェクトとして2020年10月に検討を開始した、 子どもが本当の好きと出会うためのマッチングプラットフォーム を開発するためのエンジニアを募集します。
株式会社dotD


株式会社dotD | 事業創造ファーム
dotDはB2B,B2Cに関わらずのデジタルを活用した事業を連続的、非連続的に作り出すことによって社会の基盤になることを目指している「事業創造ファーム」です。
https://dotd-inc.com/



Invitation from 株式会社dotD
If this story triggered your interest, have a chat with the team?
株式会社dotD's job postings

Weekly ranking

Show other rankings
Like funabashi yukiko's Story
Let funabashi yukiko's company know you're interested in their content