Merge branch 'master' of github.com:matrix-org/matrix-doc

pull/977/head
Oddvar Lovaas 9 years ago
commit 04c2fa23e3

@ -45,7 +45,7 @@ paths:
properties:
presence:
type: string
enum: ["online", "offline", "unavailable", "free_for_chat"]
enum: ["online", "offline", "unavailable"]
description: The new presence state.
status_msg:
type: string
@ -90,7 +90,7 @@ paths:
properties:
presence:
type: string
enum: ["online", "offline", "unavailable", "free_for_chat"]
enum: ["online", "offline", "unavailable"]
description: This user's presence.
last_active_ago:
type: integer
@ -100,6 +100,10 @@ paths:
status_msg:
type: [string, "null"]
description: The state message for this user if one was set.
currently_active:
type: boolean
description: "Whether the user is currently active"
required: ["presence"]
404:
description: |-
There is no presence state for this user. This user may not exist or
@ -181,8 +185,6 @@ paths:
[
{
"content": {
"avatar_url": "mxc://matrix.org/AfwefuigfWEfhuiPP",
"displayname": "Alice Margatroid",
"last_active_ago": 395,
"presence": "offline",
"user_id": "@alice:matrix.org"
@ -191,11 +193,10 @@ paths:
},
{
"content": {
"avatar_url": "mxc://matrix.org/FWEhuiwegfWEfhuiwf",
"displayname": "Marisa Kirisame",
"last_active_ago": 16874,
"presence": "online",
"user_id": "@marisa:matrix.org"
"user_id": "@marisa:matrix.org",
"currently_active": true
},
"type": "m.presence"
}

@ -360,7 +360,8 @@ paths:
x-example: someRuleId
description: |-
Use 'before' with a ``rule_id`` as its value to make the new rule the
next-most important rule with respect to the given rule.
next-most important rule with respect to the given user defined rule.
It is not possible to add a rule relative to a predefined server rule.
- in: query
type: string
name: after
@ -368,7 +369,8 @@ paths:
x-example: anotherRuleId
description: |-
This makes the new rule the next-less important rule relative to the
given rule.
given user defined rule. It is not possible to add a rule relative
to a predefined server rule.
- in: body
name: pushrule
description: |-

@ -7,6 +7,7 @@
federated aliases
- ``GET /directory/room/{roomAlias}`` cannot return a 409; the ``PUT``
endpoint can, however.
- Clarify the behaviour of the ``m.room.power_levels`` event.
r0.1.0
======

@ -3,6 +3,7 @@
"avatar_url": "mxc://localhost:wefuiwegh8742w",
"last_active_ago": 2478593,
"presence": "online",
"currently_active": false,
"user_id": "@example:localhost"
},
"event_id": "$WLGTSEFSEF:localhost",

@ -7,6 +7,7 @@
"m.room.power_levels": 100
},
"events_default": 0,
"invite": 50,
"kick": 50,
"redact": 50,
"state_default": 50,

@ -24,7 +24,11 @@
"presence": {
"type": "string",
"description": "The presence state for this user.",
"enum": ["online", "offline", "unavailable", "free_for_chat", "hidden"]
"enum": ["online", "offline", "unavailable"]
},
"currently_active": {
"type": boolean,
"description": "Whether the user is currently active"
},
"user_id": {
"type": "string",

@ -1,31 +1,24 @@
{
"type": "object",
"title": "Informs the room about what room aliases it has been given.",
"description": "This event is sent by a homeserver directly to inform of changes to the list of aliases it knows about for that room. The ``state_key`` for this event is set to the homeserver which owns the room alias. The entire set of known aliases for the room is the union of all the ``m.room.aliases`` events, one for each homeserver. Clients **should** check the validity of any room alias given in this list before presenting it to the user as trusted fact. The lists given by this event should be considered simply as advice on which aliases might exist, for which the client can perform the lookup to confirm whether it receives the correct room ID.",
"allOf": [{
"$ref": "core-event-schema/state_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"aliases": {
"type": "array",
"description": "A list of room aliases.",
"items": {
"type": "string"
}
}
},
"required": ["aliases"]
},
"state_key": {
"type": "string",
"description": "The homeserver domain which owns these room aliases."
},
"type": {
"type": "string",
"enum": ["m.room.aliases"]
}
}
}
---
allOf:
- $ref: core-event-schema/state_event.yaml
description: 'This event is sent by a homeserver directly to inform of changes to the list of aliases it knows about for that room. The ``state_key`` for this event is set to the homeserver which owns the room alias. The entire set of known aliases for the room is the union of all the ``m.room.aliases`` events, one for each homeserver. Clients **should** check the validity of any room alias given in this list before presenting it to the user as trusted fact. The lists given by this event should be considered simply as advice on which aliases might exist, for which the client can perform the lookup to confirm whether it receives the correct room ID.'
properties:
content:
properties:
aliases:
description: A list of room aliases.
items:
type: string
type: array
required:
- aliases
type: object
state_key:
description: The homeserver domain which owns these room aliases.
type: string
type:
enum:
- m.room.aliases
type: string
title: Informs the room about what room aliases it has been given.
type: object

@ -1,49 +1,38 @@
{
"title": "RoomAvatar",
"description": "A picture that is associated with the room. This can be displayed alongside the room information.",
"type": "object",
"allOf": [{
"$ref": "core-event-schema/state_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "The URL to the image."
},
"thumbnail_url": {
"type": "string",
"description": "The URL to the thumbnail of the image."
},
"thumbnail_info": {
"type": "object",
"title": "ImageInfo",
"description": "Metadata about the image referred to in ``thumbnail_url``.",
"allOf": [{
"$ref": "core-event-schema/msgtype_infos/image_info.yaml"
}]
},
"info": {
"type": "object",
"title": "ImageInfo",
"description": "Metadata about the image referred to in ``url``.",
"allOf": [{
"$ref": "core-event-schema/msgtype_infos/image_info.yaml"
}]
}
},
"required": ["url"]
},
"state_key": {
"type": "string",
"description": "A zero-length string.",
"pattern": "^$"
},
"type": {
"type": "string",
"enum": ["m.room.avatar"]
}
}
}
---
allOf:
- $ref: core-event-schema/state_event.yaml
description: A picture that is associated with the room. This can be displayed alongside the room information.
properties:
content:
properties:
info:
allOf:
- $ref: core-event-schema/msgtype_infos/image_info.yaml
description: Metadata about the image referred to in ``url``.
title: ImageInfo
type: object
thumbnail_info:
allOf:
- $ref: core-event-schema/msgtype_infos/image_info.yaml
description: Metadata about the image referred to in ``thumbnail_url``.
title: ImageInfo
type: object
thumbnail_url:
description: The URL to the thumbnail of the image.
type: string
url:
description: The URL to the image.
type: string
required:
- url
type: object
state_key:
description: A zero-length string.
pattern: '^$'
type: string
type:
enum:
- m.room.avatar
type: string
title: RoomAvatar
type: object

@ -1,28 +1,21 @@
{
"type": "object",
"title": "Informs the room as to which alias is the canonical one.",
"description": "This event is used to inform the room about which alias should be considered the canonical one. This could be for display purposes or as suggestion to users which alias to use to advertise the room.",
"allOf": [{
"$ref": "core-event-schema/state_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"alias": {
"type": "string",
"description": "The canonical alias."
}
}
},
"state_key": {
"type": "string",
"description": "A zero-length string.",
"pattern": "^$"
},
"type": {
"type": "string",
"enum": ["m.room.canonical_alias"]
}
}
}
---
allOf:
- $ref: core-event-schema/state_event.yaml
description: This event is used to inform the room about which alias should be considered the canonical one. This could be for display purposes or as suggestion to users which alias to use to advertise the room.
properties:
content:
properties:
alias:
description: The canonical alias.
type: string
type: object
state_key:
description: A zero-length string.
pattern: '^$'
type: string
type:
enum:
- m.room.canonical_alias
type: string
title: Informs the room as to which alias is the canonical one.
type: object

@ -1,33 +1,26 @@
{
"type": "object",
"title": "The first event in the room.",
"description": "This is the first event in a room and cannot be changed. It acts as the root of all other events.",
"allOf": [{
"$ref": "core-event-schema/state_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"creator": {
"type": "string",
"description": "The ``user_id`` of the room creator. This is set by the homeserver."
},
"m.federate": {
"type": "boolean",
"description": "Whether users on other servers can join this room. Defaults to ``true`` if key does not exist."
}
},
"required": ["creator"]
},
"state_key": {
"type": "string",
"description": "A zero-length string.",
"pattern": "^$"
},
"type": {
"type": "string",
"enum": ["m.room.create"]
}
}
}
---
allOf:
- $ref: core-event-schema/state_event.yaml
description: This is the first event in a room and cannot be changed. It acts as the root of all other events.
properties:
content:
properties:
creator:
description: The ``user_id`` of the room creator. This is set by the homeserver.
type: string
m.federate:
description: Whether users on other servers can join this room. Defaults to ``true`` if key does not exist.
type: boolean
required:
- creator
type: object
state_key:
description: A zero-length string.
pattern: '^$'
type: string
type:
enum:
- m.room.create
type: string
title: The first event in the room.
type: object

