diff --git a/examples/flask-kitchensink/app.py b/examples/flask-kitchensink/app.py index 039b89e4..3ce6dc15 100644 --- a/examples/flask-kitchensink/app.py +++ b/examples/flask-kitchensink/app.py @@ -41,7 +41,7 @@ StickerMessage, StickerSendMessage, LocationMessage, LocationSendMessage, ImageMessage, VideoMessage, AudioMessage, FileMessage, UnfollowEvent, FollowEvent, JoinEvent, LeaveEvent, BeaconEvent, - MemberJoinedEvent, MemberLeftEvent, + MemberJoinedEvent, MemberLeftEvent, UnknownEvent, FlexSendMessage, BubbleContainer, ImageComponent, BoxComponent, TextComponent, IconComponent, ButtonComponent, SeparatorComponent, QuickReply, QuickReplyButton, @@ -680,6 +680,11 @@ def handle_member_left(event): app.logger.info("Got memberLeft event") +@handler.add(UnknownEvent) +def handle_unknown_left(event): + app.logger.info(f"unknown event {event}") + + @app.route('/static/') def send_static_content(path): return send_from_directory('static', path) diff --git a/linebot/models/__init__.py b/linebot/models/__init__.py index 84c019ef..5136d5f5 100644 --- a/linebot/models/__init__.py +++ b/linebot/models/__init__.py @@ -51,6 +51,7 @@ MemberLeftEvent, BeaconEvent, ThingsEvent, + UnknownEvent, Postback, Beacon, Link, diff --git a/linebot/models/events.py b/linebot/models/events.py index d0b1adba..8cf95fd9 100644 --- a/linebot/models/events.py +++ b/linebot/models/events.py @@ -490,6 +490,22 @@ def __init__(self, mode=None, timestamp=None, source=None, reply_token=None, ) +class UnknownEvent(Event): + """Unknown event. + + We welcome your contribution to line-bot-sdk-python! + """ + + def __init__(self, **kwargs): + """__init__ method. + + :param kwargs: + """ + super(UnknownEvent, self).__init__(**kwargs) + + self.type = 'unknown' + + class Postback(Base): """Postback. diff --git a/linebot/webhook.py b/linebot/webhook.py index c950c4d7..3601ae87 100644 --- a/linebot/webhook.py +++ b/linebot/webhook.py @@ -33,7 +33,10 @@ AccountLinkEvent, MemberJoinedEvent, MemberLeftEvent, - ThingsEvent, UnsendEvent, VideoPlayCompleteEvent, + ThingsEvent, + UnsendEvent, + VideoPlayCompleteEvent, + UnknownEvent, ) from .utils import LOGGER, PY3, safe_compare_digest @@ -172,7 +175,8 @@ def parse(self, body, signature, as_payload=False): elif event_type == 'videoPlayComplete': events.append(VideoPlayCompleteEvent.new_from_json_dict(event)) else: - LOGGER.warn('Unknown event type. type=' + event_type) + LOGGER.info('Unknown event type. type=' + event_type) + events.append(UnknownEvent.new_from_json_dict(event)) if as_payload: return WebhookPayload(events=events, destination=body_json.get('destination')) diff --git a/tests/test_webhook.py b/tests/test_webhook.py index 63345559..39ded49f 100644 --- a/tests/test_webhook.py +++ b/tests/test_webhook.py @@ -26,6 +26,7 @@ MessageEvent, FollowEvent, UnfollowEvent, JoinEvent, LeaveEvent, PostbackEvent, BeaconEvent, AccountLinkEvent, MemberJoinedEvent, MemberLeftEvent, ThingsEvent, + UnknownEvent, TextMessage, ImageMessage, VideoMessage, AudioMessage, LocationMessage, StickerMessage, FileMessage, SourceUser, SourceRoom, SourceGroup, @@ -69,7 +70,7 @@ def test_parse(self): events = self.parser.parse(body, 'channel_secret') # events count - self.assertEqual(len(events), 29) + self.assertEqual(len(events), 30) # MessageEvent, SourceUser, TextMessage self.assertIsInstance(events[0], MessageEvent) @@ -567,6 +568,9 @@ def test_parse(self): self.assertEqual(events[28].message.type, 'text') self.assertEqual(events[28].message.text, 'Hello, world') + # UnknownEvent + self.assertIsInstance(events[29], UnknownEvent) + def test_parse_webhook_req_without_destination(self): body = """ { diff --git a/tests/text/webhook.json b/tests/text/webhook.json index 14ae8196..7b90c099 100644 --- a/tests/text/webhook.json +++ b/tests/text/webhook.json @@ -581,6 +581,22 @@ "type": "text", "text": "Hello, world" } + }, + { + "type": "undefined", + "mode": "active", + "timestamp": 1462629479859, + "source": { + "type": "user", + "userId": "U206d25c2ea6bd87c17655609a1c37cb8" + }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": true + }, + "undefinedField": { + "1": 1 + } } ] }