Repository: line/line-bot-sdk-python

Issue:
Messaging API Update - November 2021
News: https://developers.line.biz/en/news/2021/11/09/messaging-api-update/

- [ ] [You can now retrieve the text entered by the user in a message sticker](https://developers.line.biz/en/news/2021/11/09/messaging-api-update/#messaging-api-202111-01)
- [ ] [You can now retrieve up to 1000 user IDs of friends](https://developers.line.biz/en/news/2021/11/09/messaging-api-update/#messaging-api-202111-02)

Discussion:
louis70109: > LGTM
> 
> [ask] BTW, Don't you have to reflect the changes in README?
> 
> It seems that some features are not reflected yet, so please ignore if there is no problem.

Thanks @cryeo -san, I changed README file with Sticker message and get_followers_ids API :)

Patch:
diff --git a/README.rst b/README.rst
index 022def1..e7563e6 100644
--- a/README.rst
+++ b/README.rst
@@ -650,6 +650,19 @@ https://developers.line.biz/en/reference/messaging-api/#test-webhook-endpoint
     print(test_result.reason)
     print(test_result.detail)
 
+get\_followers\_ids(self, limit=300, start=None, timeout=None)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Get a list of users who added your LINE Official Account as a friend.
+
+https://developers.line.biz/en/reference/messaging-api/#get-follower-ids
+
+.. code:: python
+
+    test_result = line_bot_api.get_followers_ids()
+    print(test_result.user_ids)
+    print(test_result.next)
+
 ※ Error handling
 ^^^^^^^^^^^^^^^^^
 
@@ -1229,6 +1242,8 @@ Message
     - package\_id
     - sticker\_id
     - sticker\_resource\_type
+    - keywords
+    - text
 - FileMessage
     - type
     - id
diff --git a/linebot/api.py b/linebot/api.py
index 465cd12..48a066e 100644
--- a/linebot/api.py
+++ b/linebot/api.py
@@ -1569,11 +1569,13 @@ class LineBotApi(object):
 
         return TestWebhookResponse.new_from_json_dict(response.json)
 
-    def get_followers_ids(self, start=None, timeout=None):
+    def get_followers_ids(self, limit=300, start=None, timeout=None):
         """Get a list of users who added your LINE Official Account as a friend.
 
         https://developers.line.biz/en/reference/messaging-api/#get-follower-ids
 
+        :param int limit: The maximum number of user IDs to retrieve in a single request.
+            The default value is 300.
         :param str start: Get the next array of user IDs.
         :param timeout: (optional) How long to wait for the server
             to send data before giving up, as a float,
@@ -1582,7 +1584,7 @@ class LineBotApi(object):
         :type timeout: float | tuple(float, float)
         :rtype: :py:class:`linebot.models.responses.UserIds`
         """
-        params = None if start is None else {'start': start}
+        params = {'limit': limit} if start is None else {'limit': limit, 'start': start}
 
         response = self._get(
             '/v2/bot/followers/ids',
diff --git a/linebot/models/messages.py b/linebot/models/messages.py
index 9f14dfa..92d6e10 100644
--- a/linebot/models/messages.py
+++ b/linebot/models/messages.py
@@ -213,7 +213,7 @@ class StickerMessage(Message):
     """
 
     def __init__(self, id=None, package_id=None, sticker_id=None,
-                 sticker_resource_type=None, keywords=None, **kwargs):
+                 sticker_resource_type=None, keywords=None, text=None, **kwargs):
         """__init__ method.
 
         :param str id: Message ID
@@ -221,6 +221,7 @@ class StickerMessage(Message):
         :param str sticker_id: Sticker ID
         :param str sticker_resource_type: Sticker resource type
         :param list[str] keywords: List of up to 15 keywords describing the sticker
+        :param str text: Any text entered by the user
         :param kwargs:
         """
         super(StickerMessage, self).__init__(id=id, **kwargs)
@@ -230,6 +231,7 @@ class StickerMessage(Message):
         self.sticker_id = sticker_id
         self.sticker_resource_type = sticker_resource_type
         self.keywords = keywords
+        self.text = text
 
 
 class FileMessage(Message):


Test patch:
diff --git a/tests/api/test_get_member_ids.py b/tests/api/test_get_member_ids.py
index e0d2654..fa77417 100644
--- a/tests/api/test_get_member_ids.py
+++ b/tests/api/test_get_member_ids.py
@@ -134,7 +134,7 @@ class TestLineBotApi(unittest.TestCase):
         self.assertEqual(request.method, 'GET')
         self.assertEqual(
             request.url,
-            LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/followers/ids')
+            LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/followers/ids?limit=300')
         self.assertEqual(member_ids_response.user_ids, ['U1', 'U2'])
         self.assertEqual(member_ids_response.next, None)
 
@@ -157,7 +157,30 @@ class TestLineBotApi(unittest.TestCase):
         self.assertEqual(
             request.url,
             LineBotApi.DEFAULT_API_ENDPOINT +
-            '/v2/bot/followers/ids?start=continuationToken1')
+            '/v2/bot/followers/ids?limit=300&start=continuationToken1')
+        self.assertEqual(member_ids_response.user_ids, ['U1', 'U2'])
+        self.assertEqual(member_ids_response.next, 'continuationToken2')
+
+    @responses.activate
+    def test_get_follower_user_ids_with_start_and_limit(self):
+        responses.add(
+            responses.GET,
+            LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/followers/ids',
+            json={
+                'userIds': ['U1', 'U2'],
+                'next': 'continuationToken2'
+            },
+            status=200
+        )
+
+        member_ids_response = self.tested.get_followers_ids(limit=2, start='continuationToken1')
+
+        request = responses.calls[0].request
+        self.assertEqual(request.method, 'GET')
+        self.assertEqual(
+            request.url,
+            LineBotApi.DEFAULT_API_ENDPOINT +
+            '/v2/bot/followers/ids?limit=2&start=continuationToken1')
         self.assertEqual(member_ids_response.user_ids, ['U1', 'U2'])
         self.assertEqual(member_ids_response.next, 'continuationToken2')
 
diff --git a/tests/test_webhook.py b/tests/test_webhook.py
index 536bffc..ad39638 100644
--- a/tests/test_webhook.py
+++ b/tests/test_webhook.py
@@ -170,6 +170,7 @@ class TestWebhookParser(unittest.TestCase):
         self.assertEqual(events[5].message.sticker_resource_type, 'STATIC')
         self.assertEqual(events[5].message.keywords[0], 'Love You')
         self.assertEqual(events[5].message.keywords[1], 'Love')
+        self.assertEqual(events[5].message.text, 'Just sticker')
 
         # FollowEvent, SourceUser
         self.assertIsInstance(events[6], FollowEvent)
diff --git a/tests/text/webhook.json b/tests/text/webhook.json
index a793d01..fc40964 100644
--- a/tests/text/webhook.json
+++ b/tests/text/webhook.json
@@ -107,7 +107,8 @@
         "packageId": "1",
         "stickerId": "1",
         "stickerResourceType": "STATIC",
-        "keywords": ["Love You", "Love"]
+        "keywords": ["Love You", "Love"],
+        "text": "Just sticker"
       }
     },
     {