AI LINE Bot練功坊-L12 Rich Menu
===
### 什麼是 Rich Menu?
> Rich Menu 是位於聊天室畫面下方的選單,可以讓使用者在聊天視窗中直接點擊按鈕,進行操作或獲取資訊。
### Rich Menu的優點
> Rich Menu,這個版位有絕佳的曝光度,每次用戶不管是因為推播或其他互動打開您的官方帳號時,都能看到這個版位。有了圖文選單區塊,不只曝光,更能幫您24小時導流做互動,讓您的服務不間斷!
# 設定 Rich Menu?
> 要建立圖文選單有兩種方式,第一種進入 Line@ 後台有功能可以使用,第二種透過 Messaging API 的程式端去建立
## Line官方帳號管理器
1. 在主頁裡點選「圖文選單」,再點選建立即可新增圖文選單


2. 設定頁面各個項目,設定完成後點選「儲存」
* 顯示設定:
* 設定標題名稱:管理圖文選單,此設定不會對用戶顯示

* 可以設定在用戶裝置上的圖文選單以及顯示時間
* 選單欄中顯示的文字設定欄
* 預設顯示方式:設定顯示時,當用戶進入聊天室,會直接顯示圖文選單;反之,設定隱藏時,用戶需要點選選單欄才會顯示圖文選單
* 內容設定:
* 選擇版型
Line官方有給參考的大小範例,可以參考使用



* 設定圖文選單的圖片


選擇剛剛下載好的模板

按下套用

* 根據模板的對應部分中設定動作

選擇文字

並在下方輸入文字內容

>Reference:https://tw.linebiz.com/manual/line-official-account/oa-manager-richmenu/
## Messaging API
* 更加客製化
* 可以在 rich menu 設定 postback action 和 datetime picker
* 可以設定切換 rich menu 的標籤
在開始之前,我們要先準備 rich menu 的圖片(下圖為範例圖片,可以到前面的設計規範下載)

使用 Linebot Designer 設計圖文選單,並複製產生的 json 檔




