def forward_message(msg, src_group, target_groups):
    '''按类型发消息'''
    msg["UserImg"] = ''
    if msg["Type"] == 'Text':
        '''
        #print(itchat.get_friends())
        # 消息入口
        username = msg["ActualUserName"] # 发言用户id 群id:FromUserName
        user = itchat.search_friends(userName=username)
        '''
        logger.info("forward_message begin")  # log for debug
        logger.info(("forward message : ", msg))

        # 多给msg一个属性 at_id
        message2push = {}
        message2push["group_name"] = src_group._group_name
        message2push["content"] = msg["Text"]
        message2push["group_user_name"] = msg["ActualNickName"]
        try:
            # todo 部分用户无法获取头像  chatroomid 错误
            # 头像
            # user_head_img = itchat.get_head_img(userName=msg["ActualUserName"],chatroomUserName=src_group._group_id,picDir="/tmp/wechat_user/{}".format(img_id)) #存储到本地
            # todo:第一层缓存,获取头像之前,先检查本轮对话中 msg["ActualUserName"]
            # 是否被记录在本地数据库,免去向微信请求
            user_img = UserImgCache()
            group_user_id = msg["ActualUserName"]
            url_get_with_user_id = user_img.get_user_img_with_user_id(
                group_user_id)  # 第一层缓存
            if url_get_with_user_id:
                message2push["user_img"] = url_get_with_user_id
                logger.info(("url_get_with_user_id: " +
                             message2push["user_img"]))
            else:
                # 重新登录user id 变了,但是img md5还有效
                # todo 无法获取头像 可能是这么问题 chatroomUserName
                logging.debug("ActualUserName :%s, src_group _group_id: %s", msg[
                              "ActualUserName"], src_group._group_id)
                img_data = itchat.get_head_img(userName=msg[
                                               "ActualUserName"], chatroomUserName=src_group._group_id)  # .getvalue()#前头是str #有时候错误
                # logging.debug(img_data)
                img_md5 = hashlib.md5(buffer(img_data)).hexdigest()
                url_get_with_img_md5 = user_img.get_user_img_with_img_md5(
                    img_md5)
                if url_get_with_img_md5:
                    message2push["user_img"] = url_get_with_img_md5
                    logger.info(("url_get_with_img_md5: " +
                                 message2push["user_img"]))
                else:
                    # 如果两级缓存都没有命中,再上传头像
                    url_with_uploading_img = user_img.set_user_img(
                        group_user_id, buffer(img_data))
                    message2push["user_img"] = url_with_uploading_img
                    logger.info(("url_with_uploading_img: " +
                                 message2push["user_img"]))
            msg["UserImg"] = message2push["user_img"]
        except Exception as e:
            logger.error("can not get user head img")
            logger.error('Failed to open file', exc_info=True)

        try:
            # 日志系统
            if USE_LEANCLOUD:
                logger.info("ready to push message to cloud")
                push_message(message2push)
            logger.info("ready to push message to local file")
            logger.info(message2push)
            logger.info("ready to push message to local db(sqlite)")  # 有问题
            db_store.push_message(message2push)
        except Exception as e:
            logger.error("log error")
            logger.info(str(e))
            # todo 有空优化

        actual_user_name = msg["ActualNickName"]
        # for at id
        localuser_tool = LocalUserTool()

        # feature : at_id todo:插件化
        at_id = localuser_tool.get_at_id(actual_user_name)
        if not at_id:
            at_id = localuser_tool.set_at_id(actual_user_name)
        # 改造消息对象,使其多一个at_id
        msg["at_id"] = at_id
        match_at_message = re.match(
            r'at *(?P<message_at_id>\d+) *(?P<message_text>.*)', msg["Text"])
        if match_at_message:
            # 如果是at意图的消息
            groupdict = match_at_message.groupdict()
            message_at_id = groupdict.get("message_at_id")
            message_text = groupdict.get("message_text")
            actual_user_name = localuser_tool.get_actual_user_name(
                int(message_at_id))

            for group in target_groups:
                now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                logger.info((now, group._group_name, msg[
                            'ActualNickName'], msg["Text"]))
                message = u'@{} \n{}-at_id:{} 发言 :\n{}'.format(
                    actual_user_name, msg['ActualNickName'], msg['at_id'], message_text)
                #message = u'@{}\u2005\n : {}'.format(actual_user_name,message_text)
                itchat.send(message, group._group_id)
        else:
            # 如果不是at消息:即普通文本消息
            # bot回复论坛消息
            # handle_text_msg对消息做个分类,只做分析,handle_text_msg不主动发送消息,此处可嵌入插件
            response = handle_text_msg(msg).get("response")
            if response:
                # 只回复本群
                itchat.send(response, src_group._group_id)
            else:
                # 推送到其他群
                for group in target_groups:
                    now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    logger.info((now, group._group_name, msg[
                                'ActualNickName'], msg["Text"]))
                    # if group._group_id:
                    message = '{}-at_id:{} 发言 :\n{}'.format(
                        msg['ActualNickName'], msg['at_id'], msg['Text'])
                    itchat.send(message, group._group_id)  # 采用异步
    # 之后的消息统一转发
    if msg["Type"] == 'Picture':
            # todo:上传到云端
        msg['Text'](msg['FileName'])  # 下载
        for group in target_groups:
            itchat.send_image(msg['FileName'], group._group_id)

    if msg['Type'] == 'Sharing':
        # 同样作为普通消息存入log
        share_message = "@{}分享\n{} {}".format(
            msg['ActualNickName'], msg["Url"].replace("amp;", ""), msg["Text"])
        for group in target_groups:
            itchat.send_msg(share_message, group._group_id)
