Пример #1
0
def wechat_handler():
    try:
        token = current_app.config['WECHAT_TOEKN']
        signature = request.args.get('signature')
        timestamp = request.args.get('timestamp')
        nonce = request.args.get('nonce')
        check_signature(token, signature, timestamp, nonce)

        current_app.logger.info('wechat_handler begin')
        body = request.get_data()
        current_app.logger.info('wechat_handler body %s' % body)
        msg = parse_message(body)
        if msg.type == 'text':
            return reply_msg(msg)
        elif msg.type == 'event' and msg.event == 'click' and msg.key == 'V2003_SignIn':
            return sign_in(msg)
        elif msg.type == 'event' and msg.event in ['subscribe_scan', 'scan'] and msg.scene_id == '123':
            binding(msg)
            if msg.event == 'subscribe_scan':
                return welcome_article(msg)
        elif msg.type == 'event' and msg.event == 'unsubscribe':
            unsubscribe_unbinding(msg)
        elif msg.type == 'event' and msg.event == 'subscribe':
            return welcome_article(msg)
        reply = EmptyReply()
        return reply.render()
    except InvalidSignatureException:
        abort(404)
    except Exception as e:
        current_app.logger.exception('wechat_handler %s' % e)
        reply = EmptyReply()
        return reply.render()
Пример #2
0
def get_resp_message(request, source_msg, mode=None):
    request_msg = parse_message(source_msg)
    request_msg_type = request_msg.type
    log.info('>>> body[{}],request_msg_type[{}],request_msg[{}]'.format(
        request.body, request_msg_type, request_msg))
    # 根据消息类型解析
    if request_msg_type == 'text':
        reply = TextReply(content='{}'.format(
            get_text_reply(request, request_msg.content)),
                          message=request_msg)
    elif request_msg_type == 'image':
        reply = TextReply(content=howold(request_msg.image),
                          message=request_msg)
    elif request_msg_type == 'voice':
        if not request_msg.recognition:
            reply = TextReply(content='没听清楚啊,再说一遍,亲', message=request_msg)
        else:
            content = get_text_reply(request, request_msg.recognition)
            # tts = gTTS(text=content, lang='zh-cn')
            # tmpfd, tempfilename = tempfile.mkstemp()
            # tts.save(tempfilename)
            # with open(tempfilename, mode='rb') as f:
            #     client = WeChatClient(config.WECHAT_APPID, config.WECHAT_SECRET)
            #     res = WeChatMedia(client=client).upload('voice', f.read())
            #     print('>>>', res)
            #     media_id = json.loads(res).get('media_id')
            #     if not media_id:
            #         reply = VideoReply(message=request_msg)
            #         reply.media_id = media_id
            #     else:
            #         reply = TextReply(content='{}'.format(content), message=request_msg)
            reply = TextReply(content='{}'.format(content),
                              message=request_msg)
    elif request_msg_type == 'event':
        request_msg_event = request_msg.event
        if request_msg_event == 'subscribe':
            reply = TextReply(content=config.WELCOME_MSG, message=request_msg)
        elif request_msg_event == 'unsubscribe':
            reply = TextReply(content='多谢关注!', message=request_msg)
        else:
            reply = EmptyReply()
    else:
        reply = EmptyReply()

    # 返回xml报文
    xml = reply.render()

    if mode == 'aes':
        # get var
        timestamp = request.raw_args.get('timestamp', '')
        nonce = request.raw_args.get('nonce', '')

        crypto = WeChatCrypto(config.WECHAT_TOKEN,
                              config.WECHAT_ENCODING_AES_KEY,
                              config.WECHAT_APPID)
        encrypted_xml = crypto.encrypt_message(xml, nonce, timestamp)
        return encrypted_xml
    else:
        return xml
