Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document how presence EDUs work between servers #1482

Merged
merged 12 commits into from
Aug 21, 2018
46 changes: 46 additions & 0 deletions api/server-server/definitions/event-schemas/m.presence.accept.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright 2018 New Vector Ltd
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hum; the existing event schemas are in /event-schemas/schema.

I'm not entirely convinced there is a clear enough delineation between "events that are only for the S-S API" and "events that are only for clients" and "events that may be of interest to both" to justify putting them in separate directories.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Note to self for when I inevitably dig this up again: the existing schemas really are yaml, as per the rejected #320.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm concerned about doing this for two reasons:

  • The server events are slightly different in some cases, and would like to keep them away from the c2s to avoid accidental use.
  • This means another symlink, which I might just flip a table over if I have to keep fixing the damn things.
    • One solution is to make event-schemas a magical directory that gets referenced/loaded in the python script, but that feels like a whole new PR to me (and potentially dangerous).

#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

type: object
title: Presence Invite Accept EDU
description: |-
An EDU representing approval for the observing user to subscribe to the
presence of the the observed user.
allOf:
- $ref: ../edu.yaml
- type: object
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the other schema files don't nest the 'type/properties' under 'allOf': is there a reason we are doing so here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the question. This is to merge an EDU with more specific definitions for the type, content, etc

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, but other files which use allOf do it like:

type: object
allOf:
  - $ref: ../edu.yaml
properties:
  ...

(instead of nesting properties under allOf).

I'm not sure if one is more correct than the other, but I'd like to know if we're making a decision to change it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are you seeing the properties at such a high level? The OpenAPI way is to put them with the definition under allOf.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea, I'm tempted to call that wrong and push forward with doing it the "OpenAPI" way (I think it technically works in either way though). Potentially fixing the other cases of it are worth doing in the last hours of August.

properties:
edu_type:
type: enum
enum: ['m.presence_accept']
description: The string ``m.presence_accept``
example: "m.presence_accept"
content:
type: object
description: The invite information.
title: Invite Information
properties:
observed_user:
type: string
description: |-
The user ID that has approved the ``observer_user`` to
subscribe to their presence.
example: "@alice:elsewhere.com"
observer_user:
type: string
description: |-
The user ID that requested to subscribe to the presence of
the ``observed_user``.
example: "@john:matrix.org"
required: ['observer_user', 'observed_user']
55 changes: 55 additions & 0 deletions api/server-server/definitions/event-schemas/m.presence.deny.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

type: object
title: Presence Invite Deny EDU
description: |-
An EDU representing a declination or revocation for the observing user
to subscribe to the presence of the observed user.
example: {
"origin": "domain.com",
"destination": "elsewhere.org",
"edu_type": "m.presence_deny",
"content": {
"observed_user": "@alice:elsewhere.org",
"observer_user": "@john:domain.com"
}
}
allOf:
- $ref: ../edu.yaml
- type: object
properties:
edu_type:
type: enum
enum: ['m.presence_deny']
description: The string ``m.presence_deny``
example: "m.presence_deny"
content:
type: object
description: The invite information.
title: Invite Information
properties:
observed_user:
type: string
description: |-
The user ID that has declined or revoked the ``observer_user`` from
subscribing to their presence.
example: "@alice:elsewhere.com"
observer_user:
type: string
description: |-
The user ID that requested to subscribe to the presence of
the ``observed_user``.
example: "@john:matrix.org"
required: ['observer_user', 'observed_user']
45 changes: 45 additions & 0 deletions api/server-server/definitions/event-schemas/m.presence.invite.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

type: object
title: Presence Invite EDU
description: |-
An EDU representing a request to subscribe to a user's presence.
allOf:
- $ref: ../edu.yaml
- type: object
properties:
edu_type:
type: enum
enum: ['m.presence_invite']
description: The string ``m.presence_invite``
example: "m.presence_invite"
content:
type: object
description: The invite information.
title: Invite Information
properties:
observed_user:
type: string
description: |-
The user ID the ``observer_user`` would like to subscribe
to the presence of.
example: "@alice:elsewhere.com"
observer_user:
type: string
description: |-
The user ID that is wishing to subscribe to the presence of
the ``observed_user``.
example: "@john:matrix.org"
required: ['observer_user', 'observed_user']
71 changes: 71 additions & 0 deletions api/server-server/definitions/event-schemas/m.presence.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

type: object
title: Presence EDU
description: |-
An EDU representing presence updates for users of the sending homeserver.
allOf:
- $ref: ../edu.yaml
- type: object
properties:
edu_type:
type: enum
enum: ['m.presence']
description: The string ``m.presence``
example: "m.presence"
content:
type: object
description: The presence updates and requests.
title: Presence Update
properties:
push:
type: array
description: |-
A list of presence updates that the receiving server is likely
to be interested in.
items:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we share the definitions with the C-S side m.presence? It seems annoying that we have to maintain all this text twice.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

potentially, I'll take a closer look at the client-server format and make them link if I can.

type: object
title: User Presence Update
properties:
user_id:
type: string
description: The user ID this presence EDU is for.
example: "@john:matrix.org"
presence:
type: enum
enum: ['offline', 'unavailable', 'online']
description: The presence of the user.
example: "online"
status_msg:
type: string
description: An optional description to accompany the presence.
example: "Making cupcakes"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yum, cupcakes.

