Skip to content

Commit 982ea3d

Browse files
xsfishxsbe-hase
authored andcommitted
Add FileMessage (#65)
* Add FileMessage * 1. Fix flake8 errors. 2. Add test code for parsing webhook
1 parent de09375 commit 982ea3d

File tree

7 files changed

+85
-4
lines changed

7 files changed

+85
-4
lines changed

README.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,11 @@ Message
660660
- id
661661
- package\_id
662662
- sticker\_id
663+
_ FileMessage
664+
- type
665+
- id
666+
- file\_size
667+
- file\_name
663668

664669
Hints
665670
-----

examples/flask-kitchensink/app.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
PostbackTemplateAction, DatetimePickerTemplateAction,
3737
CarouselTemplate, CarouselColumn, PostbackEvent,
3838
StickerMessage, StickerSendMessage, LocationMessage, LocationSendMessage,
39-
ImageMessage, VideoMessage, AudioMessage,
39+
ImageMessage, VideoMessage, AudioMessage, FileMessage,
4040
UnfollowEvent, FollowEvent, JoinEvent, LeaveEvent, BeaconEvent
4141
)
4242

@@ -231,6 +231,25 @@ def handle_content_message(event):
231231
])
232232

233233

234+
@handler.add(MessageEvent, message=FileMessage)
235+
def handle_file_message(event):
236+
message_content = line_bot_api.get_message_content(event.message.id)
237+
with tempfile.NamedTemporaryFile(dir=static_tmp_path, prefix='file-', delete=False) as tf:
238+
for chunk in message_content.iter_content():
239+
tf.write(chunk)
240+
tempfile_path = tf.name
241+
242+
dist_path = tempfile_path + '-' + event.message.file_name
243+
dist_name = os.path.basename(dist_path)
244+
os.rename(tempfile_path, dist_path)
245+
246+
line_bot_api.reply_message(
247+
event.reply_token, [
248+
TextSendMessage(text='Save file.'),
249+
TextSendMessage(text=request.host_url + os.path.join('static', 'tmp', dist_name))
250+
])
251+
252+
234253
@handler.add(FollowEvent)
235254
def handle_follow(event):
236255
line_bot_api.reply_message(

linebot/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
AudioMessage,
5050
LocationMessage,
5151
StickerMessage,
52+
FileMessage
5253
)
5354
from .responses import ( # noqa
5455
Profile,

linebot/models/events.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
VideoMessage,
2828
AudioMessage,
2929
LocationMessage,
30-
StickerMessage
30+
StickerMessage,
31+
FileMessage
3132
)
3233
from .sources import SourceUser, SourceGroup, SourceRoom
3334

@@ -93,7 +94,8 @@ def __init__(self, timestamp=None, source=None, reply_token=None, message=None,
9394
'video': VideoMessage,
9495
'audio': AudioMessage,
9596
'location': LocationMessage,
96-
'sticker': StickerMessage
97+
'sticker': StickerMessage,
98+
'file': FileMessage
9799
}
98100
)
99101

linebot/models/messages.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,27 @@ def __init__(self, id=None, package_id=None, sticker_id=None, **kwargs):
167167
self.type = 'sticker'
168168
self.package_id = package_id
169169
self.sticker_id = sticker_id
170+
171+
172+
class FileMessage(Message):
173+
"""FileMessage.
174+
175+
https://devdocs.line.me/en/#file-message
176+
177+
Message object which contains the file content sent from the source.
178+
The binary file data can be retrieved with the Content API.
179+
"""
180+
181+
def __init__(self, id=None, file_name=None, file_size=None, **kwargs):
182+
"""__init__ method.
183+
184+
:param str id: Message ID
185+
:param str file_name: File Name
186+
:param int file_size: File Size
187+
:param kwargs:
188+
"""
189+
super(FileMessage, self).__init__(id=id, **kwargs)
190+
191+
self.type = 'file'
192+
self.file_size = file_size
193+
self.file_name = file_name

tests/test_webhook.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
MessageEvent, FollowEvent, UnfollowEvent, JoinEvent,
2626
LeaveEvent, PostbackEvent, BeaconEvent,
2727
TextMessage, ImageMessage, VideoMessage, AudioMessage,
28-
LocationMessage, StickerMessage,
28+
LocationMessage, StickerMessage, FileMessage,
2929
SourceUser, SourceRoom, SourceGroup
3030
)
3131

@@ -291,6 +291,21 @@ def test_parse(self):
291291
self.assertEqual(events[17].postback.data, 'action=buyItem&itemId=123123&color=red')
292292
self.assertEqual(events[17].postback.params['datetime'], '2013-04-01T10:00')
293293

294+
# MessageEvent, SourceUser, FileMessage
295+
self.assertIsInstance(events[18], MessageEvent)
296+
self.assertEqual(events[18].reply_token, 'nHuyWiB7yP5Zw52FIkcQobQuGDXCTA')
297+
self.assertEqual(events[18].type, 'message')
298+
self.assertEqual(events[18].timestamp, 1462629479859)
299+
self.assertIsInstance(events[18].source, SourceUser)
300+
self.assertEqual(events[18].source.type, 'user')
301+
self.assertEqual(events[18].source.user_id, 'U206d25c2ea6bd87c17655609a1c37cb8')
302+
self.assertEqual(events[18].source.sender_id, 'U206d25c2ea6bd87c17655609a1c37cb8')
303+
self.assertIsInstance(events[18].message, FileMessage)
304+
self.assertEqual(events[18].message.id, '325708')
305+
self.assertEqual(events[18].message.type, 'file')
306+
self.assertEqual(events[18].message.file_name, "file.txt")
307+
self.assertEqual(events[18].message.file_size, 2138)
308+
294309

295310
class TestWebhookHandler(unittest.TestCase):
296311
def setUp(self):

tests/text/webhook.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,21 @@
232232
"datetime": "2013-04-01T10:00"
233233
}
234234
}
235+
},
236+
{
237+
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
238+
"type": "message",
239+
"timestamp": 1462629479859,
240+
"source": {
241+
"type": "user",
242+
"userId": "U206d25c2ea6bd87c17655609a1c37cb8"
243+
},
244+
"message": {
245+
"id": "325708",
246+
"type": "file",
247+
"fileName": "file.txt",
248+
"fileSize": 2138
249+
}
235250
}
236251
]
237252
}

0 commit comments

Comments
 (0)