Skip to content

Commit fbf8688

Browse files
tokuhirombe-hase
authored andcommitted
Support memberJoined/memberLeft event. Close #142 (#148)
* Support memberJoined/memberLeft event. Close #142 * Fix argument's type
1 parent 1b38bfc commit fbf8688

File tree

6 files changed

+196
-0
lines changed

6 files changed

+196
-0
lines changed

examples/flask-kitchensink/app.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
StickerMessage, StickerSendMessage, LocationMessage, LocationSendMessage,
4141
ImageMessage, VideoMessage, AudioMessage, FileMessage,
4242
UnfollowEvent, FollowEvent, JoinEvent, LeaveEvent, BeaconEvent,
43+
MemberJoinedEvent, MemberLeftEvent,
4344
FlexSendMessage, BubbleContainer, ImageComponent, BoxComponent,
4445
TextComponent, SpacerComponent, IconComponent, ButtonComponent,
4546
SeparatorComponent, QuickReply, QuickReplyButton,
@@ -436,6 +437,20 @@ def handle_beacon(event):
436437
event.beacon.hwid, event.beacon.dm)))
437438

438439

440+
@handler.add(MemberJoinedEvent)
441+
def handle_member_joined(event):
442+
line_bot_api.reply_message(
443+
event.reply_token,
444+
TextSendMessage(
445+
text='Got memberJoined event. event={}'.format(
446+
event)))
447+
448+
449+
@handler.add(MemberLeftEvent)
450+
def handle_member_left(event):
451+
app.logger.info("Got memberLeft event")
452+
453+
439454
@app.route('/static/<path:path>')
440455
def send_static_content(path):
441456
return send_from_directory('static', path)

linebot/models/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
LeaveEvent,
4646
PostbackEvent,
4747
AccountLinkEvent,
48+
MemberJoinedEvent,
49+
MemberLeftEvent,
4850
BeaconEvent,
4951
Postback,
5052
Beacon,

linebot/models/events.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,68 @@ def __init__(self, timestamp=None, source=None, reply_token=None,
261261
)
262262

263263

264+
class MemberJoinedEvent(Event):
265+
"""Webhook MemberJoinedEvent.
266+
267+
https://developers.line.biz/en/reference/messaging-api/#member-joined-event
268+
269+
Event object for when a user joins a group or room that the bot is in.
270+
271+
"""
272+
273+
def __init__(self, timestamp=None, source=None, reply_token=None,
274+
joined=None, **kwargs):
275+
"""__init__ method.
276+
277+
:param long timestamp: Time of the event in milliseconds
278+
:param source: Source object
279+
:type source: T <= :py:class:`linebot.models.sources.Source`
280+
:param str reply_token: Reply token
281+
:param joined: Joined object
282+
:type joined: :py:class:`linebot.models.events.Joined`
283+
:param kwargs:
284+
"""
285+
super(MemberJoinedEvent, self).__init__(
286+
timestamp=timestamp, source=source, **kwargs
287+
)
288+
289+
self.type = 'memberJoined'
290+
self.reply_token = reply_token
291+
self.joined = self.get_or_new_from_json_dict(
292+
joined, Joined
293+
)
294+
295+
296+
class MemberLeftEvent(Event):
297+
"""Webhook MemberLeftEvent.
298+
299+
https://developers.line.biz/en/reference/messaging-api/#member-left-event
300+
301+
Event object for when a user leaves a group or room that the bot is in.
302+
303+
"""
304+
305+
def __init__(self, timestamp=None, source=None,
306+
left=None, **kwargs):
307+
"""__init__ method.
308+
309+
:param long timestamp: Time of the event in milliseconds
310+
:param source: Source object
311+
:type source: T <= :py:class:`linebot.models.sources.Source`
312+
:param left: Left object
313+
:type left: :py:class:`linebot.models.events.Left`
314+
:param kwargs:
315+
"""
316+
super(MemberLeftEvent, self).__init__(
317+
timestamp=timestamp, source=source, **kwargs
318+
)
319+
320+
self.type = 'memberLeft'
321+
self.left = self.get_or_new_from_json_dict(
322+
left, Left
323+
)
324+
325+
264326
class AccountLinkEvent(Event):
265327
"""Webhook AccountLinkEvent.
266328
@@ -345,6 +407,50 @@ def device_message(self):
345407
return bytearray.fromhex(self.dm) if self.dm is not None else None
346408

347409

410+
class Joined(Base):
411+
"""Joined.
412+
413+
https://developers.line.biz/en/reference/messaging-api/#member-joined-event
414+
"""
415+
416+
def __init__(self, members=None, **kwargs):
417+
"""__init__ method.
418+
419+
:param dict members: Member of users who joined
420+
:param kwargs:
421+
"""
422+
super(Joined, self).__init__(**kwargs)
423+
424+
self._members = members
425+
426+
@property
427+
def members(self):
428+
"""Get members as list of SourceUser."""
429+
return [SourceUser(user_id=x['userId']) for x in self._members]
430+
431+
432+
class Left(Base):
433+
"""Left.
434+
435+
https://developers.line.biz/en/reference/messaging-api/#member-left-event
436+
"""
437+
438+
def __init__(self, members=None, **kwargs):
439+
"""__init__ method.
440+
441+
:param dict members: Member of users who joined
442+
:param kwargs:
443+
"""
444+
super(Left, self).__init__(**kwargs)
445+
446+
self._members = members
447+
448+
@property
449+
def members(self):
450+
"""Get members as list of SourceUser."""
451+
return [SourceUser(user_id=x['userId']) for x in self._members]
452+
453+
348454
class Link(Base):
349455
"""Link.
350456