Пример #3
0
def wechat_handler():
    msg = request.wechat_msg
    reply = EmptyReply()
    if msg.type == 'text':

        if msg.content == '课表':
            schedule_year = '2015-2016'
            schedule_term = '2'
            schedule_data = school.schedule(schedule_year, schedule_term)
            if type(schedule_data) == dict and schedule_data.get('error'):
                reply = TextReply(content=schedule_data['error'], message=msg)
            else:
                data = assemble_schedule(schedule_data)
                reply = create_reply(data, message=msg)

        elif msg.content == '成绩':
            score_year = '2015-2016'
            score_term = '2'
            score_data = school.score(score_year, score_term)
            if type(score_data) == dict and score_data.get('error'):
                reply = TextReply(content=schedule_data['error'], message=msg)
            else:
                data = assemble_score(score_year, score_term, score_data)
                reply = create_reply(data, message=msg)

        elif msg.content == '绑定':
            content = '<a >点击绑定</a>'
            content = '<a href="https://weixin.gxgk.cc/">点击绑定</a>'
            reply = TextReply(content=content, message=msg)

        else:
            reply = TextReply(content=msg.content, message=msg)

    return reply
Пример #4
0
class Event(object):
    '''
    事件基类
    '''

    reply = None
    expected_type = None
    msg_reply = None

    id = 0
    type = 'unknown'  # 消息的类型
    source = None  # 消息的来源用户,即发送消息的用户
    target = None  # 消息的目标用户
    create_time = None  # 消息的发送时间,UNIX 时间戳
    time = None

    def __init__(self, msg):
        if not isinstance(msg, self.expected_type):
            raise TypeError("Expected " + str(self.expected_type))

        self.msg = msg
        self.id = self.msg.id
        self.type = self.msg.type
        self.source = self.msg.source
        self.target = self.msg.target
        self.create_time = self.msg.create_time
        self.time = self.msg.time

    def on_take(self):
        '''
        推送消息-主动调用该方法
        :return:
        '''
        print('TextMessageBase', self.id)
        print('TextMessageBase', self.type)
        print('TextMessageBase', self.source)
        print('TextMessageBase', self.target)
        print('TextMessageBase', self.create_time)
        print('TextMessageBase', self.time)

        context = self.get_reply_body()
        if not context:
            self.msg_reply = EmptyReply()
            print('EmptyReply', type(self.msg_reply))
            return

        context_send = {'message': self.msg, **context}

        self.msg_reply = self.reply(**context_send)

    def get_reply_body(self, context=None):
        '''
        微信公众号消息回复内容构建
        :param context:
        :return:
        '''
        return context

    def render(self):
        return self.msg_reply.render()
Пример #5
0
def deserialize_reply(xml, update_time=False):
    """反序列化被动回复
    :param xml: 待反序列化的xml
    :param update_time: 是否用当前时间替换xml中的时间
    :raises ValueError: 不能辨识的reply xml
    :rtype: wechatpy.replies.BaseReply
    """
    if not xml:
        return EmptyReply()

    try:
        reply_dict = xmltodict.parse(xml)["xml"]
        msg_type = reply_dict["MsgType"]
    except:
        raise ValueError("bad reply xml")
    if msg_type not in REPLY_TYPES:
        raise ValueError("unknown reply type")

    cls = REPLY_TYPES[msg_type]
    kwargs = dict()
    for attr, field in cls._fields.items():
        if field.name in reply_dict:
            str_value = reply_dict[field.name]
            kwargs[attr] = field.from_xml(str_value)

    if update_time:
        kwargs["time"] = time.time()

    return cls(**kwargs)
Пример #6
0
 def _reply(self, msg):
     """处理消息
     """
     for h in self.handlers:
         reply = h.handle(msg)
         if isinstance(reply, BaseReply):
             return reply
     return EmptyReply()
Пример #7
0
def reply_msg(msg):
    rs = get_match_bloginfo(msg.content)
    record_msg(msg, rs['is_match'])
    if rs['is_match']:
        data = [rs]
        client = get_wechat_client()
        client.message.send_articles(msg.source, data)
        reply = EmptyReply()
    else:
        rs = get_sougou_result(msg.content)
        if rs['is_match']:
            client = get_wechat_client()
            client.message.send_articles(msg.source, [rs])
            reply = EmptyReply()
        else:
            reply = TextReply(content=u'抱歉,关键词:{keyword} 还未收录。'.format(
                keyword=msg.content), message=msg)
    return reply.render()