@ -1,30 +1,26 @@
{
"type": "object",
"title": "Controls whether guest users are allowed to join rooms.",
"description": "This event controls whether guest users are allowed to join rooms. If this event is absent, servers should act as if it is present and has the guest_access value \"forbidden\".",
"allOf": [{
"$ref": "core-event-schema/state_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"guest_access": {
"type": "string",
"description": "Whether guests can join the room.",
"enum": ["can_join", "forbidden"]
}
},
"required": ["guest_access"]
},
"state_key": {
"type": "string",
"description": "A zero-length string.",
"pattern": "^$"
},
"type": {
"type": "string",
"enum": ["m.room.guest_access"]
}
}
}
---
allOf:
- $ref: core-event-schema/state_event.yaml
description: 'This event controls whether guest users are allowed to join rooms. If this event is absent, servers should act as if it is present and has the guest_access value "forbidden".'
properties:
content:
properties:
guest_access:
description: Whether guests can join the room.
enum:
- can_join
- forbidden
type: string
required:
- guest_access
type: object
state_key:
description: A zero-length string.
pattern: '^$'
type: string
type:
enum:
- m.room.guest_access
type: string
title: Controls whether guest users are allowed to join rooms.
type: object

@ -1,30 +1,28 @@
{
"type": "object",
"title": "Controls visibility of history.",
"description": "This event controls whether a user can see the events that happened in a room from before they joined.",
"allOf": [{
"$ref": "core-event-schema/state_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"history_visibility": {
"type": "string",
"description": "Who can see the room history.",
"enum": ["invited","joined","shared","world_readable"]
}
},
"required": ["history_visibility"]
},
"state_key": {
"type": "string",
"description": "A zero-length string.",
"pattern": "^$"
},
"type": {
"type": "string",
"enum": ["m.room.history_visibility"]
}
}
}
---
allOf:
- $ref: core-event-schema/state_event.yaml
description: This event controls whether a user can see the events that happened in a room from before they joined.
properties:
content:
properties:
history_visibility:
description: Who can see the room history.
enum:
- invited
- joined
- shared
- world_readable
type: string
required:
- history_visibility
type: object
state_key:
description: A zero-length string.
pattern: '^$'
type: string
type:
enum:
- m.room.history_visibility
type: string
title: Controls visibility of history.
type: object

@ -1,30 +1,28 @@
{
"type": "object",
"title": "Describes how users are allowed to join the room.",
"description": "A room may be ``public`` meaning anyone can join the room without any prior action. Alternatively, it can be ``invite`` meaning that a user who wishes to join the room must first receive an invite to the room from someone already inside of the room. Currently, ``knock`` and ``private`` are reserved keywords which are not implemented.",
"allOf": [{
"$ref": "core-event-schema/state_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"join_rule": {
"type": "string",
"description": "The type of rules used for users wishing to join this room.",
"enum": ["public","knock","invite","private"]
}
},
"required": ["join_rule"]
},
"state_key": {
"type": "string",
"description": "A zero-length string.",
"pattern": "^$"
},
"type": {
"type": "string",
"enum": ["m.room.join_rules"]
}
}
}
---
allOf:
- $ref: core-event-schema/state_event.yaml
description: 'A room may be ``public`` meaning anyone can join the room without any prior action. Alternatively, it can be ``invite`` meaning that a user who wishes to join the room must first receive an invite to the room from someone already inside of the room. Currently, ``knock`` and ``private`` are reserved keywords which are not implemented.'
properties:
content:
properties:
join_rule:
description: The type of rules used for users wishing to join this room.
enum:
- public
- knock
- invite
- private
type: string
required:
- join_rule
type: object
state_key:
description: A zero-length string.
pattern: '^$'
type: string
type:
enum:
- m.room.join_rules
type: string
title: Describes how users are allowed to join the room.
type: object

@ -1,95 +1,105 @@
{
"type": "object",
"title": "The current membership state of a user in the room.",
"description": "Adjusts the membership state for a user in a room. It is preferable to use the membership APIs (``/rooms/<room id>/invite`` etc) when performing membership actions rather than adjusting the state directly as there are a restricted set of valid transformations. For example, user A cannot force user B to join a room, and trying to force this state change directly will fail. \n\nThe following membership states are specified:\n\n- ``invite`` - The user has been invited to join a room, but has not yet joined it. They may not participate in the room until they join.\n\n- ``join`` - The user has joined the room (possibly after accepting an invite), and may participate in it.\n\n- ``leave`` - The user was once joined to the room, but has since left (possibly by choice, or possibly by being kicked).\n\n- ``ban`` - The user has been banned from the room, and is no longer allowed to join it until they are un-banned from the room (by having their membership state set to a value other than ``ban``).\n\n- ``knock`` - This is a reserved word, which currently has no meaning.\n\nThe ``third_party_invite`` property will be set if this invite is an ``invite`` event and is the successor of an ``m.room.third_party_invite`` event, and absent otherwise.\n\nThis event may also include an ``invite_room_state`` key **outside the** ``content`` **key**. If present, this contains an array of ``StrippedState`` Events. These events provide information on a subset of state events such as the room name.",
"allOf": [{
"$ref": "core-event-schema/state_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"title": "EventContent",
"properties": {
"membership": {
"type": "string",
"description": "The membership state of the user.",
"enum": ["invite","join","knock","leave","ban"]
},
"avatar_url": {
"type": "string",
"description": "The avatar URL for this user, if any. This is added by the homeserver."
},
"displayname": {
"type": ["string", "null"],
"description": "The display name for this user, if any. This is added by the homeserver."
},
"third_party_invite": {
"type": "object",
"title": "Invite",
"properties": {
"display_name": {
"type": "string",
"description": "A name which can be displayed to represent the user instead of their third party identifier"
},
"signed": {
"type": "object",
"title": "signed",
"description": "A block of content which has been signed, which servers can use to verify the event. Clients should ignore this.",
"properties": {
"mxid": {
"type": "string",
"description": "The invited matrix user ID. Must be equal to the user_id property of the event."
},
"token": {
"type": "string",
"description": "The token property of the containing third_party_invite object."
},
"signatures": {
"type": "object",
"description": "A single signature from the verifying server, in the format specified by the Signing Events section of the server-server API.",
"title": "Signatures"
}
},
"required": ["mxid", "signatures", "token"]
}
},
"required": ["display_name", "signed"]
}
},
"required": ["membership"]
},
"state_key": {
"type": "string",
"description": "The ``user_id`` this membership event relates to."
},
"type": {
"type": "string",
"enum": ["m.room.member"]
},
"invite_room_state": {
"type": "array",
"description": "A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``. Note that this state is informational, and SHOULD NOT be trusted; once the client has joined the room, it SHOULD fetch the live state from the server and discard the invite_room_state. Also, clients must not rely on any particular state being present here; they SHOULD behave properly (with possibly a degraded but not a broken experience) in the absence of any particular events here. If they are set on the room, at least the state for ``m.room.avatar``, ``m.room.canonical_alias``, ``m.room.join_rules``, and ``m.room.name`` SHOULD be included.",
"items": {
"type": "object",
"title": "StrippedState",
"description": "A stripped down state event, with only the ``type``, ``state_key`` and ``content`` keys.",
"required": ["type", "state_key", "content"],
"properties": {
"type": {
"type": "string",
"description": "The ``type`` for the event."
},
"state_key": {
"type": "string",
"description": "The ``state_key`` for the event."
},
"content": {
"title": "EventContent",
"type": "object",
"description": "The ``content`` for the event."
}
}
}
}
}
}
---
allOf:
- $ref: core-event-schema/state_event.yaml
description: |-
Adjusts the membership state for a user in a room. It is preferable to use the membership APIs (``/rooms/<room id>/invite`` etc) when performing membership actions rather than adjusting the state directly as there are a restricted set of valid transformations. For example, user A cannot force user B to join a room, and trying to force this state change directly will fail.
The following membership states are specified:
- ``invite`` - The user has been invited to join a room, but has not yet joined it. They may not participate in the room until they join.
- ``join`` - The user has joined the room (possibly after accepting an invite), and may participate in it.
- ``leave`` - The user was once joined to the room, but has since left (possibly by choice, or possibly by being kicked).
- ``ban`` - The user has been banned from the room, and is no longer allowed to join it until they are un-banned from the room (by having their membership state set to a value other than ``ban``).
- ``knock`` - This is a reserved word, which currently has no meaning.
The ``third_party_invite`` property will be set if this invite is an ``invite`` event and is the successor of an ``m.room.third_party_invite`` event, and absent otherwise.
This event may also include an ``invite_room_state`` key **outside the** ``content`` **key**. If present, this contains an array of ``StrippedState`` Events. These events provide information on a subset of state events such as the room name.
properties:
content:
properties:
avatar_url:
description: 'The avatar URL for this user, if any. This is added by the homeserver.'
type: string
displayname:
description: 'The display name for this user, if any. This is added by the homeserver.'
type:
- "string"
- "null"
membership:
description: The membership state of the user.
enum:
- invite
- join
- knock
- leave
- ban
type: string
third_party_invite:
properties:
display_name:
description: A name which can be displayed to represent the user instead of their third party identifier
type: string
signed:
description: 'A block of content which has been signed, which servers can use to verify the event. Clients should ignore this.'
properties:
mxid:
description: The invited matrix user ID. Must be equal to the user_id property of the event.
type: string
signatures:
description: 'A single signature from the verifying server, in the format specified by the Signing Events section of the server-server API.'
title: Signatures
type: object
token:
description: The token property of the containing third_party_invite object.
type: string
required:
- mxid
- signatures
- token
title: signed
type: object
required:
- display_name
- signed
title: Invite
type: object
required:
- membership
title: EventContent
type: object
invite_room_state:
description: 'A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``. Note that this state is informational, and SHOULD NOT be trusted; once the client has joined the room, it SHOULD fetch the live state from the server and discard the invite_room_state. Also, clients must not rely on any particular state being present here; they SHOULD behave properly (with possibly a degraded but not a broken experience) in the absence of any particular events here. If they are set on the room, at least the state for ``m.room.avatar``, ``m.room.canonical_alias``, ``m.room.join_rules``, and ``m.room.name`` SHOULD be included.'
items:
description: 'A stripped down state event, with only the ``type``, ``state_key`` and ``content`` keys.'
properties:
content:
description: The ``content`` for the event.
title: EventContent
type: object
state_key:
description: The ``state_key`` for the event.
type: string
type:
description: The ``type`` for the event.
type: string
required:
- type
- state_key
- content
title: StrippedState
type: object
type: array
state_key:
description: The ``user_id`` this membership event relates to.
type: string
type:
enum:
- m.room.member
type: string
title: The current membership state of a user in the room.
type: object

