Skip to content

Commit 4ab7a9c

Browse files
authored
Implement new richmenu API (#170)
* Implement new richmenu API * polish
1 parent c274772 commit 4ab7a9c

File tree

3 files changed

+265
-2
lines changed

3 files changed

+265
-2
lines changed

README.rst

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,17 @@ https://developers.line.me/en/docs/messaging-api/reference/#link-rich-menu-to-us
320320
321321
line_bot_api.link_rich_menu_to_user(user_id, rich_menu_id)
322322
323+
link\_rich\_menu\_to\_users(self, user\_ids, rich\_menu\_id, timeout=None)
324+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
325+
326+
Links a rich menu to multiple users.
327+
328+
https://developers.line.biz/en/reference/messaging-api/#link-rich-menu-to-users
329+
330+
.. code:: python
331+
332+
line_bot_api.link_rich_menu_to_users(<user_ids>, <rich_menu_id>)
333+
323334
unlink\_rich\_menu\_from\_user(self, user\_id, timeout=None)
324335
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
325336

@@ -331,6 +342,17 @@ https://developers.line.me/en/docs/messaging-api/reference/#unlink-rich-menu-fro
331342
332343
line_bot_api.unlink_rich_menu_from_user(user_id)
333344
345+
unlink\_rich\_menu\_from\_users(self, user\_ids, timeout=None)
346+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
347+
348+
Unlinks rich menus from multiple users.
349+
350+
https://developers.line.biz/en/reference/messaging-api/#unlink-rich-menu-from-users
351+
352+
.. code:: python
353+
354+
line_bot_api.unlink_rich_menu_from_users(<user_ids>)
355+
334356
get\_rich\_menu\_image(self, rich\_menu\_id, timeout=None)
335357
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
336358

@@ -370,6 +392,39 @@ https://developers.line.me/en/docs/messaging-api/reference/#get-rich-menu-list
370392
for rich_menu in rich_menu_list:
371393
print(rich_menu.rich_menu_id)
372394
395+
set\_default\_rich\_menu(self, rich\_menu\_id, timeout=None)
396+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
397+
398+
Sets the default rich menu.
399+
400+
https://developers.line.biz/en/reference/messaging-api/#set-default-rich-menu
401+
402+
.. code:: python
403+
404+
line_bot_api.set_default_rich_menu(<rich_menu_id>)
405+
406+
get\_default\_rich\_menu(self, timeout=None)
407+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
408+
409+
Gets the ID of the default rich menu set with the Messaging API.
410+
411+
https://developers.line.biz/en/reference/messaging-api/#get-default-rich-menu-id
412+
413+
.. code:: python
414+
415+
line_bot_api.get_default_rich_menu()
416+
417+
cancel\_default\_rich\_menu(self, timeout=None)
418+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
419+
420+
Cancels the default rich menu set with the Messaging API.
421+
422+
https://developers.line.biz/en/reference/messaging-api/#cancel-default-rich-menu
423+
424+
.. code:: python
425+
426+
line_bot_api.cancel_default_rich_menu()
427+
373428
※ Error handling
374429
^^^^^^^^^^^^^^^^
375430

linebot/api.py

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,8 +498,12 @@ def link_rich_menu_to_user(self, user_id, rich_menu_id, timeout=None):
498498
499499
https://developers.line.me/en/docs/messaging-api/reference/#link-rich-menu-to-user
500500
501-
:param str user_id: ID of an uploaded rich menu
502-
:param str rich_menu_id: ID of the user
501+
:param str user_id: ID of the user
502+
:param str rich_menu_id: ID of an uploaded rich menu
503+
:param timeout: (optional) How long to wait for the server
504+
to send data before giving up, as a float,
505+
or a (connect timeout, read timeout) float tuple.
506+
Default is self.http_client.timeout
503507
:type timeout: float | tuple(float, float)
504508
"""
505509
self._post(
@@ -510,6 +514,30 @@ def link_rich_menu_to_user(self, user_id, rich_menu_id, timeout=None):
510514
timeout=timeout
511515
)
512516

517+
def link_rich_menu_to_users(self, user_ids, rich_menu_id, timeout=None):
518+
"""Links a rich menu to multiple users.
519+
520+
https://developers.line.biz/en/reference/messaging-api/#link-rich-menu-to-users
521+
522+
:param user_ids: user IDs
523+
Max: 150 users
524+
:type user_ids: list[str]
525+
:param str rich_menu_id: ID of an uploaded rich menu
526+
:param timeout: (optional) How long to wait for the server
527+
to send data before giving up, as a float,
528+
or a (connect timeout, read timeout) float tuple.
529+
Default is self.http_client.timeout
530+
:type timeout: float | tuple(float, float)
531+
"""
532+
self._post(
533+
'/v2/bot/richmenu/bulk/link',
534+
data=json.dumps({
535+
'userIds': user_ids,
536+
'richMenuId': rich_menu_id,
537+
}),
538+
timeout=timeout
539+
)
540+
513541
def unlink_rich_menu_from_user(self, user_id, timeout=None):
514542
"""Call unlink rich menu from user API.
515543
@@ -527,6 +555,28 @@ def unlink_rich_menu_from_user(self, user_id, timeout=None):
527555
timeout=timeout
528556
)
529557

