diff --git a/linebot/models/delivery_context.py b/linebot/models/delivery_context.py new file mode 100644 index 000000000..b14085789 --- /dev/null +++ b/linebot/models/delivery_context.py @@ -0,0 +1,34 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""linebot.models.delivery_context module.""" + + +from abc import ABCMeta + +from future.utils import with_metaclass + +from .base import Base + + +class DeliveryContext(with_metaclass(ABCMeta, Base)): + """Abstract Base Class of DeliveryContext.""" + + def __init__(self, is_redelivery=None, **kwargs): + """__init__ method. + + :param bool is_redelivery: Whether the webhook event is a redelivered one or not + :param kwargs: + """ + super(DeliveryContext, self).__init__(**kwargs) + + self.is_redelivery = is_redelivery diff --git a/linebot/models/events.py b/linebot/models/events.py index a33c8a147..d0b1adba2 100644 --- a/linebot/models/events.py +++ b/linebot/models/events.py @@ -20,6 +20,7 @@ from future.utils import with_metaclass from linebot.models.base import Base +from linebot.models.delivery_context import DeliveryContext from linebot.models.messages import ( TextMessage, ImageMessage, @@ -46,7 +47,15 @@ class Event(with_metaclass(ABCMeta, Base)): https://developers.line.biz/en/reference/messaging-api/#webhook-event-objects """ - def __init__(self, mode=None, timestamp=None, source=None, **kwargs): + def __init__( + self, + mode=None, + timestamp=None, + source=None, + webhook_event_id=None, + delivery_context=None, + **kwargs + ): """__init__ method. :param str mode: Channel state @@ -67,6 +76,10 @@ def __init__(self, mode=None, timestamp=None, source=None, **kwargs): 'room': SourceRoom, } ) + self.webhook_event_id = webhook_event_id + self.delivery_context = self.get_or_new_from_json_dict( + delivery_context, DeliveryContext + ) class MessageEvent(Event): diff --git a/tests/test_webhook.py b/tests/test_webhook.py index ad39638d8..633455591 100644 --- a/tests/test_webhook.py +++ b/tests/test_webhook.py @@ -30,6 +30,7 @@ LocationMessage, StickerMessage, FileMessage, SourceUser, SourceRoom, SourceGroup, DeviceLink, DeviceUnlink, ScenarioResult, ActionResult) +from linebot.models.delivery_context import DeliveryContext from linebot.models.events import UnsendEvent, VideoPlayCompleteEvent from linebot.models.unsend import Unsend from linebot.models.video_play_complete import VideoPlayComplete @@ -67,6 +68,9 @@ def test_parse(self): events = self.parser.parse(body, 'channel_secret') + # events count + self.assertEqual(len(events), 29) + # MessageEvent, SourceUser, TextMessage self.assertIsInstance(events[0], MessageEvent) self.assertEqual(events[0].reply_token, 'nHuyWiB7yP5Zw52FIkcQobQuGDXCTA') @@ -76,6 +80,9 @@ def test_parse(self): self.assertIsInstance(events[0].source, SourceUser) self.assertEqual(events[0].source.type, 'user') self.assertEqual(events[0].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[0].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[0].delivery_context, DeliveryContext) + self.assertFalse(events[0].delivery_context.is_redelivery) self.assertIsInstance(events[0].message, TextMessage) self.assertEqual(events[0].message.id, '325708') self.assertEqual(events[0].message.type, 'text') @@ -91,6 +98,9 @@ def test_parse(self): self.assertEqual(events[1].source.type, 'room') self.assertEqual(events[1].source.room_id, 'Ra8dbf4673c4c812cd491258042226c99') self.assertEqual(events[1].source.user_id, None) + self.assertEqual(events[1].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[1].delivery_context, DeliveryContext) + self.assertFalse(events[1].delivery_context.is_redelivery) self.assertIsInstance(events[1].message, ImageMessage) self.assertEqual(events[1].message.id, '325708') self.assertEqual(events[1].message.type, 'image') @@ -109,6 +119,9 @@ def test_parse(self): self.assertIsInstance(events[2].source, SourceUser) self.assertEqual(events[2].source.type, 'user') self.assertEqual(events[2].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[2].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[2].delivery_context, DeliveryContext) + self.assertFalse(events[2].delivery_context.is_redelivery) self.assertIsInstance(events[2].message, VideoMessage) self.assertEqual(events[2].message.id, '325708') self.assertEqual(events[2].message.type, 'video') @@ -128,6 +141,9 @@ def test_parse(self): self.assertIsInstance(events[3].source, SourceUser) self.assertEqual(events[3].source.type, 'user') self.assertEqual(events[3].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[3].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[3].delivery_context, DeliveryContext) + self.assertFalse(events[3].delivery_context.is_redelivery) self.assertIsInstance(events[3].message, AudioMessage) self.assertEqual(events[3].message.id, '325708') self.assertEqual(events[3].message.type, 'audio') @@ -145,6 +161,9 @@ def test_parse(self): self.assertIsInstance(events[4].source, SourceUser) self.assertEqual(events[4].source.type, 'user') self.assertEqual(events[4].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[4].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[4].delivery_context, DeliveryContext) + self.assertFalse(events[4].delivery_context.is_redelivery) self.assertIsInstance(events[4].message, LocationMessage) self.assertEqual(events[4].message.id, '325708') self.assertEqual(events[4].message.type, 'location') @@ -162,6 +181,9 @@ def test_parse(self): self.assertIsInstance(events[5].source, SourceUser) self.assertEqual(events[5].source.type, 'user') self.assertEqual(events[5].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[5].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[5].delivery_context, DeliveryContext) + self.assertFalse(events[5].delivery_context.is_redelivery) self.assertIsInstance(events[5].message, StickerMessage) self.assertEqual(events[5].message.id, '325708') self.assertEqual(events[5].message.type, 'sticker') @@ -181,6 +203,9 @@ def test_parse(self): self.assertIsInstance(events[6].source, SourceUser) self.assertEqual(events[6].source.type, 'user') self.assertEqual(events[6].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[6].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[6].delivery_context, DeliveryContext) + self.assertFalse(events[6].delivery_context.is_redelivery) # UnfollowEvent, SourceUser self.assertIsInstance(events[7], UnfollowEvent) @@ -190,6 +215,9 @@ def test_parse(self): self.assertIsInstance(events[7].source, SourceUser) self.assertEqual(events[7].source.type, 'user') self.assertEqual(events[7].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[7].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[7].delivery_context, DeliveryContext) + self.assertFalse(events[7].delivery_context.is_redelivery) # JoinEvent, SourceGroup self.assertIsInstance(events[8], JoinEvent) @@ -201,6 +229,9 @@ def test_parse(self): self.assertEqual(events[8].source.type, 'group') self.assertEqual(events[8].source.group_id, 'Ca56f94637cc4347f90a25382909b24b9') self.assertEqual(events[8].source.user_id, None) + self.assertEqual(events[8].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[8].delivery_context, DeliveryContext) + self.assertFalse(events[8].delivery_context.is_redelivery) # LeaveEvent, SourceGroup self.assertIsInstance(events[9], LeaveEvent) @@ -211,6 +242,9 @@ def test_parse(self): self.assertEqual(events[9].source.type, 'group') self.assertEqual(events[9].source.group_id, 'Ca56f94637cc4347f90a25382909b24b9') self.assertEqual(events[9].source.user_id, None) + self.assertEqual(events[9].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[9].delivery_context, DeliveryContext) + self.assertFalse(events[9].delivery_context.is_redelivery) # PostbackEvent, SourceUser self.assertIsInstance(events[10], PostbackEvent) @@ -221,6 +255,9 @@ def test_parse(self): self.assertIsInstance(events[10].source, SourceUser) self.assertEqual(events[10].source.type, 'user') self.assertEqual(events[10].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[10].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[10].delivery_context, DeliveryContext) + self.assertFalse(events[10].delivery_context.is_redelivery) self.assertEqual(events[10].postback.data, 'action=buyItem&itemId=123123&color=red') self.assertEqual(events[10].postback.params, None) @@ -233,6 +270,9 @@ def test_parse(self): self.assertIsInstance(events[11].source, SourceUser) self.assertEqual(events[11].source.type, 'user') self.assertEqual(events[11].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[11].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[11].delivery_context, DeliveryContext) + self.assertFalse(events[11].delivery_context.is_redelivery) self.assertEqual(events[11].beacon.hwid, 'd41d8cd98f') self.assertEqual(events[11].beacon.type, 'enter') self.assertEqual(events[11].beacon.dm, None) @@ -247,6 +287,9 @@ def test_parse(self): self.assertIsInstance(events[12].source, SourceUser) self.assertEqual(events[12].source.type, 'user') self.assertEqual(events[12].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[12].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[12].delivery_context, DeliveryContext) + self.assertFalse(events[12].delivery_context.is_redelivery) self.assertEqual(events[12].beacon.hwid, 'd41d8cd98f') self.assertEqual(events[12].beacon.type, 'enter') self.assertEqual(events[12].beacon.dm, '1234567890abcdef') @@ -261,6 +304,9 @@ def test_parse(self): self.assertIsInstance(events[13].source, SourceUser) self.assertEqual(events[13].source.type, 'user') self.assertEqual(events[13].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[13].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[13].delivery_context, DeliveryContext) + self.assertFalse(events[13].delivery_context.is_redelivery) self.assertEqual(events[13].link.result, 'ok') self.assertEqual(events[13].link.nonce, 'Vb771wDYtXuammLszK6h9A') @@ -274,6 +320,9 @@ def test_parse(self): self.assertEqual(events[14].source.type, 'group') self.assertEqual(events[14].source.group_id, 'Ca56f94637cc4347f90a25382909b24b9') self.assertEqual(events[14].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[14].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[14].delivery_context, DeliveryContext) + self.assertFalse(events[14].delivery_context.is_redelivery) self.assertIsInstance(events[14].message, TextMessage) self.assertEqual(events[14].message.id, '325708') self.assertEqual(events[14].message.type, 'text') @@ -289,6 +338,9 @@ def test_parse(self): self.assertEqual(events[15].source.type, 'room') self.assertEqual(events[15].source.room_id, 'Ra8dbf4673c4c812cd491258042226c99') self.assertEqual(events[15].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[15].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[15].delivery_context, DeliveryContext) + self.assertFalse(events[15].delivery_context.is_redelivery) self.assertIsInstance(events[15].message, TextMessage) self.assertEqual(events[15].message.id, '325708') self.assertEqual(events[15].message.type, 'text') @@ -303,6 +355,9 @@ def test_parse(self): self.assertIsInstance(events[16].source, SourceUser) self.assertEqual(events[16].source.type, 'user') self.assertEqual(events[16].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[16].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[16].delivery_context, DeliveryContext) + self.assertFalse(events[16].delivery_context.is_redelivery) self.assertEqual(events[16].postback.data, 'action=buyItem&itemId=123123&color=red') self.assertEqual(events[16].postback.params['date'], '2013-04-01') @@ -315,6 +370,9 @@ def test_parse(self): self.assertIsInstance(events[17].source, SourceUser) self.assertEqual(events[17].source.type, 'user') self.assertEqual(events[17].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[17].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[17].delivery_context, DeliveryContext) + self.assertFalse(events[17].delivery_context.is_redelivery) self.assertEqual(events[17].postback.data, 'action=buyItem&itemId=123123&color=red') self.assertEqual(events[17].postback.params['time'], '10:00') @@ -327,6 +385,9 @@ def test_parse(self): self.assertIsInstance(events[18].source, SourceUser) self.assertEqual(events[18].source.type, 'user') self.assertEqual(events[18].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[18].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[18].delivery_context, DeliveryContext) + self.assertFalse(events[18].delivery_context.is_redelivery) self.assertEqual(events[18].postback.data, 'action=buyItem&itemId=123123&color=red') self.assertEqual(events[18].postback.params['datetime'], '2013-04-01T10:00') @@ -339,6 +400,9 @@ def test_parse(self): self.assertIsInstance(events[19].source, SourceUser) self.assertEqual(events[19].source.type, 'user') self.assertEqual(events[19].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[19].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[19].delivery_context, DeliveryContext) + self.assertFalse(events[19].delivery_context.is_redelivery) self.assertIsInstance(events[19].things, DeviceLink) self.assertEqual(events[19].things.type, 'link') self.assertEqual(events[19].things.device_id, 't2c449c9d1') @@ -352,6 +416,9 @@ def test_parse(self): self.assertIsInstance(events[20].source, SourceGroup) self.assertEqual(events[20].source.type, 'group') self.assertEqual(events[20].source.group_id, 'C4af4980629...') + self.assertEqual(events[20].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[20].delivery_context, DeliveryContext) + self.assertFalse(events[20].delivery_context.is_redelivery) self.assertEqual(len(events[20].joined.members), 2) self.assertIsInstance(events[20].joined.members[0], SourceUser) self.assertEqual(events[20].joined.members[0].user_id, 'U4af4980629...') @@ -365,6 +432,9 @@ def test_parse(self): self.assertIsInstance(events[21].source, SourceGroup) self.assertEqual(events[21].source.type, 'group') self.assertEqual(events[21].source.group_id, 'C4af4980629...') + self.assertEqual(events[21].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[21].delivery_context, DeliveryContext) + self.assertFalse(events[21].delivery_context.is_redelivery) self.assertEqual(len(events[21].left.members), 2) self.assertIsInstance(events[21].left.members[0], SourceUser) self.assertEqual(events[21].left.members[0].user_id, 'U4af4980629...') @@ -379,6 +449,9 @@ def test_parse(self): self.assertIsInstance(events[22].source, SourceUser) self.assertEqual(events[22].source.type, 'user') self.assertEqual(events[22].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[22].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[22].delivery_context, DeliveryContext) + self.assertFalse(events[22].delivery_context.is_redelivery) self.assertIsInstance(events[22].things, DeviceUnlink) self.assertEqual(events[22].things.type, 'unlink') self.assertEqual(events[22].things.device_id, 't2c449c9d1') @@ -392,6 +465,9 @@ def test_parse(self): self.assertIsInstance(events[23].source, SourceUser) self.assertEqual(events[23].source.type, 'user') self.assertEqual(events[23].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[23].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[23].delivery_context, DeliveryContext) + self.assertFalse(events[23].delivery_context.is_redelivery) self.assertIsInstance(events[23].message, FileMessage) self.assertEqual(events[23].message.id, '325708') self.assertEqual(events[23].message.type, 'file') @@ -407,6 +483,9 @@ def test_parse(self): self.assertIsInstance(events[24].source, SourceUser) self.assertEqual(events[24].source.type, 'user') self.assertEqual(events[24].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[24].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[24].delivery_context, DeliveryContext) + self.assertFalse(events[24].delivery_context.is_redelivery) self.assertIsInstance(events[24].things, ScenarioResult) self.assertEqual(events[24].things.type, 'scenarioResult') self.assertEqual(events[24].things.device_id, 't2c449c9d1') @@ -430,6 +509,9 @@ def test_parse(self): self.assertIsInstance(events[25].source, SourceGroup) self.assertEqual(events[25].source.type, 'group') self.assertEqual(events[25].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[25].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[25].delivery_context, DeliveryContext) + self.assertFalse(events[25].delivery_context.is_redelivery) self.assertIsInstance(events[25].unsend, Unsend) self.assertEqual(events[25].unsend.message_id, '325708') @@ -442,6 +524,9 @@ def test_parse(self): self.assertIsInstance(events[26].source, SourceUser) self.assertEqual(events[26].source.type, 'user') self.assertEqual(events[26].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[26].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[26].delivery_context, DeliveryContext) + self.assertFalse(events[26].delivery_context.is_redelivery) self.assertIsInstance(events[26].video_play_complete, VideoPlayComplete) self.assertEqual(events[26].video_play_complete.tracking_id, 'track_id') @@ -454,6 +539,9 @@ def test_parse(self): self.assertIsInstance(events[27].source, SourceUser) self.assertEqual(events[27].source.type, 'user') self.assertEqual(events[27].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[27].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[27].delivery_context, DeliveryContext) + self.assertFalse(events[27].delivery_context.is_redelivery) self.assertIsInstance(events[27].message, ImageMessage) self.assertEqual(events[27].message.id, '354718705033693861') self.assertEqual(events[27].message.type, 'image') @@ -462,6 +550,23 @@ def test_parse(self): self.assertEqual(events[27].message.image_set.index, 2) self.assertEqual(events[27].message.image_set.total, 2) + # MessageEvent, SourceUser, TextMessage (Redeliveried) + self.assertIsInstance(events[28], MessageEvent) + self.assertEqual(events[28].reply_token, 'nHuyWiB7yP5Zw52FIkcQobQuGDXCTA') + self.assertEqual(events[28].type, 'message') + self.assertEqual(events[28].mode, 'active') + self.assertEqual(events[28].timestamp, 1462629479859) + self.assertIsInstance(events[28].source, SourceUser) + self.assertEqual(events[28].source.type, 'user') + self.assertEqual(events[28].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8') + self.assertEqual(events[28].webhook_event_id, 'testwebhookeventid') + self.assertIsInstance(events[28].delivery_context, DeliveryContext) + self.assertTrue(events[28].delivery_context.is_redelivery) + self.assertIsInstance(events[28].message, TextMessage) + self.assertEqual(events[28].message.id, '325708') + self.assertEqual(events[28].message.type, 'text') + self.assertEqual(events[28].message.text, 'Hello, world') + def test_parse_webhook_req_without_destination(self): body = """ { diff --git a/tests/text/webhook.json b/tests/text/webhook.json index fc4096402..14ae81960 100644 --- a/tests/text/webhook.json +++ b/tests/text/webhook.json @@ -10,6 +10,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "message": { "id": "325708", "type": "text", @@ -25,6 +29,10 @@ "type": "room", "roomId": "Ra8dbf4673c4c812cd491258042226c99" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "message": { "id": "325708", "type": "image", @@ -44,6 +52,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "message": { "id": "325708", "type": "video", @@ -64,6 +76,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "message": { "id": "325708", "type": "audio", @@ -83,6 +99,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "message": { "id": "325708", "type": "location", @@ -101,6 +121,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "message": { "id": "325708", "type": "sticker", @@ -119,6 +143,10 @@ "source": { "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" + }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false } }, { @@ -128,6 +156,10 @@ "source": { "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" + }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false } }, { @@ -138,6 +170,10 @@ "source": { "type": "group", "groupId": "Ca56f94637cc4347f90a25382909b24b9" + }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false } }, { @@ -147,6 +183,10 @@ "source": { "type": "group", "groupId": "Ca56f94637cc4347f90a25382909b24b9" + }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false } }, { @@ -160,6 +200,10 @@ }, "postback": { "data": "action=buyItem&itemId=123123&color=red" + }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false } }, { @@ -171,6 +215,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "beacon": { "hwid": "d41d8cd98f", "type": "enter" @@ -185,6 +233,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "beacon": { "hwid": "d41d8cd98f", "type": "enter", @@ -200,6 +252,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "link": { "result": "ok", "nonce": "Vb771wDYtXuammLszK6h9A" @@ -215,6 +271,10 @@ "groupId": "Ca56f94637cc4347f90a25382909b24b9", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "message": { "id": "325708", "type": "text", @@ -231,6 +291,10 @@ "roomId": "Ra8dbf4673c4c812cd491258042226c99", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "message": { "id": "325708", "type": "text", @@ -246,6 +310,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "postback": { "data": "action=buyItem&itemId=123123&color=red", "params": { @@ -262,6 +330,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "postback": { "data": "action=buyItem&itemId=123123&color=red", "params": { @@ -278,6 +350,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "postback": { "data": "action=buyItem&itemId=123123&color=red", "params": { @@ -294,6 +370,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "things": { "deviceId": "t2c449c9d1", "type": "link" @@ -308,6 +388,10 @@ "type": "group", "groupId": "C4af4980629..." }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "joined": { "members": [ { @@ -329,6 +413,10 @@ "type": "group", "groupId": "C4af4980629..." }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "left": { "members": [ { @@ -351,6 +439,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "things": { "deviceId": "t2c449c9d1", "type": "unlink" @@ -365,6 +457,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "message": { "id": "325708", "type": "file", @@ -380,6 +476,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "timestamp": 1547817848122, "things": { "type": "scenarioResult", @@ -412,6 +512,10 @@ "groupId": "Ca56f94637cc4347f90a25382909b24b9", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "unsend": { "messageId": "325708" } @@ -425,6 +529,10 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "videoPlayComplete": { "trackingId": "track_id" } @@ -448,8 +556,31 @@ "type": "user", "userId": "U206d25c2ea6bd87c17655609a1c37cb8" }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": false + }, "replyToken": "fbf94e269485410da6b7e3a5e33283e8", "mode": "active" + }, + { + "replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA", + "type": "message", + "mode": "active", + "timestamp": 1462629479859, + "source": { + "type": "user", + "userId": "U206d25c2ea6bd87c17655609a1c37cb8" + }, + "webhookEventId": "testwebhookeventid", + "deliveryContext": { + "isRedelivery": true + }, + "message": { + "id": "325708", + "type": "text", + "text": "Hello, world" + } } ] }