def edit_link_message(self, message: Message, reactions: bool = False, commands: bool = False, substitution: bool = False) -> Message: message.text = f"Content of edited link message with ID {message.uid}" message.edit = True message.attributes = LinkAttribute( title="EH Forwarder Bot (edited)", description="EH Forwarder Bot project site. (edited)", url="https://efb.1a23.studio/#edited") message = self.attach_message_properties(message, reactions, commands, substitution) self.messages_sent[message.uid] = message coordinator.send_message(message) return message
def qq_contact_wrapper(self, data, chat: Chat = None): uid = data['id'] contact_type = data['type'] efb_msg = Message( type=MsgType.Text, text=self._( "Chat Recommendation Received\nID: {}\nType: {}").format( uid, contact_type)) return [efb_msg]
def send_reactions_update(self, message: Message) -> MessageReactionsUpdate: reactions = self.build_reactions(message.chat) message.reactions = reactions status = MessageReactionsUpdate(chat=message.chat, msg_id=message.uid, reactions=reactions) coordinator.send_status(status) return status
def qq_sign_wrapper(self, data, chat: Chat = None): location = self._('at {}').format(data['location']) if 'location' in data else self._('at Unknown Place') title = '' if 'title' not in data else (self._('with title {}').format(data['title'])) efb_msg = Message( type=MsgType.Text, text=self._('signed in {location} {title}').format(title=title, location=location) ) return [efb_msg]
def base_message(chat, master_channel): msg = Message( deliver_to=master_channel, author=chat.other, chat=chat, text="Message", uid="0", ) return msg
def wechat_system_msg(self, msg: wxpy.Message) -> Optional[Message]: if msg.recalled_message_id: recall_id = str(msg.recalled_message_id) # check conversion table first if recall_id in self.recall_msg_id_conversion: # prevent feedback of messages deleted by master channel. del self.recall_msg_id_conversion[recall_id] return None # val = self.recall_msg_id_conversion.pop(recall_id) # val[1] -= 1 # if val[1] > 0: # not all associated messages are recalled. # return None # else: # efb_msg.uid = val[0] else: # Format message IDs as JSON of List[List[str]]. chat, author = self.get_chat_and_author(msg) efb_msg = Message(chat=chat, author=author, uid=MessageID(json.dumps([[recall_id]]))) coordinator.send_status( MessageRemoval(source_channel=self.channel, destination_channel=coordinator.master, message=efb_msg)) return None chat, _ = self.get_chat_and_author(msg) try: author = chat.get_member(SystemChatMember.SYSTEM_ID) except KeyError: author = chat.add_system_member() if any(i in msg.text for i in self.NEW_CHAT_PATTERNS): coordinator.send_status( ChatUpdates(channel=self.channel, new_chats=(chat.uid, ))) elif any(i in msg.text for i in self.CHAT_AND_MEMBER_UPDATE_PATTERNS): # TODO: detect actual member changes from message text coordinator.send_status( ChatUpdates(channel=self.channel, modified_chats=(chat.uid, ))) return Message( text=msg.text, type=MsgType.Text, chat=chat, author=author, )
def qq_share_wrapper(self, data, chat: Chat = None): efb_msg = Message( type=MsgType.Link, text='', attributes=LinkAttribute( title='' if 'title' not in data else data['title'], description='' if 'content' not in data else data['content'], image='' if 'image' not in data else data['image'], url=data['url'])) return [efb_msg]
def wechat_system_unsupported_msg(self, msg: wxpy.Message) -> Optional[Message]: if msg.raw['MsgType'] in (50, 52, 53): text = self._("[Incoming audio/video call, please check your phone.]") else: return None efb_msg = Message( text=text, type=MsgType.Unsupported, ) return efb_msg
def send_message_recall_status(self): slave = next(iter(coordinator.slaves.values())) alice = slave.get_chat('alice') msg = Message( deliver_to=slave, chat=alice, author=alice.self, uid="1" ) status = MessageRemoval(self, slave, msg) return coordinator.send_status(status)
def send_text_msg(self): slave = next(iter(coordinator.slaves.values())) wonderland = slave.get_chat('wonderland001') msg = Message( deliver_to=slave, chat=wonderland, author=wonderland.self, type=MsgType.Text, text="Hello, world.", ) return coordinator.send_message(msg)
def send_location_msg(self): slave = next(iter(coordinator.slaves.values())) alice = slave.get_chat('alice') msg = Message( deliver_to=slave, chat=alice, author=alice.self, type=MsgType.Location, text="I'm not here.", attributes=LocationAttribute(latitude=0.1, longitude=1.0), ) return coordinator.send_message(msg)
def qq_file_after_wrapper(self, data): efb_msg = Message() efb_msg.file = data['file'] efb_msg.type = MsgType.File mime = magic.from_file(efb_msg.file.name, mime=True) if isinstance(mime, bytes): mime = mime.decode() efb_msg.path = efb_msg.file.name efb_msg.mime = mime efb_msg.filename = quote(data['filename']) return efb_msg
def wechat_shared_image_msg(self, msg: wxpy.Message, source: str, text: str = "", mode: str = "image") -> Message: efb_msg = Message() efb_msg.type = MsgType.Image efb_msg.text = self._("Via {source}").format(source=source) if text: efb_msg.text = "%s\n%s" % (text, efb_msg.text) efb_msg.path, efb_msg.mime, efb_msg.file = self.save_file(msg, app_message=mode) return efb_msg
def wechat_friend_msg(self, msg: wxpy.Message) -> Message: # TRANSLATORS: Gender of contact txt = self.generate_card_info(msg) return Message( text=txt, type=MsgType.Text, commands=MessageCommands([ MessageCommand( name=self._("Accept friend request"), callable_name="accept_friend", kwargs={"username": msg.card.user_name} ) ]) )
def qq_music_wrapper(self, data, chat: Chat = None): efb_msg = Message() if data['type'] == '163': # Netease Cloud Music efb_msg.type = MsgType.Text efb_msg.text = 'https://music.163.com/#/song?id=' + data['id'] else: efb_msg.type = MsgType.Text efb_msg.text = data['text'] return [efb_msg] # todo Port for other music platform
def make_status_message(self, msg_base: Message = None, mid: MessageID = None) -> Message: if mid is not None: msg = self.message_cache[mid] elif msg_base is not None: msg = msg_base else: raise ValueError reply = Message( type=MsgType.Text, chat=msg.chat, author=msg.chat.make_system_member(uid=ChatID("filter_info"), name="Filter middleware", middleware=self), deliver_to=coordinator.master, ) if mid: reply.uid = mid else: reply.uid = str(uuid.uuid4()) status = self.filter_reason(msg) if not status: # Blue circle emoji status = "\U0001F535 This chat is not filtered." else: # Red circle emoji status = "\U0001F534 " + status reply.text = "Filter status for chat {chat_id} from {module_id}:\n" \ "\n" \ "{status}\n".format( module_id=msg.chat.module_id, chat_id=msg.chat.id, status=status ) command = MessageCommand(name="%COMMAND_NAME%", callable_name="toggle_filter_by_chat_id", kwargs={ "mid": reply.uid, "module_id": msg.chat.module_id, "chat_id": msg.chat.id }) if self.is_chat_filtered_by_id(msg.chat): command.name = "Unfilter by chat ID" command.kwargs['value'] = False else: command.name = "Filter by chat ID" command.kwargs['value'] = True reply.commands = MessageCommands([command]) return reply
def send_link_msg(self): slave = next(iter(coordinator.slaves.values())) alice = slave.get_chat('alice') msg = Message( deliver_to=slave, chat=alice, author=alice.self, type=MsgType.Link, text="Check it out.", attributes=LinkAttribute( title="Example", url="https://example.com" ) ) return coordinator.send_message(msg)
def wechat_raw_link_msg(self, msg: wxpy.Message, title: str, description: str, image: str, url: str, suffix: str = "") -> Message: if url: efb_msg = Message( type=MsgType.Link, text=suffix, attributes=LinkAttribute( title=title, description=description, image=image, url=url ) ) else: efb_msg = Message( type=MsgType.Text, text=f"{title}\n{description}", ) if suffix: efb_msg.text += f"\n{suffix}" if image: efb_msg.text += f"\n\n{image}" return efb_msg
def exit_callback(self): # Don't send prompt if there's nowhere to send. if not getattr(coordinator, 'master', None): raise Exception( self. _("Web WeChat logged your account out before master channel is ready." )) self.logger.debug('Calling exit callback...') if self._stop_polling_event.is_set(): return msg = Message( chat=self.user_auth_chat, author=self.user_auth_chat.other, deliver_to=coordinator.master, text=self. _("WeChat server has logged you out. Please log in again when you are ready." ), uid=f"__reauth__.{uuid4()}", type=MsgType.Text, ) on_log_out = self.flag("on_log_out") on_log_out = on_log_out if on_log_out in ("command", "idle", "reauth") else "command" if on_log_out == "command": msg.type = MsgType.Text msg.commands = MessageCommands([ MessageCommand(name=self._("Log in again"), callable_name="reauth", kwargs={"command": True}) ]) elif on_log_out == "reauth": if self.flag("qr_reload") == "console_qr_code": msg.text += "\n" + self._("Please check your log to continue.") self.reauth() coordinator.send_message(msg)
def reply_message(self, message: Message, text: str): reply = Message() reply.text = text # reply.chat = coordinator.slaves[message.chat.channel_id].get_chat(message.chat.chat_uid) reply.chat = coordinator.slaves[message.chat.module_id].get_chat( message.chat.uid) reply.author = message.chat.make_system_member( uid=self.middleware_id, name=self.middleware_name, middleware=self) reply.type = MsgType.Text # reply.deliver_to = coordinator.master reply.deliver_to = coordinator.slaves[message.chat.module_id] # reply.target = message reply.uid = str(uuid.uuid4()) r2 = reply coordinator.send_message(reply) r2.deliver_to = coordinator.master coordinator.send_message(r2)
def wechat_file_msg(self, msg: wxpy.Message) -> Message: efb_msg = Message(type=MsgType.File) try: file_name = msg.file_name efb_msg.text = file_name or "" app_name = msg.app_name if app_name: efb_msg.text = self._("{file_name} sent via {app_name}").format(file_name=file_name, app_name=app_name) efb_msg.filename = file_name or "" efb_msg.path, efb_msg.mime, efb_msg.file = self.save_file(msg) except EOFError: efb_msg.type = MsgType.Text efb_msg.text += self._("[Failed to download the file, please check your phone.]") return efb_msg
def qq_rich_wrapper(self, data: dict, chat: Chat = None): # Buggy, Help needed efb_messages = list() efb_msg = Message( type=MsgType.Unsupported, text=self._('[Here comes the Rich Text, dumping...] \n') ) for key, value in data.items(): efb_msg.text += key + ': ' + value + '\n' efb_messages.append(efb_msg) # Optimizations for rich messages # Group Broadcast _ = self.qq_group_broadcast_wrapper(data, chat) if _ is not None: efb_messages.append(_) return efb_messages
def gen_reply_msg(self, message: Message, text: str) -> Message: msg: Message = Message() msg.chat = message.chat msg.author = ChatMember(msg.chat) msg.author.uid = self.middleware_id msg.author.name = 'Search Message' msg.author.alias = '' msg.author.description = '' # msg.author.module_id = self.middleware_id # msg.author.module_name = self.middleware_name msg.author.middleware = self msg.deliver_to = coordinator.master msg.type = MsgType.Text msg.uid = message.uid msg.text = text return msg
def qq_record_wrapper(self, data, chat: Chat = None): # Experimental! efb_msg = Message() try: transformed_file = self.inst.coolq_api_query("get_record", file=data['file'], out_format='mp3') efb_msg.type = MsgType.Audio efb_msg.file = download_voice(transformed_file['file'], self.inst.client_config['api_root'].rstrip("/"), self.inst.client_config['access_token']) mime = magic.from_file(efb_msg.file.name, mime=True) if isinstance(mime, bytes): mime = mime.decode() efb_msg.path = efb_msg.file.name efb_msg.mime = mime except Exception: efb_msg.type = MsgType.Unsupported efb_msg.text = self._('[Voice Message] Please check it on your QQ') logging.getLogger(__name__).exception("Failed to download voice") return [efb_msg]
def wechat_video_msg(self, msg: wxpy.Message) -> Message: efb_msg = Message(type=MsgType.Video) try: if msg.file_size == 0: raise EOFError efb_msg.path, efb_msg.mime, efb_msg.file = self.save_file(msg) efb_msg.filename = msg.file_name efb_msg.text = "" except EOFError: efb_msg.type = MsgType.Text efb_msg.text += self._("[Failed to download the video message, please check your phone.]") return efb_msg
def wechat_friend_msg(self, msg: wxpy.Message) -> Message: gender = { 1: self._("M"), 2: self._("F") }.get(msg.card.sex, msg.card.sex) txt = (self._("Card: {user.nick_name}\n" "From: {user.province}, {user.city}\n" "Bio: {user.signature}\n" "Gender: {gender}")) txt = txt.format(user=msg.card, gender=gender) return Message(text=txt, type=MsgType.Text, commands=MessageCommands([ MessageCommand( name=self._("Accept friend request"), callable_name="accept_friend", kwargs={"username": msg.card.user_name}) ]))
def wechat_sticker_msg(self, msg: wxpy.Message) -> Message: efb_msg = Message(type=MsgType.Sticker) try: if msg.raw['MsgType'] == 47 and not msg.raw['Content']: raise EOFError if msg.file_size == 0: raise EOFError efb_msg.path, efb_msg.mime, efb_msg.file = self.save_file(msg) efb_msg.filename = msg.file_name # ^ Also throws EOFError if 'gif' in efb_msg.mime and Image.open(efb_msg.path).is_animated: efb_msg.type = MsgType.Animation efb_msg.text = "" except EOFError: efb_msg.text += self._("[Failed to download the sticker, please check your phone.]") efb_msg.type = MsgType.Unsupported return efb_msg
def edit_file_like_message(self, message: Message, file_path: Path, mime: str, reactions: bool = False, commands: bool = False, substitution: bool = False) -> Message: message.text = f"Content of edited {message.type.name} media with ID {message.uid}" message.edit = True message.edit_media = True message.file = file_path.open('rb') message.filename = file_path.name message.path = file_path message.mime = mime message = self.attach_message_properties(message, reactions, commands, substitution) self.messages_sent[message.uid] = message coordinator.send_message(message) return message
def wechat_picture_msg(self, msg: wxpy.Message) -> Message: efb_msg = Message(type=MsgType.Image) try: if msg.raw['MsgType'] == 47 and not msg.raw['Content']: raise EOFError if msg.file_size == 0: raise EOFError efb_msg.path, efb_msg.mime, efb_msg.file = self.save_file(msg) efb_msg.filename = msg.file_name # ^ Also throws EOFError efb_msg.text = "" except EOFError: efb_msg.text += self._("[Failed to download the picture, please check your phone.]") efb_msg.type = MsgType.Unsupported return efb_msg
def send_location_message(self, chat: Chat, author: Optional[ChatMember] = None, target: Optional[Message] = None, reactions: bool = False, commands: bool = False, substitution: bool = False) -> Message: author = author or chat.self uid = f"__msg_id_{uuid4()}__" message = Message(chat=chat, author=author, type=MsgType.Location, target=target, uid=uid, text=f"Content of location message with ID {uid}", attributes=LocationAttribute( latitude=random.uniform(0.0, 90.0), longitude=random.uniform(0.0, 90.0)), deliver_to=coordinator.master) message = self.attach_message_properties(message, reactions, commands, substitution) self.messages_sent[uid] = message coordinator.send_message(message) return message