Пример #8
0
    def on_take(self):
        '''
        推送消息-主动调用该方法
        :return:
        '''
        print('TextMessageBase', self.id)
        print('TextMessageBase', self.type)
        print('TextMessageBase', self.source)
        print('TextMessageBase', self.target)
        print('TextMessageBase', self.create_time)
        print('TextMessageBase', self.time)

        context = self.get_reply_body()
        if not context:
            self.msg_reply = EmptyReply()
            print('EmptyReply', type(self.msg_reply))
            return

        context_send = {'message': self.msg, **context}

        self.msg_reply = self.reply(**context_send)
Пример #9
0
def get_resp_message(source_msg):
    """构造微信公众号返回消息"""
    request_msg = parse_message(source_msg)
    request_msg_type = request_msg.type
    openid = request.args.get('openid', '')
    print('>>> request_msg_type[{}],request_msg[{}]'.format(request_msg_type, request_msg))
    # 根据消息类型解析
    if request_msg_type == 'text':
        reply = TextReply(content='{}'.format(request_msg.content), message=request_msg)
    elif request_msg_type == 'image':
        reply = TextReply(content='{}'.format('hello'), message=request_msg)
    elif request_msg_type == 'voice':
        if not request_msg.recognition:
            reply = TextReply(content='没听清楚啊,再说一遍,亲', message=request_msg)
        else:
            reply = TextReply(content='{}'.format(request_msg.recognition), message=request_msg)
    elif request_msg_type == 'event':
        request_msg_event = request_msg.event
        if request_msg_event == 'subscribe':
            # 用户关注后,登记用户信息
            try:
                client = WeChatClient(WECHAT_APPID, WECHAT_SECRET)
                user_json = client.user.get(openid)
            except:
                print('>>>', '获取用户信息失败')
            else:
                save_wechat_user(user_json)

            reply = TextReply(content=WECHAT_WELCOME_MSG, message=request_msg)
        elif request_msg_event == 'unsubscribe':
            reply = TextReply(content='多谢关注!', message=request_msg)
        elif request_msg_event == 'CLICK':
            reply = EmptyReply()
        else:
            reply = EmptyReply()
    else:
        reply = EmptyReply()

    # 返回xml报文
    return reply.render()
Пример #10
0
 def _reply(self, msg):
     """处理消息的核心方法
     """
     for handler in self.handlers:
         # 每个消息处理器会判断 msg 的数据类型
         # 如果不符合,直接返回 None
         # 如果符合,返回处理之后的 BaseReply 实例
         reply = handler.handle(msg)
         if isinstance(reply, BaseReply):
             return reply
     # 如果微信公众号发来的消息不符合任何一个消息处理器的处理规则
     # 返回 EmptyReply 这个类的实例
     return EmptyReply()
Пример #11
0
def wxUrlTest(request):
    if request.method == 'GET':
        token = request.GET.get('token', '')
        timestamp = request.GET.get('timestamp', '')
        nonce = request.GET.get('nonce', '')
        echostr = request.GET.get('echostr', '')
        return HttpResponse(echostr)
    elif request.method == 'POST':
        # 回复空消息
        msg = parse_message(request.body)
        if msg.type == 'text':
            print(msg)
            client.message.send_text(msg.source, '客服消息测试')
        return HttpResponse(EmptyReply().render())
