Skip to content

Latest commit

 

History

History
199 lines (161 loc) · 7.8 KB

3488-location.md

File metadata and controls

199 lines (161 loc) · 7.8 KB

MSC3488 - m.location: Extending events with location data

Problem

We need a standard way to share location data about events in Matrix. Use cases include sharing freeform static location info, sharing live-updating location data of assets, associating location data with IOT telemetry, etc.

The spec currently has the concept of an m.location msgtype on m.room.message events, but this is very limiting as it only applies to sharing location as an instant message. Instead, we'd like to leverage extensible events (MSC1767) to associate location data with any kind of event.

Proposal

We introduce m.location as an extensible event type: a key which can be placed in the content of any event to associate a location object with the other data (if any) in that event. Clients which are location-aware may let the user view events containing m.location on a map.

This is intended to eventually replace the m.location msgtype (although this MSC doesn't obsolete it)

The m.location object must contain a uri field with a standard RFC5870 geo: URI.

It may also contain an optional description field, giving a free-form label that should be used to label this location on a map. This is not to be confused with fallback text representations of the event, which are given by m.text or m.html as per MSC1767. The description field is also not intended to include semantic descriptions of the location (e.g. the details of a calendar invite), which should be stored in their respective extensible event types when available.

XXX: should description be localised?

m.location can also contain an optional zoom_level field to specify the displayed area size on client mapping libraries. Possible values range from 0 to 20 based on the definitions from OpenStreetMap here and it would be the client's responsibility to map them to values a particular library uses, if different. The client is also free to completely ignore it and decide the zoom level through other means.

"m.location": {
    "uri": "geo:51.5008,0.1247;u=35",
    "description": "Our destination",
    "zoom_level": 15,
}

In order to differentiate between user tracking and other objects we also introduce a new subtype called m.asset to give the object a type and ID.

m.asset defines a generic asset that can be used for location tracking but also in other places like inventories, geofencing, checkins/checkouts etc. It should contain a mandatory namespaced type key defining what particular asset is being referred to. For the purposes of user location tracking m.self should be used in order to avoid duplicating the mxid.

If m.asset is missing from the location's content the client should render it as m.self as that will be the most common use case. Otherwise, if it's not missing but the type is invalid or unknown the client should attempt to render it as a generic location. Clients should be able to distinguish between m.self and explicit assets for this feature to be correctly implemented as interpreting everything as m.self is unwanted.

If sharing time-sensitive data, one would add another subtype (e.g. a hypothetical m.ts type) to spell out the exact time that the data in the event refers to (milliseconds since the UNIX epoch)

If m.location is used as the event type itself, it describes a contextless static location, suitable for "drop a pin on a map" style use cases.

Example for sharing a static location:

{
    "type": "m.location",
    "content": {
        "m.location": {
            "uri": "geo:51.5008,0.1247;u=35",
            "description": "Matthew's whereabouts",
        },
        "m.asset": {
            "type": "m.self" // the type of asset being tracked
        },
        "m.ts": 1636829458432,
        "m.text": "Matthew was at geo:51.5008,0.1247;u=35 as of Sat Nov 13 18:50:58 2021"
    }
}

Migration from the m.location msgtype

Historically in Matrix, static locations have been shared via the m.location msgtype in m.room.message. Until that API is deprecated from the spec, clients should share static locations in a backwards-compatible way by mixing in the m.location extensible event type from this MSC into the old-style m.room.message. During this migratory phase, this necessarily duplicates the relevant data. If both fields are present, clients that speak MSC3488 should favour the contents of the MSC3488 fields over the legacy geo_uri field.

{
    "type": "m.room.message",
    "content": {
        "body": "Matthew was at geo:51.5008,0.1247;u=35 as of Sat Nov 13 18:50:58 2021",
        "msgtype": "m.location",
        "geo_uri": "geo:51.5008,0.1247;u=35",
        "m.location": {
            "uri": "geo:51.5008,0.1247;u=35",
            "description": "Matthew's whereabouts",
        },
        "m.asset": {
            "type": "m.self" // the type of asset being tracked
        },
        "m.text": "Matthew was at geo:51.5008,0.1247;u=35 as of Sat Nov 13 18:50:58 2021",
        "m.ts": 1636829458432,
    }
}

This means that clients which do not yet implement MSC3488 will be able to correctly handle the location share. In future, an MSC will be written to officially deprecate the m.location msgtype from the spec, at which point clients should start sending m.location event types instead. Clients should grandfather in the old m.location msgtype format for posterity in order to display old events; this is unavoidable (similar to HTML being doomed to display blink tags until the end of days).

Alternatives

We could use GeoJSON (RFC7946) to describe the location. However, it doesn't support the concept of uncertainty, and is designed more for sharing map annotations than location sharing. It would look something like this if we used it:

"m.geo": {
    "type": "Point", 
    "coordinates": [30.0, 10.0]
}

Another design choice is to represent static shared locations as a normal room event rather than a state event. The reason we've chosen non-state events is so that the data is subject to normal history visibility: it's very much a transient event. Just because I temporarily mention a location to someone doesn't mean I want it pinned in the room state forever more. On the other hand, it means that streaming location data (where you do want to keep track of the current location in room state) ends up being a different shape, which could be a little surprising.

Security considerations

Geographic location data is high risk from a privacy perspective. Clients should remind users to be careful where they send location data, and encourage them to do so in end-to-end encrypted rooms, given the very real risk of real-world abuse from location data.

All points from https://www.w3.org/TR/geolocation/#security apply.

Well-known configuration

Homeservers should be allowed to define a custom tile server to use. For that we introduce a new key in .well-known called m.tile_server which should contain a map_style_url pointing to the desired map style json.

Clients should read the .well-known and reconfigure accordingly, with values coming from it taking precedence over base configuration.

{
    "m.tile_server": { 
        "map_style_url": "https://www.example.com/style.json"
    },
    
    
    "m.homeserver": {
        "base_url": "https://matrix-client.matrix.org"
    },
    "m.identity_server": {
        "base_url": "https://vector.im"
    }
}

Unstable prefix

  • m.location used as a event type and extensible event field name should be referred to as org.matrix.msc3488.location until this MSC lands.
  • m.ts should be referred to as org.matrix.msc3488.ts until this MSC lands.
  • m.asset should be referred to as org.matrix.msc3488.asset until this MSC lands.
  • m.tile_server should be referred to as org.matrix.msc3488.tile_server until this MSC lands.