async def on_message(self, msg: Message): """ listen for message event """ from_contact = msg.talker() text = msg.text() room = msg.room() # 不处理群消息 if room is None: if text == 'hi' or text == '你好': conversation = from_contact await conversation.ready() await conversation.say('这是自动回复:机器人目前的功能有:\n1. 收到"ding",自动回复"dong dong dong"\n2. 收到"图片",自动回复一张图片') if text == 'ding': conversation = from_contact await conversation.ready() await conversation.say('这是自动回复:dong dong dong') if text == '图片': conversation = from_contact # 从网络上加载图片到file_box img_url = 'https://images.unsplash.com/photo-1470770903676-69b98201ea1c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1500&q=80' file_box = FileBox.from_url(img_url, name='xx.jpg') await conversation.ready() await conversation.say('这是自动回复:') await conversation.say(file_box)
async def message_file(self, message_id: str) -> FileBox: """ extract file from message :param message_id: :return: """ response = await self.puppet_stub.message_file(id=message_id) file_box = FileBox.from_json(response.filebox) return file_box
async def run(): """async run method""" img_url = 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy' \ '/it/u=1257042014,3164688936&fm=26&gp=0.jpg' plugin = AutoReplyPlugin(options=AutoReplyOptions(rules=[ AutoReplyRule(keyword='ding', reply_content='dong'), AutoReplyRule(keyword='七龙珠', reply_content='七龙珠'), AutoReplyRule(keyword='七龙珠', reply_content=FileBox.from_url(img_url, name='python.png')), AutoReplyRule(keyword='wechaty-icon', reply_content=FileBox.from_url(img_url, name='python.png')) ], matchers=[ ContactMatcher('秋客'), ])) bot = Wechaty().use(plugin) await bot.start()
def qr_code_for_chatie() -> FileBox: """ create QRcode for chatie :return: """ # const CHATIE_OFFICIAL_ACCOUNT_QRCODE = # 'http://weixin.qq.com/r/qymXj7DEO_1ErfTs93y5' chatie_official_account_qr_code: str = \ 'http://weixin.qq.com/r/qymXj7DEO_1ErfTs93y5' return FileBox.from_qr_code(chatie_official_account_qr_code)
async def message_file(self, message_id: str) -> FileBox: """get the file-box from message instance save the file-box data in message_payload.text field to avoid creating a new structure to support this feature """ message_payload = self.mocker.environment.get_message_payload( message_id=message_id ) return FileBox.from_json(message_payload.text)
async def on_message(self, msg: Message): if msg.is_self(): # for self testing if msg.type() == MessageType.MESSAGE_TYPE_IMAGE or msg.type( ) == MessageType.MESSAGE_TYPE_EMOTICON: st_time = time.time() try: ret_json = await self.msg_handler(msg) except KeyError as e: # echoing meme image have no keys print(str(e)) return except (requests.exceptions.ConnectionError or requests.exceptions.ConnectTimeout) as e: await msg.say('访问后端出错:' + str(e)) return # example returning json: {'img_name': '/001/001.jpg', 'md5': 'ff7bd2b664bf65962a924912bfd17507'} if ret_json['md5'] in self.cache_dict: # hit cache ret_path: str = self.cache_dict[ret_json['md5']] if 'log' in ret_json: ret_json['log'] += '\n回复图片命中缓存!' else: ret_img = self.s.get( url=self.config_dict['backend']['backend_static_url'] + ret_json['img_name']) if not str(ret_img.status_code).startswith( '2'): # not 2XX response code raise FileNotFoundError( "Can't get img from URL {}, with HTTP status code {}" .format( self.config_dict['backend'] ['backend_static_url'] + ret_json['img_name'], str(ret_img.status_code))) ret_path = os.path.join( self.config_dict['general']['image_temp_dir'], str(uuid.uuid4()) + os.path.extsep + ret_json['img_name'].split('.')[-1]) with open(ret_path, 'wb') as f: f.write(ret_img.content) self.cache_dict[ret_json['md5']] = ret_path ret_json['log'] += '\n前后端交互耗时:%.2fs' % (time.time() - st_time) if self.debug and 'log' in ret_json: await msg.say(ret_json['log']) with open(ret_path, 'rb') as f: content: str = base64.b64encode(f.read()) ret_img = FileBox.from_base64( name=os.path.basename(ret_path), base64=content) # file_box = FileBox.from_url( # 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/' # 'u=1116676390,2305043183&fm=26&gp=0.jpg', # name='ding-dong.jpg') # await msg.say(file_box) # ret_img = FileBox.from_file(ret_path) await msg.say(ret_img)
async def contact_avatar(self, contact_id: str, file_box: Optional[FileBox] = None) -> FileBox: """ get/set contact avatar :param contact_id: :param file_box: :return: """ response = await self.puppet_stub.contact_avatar( id=contact_id, filebox=file_box) return FileBox.from_json(response.filebox)
async def message_send_file(self, conversation_id: str, file: FileBox) -> str: """ send file message :param conversation_id: :param file: :return: """ response = await self.puppet_stub.message_send_file( conversation_id=conversation_id, filebox=file.to_json_str()) return response.id
async def contact_avatar(self, contact_id: str, file_box: Optional[FileBox] = None) -> FileBox: """get the contact avatar""" contact_payload = self.mocker.environment.\ get_contact_payload(contact_id) if not file_box: return FileBox.from_base64( contact_payload.avatar, name=f'{contact_payload.name}.png' ) contact_payload.avatar = file_box.base64 self.mocker.environment.update_contact_payload(contact_payload)
async def contact_avatar(self, contact_id: str, file_box: Optional[FileBox] = None) -> FileBox: """ get/set contact avatar :param contact_id: :param file_box: :return: """ if self.puppet_stub is None: raise Exception('puppet_stub should not be none') response = await self.puppet_stub.contact_avatar( id=contact_id, filebox=file_box) return FileBox.from_json(response.filebox)
async def message_send_file(self, conversation_id: str, file: FileBox) -> str: """ send file message :param conversation_id: :param file: :return: """ if self.puppet_stub is None: raise Exception('puppet_stub should not be none') response = await self.puppet_stub.message_send_file( conversation_id=conversation_id, filebox=file.to_json_str()) return response.id
async def message_emoticon(self, message: str) -> FileBox: """ emoticon from message :param message: :return: """ DOMTree = xml.dom.minidom.parseString(message) collection = DOMTree.documentElement file_box = FileBox.from_url( url=collection.getElementsByTagName('emoji')[0].getAttribute('cdnurl'), name=collection.getElementsByTagName('emoji')[0].getAttribute('md5') + '.gif' ) return file_box
async def on_message(self, msg: Message): """ listen for message event """ from_contact = msg.talker() text = msg.text() room = msg.room() if text == 'gif': conversation: Union[ Room, Contact] = from_contact if room is None else room await conversation.ready() await conversation.say('dong') file_box = FileBox.from_file('./bot.gif') await conversation.say(file_box)
async def message(msg: Message) -> None: """back on message""" from_contact = msg.talker() text = msg.text() room = msg.room() if text == '#ding': conversation: Union[ Room, Contact] = from_contact if room is None else room await conversation.ready() await conversation.say('dong') file_box = FileBox.from_url( 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/' 'u=1116676390,2305043183&fm=26&gp=0.jpg', name='ding-dong.jpg') await conversation.say(file_box)
async def message_file(self, message_id: str) -> FileBox: """ extract file from message :param message_id: :return: """ if self.puppet_stub is None: raise Exception('puppet_stub should not be none') response = await self.puppet_stub.message_file(id=message_id) json_response = json.loads(response.filebox) if 'base64' not in json_response: raise Exception('file response data structure is not correct') file_box = FileBox.from_base64(json_response['base64'], name=json_response['name']) return file_box
async def room_avatar(self, room_id: str) -> FileBox: """ get room avatar :param room_id: :return: """ room_avatar_response = await self.puppet_stub.room_avatar(id=room_id) file_box_data = json.loads(room_avatar_response.filebox) if 'remoteUrl' not in file_box_data: raise WechatyPuppetPayloadError('invalid room avatar response') file_box = FileBox.from_url(url=file_box_data['remoteUrl'], name=f'avatar-{room_id}.jpeg') return file_box
async def message_file(self, message_id: str) -> FileBox: """ extract file from message :param message_id: :return: """ file_chunk_data: List[bytes] = [] name: str = '' async for stream in self.puppet_stub.message_file_stream(id=message_id): file_chunk_data.append(stream.file_box_chunk.data) if not name and stream.file_box_chunk.name: name = stream.file_box_chunk.name file_stream = reduce(lambda pre, cu: pre + cu, file_chunk_data) file_box = FileBox.from_stream(file_stream, name=name) return file_box
async def message_image(self, message_id: str, image_type: ImageType) -> FileBox: """ get message image data :param message_id: :param image_type: :return: """ if self.puppet_stub is None: raise Exception('puppet_stub should not be none') response = await self.puppet_stub.message_image(id=message_id, type=image_type) if response is None: # TODO -> need to refactor the raised error raise ValueError('response is invalid') json_response = json.loads(response.filebox) return FileBox.from_json(obj=json_response)
async def message_image(self, message_id: str, image_type: ImageType = 3 ) -> FileBox: """ get message image data :param message_id: :param image_type: :return: """ response = await self.puppet_stub.message_image(id=message_id, type=image_type) json_response = json.loads(response.filebox) if 'base64' not in json_response: raise WechatyPuppetGrpcError('image response data structure is not correct') file_box = FileBox.from_base64( json_response['base64'], name=json_response['name'] ) return file_box
async def room_avatar(self, room_id: str) -> FileBox: """ get room avatar :param room_id: :return: """ if self.puppet_stub is None: raise Exception('puppet_stub should not be none') room_avatar_response = await self.puppet_stub.room_avatar(id=room_id) file_box_data = json.loads(room_avatar_response.filebox) if 'remoteUrl' not in file_box_data: raise Exception('invalid room avatar response') file_box = FileBox.from_url(url=file_box_data['remoteUrl'], name=f'avatar-{room_id}.jpeg') return file_box
async def message_image(self, message_id: str, image_type: ImageType = 3 ) -> FileBox: """ get message image data :param message_id: :param image_type: :return: """ file_chunk_data: List[bytes] = [] name: str = '' async for stream in self.puppet_stub.message_image_stream(id=message_id, type=image_type): file_chunk_data.append(stream.file_box_chunk.data) if not name and stream.file_box_chunk.name: name = stream.file_box_chunk.name file_stream = reduce(lambda pre, cu: pre + cu, file_chunk_data) file_box = FileBox.from_stream(file_stream, name=name) return file_box
async def message(msg: Message): """back on message""" from_contact = msg.talker() text = msg.text() room = msg.room() conversation: Union[Room, Contact] = from_contact if room is None else room global chat_friend if "#关闭闲聊" == text: try: chat_friend.remove(conversation) except Exception as e: return await conversation.ready() await conversation.say('好的,有需要随时叫我') return elif "#开启闲聊" == text: chat_friend.append(conversation) await conversation.ready() await conversation.say('闲聊功能开启成功!现在你可以和我聊天啦!') return if conversation in chat_friend: data = TencentAI(text) await conversation.ready() await conversation.say(data) return if text == '#ding': await conversation.ready() await conversation.say('dong') file_box = FileBox.from_url( 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/' 'u=1116676390,2305043183&fm=26&gp=0.jpg', name='ding-dong.jpg') await conversation.say(file_box)
async def on_message(self, msg: Message): from_contact = msg.talker() if msg.is_self(): # for self testing if msg.type( ) == MessageType.MESSAGE_TYPE_IMAGE or MessageType.MESSAGE_TYPE_EMOTICON: ret_json = await self.msg_handler(msg) # example returning json: {'img_name': '/001/001.jpg', 'md5': 'ff7bd2b664bf65962a924912bfd17507'} if ret_json['md5'] in self.cache_dict: # hit cache ret_path = self.cache_dict[ret_json['md5']] if 'log' in ret_json: ret_json['log'] += '\n回复图片命中缓存!' else: ret_img = self.s.get(url=config.backend_static_url + ret_json['img_name']) if not str(ret_img.status_code).startswith( '2'): # not 2XX response code raise FileNotFoundError( "Can't get img from URL {}, with HTTP status code {}" .format( config.backend_static_url + ret_json['img_name'], str(ret_img.status_code))) ret_path = os.path.join( config.image_temp_dir, str(uuid.uuid4()) + '.' + ret_json['img_name'].split('.')[-1]) with open(ret_path, 'wb') as f: f.write(ret_img.content) self.cache_dict[ret_json['md5']] = ret_path # ret_path = os.path.join(config.image_temp_dir, '0c4baea3-9792-4d07-8ec0-4fd62afd6117.jpg') if self.debug and 'log' in ret_json: await msg.say(ret_json['log']) with open(ret_path, 'rb') as f: content: str = base64.b64encode(f.read()) ret_img = FileBox.from_base64( name=os.path.basename(ret_path), base64=content) await msg.say(ret_img)
async def on_message(self, msg: Message): """ listen for message event """ from_contact = msg.talker() text = msg.text() type = msg.type() room = msg.room() # 不处理群消息 if room is None: # 识别主人 if text == '你好我的机器人' and self.host_contact is None: # 记录主人的contact self.host_contact = from_contact # 列举所有好友的contact friend_contacts = await self.Contact.find_all() # 列举所有群 self.rooms = await self.Room.find_all() # 过滤一些contact self.friend_contacts = [ contact for contact in friend_contacts if len(contact.contact_id) > 50 ] # 初始化好友权限 self.friend_allow = { contact: [False, None] for contact in self.friend_contacts } # 初始化群聊权限 self.room_allow = {room: [False, None] for room in self.rooms} # 对主人开启权限 self.friend_allow[self.host_contact] = [True, None] # 给主人发消息 conversation = self.host_contact await conversation.ready() await conversation.say( '你好亲爱的主人,机器人目前的功能有:\n1 将图片转换为动漫风格\n2 对好友开启机器人\n3 对好友关闭机器人\n4 对群聊开启机器人\n5 对群聊关闭机器人\n主人回复相应数字即可开启对应功能' ) # 如果是主人的消息 if from_contact == self.host_contact: conversation = self.host_contact await conversation.ready() if self.friend_allow[self.host_contact][1] == 2: # 关闭功能 self.friend_allow[self.host_contact][1] = None # 获取好友备注或昵称 friend_name = text # 记录是否找到好友 is_find = False # 查找好友 for contact in self.friend_contacts: if friend_name == contact.payload.alias or friend_name == contact.name: # 找到 is_find = True # 对好友开启权限 self.friend_allow[contact] = [True, None] # 给好友发消息 conversation_friend = contact await conversation_friend.ready() await conversation_friend.say( '这是自动回复:你好,我是机器人,我的主人是Lovely-Pig,主人对你开启了机器人的功能' ) await conversation_friend.say( '这是自动回复:机器人目前的功能有:\n1 将图片转换为动漫风格\n回复相应数字即可开启对应功能' ) break # 给主人反馈 if is_find: await conversation.say(f'亲爱的主人,已对{friend_name}开启机器人功能') if not is_find: await conversation.say( f'亲爱的主人,{friend_name}不在您的好友列表里,“对好友开启机器人”功能已关闭') if self.friend_allow[self.host_contact][1] == 3: # 关闭功能 self.friend_allow[self.host_contact][1] = None # 获取好友备注或昵称 friend_name = text # 记录是否找到好友 is_find = False # 查找好友 for contact in self.friend_contacts: if friend_name == contact.payload.alias or friend_name == contact.name: # 找到 is_find = True # 对好友关闭权限 self.friend_allow[contact] = [False, None] # 给好友发消息 conversation_friend = contact await conversation_friend.ready() await conversation_friend.say( '这是自动回复:你好,我是机器人,我的主人是Lovely-Pig,主人对你关闭了机器人的功能' ) break # 给主人反馈 if is_find: await conversation.say(f'亲爱的主人,已对{friend_name}关闭机器人功能') if not is_find: await conversation.say( f'亲爱的主人,{friend_name}不在您的好友列表里,“对好友关闭机器人”功能已关闭') if self.friend_allow[self.host_contact][1] == 4: # 关闭功能 self.friend_allow[self.host_contact][1] = None # 获取群聊名称 room_name = text # 记录是否找到群聊 is_find = False # 查找群聊 for room in self.rooms: if room_name == await room.topic(): # 找到 is_find = True # 对群聊开启权限 self.room_allow[room] = [True, None] # 给群聊发消息 conversation_room = room await conversation_room.ready() await conversation_room.say( '这是自动回复:你们好,我是机器人,我的主人是Lovely-Pig,主人对群开启了机器人的功能' ) await conversation_room.say( '这是自动回复:机器人目前的功能有:\n1 将图片转换为动漫风格\n回复相应数字即可开启对应功能' ) break # 给主人反馈 if is_find: await conversation.say(f'亲爱的主人,已对{room_name}开启机器人功能') if not is_find: await conversation.say( f'亲爱的主人,{room_name}不在您的群聊列表里,“对群聊开启机器人”功能已关闭') if self.friend_allow[self.host_contact][1] == 5: # 关闭功能 self.friend_allow[self.host_contact][1] = None # 获取群聊名称 room_name = text # 记录是否找到群聊 is_find = False # 查找群聊 for room in self.rooms: if room_name == await room.topic(): # 找到 is_find = True # 对群聊开启权限 self.room_allow[room] = [False, None] # 给群聊发消息 conversation_room = room await conversation_room.ready() await conversation_room.say( '这是自动回复:你们好,我是机器人,我的主人是Lovely-Pig,主人对群关闭了机器人的功能' ) break # 给主人反馈 if is_find: await conversation.say(f'亲爱的主人,已对{room_name}关闭机器人功能') if not is_find: await conversation.say( f'亲爱的主人,{room_name}不在您的群聊列表里,“对群聊关闭机器人”功能已关闭') if text == '1': self.friend_allow[self.host_contact][1] = 1 await conversation.say('亲爱的主人,您已开启“将图片转换为动漫风格”功能,请发给我一张图片') if text == '2': self.friend_allow[self.host_contact][1] = 2 await conversation.say('亲爱的主人,您已开启“对好友开启机器人”功能,请指明是哪一个好友') if text == '3': self.friend_allow[self.host_contact][1] = 3 await conversation.say('亲爱的主人,您已开启“对好友关闭机器人”功能,请指明是哪一个好友') if text == '4': self.friend_allow[self.host_contact][1] = 4 await conversation.say('亲爱的主人,您已开启“对群聊开启机器人”功能,请指明是哪一个群') if text == '5': self.friend_allow[self.host_contact][1] = 5 await conversation.say('亲爱的主人,您已开启“对群聊关闭机器人”功能,请指明是哪一个群') # 好友的消息 if from_contact in self.friend_contacts and from_contact != self.host_contact: # 如果好友有权限 if self.friend_allow[from_contact][0]: conversation = from_contact await conversation.ready() if text == '1': self.friend_allow[from_contact][1] = 1 await conversation.say( '这是自动回复:你已开启“将图片转换为动漫风格”功能,请发给我一张图片') # 如果消息类型是图片 if type == Message.Type.MESSAGE_TYPE_IMAGE: # 如果有权限 if from_contact in self.friend_contacts and self.friend_allow[ from_contact][0]: # 判断功能 if self.friend_allow[from_contact][1] == 1: # 关闭功能 self.friend_allow[from_contact][1] = None conversation = from_contact await conversation.ready() await conversation.say('这是自动回复:正在飞速处理中...') # 将msg转换为file_box file_box = await msg.to_file_box() # 获取图片名 img_name = file_box.name # 图片保存的路径 img_path = './images/' + img_name # 将图片保存到文件中 await file_box.to_file(file_path=img_path, overwrite=True) # 调用函数,获取图片新路径 img_new_path = img_to_anime(img_name, img_path) # 从文件中加载图片到file_box file_box_new = FileBox.from_file(img_new_path) await conversation.say(file_box_new) # 如果群聊有权限 if room is not None and self.room_allow[room][0]: conversation = room await conversation.ready() if text == '1': self.room_allow[room][1] = 1 await conversation.say('这是自动回复:已开启“将图片转换为动漫风格”功能,请发给我一张图片') # 如果消息类型是图片 if type == Message.Type.MESSAGE_TYPE_IMAGE: # 判断功能 if self.room_allow[room][1] == 1: # 关闭功能 self.room_allow[room][1] = None conversation = room await conversation.ready() await conversation.say('这是自动回复:正在飞速处理中...') # 将msg转换为file_box file_box = await msg.to_file_box() # 获取图片名 img_name = file_box.name # 图片保存的路径 img_path = './images/' + img_name # 将图片保存到文件中 await file_box.to_file(file_path=img_path, overwrite=True) # 调用函数,获取图片新路径 img_new_path = img_to_anime(img_name, img_path) # 从文件中加载图片到file_box file_box_new = FileBox.from_file(img_new_path) await conversation.say(file_box_new)
async def message(msg: Message): """back on message""" from_contact = msg.talker() username = from_contact.name text = msg.text() room = msg.room() conversation: Union[Room, Contact] = from_contact if room is None else room global chat_friend global splitNum global bm global tm if "吐槽" in text or "图槽" in text or "树洞" in text: chat_friend.append(conversation) inputdata = "#str#" + msg.text() print('————text') bot = bm.run(username, inputdata) if bot is not None: # print('bot', bot) # print('bot replys',bot.replys[-1]) # print('bot.replys_index',bot.replys_index) for i in range(bot.replys_index): bot, rdict = tm.run(bot) print('rdict', rdict) if len(list(rdict.keys())) == 0: continue if list(rdict.keys())[0] == "str": print('reply str') conversation: Union[ Room, Contact] = from_contact if room is None else room await conversation.ready() print('rdict[splitNum:]', list(rdict.values())[0]) await conversation.say(list(rdict.values())[0]) elif list(rdict.keys())[0] == "pic" or 'mov': print('reply pic/mov') conversation: Union[ Room, Contact] = from_contact if room is None else room await conversation.ready() try: file_box = FileBox.from_file(list(rdict.values())[0]) except Exception as e: print('file box error', e) file_box = '嗯嗯' await conversation.say(file_box) # await conversation.ready() # await conversation.say('闲聊功能开启成功!现在你可以和我聊天啦!') return if conversation in chat_friend: if username == 'KFu': print('KFu') return if msg.type() == Message.Type.MESSAGE_TYPE_IMAGE: print('__image') image_file_box = await msg.to_file_box() filename = 'p' + str(time.time()) + '.jpg' await image_file_box.to_file(file_path=filename, overwrite=True) inputdata = "#pic#" + filename elif msg.type() == Message.Type.MESSAGE_TYPE_TEXT: print('--text') inputdata = "#str#" + msg.text() bot = bm.run(username, inputdata) if bot is not None: # print('bot', bot) # print('bot replys',bot.replys[-1]) # print('bot.replys_index',bot.replys_index) for i in range(bot.replys_index): bot, rdict = tm.run(bot) print('rdict', rdict) if len(list(rdict.keys())) == 0: continue if list(rdict.keys())[0] == "str": print('reply str') conversation: Union[ Room, Contact] = from_contact if room is None else room await conversation.ready() print('rdict[splitNum:]', list(rdict.values())[0]) await conversation.say(list(rdict.values())[0]) elif list(rdict.keys())[0] == "pic" or 'mov': print('reply pic/mov') conversation: Union[ Room, Contact] = from_contact if room is None else room await conversation.ready() try: file_box = FileBox.from_file( list(rdict.values())[0]) except Exception as e: print('file box error', e) file_box = '嗯嗯' await conversation.say(file_box) # data = TencentAI(text) # await conversation.ready() # await conversation.say(data) return else: print('not in friend') return
async def on_message(self, msg: Message): """ listen for message event """ from_contact = msg.talker() text = msg.text() type = msg.type() room = msg.room() # 不处理群消息 if room is None: if text == 'hi' or text == '你好': conversation = from_contact await conversation.ready() await conversation.say( '这是自动回复:机器人目前的功能有:\n1 收到"ding",自动回复"dong dong dong"\n2 收到"图片",自动回复一张图片\n3 收到两张图片,将第一张图片转换为第二张图片的风格并返回,如需使用此功能,请回复“风格转换”' ) if text == 'ding': conversation = from_contact await conversation.ready() await conversation.say('这是自动回复:dong dong dong') if text == '图片': conversation = from_contact # 从网络上加载图片到file_box img_url = 'https://images.unsplash.com/photo-1470770903676-69b98201ea1c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1500&q=80' file_box = FileBox.from_url(img_url, name='xx.jpg') await conversation.ready() await conversation.say('这是自动回复:') await conversation.say(file_box) if text == '风格转换': self.img[1] = 0 conversation = from_contact await conversation.ready() await conversation.say('这是自动回复:请输入第一张图片') # 如果消息类型是图片 if type == Message.Type.MESSAGE_TYPE_IMAGE: if from_contact == self.friend_contact: self.img[0] = not self.img[0] if self.img[1] == 0: self.img[1] = 1 # 将msg转换为file_box file_box = await msg.to_file_box() # 获取图片名 self.img[2] = file_box.name # 图片保存的路径 self.img[3] = './images/' + self.img[2] # 将图片保存到文件中 await file_box.to_file(file_path=self.img[3], overwrite=True) conversation = from_contact await conversation.ready() await conversation.say('这是自动回复:请输入第二张图片') if self.img[1] == 1 and self.img[0]: self.img[1] = None conversation = from_contact await conversation.ready() await conversation.say('这是自动回复:正在飞速处理中...') # 将msg转换为file_box file_box_art = await msg.to_file_box() # 获取图片名 self.img[4] = file_box_art.name # 图片保存的路径 self.img[5] = './images/' + self.img[4] # 将图片保存到文件中 await file_box_art.to_file(file_path=self.img[5], overwrite=True) # 调用函数,获取图片新路径 img_new_path = img_to_art(self.img[2], self.img[3], self.img[5]) # 从文件中加载图片到file_box file_box_new = FileBox.from_file(img_new_path) await conversation.say(file_box_new)
async def on_message(self, msg: Message): """ listen for message event """ from_contact = msg.talker() text = msg.text() type = msg.type() room = msg.room() # username = from_contact.name if username=='KFu': print('message from myself') return # 不处理群消息 # if room is None: if msg.type() == Message.Type.MESSAGE_TYPE_IMAGE: print('__image') image_file_box = await msg.to_file_box() filename='p'+str(time.time())+'.jpg' await image_file_box.to_file(file_path=filename,overwrite=True) inputdata="#pic#"+filename bot = self.bm.run(username, inputdata) if bot is not None: # print('bot',bot) # print('bot replys',bot.replys[-1]) # print('bot.replys_index',bot.replys_index) for i in range(bot.replys_index): bot, rdict = self.tm.run(bot) print('rdict',rdict) if len(list(rdict.keys()))==0:continue if list(rdict.keys())[0] == "str": print('reply str') conversation: Union[ Room, Contact] = from_contact if room is None else room print('ready') await conversation.ready() print(list(rdict.values())[0]) await conversation.say(list(rdict.values())[0]) elif list(rdict.keys())[0] == "pic" or 'mov': print('reply pic/mov') conversation: Union[ Room, Contact] = from_contact if room is None else room await conversation.ready() try: file_box = FileBox.from_file(list(rdict.values())[0]) except Exception as e: print('file box error',e) file_box='嗯嗯' await conversation.say(file_box) elif msg.type() == Message.Type.MESSAGE_TYPE_TEXT: inputdata = "#str#" + msg.text() print('————text') bot = self.bm.run(username, inputdata) if bot is not None: # print('bot', bot) # print('bot replys',bot.replys[-1]) # print('bot.replys_index',bot.replys_index) for i in range(bot.replys_index): bot, rdict = self.tm.run(bot) print('rdict',rdict) if len(list(rdict.keys()))==0:continue if list(rdict.keys())[0] == "str": print('reply str') conversation: Union[ Room, Contact] = from_contact if room is None else room await conversation.ready() print('rdict[splitNum:]',list(rdict.values())[0]) await conversation.say(list(rdict.values())[0]) elif list(rdict.keys())[0] == "pic" or 'mov': print('reply pic/mov') conversation: Union[ Room, Contact] = from_contact if room is None else room await conversation.ready() try: file_box = FileBox.from_file(list(rdict.values())[0]) except Exception as e: print('file box error',e) file_box='嗯嗯' await conversation.say(file_box) else: print('__new for dict') conversation: Union[ Room, Contact] = from_contact if room is None else room await conversation.ready() await conversation.say('暂时不支持这种类型的消息哦')
async def on_message(self, msg: Message): # 加载消息发送者 talker = msg.talker() await talker.ready() # 忽略自己发的消息 if talker.contact_id == self.my_contact_id: return # 加载聊天室信息 room = msg.room() room_topic = None if room: await room.ready() room_topic = await room.topic() # 基本信息 msg_text = msg.text() msg_text_inline = msg.text().replace('\n', '') msg_type = msg.message_type() msg_id = msg.message_id if msg_type == 6: log.info('Received text, msg_type = {}, id = {}'.format( msg_type, msg_id)) else: log.info('Received text = {}, msg_type = {}, id = {}'.format( msg_text, msg_type, msg_id)) # 保存聊天记录 insert_data = { 'contact_id': talker.contact_id, 'contact_name': talker.name, 'room_id': room.room_id if room else None, 'room_name': room_topic, 'msg_id': msg_id, 'msg_text': msg_text[:20], 'created_at': datetime.now() } keys = ','.join(['`{}`'.format(str(v)) for v in insert_data.keys()]) values = ','.join( ['\'{}\''.format(str(v)) for v in insert_data.values()]) sql = 'INSERT INTO {table}({keys}) VALUES({values})'.format( table='msg_records', keys=keys, values=values) try: self.db.cursor.execute(sql) self.db.db.commit() except Exception as e: log.error(e) self.db.db.rollback() # 鉴定是否为广告 if room and not re.match(r'.*(kda|kadena|可达).*', msg_text_inline.lower()): is_ad = False if msg_type == 4: pass elif msg_type == 5: # 识别是否有二维码 img = await msg.to_file_box() log.info('get img {}'.format(img.name)) img_path = './images/{}'.format(img.name) img_file = await img.to_file(img_path) log.info('get img stored') img = cv2.imread(img_path) data, bbox, straight_qrcode = self.detector.detectAndDecode( img) log.info('qrcode results: {}, {}, {}'.format( data, bbox, straight_qrcode)) if bbox is not None: log.info('ad detected qr_code') is_ad = True os.remove(img_path) elif msg_type == 6: if len(msg_text) >= 50 and re.match( r'.*(http|空投|撸).*', msg_text) and not re.match(r'.*bihu\.com.*', msg_text): log.info('ad detected text') is_ad = True if is_ad: sql = """SELECT count(*) as msg_cnt FROM {} where contact_id = '{}'""".format( 'msg_records', talker.contact_id) self.db.cursor.execute(sql) if list(self.db.cursor.fetchall())[0]['msg_cnt'] < 10: q_list = list(self.ad_qa_dict.keys()) question = q_list[random.randrange(0, len(q_list))] threading.Thread(target=self.kick_member, args=(talker, room, question)).start() reply = '@{}\n你有打广告的嫌疑哦,请在15秒内回答以下问题,否则给你抱出去~~~\n{}'.format( talker.name, question) await room.say(reply, mention_ids=[talker.contact_id]) return # GOD的指令 if talker.contact_id == self.god_contact_id and 'c/' in msg_text: if 'c/new' in msg_text: if '上一条' in msg_text: sql = """SELECT msg_id FROM {} where contact_id = '{}' order by created_at desc""".format( 'msg_records', self.god_contact_id) self.db.cursor.execute(sql) refer_msg_id = list(self.db.cursor.fetchall())[1]['msg_id'] title = msg_text else: root = ET.fromstring(msg_text) refer_msg_id = root.find('.//refermsg//svrid').text title = root.find('.//title').text keyword = re.findall('#.+#', title)[0].replace('#', '') log.info('title = {}, keyword = {}'.format(title, keyword)) insert_data = { 'keyword': keyword, 'msg_id': refer_msg_id, 'created_at': datetime.now() } keys = ','.join( ['`{}`'.format(str(v)) for v in insert_data.keys()]) values = ','.join( ['\'{}\''.format(str(v)) for v in insert_data.values()]) sql = 'INSERT INTO {table}({keys}) VALUES({values})'.format( table='materials', keys=keys, values=values) try: self.db.cursor.execute(sql) self.db.db.commit() log.info('INSERT succesfully: {}'.format(sql)) except Exception as e: log.error(e) self.db.db.rollback() reply = '指令已储存,关键词:{}'.format(keyword) await msg.say(reply) elif 'c/list' in msg_text: sql = """SELECT keyword FROM {} group by keyword""".format( 'materials') self.db.cursor.execute(sql) reply = '现有指令' for row in self.db.cursor.fetchall(): reply += '\n' + row['keyword'] await msg.say(reply) elif 'c/show' in msg_text: keyword = re.findall('#.+#', msg_text)[0].replace('#', '') await self.send_msg_with_keyword(keyword, contact=talker, room=room) elif 'c/active' in msg_text: today = datetime.now() start_dt = datetime(today.year, today.month, today.day) sql = """SELECT contact_id, count(*) as msg_cnt FROM {} where room_id = '{}' and created_at >= '{}' group by contact_id""".format('msg_records', room.room_id, start_dt) self.db.cursor.execute(sql) records = [ row['contact_id'] for row in self.db.cursor.fetchall() ] member_list = await room.member_list() reply = '今日群内未发言成员:' for member in member_list: if member.contact_id != self.my_contact_id and member.contact_id not in records: reply += '\n' + member.name topic = await room.topic() if '星火' in topic: reply += '\n如果没法保持每天活跃,会被移出此群哦~' await msg.say(reply) elif 'c/fixroomname' in msg_text: log.info('to fix room name') sql = """SELECT * FROM {} WHERE room_id is not null and room_name = ''""".format( 'msg_records') self.db.cursor.execute(sql) for row in self.db.cursor.fetchall(): to_fix_room = self.Room(room_id=row['room_id']) await to_fix_room.ready() to_fix_room_name = await to_fix_room.topic() sql = """UPDATE {} SET room_name = '{}' where id = {}""".format( 'msg_records', to_fix_room_name, row['id']) try: self.db.cursor.execute(sql) self.db.db.commit() log.info('update succesfully: {}'.format(sql)) except Exception as e: log.error(e) self.db.db.rollback() log.info('finished') elif 'c/kdashill_to_tg' in msg_text: log.info('to send telegram') sql = """SELECT * FROM {} WHERE has_sent_tg is null""".format( 'kdashill_records') self.db.cursor.execute(sql) for row in self.db.cursor.fetchall(): url = 'https://m.bihu.com/shortcontent/{}'.format( row['content_id']) data = None with concurrent.futures.ThreadPoolExecutor() as executor: future = executor.submit(self.telegram.send_msg, url) data = future.result() log.info('get res: {}'.format(data)) if data: sql = """UPDATE {} SET has_sent_tg = {} where content_id = '{}'""".format( 'kdashill_records', 1, row['content_id']) try: self.db.cursor.execute(sql) self.db.db.commit() log.info('update succesfully: {}'.format(sql)) except Exception as e: log.error(e) self.db.db.rollback() time.sleep(1) break return # 推荐活动 if room and re.match(r'.*[bihu|chainnode]\.com.*', msg_text_inline): content_id = None match_results = re.search(r'(?<=bihu\.com/s/)[0-9A-Za-z]{1,}', msg_text) if match_results: key = match_results[0] x = 0 for y in key: k = digit62.find(y) if k >= 0: x = x * 62 + k content_id = str(x) platform = 'bihu' log.info('transfer {} to {}'.format(key, content_id)) elif 'bihu' in msg_text: match_results = re.search( r'(?<=bihu\.com/shortcontent/)\d{1,}', msg_text_inline.lower()) content_id = match_results[0] platform = 'bihu' elif 'chainnode' in msg_text: match_results = re.search(r'(?<=chainnode\.com/post/)\d{1,}', msg_text_inline.lower()) content_id = match_results[0] platform = 'chainnode' else: log.info('not find pattern') if content_id: log.info('get content id = {}'.format(content_id)) data = None with concurrent.futures.ThreadPoolExecutor() as executor: if platform == 'bihu': future = executor.submit(self.crawler.fetch_bihu, content_id) else: future = executor.submit(self.crawler.fetch_chainnode, content_id) data = future.result() log.info('fetched data = {}'.format(data)) if data: content_inline = data['content'].replace('\n', '') post_date = data['post_date'] if not re.match(r'.*(kda|kadena|可达).*', content_inline.lower()): reply = '未发现Kadena相关信息哦~' reply = reply + ' @{}'.format(talker.name) await room.say(reply, mention_ids=[talker.contact_id]) return elif post_date < datetime( 2021, 3, 26) or post_date >= datetime(2021, 4, 2): reply = '文章发布时间不在活动范围内,不能算入哦~' reply = reply + ' @{}'.format(talker.name) await room.say(reply, mention_ids=[talker.contact_id]) return # 展示 sql = """SELECT * FROM {} where phase = 1 and platform = '{}' and content_id = '{}'""".format( 'kdashill_records', platform, content_id) self.db.cursor.execute(sql) results = list(self.db.cursor.fetchall()) if len(results): # 处理重复 is_duplicate = True ww_id = results[0]['id'] from_room = self.Room(room_id=results[0]['room_id']) await from_room.ready() from_room_name = await from_room.topic() room_name_str = '「{}」\n'.format( from_room_name.replace('Kadena', '')) from_contact = self.Contact( contact_id=results[0]['contact_id']) await from_contact.ready() from_contact_name = from_contact.name else: is_duplicate = False sql = """SELECT max(id) as max_id FROM {} """.format( 'kdashill_records') self.db.cursor.execute(sql) max_id = list(self.db.cursor.fetchall())[0]['max_id'] ww_id = max_id + 1 room_name_str = '「{}」\n'.format( room_topic.replace('Kadena', '')) from_contact_name = talker.name reply_title = '可达秀.{:02} @ {}'.format( ww_id, from_contact_name) if platform == 'bihu': reply_url = 'https://m.bihu.com/shortcontent/{}'.format( content_id) score = 1 if 'img_url' in data: prefix = 'https://oss-cdn1.bihu-static.com/' reply_thumbnail = prefix + data['img_url'] else: reply_thumbnail = 'https://m.bihu.com/static/img/pic300.jpg' else: score = 2 reply_url = 'https://www.chainnode.com/post/{}'.format( content_id) if 'img_url' in data: reply_thumbnail = data['img_url'] else: reply_thumbnail = 'https://webcdn.chainnode.com/mobile-1.3.15/img/ChainNode.4e5601a.svg' reply_description = room_name_str + data['content'][:60] log.info('to create url_link: {},{},{},{}'.format( reply_url, reply_title, reply_thumbnail, reply_description)) reply_link = UrlLink.create(reply_url, reply_title, reply_thumbnail, reply_description) log.info('url created') # 查重 if is_duplicate: reply = '文章已有录入哦~' reply = reply + ' @{}'.format(talker.name) await room.say(reply, mention_ids=[talker.contact_id]) return # 记分 insert_data = { 'phase': 2, 'platform': platform, 'content_id': content_id, 'contact_id': talker.contact_id, 'contact_name': talker.name, 'room_id': room.room_id, 'created_at': datetime.now(), 'score': score, } keys = ','.join( ['`{}`'.format(str(v)) for v in insert_data.keys()]) values = ','.join([ '\'{}\''.format(str(v)) for v in insert_data.values() ]) sql = 'INSERT INTO {table}({keys}) VALUES({values})'.format( table='kdashill_records', keys=keys, values=values) try: self.db.cursor.execute(sql) self.db.db.commit() log.info('INSERT succesfully: {}'.format(sql)) except Exception as e: log.error(e) self.db.db.rollback() # 报积分 sql = """SELECT contact_id, sum(score) as score FROM {} where phase = 2 group by contact_id order by score desc""".format( 'kdashill_records') self.db.cursor.execute(sql) rank = 0 for row in self.db.cursor.fetchall(): rank += 1 if row['contact_id'] == talker.contact_id: reply = '感谢参加可达秀 [KDA-Show] 活动!🍻\n' reply += '您当前积分为{},排名为{}'.format( row['score'], rank) break reply = reply + ' @{}'.format(talker.name) await room.say(reply, mention_ids=[talker.contact_id]) # 发送至其他群 sql = """SELECT room_id, max(room_name) as room_name FROM {} group by room_id""".format( 'msg_records') self.db.cursor.execute(sql) for row in self.db.cursor.fetchall(): if '可达社区信息流' in row['room_name']: forward_room = self.Room(room_id=row['room_id']) await forward_room.ready() try: await forward_room.say(reply_link) except Exception as e: log.exception(e) # 发送至Telegram #threading.Thread(target=self.telegram.send_msg, args=(reply_url)).start() return else: reply = '未查到相关网页' reply = reply + ' @{}'.format(talker.name) await room.say(reply, mention_ids=[talker.contact_id]) return # 关键词回复 if re.match(r'(资料|学习|学习资料|新人)', msg_text_inline): await self.send_msg_with_keyword('新手指南', contact=talker, room=room) return coin_dict = { 'kda': 'kadena', 'btc': 'bitcoin', 'eth': 'ethereum', 'dot': 'polkadot', 'link': 'chainlink', 'atom': 'cosmos', 'mkr': 'maker', 'luna': 'terra-luna', 'celo': 'celo', } if room and msg_text.lower() in coin_dict: name = msg_text.lower() full_name = coin_dict[name] url = 'https://api.coingecko.com/api/v3/coins/{}/market_chart?vs_currency=usd&days=30&interval=daily'.format( full_name) data = requests.get(url).json() log.info('get chart, response: {}'.format(data)) url = 'http://*****:*****@{}'.format(self.my_contact_name) in msg_text): data = {'msg': msg_text, 'appid': '0', 'key': 'free'} url = 'http://api.qingyunke.com/api.php' res = requests.get(url, params=data) log.info('get AI request: {}, {}, response: {}'.format( url, data, res.text)) data = res.json() reply = data['content'].replace('{br}', '\n') reply = reply + ' @{}'.format(talker.name) if room: await room.say(reply, mention_ids=[talker.contact_id]) else: await msg.say(reply)
def get_music_file_url(name: str) -> FileBox: log.info("name=%s" % name) music_url, music_name = get_music_url(name) log.info("url=%s,name=%s" % (music_url, music_name)) return FileBox.from_url(music_url, music_name)