Exemple #1
0
    async def forward(self, to: Union[Room, Contact]) -> None:
        """
        Forward a message to a room or a contact.
        Args:
            to: the room or contact to forward to
        Examples:
            >>> msg.forward(room)
            >>> msg.forward(contact)
        """
        log.info('forward() <%s>', to)
        if to is None:
            raise WechatyPayloadError('to param not found')
        try:
            if isinstance(to, Room):
                to_id = to.room_id
            elif isinstance(to, Contact):
                to_id = to.contact_id
            else:
                raise WechatyPayloadError(
                    'expected type is <Room, Contact>, but get <%s>' %
                    to.__class__)
            print(to_id)
            await self.puppet.message_forward(to_id, self.message_id)

        # pylint:disable=W0703
        except Exception as exception:
            message = 'Message forward error <%s>' % exception.args
            log.error(message)
            raise WechatyOperationError(message)
Exemple #2
0
    async def forward(self, to: Union[Room, Contact]):
        """
        doc
        :param to:
        :return:
        """
        log.info('forward() <%s>', to)
        if to is None:
            raise WechatyPayloadError('to param not found')
        try:
            if isinstance(to, Room):
                to_id = to.room_id
            elif isinstance(to, Contact):
                to_id = to.contact_id
            else:
                raise WechatyPayloadError(
                    'expected type is <Room, Contact>, but get <%s>' %
                    to.__class__)
            print(to_id)
            await self.puppet.message_forward(to_id, self.message_id)

        # pylint:disable=W0703
        except Exception as exception:
            message = 'Message forward error <%s>' % exception.args
            log.error(message)
            raise WechatyOperationError(message)
Exemple #3
0
    async def say(self,
                  msg: Union[str, Contact, FileBox, UrlLink, MiniProgram],
                  mention_ids: Optional[List[str]] = None) -> Message:
        """
        send message
        """
        log.info('say() <%s>', msg)

        room = self.room()
        if room is not None:
            conversation_id = room.room_id
        else:
            talker = self.talker()
            if talker is None:
                raise WechatyPayloadError(f'Message must be from room/contact')
            conversation_id = talker.contact_id

        # in order to resolve circular dependency problems which is not for
        # typing, we import some modules locally.
        # TODO -> this is not good solution, we will fix it later.

        from .url_link import UrlLink
        from .mini_program import MiniProgram

        if isinstance(msg, str):
            message_id = await self.puppet.message_send_text(
                conversation_id=conversation_id,
                message=msg,
                mention_ids=mention_ids)

        elif isinstance(msg, Contact):
            message_id = await self.puppet.message_send_contact(
                conversation_id=conversation_id, contact_id=msg.contact_id)
        elif isinstance(msg, FileBox):
            message_id = await self.puppet.message_send_file(
                conversation_id=conversation_id, file=msg)
        elif isinstance(msg, UrlLink):
            message_id = await self.puppet.message_send_url(
                conversation_id=conversation_id,
                url=json.dumps(dataclasses.asdict(msg.payload)))
        elif isinstance(msg, MiniProgram):
            assert msg.payload is not None
            message_id = await self.puppet.message_send_mini_program(
                conversation_id=conversation_id, mini_program=msg.payload)
        else:
            raise WechatyPayloadError(f'message type should be str, '
                                      f'Contact/FileBox/UrlLink/MiniProgram')

        message = self.load(message_id)
        await message.ready()
        return message
Exemple #4
0
    async def to_recalled(self) -> Message:
        """
        Get the recalled message

        Args:
            None
        Examples:
            >>> msg.to_recalled()
        Returns:
            Message: the recalled message
        """
        if self.message_type() != MessageType.MESSAGE_TYPE_RECALLED:
            raise WechatyOperationError(
                'Can not call toRecalled() on message which is not'
                ' recalled type.')

        origin_message_id = self.text()
        if origin_message_id is None:
            raise WechatyPayloadError('Can not find recalled message')

        log.info('get recall message <%s>', origin_message_id)
        try:
            message = self.wechaty.Message.load(origin_message_id)
            await message.ready()
            return message
        except Exception as exception:
            error_info = 'can"t load or ready message payload {}'.format(
                str(exception.args))

            log.error(error_info)
            raise WechatyOperationError(error_info)
    async def alias(self, new_alias: Optional[str] = None) -> Union[None, str]:
        """
        get/set alias
        """
        log.info('Contact alias <%s>', new_alias)
        if not self.is_ready():
            await self.ready()

        if self.payload is None:
            raise WechatyPayloadError('can"t load contact payload <%s>' % self)

        # if new_alias is None:
        #     if self.payload.alias is None:
        #         return ''
        #     return self.payload.alias

        try:
            alias = await self.puppet.contact_alias(self.contact_id, new_alias)
            await self.ready(force_sync=True)
            if new_alias != self.payload.alias:
                log.info(
                    'Contact alias(%s) sync with server fail: \
                    set(%s) is not equal to get(%s)', new_alias, new_alias,
                    self.payload.alias)
            return alias
        # pylint:disable=W0703
        except Exception as exception:
            log.info('Contact alias(%s) rejected: %s', new_alias,
                     str(exception.args))
        return None