558+
def unlink_rich_menu_from_users(self, user_ids, timeout=None):
559+
"""Unlinks rich menus from multiple users.
560+
561+
https://developers.line.biz/en/reference/messaging-api/#unlink-rich-menu-from-users
562+
563+
:param user_ids: user IDs
564+
Max: 150 users
565+
:type user_ids: list[str]
566+
:param timeout: (optional) How long to wait for the server
567+
to send data before giving up, as a float,
568+
or a (connect timeout, read timeout) float tuple.
569+
Default is self.http_client.timeout
570+
:type timeout: float | tuple(float, float)
571+
"""
572+
self._post(
573+
'/v2/bot/richmenu/bulk/unlink',
574+
data=json.dumps({
575+
'userIds': user_ids,
576+
}),
577+
timeout=timeout
578+
)
579+
530580
def get_rich_menu_image(self, rich_menu_id, timeout=None):
531581
"""Call download rich menu image API.
532582
@@ -595,6 +645,59 @@ def get_rich_menu_list(self, timeout=None):
595645

596646
return result
597647

648+
def set_default_rich_menu(self, rich_menu_id, timeout=None):
649+
"""Set the default rich menu.
650+
651+
https://developers.line.biz/en/reference/messaging-api/#set-default-rich-menu
652+
653+
:param str rich_menu_id: ID of an uploaded rich menu
654+
:param timeout: (optional) How long to wait for the server
655+
to send data before giving up, as a float,
656+
or a (connect timeout, read timeout) float tuple.
657+
Default is self.http_client.timeout
658+
:type timeout: float | tuple(float, float)
659+
"""
660+
self._post(
661+
'/v2/bot/user/all/richmenu/{rich_menu_id}'.format(
662+
rich_menu_id=rich_menu_id,
663+
),
664+
timeout=timeout
665+
)
666+
667+
def get_default_rich_menu(self, timeout=None):
668+
"""Get the ID of the default rich menu set with the Messaging API.
669+
670+
https://developers.line.biz/en/reference/messaging-api/#get-default-rich-menu-id
671+
672+
:param timeout: (optional) How long to wait for the server
673+
to send data before giving up, as a float,
674+
or a (connect timeout, read timeout) float tuple.
675+
Default is self.http_client.timeout
676+
:type timeout: float | tuple(float, float)
677+
"""
678+
response = self._get(
679+
'/v2/bot/user/all/richmenu',
680+
timeout=timeout
681+
)
682+
683+
return response.json.get('richMenuId')
684+
685+
def cancel_default_rich_menu(self, timeout=None):
686+
"""Cancel the default rich menu set with the Messaging API.
687+
688+
https://developers.line.biz/en/reference/messaging-api/#cancel-default-rich-menu
689+
690+
:param timeout: (optional) How long to wait for the server
691+
to send data before giving up, as a float,
692+
or a (connect timeout, read timeout) float tuple.
693+
Default is self.http_client.timeout
694+
:type timeout: float | tuple(float, float)
695+
"""
696+
self._delete(
697+
'/v2/bot/user/all/richmenu',
698+
timeout=timeout
699+
)
700+
598701
def get_message_quota(self, timeout=None):
599702
"""Call Get the target limit for additional messages.
600703

