Location

The user can share where they are in a message: once, as a static location, or for a while, as a live location that follows them. The location composer, messageComposer.locationComposer, holds the location to share until it's sent.

Info:

Example

The user wants to show the channel where they are for the next 15 minutes:

  1. The user's app reads the device's position and gives it to the location composer, with a duration of 15 minutes.
  2. The composer sends a message that carries the location.
  3. For the next 15 minutes, the user's app sends each new position of the device to the server.
  4. The other members' apps receive each new position as an update of that message, and their map moves with the user. After 15 minutes, the updates stop.

What it holds

The location composer's state is in locationComposer.state. Its one field, location, is the location to share, or null when there is none:

Field What it holds Set by
latitude The position's latitude. your app
longitude The position's longitude. your app
durationMs For a live location: how long to share it, in milliseconds. Absent for a static location. your app
end_at Only while a message with a live location is edited: when its sharing ends, taken from the message. the edited message
message_id The id of the message that will carry the location, which is the composer's id. the composer
created_by_device_id The device the location is shared from. the composer, from the getDeviceId setting

The composer adds message_id and created_by_device_id itself. By default, the device id is a random one, new for each composer. To keep one id per device, set messageComposer.location.getDeviceId in client.config to return an id your app stores, as Settings shows.

A new live location gets its end_at when the message is sent: the send time plus durationMs. The message then carries it in message.shared_location.end_at. While that message is edited, the composer keeps its end_at, so editing doesn't extend the sharing.

Two getters read the location:

Getter Returns Use it to
locationComposer.location The location as the composer holds it, or null. show what's being shared
locationComposer.validLocation The location the composer will send, or null when it can't be sent yet: a field is missing, or durationMs is shorter than the minShareDurationMs setting. MessageComposer.sendLocation() sends nothing while it's null. enable sharing only when the location can be sent

Sharing a location

What a location picker needs, and the call for each:

To… Call What happens
set the location to share LocationComposer.setData({ latitude, longitude }) Sets the location, with the composer's id and the device id. Does nothing while location sharing is off, or when latitude or longitude is missing.
set a live location LocationComposer.setData({ latitude, longitude, durationMs }) The same, for a location shared for durationMs milliseconds.
send the location as a message of its own MessageComposer.sendLocation() Sends a message that carries only the location, then removes the location from the composer and gives the composer a new id. Text and attachments stay. Does nothing in a thread composer, or while locationComposer.validLocation is null.
remove the location LocationComposer.initState() Sets location back to null.
const composer = channel.messageComposer;

composer.locationComposer.setData({
  durationMs: 15 * 60 * 1000,
  latitude: 50.0875,
  longitude: 14.4213,
});

await composer.sendLocation();

MessageComposer.sendLocation() doesn't add the message to the list at once: the message appears when the server's copy arrives. When the request fails, it publishes an api:location:create:failed notification and throws.

A valid location also counts as content for MessageComposer.send(), which then sends it as the message's shared_location, together with the text and attachments.

Once a live location is shared, its updates are not the composer's job. Location sharing explains how they're sent and how the sharing stops.

When location sharing is on

Location sharing is on while messageComposer.config.location.enabled is true. That's when both the location.enabled setting in client.config and the channel type's shared_locations setting are on. While sharing is off, LocationComposer.setData() ignores the location it's given, so the composer has no new location to send.

Settings

Set them for every composer in client.config, under messageComposer.location:

const deviceId = "my-app-device-id"; // for example, an id your app keeps for this device

client.config.set({
  messageComposer: {
    location: {
      getDeviceId: () => deviceId,
      minShareDurationMs: 5 * 60 * 1000,
    },
  },
});

The location composer has no setters. To change a setting for one composer only, patch that composer's configuration, for example channel.messageComposer.updateConfig({ location: { enabled: false } }).

Setting Default What it does
enabled true false turns off location sharing. Combined with the channel type's shared_locations setting.
getDeviceId a new random id per composer Returns the id of the device the location is shared from. The default gives each composer a different id: to keep one id per device, return an id your app stores. A composer calls it once, when it's created, as Settings read once explains.
minShareDurationMs 60000, one minute The shortest durationMs a live location can have. A location with a shorter one isn't valid, so it isn't sent.

See Location sharing for the feature.

Used in