Skip to content

Commit cb3af08

Browse files
qutsbe-hase
authored andcommitted
Add API for RichMenu Control (#85)
* Add API for RichMenu Control * Add create rich menu function and function will return a rich menu id * Add function to delete rich menu * Add function to get rich menu by rich menu id * Add comments for new functions * add function link_rich_menu_to_user but not test yet * add function to get rich menu list * add function to upload rich menu image * add function to get rich menu id of user * add function to unlink rich menu from user * fix typo in comment * Fix for flake8 check result * Add test case for get_rich_menu_id_of_user, unlink_rich_menu_from_user, link_rich_menu_to_user, delete_rich_menu * add api to download_rich_menu_image * add test case for create_rich_menu and get_rich_menu_list * Update README.rst for Rich menu apis * Update README.rst * Update URL * Remove py33 from tox.ini (#88) * Fix arg_parser option for examples (#87) * modify after PR review
1 parent 6d2b431 commit cb3af08

File tree

7 files changed

+718
-1
lines changed

7 files changed

+718
-1
lines changed

README.rst

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,135 @@ https://developers.line.me/en/docs/messaging-api/reference/#leave-room
241241
242242
line_bot_api.leave_room(room_id)
243243
244+
create\_rich\_menu(self, data, timeout=None)
245+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
246+
Create a rich menu object through a group of given data and return rich menu id.
247+
The data is an rich menu object to create.
248+
249+
https://developers.line.me/en/docs/messaging-api/reference/#create-rich-menu
250+
251+
.. code:: python
252+
253+
rich_menu_to_create = RichMenu(
254+
size=RichMenuBound(
255+
width=2500,
256+
height=1686
257+
),
258+
selected= False,
259+
name="nice richmenu",
260+
chatBarText="touch me",
261+
areas=[
262+
RichMenuArea(
263+
RichMenuBound(
264+
x=0,
265+
y=0,
266+
width=2500,
267+
height=1686
268+
),
269+
URITemplateAction(
270+
uri='line://nv/location'
271+
)
272+
)
273+
]
274+
)
275+
rich_menu_id = line_bot_api.create_rich_menu(data=rich_menu_to_create)
276+
print(rich_menu_id)
277+
278+
delete\_rich\_menu(self, rich\_menu\_id, timeout=None)
279+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
280+
281+
Delete rich menu object through a given rich_menu_id.
282+
283+
https://developers.line.me/en/docs/messaging-api/reference/#delete-rich-menu
284+
285+
.. code:: python
286+
287+
line_bot_api.delete_rich_menu(rich_menu_id)
288+
289+
set\_rich\_menu\_image(self, rich\_menu\_id, content\_type, content, timeout=None)
290+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
291+
292+
Uploads and attaches an image to a rich menu through id and image path.
293+
294+
https://developers.line.me/en/docs/messaging-api/reference/#upload-rich-menu-image
295+
296+
.. code:: python
297+
298+
line_bot_api.set_rich_menu_image(rich_menu_id, content_type, content)
299+
300+
link\_rich\_menu\_to\_user(self, user\_id, rich\_menu\_id, timeout=None)
301+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
302+
303+
Links a rich menu to a user. Only one rich menu can be linked to a user at one time.
304+
305+
https://developers.line.me/en/docs/messaging-api/reference/#link-rich-menu-to-user
306+
307+
.. code:: python
308+
309+
line_bot_api.link_rich_menu_to_user(user_id, rich_menu_id)
310+
311+
get\_rich\_menu\_list(self, timeout=None)
312+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
313+
314+
Gets a list of all uploaded rich menus.
315+
316+
https://developers.line.me/en/docs/messaging-api/reference/#get-rich-menu-list
317+
318+
.. code:: python
319+
320+
lst_rich_menu_obj = line_bot_api.get_rich_menu_list()
321+
for rich_menu_obj in lst_rich_menu_obj:
322+
print(rich_menu_obj.rich_menu_id)
323+
324+
get\_rich\_menu(self, rich\_menu\_id, timeout=None)
325+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
326+
327+
Get rich menu object through a given Rich menu ID.
328+
329+
https://developers.line.me/en/docs/messaging-api/reference/#get-rich-menu
330+
331+
.. code:: python
332+
333+
rich_menu_object = line_bot_api.get_rich_menu(rich_menu_id)
334+
print(rich_menu_obj.rich_menu_id)
335+
336+
get\_rich\_menu\_id\_of\_user(self, user\_id, timeout=None)
337+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
338+
339+
Gets the ID of the rich menu linked to a user.
340+
341+
https://developers.line.me/en/docs/messaging-api/reference/#get-rich-menu-id-of-user
342+
343+
.. code:: python
344+
345+
rich_menu_object = ine_bot_api.get_rich_menu_id_of_user(user_id)
346+
print(rich_menu_object.rich_menu_id)
347+
348+
unlink\_rich\_menu\_from\_user(self, user\_id, timeout=None)
349+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
350+
351+
Unlinks a rich menu from a user.
352+
353+
https://developers.line.me/en/docs/messaging-api/reference/#unlink-rich-menu-from-user
354+
355+
.. code:: python
356+
357+
line_bot_api.unlink_rich_menu_from_user(user_id)
358+
359+
get_rich_menu_image(self, rich\_menu\_id, timeout=None)
360+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
361+
362+
Downloads an image associated with a rich menu.
363+
364+
https://developers.line.me/en/docs/messaging-api/reference/#download-rich-menu-image
365+
366+
.. code:: python
367+
368+
message_content = line_bot_api.get_rich_menu_image(rich_menu_id)
369+
with open(file_path, 'wb') as fd:
370+
for chunk in message_content.iter_content():
371+
fd.write(chunk)
372+
244373
※ Error handling
245374
^^^^^^^^^^^^^^^^
246375

linebot/api.py

Lines changed: 213 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from .exceptions import LineBotApiError
2323
from .http_client import HttpClient, RequestsHttpClient
2424
from .models.error import Error
25-
from .models.responses import Profile, MemberIds, MessageContent
25+
from .models.responses import Profile, MemberIds, MessageContent, RichMenuResponse
2626

2727

2828
class LineBotApi(object):
@@ -124,6 +124,206 @@ def push_message(self, to, messages, timeout=None):
124124
'/v2/bot/message/push', data=json.dumps(data), timeout=timeout
125125
)
126126

127+
def get_rich_menu(self, rich_menu_id, timeout=None):
128+
"""Call get rich menu API.
129+
130+
https://developers.line.me/en/docs/messaging-api/reference/#get-rich-menu
131+
132+
Get rich menu object through a given rich_menu_id
133+
134+
:param str rich_menu_id: ID of the rich menu
135+
:param timeout: (optional) How long to wait for the server
136+
to send data before giving up, as a float,
137+
or a (connect timeout, read timeout) float tuple.
138+
Default is self.http_client.timeout
139+
:type timeout: float | tuple(float, float)
140+
:return: RichMenuResponse instance
141+
:type RichMenuResponse: T <= :py:class:`linebot.models.reponse.RichMenuResponse`
142+
"""
143+
response = self._get(
144+
'/v2/bot/richmenu/{rich_menu_id}'.format(rich_menu_id=rich_menu_id),
145+
timeout=timeout
146+
)
147+
148+
return RichMenuResponse.new_from_json_dict(response.json)
149+
150+
def delete_rich_menu(self, rich_menu_id, timeout=None):
151+
"""Call delete rich menu API.
152+
153+
https://developers.line.me/en/docs/messaging-api/reference/#delete-rich-menu
154+
155+
Delete rich menu object through a given rich_menu_id
156+
157+
:param str rich_menu_id: ID of the rich menu
158+
:param timeout: (optional) How long to wait for the server
159+
to send data before giving up, as a float,
160+
or a (connect timeout, read timeout) float tuple.
161+
Default is self.http_client.timeout
162+
:type timeout: float | tuple(float, float)
163+
"""
164+
self._delete(
165+
'/v2/bot/richmenu/{rich_menu_id}'.format(rich_menu_id=rich_menu_id),
166+
timeout=timeout
167+
)
168+
169+
def create_rich_menu(self, rich_menu, timeout=None):
170+
"""Call delete rich menu API.
171+
172+
https://developers.line.me/en/docs/messaging-api/reference/#create-rich-menu
173+
174+
Create a rich menu object through a group of given rich_menu data
175+
176+
:param rich_menu: Inquired to create a rich menu.
177+
:type rich_menu: T <= :py:class:`linebot.models.rich_menu.RichMenu`
178+
:param timeout: (optional) How long to wait for the server
179+
to send data before giving up, as a float,
180+
or a (connect timeout, read timeout) float tuple.
181+
Default is self.http_client.timeout
182+
:type timeout: float | tuple(float, float)
183+
:return: rich menu id
184+
"""
185+
response = self._post(
186+
'/v2/bot/richmenu', data=rich_menu.as_json_string(), timeout=timeout
187+
)
188+
189+
return response.json.get('richMenuId')
190+
191+
def link_rich_menu_to_user(self, user_id, rich_menu_id, timeout=None):
192+
"""Call link rich menu to user API.
193+
194+
https://developers.line.me/en/docs/messaging-api/reference/#link-rich-menu-to-user
195+
196+
Links a rich menu to a user. Only one rich menu can be linked to a user at one time.
197+
198+
:param str user_id: ID of an uploaded rich menu
199+
:param str rich_menu_id: ID of the user
200+
:type timeout: float | tuple(float, float)
201+
"""
202+
self._post(
203+
'/v2/bot/user/{user_id}/richmenu/{rich_menu_id}'.format(
204+
user_id=user_id,
205+
rich_menu_id=rich_menu_id
206+
),
207+
timeout=timeout
208+
)
209+
210+
def get_rich_menu_list(self, timeout=None):
211+
"""Call get rich menu list API.
212+
213+
https://developers.line.me/en/docs/messaging-api/reference/#get-rich-menu-list
214+
215+
Gets a list of all uploaded rich menus.
216+
217+
:return: An list of RichMenuResponse instances
218+
:type RichMenuResponse: T <= :py:class:`linebot.models.reponse.RichMenuResponse`
219+
:param timeout: (optional) How long to wait for the server
220+
to send data before giving up, as a float,
221+
or a (connect timeout, read timeout) float tuple.
222+
Default is self.http_client.timeout
223+
:type timeout: float | tuple(float, float)
224+
"""
225+
response = self._get(
226+
'/v2/bot/richmenu/list',
227+
timeout=timeout
228+
)
229+
230+
lst_result = []
231+
for richmenu in response.json['richmenus']:
232+
lst_result.append(RichMenuResponse.new_from_json_dict(richmenu))
233+
234+
return lst_result
235+
236+
def set_rich_menu_image(self, rich_menu_id, content_type, content, timeout=None):
237+
"""Call upload rich menu image API.
238+
239+
https://developers.line.me/en/docs/messaging-api/reference/#upload-rich-menu-image
240+
241+
Uploads and attaches an image to a rich menu.
242+
243+
:param str rich_menu_id: IDs of the rechmenu
244+
:param str content_type: image/jpeg or image/png
245+
:param str content: image content as request body in bytes
246+
:param timeout: (optional) How long to wait for the server
247+
to send data before giving up, as a float,
248+
or a (connect timeout, read timeout) float tuple.
249+
Default is self.http_client.timeout
250+
:type timeout: float | tuple(float, float)
251+
"""
252+
self.headers['Content-Type'] = content_type
253+
254+
# send request
255+
self._post(
256+
'/v2/bot/richmenu/{rich_menu_id}/content'.format(rich_menu_id=rich_menu_id),
257+
data=content,
258+
timeout=timeout
259+
)
260+
261+
# remove added header to avoid side effect in other apis
262+
del self.headers['Content-Type']
263+
264+
def get_rich_menu_id_of_user(self, user_id, timeout=None):
265+
"""Call get rich menu ID of user API.
266+
267+
https://developers.line.me/en/docs/messaging-api/reference/#get-rich-menu-id-of-user
268+
269+
Gets the ID of the rich menu linked to a user.
270+
271+
:param str user_id: IDs of the user
272+
:param timeout: (optional) How long to wait for the server
273+
to send data before giving up, as a float,
274+
or a (connect timeout, read timeout) float tuple.
275+
Default is self.http_client.timeout
276+
:type timeout: float | tuple(float, float)
277+
"""
278+
response = self._get(
279+
'/v2/bot/user/{user_id}/richmenu'.format(user_id=user_id),
280+
timeout=timeout
281+
)
282+
283+
return response.json.get('richMenuId')
284+
285+
def unlink_rich_menu_from_user(self, user_id, timeout=None):
286+
"""Call unlink rich menu from user API.
287+
288+
https://developers.line.me/en/docs/messaging-api/reference/#unlink-rich-menu-from-user
289+
290+
Unlinks a rich menu from a user.
291+
292+
:param str user_id: ID of the user
293+
:param timeout: (optional) How long to wait for the server
294+
to send data before giving up, as a float,
295+
or a (connect timeout, read timeout) float tuple.
296+
Default is self.http_client.timeout
297+
:type timeout: float | tuple(float, float)
298+
"""
299+
self._delete(
300+
'/v2/bot/user/{user_id}/richmenu'.format(user_id=user_id),
301+
timeout=timeout
302+
)
303+
304+
def get_rich_menu_image(self, rich_menu_id, timeout=None):
305+
"""Call download rich menu image API.
306+
307+
https://developers.line.me/en/docs/messaging-api/reference/#download-rich-menu-image
308+
309+
Downloads an image associated with a rich menu.
310+
311+
:param str rich_menu_id: ID of the rich menu with the image to be downloaded
312+
:param timeout: (optional) How long to wait for the server
313+
to send data before giving up, as a float,
314+
or a (connect timeout, read timeout) float tuple.
315+
Default is self.http_client.timeout
316+
:type timeout: float | tuple(float, float)
317+
:rtype: :py:class:`linebot.models.responses.MessageContent`
318+
:return: MessageContent instance
319+
"""
320+
response = self._get(
321+
'/v2/bot/richmenu/{rich_menu_id}/content'.format(rich_menu_id=rich_menu_id),
322+
timeout=timeout
323+
)
324+
325+
return MessageContent(response)
326+
127327
def multicast(self, to, messages, timeout=None):
128328
"""Call multicast API.
129329
@@ -372,6 +572,18 @@ def _post(self, path, data=None, timeout=None):
372572
self.__check_error(response)
373573
return response
374574

575+
def _delete(self, path, data=None, timeout=None):
576+
url = self.endpoint + path
577+
headers = {'Content-Type': 'application/json'}
578+
headers.update(self.headers)
579+
580+
response = self.http_client.delete(
581+
url, headers=headers, data=data, timeout=timeout
582+
)
583+
584+
self.__check_error(response)
585+
return response
586+
375587
@staticmethod
376588
def __check_error(response):
377589
if 200 <= response.status_code < 300:

0 commit comments

Comments
 (0)