cloverstd / flask-wechatpy

wechatpy support for flask
MIT License
96 stars 35 forks source link

建议支持多号联动扩展 #4

Open aiportal opened 7 years ago

aiportal commented 7 years ago

我遇到的情况:

开发订阅号后台时,因订阅号不支持网页授权功能,只好绕道用服务号实现网页登录授权。 flask-wechatpy 中使用 app.config 全局配置了 oauth 和 WechatPay 所需的服务号 appid。

要接收订阅号的文字、菜单等消息,就要单写一个服务,没法用 wechat 和 wechat_requeired。

aiportal commented 7 years ago
from flask.views import View, request
from flask import abort, current_app
from wechatpy import parse_message
from wechatpy.utils import check_signature
from wechatpy.exceptions import InvalidSignatureException, InvalidAppIdException
from wechatpy.crypto import WeChatCrypto
from wechatpy.replies import BaseReply

class WechatServerView(View):
    methods = ['GET', 'POST']

    @property
    def appid(self):
        raise NotImplemented

    @property
    def secret(self):
        raise NotImplemented

    @property
    def token(self):
        raise NotImplemented

    @property
    def aes_key(self):
        return None

    def dispatch_request(self):
        signature, timestamp, nonce = [request.args.get(k) for k in ('signature', 'timestamp', 'nonce')]

        # check signature
        try:
            check_signature(self.token, signature, timestamp, nonce)
        except InvalidSignatureException as ex:
            current_app.logger.warning('signature failed.')
            return abort(403)

        if request.method == 'GET':
            return request.args.get('echostr')

        raw_msg = request.data
        current_app.logger.debug(raw_msg)
        if self.aes_key:
            crypto = WeChatCrypto(self.token, self.aes_key, self.appid)
            try:
                raw_msg = crypto.decrypt_message(
                    raw_msg,
                    signature,
                    timestamp,
                    nonce
                )
            except (InvalidAppIdException, InvalidSignatureException):
                current_app.logger.warning('decode message failed.')
                return abort(403)

        wechat_msg = parse_message(raw_msg)
        res = self.process_wechat_msg(wechat_msg)
        xml = ''

        if isinstance(res, BaseReply):
            xml = res.render()

        if self.aes_key:
            crypto = WeChatCrypto(
                self.token,
                self.aes_key,
                self.appid
            )
            xml = crypto.encrypt_message(xml, nonce, timestamp)

        return xml

    def process_wechat_msg(self, msg):
        raise NotImplemented