Skip to content

Commit 0b4b6b7

Browse files
be-haseokdtsk
authored andcommitted
Add get_group_member_ids / get_room_member_ids (#58)
1 parent 376c09d commit 0b4b6b7

File tree

8 files changed

+266
-66
lines changed

8 files changed

+266
-66
lines changed

README.rst

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,36 @@ https://devdocs.line.me/en/#get-group-room-member-profile
174174
print(profile.user_id)
175175
print(profile.picture_url)
176176
177+
get\_group\_member\_ids(self, group\_id, start=None, timeout=None)
178+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
179+
180+
Gets the user IDs of the members of a group that the bot is in.
181+
This includes the user IDs of users who have not added the bot as a friend or has blocked the bot.
182+
183+
https://devdocs.line.me/en/#get-group-room-member-ids
184+
185+
.. code:: python
186+
187+
member_ids_res = line_bot_api.get_group_member_ids(group_id)
188+
189+
print(member_ids_res.member_ids)
190+
print(member_ids_res.next)
191+
192+
get\_room\_member\_ids(self, room\_id, start=None, timeout=None)
193+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
194+
195+
Gets the user IDs of the members of a room that the bot is in.
196+
This includes the user IDs of users who have not added the bot as a friend or has blocked the bot.
197+
198+
https://devdocs.line.me/en/#get-group-room-member-ids
199+
200+
.. code:: python
201+
202+
member_ids_res = line_bot_api.get_room_member_ids(room_id)
203+
204+
print(member_ids_res.member_ids)
205+
print(member_ids_res.next)
206+
177207
get\_message\_content(self, message\_id, timeout=None)
178208
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
179209

linebot/api.py

Lines changed: 61 additions & 3 deletions
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, MessageContent
25+
from .models.responses import Profile, MemberIds, MessageContent
2626

2727

2828
class LineBotApi(object):
@@ -231,6 +231,64 @@ def get_room_member_profile(self, room_id, user_id, timeout=None):
231231

232232
return Profile.new_from_json_dict(response.json)
233233

234+
def get_group_member_ids(self, group_id, start=None, timeout=None):
235+
"""Call get group member IDs API.
236+
237+
https://devdocs.line.me/en/#get-group-room-member-ids
238+
239+
Gets the user IDs of the members of a group that the bot is in.
240+
This includes the user IDs of users who have not added the bot as a friend
241+
or has blocked the bot.
242+
243+
:param str group_id: Group ID
244+
:param str start: continuationToken
245+
:param timeout: (optional) How long to wait for the server
246+
to send data before giving up, as a float,
247+
or a (connect timeout, read timeout) float tuple.
248+
Default is self.http_client.timeout
249+
:type timeout: float | tuple(float, float)
250+
:rtype: :py:class:`linebot.models.responses.MemberIds`
251+
:return: MemberIds instance
252+
"""
253+
params = None if start is None else {'start': start}
254+
255+
response = self._get(
256+
'/v2/bot/group/{group_id}/members/ids'.format(group_id=group_id),
257+
params=params,
258+
timeout=timeout
259+
)
260+
261+
return MemberIds.new_from_json_dict(response.json)
262+
263+
def get_room_member_ids(self, room_id, start=None, timeout=None):
264+
"""Call get room member IDs API.
265+
266+
https://devdocs.line.me/en/#get-group-room-member-ids
267+
268+
Gets the user IDs of the members of a group that the bot is in.
269+
This includes the user IDs of users who have not added the bot as a friend
270+
or has blocked the bot.
271+
272+
:param str room_id: Room ID
273+
:param str start: continuationToken
274+
:param timeout: (optional) How long to wait for the server
275+
to send data before giving up, as a float,
276+
or a (connect timeout, read timeout) float tuple.
277+
Default is self.http_client.timeout
278+
:type timeout: float | tuple(float, float)
279+
:rtype: :py:class:`linebot.models.responses.MemberIds`
280+
:return: MemberIds instance
281+
"""
282+
params = None if start is None else {'start': start}
283+
284+
response = self._get(
285+
'/v2/bot/room/{room_id}/members/ids'.format(room_id=room_id),
286+
params=params,
287+
timeout=timeout
288+
)
289+
290+
return MemberIds.new_from_json_dict(response.json)
291+
234292
def get_message_content(self, message_id, timeout=None):
235293
"""Call get content API.
236294
@@ -292,11 +350,11 @@ def leave_room(self, room_id, timeout=None):
292350
timeout=timeout
293351
)
294352

295-
def _get(self, path, stream=False, timeout=None):
353+
def _get(self, path, params=None, stream=False, timeout=None):
296354
url = self.endpoint + path
297355

298356
response = self.http_client.get(
299-
url, headers=self.headers, stream=stream, timeout=timeout
357+
url, headers=self.headers, params=params, stream=stream, timeout=timeout
300358
)
301359

302360
self.__check_error(response)

linebot/http_client.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def __init__(self, timeout=DEFAULT_TIMEOUT):
3232
3333
:param timeout: (optional) How long to wait for the server
3434
to send data before giving up, as a float,
35-
or a (connect timeout, readtimeout) float tuple.
35+
or a (connect timeout, read timeout) float tuple.
3636
Default is :py:attr:`DEFAULT_TIMEOUT`
3737
:type timeout: float | tuple(float, float)
3838
:rtype: T <= :py:class:`HttpResponse`
@@ -50,7 +50,7 @@ def get(self, url, headers=None, params=None, stream=False, timeout=None):
5050
:param bool stream: (optional) get content as stream
5151
:param timeout: (optional), How long to wait for the server
5252
to send data before giving up, as a float,
53-
or a (connect timeout, readtimeout) float tuple.
53+
or a (connect timeout, read timeout) float tuple.
5454
Default is :py:attr:`self.timeout`
5555
:type timeout: float | tuple(float, float)
5656
:rtype: T <= :py:class:`HttpResponse`
@@ -67,7 +67,7 @@ def post(self, url, headers=None, data=None, timeout=None):
6767
:param data: (optional) Dictionary, bytes, or file-like object to send in the body
6868
:param timeout: (optional), How long to wait for the server
6969
to send data before giving up, as a float,
70-
or a (connect timeout, readtimeout) float tuple.
70+
or a (connect timeout, read timeout) float tuple.
7171
Default is :py:attr:`self.timeout`
7272
:type timeout: float | tuple(float, float)
7373
:rtype: T <= :py:class:`HttpResponse`
@@ -84,7 +84,7 @@ def __init__(self, timeout=HttpClient.DEFAULT_TIMEOUT):
8484
8585
:param timeout: (optional) How long to wait for the server
8686
to send data before giving up, as a float,
87-
or a (connect timeout, readtimeout) float tuple.
87+
or a (connect timeout, read timeout) float tuple.
8888
Default is :py:attr:`DEFAULT_TIMEOUT`
8989
:type timeout: float | tuple(float, float)
9090
"""
@@ -99,7 +99,7 @@ def get(self, url, headers=None, params=None, stream=False, timeout=None):
9999
:param bool stream: (optional) get content as stream
100100
:param timeout: (optional), How long to wait for the server
101101
to send data before giving up, as a float,
102-
or a (connect timeout, readtimeout) float tuple.
102+
or a (connect timeout, read timeout) float tuple.
103103
Default is :py:attr:`self.timeout`
104104
:type timeout: float | tuple(float, float)
105105
:rtype: :py:class:`RequestsHttpResponse`
@@ -122,7 +122,7 @@ def post(self, url, headers=None, data=None, timeout=None):
122122
:param data: (optional) Dictionary, bytes, or file-like object to send in the body
123123
:param timeout: (optional), How long to wait for the server
124124
to send data before giving up, as a float,
125-
or a (connect timeout, readtimeout) float tuple.
125+
or a (connect timeout, read timeout) float tuple.
126126
Default is :py:attr:`self.timeout`
127127
:type timeout: float | tuple(float, float)
128128
:rtype: :py:class:`RequestsHttpResponse`

linebot/models/responses.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,28 @@ def __init__(self, display_name=None, user_id=None, picture_url=None,
4343
self.status_message = status_message
4444

4545

46+
class MemberIds(Base):
47+
"""MemberIds.
48+
49+
https://devdocs.line.me/en/#get-group-room-member-ids
50+
"""
51+
52+
def __init__(self, member_ids=None, next=None, **kwargs):
53+
"""__init__ method.
54+
55+
:param member_ids: List of user IDs of the members in the group or room.
56+
Max: 100 user IDs
57+
:type member_ids: list[str]
58+
:param str next: continuationToken.
59+
Only returned when there are more user IDs remaining in memberIds.
60+
:param kwargs:
61+
"""
62+
super(MemberIds, self).__init__(**kwargs)
63+
64+
self.member_ids = member_ids
65+
self.next = next
66+
67+
4668
class MessageContent(object):
4769
"""MessageContent.
4870
@@ -54,7 +76,6 @@ def __init__(self, response):
5476
5577
:param response: HttpResponse object
5678
:type response: T <= :py:class:`linebot.http_client.HttpResponse`
57-
:param kwargs:
5879
"""
5980
self.response = response
6081

tests/api/test_get_member_ids.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
15+
from __future__ import unicode_literals, absolute_import
16+
17+
import unittest
18+
19+
import responses
20+
21+
from linebot import (
22+
LineBotApi
23+
)
24+
25+
26+
class TestLineBotApi(unittest.TestCase):
27+
def setUp(self):
28+
self.tested = LineBotApi('channel_secret')
29+
30+
@responses.activate
31+
def test_get_group_member_ids(self):
32+
responses.add(
33+
responses.GET,
34+
LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/group/group_id/members/ids',
35+
json={
36+
'memberIds': ['U1', 'U2']
37+
},
38+
status=200
39+
)
40+
41+
member_ids_response = self.tested.get_group_member_ids('group_id')
42+
43+
request = responses.calls[0].request
44+
self.assertEqual(request.method, 'GET')
45+
self.assertEqual(
46+
request.url,
47+
LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/group/group_id/members/ids')
48+
self.assertEqual(member_ids_response.member_ids, ['U1', 'U2'])
49+
self.assertEqual(member_ids_response.next, None)
50+
51+
@responses.activate
52+
def test_get_group_member_ids_with_start(self):
53+
responses.add(
54+
responses.GET,
55+
LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/group/group_id/members/ids',
56+
json={
57+
'memberIds': ['U1', 'U2'],
58+
'next': 'continuationToken2'
59+
},
60+
status=200
61+
)
62+
63+
member_ids_response = self.tested.get_group_member_ids('group_id',
64+
start='continuationToken1')
65+
66+
request = responses.calls[0].request
67+
self.assertEqual(request.method, 'GET')
68+
self.assertEqual(
69+
request.url,
70+
LineBotApi.DEFAULT_API_ENDPOINT +
71+
'/v2/bot/group/group_id/members/ids?start=continuationToken1')
72+
self.assertEqual(member_ids_response.member_ids, ['U1', 'U2'])
73+
self.assertEqual(member_ids_response.next, 'continuationToken2')
74+
75+
@responses.activate
76+
def test_get_room_member_ids(self):
77+
responses.add(
78+
responses.GET,
79+
LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/room/room_id/members/ids',
80+
json={
81+
'memberIds': ['U1', 'U2']
82+
},
83+
status=200
84+
)
85+
86+
member_ids_response = self.tested.get_room_member_ids('room_id')
87+
88+
request = responses.calls[0].request
89+
self.assertEqual(request.method, 'GET')
90+
self.assertEqual(
91+
request.url,
92+
LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/room/room_id/members/ids')
93+
self.assertEqual(member_ids_response.member_ids, ['U1', 'U2'])
94+
self.assertEqual(member_ids_response.next, None)
95+
96+
@responses.activate
97+
def test_get_room_member_ids_with_start(self):
98+
responses.add(
99+
responses.GET,
100+
LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/room/room_id/members/ids',
101+
json={
102+
'memberIds': ['U1', 'U2'],
103+
'next': 'continuationToken2'
104+
},
105+
status=200
106+
)
107+
108+
member_ids_response = self.tested.get_room_member_ids('room_id',
109+
start='continuationToken1')
110+
111+
request = responses.calls[0].request
112+
self.assertEqual(request.method, 'GET')
113+
self.assertEqual(
114+
request.url,
115+
LineBotApi.DEFAULT_API_ENDPOINT +
116+
'/v2/bot/room/room_id/members/ids?start=continuationToken1')
117+
self.assertEqual(member_ids_response.member_ids, ['U1', 'U2'])
118+
self.assertEqual(member_ids_response.next, 'continuationToken2')
119+
120+
121+
if __name__ == '__main__':
122+
unittest.main()

tests/api/test_get_group_member_profile.py renamed to tests/api/test_get_member_profile.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,30 @@ def test_get_group_member_profile(self):
5151
self.assertEqual(profile.user_id, 'Uxxxxxxxxxxxxxx...')
5252
self.assertEqual(profile.picture_url, 'http://obs.line-apps.com/...')
5353

54+
@responses.activate
55+
def test_get_room_member_profile(self):
56+
responses.add(
57+
responses.GET,
58+
LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/room/room_id/member/user_id',
59+
json={
60+
"displayName": "LINE taro",
61+
"userId": "Uxxxxxxxxxxxxxx...",
62+
"pictureUrl": "http://obs.line-apps.com/..."
63+
},
64+
status=200
65+
)
66+
67+
profile = self.tested.get_room_member_profile('room_id', 'user_id')
68+
69+
request = responses.calls[0].request
70+
self.assertEqual(request.method, 'GET')
71+
self.assertEqual(
72+
request.url,
73+
LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/room/room_id/member/user_id')
74+
self.assertEqual(profile.display_name, 'LINE taro')
75+
self.assertEqual(profile.user_id, 'Uxxxxxxxxxxxxxx...')
76+
self.assertEqual(profile.picture_url, 'http://obs.line-apps.com/...')
77+
5478

5579
if __name__ == '__main__':
5680
unittest.main()

tests/api/test_get_profile.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import unittest
1818

1919
import responses
20+
2021
from linebot import (
2122
LineBotApi
2223
)

0 commit comments

Comments
 (0)