@ -1,28 +1,23 @@
{
"type": "object",
"title": "Message",
"description": "This event is used when sending messages in a room. Messages are not limited to be text. The ``msgtype`` key outlines the type of message, e.g. text, audio, image, video, etc. The ``body`` key is text and MUST be used with every kind of ``msgtype`` as a fallback mechanism for when a client cannot render a message. This allows clients to display *something* even if it is just plain text.",
"allOf": [{
"$ref": "core-event-schema/room_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"msgtype": {
"type": "string",
"description": "The type of message, e.g. ``m.image``, ``m.text``"
},
"body": {
"type": "string",
"description": "The textual representation of this message."
}
},
"required": ["msgtype", "body"]
},
"type": {
"type": "string",
"enum": ["m.room.message"]
}
}
}
---
allOf:
- $ref: core-event-schema/room_event.yaml
description: 'This event is used when sending messages in a room. Messages are not limited to be text. The ``msgtype`` key outlines the type of message, e.g. text, audio, image, video, etc. The ``body`` key is text and MUST be used with every kind of ``msgtype`` as a fallback mechanism for when a client cannot render a message. This allows clients to display *something* even if it is just plain text.'
properties:
content:
properties:
body:
description: The textual representation of this message.
type: string
msgtype:
description: 'The type of message, e.g. ``m.image``, ``m.text``'
type: string
required:
- msgtype
- body
type: object
type:
enum:
- m.room.message
type: string
title: Message
type: object

@ -1,51 +1,42 @@
{
"type": "object",
"title": "AudioMessage",
"description": "This message represents a single audio clip.",
"allOf": [{
"$ref": "core-event-schema/room_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"msgtype": {
"type": "string",
"enum": ["m.audio"]
},
"body": {
"type": "string",
"description": "A description of the audio e.g. 'Bee Gees - Stayin' Alive', or some kind of content description for accessibility e.g. 'audio attachment'."
},
"url": {
"type": "string",
"description": "The URL to the audio clip."
},
"info": {
"type": "object",
"title": "AudioInfo",
"description": "Metadata for the audio clip referred to in ``url``.",
"properties": {
"mimetype": {
"type": "string",
"description": "The mimetype of the audio e.g. ``audio/aac``."
},
"size": {
"type": "integer",
"description": "The size of the audio clip in bytes."
},
"duration": {
"type": "integer",
"description": "The duration of the audio in milliseconds."
}
}
}
},
"required": ["msgtype", "body", "url"]
},
"type": {
"type": "string",
"enum": ["m.room.message"]
}
}
}
---
allOf:
- $ref: core-event-schema/room_event.yaml
description: This message represents a single audio clip.
properties:
content:
properties:
body:
description: "A description of the audio e.g. 'Bee Gees - Stayin' Alive', or some kind of content description for accessibility e.g. 'audio attachment'."
type: string
info:
description: Metadata for the audio clip referred to in ``url``.
properties:
duration:
description: The duration of the audio in milliseconds.
type: integer
mimetype:
description: The mimetype of the audio e.g. ``audio/aac``.
type: string
size:
description: The size of the audio clip in bytes.
type: integer
title: AudioInfo
type: object
msgtype:
enum:
- m.audio
type: string
url:
description: The URL to the audio clip.
type: string
required:
- msgtype
- body
- url
type: object
type:
enum:
- m.room.message
type: string
title: AudioMessage
type: object

@ -1,28 +1,24 @@
{
"type": "object",
"title": "EmoteMessage",
"description": "This message is similar to ``m.text`` except that the sender is 'performing' the action contained in the ``body`` key, similar to ``/me`` in IRC. This message should be prefixed by the name of the sender. This message could also be represented in a different colour to distinguish it from regular ``m.text`` messages.",
"allOf": [{
"$ref": "core-event-schema/room_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"msgtype": {
"type": "string",
"enum": ["m.emote"]
},
"body": {
"type": "string",
"description": "The emote action to perform."
}
},
"required": ["msgtype", "body"]
},
"type": {
"type": "string",
"enum": ["m.room.message"]
}
}
}
---
allOf:
- $ref: core-event-schema/room_event.yaml
description: "This message is similar to ``m.text`` except that the sender is 'performing' the action contained in the ``body`` key, similar to ``/me`` in IRC. This message should be prefixed by the name of the sender. This message could also be represented in a different colour to distinguish it from regular ``m.text`` messages."
properties:
content:
properties:
body:
description: The emote action to perform.
type: string
msgtype:
enum:
- m.emote
type: string
required:
- msgtype
- body
type: object
type:
enum:
- m.room.message
type: string
title: EmoteMessage
type: object

@ -1,63 +1,52 @@
{
"type": "object",
"title": "FileMessage",
"description": "This message represents a generic file.",
"allOf": [{
"$ref": "core-event-schema/room_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"msgtype": {
"type": "string",
"enum": ["m.file"]
},
"filename": {
"type": "string",
"description": "The original filename of the uploaded file."
},
"body": {
"type": "string",
"description": "A human-readable description of the file. This is recommended to be the filename of the original upload."
},
"url": {
"type": "string",
"description": "The URL to the file."
},
"info": {
"type": "object",
"title": "FileInfo",
"description": "Information about the file referred to in ``url``.",
"properties": {
"size": {
"type": "integer",
"description": "The size of the file in bytes."
},
"mimetype": {
"type": "string",
"description": "The mimetype of the file e.g. ``application/msword``."
}
}
},
"thumbnail_url": {
"type": "string",
"description": "The URL to the thumbnail of the file."
},
"thumbnail_info": {
"type": "object",
"title": "ImageInfo",
"description": "Metadata about the image referred to in ``thumbnail_url``.",
"allOf": [{
"$ref": "core-event-schema/msgtype_infos/image_info.yaml"
}]
}
},
"required": ["msgtype", "body", "url", "filename"]
},
"type": {
"type": "string",
"enum": ["m.room.message"]
}
}
}
---
allOf:
- $ref: core-event-schema/room_event.yaml
description: This message represents a generic file.
properties:
content:
properties:
body:
description: A human-readable description of the file. This is recommended to be the filename of the original upload.
type: string
filename:
description: The original filename of the uploaded file.
type: string
info:
description: Information about the file referred to in ``url``.
properties:
mimetype:
description: The mimetype of the file e.g. ``application/msword``.
type: string
size:
description: The size of the file in bytes.
type: integer
title: FileInfo
type: object
msgtype:
enum:
- m.file
type: string
thumbnail_info:
allOf:
- $ref: core-event-schema/msgtype_infos/image_info.yaml
description: Metadata about the image referred to in ``thumbnail_url``.
title: ImageInfo
type: object
thumbnail_url:
description: The URL to the thumbnail of the file.
type: string
url:
description: The URL to the file.
type: string
required:
- msgtype
- body
- url
- filename
type: object
type:
enum:
- m.room.message
type: string
title: FileMessage
type: object

