123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701 |
- # -*- coding: utf-8 -*-
- """
- wechatpy.events
- ~~~~~~~~~~~~~~~~
- This module contains all the events WeChat callback uses.
- :copyright: (c) 2014 by messense.
- :license: MIT, see LICENSE for more details.
- """
- from __future__ import absolute_import, unicode_literals
- from library.wechatpy.fields import (
- StringField,
- FloatField,
- IntegerField,
- BaseField,
- Base64DecodeField,
- DateTimeField
- )
- from library.wechatpy.messages import BaseMessage
- EVENT_TYPES = {}
- def register_event(event_type):
- """
- Register the event class so that they can be accessed from EVENT_TYPES
- :param event_type: Event type
- """
- def register(cls):
- EVENT_TYPES[event_type] = cls
- return cls
- return register
- class BaseEvent(BaseMessage):
- """Base class for all events"""
- type = 'event'
- event = ''
- @register_event('subscribe')
- class SubscribeEvent(BaseEvent):
- """
- 用户关注事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1421140454
- """
- event = 'subscribe'
- key = StringField('EventKey', '')
- @register_event('unsubscribe')
- class UnsubscribeEvent(BaseEvent):
- """
- 用户取消关注事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1421140454
- """
- event = 'unsubscribe'
- @register_event('subscribe_scan')
- class SubscribeScanEvent(BaseEvent):
- """
- 用户扫描二维码关注事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1421140454
- """
- event = 'subscribe_scan'
- scene_id = StringField('EventKey')
- ticket = StringField('Ticket')
- @register_event('scan')
- class ScanEvent(BaseEvent):
- """
- 用户扫描二维码事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1421140454
- """
- event = 'scan'
- scene_id = StringField('EventKey')
- ticket = StringField('Ticket')
- @register_event('location')
- class LocationEvent(BaseEvent):
- """
- 上报地理位置事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1421140454
- """
- event = 'location'
- latitude = FloatField('Latitude', 0.0)
- longitude = FloatField('Longitude', 0.0)
- precision = FloatField('Precision', 0.0)
- @register_event('click')
- class ClickEvent(BaseEvent):
- """
- 点击菜单拉取消息事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1421140454
- """
- event = 'click'
- key = StringField('EventKey')
- @register_event('view')
- class ViewEvent(BaseEvent):
- """
- 点击菜单跳转链接事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1421140454
- """
- event = 'view'
- url = StringField('EventKey')
- @register_event('masssendjobfinish')
- class MassSendJobFinishEvent(BaseEvent):
- """
- 群发消息任务完成事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1481187827_i0l21
- """
- id = IntegerField('MsgID', 0)
- event = 'masssendjobfinish'
- status = StringField('Status')
- total_count = IntegerField('TotalCount', 0)
- filter_count = IntegerField('FilterCount', 0)
- sent_count = IntegerField('SentCount', 0)
- error_count = IntegerField('ErrorCount', 0)
- @register_event('templatesendjobfinish')
- class TemplateSendJobFinishEvent(BaseEvent):
- """
- 模板消息任务完成事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1433751277
- """
- id = IntegerField('MsgID')
- event = 'templatesendjobfinish'
- status = StringField('Status')
- class BaseScanCodeEvent(BaseEvent):
- key = StringField('EventKey')
- scan_code_info = BaseField('ScanCodeInfo', {})
- @property
- def scan_type(self):
- return self.scan_code_info['ScanType']
- @property
- def scan_result(self):
- return self.scan_code_info['ScanResult']
- @register_event('scancode_push')
- class ScanCodePushEvent(BaseScanCodeEvent):
- """
- 扫码推事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1421141016
- """
- event = 'scancode_push'
- @register_event('scancode_waitmsg')
- class ScanCodeWaitMsgEvent(BaseScanCodeEvent):
- """
- 扫码推事件且弹出“消息接收中”提示框的事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1421141016
- """
- event = 'scancode_waitmsg'
- class BasePictureEvent(BaseEvent):
- key = StringField('EventKey')
- pictures_info = BaseField('SendPicsInfo', {})
- @property
- def count(self):
- return int(self.pictures_info['Count'])
- @property
- def pictures(self):
- if self.pictures_info['PicList']:
- items = self.pictures_info['PicList']['item']
- if self.count > 1:
- return items
- return [items]
- return []
- @register_event('pic_sysphoto')
- class PicSysPhotoEvent(BasePictureEvent):
- """
- 弹出系统拍照发图的事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1421141016
- """
- event = 'pic_sysphoto'
- @register_event('pic_photo_or_album')
- class PicPhotoOrAlbumEvent(BasePictureEvent):
- """
- 弹出拍照或者相册发图的事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1421141016
- """
- event = 'pic_photo_or_album'
- @register_event('pic_weixin')
- class PicWeChatEvent(BasePictureEvent):
- """
- 弹出微信相册发图器的事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1421141016
- """
- event = 'pic_weixin'
- @register_event('location_select')
- class LocationSelectEvent(BaseEvent):
- """
- 弹出地理位置选择器的事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1421141016
- """
- event = 'location_select'
- key = StringField('EventKey')
- location_info = BaseField('SendLocationInfo', {})
- @property
- def location_x(self):
- return self.location_info['Location_X']
- @property
- def location_y(self):
- return self.location_info['Location_Y']
- @property
- def location(self):
- return self.location_x, self.location_y
- @property
- def scale(self):
- return self.location_info['Scale']
- @property
- def label(self):
- return self.location_info['Label']
- @property
- def poiname(self):
- return self.location_info['Poiname']
- @register_event('card_pass_check')
- class CardPassCheckEvent(BaseEvent):
- event = 'card_pass_check'
- card_id = StringField('CardId')
- @register_event('card_not_pass_check')
- class CardNotPassCheckEvent(BaseEvent):
- event = 'card_not_pass_check'
- card_id = StringField('CardId')
- @register_event('user_get_card')
- class UserGetCardEvent(BaseEvent):
- """
- 领取事件推送
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1451025274
- """
- event = 'user_get_card'
- card_id = StringField('CardId')
- is_given_by_friend = IntegerField('IsGiveByFriend')
- friend = StringField('FriendUserName')
- code = StringField('UserCardCode')
- old_code = StringField('OldUserCardCode')
- outer_id = StringField('OuterId')
- @register_event('user_del_card')
- class UserDeleteCardEvent(BaseEvent):
- """
- 卡券删除事件推送
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1451025274
- """
- event = 'user_del_card'
- card_id = StringField('CardId')
- code = StringField('UserCardCode')
- @register_event('user_consume_card')
- class UserConsumeCardEvent(BaseEvent):
- """
- 卡券核销事件推送
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1451025274
- """
- event = 'user_consume_card'
- card_id = StringField('CardId')
- code = StringField('UserCardCode')
- consume_source = StringField('ConsumeSource')
- location_id = StringField('LocationId')
- staff = StringField('StaffOpenId')
- @register_event('merchant_order')
- class MerchantOrderEvent(BaseEvent):
- event = 'merchant_order'
- order_id = StringField('OrderId')
- order_status = IntegerField('OrderStatus')
- product_id = StringField('ProductId')
- sku_info = StringField('SkuInfo')
- @register_event('kf_create_session')
- class KfCreateSessionEvent(BaseEvent):
- event = 'kf_create_session'
- account = StringField('KfAccount')
- @register_event('kf_close_session')
- class KfCloseSessionEvent(BaseEvent):
- event = 'kf_close_session'
- account = StringField('KfAccount')
- @register_event('kf_switch_session')
- class KfSwitchSessionEvent(BaseEvent):
- event = 'kf_switch_session'
- from_account = StringField('FromKfAccount')
- to_account = StringField('ToKfAccount')
- @register_event('device_text')
- class DeviceTextEvent(BaseEvent):
- event = 'device_text'
- device_type = StringField('DeviceType')
- device_id = StringField('DeviceID')
- session_id = StringField('SessionID')
- content = Base64DecodeField('Content')
- open_id = StringField('OpenID')
- @register_event('device_bind')
- class DeviceBindEvent(BaseEvent):
- event = 'device_bind'
- device_type = StringField('DeviceType')
- device_id = StringField('DeviceID')
- session_id = StringField('SessionID')
- content = Base64DecodeField('Content')
- open_id = StringField('OpenID')
- @register_event('device_unbind')
- class DeviceUnbindEvent(BaseEvent):
- event = 'device_unbind'
- device_type = StringField('DeviceType')
- device_id = StringField('DeviceID')
- session_id = StringField('SessionID')
- content = Base64DecodeField('Content')
- open_id = StringField('OpenID')
- @register_event('device_subscribe_status')
- class DeviceSubscribeStatusEvent(BaseEvent):
- event = 'device_subscribe_status'
- device_type = StringField('DeviceType')
- device_id = StringField('DeviceID')
- open_id = StringField('OpenID')
- op_type = IntegerField('OpType')
- @register_event('device_unsubscribe_status')
- class DeviceUnsubscribeStatusEvent(BaseEvent):
- event = 'device_unsubscribe_status'
- device_type = StringField('DeviceType')
- device_id = StringField('DeviceID')
- open_id = StringField('OpenID')
- op_type = IntegerField('OpType')
- @register_event('shakearoundusershake')
- class ShakearoundUserShakeEvent(BaseEvent):
- event = 'shakearound_user_shake'
- _chosen_beacon = BaseField('ChosenBeacon', {})
- _around_beacons = BaseField('AroundBeacons', {})
- @property
- def chosen_beacon(self):
- beacon = self._chosen_beacon
- if not beacon:
- return {}
- return {
- 'uuid': beacon['Uuid'],
- 'major': beacon['Major'],
- 'minor': beacon['Minor'],
- 'distance': float(beacon['Distance']),
- }
- @property
- def around_beacons(self):
- beacons = self._around_beacons
- if not beacons:
- return []
- ret = []
- for beacon in beacons['AroundBeacon']:
- ret.append({
- 'uuid': beacon['Uuid'],
- 'major': beacon['Major'],
- 'minor': beacon['Minor'],
- 'distance': float(beacon['Distance']),
- })
- return ret
- @register_event('poi_check_notify')
- class PoiCheckNotifyEvent(BaseEvent):
- event = 'poi_check_notify'
- poi_id = StringField('PoiId')
- uniq_id = StringField('UniqId')
- result = StringField('Result')
- message = StringField('Msg')
- @register_event('wificonnected')
- class WiFiConnectedEvent(BaseEvent):
- event = 'wificconnected'
- connect_time = IntegerField('ConnectTime')
- expire_time = IntegerField('ExpireTime')
- vendor_id = StringField('VendorId')
- shop_id = StringField('PlaceId')
- bssid = StringField('DeviceNo')
- # ============================================================================
- # 微信认证事件推送
- # ============================================================================
- @register_event('qualification_verify_success')
- class QualificationVerifySuccessEvent(BaseEvent):
- """
- 资质认证成功事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1455785130
- """
- event = 'qualification_verify_success'
- expired_time = DateTimeField('ExpiredTime')
- @register_event('qualification_verify_fail')
- class QualificationVerifyFailEvent(BaseEvent):
- """
- 资质认证失败事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1455785130
- """
- event = 'qualification_verify_fail'
- fail_time = DateTimeField('FailTime')
- fail_reason = StringField('FailReason')
- @register_event('naming_verify_success')
- class NamingVerifySuccessEvent(BaseEvent):
- """
- 名称认证成功事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1455785130
- """
- event = 'naming_verify_success'
- expired_time = DateTimeField('ExpiredTime')
- @register_event('naming_verify_fail')
- class NamingVerifyFailEvent(BaseEvent):
- """
- 名称认证失败事件
- 客户端不打勾,但仍有接口权限。详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1455785130
- """
- event = 'naming_verify_fail'
- fail_time = DateTimeField('FailTime')
- fail_reason = StringField('FailReason')
- @register_event('annual_renew')
- class AnnualRenewEvent(BaseEvent):
- """
- 年审通知事件
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1455785130
- """
- event = 'annual_renew'
- expired_time = DateTimeField('ExpiredTime')
- @register_event('verify_expired')
- class VerifyExpiredEvent(BaseEvent):
- """
- 认证过期失效通知
- 详情请参阅
- https://mp.weixin.qq.com/wiki?id=mp1455785130
- """
- event = 'verify_expired'
- expired_time = DateTimeField('ExpiredTime')
- @register_event('user_scan_product')
- class UserScanProductEvent(BaseEvent):
- """
- 打开商品主页事件
- 详情请参考
- https://mp.weixin.qq.com/wiki?id=mp1455872179
- """
- event = 'user_scan_product'
- standard = StringField('KeyStandard')
- key = StringField('KeyStr')
- country = StringField('Country')
- province = StringField('Province')
- city = StringField('City')
- sex = IntegerField('Sex')
- scene = IntegerField('Scene')
- @register_event('user_scan_product_enter_session')
- class UserScanProductEnterSessionEvent(BaseEvent):
- """
- 进入公众号事件
- 详情请参考
- https://mp.weixin.qq.com/wiki?id=mp1455872179
- """
- event = 'user_scan_product_enter_session'
- standard = StringField('KeyStandard')
- key = StringField('KeyStr')
- @register_event('user_scan_product_async')
- class UserScanProductAsyncEvent(BaseEvent):
- """
- 地理位置信息异步推送事件
- 详情请参考
- https://mp.weixin.qq.com/wiki?id=mp1455872179
- """
- event = 'user_scan_product_async'
- standard = StringField('KeyStandard')
- key = StringField('KeyStr')
- region_code = StringField('RegionCode')
- @register_event('user_scan_product_verify_action')
- class UserScanProductVerifyActionEvent(BaseEvent):
- """
- 商品审核结果事件
- 详情请参考
- https://mp.weixin.qq.com/wiki?id=mp1455872179
- """
- event = 'user_scan_product_verify_action'
- standard = StringField('KeyStandard')
- key = StringField('KeyStr')
- result = StringField('Result')
- reason = StringField('ReasonMsg')
- @register_event('subscribe_scan_product')
- class SubscribeScanProductEvent(BaseEvent):
- """
- 用户在商品主页中关注公众号事件
- 详情请参考
- https://mp.weixin.qq.com/wiki?id=mp1455872179
- """
- event = 'subscribe_scan_product'
- event_key = StringField('EventKey')
- @property
- def scene(self):
- return self.event_key.split('|', 1)[0]
- @property
- def standard(self):
- return self.event_key.split('|')[1]
- @property
- def key(self):
- return self.event_key.split('|')[2]
- @register_event('user_authorize_invoice')
- class UserAuthorizeInvoiceEvent(BaseEvent):
- """
- 用户授权发票事件
- (会包含一个订单号,不成功就失败)
- 详情请参考
- https://mp.weixin.qq.com/wiki?id=mp1497082828_r1cI2
- """
- event = 'user_authorize_invoice'
- success_order_id = StringField('SuccOrderId') # 授权成功的订单号
- fail_order_id = StringField('FailOrderId') # 授权失败的订单号
- app_id = StringField('AppId') # 用于接收事件推送的公众号的AppId
- auth_source = StringField('Source') # 授权来源,web表示来自微信内H5,app标识来自app
- @register_event('update_invoice_status')
- class UpdateInvoiceStatusEvent(BaseEvent):
- """
- 发票状态更新事件
- 详情请参考
- https://mp.weixin.qq.com/wiki?id=mp1497082828_r1cI2
- """
- event = 'update_invoice_status'
- status = StringField('Status') # 发票报销状态
- card_id = StringField('CardId') # 发票 Card ID
- code = StringField('Code') # 发票 Code
- @register_event('submit_invoice_title')
- class SubmitInvoiceTitleEvent(BaseEvent):
- """
- 用户提交发票抬头事件
- 详情请参考
- https://mp.weixin.qq.com/wiki?id=mp1496554912_vfWU0
- """
- event = 'submit_invoice_title'
- title = StringField('title') # 抬头
- phone = StringField('phone') # 联系方式
- tax_no = StringField('tax_no') # 税号
- addr = StringField('addr') # 地址
- bank_type = StringField('bank_type') # 银行类型
- bank_no = StringField('bank_no') # 银行号码
- attach = StringField('attach') # 附加字段
- title_type = StringField('title_type') # 抬头类型,个人InvoiceUserTitlePersonType, 公司InvoiceUserTitleBusinessType
- @register_event('user_enter_tempsession')
- class UserEnterTempSessionEvent(BaseEvent):
- """
- 小程序用户进入客服消息
- 详情请参阅
- https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/customer-message/receive.html
- """
- event = 'user_enter_tempsession'
- session_from = StringField('SessionFrom')
- @register_event('view_miniprogram')
- class ViewMiniProgramEvent(BaseEvent):
- """
- 从菜单进入小程序事件
- """
- event = 'view_miniprogram'
- page_path = StringField('EventKey') # 小程序路径
- menu_id = StringField('MenuId') # 菜单ID
|