mautrix-go/bridgev2/networkid/bridgeid.go
Tulir Asokan f8c3a95de7
Some checks are pending
Go / Lint (latest) (push) Waiting to run
Go / Build (old, libolm) (push) Waiting to run
Go / Build (latest, libolm) (push) Waiting to run
Go / Build (old, goolm) (push) Waiting to run
Go / Build (latest, goolm) (push) Waiting to run
bridgev2: add support for creating groups (#405)
2025-09-01 18:01:20 +03:00

146 lines
6.5 KiB
Go

// Copyright (c) 2024 Tulir Asokan
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Package networkid contains string types used to represent different kinds of identifiers on remote networks.
//
// Except for [BridgeID], all types in this package are only generated by network connectors.
// Network connectors may generate and parse these types any way they want, all other components
// will treat them as opaque identifiers and will not parse them nor assume anything about them.
// However, identifiers are stored in the bridge database, so backwards-compatibility must be
// considered when changing the format.
//
// All IDs are scoped to a bridge, i.e. they don't need to be unique across different bridges.
// However, most IDs need to be globally unique within the bridge, i.e. the same ID must refer
// to the same entity even from another user's point of view. If the remote network does not
// directly provide such globally unique identifiers, the network connector should prefix them
// with a user ID or other identifier to make them unique.
package networkid
import (
"fmt"
"github.com/rs/zerolog"
)
// BridgeID is an opaque identifier for a bridge
type BridgeID string
// PortalID is the ID of a room on the remote network. A portal ID alone should identify group chats
// uniquely, and also DMs when scoped to a user login ID (see [PortalKey]).
type PortalID string
// PortalKey is the unique key of a room on the remote network. It combines a portal ID and a receiver ID.
//
// The Receiver field is generally only used for DMs, and should be empty for group chats.
// The purpose is to segregate DMs by receiver, so that the same DM has separate rooms even
// if both sides are logged into the bridge. Also, for networks that use user IDs as DM chat IDs,
// the receiver is necessary to have separate rooms for separate users who have a DM with the same
// remote user.
//
// It is also permitted to use a non-empty receiver for group chats if there is a good reason to
// segregate them. For example, Telegram's non-supergroups have user-scoped message IDs instead
// of chat-scoped IDs, which is easier to manage with segregated rooms.
//
// As a special case, Receiver MUST be set if the Bridge.Config.SplitPortals flag is set to true.
// The flag is intended for puppeting-only bridges which want multiple logins to create separate portals for each user.
type PortalKey struct {
ID PortalID `json:"portal_id"`
Receiver UserLoginID `json:"portal_receiver,omitempty"`
}
func (pk PortalKey) IsEmpty() bool {
return pk.ID == "" && pk.Receiver == ""
}
func (pk PortalKey) String() string {
if pk.Receiver == "" {
return string(pk.ID)
}
return fmt.Sprintf("%s/%s", pk.ID, pk.Receiver)
}
func (pk PortalKey) MarshalZerologObject(evt *zerolog.Event) {
evt.Str("portal_id", string(pk.ID))
if pk.Receiver != "" {
evt.Str("portal_receiver", string(pk.Receiver))
}
}
// UserID is the ID of a user on the remote network.
//
// User IDs must be globally unique within the bridge for identifying a specific remote user.
type UserID string
// UserLoginID is the ID of the user being controlled on the remote network.
//
// It may be the same shape as [UserID]. However, being the same shape is not required, and the
// central bridge module and Matrix connectors will never assume it is. Instead, the bridge will
// use methods like [maunium.net/go/mautrix/bridgev2.NetworkAPI.IsThisUser] to check if a user ID
// is associated with a given UserLogin.
// The network connector is of course allowed to assume a UserLoginID is equivalent to a UserID,
// because it is the one defining both types.
type UserLoginID string
// MessageID is the ID of a message on the remote network.
//
// Message IDs must be unique across rooms and consistent across users (i.e. globally unique within the bridge).
type MessageID string
// TransactionID is a client-generated identifier for a message send operation on the remote network.
//
// Transaction IDs must be unique across users in a room, but don't need to be unique across different rooms.
type TransactionID string
// RawTransactionID is a client-generated identifier for a message send operation on the remote network.
//
// Unlike TransactionID, RawTransactionID's are only used for sending and don't have any uniqueness requirements.
type RawTransactionID string
// PartID is the ID of a message part on the remote network (e.g. index of image in album).
//
// Part IDs are only unique within a message, not globally.
// To refer to a specific message part globally, use the MessagePartID tuple struct.
type PartID string
// MessagePartID refers to a specific part of a message by combining a message ID and a part ID.
type MessagePartID struct {
MessageID MessageID
PartID PartID
}
// MessageOptionalPartID refers to a specific part of a message by combining a message ID and an optional part ID.
// If the part ID is not set, this should refer to the first part ID sorted alphabetically.
type MessageOptionalPartID struct {
MessageID MessageID
PartID *PartID
}
// PaginationCursor is a cursor used for paginating message history.
type PaginationCursor string
// AvatarID is the ID of a user or room avatar on the remote network.
//
// It may be a real URL, an opaque identifier, or anything in between. It should be an identifier that
// can be acquired from the remote network without downloading the entire avatar.
//
// In general, it is preferred to use a stable identifier which only changes when the avatar changes.
// However, the bridge will also hash the avatar data to check for changes before sending an avatar
// update to Matrix, so the avatar ID being slightly unstable won't be the end of the world.
type AvatarID string
// EmojiID is the ID of a reaction emoji on the remote network.
//
// On networks that only allow one reaction per message, an empty string should be used
// to apply the unique constraints in the database appropriately.
// On networks that allow multiple emojis, this is the unicode emoji or a network-specific shortcode.
type EmojiID string
// MediaID represents a media identifier that can be downloaded from the remote network at any point in the future.
//
// This is used to implement on-demand media downloads. The network connector can ask the Matrix connector
// to generate a content URI from a media ID. Then, when the Matrix connector wants to download the media,
// it will parse the content URI and ask the network connector for the data using the media ID.
type MediaID []byte