@ -1,67 +1,54 @@
{
"type": "object",
"title": "ImageMessage",
"description": "This message represents a single image and an optional thumbnail.",
"allOf": [{
"$ref": "core-event-schema/room_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"msgtype": {
"type": "string",
"enum": ["m.image"]
},
"body": {
"type": "string",
"description": "A textual representation of the image. This could be the alt text of the image, the filename of the image, or some kind of content description for accessibility e.g. 'image attachment'."
},
"url": {
"type": "string",
"description": "The URL to the image."
},
"thumbnail_url": {
"type": "string",
"description": "The URL to the thumbnail of the image."
},
"thumbnail_info": {
"type": "object",
"title": "ImageInfo",
"description": "Metadata about the image referred to in ``thumbnail_url``.",
"allOf": [{
"$ref": "core-event-schema/msgtype_infos/image_info.yaml"
}]
},
"info": {
"type": "object",
"title": "ImageInfo",
"description": "Metadata about the image referred to in ``url``.",
"properties": {
"size": {
"type": "integer",
"description": "Size of the image in bytes."
},
"w": {
"type": "integer",
"description": "The width of the image in pixels."
},
"h": {
"type": "integer",
"description": "The height of the image in pixels."
},
"mimetype": {
"type": "string",
"description": "The mimetype of the image, e.g. ``image/jpeg``."
}
}
}
},
"required": ["msgtype", "body", "url"]
},
"type": {
"type": "string",
"enum": ["m.room.message"]
}
}
}
---
allOf:
- $ref: core-event-schema/room_event.yaml
description: This message represents a single image and an optional thumbnail.
properties:
content:
properties:
body:
description: "A textual representation of the image. This could be the alt text of the image, the filename of the image, or some kind of content description for accessibility e.g. 'image attachment'."
type: string
info:
description: Metadata about the image referred to in ``url``.
properties:
h:
description: The height of the image in pixels.
type: integer
mimetype:
description: 'The mimetype of the image, e.g. ``image/jpeg``.'
type: string
size:
description: Size of the image in bytes.
type: integer
w:
description: The width of the image in pixels.
type: integer
title: ImageInfo
type: object
msgtype:
enum:
- m.image
type: string
thumbnail_info:
allOf:
- $ref: core-event-schema/msgtype_infos/image_info.yaml
description: Metadata about the image referred to in ``thumbnail_url``.
title: ImageInfo
type: object
thumbnail_url:
description: The URL to the thumbnail of the image.
type: string
url:
description: The URL to the image.
type: string
required:
- msgtype
- body
- url
type: object
type:
enum:
- m.room.message
type: string
title: ImageMessage
type: object

@ -1,43 +1,36 @@
{
"type": "object",
"title": "LocationMessage",
"description": "This message represents a real-world location.",
"allOf": [{
"$ref": "core-event-schema/room_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"msgtype": {
"type": "string",
"enum": ["m.location"]
},
"body": {
"type": "string",
"description": "A description of the location e.g. 'Big Ben, London, UK', or some kind of content description for accessibility e.g. 'location attachment'."
},
"geo_uri": {
"type": "string",
"description": "A geo URI representing this location."
},
"thumbnail_url": {
"type": "string",
"description": "The URL to a thumbnail of the location being represented."
},
"thumbnail_info": {
"type": "object",
"title": "ImageInfo",
"allOf": [{
"$ref": "core-event-schema/msgtype_infos/image_info.yaml"
}]
}
},
"required": ["msgtype", "body", "geo_uri"]
},
"type": {
"type": "string",
"enum": ["m.room.message"]
}
}
}
---
allOf:
- $ref: core-event-schema/room_event.yaml
description: This message represents a real-world location.
properties:
content:
properties:
body:
description: "A description of the location e.g. 'Big Ben, London, UK', or some kind of content description for accessibility e.g. 'location attachment'."
type: string
geo_uri:
description: A geo URI representing this location.
type: string
msgtype:
enum:
- m.location
type: string
thumbnail_info:
allOf:
- $ref: core-event-schema/msgtype_infos/image_info.yaml
title: ImageInfo
type: object
thumbnail_url:
description: The URL to a thumbnail of the location being represented.
type: string
required:
- msgtype
- body
- geo_uri
type: object
type:
enum:
- m.room.message
type: string
title: LocationMessage
type: object

@ -1,28 +1,24 @@
{
"type": "object",
"title": "NoticeMessage",
"description": "A m.notice message should be considered similar to a plain m.text message except that clients should visually distinguish it in some way. It is intended to be used by automated clients, such as bots, bridges, and other entities, rather than humans. Additionally, such automated agents which watch a room for messages and respond to them ought to ignore m.notice messages. This helps to prevent infinite-loop situations where two automated clients continuously exchange messages, as each responds to the other.",
"allOf": [{
"$ref": "core-event-schema/room_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"msgtype": {
"type": "string",
"enum": ["m.notice"]
},
"body": {
"type": "string",
"description": "The notice text to send."
}
},
"required": ["msgtype", "body"]
},
"type": {
"type": "string",
"enum": ["m.room.message"]
}
}
}
---
allOf:
- $ref: core-event-schema/room_event.yaml
description: 'A m.notice message should be considered similar to a plain m.text message except that clients should visually distinguish it in some way. It is intended to be used by automated clients, such as bots, bridges, and other entities, rather than humans. Additionally, such automated agents which watch a room for messages and respond to them ought to ignore m.notice messages. This helps to prevent infinite-loop situations where two automated clients continuously exchange messages, as each responds to the other.'
properties:
content:
properties:
body:
description: The notice text to send.
type: string
msgtype:
enum:
- m.notice
type: string
required:
- msgtype
- body
type: object
type:
enum:
- m.room.message
type: string
title: NoticeMessage
type: object

@ -1,28 +1,24 @@
{
"type": "object",
"title": "TextMessage",
"description": "This message is the most basic message and is used to represent text.",
"allOf": [{
"$ref": "core-event-schema/room_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"msgtype": {
"type": "string",
"enum": ["m.text"]
},
"body": {
"type": "string",
"description": "The body of the message."
}
},
"required": ["msgtype", "body"]
},
"type": {
"type": "string",
"enum": ["m.room.message"]
}
}
}
---
allOf:
- $ref: core-event-schema/room_event.yaml
description: This message is the most basic message and is used to represent text.
properties:
content:
properties:
body:
description: The body of the message.
type: string
msgtype:
enum:
- m.text
type: string
required:
- msgtype
- body
type: object
type:
enum:
- m.room.message
type: string
title: TextMessage
type: object

@ -1,70 +1,56 @@
{
"type": "object",
"title": "VideoMessage",
"description": "This message represents a single video clip.",
"allOf": [{
"$ref": "core-event-schema/room_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"msgtype": {
"type": "string",
"enum": ["m.video"]
},
"body": {
"type": "string",
"description": "A description of the video e.g. 'Gangnam style', or some kind of content description for accessibility e.g. 'video attachment'."
},
"url": {
"type": "string",
"description": "The URL to the video clip."
},
"info": {
"type": "object",
"title": "VideoInfo",
"description": "Metadata about the video clip referred to in ``url``.",
"properties": {
"mimetype": {
"type": "string",
"description": "The mimetype of the video e.g. ``video/mp4``."
},
"size": {
"type": "integer",
"description": "The size of the video in bytes."
},
"duration": {
"type": "integer",
"description": "The duration of the video in milliseconds."
},
"w": {
"type": "integer",
"description": "The width of the video in pixels."
},
"h": {
"type": "integer",
"description": "The height of the video in pixels."
},
"thumbnail_url": {
"type": "string",
"description": "The URL to a thumbnail of the video clip."
},
"thumbnail_info": {
"type": "object",
"title": "ImageInfo",
"allOf": [{
"$ref": "core-event-schema/msgtype_infos/image_info.yaml"
}]
}
}
}
},
"required": ["msgtype", "body", "url"]
},
"type": {
"type": "string",
"enum": ["m.room.message"]
}
}
}
---
allOf:
- $ref: core-event-schema/room_event.yaml
description: This message represents a single video clip.
properties:
content:
properties:
body:
description: "A description of the video e.g. 'Gangnam style', or some kind of content description for accessibility e.g. 'video attachment'."
type: string
info:
description: Metadata about the video clip referred to in ``url``.
properties:
duration:
description: The duration of the video in milliseconds.
type: integer
h:
description: The height of the video in pixels.
type: integer
mimetype:
description: The mimetype of the video e.g. ``video/mp4``.
type: string
size:
description: The size of the video in bytes.
type: integer
thumbnail_info:
allOf:
- $ref: core-event-schema/msgtype_infos/image_info.yaml
title: ImageInfo
type: object
thumbnail_url:
description: The URL to a thumbnail of the video clip.
type: string
w:
description: The width of the video in pixels.
type: integer
title: VideoInfo
type: object
msgtype:
enum:
- m.video
type: string
url:
description: The URL to the video clip.
type: string
required:
- msgtype
- body
- url
type: object
type:
enum:
- m.room.message
type: string
title: VideoMessage
type: object