last_active_ago:
type: integer
format: int64
description: |-
The number of milliseconds that have ellapsed since the user
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

elapsed

last did something.
example: 5000
currently_active:
type: boolean
description: |-
Whether or not the user is currently using a device of theirs.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we define this in a clearer way. What does "currently" mean? How does it interact with 'last active ago'?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(github didn't collapse the thread - improved documentation by adding a blurb below this)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'm afraid the first sentence here is still pretty tortuous.

"Whether the user is currently active." is probably just as helpful and doesn't involve an ugly dangling possessive

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wording suggestions appreciated here - I'm having troubles coming up with a better way to word this at the moment.

Copy link
Member Author

@turt2live turt2live Aug 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this sound:

True if the user is likely to be interacting with their client. This may be indicated by the user having a last_active_ago within the last few minutes. Defaults to false.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, that sounds great :)

For example, if the user's ``last_active_ago`` was within the
last few minutes, they may be considered ``currently_active``.
Defaults to false.
example: true
required: ['user_id', 'presence', 'last_active_ago']
required: ['push']
3 changes: 2 additions & 1 deletion api/server-server/definitions/event-schemas/m.typing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ allOf:
- type: object
properties:
edu_type:
type: string
type: enum
enum: ['m.typing']
description: The string ``m.typing``
example: "m.typing"
content:
Expand Down
1 change: 1 addition & 0 deletions scripts/templating/matrix_templates/units.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
os.path.join(matrix_doc_dir, "api/identity/definitions"): "is",
os.path.join(matrix_doc_dir, "api/push-gateway/definitions"): "push",
os.path.join(matrix_doc_dir, "api/server-server/definitions"): "ss",
os.path.join(matrix_doc_dir, "api/server-server/definitions/presence"): "ss_presence",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this used?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed the spec seems to refer to ss_event_schemas which doesn't seem to be defined?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that said it seems to be working somehow. I'm confused.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic was added in an earlier commit: ea307b5

The TLDR is it adds another section to the templating.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right. Nevertheless api/server-server/definitions/presence doesn't seem to exist.

}
EVENT_EXAMPLES = os.path.join(matrix_doc_dir, "event-schemas/examples")
EVENT_SCHEMA = os.path.join(matrix_doc_dir, "event-schemas/schema")
Expand Down
68 changes: 18 additions & 50 deletions specification/server_server_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -827,64 +827,32 @@ Presence
The server API for presence is based entirely on exchange of the following
EDUs. There are no PDUs or Federation Queries involved.

Performing a presence update and poll subscription request::
Servers should only send presence updates for users that the receiving server
would be interested in. This can include the receiving server sharing a room
with a given user, or a user on the receiving server has added one of the
sending server's users to their presence list.

EDU type: m.presence

Content keys:
push: (optional): list of push operations.
Each should be an object with the following keys:
user_id: string containing a User ID
presence: "offline"|"unavailable"|"online"|"free_for_chat"
status_msg: (optional) string of free-form text
last_active_ago: milliseconds since the last activity by the user

poll: (optional): list of strings giving User IDs

unpoll: (optional): list of strings giving User IDs

The presence of this combined message is two-fold: it informs the recipient
server of the current status of one or more users on the sending server (by the
``push`` key), and it maintains the list of users on the recipient server that
the sending server is interested in receiving updates for, by adding (by the
``poll`` key) or removing them (by the ``unpoll`` key). The ``poll`` and
``unpoll`` lists apply *changes* to the implied list of users; any existing IDs
that the server sent as ``poll`` operations in a previous message are not
removed until explicitly requested by a later ``unpoll``.

On receipt of a message containing a non-empty ``poll`` list, the receiving
server should immediately send the sending server a presence update EDU of its
own, containing in a ``push`` list the current state of every user that was in
the original EDU's ``poll`` list.

Sending a presence invite::

EDU type: m.presence_invite

Content keys:
observed_user: string giving the User ID of the user whose presence is
requested (i.e. the recipient of the invite)
observer_user: string giving the User ID of the user who is requesting to
observe the presence (i.e. the sender of the invite)

Accepting a presence invite::

EDU type: m.presence_accept

Content keys - as for m.presence_invite

Rejecting a presence invite::

EDU type: m.presence_deny

Content keys - as for m.presence_invite
Clients may define lists of users that they are interested in via "Presence
Lists" through the `Client-Server API`_. When users are added to a presence
list, a ``m.presence_invite`` EDU is sent to them. The user may then accept
or deny their involvement in the list by sending either an ``m.presence_accept``
or ``m.presence_deny`` EDU back.

.. TODO-doc
- Explain the timing-based round-trip reduction mechanism for presence
messages
- Explain the zero-byte presence inference logic
See also: docs/client-server/model/presence

{{definition_ss_event_schemas_m_presence}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's jarring that this ends up formatted very differently to the event schemas in the C-S spec.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My dream is to put the c2s spec through the same treatment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum. the heading is fugly. can it be made to say "m.presence.invite schema" or "m.presence.invite EDU schema" rather than "Presence Invite EDU Schema" (cf also #1531)


{{definition_ss_event_schemas_m_presence_invite}}

{{definition_ss_event_schemas_m_presence_accept}}

{{definition_ss_event_schemas_m_presence_deny}}


Receipts
--------

Expand Down