Exemple #6
0
    async def ready(self, force_sync: bool = False) -> None:
        """
        Make contact ready for use which will load contact payload info.

        Args:
            force_sync: if true, it will re-fetch the data although it exist.

        Examples:
            >>> contact = Contact.load('contact-id')
            >>> await await contact.ready()

        Raises:
            WechatyPayloadError: when payload can"t be loaded
        """
        if force_sync or not self.is_ready():
            try:
                self.payload = await self.puppet.contact_payload(
                    self.contact_id)
                log.info('load contact <%s>', self)
            except IOError as e:
                log.info('can"t load contact %s payload, message : %s',
                         self.name,
                         str(e.args))

                raise WechatyPayloadError('can"t load contact payload')
Exemple #7
0
    async def ready(self, force_sync=False):
        """
        Please not to use `ready()` at the user land.
        """
        if self.is_ready():
            return

        if force_sync:
            self.payload = None

            # TODO -> *_dirty method is not implemented in puppet
            # await self.puppet.room_payload_dirty(self.room_id)
            # await self.puppet.room_member_payload_dirty(self.room_id)

        self.payload = await self.puppet.room_payload(self.room_id)

        if self.payload is None:
            raise WechatyPayloadError('Room Payload can"t be ready')

        member_ids = await self.puppet.room_members(self.room_id)

        contacts = [
            self.wechaty.Contact.load(member_id) for member_id in member_ids
        ]

        for contact in contacts:
            try:
                await contact.ready()
            # pylint:disable=W0703
            except Exception as exception:
                log.error('Room ready() member.ready() rejection: %s',
                          exception)
 def type(self) -> ContactType:
     """
     get contact type
     """
     if self.payload is None:
         raise WechatyPayloadError('contact payload not found')
     return self.payload.type
Exemple #9
0
    async def alias(self,
                    new_alias: Optional[str] = None
                    ) -> Union[None, str]:
        """get or set alias of contact.
            If new_alias is given, it will set alias to new_alias,
            otherwise return current alias

        Args:
            new_alias (Optional[str], optional): the new alias of contact. Defaults to None.

        Returns:
            Union[None, str]: the current alias of contact
        """
        log.info('Contact alias <%s>', new_alias)
        if not self.is_ready():
            await self.ready()

        if self.payload is None:
            raise WechatyPayloadError('can"t load contact payload <%s>' % self)

        try:
            alias = await self.puppet.contact_alias(self.contact_id, new_alias)

            # reload the contact payload
            await self.ready(force_sync=True)
            return alias
        # pylint:disable=W0703
        except Exception as exception:
            log.info(
                'Contact alias(%s) rejected: %s',
                new_alias, str(exception.args))
        return None
Exemple #10
0
    def type(self) -> ContactType:
        """get type of contact, which can person, official, corporation, and unspecified.

        Returns:
            ContactType: the type of contact.
        """
        if self.payload is None:
            raise WechatyPayloadError('contact payload not found')
        return self.payload.type
Exemple #11
0
    def talker(self) -> Contact:
        """
        get message talker

        # TODO ->   Suggestion: talker/to/room/text func can
        #           be converted to property func
        """
        talker_id = self.payload.from_id
        if talker_id is None:
            raise WechatyPayloadError(f'message must be from Contact')
        return self.wechaty.Contact.load(talker_id)
Exemple #12
0
    def talker(self) -> Contact:
        """get the talker of the message

        Raises:
            WechatyPayloadError: can't find the talker information from the payload

        Returns:
            Contact: the talker contact object
        """
        talker_id = self.payload.from_id
        if talker_id is None:
            raise WechatyPayloadError('message must be from Contact')
        return self.wechaty.Contact.load(talker_id)
Exemple #13
0
    def type(self) -> ContactType:
        """
        Get type of contact, which can person, official, corporation, and unspecified.

        Examples:
            >>> contact = Contact.load('contact-id')
            >>> contact_type = contact.type()

        Returns:
            ContactType: the type of contact.
        """
        if self.payload is None:
            raise WechatyPayloadError('contact payload not found')
        return self.payload.type
Exemple #14
0
    async def to_mini_program(self) -> MiniProgram:
        """
        get message mini_program
        :return:
        """
        log.info('Message to MiniProgram <%s>', self.message_id)

        if self.type() != MessageType.MESSAGE_TYPE_MINI_PROGRAM:
            raise WechatyOperationError('not a mini_program type message')

        payload = await self.puppet.message_mini_program(self.message_id)
        if payload is None:
            raise WechatyPayloadError('no miniProgram payload for message %s' %
                                      self.message_id)
        return MiniProgram(payload)