:::success
**注意事項**
* 每個 richmenu 最多可以設置20個可點選區塊
* 可以設置多個 richmenu 可按照情境作切換
* 最多可以同時有1000個 richmenu
* 可以為不同的 User 指定不同的 richmenu
:::
使用的套件
```python
from linebot.v3.messaging import (
MessagingApi,
MessagingApiBlob,
RichMenuSize,
RichMenuRequest,
RichMenuArea,
RichMenuBounds,
MessageAction
)
```
### 使用物件的方式
1. 利用 RichMenuArea 和 RichMenuBounds 兩個套件去建立 action 範圍的物件
(物件的範圍根據 Linebot Designer 設計出的範圍填寫)
```python
areas = [
RichMenuArea(
bounds=RichMenuBounds(
x=0,
y=0,
width=833,
height=843
),
action=MessageAction(text='A')
),
RichMenuArea(
bounds=RichMenuBounds(
x=834,
y=0,
width=833,
height=843
),
action=MessageAction(text='B')
),
RichMenuArea(
bounds=RichMenuBounds(
x=1663,
y=0,
width=834,
height=843
),
action=MessageAction(text='C')
),
RichMenuArea(
bounds=RichMenuBounds(
x=0,
y=843,
width=833,
height=843
),
action=MessageAction(text='D')
),
RichMenuArea(
bounds=RichMenuBounds(
x=834,
y=843,
width=833,
height=843
),
action=MessageAction(text='E')
),
RichMenuArea(
bounds=RichMenuBounds(
x=1662,
y=843,
width=834,
height=843
),
action=MessageAction(text='F')
)
]
```
2. 利用 RichMenuRequest 去製作整個 richmenu 的基本設定
* richmenu 圖片的大小
* 圖文選單的名稱
* 圖文選單縮小欄位的文字標籤
* areas 的物件(action 的設定)
```python
rich_menu_to_create = RichMenuRequest(
size=RichMenuSize(
width=2500,
height=1686,
),
selected=True,
name="圖文選單1",
chat_bar_text="查看更多資訊",
areas=areas
)
```
3. 取得 richmenu id
```python
rich_menu_a_id = line_bot_api.create_rich_menu(
rich_menu_request=rich_menu_to_create
).rich_menu_id
```
4. 設定 richmenu 到 Linebot 上
```python
with open('./public/richmenu-a.png', 'rb') as image:
line_bot_blob_api.set_rich_menu_image(
rich_menu_id=rich_menu_a_id,
body=bytearray(image.read()),
_headers={'Content-Type': 'image/png'}
)
```
完整的程式碼 :
```python
def create_rich_menu_1():
with ApiClient(configuration) as api_client:
line_bot_api = MessagingApi(api_client)
line_bot_blob_api = MessagingApiBlob(api_client)
areas = [
RichMenuArea(
bounds=RichMenuBounds(
x=0,
y=0,
width=833,
height=843
),
action=MessageAction(text='A')
),
RichMenuArea(
bounds=RichMenuBounds(
x=834,
y=0,
width=833,
height=843
),
action=MessageAction(text='B')
),
RichMenuArea(
bounds=RichMenuBounds(
x=1663,
y=0,
width=834,
height=843
),
action=MessageAction(text='C')
),
RichMenuArea(
bounds=RichMenuBounds(
x=0,
y=843,
width=833,
height=843
),
action=MessageAction(text='D')
),
RichMenuArea(
bounds=RichMenuBounds(
x=834,
y=843,
width=833,
height=843
),
action=MessageAction(text='E')
),
RichMenuArea(
bounds=RichMenuBounds(
x=1662,
y=843,
width=834,
height=843
),
action=MessageAction(text='F')
)
]
rich_menu_to_create = RichMenuRequest(
size=RichMenuSize(
width=2500,
height=1686,
),
selected=True,
name="圖文選單1",
chat_bar_text="查看更多資訊",
areas=areas
)
rich_menu_id = line_bot_api.create_rich_menu(
rich_menu_request=rich_menu_to_create
).rich_menu_id
with open('./public/richmenu-a.png', 'rb') as image:
line_bot_blob_api.set_rich_menu_image(
rich_menu_id=rich_menu_id,
body=bytearray(image.read()),
_headers={'Content-Type': 'image/png'}
)
line_bot_api.set_default_rich_menu(rich_menu_id)
```
#### 使用json的方式
1. 複製前面用 Linebot Designer 設計好的 json,並放在 `body` 中

