simplex-chat/docs/protocol/simplex-chat.schema.json
Evgeny 569832c8de
core: rfc, protocol and types for user reports (#5451)
* core: rfc, protocol and types for user reports

* add comment

* rfc

* moderation rfc

* api, types

* update

* typos

* migration

* update

* report reason

* query

* deleted

* remove auto-accepting conditions for SimpleX Chat Ltd

* api, query

* make indices work

* index without filtering

* query for unread

* postgres: rework chat list pagination query (#5441)

* fix query

* fix

* report counts to stats

* internalMark

* fix parser

* AND

* delete reports on event, fix counters

* test

* remove reports when message is moderated on sending side

---------

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
2025-01-08 09:42:26 +00:00

759 lines
18 KiB
JSON

{
"metadata": {
"description": "JTD schema for SimpleX Chat Protocol messages for chat functions"
},
"definitions": {
"profile": {
"properties": {
"displayName": {
"type": "string",
"metadata": {
"format": "non-empty string, the first character must not be # or @"
}
},
"fullName": {"type": "string"}
},
"optionalProperties": {
"image": {
"type": "string",
"metadata": {
"format": "data URI format for base64 encoded image"
}
},
"contactLink": {"ref": "connReqUri"},
"preferences": {
"type": "string",
"metadata": {
"format": "JSON encoded user preferences"
}
}
},
"additionalProperties": true
},
"groupProfile": {
"properties": {
"displayName": {
"type": "string",
"metadata": {
"format": "non-empty string, the first character must not be # or @"
}
},
"fullName": {"type": "string"}
},
"optionalProperties": {
"image": {
"type": "string",
"metadata": {
"format": "data URI format for base64 encoded image"
}
},
"groupPreferences": {
"type": "string",
"metadata": {
"format": "JSON encoded user preferences"
}
}
},
"additionalProperties": true
},
"msgContainer": {
"properties": {
"content": {"ref": "msgContent"}
},
"optionalProperties": {
"file": {"ref": "fileInvitation"},
"ttl": {"type": "integer"},
"live": {"type": "boolean"},
"quote": {
"properties": {
"msgRef": {"ref": "msgRef"},
"content": {"ref": "msgContent"}
}
},
"forward": {"type": "boolean"}
},
"metadata": {
"comment": "optional properties `quote` and `forward` are mutually exclusive"
}
},
"msgContent": {
"discriminator": "type",
"mapping": {
"text": {
"properties": {
"text": {"type": "string", "metadata": {"comment": "non-empty"}}
}
},
"link": {
"properties": {
"text": {"type": "string", "metadata": {"comment": "non-empty"}},
"preview": {"ref": "linkPreview"}
}
},
"image": {
"properties": {
"text": {"type": "string", "metadata": {"comment": "can be empty"}},
"image": {"ref": "base64url"}
}
},
"video": {
"properties": {
"text": {"type": "string", "metadata": {"comment": "can be empty"}},
"image": {"ref": "base64url"},
"duration": {"type": "integer"}
}
},
"voice": {
"properties": {
"text": {"type": "string", "metadata": {"comment": "can be empty"}},
"duration": {"type": "integer"}
}
},
"file": {
"properties": {
"text": {"type": "string", "metadata": {"comment": "can be empty"}}
}
},
"report": {
"properties": {
"text": {"type": "string", "metadata": {"comment": "can be empty, includes report reason for old clients"}},
"reason": {"enum": ["spam", "illegal", "community", "other"]}
}
}
},
"metadata": {
"comment": "it is RECOMMENDED that the clients support other values in `type` properties showing them as text messages in case `text` property is present"
}
},
"msgReaction" : {
"discriminator": "type",
"mapping": {
"emoji": {
"properties": {
"emoji": {
"type": "string",
"metadata": {"comment": "emoji character"}
}
}
}
}
},
"msgRef": {
"properties": {
"msgId": {"ref": "base64url"},
"sentAt": {
"type": "string",
"metadata": {
"format": "ISO8601 UTC time of the message"
}
},
"sent": {"type": "boolean"}
},
"optionalProperties": {
"memberId": {"ref": "base64url"},
"metadata": {
"comment": "memberId must be present in all group message references, both for sent and received"
}
}
},
"fileInvitation": {
"properties": {
"fileName": {"type": "string"},
"fileSize": {"type": "uint32"}
},
"optionalProperties": {
"fileDigest": {"ref": "base64url"},
"fileConnReq": {"ref": "connReqUri"},
"fileDescr": {"ref": "fileDescription"}
}
},
"fileDescription": {
"properties": {
"fileDescrText": {
"type": "string",
"metadata": {
"format": "XFTP file description part text"
}
},
"fileDescrPartNo": {
"type": "integer",
"metadata": {
"format": "XFTP file description part number"
}
},
"fileDescrComplete": {
"type": "boolean",
"metadata": {
"format": "XFTP file description completion marker"
}
}
}
},
"linkPreview": {
"properties": {
"uri": {"type": "string"},
"title": {"type": "string"},
"description": {"type": "string"},
"image": {"ref": "base64url"}
},
"optionalProperties": {
"content": {"ref": "linkContent"}
}
},
"linkContent": {
"discriminator": "type",
"mapping": {
"page": {},
"image": {},
"video": {
"optionalProperties": {
"duration": {"type": "integer"}
}
}
}
},
"groupInvitation": {
"properties": {
"fromMember": {"ref": "memberIdRole"},
"invitedMember": {"ref": "memberIdRole"},
"connRequest": {"ref": "connReqUri"},
"groupProfile": {"ref": "groupProfile"}
},
"optionalProperties": {
"groupLinkId": {"ref": "base64url"},
"groupSize": {"type": "integer"},
"metadata": {
"comment": "groupLinkId is used to identify invitation via group link"
}
}
},
"groupLinkInvitation": {
"properties": {
"fromMember": {"ref": "memberIdRole"},
"fromMemberName": {"type": "string"},
"invitedMember": {"ref": "memberIdRole"},
"groupProfile": {"ref": "groupProfile"}
},
"optionalProperties": {
"groupSize": {"type": "integer"}
}
},
"memberIdRole": {
"properties": {
"memberId": {"ref": "base64url"},
"memberRole": {"ref": "groupMemberRole"}
}
},
"memberInfo": {
"properties": {
"memberId": {"ref": "base64url"},
"memberRole": {"ref": "groupMemberRole"},
"profile": {"ref": "profile"}
},
"optionalProperties": {
"v": {"ref": "chatVersionRange"}
}
},
"memberRestrictions": {
"properties": {
"restriction": {"ref": "memberRestrictionStatus"}
}
},
"memberRestrictionStatus": {
"enum": ["blocked", "unrestricted"]
},
"chatVersionRange": {
"type": "string",
"metadata": {
"format": "chat version range string encoded as `<min>-<max>`, or as `<number>` if min = max"
}
},
"introInvitation": {
"properties": {
"groupConnReq": {"ref": "connReqUri"}
},
"optionalProperties": {
"directConnReq": {"ref": "connReqUri"}
}
},
"groupMemberRole": {
"enum": ["observer", "author", "member", "admin", "owner"]
},
"callInvitation": {
"properties": {
"callType": {"ref": "callType"}
},
"optionalProperties": {
"callDhPubKey": {"ref": "base64url"}
}
},
"callOffer": {
"properties": {
"callType": {"ref": "callType"},
"rtcSession": {"ref": "webRTCSession"}
},
"optionalProperties": {
"callDhPubKey": {"ref": "base64url"}
}
},
"callAnswer": {
"properties": {
"rtcSession": {"ref": "webRTCSession"}
}
},
"callExtraInfo": {
"properties": {
"rtcExtraInfo": {
"properties": {
"rtcIceCandidates": {"type": "string"}
}
}
}
},
"callType": {
"properties": {
"media": {"enum": ["audio", "video"]},
"capabilities": {
"properties": {
"encryption": {"type": "boolean"}
}
}
}
},
"webRTCSession": {
"properties": {
"rtcSession": {"type": "string"},
"rtcIceCandidates": {"type": "string"}
}
},
"base64url": {
"type": "string",
"metadata": {
"format": "base64url encoded string"
}
},
"connReqUri": {
"type": "string",
"metadata": {
"format": "URI for connection request"
}
}
},
"discriminator": "event",
"mapping": {
"x.contact": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"profile": {"ref": "profile"},
"contactReqId": {"ref": "base64url"}
}
}
}
},
"x.info": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"profile": {"ref": "profile"}
}
}
}
},
"x.info.probe": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"probe": {"ref": "base64url"}
}
}
}
},
"x.info.probe.check": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"probeHash": {"ref": "base64url"}
}
}
}
},
"x.info.probe.ok": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"probe": {"ref": "base64url"}
}
}
}
},
"x.msg.new": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {"ref": "msgContainer"}
}
},
"x.msg.file.descr": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"msgId": {"ref": "base64url"},
"fileDescr": {"ref": "fileDescription"}
}
}
}
},
"x.msg.update": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"msgId": {"ref": "base64url"},
"content": {"ref": "msgContent"}
},
"optionalProperties": {
"ttl": {"type": "integer"},
"live": {"type": "boolean"}
}
}
}
},
"x.msg.del": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"msgId": {"ref": "base64url"}
},
"optionalProperties": {
"memberId": {"ref": "base64url"}
}
}
}
},
"x.msg.react": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"msgId": {"ref": "base64url"},
"reaction": {"ref": "msgReaction"},
"add": {"type": "boolean"}
},
"optionalProperties": {
"memberId": {"ref": "base64url"}
}
}
}
},
"x.file.acpt": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"fileName": {"type": "string"}
}
}
}
},
"x.file.acpt.inv": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"msgId": {"ref": "base64url"},
"fileName": {"type": "string"}
},
"optionalProperties": {
"fileConnReq": {"ref": "connReqUri"}
}
}
}
},
"x.file.cancel": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"msgId": {"ref": "base64url"}
}
}
}
},
"x.direct.del": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {}
}
}
},
"x.grp.inv": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"groupInvitation": {"ref": "groupInvitation"}
}
}
}
},
"x.grp.acpt": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"memberId": {"ref": "base64url"}
}
}
}
},
"x.grp.link.inv": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"groupLinkInvitation": {"ref": "groupLinkInvitation"}
}
}
}
},
"x.grp.link.mem": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"profile": {"ref": "profile"}
}
}
}
},
"x.grp.mem.new": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"memberInfo": {"ref": "memberInfo"}
}
}
}
},
"x.grp.mem.intro": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"memberInfo": {"ref": "memberInfo"}
},
"optionalProperties": {
"memberRestrictions": {"ref": "memberRestrictions"}
}
}
}
},
"x.grp.mem.inv": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"memberId": {"ref": "base64url"},
"memberIntro": {"ref": "introInvitation"}
}
}
}
},
"x.grp.mem.fwd": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"memberInfo": {"ref": "memberInfo"},
"memberIntro": {"ref": "introInvitation"}
}
}
}
},
"x.grp.mem.info": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"memberId": {"ref": "base64url"},
"profile": {"ref": "profile"}
}
}
}
},
"x.grp.mem.role": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"memberId": {"ref": "base64url"},
"role": {"ref": "groupMemberRole"}
}
}
}
},
"x.grp.mem.restrict": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"memberId": {"ref": "base64url"},
"memberRestrictions": {"ref": "memberRestrictions"}
}
}
}
},
"x.grp.mem.con": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"memberId": {"ref": "base64url"}
}
}
}
},
"x.grp.mem.del": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"memberId": {"ref": "base64url"}
}
}
}
},
"x.grp.leave": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {}
}
}
},
"x.grp.del": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {}
}
}
},
"x.grp.info": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"groupProfile": {"ref": "groupProfile"}
}
}
}
},
"x.grp.direct.inv": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"connReq": {"ref": "connReqUri"}
},
"optionalProperties": {
"content": {"ref": "msgContent"}
}
}
}
},
"x.grp.msg.forward": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"memberId": {"ref": "base64url"},
"msg": {
"type": "string",
"metadata": {
"format": "JSON encoded chat message"
}
},
"msgTs": {
"type": "string",
"metadata": {
"format": "ISO8601 UTC time of the message"
}
}
}
}
}
},
"x.call.inv": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"callId": {"ref": "base64url"},
"invitation": {"ref": "callInvitation"}
}
}
}
},
"x.call.offer": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"callId": {"ref": "base64url"},
"offer": {"ref": "callOffer"}
}
}
}
},
"x.call.answer": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"callId": {"ref": "base64url"},
"answer": {"ref": "callAnswer"}
}
}
}
},
"x.call.extra": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"callId": {"ref": "base64url"},
"extra": {"ref": "callExtraInfo"}
}
}
}
},
"x.call.end": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {
"callId": {"ref": "base64url"}
}
}
}
},
"x.ok": {
"properties": {
"msgId": {"ref": "base64url"},
"params": {
"properties": {}
}
}
}
}
}