wechatpy.events 源代码

# -*- 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 wechatpy.fields import (
    Base64DecodeField,
    BaseField,
    DateTimeField,
    FloatField,
    IntegerField,
    StringField
)
from 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): """ 卡券审核事件推送 https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Coupons_Vouchers_and_Cards_Event_Push_Messages.html#1 """ 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') refuse_reason = StringField('RefuseReason') @register_event('user_get_card') class UserGetCardEvent(BaseEvent): """ 领取事件推送 详情请参阅 https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Coupons_Vouchers_and_Cards_Event_Push_Messages.html#2 """ 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') outer_str = StringField('OuterStr') is_restore_member_card = IntegerField('IsRestoreMemberCard') is_recommend_by_friend = IntegerField('IsRecommendByFriend') union_id = StringField('UnionId') @register_event('user_gifting_card') class UserGiftingCardEvent(BaseEvent): """ 转赠事件推送 详情请参阅 https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Coupons_Vouchers_and_Cards_Event_Push_Messages.html#3 """ event = 'user_gifting_card' card_id = StringField('CardId') code = StringField('UserCardCode') is_return_back = IntegerField('IsReturnBack') friend = StringField('FriendUserName') is_chat_room = IntegerField('IsChatRoom') @register_event('user_del_card') class UserDeleteCardEvent(BaseEvent): """ 卡券删除事件推送 详情请参阅 https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Coupons_Vouchers_and_Cards_Event_Push_Messages.html#4 """ event = 'user_del_card' card_id = StringField('CardId') code = StringField('UserCardCode') @register_event('user_consume_card') class UserConsumeCardEvent(BaseEvent): """ 卡券核销事件推送 详情请参阅 https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Coupons_Vouchers_and_Cards_Event_Push_Messages.html#5 """ event = 'user_consume_card' card_id = StringField('CardId') code = StringField('UserCardCode') consume_source = StringField('ConsumeSource') location_name = StringField('LocationName') staff = StringField('StaffOpenId') verify_code = StringField('VerifyCode') remark_amount = StringField('RemarkAmount') outer_str = StringField('OuterStr') @register_event('user_pay_from_pay_cell') class UserPayFromPayCell(BaseEvent): """ 卡券买单事件推送 详情请参阅 https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Coupons_Vouchers_and_Cards_Event_Push_Messages.html#6 """ event = 'user_pay_from_pay_cell' card_id = StringField('CardId') code = StringField('UserCardCode') trans_id = StringField('TransId') location_id = IntegerField('LocationId') fee = IntegerField('Fee') original_fee = IntegerField('OriginalFee') @register_event('user_view_card') class UserViewCard(BaseEvent): """ 进入会员卡事件推送 详情请参阅 https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Coupons_Vouchers_and_Cards_Event_Push_Messages.html#7 """ event = 'user_view_card' card_id = StringField('CardId') code = StringField('UserCardCode') outer_str = StringField('OuterStr') @register_event('user_enter_session_from_card') class UserEnterSessionFromCardEvent(BaseEvent): """ 从卡券进入公众号会话事件推送 详情请参阅 https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Coupons_Vouchers_and_Cards_Event_Push_Messages.html#8 """ event = 'user_enter_session_from_card' card_id = StringField('CardId') code = StringField('UserCardCode') @register_event('update_member_card') class UpdateMemberCard(BaseEvent): """ 会员卡内容更新事件 详情请参阅 https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Coupons_Vouchers_and_Cards_Event_Push_Messages.html#9 """ event = 'update_member_card' card_id = StringField('CardId') code = StringField('UserCardCode') modify_bonus = IntegerField('ModifyBonus') modify_balance = IntegerField('ModifyBalance') @register_event('card_sku_remind') class CardSkuRemindEvent(BaseEvent): """ 卡券库存报警事件 详情请参阅 https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Coupons_Vouchers_and_Cards_Event_Push_Messages.html#10 """ event = 'card_sku_remind' card_id = StringField('CardId') detail = StringField('Detail') @register_event('card_pay_order') class CardPayOrderEvent(BaseEvent): """ 券点流水详情事件 详情请参阅 https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Coupons_Vouchers_and_Cards_Event_Push_Messages.html#11 """ event = 'card_pay_order' order_id = IntegerField('OrderId') status = StringField('Status') create_order_time = IntegerField('CreateOrderTime') pay_finish_time = IntegerField('PayFinishTime') description = StringField('Desc') free_coin_count = IntegerField('FreeCoinCount') pay_coin_count = IntegerField('PayCoinCount') refund_free_coin_count = IntegerField('RefundFreeCoinCount') refund_pay_coin_count = IntegerField('RefundPayCoinCount') order_type = StringField('OrderType') memo = StringField('Memo') receipt_info = StringField('ReceiptInfo') @register_event('submit_membercard_user_info') class SubmitMembercardUserInfo(BaseEvent): """ 会员卡激活事件推送 详情请参阅 https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Coupons_Vouchers_and_Cards_Event_Push_Messages.html#12 """ event = 'submit_membercard_user_info' card_id = StringField('CardId') card_code = StringField('UserCardCode') @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 @register_event('wxa_media_check') class WxaMediaCheckEvent(BaseEvent): """ 异步检测结果通知事件 详情请参考 https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/sec-check/security.mediaCheckAsync.html """ event = 'wxa_media_check' is_risky = IntegerField('isrisky') # 检测结果,0:暂未检测到风险,1:风险 extra_info_json = StringField('extra_info_json') # 附加信息,默认为空 trace_id = StringField('trace_id') # 任务 id status_code = IntegerField('status_code') # 默认为:0,4294966288(-1008)为链接无法下载 @property def is_valid(self): return self.is_risky == 0 and self.status_code == 0