Beispiel #1
0
    def on_message(self, unused_channel, basic_deliver, properties, body):
        """Invoked by pika when a message is delivered from RabbitMQ. The
        channel is passed for your convenience. The basic_deliver object that
        is passed in carries the exchange, routing key, delivery tag and
        a redelivered flag for the message. The properties passed in is an
        instance of BasicProperties with the message properties and the body
        is the message that was sent.

        :param pika.channel.Channel unused_channel: The channel object
        :param pika.Spec.Basic.Deliver: basic_deliver method
        :param pika.Spec.BasicProperties: properties
        :param str|unicode body: The message body

        """
        # LOGGER.info('Received message # %s from %s: %s',
        #             basic_deliver.delivery_tag, properties.app_id, body)

        try:
            receive = json.loads(body)
            # print("Receving \"{}\"".format(receive.get("message", "")))
            receive["pika_time"] = time.time()
            self_id = receive["self_id"]
            # print("receving message from {}".format(self_id))
            try:
                # get the bot
                bot = QQBot.objects.get(user_id=self_id)
            except QQBot.DoesNotExist as e:
                LOGGER.error("bot {} does not exsit.".format(self_id))
                raise e
            config = json.load(open(CONFIG_PATH, encoding="utf-8"))
            already_reply = False

            # heart beat
            if (receive["post_type"] == "meta_event"
                    and receive["meta_event_type"] == "heartbeat"):
                LOGGER.debug("bot:{} Event heartbeat at time:{}".format(
                    self_id, int(time.time())))
                call_api(bot,
                         "get_status", {},
                         "get_status:{}".format(self_id),
                         post_type=receive.get("reply_api_type", "websocket"))

            if receive["post_type"] == "message":
                user_id = receive["user_id"]
                # don't reply another bot
                if QQBot.objects.filter(user_id=user_id).exists():
                    raise PikaException("{} reply from another bot:{}".format(
                        receive["self_id"], user_id))
                (user, created) = QQUser.objects.get_or_create(user_id=user_id)
                if 0 < time.time() < user.ban_till:
                    raise PikaException("User {} get banned till {}".format(
                        user_id, user.ban_till))

                # replace alter commands
                for (alter_command,
                     command) in handlers.alter_commands.items():
                    if receive["message"].find(alter_command) == 0:
                        receive["message"] = receive["message"].replace(
                            alter_command, command, 1)
                        break

                group_id = None
                group = None
                group_created = False
                discuss_id = None
                # Group Control Func
                if receive["message"].find("\\") == 0:
                    receive["message"] = receive["message"].replace(
                        "\\", "/", 1)
                if receive["message_type"] == "discuss":
                    discuss_id = receive["discuss_id"]
                if receive["message_type"] == "group":
                    group_id = receive["group_id"]
                    (group, group_created) = QQGroup.objects.get_or_create(
                        group_id=group_id)
                    # self-ban in group
                    if int(time.time()) < group.ban_till:
                        raise PikaException("{} banned by group:{}".format(
                            self_id, group_id))
                        # LOGGER.info("{} banned by group:{}".format(self_id, group_id))
                        # self.acknowledge_message(basic_deliver.delivery_tag)
                        # return
                    group_commands = json.loads(group.commands)

                    try:
                        member_list = json.loads(group.member_list)
                        if group_created or not member_list:
                            update_group_member_list(bot,
                                                     group_id,
                                                     post_type=receive.get(
                                                         "reply_api_type",
                                                         "websocket"))
                    except json.decoder.JSONDecodeError:
                        member_list = []

                    if receive["message"].find("/group_help") == 0:
                        msg = ("" if member_list else
                               "本群成员信息获取失败,请尝试重启酷Q并使用/update_group刷新群成员信息\n")
                        for (k, v) in handlers.group_commands.items():
                            command_enable = True
                            if group and group_commands:
                                command_enable = group_commands.get(
                                    k, "enable") == "enable"
                            if command_enable:
                                msg += "{}: {}\n".format(k, v)
                        msg = msg.strip()
                        send_message(bot,
                                     receive["message_type"],
                                     discuss_id or group_id or user_id,
                                     msg,
                                     post_type=receive.get(
                                         "reply_api_type", "websocket"),
                                     chatId=receive.get("chatId", ""))
                    else:
                        if receive["message"].find("/update_group") == 0:
                            update_group_member_list(bot,
                                                     group_id,
                                                     post_type=receive.get(
                                                         "reply_api_type",
                                                         "websocket"))
                        # get sender's user_info
                        user_info = receive.get("sender")
                        user_info = (user_info if
                                     (user_info and
                                      ("role" in user_info.keys())) else None)
                        if member_list and not user_info:
                            for item in member_list:
                                if str(item["user_id"]) == str(user_id):
                                    user_info = item
                                    break
                        if not user_info:
                            if receive.get("reply_api_type",
                                           "websocket") == "wechat":
                                user_info = {
                                    "user_id": receive["user_id"],
                                    "nickname": receive["data"]["contactName"],
                                    "role": "member",
                                }
                                if receive["user_id"] not in list(
                                        map(lambda x: x["user_id"],
                                            member_list)):
                                    member_list.append(user_info)
                                    group.member_list = json.dumps(member_list)
                                    group.save(update_fields=["member_list"])
                            else:
                                raise PikaException(
                                    "No user info for user_id:{} in group:{}".
                                    format(user_id, group_id))
                            # LOGGER.error("No user info for user_id:{} in group:{}".format(user_id, group_id))
                            # self.acknowledge_message(basic_deliver.delivery_tag)
                            # return

                        group_command_keys = sorted(
                            handlers.group_commands.keys(),
                            key=lambda x: -len(x))
                        for command_key in group_command_keys:
                            if receive["message"].find(command_key) == 0:
                                if (receive["message_type"] == "group"
                                        and group_commands):
                                    if (command_key in group_commands.keys()
                                            and group_commands[command_key]
                                            == "disable"):
                                        continue
                                if not group.registered and command_key != "/group":
                                    msg = "本群%s未在数据库注册,请群主使用/register_group命令注册" % (
                                        group_id)
                                    send_message(bot,
                                                 "group",
                                                 group_id,
                                                 msg,
                                                 post_type=receive.get(
                                                     "reply_api_type",
                                                     "websocket"),
                                                 chatId=receive.get(
                                                     "chatId", ""))
                                    break
                                else:
                                    handle_method = getattr(
                                        handlers,
                                        "QQGroupCommand_{}".format(
                                            command_key.replace("/", "", 1)),
                                    )
                                    action_list = handle_method(
                                        receive=receive,
                                        global_config=config,
                                        bot=bot,
                                        user_info=user_info,
                                        member_list=member_list,
                                        group=group,
                                        commands=handlers.commands,
                                        group_commands=handlers.group_commands,
                                        alter_commands=handlers.alter_commands,
                                    )
                                    if USE_GRAFANA:
                                        command_log = CommandLog(
                                            time=int(time.time()),
                                            bot_id=str(self_id),
                                            user_id=str(user_id),
                                            group_id=str(group_id),
                                            command=str(command_key),
                                            message=receive["message"])
                                        command_log.save()
                                    for action in action_list:
                                        call_api(
                                            bot,
                                            action["action"],
                                            action["params"],
                                            echo=action["echo"],
                                            post_type=receive.get(
                                                "reply_api_type", "websocket"),
                                            chatId=receive.get("chatId", ""),
                                        )
                                        already_reply = True
                                    if already_reply:
                                        break

                if receive["message"].find("/help") == 0:
                    msg = ""
                    for (k, v) in handlers.commands.items():
                        command_enable = True
                        if group and group_commands:
                            command_enable = group_commands.get(
                                k, "enable") == "enable"
                        if command_enable:
                            msg += "{}: {}\n".format(k, v)
                    msg += "具体介绍详见Wiki使用手册: {}\n".format(
                        "https://github.com/Bluefissure/FFXIVBOT/wiki/")
                    msg = msg.strip()
                    send_message(bot,
                                 receive["message_type"],
                                 group_id or user_id,
                                 msg,
                                 post_type=receive.get("reply_api_type",
                                                       "websocket"),
                                 chatId=receive.get("chatId", ""))

                if receive["message"].find("/ping") == 0:
                    msg = ""
                    if "detail" in receive["message"]:
                        msg += "[CQ:at,qq={}]\ncoolq->server: {:.2f}s\nserver->rabbitmq: {:.2f}s\nhandle init: {:.2f}s".format(
                            receive["user_id"],
                            receive["consumer_time"] - receive["time"],
                            receive["pika_time"] - receive["consumer_time"],
                            time.time() - receive["pika_time"],
                        )
                    else:
                        msg += "[CQ:at,qq={}] {:.2f}s".format(
                            receive["user_id"],
                            time.time() - receive["time"])
                    msg = msg.strip()
                    LOGGER.info("{} calling command: {}".format(
                        user_id, "/ping"))
                    print(("{} calling command: {}".format(user_id, "/ping")))
                    send_message(bot,
                                 receive["message_type"],
                                 discuss_id or group_id or user_id,
                                 msg,
                                 post_type=receive.get("reply_api_type",
                                                       "websocket"),
                                 chatId=receive.get("chatId", ""))

                command_keys = sorted(handlers.commands.keys(),
                                      key=lambda x: -len(x))
                for command_key in command_keys:
                    if receive["message"].find(command_key) == 0:
                        if receive[
                                "message_type"] == "group" and group_commands:
                            if (command_key in group_commands.keys() and
                                    group_commands[command_key] == "disable"):
                                continue
                        handle_method = getattr(
                            handlers,
                            "QQCommand_{}".format(
                                command_key.replace("/", "", 1)),
                        )
                        action_list = handle_method(receive=receive,
                                                    global_config=config,
                                                    bot=bot)
                        if USE_GRAFANA:
                            command_log = CommandLog(
                                time=int(time.time()),
                                bot_id=str(self_id),
                                user_id=str(user_id),
                                group_id="private"
                                if receive["message_type"] != "group" else
                                str(group_id),
                                command=str(command_key),
                                message=receive["message"])
                            command_log.save()
                        for action in action_list:
                            call_api(
                                bot,
                                action["action"],
                                action["params"],
                                echo=action["echo"],
                                post_type=receive.get("reply_api_type",
                                                      "websocket"),
                                chatId=receive.get("chatId", ""),
                            )
                            already_reply = True
                        break

                # handling chat
                if receive["message_type"] == "group":
                    if not already_reply:
                        action_list = handlers.QQGroupChat(
                            receive=receive,
                            global_config=config,
                            bot=bot,
                            user_info=user_info,
                            member_list=member_list,
                            group=group,
                            commands=handlers.commands,
                            alter_commands=handlers.alter_commands,
                        )
                        # need fix: disable chat logging for a while
                        # if USE_GRAFANA:
                        #     command_log = CommandLog(
                        #         time = int(time.time()),
                        #         bot_id = str(self_id),
                        #         user_id = str(user_id),
                        #         group_id = "private" if receive["message_type"] != "group" else str(group_id),
                        #         command = "/chat",
                        #         message = receive["message"]
                        #     )
                        #     command_log.save()
                        for action in action_list:
                            call_api(
                                bot,
                                action["action"],
                                action["params"],
                                echo=action["echo"],
                                post_type=receive.get("reply_api_type",
                                                      "websocket"),
                                chatId=receive.get("chatId", ""),
                            )

            CONFIG_GROUP_ID = config["CONFIG_GROUP_ID"]
            if receive["post_type"] == "request":
                if receive["request_type"] == "friend":  # Add Friend
                    qq = receive["user_id"]
                    flag = receive["flag"]
                    if bot.auto_accept_friend:
                        reply_data = {"flag": flag, "approve": True}
                        call_api(bot,
                                 "set_friend_add_request",
                                 reply_data,
                                 post_type=receive.get("reply_api_type",
                                                       "websocket"))
                if (receive["request_type"] == "group"
                        and receive["sub_type"] == "invite"):  # Invite Group
                    flag = receive["flag"]
                    if bot.auto_accept_invite:
                        reply_data = {
                            "flag": flag,
                            "sub_type": "invite",
                            "approve": True,
                        }
                        call_api(bot,
                                 "set_group_add_request",
                                 reply_data,
                                 post_type=receive.get("reply_api_type",
                                                       "websocket"))
                if (receive["request_type"] == "group"
                        and receive["sub_type"] == "add"
                        and str(receive["group_id"])
                        == CONFIG_GROUP_ID):  # Add Group
                    flag = receive["flag"]
                    user_id = receive["user_id"]
                    qs = QQBot.objects.filter(owner_id=user_id)
                    if qs.count() > 0:
                        reply_data = {
                            "flag": flag,
                            "sub_type": "add",
                            "approve": True
                        }
                        call_api(bot,
                                 "set_group_add_request",
                                 reply_data,
                                 post_type=receive.get("reply_api_type",
                                                       "websocket"))
                        reply_data = {
                            "group_id": CONFIG_GROUP_ID,
                            "user_id": user_id,
                            "special_title": "饲养员",
                        }
                        call_api(bot,
                                 "set_group_special_title",
                                 reply_data,
                                 post_type=receive.get("reply_api_type",
                                                       "websocket"))
            if receive["post_type"] == "event":
                if receive["event"] == "group_increase":
                    group_id = receive["group_id"]
                    user_id = receive["user_id"]
                    try:
                        group = QQGroup.objects.get(group_id=group_id)
                        msg = group.welcome_msg.strip()
                        if msg != "":
                            msg = "[CQ:at,qq=%s]" % (user_id) + msg
                            send_message(bot,
                                         "group",
                                         group_id,
                                         msg,
                                         post_type=receive.get(
                                             "reply_api_type", "websocket"),
                                         chatId=receive.get("chatId", ""))
                    except Exception as e:
                        traceback.print_exc()
            # print(" [x] Received %r" % body)
        except PikaException as pe:
            traceback.print_exc()
            LOGGER.error(pe)
        except Exception as e:
            traceback.print_exc()
            LOGGER.error(e)

        self.acknowledge_message(basic_deliver.delivery_tag)
