-
Notifications
You must be signed in to change notification settings - Fork 401
MSC1767: Extensible event types & fallback in Matrix (v2) #1767
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
Merged
Merged
Changes from 6 commits
Commits
Show all changes
45 commits
Select commit
Hold shift + click to select a range
6121eee
first cut of MSC1767 for extensible events (replaces MSC1225)
ara4n ba2c279
tabs->spaces
ara4n 132526c
fix markdown
ara4n dcedbeb
fix markdown
ara4n 02f257a
GFM needs two spaces after ##?
ara4n e8d8b94
delta from msc1225
ara4n 2929a66
Merge branch 'master' into matthew/msc1767
turt2live 2ab20c3
2021 refresh
turt2live d7cb0a9
Refactor to be just text messaging + schema
turt2live fdd5b84
Update MSC numbers
turt2live 80e8a42
Touchups for FCP
turt2live 0e4631c
*ahem*
turt2live 4afdc32
Rewrite MSC to be understandable?
turt2live d6046d8
Update proposals/1767-extensible-events.md
turt2live e05922d
Rewrite MSC, again
turt2live 3af300b
Clarify Andy's blog state
turt2live 5f15b9f
Relax m.markup's requirements
turt2live 0564626
Misc clarifications
turt2live 78d77f7
Revert "Relax m.markup's requirements"
turt2live 16f8f08
Clarify push rules handling
turt2live 13fd844
Fix example
turt2live b10cc39
Merge branch 'old_master' into matthew/msc1767
turt2live 67d3942
Update extensible events MSCs list
turt2live 516f8da
Update Andy's blog post reference
turt2live 48e0588
Update per review feedback
turt2live e38c1ea
Cover all the bases
turt2live d793b56
Clarify mixins are exactly what they're assumed to be
turt2live 4d7e4a6
Clarify fallback and number of datums per event
turt2live 99284b3
Fix description of plain text baseline
turt2live ed21067
Clarify SCT's role in feature scope & cut "mixed" events (not mixins)
turt2live 7ed4cbc
Fix description of mixins
turt2live 67bb399
Update proposals/1767-extensible-events.md
turt2live c18b155
Expand on how unknown events are handled
turt2live d7488b8
Apply suggestions from code review
turt2live d11a26c
Trim line length post-suggestions
turt2live 38b8878
Mention that extensible events might appear in other room versions early
turt2live 435f172
Remove duplicated unknown parse order being an implementation detail
turt2live 564499f
Note difference between optional content blocks and mixins
turt2live 4bd286e
Apply suggestions from code review
turt2live 3819d92
Update proposals/1767-extensible-events.md
turt2live 6861219
Clarify that clients are still strongly encouraged to validate HTML
turt2live c5db1a0
Fix mention of mixing legacy event types
turt2live 7381697
Update proposals/1767-extensible-events.md
turt2live 98bc9ad
Link to MSC3765
turt2live 7161196
Rename `m.markup` to `m.text`
turt2live File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,347 @@ | ||
# MSC1767: Extensible events in Matrix | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Problem | ||
|
||
1. There is no formal mechanism of extending events with additional structured metadata. | ||
2. New events tend to reinvent the wheel rather than being able to reuse existing types. | ||
3. Clients don’t know how to render unknown event types. | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
This is seriously hindering uptake of new event types in Matrix - whether that’s | ||
richer data types (stickers, location, calendaring, etc) or IOT-style use cases. | ||
It also means we are currently using an underspecified solution for rich | ||
messaging, as there has never been a previous agreed way of a jury rig solution | ||
for rich messaging as we never previously agreed a way of expressing alternate | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
formats of displaying the same event. | ||
|
||
## Solution | ||
|
||
We group the keys of an event's contents together into different types. This lets | ||
us address the problem by: | ||
|
||
1. Making it easy to extend events by adding new types into contents alongside existing ones. | ||
2. Making it easy to reuse existing types by adding new ones alongside existing ones. | ||
3. Letting clients render unknown event types by falling back to types in the event that they *do* recognise. | ||
|
||
Events still have a primary type, which is used when sending them in Matrix. | ||
|
||
The names of the keys in contents are now expected to be namespaced, given they | ||
typically refer to types of events. However, for compatibility, we can keep using | ||
some of the original fields too. | ||
|
||
Certain types (e.g. `m.message`, `m.caption`, `m.thumbnail`) which can contain | ||
multiple alternative payloads in different formats express the alternatives as | ||
an ordered list; most preferred first. | ||
|
||
We provide short-form types (`m.text` and `m.html`) for the most common scenarios | ||
of an event requiring a plain-text or HTML-formatted representation. | ||
|
||
For convenience and compatibility, we keep "body" and "formatted_body" as | ||
shorthand for plain-text and html-formatted fallback for events. | ||
|
||
The various types in an event's contents MUST refer to the same event. Multiple | ||
events should be linked using a `m.relates_to` reference rather than multiplexing | ||
into a single event. | ||
|
||
Here are proposals for different types of events: | ||
|
||
### m.text and m.html | ||
|
||
For compactness for this super-common case, we define a short form which is | ||
equivalent to the longer form `m.message` example below: | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```json | ||
{ | ||
"type": "m.message", | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"content": { | ||
"m.text": "i am a *fish*", | ||
"m.html": "i am a <b>fish</b>" | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
``` | ||
|
||
### m.message | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
m.message describes a simple textual instant message. | ||
|
||
```json | ||
{ | ||
"type": "m.message", | ||
"content": { | ||
"m.message": [ | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
"mimetype": "text/html", | ||
"body": "i am a <b>fish</b>" | ||
}, | ||
{ | ||
"mimetype": "text/plain", | ||
"body": "i am a *fish*" | ||
} | ||
], | ||
} | ||
} | ||
``` | ||
|
||
### m.file | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```json | ||
{ | ||
"type": "m.file", | ||
"content": { | ||
"m.text": "foo.dat (12KB)", | ||
"m.file": { | ||
"url": "mxc://matrix.org/asdjkhcsd", | ||
"name": "foo.dat", | ||
"mimetype": "application/octet-stream", | ||
"size": 12345 | ||
} | ||
} | ||
} | ||
``` | ||
|
||
### m.image | ||
|
||
```json | ||
{ | ||
"type": "m.image", | ||
"content": { | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"m.text": "matrix logo (640x480, 12KB)", | ||
"m.image": { | ||
"width": 640, | ||
"height": 480, | ||
}, | ||
"m.file": { | ||
"url": "mxc://matrix.org/asdjkhcsd", | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"mimetype": "image/jpeg", | ||
"name": "logo.jpg", | ||
"size": 12345 | ||
}, | ||
"m.caption": [ | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
"body": "matrix logo" | ||
} | ||
], | ||
"m.thumbnail": [ | ||
{ | ||
"url": "mxc://matrix.org/thumb", | ||
"mimetype": "image/jpeg", | ||
"width": 160, | ||
"height": 120, | ||
"size": 123 | ||
} | ||
], | ||
} | ||
} | ||
``` | ||
|
||
XXX: do we need to worry about the schema overlap between m.file/m.image and m.thumbnail? | ||
do we need to specify how specific thumbnails can have specific captions (or is that effectively displayhints?) | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### m.message containing original source text, to allow future edits: | ||
|
||
```json | ||
{ | ||
"type": "m.message", | ||
"content": { | ||
"m.message": [ | ||
{ | ||
"mimetype": "text/html", | ||
"body": "I am a <a href=\"http://www.reddwarf.co.uk\">fish</a>", | ||
}, | ||
{ | ||
"mimetype": "text/markdown", | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"original": true, | ||
"body": "I am a [fish](http://www.reddwarf.co.uk)", | ||
}, | ||
{ | ||
"mimetype": "text/plain", | ||
"body": "I am a fish < http://www.reddwarf.co.uk/ >", | ||
}, | ||
] | ||
} | ||
} | ||
``` | ||
|
||
### m.message interationalised | ||
|
||
```json | ||
{ | ||
"type": "m.message", | ||
"content": { | ||
"m.message": [ | ||
{ | ||
"body": "Je suis un poisson", | ||
"lang": "fr", | ||
}, | ||
{ | ||
"body": "I am a fish", | ||
"lang": "en_EN", | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
|
||
The french text is preferred and comes next, and a non-i18n aware client would | ||
use it. A smarter i18n-aware client would realise the user can't speak french | ||
and fall through to the next one. | ||
|
||
### m.video | ||
|
||
```json | ||
{ | ||
"type": "m.video", | ||
"content": { | ||
"m.text": "animated matrix logo (logo.mp4, 1280x720, 1m30s, 23.6MB)", | ||
"m.video": { | ||
"width": 1280, | ||
"height": 720, | ||
"duration": 90000, | ||
}, | ||
"m.file": { | ||
"url": "mxc://matrix.org/v1d30", | ||
"mimetype": "video/mp4", | ||
"name": "logo.mp4", | ||
"size": 23654321 | ||
}, | ||
"m.caption": [ | ||
{ | ||
"body": "animated matrix logo" | ||
} | ||
], | ||
"m.thumbnail": [ | ||
{ | ||
"url": "mxc://matrix.org/videothumb", | ||
"mimetype": "video/mp4", | ||
"animated": true, | ||
"width": 128, | ||
"height": 72, | ||
"size": 12300 | ||
}, | ||
{ | ||
"url": "mxc://matrix.org/thumb", | ||
"mimetype": "image/jpeg", | ||
"width": 128, | ||
"height": 72, | ||
"size": 123 | ||
} | ||
], | ||
} | ||
} | ||
``` | ||
|
||
### IOT events (e.g. net.arasphere.temperature) | ||
|
||
with text fallback: | ||
|
||
```json | ||
{ | ||
"type": "net.arasphere.temperature", | ||
"content": { | ||
"m.text": "The temperature is 37C", | ||
"m.html": "The temperature is <font color='#f00'>37C</font>", | ||
"net.arasphere.temperature": { | ||
"temperature": 37.0 | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
} | ||
``` | ||
|
||
### m.calendar.request | ||
|
||
This is a deliberately chunky event designed to show a geotagged calendar request. | ||
|
||
(In practice we should probably use the IETF jsCalendar format rather than inventing a | ||
new one here, and to ensure interop with the JMAP folks. | ||
https://tools.ietf.org/html/draft-ietf-calext-jscalendar-11) | ||
|
||
```json | ||
{ | ||
"type": "m.calendar.request", | ||
"content": { | ||
"m.text": "Invite to Party at Bob's House on Feb 7th, 3pm", | ||
"m.html": "Invite to Party at <i>Bob's house</i> on Feb 7th, 3pm", | ||
"m.calendar.request": { | ||
"version": "2.0", | ||
"summary": "Party at Bob's house", | ||
"vEvent": { | ||
"dtStart": { | ||
"date": "20180207T150000", | ||
"tzId": "Europe/London" | ||
}, | ||
"dtEnd": { | ||
"date": "20180207T180000", | ||
"tzId": "Europe/London" | ||
} | ||
} | ||
}, | ||
"m.file": { | ||
"uri": "mxc://matrix.org/auiheiuh1eqwd", | ||
"mimetype": "text/calendar", | ||
"name": "bobs-party.ics", | ||
"size": 1246 | ||
}, | ||
"m.location": { | ||
ara4n marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"uri": "geo:37.786971,-122.399677;u=35", | ||
"description": "123 Fake Street" | ||
}, | ||
"m.thumbnail": [ | ||
{ | ||
"uri": "mxc://localhost/JWEIFJgwEIhweiWJE", | ||
"width": 256, | ||
"height": 256, | ||
"mimetype": "image/jpeg", | ||
"size": 1024000 | ||
} | ||
], | ||
} | ||
} | ||
``` | ||
|
||
This would be nicer with displayhints support, but still works pretty well. | ||
|
||
|
||
## Tradeoffs | ||
|
||
It's a bit ugly to not know whether a given key will take a string, hash or array. | ||
|
||
It's a bit arbitrary as to which fields are allowed lists of fallbacks. | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
It's a bit ugly that you have to look over the keys of contents to see what types | ||
are present, but better than duplicating this into an explicit `types` list (on balance). | ||
|
||
We're skipping over defining rules for which fallback combinations to display | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
(i.e. "display hints") for now; these can be added in a future MSC if needed. | ||
MSC1225 contains a proposal for this. | ||
|
||
## Issues | ||
|
||
I think Erik had some concerns about mixing together types at the top level of `contents` | ||
but I've forgotten the details. Hopefully these are mitigated by the revised approach. | ||
|
||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
## Security considerations | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
We can't apply ACLs serverside to the types embedded in the event contents. | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
However, this is inevitable given the existence of E2E, so we have no choice but | ||
for clients to apply ACLs clientside (e.g. refuse to render an m.image contents | ||
on an event if the sender doesn't have enough PL to send an m.image event). | ||
|
||
## Availability | ||
|
||
Given the disruption of migrating clients & bridges to the new event shape, this | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
should probably land after S2S r0. | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Migration | ||
|
||
Currently visible events are `m.room.message` with a `msgtype` to distinguish | ||
between `m.text`, `m.image`, `m.file`, etc. | ||
|
||
...? | ||
|
||
## Changes from MSC1225 | ||
|
||
* converted from googledoc to MD, and to be a single PR rather than split PR/Issue. | ||
* simplifies it by removing displayhints (for now) | ||
* removes all references to mixins, as the term was scaring people and making it feel far too type-theoretic | ||
* replaces the clunky m.text.1 idea with lists for types which support fallbacks | ||
* removes the concept of optional compact form for m.text by instead having m.text always in compact form | ||
* tries to accomodate most of the feedback on GH and Google Docs from MSC1225. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.