@ -1,29 +1,26 @@
{
"type": "object",
"title": "MessageFeedback",
"description": "**NB: Usage of this event is discouraged in favour of the** `receipts module`_. **Most clients will not recognise this event.** Feedback events are events sent to acknowledge a message in some way. There are two supported acknowledgements: ``delivered`` (sent when the event has been received) and ``read`` (sent when the event has been observed by the end-user). The ``target_event_id`` should reference the ``m.room.message`` event being acknowledged.",
"allOf": [{
"$ref": "core-event-schema/room_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "The type of feedback.",
"enum": ["delivered", "read"]
},
"target_event_id": {
"type": "string",
"description": "The event that this feedback is related to."
}
},
"required": ["type", "target_event_id"]
},
"type": {
"type": "string",
"enum": ["m.room.message.feedback"]
}
}
}
---
allOf:
- $ref: core-event-schema/room_event.yaml
description: '**NB: Usage of this event is discouraged in favour of the** `receipts module`_. **Most clients will not recognise this event.** Feedback events are events sent to acknowledge a message in some way. There are two supported acknowledgements: ``delivered`` (sent when the event has been received) and ``read`` (sent when the event has been observed by the end-user). The ``target_event_id`` should reference the ``m.room.message`` event being acknowledged.'
properties:
content:
properties:
target_event_id:
description: The event that this feedback is related to.
type: string
type:
description: The type of feedback.
enum:
- delivered
- read
type: string
required:
- type
- target_event_id
type: object
type:
enum:
- m.room.message.feedback
type: string
title: MessageFeedback
type: object

@ -1,29 +1,23 @@
{
"title": "RoomName",
"description": "A room has an opaque room ID which is not human-friendly to read. A room alias is human-friendly, but not all rooms have room aliases. The room name is a human-friendly string designed to be displayed to the end-user. The room name is not unique, as multiple rooms can have the same room name set. The room name can also be set when creating a room using ``/createRoom`` with the ``name`` key.",
"type": "object",
"allOf": [{
"$ref": "core-event-schema/state_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The name of the room. This MUST NOT exceed 255 bytes."
}
},
"required": ["name"]
},
"state_key": {
"type": "string",
"description": "A zero-length string.",
"pattern": "^$"
},
"type": {
"type": "string",
"enum": ["m.room.name"]
}
}
}
---
allOf:
- $ref: core-event-schema/state_event.yaml
description: 'A room has an opaque room ID which is not human-friendly to read. A room alias is human-friendly, but not all rooms have room aliases. The room name is a human-friendly string designed to be displayed to the end-user. The room name is not unique, as multiple rooms can have the same room name set. The room name can also be set when creating a room using ``/createRoom`` with the ``name`` key.'
properties:
content:
properties:
name:
description: The name of the room. This MUST NOT exceed 255 bytes.
type: string
required:
- name
type: object
state_key:
description: A zero-length string.
pattern: '^$'
type: string
type:
enum:
- m.room.name
type: string
title: RoomName
type: object

@ -1,70 +1,86 @@
{
"type": "object",
"title": "Defines the power levels (privileges) of users in the room.",
"description": "This event specifies the minimum level a user must have in order to perform a certain action. It also specifies the levels of each user in the room.\n\nIf a ``user_id`` is in the ``users`` list, then that ``user_id`` has the associated power level. Otherwise they have the default level ``users_default``. If ``users_default`` is not supplied, it is assumed to be 0.\n\nThe level required to send a certain event is governed by ``events``, ``state_default`` and ``events_default``. If an event type is specified in ``events``, then the user must have at least the level specified in order to send that event. If the event type is not supplied, it defaults to ``events_default`` for Message Events and ``state_default`` for State Events. If there is no ``state_default`` in the ``power_levels`` event, the ``state_default`` is 50. If the room contains no ``power_levels`` event, the ``state_default`` is 0. The ``events_default`` is 0 in either of these cases.",
"allOf": [{
"$ref": "core-event-schema/state_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"ban": {
"type": "number",
"description": "The level required to ban a user."
},
"events_default": {
"type": "number",
"description": "The default level required to send message events. Can be overridden by the ``events`` key."
},
"kick": {
"type": "number",
"description": "The level required to kick a user."
},
"redact": {
"type": "number",
"description": "The level required to redact an event."
},
"invite": {
"type": "number",
"description": "The level required to invite a user."
},
"state_default": {
"type": "number",
"description": "The default level required to send state events. Can be overridden by the ``events`` key."
},
"users_default": {
"type": "number",
"description": "The default power level for every user in the room, unless their ``user_id`` is mentioned in the ``users`` key."
},
"events": {
"type": "object",
"title": "Event power levels",
"description": "The level required to send specific event types. This is a mapping from event type to power level required.",
"additionalProperties": {
"type": "number"
}
},
"users": {
"type": "object",
"title": "User power levels",
"description": "The power levels for specific users. This is a mapping from ``user_id`` to power level for that user.",
"additionalProperties": {
"type": "number"
}
}
},
"required": ["ban","events","events_default","kick","redact",
"state_default","users"]
},
"state_key": {
"type": "string",
"description": "A zero-length string.",
"pattern": "^$"
},
"type": {
"type": "string",
"enum": ["m.room.power_levels"]
}
}
}
---
allOf:
- $ref: core-event-schema/state_event.yaml
description: |-
This event specifies the minimum level a user must have in order to perform a
certain action. It also specifies the levels of each user in the room.
If a ``user_id`` is in the ``users`` list, then that ``user_id`` has the
associated power level. Otherwise they have the default level
``users_default``. If ``users_default`` is not supplied, it is assumed to be
0.
The level required to send a certain event is governed by ``events``,
``state_default`` and ``events_default``. If an event type is specified in
``events``, then the user must have at least the level specified in order to
send that event. If the event type is not supplied, it defaults to
``events_default`` for Message Events and ``state_default`` for State
Events.
If there is no ``state_default`` in the ``m.room.power_levels`` event, the
``state_default`` is 50. If there is no ``events_default`` in the
``m.room.power_levels`` event, the ``events_default`` is 0. If the room
contains no ``m.room.power_levels`` event, *both* the ``state_default`` and
``events_default`` are 0.
The power level required to invite a user to the room, kick a user from the
room, ban a user from the room, or redact an event, is defined by ``invite``,
``kick``, ``ban``, and ``redact``, respectively. Each of these levels defaults
to 50 if they are not specified in the ``m.room.power_levels`` event, or if
the room contains no ``m.room.power_levels`` event.
properties:
content:
properties:
ban:
description: The level required to ban a user. Defaults to 50 if unspecified.
type: number
events:
additionalProperties:
type: number
description: The level required to send specific event types. This is a mapping from event type to power level required.
title: Event power levels
type: object
events_default:
description: |-
The default level required to send message events. Can be
overridden by the ``events`` key. Defaults to 0 if unspecified.
type: number
invite:
description: The level required to invite a user. Defaults to 50 if unspecified.
type: number
kick:
description: The level required to kick a user. Defaults to 50 if unspecified.
type: number
redact:
description: The level required to redact an event. Defaults to 50 if unspecified.
type: number
state_default:
description: |-
The default level required to send state events. Can be overridden
by the ``events`` key. Defaults to 50 if unspecified, but 0 if
there is no ``m.room.power_levels`` event at all.
type: number
users:
additionalProperties:
type: number
description: The power levels for specific users. This is a mapping from ``user_id`` to power level for that user.
title: User power levels
type: object
users_default:
description: |-
The default power level for every user in the room, unless their
``user_id`` is mentioned in the ``users`` key. Defaults to 0 if
unspecified.
type: number
type: object
state_key:
description: A zero-length string.
pattern: '^$'
type: string
type:
enum:
- m.room.power_levels
type: string
title: Defines the power levels (privileges) of users in the room.
type: object