tests/api/test_rich_menu.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from __future__ import unicode_literals, absolute_import
1616

17+
import json
1718
import unittest
1819

1920
import responses
@@ -283,6 +284,110 @@ def test_get_rich_menu_list(self):
283284
self.assertEqual(rich_menus[0].areas[0].action.type, 'postback')
284285
self.assertEqual(rich_menus[0].areas[0].action.data, 'action=buy&itemid=123')
285286

287+
@responses.activate
288+
def test_link_rich_menu_to_users(self):
289+
responses.add(
290+
responses.POST,
291+
LineBotApi.DEFAULT_API_ENDPOINT +
292+
'/v2/bot/richmenu/bulk/link',
293+
json={}, status=202
294+
)
295+
296+
self.tested.link_rich_menu_to_users(['user_id1', 'user_id2'], 'rich_menu_id')
297+
298+
request = responses.calls[0].request
299+
self.assertEqual(request.method, 'POST')
300+
self.assertEqual(
301+
request.url,
302+
LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/richmenu/bulk/link'
303+
)
304+
self.assertEqual(
305+
json.loads(request.body),
306+
{
307+
"richMenuId": "rich_menu_id",
308+
"userIds": ["user_id1", "user_id2"],
309+
}
310+
)
311+
312+
@responses.activate
313+
def test_unlink_rich_menu_to_users(self):
314+
responses.add(
315+
responses.POST,
316+
LineBotApi.DEFAULT_API_ENDPOINT +
317+
'/v2/bot/richmenu/bulk/unlink',
318+
json={}, status=202
319+
)
320+
321+
self.tested.unlink_rich_menu_from_users(['user_id1', 'user_id2'], 'rich_menu_id')
322+
323+
request = responses.calls[0].request
324+
self.assertEqual(request.method, 'POST')
325+
self.assertEqual(
326+
request.url,
327+
LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/richmenu/bulk/unlink'
328+
)
329+
self.assertEqual(
330+
json.loads(request.body),
331+
{
332+
"userIds": ["user_id1", "user_id2"],
333+
}
334+
)
335+
336+
@responses.activate
337+
def test_set_default_rich_menu(self):
338+
responses.add(
339+
responses.POST,
340+
LineBotApi.DEFAULT_API_ENDPOINT +
341+
'/v2/bot/user/all/richmenu/rich_menu_id',
342+
json={}, status=200
343+
)
344+
345+
self.tested.set_default_rich_menu('rich_menu_id')
346+
347+
request = responses.calls[0].request
348+
self.assertEqual(request.method, 'POST')
349+
self.assertEqual(
350+
request.url,
351+
LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/user/all/richmenu/rich_menu_id'
352+
)
353+
354+
@responses.activate
355+
def test_get_default_rich_menu(self):
356+
responses.add(
357+
responses.GET,
358+
LineBotApi.DEFAULT_API_ENDPOINT +
359+
'/v2/bot/user/all/richmenu',
360+
json={"richMenuId": "richMenuId"}, status=200
361+
)
362+
363+
result = self.tested.get_default_rich_menu()
364+
365+
request = responses.calls[0].request
366+
self.assertEqual(request.method, 'GET')
367+
self.assertEqual(
368+
request.url,
369+
LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/user/all/richmenu'
370+
)
371+
self.assertEqual(result, "richMenuId")
372+
373+
@responses.activate
374+
def test_cancel_default_rich_menu(self):
375+
responses.add(
376+
responses.DELETE,
377+
LineBotApi.DEFAULT_API_ENDPOINT +
378+
'/v2/bot/user/all/richmenu',
379+
json={}, status=200
380+
)
381+
382+
self.tested.cancel_default_rich_menu()
383+
384+
request = responses.calls[0].request
385+
self.assertEqual(request.method, 'DELETE')
386+
self.assertEqual(
387+
request.url,
388+
LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/user/all/richmenu'
389+
)
390+
286391

287392
if __name__ == '__main__':
288393
unittest.main()

0 commit comments

Comments
 (0)