Share Extensions for Workplace

Overview

Providing Authenticated Previews for links people share into Workplace is incredibly powerful by itself. But you can make it even easier for people to share content they're working on in your app, directly from Workplace, by supporting Share Extensions.

If your integration supports Share Extensions, you can provide a list of recent or relevant documents when a user starts to write a post in an enabled Workplace group, and Workplace will render that list so that the user can share without having to copy-paste the URL. The resulting share object will behave just like an object that was shared manually, including respecting the permissions of the authenticated preview functionality.

Share extensions require an identity-mapped user, so that you can return a personalised list of documents to the composer.

Configuration

To support share extensions, your app will need the following configuration:

  • Webhook subscription on the topic link and the field collection.
  • An account linking URL, as provided when configuring your app.

Webhook Request Format

When a linked user invokes your integration's share extension, Workplace will send a webhook out to fetch a list of documents, in the following format:

{
  "object": "link",
  "entry": [
    {
      "time": int,
      "changes": [
        {
          "field": "collection",
          "value": {
            "community": {
              "id": string,
            },
            "user": {
              "id": string,
            },
            ?"link": string,
          }
        }
      ]
    }
  ]
}
    

This payload contains the following fields:

Field NameDescription

object

The webhook topic. This is always link in this context.

entry

A list of requests, is always exactly one.

entry.time

The time when the request was sent.

entry.changes

A list of changes in this request, is always exactly one.

entry.changes.field

The webhook field, is always collection.

entry.changes.value

The actual object containing the context of the request.

entry.changes.value.field.community

The community of the user that triggered the request.

entry.changes.value.field.user

The user that triggered the request.

entry.changes.value.field.link

if the user is drilling down into folders, this is set for subsequent requests, but not present for root requests

Example:

POST /callback HTTP/1.1
Host: third-party.com
Accept: application/json
Content-Type: application/json
User-Agent: Webhooks/1.0 (https://fb.me/webhooks)
X-Hub-Signature: sha1=bf3102e52efd0fd4bd26277030aa180d7b5cf587
...

{
    "object": "link",
    "entry": [{
        "time": 1501515097793,
        "changes": [{
            "field": "collection",
            "value": {
                "community": {
                    "id": "138169208138649"
                },
                "user": {
                    "id": "88575656148087"
                }
            }
        }]
    }]
}
    

Webhook Response Format

To handle this request, your callback URLneeds to verify the `X-Hub-Signature` and is then respond with a set of objects to be shown in the composer, in the following format:

{
  "data": [
    {
      "link": string,
      "title": string,
      ?"description": string,
      ?"icon": string,
      ?"download_url": string,
      "privacy": ORGANIZATION | ACCESSIBLE,
      "type": DOCUMENT | FOLDER | TASK | LINK,
      ?"additional_data": [
        {
          "title" => string,
          "format" => 'text' | 'date' | 'datetime' | 'user',
          "value" => string | number,
        },
      ],
    }
  ],
  ?"linked_user": boolean
}

This payload will be expected to contain the following fields:

Field NameDescription

data

A collection of items available to the user

linked_user

A boolean field indicating whether the third party is aware of the user - if this is set to false, we will show a linking dialog.

data.link

A unique identifying link for this item.

data.title

The title of this item, must be present except for items that have the privacy set to inaccessible.

data.description

A short description of the item that will be rendered in the rich preview.

data.icon

A asset for this content for places where Workplace shows a icon of the content. This must be a url and publicly accessible. For best results the asset should be a 16px square.

data.download_url

A URL from which Workplace can download a PDF representation of the item to convert it into a image post. This will be ignored for anything except document and link object types.

data.privacy

Denotes the object's privacy. This can either be organization or accessible or inaccessible. If organization, then Workplace assumes this item can be shown to everybody within the community, even without linking of the account; accessible means it is available to the logged in user, but not necessarily to anybody else; inaccessible means that this document is not available to this user.

data.type

This can either be document, folder, task or link. A folder is a collection of other folders or documents. Must be present except for items that have privacy set to inaccessible.

data.additional_data

A collection of metadata that will be rendered in the rich preview. Will be ignored for document and folder. Will only use the first three elements. For more details on the format of these fields, see the Additional Data section.

Example:

HTTP/1.1 200 OK
Content-Type: application/json
X-Hub-Signature: sha1=b5a6f32f084100ae5b355174b9bb8398f5fbe983
...

{
  "data": [
    {
      "link": "https://company.third-party.com/document-A",
      "title": "Slides for Project A",
      "description": "Short summary of the slides.",
      "download_url": "https://company.provider.com/download/document-A",
      "privacy": "accessible",
      "type": "document"
    },
    {
      "link": "https://company.third-party.com/folder-B",
      "title": "Folder B",
      "privacy": "public",
      "type": "folder",
    }
  ],
  "linked_user": true
}