@ -1,28 +1,22 @@
{
"type": "object",
"title": "Redaction",
"description": "Events can be redacted by either room or server admins. Redacting an event means that all keys not required by the protocol are stripped off, allowing admins to remove offensive or illegal content that may have been attached to any event. This cannot be undone, allowing server owners to physically delete the offending data. There is also a concept of a moderator hiding a message event, which can be undone, but cannot be applied to state events. The event that has been redacted is specified in the ``redacts`` event level key.",
"allOf": [{
"$ref": "core-event-schema/room_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"description": "The reason for the redaction, if any."
}
}
},
"redacts": {
"type": "string",
"description": "The event ID that was redacted."
},
"type": {
"type": "string",
"enum": ["m.room.redaction"]
}
},
"required": ["redacts"]
}
---
allOf:
- $ref: core-event-schema/room_event.yaml
description: 'Events can be redacted by either room or server admins. Redacting an event means that all keys not required by the protocol are stripped off, allowing admins to remove offensive or illegal content that may have been attached to any event. This cannot be undone, allowing server owners to physically delete the offending data. There is also a concept of a moderator hiding a message event, which can be undone, but cannot be applied to state events. The event that has been redacted is specified in the ``redacts`` event level key.'
properties:
content:
properties:
reason:
description: 'The reason for the redaction, if any.'
type: string
type: object
redacts:
description: The event ID that was redacted.
type: string
type:
enum:
- m.room.redaction
type: string
required:
- redacts
title: Redaction
type: object

@ -1,56 +1,46 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"title": "An invitation to a room issued to a third party identifier, rather than a matrix user ID.",
"description": "Acts as an ``m.room.member`` invite event, where there isn't a target user_id to invite. This event contains a token and a public key whose private key must be used to sign the token. Any user who can present that signature may use this invitation to join the target room.",
"allOf": [{
"$ref": "core-event-schema/state_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"display_name": {
"type": "string",
"description": "A user-readable string which represents the user who has been invited. This should not contain the user's third party ID, as otherwise when the invite is accepted it would leak the association between the matrix ID and the third party ID."
},
"key_validity_url": {
"type": "string",
"description": "A URL which can be fetched, with querystring public_key=public_key, to validate whether the key has been revoked. The URL must return a JSON object containing a boolean property named 'valid'."
},
"public_key": {
"type": "string",
"description": "A base64-encoded ed25519 key with which token must be signed (though a signature from any entry in public_keys is also sufficient). This exists for backwards compatibility."
},
"public_keys": {
"type": "array",
"description": "Keys with which the token may be signed.",
"items": {
"type": "object",
"title": "PublicKeys",
"properties": {
"public_key": {
"type": "string",
"description": "A base-64 encoded ed25519 key with which token may be signed."
},
"key_validity_url": {
"type": "string",
"description": "An optional URL which can be fetched, with querystring public_key=public_key, to validate whether the key has been revoked. The URL must return a JSON object containing a boolean property named 'valid'. If this URL is absent, the key must be considered valid indefinitely."
}
},
"required": ["public_key"]
}
}
},
"required": ["display_name", "key_validity_url", "public_key"]
},
"state_key": {
"type": "string",
"description": "The token, of which a signature must be produced in order to join the room."
},
"type": {
"type": "string",
"enum": ["m.room.third_party_invite"]
}
}
}
---
$schema: http://json-schema.org/draft-04/schema#
allOf:
- $ref: core-event-schema/state_event.yaml
description: "Acts as an ``m.room.member`` invite event, where there isn't a target user_id to invite. This event contains a token and a public key whose private key must be used to sign the token. Any user who can present that signature may use this invitation to join the target room."
properties:
content:
properties:
display_name:
description: "A user-readable string which represents the user who has been invited. This should not contain the user's third party ID, as otherwise when the invite is accepted it would leak the association between the matrix ID and the third party ID."
type: string
key_validity_url:
description: "A URL which can be fetched, with querystring public_key=public_key, to validate whether the key has been revoked. The URL must return a JSON object containing a boolean property named 'valid'."
type: string
public_key:
description: A base64-encoded ed25519 key with which token must be signed (though a signature from any entry in public_keys is also sufficient). This exists for backwards compatibility.
type: string
public_keys:
description: Keys with which the token may be signed.
items:
properties:
key_validity_url:
description: "An optional URL which can be fetched, with querystring public_key=public_key, to validate whether the key has been revoked. The URL must return a JSON object containing a boolean property named 'valid'. If this URL is absent, the key must be considered valid indefinitely."
type: string
public_key:
description: A base-64 encoded ed25519 key with which token may be signed.
type: string
required:
- public_key
title: PublicKeys
type: object
type: array
required:
- display_name
- key_validity_url
- public_key
type: object
state_key:
description: 'The token, of which a signature must be produced in order to join the room.'
type: string
type:
enum:
- m.room.third_party_invite
type: string
title: 'An invitation to a room issued to a third party identifier, rather than a matrix user ID.'
type: object

@ -1,29 +1,23 @@
{
"type": "object",
"title": "Topic",
"description": "A topic is a short message detailing what is currently being discussed in the room. It can also be used as a way to display extra information about the room, which may not be suitable for the room name. The room topic can also be set when creating a room using ``/createRoom`` with the ``topic`` key.",
"allOf": [{
"$ref": "core-event-schema/state_event.yaml"
}],
"properties": {
"content": {
"type": "object",
"properties": {
"topic": {
"type": "string",
"description": "The topic text."
}
},
"required": ["topic"]
},
"state_key": {
"type": "string",
"description": "A zero-length string.",
"pattern": "^$"
},
"type": {
"type": "string",
"enum": ["m.room.topic"]
}
}
}
---
allOf:
- $ref: core-event-schema/state_event.yaml
description: 'A topic is a short message detailing what is currently being discussed in the room. It can also be used as a way to display extra information about the room, which may not be suitable for the room name. The room topic can also be set when creating a room using ``/createRoom`` with the ``topic`` key.'
properties:
content:
properties:
topic:
description: The topic text.
type: string
required:
- topic
type: object
state_key:
description: A zero-length string.
pattern: '^$'
type: string
type:
enum:
- m.room.topic
type: string
title: Topic
type: object

@ -30,8 +30,6 @@ of one of the following:
idle.
- ``offline`` : The user is not connected to an event stream or is
explicitly suppressing their profile information from being sent.
- ``free_for_chat`` : The user is generally willing to receive messages
moreso than default.
Events
------
@ -46,67 +44,44 @@ listed below.
{{presence_cs_http_api}}
Idle timeout
~~~~~~~~~~~~
Clients SHOULD implement an "idle timeout". This is a timer which fires after
a period of inactivity on the client. The definition of inactivity varies
depending on the client. For example, web implementations may determine
inactivity to be not moving the mouse for a certain period of time. When this
timer fires it should set the presence state to ``unavailable``. When the user
becomes active again (e.g. by moving the mouse) the client should set the
presence state to ``online``. A timeout value between 1 and 5 minutes is
recommended.
Server behaviour
----------------
Each user's homeserver stores a "presence list" per user. Once a user accepts
a presence list, both user's HSes must track the subscription.
Propagating profile information
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Because the profile display name and avatar information are likely to be used in
many places of a client's display, changes to these fields SHOULD cause an
automatic propagation event to occur, informing likely-interested parties of the
new values. One of these change mechanisms SHOULD be via ``m.presence`` events.
These events should set ``displayname`` and ``avatar_url`` to the new values
along with the presence-specific keys. This SHOULD be done automatically by the
homeserver when a user successfully changes their display name or avatar URL.
.. admonition:: Rationale
The intention for sending this information in ``m.presence`` is so that any
"user list" can display the *current* name/presence for a user ID outside the
scope of a room e.g. for a user page. This is bundled into a single event for
several reasons. The user's display name can change per room. This
event provides the "canonical" name for the user. In addition, the name is
bundled into a single event for the ease of client implementations. If this
was not done, the client would need to search all rooms for their own
membership event to pull out the display name.
Last active ago
~~~~~~~~~~~~~~~
The server maintains a timestamp of the last time it saw a
pro-active event from the user. A pro-active event may be sending a message to a
room or changing presence state to a higher level of availability. Levels of
availability are defined from low to high as follows:
The server maintains a timestamp of the last time it saw a pro-active event from
the user. A pro-active event may be sending a message to a room or changing
presence state to ``online``. This timestamp is presented via a key called
``last_active_ago`` which gives the relative number of milliseconds since the
pro-active event.
To reduce the number of presence updates sent to clients the server may include
a ``currently_active`` boolean field when the presence state is ``online``. When
true, the server will not send further updates to the last active time until an
update is sent to the client with either a) ``currently_active`` set to false or
b) a presence state other than ``online``. During this period clients must
consider the user to be currently active, irrespective of the last active time.
The last active time must be up to date whenever the server gives a presence
event to the client. The ``currently_active`` mechanism should purely be used by
servers to stop sending continuous presence updates, as opposed to disabling
last active tracking entirely. Thus clients can fetch up to date last active
times by explicitly requesting the presence for a given user.
- ``offline``
- ``unavailable``
- ``online``
- ``free_for_chat``
Idle timeout
~~~~~~~~~~~~
Based on this list, changing state from ``unavailable`` to ``online`` counts as
a pro-active event, whereas ``online`` to ``unavailable`` does not. This
timestamp is presented via a key called ``last_active_ago`` which gives the
relative number of milliseconds since the pro-active event.
The server will automatically set a user's presence to ``unavailable`` if their
last active time was over a threshold value (e.g. 5 minutes). Clients can
manually set a user's presence to ``unavailable``. Any activity that bumps the
last active time on any of the user's clients will cause the server to
automatically set their presence to ``online``.
Security considerations
-----------------------
Presence information is shared with all users who share a room with the target
user. In large public rooms this could be undesirable.