Beispiel #2
0
    def receive(self, text_data):
        # print("Event Channel receive from {} by channel:{}".format(self.bot.user_id,self.bot.event_channel_name))
        try:
            self.bot = QQBot.objects.select_for_update().get(user_id=self.bot_user_id)
        except QQBot.DoesNotExist:
            logging.error("QQBot.DoesNotExist:{}".format(self.bot_user_id))
            return
        self.bot.event_time = int(time.time())
        # if(int(time.time()) > self.bot.api_time+60):
        #     self.call_api("get_status",{},"get_status:{}".format(self.bot_user_id))
        self.bot.event_channel_name = self.channel_name
        self.config = json.load(open(CONFIG_PATH,encoding="utf-8"))

        try:
            receive = json.loads(text_data)
            if(receive["post_type"] == "meta_event" and receive["meta_event_type"] == "heartbeat"):
                logging.debug("bot:{} Event heartbeat at time:{}".format(self.bot.user_id, int(time.time())))
                self.call_api("get_status",{},"get_status:{}".format(self.bot_user_id))

            if (receive["post_type"] == "message"):
                # Self-ban in group
                user_id = receive["user_id"]
                group_id = None
                group = None
                if (receive["message_type"]=="group"):
                    group_id = receive["group_id"]
                    group_list = QQGroup.objects.filter(group_id=group_id)
                    if len(group_list)>0:
                        group = group_list[0]
                        if(int(time.time())<group.ban_till):
                            return
                        group_bots = json.loads(group.bots)
                        if(user_id in group_bots):
                            return
                        group_commands = json.loads(group.commands)



                if (receive["message"].find('/help')==0):
                    msg =  ""
                    for (k, v) in handlers.commands.items():
                        msg += "{} : {}\n".format(k,v)
                    msg = msg.strip()
                    self.send_message(receive["message_type"], group_id or user_id, msg)

                if (receive["message"].find('/ping')==0):
                    msg =  ""
                    msg += "[CQ:at,qq={}] {:.2f}s".format(receive["user_id"], time.time()-receive["time"])
                    msg = msg.strip()
                    self.send_message(receive["message_type"], group_id or user_id, msg)

                for (alter_command, command) in handlers.alter_commands.items():
                    if(receive["message"].find(alter_command)==0):
                        receive["message"] = receive["message"].replace(alter_command, command, 1)

                command_keys = sorted(handlers.commands.keys())
                command_keys.reverse()
                for command_key in command_keys:
                    if(receive["message"].find(command_key)==0):
                        if receive["message_type"]=="group" and group_commands:
                            if command_key in group_commands.keys() and group_commands[command_key]=="disable":
                                continue
                        handle_method = getattr(handlers,"QQCommand_{}".format(command_key.replace("/","",1)))
                        action_list = handle_method(receive=receive, global_config=self.config, bot=self.bot)
                        # if(len(json.loads(self.bot.disconnections))>100):
                        #     action_list = self.intercept_action(action_list)
                        for action in action_list:
                            self.call_api(action["action"],action["params"],echo=action["echo"])
                        break

                #Group Control Func
                if (receive["message_type"]=="group"):
                    (group, group_created) = QQGroup.objects.get_or_create(group_id=group_id)
                    group_commands = json.loads(group.commands)
                    try:
                        member_list = json.loads(group.member_list)
                        if group_created or not member_list:
                            self.update_group_member_list(group_id)
                            time.sleep(1)
                            group.refresh_from_db()
                            member_list = json.loads(group.member_list)
                    except:
                        self.update_group_member_list(group_id)
                        member_list = []
                        
                    
                    if (receive["message"].find('/group_help')==0):
                        msg =  "" if member_list else "本群成员信息获取失败,请尝试重启酷Q并使用/update_group刷新群成员信息"
                        for (k, v) in handlers.group_commands.items():
                            msg += "{} : {}\n".format(k,v)
                        msg = msg.strip()
                        self.send_message(receive["message_type"], group_id or user_id, msg)
                    else:
                        if(receive["message"].find('/update_group')==0 or not member_list):
                            self.update_group_member_list(group_id)
                        #get sender's user_info
                        if not group:
                            logging.warning("No group:{}".format(group_id))
                            return
                        if not member_list:
                            logging.warning("No member info for group:{}".format(group_id))
                            return
                        user_info = None
                        for item in member_list:
                            if(int(item["user_id"])==int(user_id)):
                                user_info = item
                                break
                        if not user_info:
                            logging.debug("No user info for user_id:{} in group:{}".format(user_id,group_id))
                            return

                        group_command_keys = sorted(handlers.group_commands.keys())
                        group_command_keys.reverse()
                        for command_key in group_command_keys:
                            if(receive["message"].find(command_key)==0):
                                if receive["message_type"]=="group" and group_commands:
                                    if command_key in group_commands.keys() and group_commands[command_key]=="disable":
                                        continue
                                if not group.registered and command_key!="/group":
                                    msg = "本群%s未在数据库注册,请群主使用/register_group命令注册"%(group_id)
                                    self.send_message("group", group_id, msg)
                                    break
                                else:
                                    handle_method = getattr(handlers,"QQGroupCommand_{}".format(command_key.replace("/","",1)))
                                    action_list = handle_method(receive = receive, 
                                                                global_config = self.config, 
                                                                bot = self.bot, 
                                                                user_info = user_info, 
                                                                member_list = member_list, 
                                                                group = group,
                                                                commands = handlers.commands,
                                                                group_commands = handlers.group_commands,
                                                                alter_commands = handlers.alter_commands,
                                                                )
                                    # self.send_message(receive["message_type"], group_id or user_id, "獭獭维护中")
                                    # if(len(json.loads(self.bot.disconnections))>100):
                                    #     action_list = self.intercept_action(action_list)
                                    for action in action_list:
                                        self.call_api(action["action"],action["params"],echo=action["echo"])
                                    break

                    action_list = handlers.QQGroupChat(receive = receive, 
                                                        global_config = self.config, 
                                                        bot = self.bot, 
                                                        user_info = user_info, 
                                                        member_list = member_list, 
                                                        group = group,
                                                        commands = handlers.commands,
                                                        alter_commands = handlers.alter_commands,
                                                        )
                    for action in action_list:
                        self.call_api(action["action"],action["params"],echo=action["echo"])
            


            CONFIG_GROUP_ID = self.config["CONFIG_GROUP_ID"]
            if (receive["post_type"] == "request"):
                if (receive["request_type"] == "friend"):   #Add Friend
                    qq = receive["user_id"]
                    flag = receive["flag"]
                    if(self.bot.auto_accept_friend):
                        reply_data = {"flag":flag, "approve": True}
                        self.call_api("set_friend_add_request",reply_data)
                if (receive["request_type"] == "group" and receive["sub_type"] == "invite"):    #Invite Group
                    flag = receive["flag"]
                    if(self.bot.auto_accept_invite):
                        reply_data = {"flag":flag, "sub_type":"invite", "approve": True}
                        self.call_api("set_group_add_request",reply_data)
                if (receive["request_type"] == "group" and receive["sub_type"] == "add" and str(receive["group_id"])==CONFIG_GROUP_ID):    #Add Group
                    flag = receive["flag"]
                    user_id = receive["user_id"]
                    qs = QQBot.objects.filter(owner_id=user_id)
                    if(len(qs)>0):
                        reply_data = {"flag":flag, "sub_type":"add", "approve": True}
                        self.call_api("set_group_add_request",reply_data)
                        time.sleep(1)
                        reply_data = {"group_id":CONFIG_GROUP_ID, "user_id":user_id, "special_title":"饲养员"}
                        self.call_api("set_group_special_title", reply_data)
            if (receive["post_type"] == "event"):
                if (receive["event"] == "group_increase"):
                    group_id = receive["group_id"]
                    user_id = receive["user_id"]
                    group_list = QQGroup.objects.filter(group_id=group_id)
                    if len(group_list)>0:
                        group = group_list[0]
                        msg = group.welcome_msg.strip()
                        if(msg!=""):
                            msg = "[CQ:at,qq=%s]"%(user_id)+msg
                            self.send_message("group", group_id, msg)
        except Exception as e:
            traceback.print_exc() 
        self.bot.save()