def get_peer_id(peer, add_mark=True):
    """
    Finds the ID of the given peer, and converts it to the "bot api" format
    so it the peer can be identified back. User ID is left unmodified,
    chat ID is negated, and channel ID is prefixed with -100.

    The original ID and the peer type class can be returned with
    a call to :meth:`resolve_id(marked_id)`.
    """
    # First we assert it's a Peer TLObject, or early return for integers
    if isinstance(peer, int):
        return peer if add_mark else resolve_id(peer)[0]

    # Tell the user to use their client to resolve InputPeerSelf if we got one
    if isinstance(peer, types.InputPeerSelf):
        _raise_cast_fail(peer, 'int (you might want to use client.get_peer_id)')

    try:
        peer = get_peer(peer)
    except TypeError:
        _raise_cast_fail(peer, 'int')

    if isinstance(peer, types.PeerUser):
        return peer.user_id
    elif isinstance(peer, types.PeerChat):
        # Check in case the user mixed things up to avoid blowing up
        if not (0 < peer.chat_id <= 0x7fffffff):
            peer.chat_id = resolve_id(peer.chat_id)[0]

        return -peer.chat_id if add_mark else peer.chat_id
    else:  # if isinstance(peer, types.PeerChannel):
        # Check in case the user mixed things up to avoid blowing up
        if not (0 < peer.channel_id <= 0x7fffffff):
            peer.channel_id = resolve_id(peer.channel_id)[0]

        if not add_mark:
            return peer.channel_id

        # Concat -100 through math tricks, .to_supergroup() on
        # Madeline IDs will be strictly positive -> log works.
        return -(peer.channel_id + pow(
            10, math.floor(math.log10(peer.channel_id) + 3)))
Finds the ID of the given peer, and converts it to the "bot api" format
    so it the peer can be identified back. User ID is left unmodified,
    chat ID is negated, and channel ID is prefixed with -100.

    The original ID and the peer type class can be returned with
    a call to :meth:`resolve_id(marked_id)`.