linebot/webhook.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
PostbackEvent,
3333
BeaconEvent,
3434
AccountLinkEvent,
35+
MemberJoinedEvent,
36+
MemberLeftEvent,
3537
)
3638
from .utils import LOGGER, PY3, safe_compare_digest
3739

@@ -144,6 +146,10 @@ def parse(self, body, signature):
144146
events.append(BeaconEvent.new_from_json_dict(event))
145147
elif event_type == 'accountLink':
146148
events.append(AccountLinkEvent.new_from_json_dict(event))
149+
elif event_type == 'memberJoined':
150+
events.append(MemberJoinedEvent.new_from_json_dict(event))
151+
elif event_type == 'memberLeft':
152+
events.append(MemberLeftEvent.new_from_json_dict(event))
147153
else:
148154
LOGGER.warn('Unknown event type. type=' + event_type)
149155

tests/test_webhook.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from linebot.models import (
2525
MessageEvent, FollowEvent, UnfollowEvent, JoinEvent,
2626
LeaveEvent, PostbackEvent, BeaconEvent, AccountLinkEvent,
27+
MemberJoinedEvent, MemberLeftEvent,
2728
TextMessage, ImageMessage, VideoMessage, AudioMessage,
2829
LocationMessage, StickerMessage, FileMessage,
2930
SourceUser, SourceRoom, SourceGroup
@@ -318,6 +319,31 @@ def test_parse(self):
318319
self.assertEqual(events[19].message.file_name, "file.txt")
319320
self.assertEqual(events[19].message.file_size, 2138)
320321

322+
# MemberJoinedEvent
323+
self.assertIsInstance(events[20], MemberJoinedEvent)
324+
self.assertEqual(events[20].reply_token, '0f3779fba3b349968c5d07db31eabf65')
325+
self.assertEqual(events[20].type, 'memberJoined')
326+
self.assertEqual(events[20].timestamp, 1462629479859)
327+
self.assertIsInstance(events[20].source, SourceGroup)
328+
self.assertEqual(events[20].source.type, 'group')
329+
self.assertEqual(events[20].source.group_id, 'C4af4980629...')
330+
self.assertEqual(len(events[20].joined.members), 2)
331+
self.assertIsInstance(events[20].joined.members[0], SourceUser)
332+
self.assertEqual(events[20].joined.members[0].user_id, 'U4af4980629...')
333+
self.assertEqual(events[20].joined.members[1].user_id, 'U91eeaf62d9...')
334+
335+
# MemberLeftEvent
336+
self.assertIsInstance(events[21], MemberLeftEvent)
337+
self.assertEqual(events[21].type, 'memberLeft')
338+
self.assertEqual(events[21].timestamp, 1462629479960)
339+
self.assertIsInstance(events[21].source, SourceGroup)
340+
self.assertEqual(events[21].source.type, 'group')
341+
self.assertEqual(events[21].source.group_id, 'C4af4980629...')
342+
self.assertEqual(len(events[21].left.members), 2)
343+
self.assertIsInstance(events[21].left.members[0], SourceUser)
344+
self.assertEqual(events[21].left.members[0].user_id, 'U4af4980629...')
345+
self.assertEqual(events[21].left.members[1].user_id, 'U91eeaf62d9...')
346+
321347

322348
class TestWebhookHandler(unittest.TestCase):
323349
def setUp(self):

tests/text/webhook.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,47 @@
260260
"fileName": "file.txt",
261261
"fileSize": 2138
262262
}
263+
},
264+
{
265+
"replyToken": "0f3779fba3b349968c5d07db31eabf65",
266+
"type": "memberJoined",
267+
"timestamp": 1462629479859,
268+
"source": {
269+
"type": "group",
270+
"groupId": "C4af4980629..."
271+
},
272+
"joined": {
273+
"members": [
274+
{
275+
"type": "user",
276+
"userId": "U4af4980629..."
277+
},
278+
{
279+
"type": "user",
280+
"userId": "U91eeaf62d9..."
281+
}
282+
]
283+
}
284+
},
285+
{
286+
"type": "memberLeft",
287+
"timestamp": 1462629479960,
288+
"source": {
289+
"type": "group",
290+
"groupId": "C4af4980629..."
291+
},
292+
"left": {
293+
"members": [
294+
{
295+
"type": "user",
296+
"userId": "U4af4980629..."
297+
},
298+
{
299+
"type": "user",
300+
"userId": "U91eeaf62d9..."
301+
}
302+
]
303+
}
263304
}
264305
]
265306
}

0 commit comments

Comments
 (0)