Repository: line/line-bot-sdk-python
Pull request #40 (2017-04-26 14:29:38)

Add DeviceMessage property to BeaconEvent
Support device message from LINE beacon.
spec: https://devdocs.line.me/en/#webhook-event-object

okdtsk: As of 2017/4/26, `flake8-docstrings` has dependency issue related `pydocstyle`.
So test `py35-flake8-src` will be failed but #39 will fix this problem.
okdtsk: I add another test when there is no 'dm' key inside webhook's json.
be-hase: LGTM 👍 
okdtsk: @be-hase Thanks! I rebased this feature branch onto master (for #39) and squashed into one commit.

Patch:
diff --git a/README.rst b/README.rst
index b679228..caf4639 100644
--- a/README.rst
+++ b/README.rst
@@ -523,6 +523,7 @@ Event
     - beacon: Beacon
         - type
         - hwid
+        - device_message
 
 Source
 ^^^^^^
diff --git a/examples/flask-kitchensink/app.py b/examples/flask-kitchensink/app.py
index 8adaf6d..f6f2d7f 100644
--- a/examples/flask-kitchensink/app.py
+++ b/examples/flask-kitchensink/app.py
@@ -250,7 +250,8 @@ def handle_postback(event):
 def handle_beacon(event):
     line_bot_api.reply_message(
         event.reply_token,
-        TextSendMessage(text='Got beacon event. hwid=' + event.beacon.hwid))
+        TextSendMessage(text='Got beacon event. hwid={}, device_message={}'
+                             .format(event.beacon.hwid, event.beacon.device_message)))
 
 
 if __name__ == "__main__":
diff --git a/linebot/models/events.py b/linebot/models/events.py
index f08b0e4..2261a42 100644
--- a/linebot/models/events.py
+++ b/linebot/models/events.py
@@ -282,14 +282,16 @@ class Beacon(Base):
     https://devdocs.line.me/en/#beacon-event
     """
 
-    def __init__(self, type=None, hwid=None, **kwargs):
+    def __init__(self, type=None, hwid=None, dm=None, **kwargs):
         """__init__ method.
 
         :param str type: Type of beacon event
         :param str hwid: Hardware ID of the beacon that was detected
+        :param str dm: Optional. Device message of beacon that was detected in bytearray
         :param kwargs:
         """
         super(Beacon, self).__init__(**kwargs)
 
         self.type = type
         self.hwid = hwid
+        self.device_message = bytearray.fromhex(dm) if dm is not None else None


Test patch:
diff --git a/tests/test_webhook.py b/tests/test_webhook.py
index 5261bcd..ec6cca8 100644
--- a/tests/test_webhook.py
+++ b/tests/test_webhook.py
@@ -204,6 +204,20 @@ class TestWebhookParser(unittest.TestCase):
         self.assertEqual(events[11].source.sender_id, 'U206d25c2ea6bd87c17655609a1c37cb8')
         self.assertEqual(events[11].beacon.hwid, 'd41d8cd98f')
         self.assertEqual(events[11].beacon.type, 'enter')
+        self.assertEqual(events[11].beacon.device_message, None)
+
+        # BeaconEvent, SourceUser (with device message)
+        self.assertIsInstance(events[12], BeaconEvent)
+        self.assertEqual(events[12].reply_token, 'nHuyWiB7yP5Zw52FIkcQobQuGDXCTA')
+        self.assertEqual(events[12].type, 'beacon')
+        self.assertEqual(events[12].timestamp, 1462629479859)
+        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].source.sender_id, 'U206d25c2ea6bd87c17655609a1c37cb8')
+        self.assertEqual(events[12].beacon.hwid, 'd41d8cd98f')
+        self.assertEqual(events[12].beacon.type, 'enter')
+        self.assertEqual(events[12].beacon.device_message, bytearray(b'\x124Vx\x90\xab\xcd\xef'))
 
 
 class TestWebhookHandler(unittest.TestCase):
@@ -271,6 +285,7 @@ class TestWebhookHandler(unittest.TestCase):
         self.assertEqual(self.calls[9], 'default leave')
         self.assertEqual(self.calls[10], '6 postback')
         self.assertEqual(self.calls[11], '7 beacon')
+        self.assertEqual(self.calls[12], '7 beacon')
 
 
 if __name__ == '__main__':
diff --git a/tests/text/webhook.json b/tests/text/webhook.json
index f46af4c..726af6f 100644
--- a/tests/text/webhook.json
+++ b/tests/text/webhook.json
@@ -131,5 +131,18 @@
       "hwid": "d41d8cd98f",
       "type": "enter"
     }
+  }, {
+    "replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
+    "type": "beacon",
+    "timestamp": 1462629479859,
+    "source": {
+      "type": "user",
+      "userId": "U206d25c2ea6bd87c17655609a1c37cb8"
+    },
+    "beacon": {
+      "hwid": "d41d8cd98f",
+      "type": "enter",
+      "dm": "1234567890abcdef"
+    }
   }]
 }
\ No newline at end of file