first pass on signal-server proto file

This commit is contained in:
Jeff Carr 2025-04-04 08:07:52 -05:00
parent 198b217cfa
commit d958fda766
1 changed files with 952 additions and 1018 deletions

View File

@ -31,7 +31,6 @@ message BackupInfo {
// For example, Chats may all be together at the beginning,
// or may each immediately precede its first ChatItem.
message Frame {
// If unset, importers should skip this frame without throwing an error.
oneof item {
AccountData account = 1;
Recipient recipient = 2;
@ -42,8 +41,9 @@ message Frame {
NotificationProfile notificationProfile = 7;
ChatFolder chatFolder = 8;
}
}
// If unset, importers should skip this frame without throwing an error.
}
message AccountData {
enum PhoneNumberSharingMode {
UNKNOWN = 0; // Interpret as "Nobody"
@ -62,12 +62,10 @@ message AccountData {
PINK = 7;
PURPLE = 8;
}
bytes entropy = 1; // 32 bytes of entropy used for encryption
bytes serverId = 2; // 16 bytes of encoded UUID provided by the server
Color color = 3;
}
message AccountSettings {
bool readReceipts = 1;
bool sealedSenderIndicators = 2;
@ -89,25 +87,23 @@ message AccountData {
ChatStyle defaultChatStyle = 18;
repeated ChatStyle.CustomChatColor customChatColors = 19;
}
message SubscriberData {
bytes subscriberId = 1;
string currencyCode = 2;
bool manuallyCancelled = 3;
}
message IAPSubscriberData {
bytes subscriberId = 1;
// If unset, importers should ignore the subscriber data without throwing an error.
oneof iapSubscriptionId {
// Identifies an Android Play Store IAP subscription.
string purchaseToken = 2;
// Identifies an iOS App Store IAP subscription.
uint64 originalTransactionId = 3;
}
}
bytes subscriberId = 1;
// If unset, importers should ignore the subscriber data without throwing an error.
}
bytes profileKey = 1;
optional string username = 2;
UsernameLink usernameLink = 3;
@ -115,15 +111,12 @@ message AccountData {
string familyName = 5;
string avatarUrlPath = 6;
SubscriberData donationSubscriberData = 7;
reserved 8; // A deprecated format // backupsSubscriberData
= 8; // A deprecated format // backupsSubscriberData
AccountSettings accountSettings = 9;
IAPSubscriberData backupsSubscriberData = 10;
string svrPin = 11;
}
message Recipient {
uint64 id = 1; // generated id for reference only within this file
// If unset, importers should skip this frame without throwing an error.
oneof destination {
Contact contact = 2;
Group group = 3;
@ -132,17 +125,10 @@ message Recipient {
ReleaseNotes releaseNotes = 6;
CallLink callLink = 7;
}
}
// If unset - computed as the value of the first byte of SHA-256(msg=CONTACT_ID)
// modulo the count of colors. Once set the avatar color for a recipient is
// never recomputed or changed.
//
// `CONTACT_ID` is the first available identifier from the list:
// - ServiceIdToBinary(ACI)
// - E164
// - ServiceIdToBinary(PNI)
// - Group Id
uint64 id = 1; // generated id for reference only within this file
// If unset, importers should skip this frame without throwing an error.
}
enum AvatarColor {
A100 = 0;
A110 = 1;
@ -164,8 +150,8 @@ message Contact {
VERIFIED = 1;
UNVERIFIED = 2; // Was once verified and is now unverified
}
message Registered {}
// isEmpty
// footer was empty
message NotRegistered {
uint64 unregisteredTimestamp = 1;
}
@ -208,29 +194,14 @@ message Contact {
string systemNickname = 20;
optional AvatarColor avatarColor = 21;
}
message Group {
enum StorySendMode {
DEFAULT = 0; // A valid value -- indicates unset by the user
DISABLED = 1;
ENABLED = 2;
}
bytes masterKey = 1;
bool whitelisted = 2;
bool hideStory = 3;
StorySendMode storySendMode = 4;
GroupSnapshot snapshot = 5;
bool blocked = 6;
optional AvatarColor avatarColor = 7;
// These are simply plaintext copies of the groups proto from Groups.proto.
// They should be kept completely in-sync with Groups.proto.
// These exist to allow us to have the latest snapshot of a group during restoration without having to hit the network.
// We would use Groups.proto if we could, but we want a plaintext version to improve export readability.
// For documentation, defer to Groups.proto. The only name change is Group -> GroupSnapshot to avoid the naming conflict.
message GroupSnapshot {
reserved 1; // The field is deprecated in the context of static group state // publicKey
= 1; // The field is deprecated in the context of static group state // publicKey
GroupAttributeBlob title = 2;
GroupAttributeBlob description = 11;
string avatarUrl = 3;
@ -244,49 +215,42 @@ message Group {
bool announcements_only = 12;
repeated MemberBanned members_banned = 13;
}
message GroupAttributeBlob {
// If unset, consider the field it represents to not be present
oneof content {
string title = 1;
bytes avatar = 2;
uint32 disappearingMessagesDuration = 3;
string descriptionText = 4;
}
// If unset, consider the field it represents to not be present
}
message Member {
enum Role {
UNKNOWN = 0; // Intepret as "Default"
DEFAULT = 1;
ADMINISTRATOR = 2;
}
bytes userId = 1;
Role role = 2;
reserved 3; // This field is ignored in Backups, in favor of Contact frames for members // profileKey
reserved 4; // This field is deprecated in the context of static group state // presentation
= 3; // This field is ignored in Backups, in favor of Contact frames for members // profileKey
= 4; // This field is deprecated in the context of static group state // presentation
uint32 joinedAtVersion = 5;
}
message MemberPendingProfileKey {
Member member = 1;
bytes addedByUserId = 2;
uint64 timestamp = 3;
}
message MemberPendingAdminApproval {
bytes userId = 1;
reserved 2; // This field is ignored in Backups, in favor of Contact frames for members // profileKey
reserved 3; // This field is deprecated in the context of static group state // presentation
= 2; // This field is ignored in Backups, in favor of Contact frames for members // profileKey
= 3; // This field is deprecated in the context of static group state // presentation
uint64 timestamp = 4;
}
message MemberBanned {
bytes userId = 1;
uint64 timestamp = 2;
}
message AccessControl {
enum AccessRequired {
UNKNOWN = 0; // Intepret as "Unsatisfiable"
@ -300,14 +264,25 @@ message Group {
AccessRequired members = 2;
AccessRequired addFromInviteLink = 3;
}
}
bytes masterKey = 1;
bool whitelisted = 2;
bool hideStory = 3;
StorySendMode storySendMode = 4;
GroupSnapshot snapshot = 5;
bool blocked = 6;
optional AvatarColor avatarColor = 7;
// These are simply plaintext copies of the groups proto from Groups.proto.
// They should be kept completely in-sync with Groups.proto.
// These exist to allow us to have the latest snapshot of a group during restoration without having to hit the network.
// We would use Groups.proto if we could, but we want a plaintext version to improve export readability.
// For documentation, defer to Groups.proto. The only name change is Group -> GroupSnapshot to avoid the naming conflict.
}
message Self {
optional AvatarColor avatarColor = 1;
}
message ReleaseNotes {}
// isEmpty
message Chat {
uint64 id = 1; // generated id for reference only within this file
uint64 recipientId = 2;
@ -342,7 +317,6 @@ message CallLink {
Restrictions restrictions = 4;
uint64 expirationMs = 5;
}
message AdHocCall {
enum State {
UNKNOWN_STATE = 0; // Interpret as "Generic"
@ -355,19 +329,18 @@ message AdHocCall {
State state = 3;
uint64 callTimestamp = 4;
}
message DistributionListItem {
oneof item {
uint64 deletionTimestamp = 2;
DistributionList distributionList = 3;
}
// distribution ids are UUIDv4s. "My Story" is represented
// by an all-0 UUID (00000000-0000-0000-0000-000000000000).
bytes distributionId = 1; // distribution list ids are uuids
// If unset, importers should skip the item entirely without showing an error.
oneof item {
uint64 deletionTimestamp = 2;
DistributionList distributionList = 3;
}
}
message DistributionList {
enum PrivacyMode {
UNKNOWN = 0; // Interpret as "Only with"
@ -381,7 +354,6 @@ message DistributionList {
PrivacyMode privacyMode = 3;
repeated uint64 memberRecipientIds = 4; // generated recipient id
}
message ChatItem {
message IncomingMessageDetails {
uint64 dateReceived = 1;
@ -389,30 +361,16 @@ message ChatItem {
bool read = 3;
bool sealedSender = 4;
}
message OutgoingMessageDetails {
repeated SendStatus sendStatus = 1;
}
message DirectionlessMessageDetails {
}
uint64 chatId = 1; // conversation id
uint64 authorId = 2; // recipient id
uint64 dateSent = 3;
optional uint64 expireStartDate = 4; // timestamp of when expiration timer started ticking down
optional uint64 expiresInMs = 5; // how long timer of message is (ms)
repeated ChatItem revisions = 6; // ordered from oldest to newest
bool sms = 7;
// If unset, importers should skip this item without throwing an error.
oneof directionalDetails {
IncomingMessageDetails incoming = 8;
OutgoingMessageDetails outgoing = 9;
DirectionlessMessageDetails directionless = 10;
}
// If unset, importers should skip this item without throwing an error.
oneof item {
StandardMessage standardMessage = 11;
ContactMessage contactMessage = 12;
@ -424,11 +382,22 @@ message ChatItem {
ViewOnceMessage viewOnceMessage = 18;
DirectStoryReplyMessage directStoryReplyMessage = 19; // group story reply messages are not backed up
}
uint64 chatId = 1; // conversation id
uint64 authorId = 2; // recipient id
uint64 dateSent = 3;
optional uint64 expireStartDate = 4; // timestamp of when expiration timer started ticking down
optional uint64 expiresInMs = 5; // how long timer of message is (ms)
repeated ChatItem revisions = 6; // ordered from oldest to newest
bool sms = 7;
// If unset, importers should skip this item without throwing an error.
// If unset, importers should skip this item without throwing an error.
}
message SendStatus {
message Pending {}
// isEmpty
// footer was empty
message Sent {
bool sealedSender = 1;
}
@ -472,7 +441,6 @@ message SendStatus {
Failed failed = 9;
}
}
message Text {
string body = 1;
repeated BodyRange bodyRanges = 2;
@ -497,24 +465,22 @@ message DirectStoryReplyMessage {
Text text = 1;
FilePointer longText = 2;
}
// If unset, importers should ignore the message without throwing an error.
oneof reply {
TextReply textReply = 1;
string emoji = 2;
}
repeated Reaction reactions = 3;
reserved 4; // storySentTimestamp
}
// If unset, importers should ignore the message without throwing an error.
repeated Reaction reactions = 3;
= 4; // storySentTimestamp
}
message PaymentNotification {
message TransactionDetails {
message MobileCoinTxoIdentification { // Used to map to payments on the ledger
repeated bytes publicKey = 1; // for received transactions
repeated bytes keyImages = 2; // for sent transactions
}
message FailedTransaction { // Failed payments can't be synced from the ledger
enum FailureReason {
GENERIC = 0; // A valid value -- reason unknown
@ -523,7 +489,6 @@ message PaymentNotification {
}
FailureReason reason = 1;
}
message Transaction {
enum Status {
INITIAL = 0; // A valid value -- state unconfirmed
@ -542,20 +507,18 @@ message PaymentNotification {
optional bytes transaction = 6; // mobile coin blobs
optional bytes receipt = 7; // mobile coin blobs
}
// If unset, importers should treat the transaction as successful with no metadata.
oneof payment {
Transaction transaction = 1;
FailedTransaction failedTransaction = 2;
}
}
// If unset, importers should treat the transaction as successful with no metadata.
}
optional string amountMob = 1; // stored as a decimal string, e.g. 1.00001
optional string feeMob = 2; // stored as a decimal string, e.g. 1.00001
optional string note = 3;
TransactionDetails transactionDetails = 4;
}
message GiftBadge {
enum State {
UNOPENED = 0; // A valid state
@ -567,7 +530,6 @@ message GiftBadge {
bytes receiptCredentialPresentation = 1;
State state = 2;
}
message ViewOnceMessage {
// Will be null for viewed messages
MessageAttachment attachment = 1;
@ -583,7 +545,6 @@ message ContactAttachment {
string middleName = 5;
string nickname = 6;
}
message Phone {
enum Type {
UNKNOWN = 0; // Interpret as "Home"
@ -592,12 +553,10 @@ message ContactAttachment {
WORK = 3;
CUSTOM = 4;
}
string value = 1;
Type type = 2;
string label = 3;
}
message Email {
enum Type {
UNKNOWN = 0; // Intepret as "Home"
@ -606,12 +565,10 @@ message ContactAttachment {
WORK = 3;
CUSTOM = 4;
}
string value = 1;
Type type = 2;
string label = 3;
}
message PostalAddress {
enum Type {
UNKNOWN = 0; // Interpret as "Home"
@ -630,7 +587,6 @@ message ContactAttachment {
string postcode = 8;
string country = 9;
}
optional Name name = 1;
repeated Phone number = 3;
repeated Email email = 4;
@ -638,15 +594,12 @@ message ContactAttachment {
optional FilePointer avatar = 6;
string organization = 7;
}
message StickerMessage {
Sticker sticker = 1;
repeated Reaction reactions = 2;
}
// Tombstone for remote delete
message RemoteDeletedMessage {}
// isEmpty
message Sticker {
bytes packId = 1;
bytes packKey = 2;
@ -670,9 +623,6 @@ message LinkPreview {
// A FilePointer on a message that has additional
// metadata that applies only to message attachments.
message MessageAttachment {
// Similar to SignalService.AttachmentPointer.Flags,
// but explicitly mutually exclusive. Note the different raw values
// (non-zero starting values are not supported in proto3.)
enum Flag {
NONE = 0; // A valid value -- no flag applied
VOICE_MESSAGE = 1;
@ -680,6 +630,10 @@ message MessageAttachment {
GIF = 3;
}
// Similar to SignalService.AttachmentPointer.Flags,
// but explicitly mutually exclusive. Note the different raw values
// (non-zero starting values are not supported in proto3.)
FilePointer pointer = 1;
Flag flag = 2;
bool wasDownloaded = 3;
@ -687,9 +641,7 @@ message MessageAttachment {
// owning message. See: SignalService.AttachmentPointer.clientUuid.
optional bytes clientUuid = 4;
}
message FilePointer {
// References attachments in the backup (media) storage tier.
message BackupLocator {
string mediaName = 1;
// If present, the cdn number of the succesful upload.
@ -703,11 +655,6 @@ message FilePointer {
optional string transitCdnKey = 6;
optional uint32 transitCdnNumber = 7;
}
// References attachments in the transit storage tier.
// May be downloaded or not when the backup is generated;
// primarily for free-tier users who cannot copy the
// attachments to the backup (media) storage tier.
message AttachmentLocator {
string cdnKey = 1;
uint32 cdnNumber = 2;
@ -716,21 +663,28 @@ message FilePointer {
bytes digest = 5;
uint32 size = 6;
}
message InvalidAttachmentLocator {
}
oneof locator {
BackupLocator backupLocator = 1;
AttachmentLocator attachmentLocator = 2;
InvalidAttachmentLocator invalidAttachmentLocator = 3;
}
// References attachments in the backup (media) storage tier.
// References attachments in the transit storage tier.
// May be downloaded or not when the backup is generated;
// primarily for free-tier users who cannot copy the
// attachments to the backup (media) storage tier.
// References attachments that are invalid in such a way where download
// cannot be attempted. Could range from missing digests to missing
// CDN keys or anything else that makes download attempts impossible.
// This serves as a 'tombstone' so that the UX can show that an attachment
// did exist, but for whatever reason it's not retrievable.
message InvalidAttachmentLocator {
}
// If unset, importers should consider it to be an InvalidAttachmentLocator without throwing an error.
oneof locator {
BackupLocator backupLocator = 1;
AttachmentLocator attachmentLocator = 2;
InvalidAttachmentLocator invalidAttachmentLocator = 3;
}
optional string contentType = 4;
optional bytes incrementalMac = 5;
@ -741,7 +695,6 @@ message FilePointer {
optional string caption = 10;
optional string blurHash = 11;
}
message Quote {
enum Type {
UNKNOWN = 0; // Interpret as "Normal"
@ -749,7 +702,6 @@ message Quote {
GIFT_BADGE = 2;
VIEW_ONCE = 3;
}
message QuotedAttachment {
optional string contentType = 1;
optional string fileName = 2;
@ -762,7 +714,6 @@ message Quote {
repeated QuotedAttachment attachments = 4;
Type type = 5;
}
message BodyRange {
enum Style {
NONE = 0; // Importers should ignore the body range without throwing an error.
@ -772,6 +723,10 @@ message BodyRange {
STRIKETHROUGH = 4;
MONOSPACE = 5;
}
oneof associatedValue {
bytes mentionAci = 3;
Style style = 4;
}
// 'start' and 'length' are measured in UTF-16 code units.
// They may refer to offsets in a longText attachment.
@ -779,12 +734,7 @@ message BodyRange {
uint32 length = 2;
// If unset, importers should ignore the body range without throwing an error.
oneof associatedValue {
bytes mentionAci = 3;
Style style = 4;
}
}
message Reaction {
string emoji = 1;
uint64 authorId = 2;
@ -795,7 +745,6 @@ message Reaction {
}
message ChatUpdateMessage {
// If unset, importers should ignore the update message without throwing an error.
oneof update {
SimpleChatUpdate simpleUpdate = 1;
GroupChangeChatUpdate groupChange = 2;
@ -807,21 +756,20 @@ message ChatUpdateMessage {
GroupCall groupCall = 8;
LearnedProfileChatUpdate learnedProfileChange = 9;
}
}
// If unset, importers should ignore the update message without throwing an error.
}
message IndividualCall {
enum Type {
UNKNOWN_TYPE = 0; // Interpret as "Audio call"
AUDIO_CALL = 1;
VIDEO_CALL = 2;
}
enum Direction {
UNKNOWN_DIRECTION = 0; // Interpret as "Incoming"
INCOMING = 1;
OUTGOING = 2;
}
enum State {
UNKNOWN_STATE = 0; // Interpret as "Accepted"
ACCEPTED = 1;
@ -841,7 +789,6 @@ message IndividualCall {
uint64 startedCallTimestamp = 5;
bool read = 6;
}
message GroupCall {
enum State {
UNKNOWN_STATE = 0; // Interpret as "Generic"
@ -872,7 +819,6 @@ message GroupCall {
optional uint64 endedCallTimestamp = 6; // The time the call ended.
bool read = 7;
}
message SimpleChatUpdate {
enum Type {
UNKNOWN = 0; // Importers should skip the update without throwing an error.
@ -896,7 +842,6 @@ message SimpleChatUpdate {
Type type = 1;
}
// For 1:1 chat updates only.
// For group thread updates use GroupExpirationTimerUpdate.
message ExpirationTimerChatUpdate {
@ -909,13 +854,13 @@ message ProfileChangeChatUpdate {
}
message LearnedProfileChatUpdate {
// If unset, importers should consider the previous name to be an empty string.
oneof previousName {
uint64 e164 = 1;
string username = 2;
}
}
// If unset, importers should consider the previous name to be an empty string.
}
message ThreadMergeChatUpdate {
uint64 previousE164 = 1;
}
@ -926,7 +871,6 @@ message SessionSwitchoverChatUpdate {
message GroupChangeChatUpdate {
message Update {
// If unset, importers should consider it to be a GenericGroupUpdate with unset updaterAci
oneof update {
GenericGroupUpdate genericGroupUpdate = 1;
GroupCreationUpdate groupCreationUpdate = 2;
@ -963,13 +907,13 @@ message GroupChangeChatUpdate {
GroupSequenceOfRequestsAndCancelsUpdate groupSequenceOfRequestsAndCancelsUpdate = 33;
GroupExpirationTimerUpdate groupExpirationTimerUpdate = 34;
}
}
// If unset, importers should consider it to be a GenericGroupUpdate with unset updaterAci
}
// Must be one or more; all updates batched together came from
// a single batched group state update.
repeated Update updates = 1;
}
message GenericGroupUpdate {
optional bytes updaterAci = 1;
}
@ -1095,7 +1039,6 @@ message GroupInvitationRevokedUpdate {
optional bytes updaterAci = 1;
repeated Invitee invitees = 2;
}
message GroupJoinRequestUpdate {
bytes requestorAci = 1;
}
@ -1144,13 +1087,8 @@ message GroupMemberJoinedByLinkUpdate {
bytes newMemberAci = 1;
}
// A gv1->gv2 migration occurred.
message GroupV2MigrationUpdate {}
// Another user migrated gv1->gv2 but was unable to add
// the local user and invited them instead.
message GroupV2MigrationSelfInvitedUpdate {}
// isEmpty
// isEmpty
// The local user migrated gv1->gv2 but was unable to
// add some members and invited them instead.
// (Happens if we don't have the invitee's profile key)
@ -1182,20 +1120,17 @@ message ChatStyle {
repeated fixed32 colors = 2; // 0xAARRGGBB
repeated float positions = 3; // percent from 0 to 1
}
message CustomChatColor {
uint64 id = 1;
// If unset, use the default chat color
oneof color {
fixed32 solid = 2; // 0xAARRGGBB
Gradient gradient = 3;
}
}
uint64 id = 1;
// If unset, use the default chat color
}
message AutomaticBubbleColor {
}
enum WallpaperPreset {
UNKNOWN_WALLPAPER_PRESET = 0; // Interpret as the wallpaper being unset
SOLID_BLUSH = 1;
@ -1220,7 +1155,6 @@ message ChatStyle {
GRADIENT_SKY = 20;
GRADIENT_PEACH = 21;
}
enum BubbleColorPreset {
UNKNOWN_BUBBLE_COLOR_PRESET = 0; // Interpret as the user's default chat bubble color
SOLID_ULTRAMARINE = 1;
@ -1246,16 +1180,12 @@ message ChatStyle {
GRADIENT_SEA = 21;
GRADIENT_TANGERINE = 22;
}
// If unset, importers should consider there to be no wallpaper.
oneof wallpaper {
WallpaperPreset wallpaperPreset = 1;
// This `FilePointer` is expected not to contain a `fileName`, `width`,
// `height`, or `caption`.
FilePointer wallpaperPhoto = 2;
}
// If unset, importers should consider it to be AutomaticBubbleColor
oneof bubbleColor {
// Bubble setting is automatically determined based on the wallpaper setting,
// or `SOLID_ULTRAMARINE` for `noWallpaper`
@ -1266,9 +1196,12 @@ message ChatStyle {
uint64 customColorId = 5;
}
// If unset, importers should consider there to be no wallpaper.
// If unset, importers should consider it to be AutomaticBubbleColor
bool dimWallpaperInDarkMode = 7;
}
message NotificationProfile {
enum DayOfWeek {
UNKNOWN = 0; // Interpret as "Monday"
@ -1293,15 +1226,15 @@ message NotificationProfile {
uint32 scheduleEndTime = 10; // 24-hour clock int, 0000-2359 (e.g., 15, 900, 1130, 2345)
repeated DayOfWeek scheduleDaysEnabled = 11;
}
message ChatFolder {
// Represents the default "All chats" folder record vs all other custom folders
enum FolderType {
UNKNOWN = 0; // Interpret as "Custom"
ALL = 1;
CUSTOM = 2;
}
// Represents the default "All chats" folder record vs all other custom folders
string name = 1;
bool showOnlyUnread = 2;
bool showMutedChats = 3;
@ -1313,3 +1246,4 @@ message ChatFolder {
repeated uint64 includedRecipientIds = 7; // generated recipient id of groups, contacts, and/or note to self
repeated uint64 excludedRecipientIds = 8; // generated recipient id of groups, contacts, and/or note to self
}
// footer was empty