@ -195,104 +195,274 @@ than "user-defined rules". The ``rule_id`` for all server-default rules MUST
start with a dot (".") to identify them as "server-default". The following
server-default rules are specified:
``.m.rule.contains_user_name``
Matches any message whose content is unencrypted and contains the local part
of the user's Matrix ID, separated by word boundaries.
Definition (as a ``content`` rule)::
Default Override Rules
^^^^^^^^^^^^^^^^^^^^^^
``m.rule.master``
`````````````````
Matches all events, this can be enabled to turn off all push notifications
other than those generated by override rules set by the user. By default this
rule is disabled.
Definition
.. code:: json
{
"rule_id": ".m.rule.contains_user_name"
"pattern": "[the local part of the user's Matrix ID]",
"rule_id": ".m.rule.master",
"default": true,
"enabled": false,
"conditions": [],
"actions": [
"notify",
"dont_notify"
]
}
``.m.rule.suppress_notices``
````````````````````````````
Matches messages with a ``msgtype`` of ``notice``. This should be an
``override`` rule so that it takes priority over ``content`` / ``sender`` /
``room`` rules.
Definition:
.. code:: json
{
"rule_id": ".m.rule.suppress_notices",
"default": true,
"enabled": true,
"conditions": [
{
"set_tweak": "sound",
"value": "default"
"kind": "event_match",
"key": "content.msgtype",
"pattern": "m.notice",
}
],
"actions": [
"dont_notify",
]
}
``.m.rule.contains_display_name``
Matches any message whose content is unencrypted and contains the user's
current display name in the room in which it was sent.
``.m.rule.invite_for_me``
`````````````````````````
Matches any invites to a new room for this user.
Definition:
Definition (this rule can only be an ``override`` or ``underride`` rule)::
.. code:: json
{
"rule_id": ".m.rule.contains_display_name"
"rule_id": ".m.rule.invite_for_me",
"default": true,
"enabled": true,
"conditions": [
{
"kind": "contains_display_name"
"key": "type",
"kind": "event_match",
"pattern": "m.room.member"
},
{
"key": "content.membership",
"kind": "event_match",
"pattern": "invite"
},
{
"key": "state_key",
"kind": "event_match",
"pattern": "[the user's Matrix ID]"
}
],
"actions": [
"notify",
"notify",
{
"set_tweak": "sound",
"value": "default"
},
{
"set_tweak": "highlight",
"value": false
}
],
]
}
``.m.rule.room_one_to_one``
Matches any message sent in a room with exactly two members.
``.m.rule.member_event``
````````````````````````
Definition (this rule can only be an ``override`` or ``underride`` rule)::
Matches any ``m.room.member_event``.
Definition:
.. code:: json
{
"rule_id": ".m.rule.room_two_members"
"rule_id": ".m.rule.member_event",
"default": true,
"enabled": true,
"conditions": [
{
"is": "2",
"kind": "room_member_count"
"key": "type",
"kind": "event_match",
"pattern": "m.room.member"
}
],
"actions": [
"dont_notify"
]
}
Default Content Rules
^^^^^^^^^^^^^^^^^^^^^
``.m.rule.contains_user_name``
``````````````````````````````
Matches any message whose content is unencrypted and contains the local part
of the user's Matrix ID, separated by word boundaries.
Definition (as a ``content`` rule):
.. code:: json
{
"rule_id": ".m.rule.contains_user_name",
"default": true,
"enabled": true,
"pattern": "[the local part of the user's Matrix ID]",
"actions": [
"notify",
{
"set_tweak": "sound",
"value": "default"
}
],
]
}
``.m.rule.suppress_notices``
Matches messages with a ``msgtype`` of ``notice``. This should be an
``override`` rule so that it takes priority over ``content`` / ``sender`` /
``room`` rules.
Default Underride Rules
^^^^^^^^^^^^^^^^^^^^^^^
``.m.rule.call``
````````````````
Matches any incoming VOIP call.
Definition:
Definition::
.. code:: json
{
'rule_id': '.m.rule.suppress_notices',
'conditions': [
"rule_id": ".m.rule.call",
"default": true,
"enabled": true,
"conditions": [
{
'kind': 'event_match',
'key': 'content.msgtype',
'pattern': 'm.notice',
"key": "type",
"kind": "event_match",
"pattern": "m.call.invite"
}
],
'actions': [
'dont-notify',
"actions": [
"notify",
{
"set_tweak": "sound",
"value": "ring"
},
{
"set_tweak": "highlight",
"value": false
}
]
}
},
``.m.rule.fallback``
Matches any message. Used to define the behaviour of messages that match no
other rules. If homeservers define this it should be the lowest priority
``underride`` rule.
``.m.rule.contains_display_name``
`````````````````````````````````
Matches any message whose content is unencrypted and contains the user's
current display name in the room in which it was sent.
Definition::
Definition:
.. code:: json
{
"rule_id": ".m.rule.fallback"
"conditions": [],
"rule_id": ".m.rule.contains_display_name",
"default": true,
"enabled": true,
"conditions": [
{
"kind": "contains_display_name"
}
],
"actions": [
"notify"
"notify",
{
"set_tweak": "sound",
"value": "default"
},
{
"set_tweak": "highlight"
}
]
}
``.m.rule.room_one_to_one``
```````````````````````````
Matches any message sent in a room with exactly two members.
Definition:
.. code:: json
{
"rule_id": ".m.rule.room_one_to_one",
"default": true,
"enabled": true,
"conditions": [
{
"kind": "room_member_count",
"is": "2"
}
],
"actions": [
"notify",
{
"set_tweak": "sound",
"value": "default"
},
{
"set_tweak": "highlight",
"value": false
}
]
}
``.m.rule.message``
```````````````````
Matches all chat messages.
Definition:
.. code:: json
{
"rule_id": ".m.rule.message",
"default": true,
"enabled": true,
"conditions": [
{
"kind": "event_match",
"key": "type",
"pattern": "m.room.message"
}
],
"actions": [
"notify",
{
"set_tweak": "highlight",
"value": false
}
]
}
Conditions

@ -54,7 +54,7 @@ groups: # reusable blobs of files when prefixed with 'group:'
- modules/event_context.rst
title_styles: ["=", "-", "~", "+", "^", "`", "@"]
title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"]
# The templating system doesn't know the right title style to use when generating
# RST. These symbols are 'relative' to say "make a sub-title" (-1), "make a title

@ -14,6 +14,7 @@ import json
import os
import re
import subprocess
import sys
import urllib
import yaml
@ -153,98 +154,121 @@ def get_json_schema_object_fields(obj, enforce_title=False,
required_keys = set(obj.get("required", []))
fields = {
"title": obj.get("title"),
"rows": []
}
tables = [fields]
obj_title = obj.get("title")
first_table_rows = []
tables = []
for key_name in props:
logger.debug("Processing property %s.%s", obj.get('title'), key_name)
prop = inherit_parents(props[key_name])
try:
logger.debug("Processing property %s.%s", obj_title, key_name)
required = key_name in required_keys
res = process_prop(key_name, props[key_name], required,
mark_required)
first_table_rows.append(res["row"])
tables.extend(res["tables"])
logger.debug("Done property %s" % key_name)
except Exception, e:
e2 = Exception("Error reading property %s.%s: %s" %
(obj_title, key_name, str(e)))
# throw the new exception with the old stack trace, so that
# we don't lose information about where the error occurred.
raise e2, None, sys.exc_info()[2]
tables.insert(0, {
"title": obj_title,
"rows": first_table_rows,
})
value_type = None
required = key_name in required_keys
desc = prop.get("description", "")
prop_type = prop.get('type')
return tables
def process_prop(key_name, prop, required, mark_required):
prop = inherit_parents(prop)
if prop_type is None:
raise KeyError("Property '%s' of object '%s' missing 'type' field"
% (key_name, obj))
logger.debug("%s is a %s", key_name, prop_type)
value_type = None
desc = prop.get("description", "")
prop_type = prop.get('type')
tables = []
if prop_type == "object":
if prop_type is None:
raise KeyError("Property '%s' of object '%s' missing 'type' field"
% (key_name, obj))
logger.debug("%s is a %s", key_name, prop_type)
if prop_type == "object":
nested_objects = get_json_schema_object_fields(
prop,
enforce_title=True,
mark_required=mark_required,
)
value_type = nested_objects[0]["title"]
value_id = value_type
tables += [x for x in nested_objects if not x.get("no-table")]
elif prop_type == "array":
items = inherit_parents(prop["items"])
# if the items of the array are objects then recurse
if items["type"] == "object":
nested_objects = get_json_schema_object_fields(
prop,
items,
enforce_title=True,
mark_required=mark_required,
)
value_type = nested_objects[0]["title"]
value_id = value_type
tables += [x for x in nested_objects if not x.get("no-table")]
elif prop_type == "array":
items = inherit_parents(prop["items"])
# if the items of the array are objects then recurse
if items["type"] == "object":
nested_objects = get_json_schema_object_fields(
items,
enforce_title=True,
mark_required=mark_required,
)
value_id = nested_objects[0]["title"]
value_type = "[%s]" % value_id
tables += nested_objects
else:
value_type = items["type"]
if isinstance(value_type, list):
value_type = " or ".join(value_type)
value_id = value_type
value_type = "[%s]" % value_type
array_enums = items.get("enum")
if array_enums:
if len(array_enums) > 1:
value_type = "[enum]"
desc += (
" One of: %s" % json.dumps(array_enums)
)
else:
desc += (
" Must be '%s'." % array_enums[0]
)
value_id = nested_objects[0]["title"]
value_type = "[%s]" % value_id
tables += nested_objects
else:
value_type = prop_type
value_id = prop_type
if prop.get("enum"):
if len(prop["enum"]) > 1:
value_type = "enum"
if desc:
desc += " "
value_type = items["type"]
if isinstance(value_type, list):
value_type = " or ".join(value_type)
value_id = value_type
value_type = "[%s]" % value_type
array_enums = items.get("enum")
if array_enums:
if len(array_enums) > 1:
value_type = "[enum]"
desc += (
"One of: %s" % json.dumps(prop["enum"])
" One of: %s" % json.dumps(array_enums)
)
else:
if desc:
desc += " "
desc += (
"Must be '%s'." % prop["enum"][0]
" Must be '%s'." % array_enums[0]
)
if isinstance(value_type, list):
value_type = " or ".join(value_type)
else:
value_type = prop_type
value_id = prop_type
if prop.get("enum"):
if len(prop["enum"]) > 1:
value_type = "enum"
if desc:
desc += " "
desc += (
"One of: %s" % json.dumps(prop["enum"])
)
else:
if desc:
desc += " "
desc += (
"Must be '%s'." % prop["enum"][0]
)
if isinstance(value_type, list):
value_type = " or ".join(value_type)
if required and mark_required:
desc = "**Required.** " + desc
fields["rows"].append({
if required and mark_required:
desc = "**Required.** " + desc
return {
"row": {
"key": key_name,
"type": value_type,
"id": value_id,
"required": required,
"desc": desc,
})
logger.debug("Done property %s" % key_name)
return tables
},
"tables": tables,
}
def get_tables_for_schema(schema, mark_required=True):
@ -611,89 +635,102 @@ class MatrixUnits(Units):
if not filename.startswith("m."):
continue
filepath = os.path.join(path, filename)
self.log("Reading %s" % filepath)
with open(filepath, "r") as f:
json_schema = yaml.load(f)
schema = {
"typeof": None,
"typeof_info": "",
"type": None,
"title": None,
"desc": None,
"msgtype": None,
"content_fields": [
# {
# title: "<title> key"
# rows: [
# { key: <key_name>, type: <string>,
# desc: <desc>, required: <bool> }
# ]
# }
]
}
try:
schemata[filename] = self.read_event_schema(filepath)
except Exception, e:
e2 = Exception("Error reading event schema "+filepath+": "+
str(e))
# throw the new exception with the old stack trace, so that
# we don't lose information about where the error occurred.
raise e2, None, sys.exc_info()[2]
# add typeof
base_defs = {
ROOM_EVENT: "Message Event",
STATE_EVENT: "State Event"
}
if type(json_schema.get("allOf")) == list:
schema["typeof"] = base_defs.get(
json_schema["allOf"][0].get("$ref")
)
elif json_schema.get("title"):
schema["typeof"] = json_schema["title"]
return schemata
json_schema = resolve_references(filepath, json_schema)
def read_event_schema(self, filepath):
self.log("Reading %s" % filepath)
with open(filepath, "r") as f:
json_schema = yaml.load(f)
schema = {
"typeof": None,
"typeof_info": "",
"type": None,
"title": None,
"desc": None,
"msgtype": None,
"content_fields": [
# {
# title: "<title> key"
# rows: [
# { key: <key_name>, type: <string>,
# desc: <desc>, required: <bool> }
# ]
# }
]
}
# add type
schema["type"] = Units.prop(
json_schema, "properties/type/enum"
)[0]
# add typeof
base_defs = {
ROOM_EVENT: "Message Event",
STATE_EVENT: "State Event"
}
if type(json_schema.get("allOf")) == list:
schema["typeof"] = base_defs.get(
json_schema["allOf"][0].get("$ref")
)
elif json_schema.get("title"):
schema["typeof"] = json_schema["title"]
# add summary and desc
schema["title"] = json_schema.get("title")
schema["desc"] = json_schema.get("description", "")
json_schema = resolve_references(filepath, json_schema)
# walk the object for field info
schema["content_fields"] = get_tables_for_schema(
Units.prop(json_schema, "properties/content")
)
# add type
schema["type"] = Units.prop(
json_schema, "properties/type/enum"
)[0]
# This is horrible because we're special casing a key on m.room.member.
# We need to do this because we want to document a non-content object.
if schema["type"] == "m.room.member":
invite_room_state = get_tables_for_schema(
json_schema["properties"]["invite_room_state"]["items"],
)
schema["content_fields"].extend(invite_room_state)
# add summary and desc
schema["title"] = json_schema.get("title")
schema["desc"] = json_schema.get("description", "")
# walk the object for field info
schema["content_fields"] = get_tables_for_schema(
Units.prop(json_schema, "properties/content")
)
# grab msgtype if it is the right kind of event
msgtype = Units.prop(
json_schema, "properties/content/properties/msgtype/enum"
)
if msgtype:
schema["msgtype"] = msgtype[0] # enum prop
# link to msgtypes for m.room.message
if schema["type"] == "m.room.message" and not msgtype:
schema["desc"] += (
" For more information on ``msgtypes``, see "+
"`m.room.message msgtypes`_."
)
# This is horrible because we're special casing a key on m.room.member.
# We need to do this because we want to document a non-content object.
if schema["type"] == "m.room.member":
invite_room_state = get_tables_for_schema(
json_schema["properties"]["invite_room_state"]["items"],
)
schema["content_fields"].extend(invite_room_state)
# Assign state key info if it has some
if schema["typeof"] == "State Event":
skey_desc = Units.prop(
json_schema, "properties/state_key/description"
)
if not skey_desc:
raise Exception("Missing description for state_key")
schema["typeof_info"] = "``state_key``: %s" % skey_desc
schemata[filename] = schema
return schemata
# grab msgtype if it is the right kind of event
msgtype = Units.prop(
json_schema, "properties/content/properties/msgtype/enum"
)
if msgtype:
schema["msgtype"] = msgtype[0] # enum prop
# link to msgtypes for m.room.message
if schema["type"] == "m.room.message" and not msgtype:
schema["desc"] += (
" For more information on ``msgtypes``, see "+
"`m.room.message msgtypes`_."
)
# Assign state key info if it has some
if schema["typeof"] == "State Event":
skey_desc = Units.prop(
json_schema, "properties/state_key/description"
)
if not skey_desc:
raise Exception("Missing description for state_key")
schema["typeof_info"] = "``state_key``: %s" % skey_desc
return schema
def load_changelogs(self):
changelogs = {}

Loading…
Cancel
Save