|
1
|
|
|
# -*- coding: utf-8 -*- |
|
2
|
10 |
|
""" |
|
3
|
|
|
wechatpy.parser |
|
4
|
|
|
~~~~~~~~~~~~~~~~ |
|
5
|
|
|
This module provides functions for parsing WeChat messages |
|
6
|
|
|
|
|
7
|
|
|
:copyright: (c) 2014 by messense. |
|
8
|
|
|
:license: MIT, see LICENSE for more details. |
|
9
|
|
|
""" |
|
10
|
10 |
|
from __future__ import absolute_import, unicode_literals |
|
11
|
10 |
|
import xmltodict |
|
12
|
|
|
|
|
13
|
10 |
|
from wechatpy.messages import MESSAGE_TYPES, UnknownMessage |
|
14
|
10 |
|
from wechatpy.events import EVENT_TYPES |
|
15
|
10 |
|
from wechatpy.utils import to_text |
|
16
|
|
|
|
|
17
|
|
|
|
|
18
|
10 |
|
def parse_message(xml): |
|
19
|
|
|
""" |
|
20
|
|
|
解析微信服务器推送的 XML 消息 |
|
21
|
|
|
|
|
22
|
|
|
:param xml: XML 消息 |
|
23
|
|
|
:return: 解析成功返回对应的消息或事件,否则返回 ``UnknownMessage`` |
|
24
|
|
|
""" |
|
25
|
10 |
|
if not xml: |
|
26
|
|
|
return |
|
27
|
10 |
|
message = xmltodict.parse(to_text(xml))['xml'] |
|
28
|
10 |
|
message_type = message['MsgType'].lower() |
|
29
|
10 |
|
event_type = None |
|
30
|
10 |
|
if message_type == 'event' or message_type.startswith('device_'): |
|
31
|
10 |
|
if 'Event' in message: |
|
32
|
10 |
|
event_type = message['Event'].lower() |
|
33
|
|
|
# special event type for device_event |
|
34
|
10 |
|
if event_type is None and message_type.startswith('device_'): |
|
35
|
10 |
|
event_type = message_type |
|
36
|
10 |
|
elif message_type.startswith('device_'): |
|
37
|
10 |
|
event_type = 'device_{event}'.format(event=event_type) |
|
38
|
|
|
|
|
39
|
10 |
|
if event_type == 'subscribe' and message.get('EventKey'): |
|
40
|
10 |
|
event_key = message['EventKey'] |
|
41
|
10 |
|
if event_key.startswith(('scanbarcode|', 'scanimage|')): |
|
42
|
10 |
|
event_type = 'subscribe_scan_product' |
|
43
|
10 |
|
message['Event'] = event_type |
|
44
|
10 |
|
elif event_key.startswith('qrscene_'): |
|
45
|
|
|
# Scan to subscribe with scene id event |
|
46
|
10 |
|
event_type = 'subscribe_scan' |
|
47
|
10 |
|
message['Event'] = event_type |
|
48
|
10 |
|
message['EventKey'] = event_key[len('qrscene_'):] |
|
49
|
10 |
|
message_class = EVENT_TYPES.get(event_type, UnknownMessage) |
|
50
|
|
|
else: |
|
51
|
10 |
|
message_class = MESSAGE_TYPES.get(message_type, UnknownMessage) |
|
52
|
|
|
return message_class(message) |
|
53
|
|
|
|