parser.py 1.9 KB

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