Exemple #15
0
 async def to_url_link(self) -> UrlLink:
     """
     get url_link from message
     :return:
     """
     log.info('Message to UrlLink')
     if self.type() != MessageType.MESSAGE_TYPE_URL:
         raise WechatyOperationError(
             'current message type: %s, not url type' % self.type())
     payload = await self.puppet.message_url(self.message_id)
     if payload is None:
         raise WechatyPayloadError(
             'can not get url_link_payload by message: %s' %
             self.message_id)
     return UrlLink(payload)
Exemple #16
0
    async def ready(self, force_sync: bool = False) -> None:
        """
        load contact object from puppet
        :return:
        """

        if force_sync or not self.is_ready():
            try:
                self.payload = await self.puppet.contact_payload(
                    self.contact_id)
                log.info('load contact <%s>', self)
            except IOError as e:
                log.info('can"t load contact %s payload, message : %s',
                         self.name, str(e.args))

                raise WechatyPayloadError('can"t load contact payload')
Exemple #17
0
    async def alias(self, new_alias: Optional[str] = None) -> Union[None, str]:
        """
        get/set alias
        """
        log.info('Contact alias <%s>', new_alias)
        if not self.is_ready():
            await self.ready()

        if self.payload is None:
            raise WechatyPayloadError('can"t load contact payload <%s>' % self)

        try:
            alias = await self.puppet.contact_alias(self.contact_id, new_alias)

            # reload the contact payload
            await self.ready(force_sync=True)
            return alias
        # pylint:disable=W0703
        except Exception as exception:
            log.info('Contact alias(%s) rejected: %s', new_alias,
                     str(exception.args))
        return None
Exemple #18
0
    async def alias(self,
                    new_alias: Optional[str] = None
                    ) -> Union[None, str]:
        """
        Get or set alias of contact.
        
        If new_alias is given, it will set alias to new_alias,
        otherwise return current alias

        Notes:
            Setting aliases too often will result in failure (60 times per minute).

        Args:
            new_alias: the new alias of contact.

        Returns:
            alias: the current alias of contact
        """
        log.info('Contact alias <%s>', new_alias)
        if not self.is_ready():
            await self.ready()

        if self.payload is None:
            raise WechatyPayloadError('can"t load contact payload <%s>' % self)

        try:
            alias = await self.puppet.contact_alias(self.contact_id, new_alias)

            # reload the contact payload
            await self.ready(force_sync=True)
            return alias
        # pylint:disable=W0703
        except Exception as exception:
            log.info(
                'Contact alias(%s) rejected: %s',
                new_alias, str(exception.args))
        return None
Exemple #19
0
    async def say(
            self,
            msg: Union[str, Contact, FileBox, UrlLink, MiniProgram],
            mention_ids: Optional[List[str]] = None) -> Optional[Message]:
        """
        send the message to the conversation envrioment which is source of this message.

        If this message is from room, so you can send message to this room.
        If this message is from contact, so you can send message to this contact, not to room.

        Args:
            msg: the message object which can be type of str/Contact/FileBox/UrlLink/MiniProgram
            mention_ids: you can send message with `@person`, the only things you should do is to
                set contact_id to mention_ids.
        """
        log.info('say() <%s>', msg)

        if not msg:
            log.error('can"t say nothing')
            return None

        room = self.room()
        if room is not None:
            conversation_id = room.room_id
        else:
            talker = self.talker()
            if talker is None:
                raise WechatyPayloadError('Message must be from room/contact')
            conversation_id = talker.contact_id

        # in order to resolve circular dependency problems which is not for
        # typing, we import some modules locally.
        # TODO -> this is not good solution, we will fix it later.

        from .url_link import UrlLink
        from .mini_program import MiniProgram

        if isinstance(msg, str):
            message_id = await self.puppet.message_send_text(
                conversation_id=conversation_id,
                message=msg,
                mention_ids=mention_ids)
        elif isinstance(msg, Contact):
            message_id = await self.puppet.message_send_contact(
                conversation_id=conversation_id,
                contact_id=msg.contact_id,
            )
        elif isinstance(msg, FileBox):
            message_id = await self.puppet.message_send_file(
                conversation_id=conversation_id, file=msg)
        elif isinstance(msg, UrlLink):
            message_id = await self.puppet.message_send_url(
                conversation_id=conversation_id,
                url=json.dumps(dataclasses.asdict(msg.payload)))
        elif isinstance(msg, MiniProgram):
            assert msg.payload is not None
            message_id = await self.puppet.message_send_mini_program(
                conversation_id=conversation_id, mini_program=msg.payload)
        else:
            raise WechatyPayloadError('message type should be str, '
                                      'Contact/FileBox/UrlLink/MiniProgram')

        message = self.load(message_id)
        await message.ready()
        return message