`headers`放的是 CHANNEL_ACCESS_TOKEN
```python
headers = {
'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
'Content-Type': 'application/json'
}
body = {
"size": {
"width": 2500,
"height": 1686
},
"selected": True,
"name": "圖文選單 1",
"chatBarText": "查看更多資訊",
"areas": [
{
"bounds": {
"x": 0,
"y": 0,
"width": 833,
"height": 843
},
"action": {
"type": "message",
"text": "A"
}
},
{
"bounds": {
"x": 834,
"y": 0,
"width": 833,
"height": 843
},
"action": {
"type": "message",
"text": "B"
}
},
{
"bounds": {
"x": 1663,
"y": 0,
"width": 834,
"height": 843
},
"action": {
"type": "message",
"text": "C"
}
},
{
"bounds": {
"x": 0,
"y": 843,
"width": 833,
"height": 843
},
"action": {
"type": "message",
"text": "D"
}
},
{
"bounds": {
"x": 834,
"y": 843,
"width": 833,
"height": 843
},
"action": {
"type": "message",
"text": "E"
}
},
{
"bounds": {
"x": 1662,
"y": 843,
"width": 838,
"height": 843
},
"action": {
"type": "message",
"text": "F"
}
}
]
}
```
2. 取得 richmenu id
```python
response = requests.post(
'https://api.line.me/v2/bot/richmenu',
headers=headers,
data=json.dumps(body).encode('utf-8')
)
response = response.json()
print(response)
rich_menu_id = response["richMenuId"]
```
3. 上傳 richmenu 圖片
```python
with open('static/richmenu-1.jpg', 'rb') as image:
line_bot_blob_api.set_rich_menu_image(
rich_menu_id=rich_menu_id,
body=bytearray(image.read()),
_headers={'Content-Type': 'image/jpeg'}
)
```
4. 其他 richmenu 操作
* 查看所有richmenuID
```python
from linebot.v3.messaging import MessagingApi
# 查看所有的richmenu
line_bot_api = MessagingApi('Channel Access Token')
rich_menu_list = line_bot_api.get_rich_menu_list()
for rich_menu in rich_menu_list:
print(rich_menu.rich_menu_id)
```
* 刪除所有richmenuID
```python
from linebot.v3.messaging import MessagingApi
#刪除richmenu
for rich_menu in rich_menu_list:
line_bot_api = MessagingApi('Channel Access Token')
line_bot_api.delete_rich_menu(rich_menu.rich_menu_id)
```
完整程式碼
```python
def create_rich_menu_2():
with ApiClient(configuration) as api_client:
line_bot_api = MessagingApi(api_client)
line_bot_blob_api = MessagingApiBlob(api_client)
# Create rich menu
headers = {
'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
'Content-Type': 'application/json'
}
body = {
"size": {
"width": 2500,
"height": 1686
},
"selected": True,
"name": "圖文選單 1",
"chatBarText": "查看更多資訊",
"areas": [
{
"bounds": {
"x": 0,
"y": 0,
"width": 833,
"height": 843
},
"action": {
"type": "message",
"text": "A"
}
},
{
"bounds": {
"x": 834,
"y": 0,
"width": 833,
"height": 843
},
"action": {
"type": "message",
"text": "B"
}
},
{
"bounds": {
"x": 1663,
"y": 0,
"width": 834,
"height": 843
},
"action": {
"type": "message",
"text": "C"
}
},
{
"bounds": {
"x": 0,
"y": 843,
"width": 833,
"height": 843
},
"action": {
"type": "message",
"text": "D"
}
},
{
"bounds": {
"x": 834,
"y": 843,
"width": 833,
"height": 843
},
"action": {
"type": "message",
"text": "E"
}
},
{
"bounds": {
"x": 1662,
"y": 843,
"width": 838,
"height": 843
},
"action": {
"type": "message",
"text": "F"
}
}
]
}
response = requests.post(
'https://api.line.me/v2/bot/richmenu',
headers=headers,
data=json.dumps(body).encode('utf-8')
)
response = response.json()
print(response)
rich_menu_id = response["richMenuId"]
# Upload rich menu image
with open('static/richmenu-1.jpg', 'rb') as image:
line_bot_blob_api.set_rich_menu_image(
rich_menu_id=rich_menu_id,
body=bytearray(image.read()),
_headers={'Content-Type': 'image/jpeg'}
)
line_bot_api.set_default_rich_menu(rich_menu_id)
```
>Reference:https://developers.line.biz/en/docs/messaging-api/using-rich-menus/
Youtube 課程影片
---
<iframe width="560" height="315" src="https://www.youtube.com/embed/kF1RVtKqzV4?si=Uibs7ZMAukkKdaqb" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
{%hackmd @ntuebigdata/about %}
## 相關教材連結
<div style="display: flex; justify-content:space-between;">
<div>
<a class="btn btn-warning" href="https://hackmd.io/@ntuebigdata/quick-reply" style="color:white;width:300px;text-overflow:ellipsis;overflow:hidden">◀◀◀ L11 Quick Reply ◀◀◀</a>
</div>
<div>
<a class="btn btn-info" href="https://hackmd.io/@ntuebigdata/deploy-linebot" style="color:white;width:300px;text-overflow:ellipsis;overflow:hidden">▶▶▶ L13 LineBot 部屬 ▶▶▶</a>
</div>
</div>