def forward_message(msg, src_group, target_groups):
    '''按类型发消息'''
    if msg["Type"] == 'Text':
        '''
        print(itchat.get_friends())
        # 消息入口
        logger.info(msg)
        username = msg["ActualUserName"] # 发言用户id 群id:FromUserName
        user = itchat.search_friends(userName=username)
        '''
        logger.info("forward_message begin")  # log
        logger.info(("forward message : ", msg))  # log
        # 跨群@ , 至于私聊 可以截图发微信号
        #把用户都存下,多给msg一个属性 at_id
        # logger.info((now, group._group_name, msg['ActualNickName'], msg["Text"]))
        # 存入云端
        message2push = {}
        message2push["group_name"] = src_group._group_name
        message2push["content"] = msg["Text"]
        message2push["group_user_name"] = msg["ActualNickName"]
        try:
            # 头像
            #user_head_img = itchat.get_head_img(userName=msg["ActualUserName"],chatroomUserName=src_group._group_id,picDir="/tmp/wechat_user/{}".format(img_id)) #存储到本地
            # todo:第一层缓存,获取头像之前,先检查本轮对话中 msg["ActualUserName"] 是否被记录在本地数据库,免去向微信请求
            user_img = UserImgCache()
            group_user_id = msg["ActualUserName"]
            url_get_with_user_id = user_img.get_user_img_with_user_id(
                group_user_id)  #第一层缓存
            if url_get_with_user_id:
                message2push["user_img"] = url_get_with_user_id
                logger.info(
                    ("url_get_with_user_id: " + message2push["user_img"]))
            else:
                #重新登录user id 变了,但是img md5还有效
                img_data = itchat.get_head_img(
                    userName=msg["ActualUserName"],
                    chatroomUserName=src_group._group_id)  #.getvalue()#前头是str
                img_md5 = hashlib.md5(buffer(img_data)).hexdigest()
                url_get_with_img_md5 = user_img.get_user_img_with_img_md5(
                    img_md5)
                if url_get_with_img_md5:
                    message2push["user_img"] = url_get_with_img_md5
                    logger.info(
                        ("url_get_with_img_md5: " + message2push["user_img"]))
                else:
                    # 如果两级缓存都没有命中
                    url_with_uploading_img = user_img.set_user_img(
                        group_user_id, buffer(img_data))
                    message2push["user_img"] = url_with_uploading_img
                    logger.info(("url_with_uploading_img: " +
                                 message2push["user_img"]))
        except Exception as e:
            logger.info("can not get user head img")
            logger.info(str(e))

        try:
            logger.info("ready to push message to cloud")
            if USE_LEANCLOUD:
                push_message(message2push)
            logger.info("ready to push message to local db(sqlite)")
            logger.info(message2push)
            db_store.push_message(message2push)
        #except e:
        except Exception as e:
            logger.info("can not push message")
            logger.info(str(e))
            # 这样不好 ,有空优化

        actual_user_name = msg["ActualNickName"]
        # for at id
        localuser_tool = LocalUserTool()
        at_id = localuser_tool.get_at_id(actual_user_name)
        if not at_id:
            at_id = localuser_tool.set_at_id(actual_user_name)
        # 改造消息属性,使其多一个at_id
        msg["at_id"] = at_id
        match_at_message = re.match(
            r'at *(?P<message_at_id>\d+) *(?P<message_text>.*)', msg["Text"])
        if match_at_message:
            # at 的消息
            groupdict = match_at_message.groupdict()
            message_at_id = groupdict.get("message_at_id")
            message_text = groupdict.get("message_text")
            actual_user_name = localuser_tool.get_actual_user_name(
                int(message_at_id))

            for group in target_groups:
                now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                logger.info((now, group._group_name, msg['ActualNickName'],
                             msg["Text"]))
                message = u'@{} \n{}-at_id:{} 发言 :\n{}'.format(
                    actual_user_name, msg['ActualNickName'], msg['at_id'],
                    message_text)
                #message = u'@{}\u2005\n : {}'.format(actual_user_name,message_text)
                itchat.send(message, group._group_id)
        else:
            #普通文本消息
            # bot回复论坛消息
            response = handle_text_msg(msg).get("response")  #来源小组不一样,回复
            if response:
                itchat.send(response, src_group._group_id)
            # 推送到其他群
            else:
                #如果是网往论坛的则不转发
                for group in target_groups:
                    now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    logger.info((now, group._group_name, msg['ActualNickName'],
                                 msg["Text"]))
                    #if group._group_id:
                    message = '{}-at_id:{} 发言 :\n{}'.format(
                        msg['ActualNickName'], msg['at_id'], msg['Text'])
                    itchat.send(message, group._group_id)  # 采用异步

    if msg["Type"] == 'Picture':
        # todo:上传到云端
        msg['Text'](msg['FileName'])  #下载
        for group in target_groups:
            itchat.send_image(msg['FileName'], group._group_id)

    if msg['Type'] == 'Sharing':
        # 同样作为普通消息存入云端
        share_message = "@{}分享\n{} {}".format(msg['ActualNickName'],
                                              msg["Url"].replace("amp;", ""),
                                              msg["Text"])
        for group in target_groups:
            itchat.send_msg(share_message, group._group_id)