Пример #12
0
def serve(request):
    timestamp = request.GET.get('timestamp', '')
    nonce = request.GET.get('nonce', '')
    if request.method == 'GET':
        signature = request.GET.get('signature', '')
        echo_str = request.GET.get('echostr', '')
        try:
            check_signature(settings.WECHAT_TOKEN, signature, timestamp, nonce)
            logger.info('Wechat signature validated.')
            return HttpResponse(echo_str)
        except InvalidSignatureException:
            logger.warning('Invalid wechat signature.')
            return HttpResponseBadRequest()
    elif request.method == 'POST':
        signature = request.GET.get('msg_signature', '')
        try:
            decrypted_xml = crypto.decrypt_message(request.body, signature,
                                                   timestamp, nonce)
        except (InvalidAppIdException, InvalidSignatureException):
            logger.warning('Invalid wechat message signature.')
            return HttpResponseBadRequest()
        msg = parse_message(decrypted_xml)
        reply = None
        if msg.type == 'text':
            reply = process_text(request, msg)
        elif msg.type == 'event':
            if msg.event == 'subscribe':
                reply = actions.subscribe(msg)
            elif msg.event == 'unsubscribe':
                reply = actions.unsubscribe(msg)
        if reply is None:
            return HttpResponse(EmptyReply().render())
        else:
            xml = reply.render()
            encrypted_xml = crypto.encrypt_message(xml, nonce, timestamp)
            return HttpResponse(encrypted_xml)
    else:
        return HttpResponseBadRequest()
Пример #13
0
    def test_empty_reply(self):
        from wechatpy.replies import EmptyReply

        reply = EmptyReply()
        self.assertEqual('', reply.render())
Пример #14
0
    def test_empty_reply(self):
        from wechatpy.replies import EmptyReply

        reply = EmptyReply()
        self.assertEqual('', reply.render())
Пример #15
0
def api(request):
    # 从 request 中提取基本信息 (signature, timestamp, nonce, xml)
    signature = request.GET.get('msg_signature')
    timestamp = request.GET.get('timestamp')
    nonce = request.GET.get('nonce')
    # 解析本次请求的 XML 数据
    crypto = WeChatCrypto(settings.TOKEN, settings.ENCODINGAESKEY, settings.CORPID)
    if request.method == 'GET':
        # 检验合法性
        echo_str = request.GET.get('echostr', '')
        try:
            echo_str = crypto.check_signature(signature, timestamp, nonce, echo_str)
        except InvalidSignatureException:
            # 处理异常情况或忽略
            return HttpResponseBadRequest('Verify Failed')
        return HttpResponse(echo_str, content_type="text/plain")

    try:
        decrypted_xml = crypto.decrypt_message(
            request.body,
            signature,
            timestamp,
            nonce
        )
    except (InvalidCorpIdException, InvalidSignatureException):
        # 处理异常或忽略
        return HttpResponseBadRequest('Failed')
    msg = parse_message(decrypted_xml)
    response = EmptyReply()
    if msg.type == 'text':
        text = msg.content
        if text == 'info':
            userinfo = wechat_client.user.get(msg.source)
            response = TextReply(content=str(userinfo), message=msg)
        else:
            reply = Wechatkeyword.objects.extra(where=['%s SIMILAR TO keyword'], params=[text]).first()
            if reply:
                response = TextReply(content=u'%s' % reply.data, message=msg)
    elif msg.type == 'event':
        if msg.event == 'subscribe':  # 关注事件
            response = EmptyReply()

        elif msg.event == 'unsubscribe':
            logger.info('wechat user %s unsubscribe' % msg.source)
            user = User.objects.get(openid=msg.source)
            user.checkinaccountabnormal = True
            user.save()

        elif msg.event == 'location':
            nowtime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
            try:
                user = User.objects.get(openid=msg.source)
            except User.DoesNotExist:
                pass
            else:
                user.latitude = msg.latitude
                user.longitude = msg.longitude
                user.accuracy = msg.precision
                user.lastpositiontime = nowtime
                user.save()

        elif msg.event == 'click':
            if msg.key == '1200':
                response = TextReply(content=u'地址:%s\n学生默认帐号:学号/身份证号\n教师默认帐号:职工号/职工号' % settings.DOMAIN,
                                     message=msg)

    xml = response.render()
    encrypted_xml = crypto.encrypt_message(xml, nonce, timestamp)
    return HttpResponse(encrypted_xml, content_type="application/xml")