async def _get_entity_from_string(self, string):
        """
        Gets a full entity from the given string, which may be a phone or
        a username, and processes all the found entities on the session.
        The string may also be a user link, or a channel/chat invite link.

        This method has the side effect of adding the found users to the
        session database, so it can be queried later without API calls,
        if this option is enabled on the session.

        Returns the found entity, or raises TypeError if not found.
        """
        phone = utils.parse_phone(string)
        if phone:
            try:
                for user in (await self(
                        functions.contacts.GetContactsRequest(0))).users:
                    if user.phone == phone:
                        return user
            except errors.BotMethodInvalidError:
                raise ValueError('Cannot get entity by phone number as a '
                                 'bot (try using integer IDs, not strings)')
        elif string.lower() in ('me', 'self'):
            return await self.get_me()
        else:
            username, is_join_chat = utils.parse_username(string)
            if is_join_chat:
                invite = await self(
                    functions.messages.CheckChatInviteRequest(username))

                if isinstance(invite, types.ChatInvite):
                    raise ValueError(
                        'Cannot get entity from a channel (or group) '
                        'that you are not part of. Join the group and retry'
                    )
                elif isinstance(invite, types.ChatInviteAlready):
                    return invite.chat
            elif username:
                try:
                    result = await self(
                        functions.contacts.ResolveUsernameRequest(username))
                except errors.UsernameNotOccupiedError as e:
                    raise ValueError('No user has "{}" as username'
                                     .format(username)) from e

                try:
                    pid = utils.get_peer_id(result.peer, add_mark=False)
                    if isinstance(result.peer, types.PeerUser):
                        return next(x for x in result.users if x.id == pid)
                    else:
                        return next(x for x in result.chats if x.id == pid)
                except StopIteration:
                    pass
            try:
                # Nobody with this username, maybe it's an exact name/title
                return await self.get_entity(
                    self.session.get_input_entity(string))
            except ValueError:
                pass

        raise ValueError(
            'Cannot find any entity corresponding to "{}"'.format(string)
        )