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)
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()