Workplace from Meta is going away. You will be able to continue using Workplace until 31 August 2025. Visit our Help Center to find out more.
Authenticated Previews make your content preview correctly on Workplace. This entails providing support for authenticated preview metadata in a format Workplace expects, such that when URLs to your content are shared, Workplace can fetch that metadata and create a preview. This process is often called link unfurling.
While Facebook is able to get metadata to unfurl a public URL via the Open Graph protocol and the Facebook Crawler, this process is not possible for private URLs, which are more commonly shared into Workplace. When someone shares a private URL into Workplace, a webhook will be issued to a callback URL you define, and you'll be able to respond with a metadata payload describing the URL for the person sharing it, in order to render a link preview.
This same process will repeat for each person who views the shared URL on Workplace, allowing you to control the preview visibility on a per-user basis.
Authenticated for Workplace allow people to share information safely and easily on Workplace, in a way that respects the privacy of the source material. By supporting Authenticated Previews, you can ensure that your content previews correctly on Workplace, in a secure privacy-aware way.
On Workplace, people often share links to internal company resources, which should only be viewable by certain people. This is in contrast to Facebook, where people commonly share public content, like news articles or blog posts.
In order for Workplace to generate a preview to company-private content, some metadata needs to be provided. As a provider, you can choose whether to provide metadata for the current viewer on Workplace, depending on whether they're allowed to view the content or not.
This document outlines the components of enabling Authenticated Previews, including:
In order to enable authenticated previews, you'll need to configure your app for the following:
There are multiple situations where we will send a request to the provider:
In any of the above scenarios, a webhook will be sent as a POST
request, in the following format:
{ "object": "link", "entry": [ { "time": int, "changes": [ { "field": "preview", "value": { "community": { "id": string, }, "user": { "id": string, }, "link": string, } } ] } ] }
This payload contains the following fields:
Field Name | Description |
---|---|
| The webhook topic. This is always |
| A list of requests, is always exactly one. |
| The time when the request was sent. |
| A list of changes in this request, is always exactly one. |
| The webhook field, is always |
| The actual object containing the context of the request. |
| The community of the user that triggered the request. |
| The user that triggered the request. |
| The link that Workplace is attempting to render, which matches the domain and regex configured by the app. |
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": "preview", "value": { "community": { "id": "138169208138649" }, "user": { "id": "88575656148087" } "link": "https://company.third-party.com/document-about-this" } }] }] }
When you receive a webhook request, you will need to provide a metadata payload in a specific response format:
{ "data": [ { "link": string, ?"canonical_link": string, ?"title": string, ?"description": string, ?"icon": string, ?"download_url": string, "privacy": 'organization' | 'accessible' | 'inaccessible', ?"type": 'document' | 'folder' | 'task' | 'link', ?"additional_data": [ { "title" => string, "format" => 'text' | 'date' | 'datetime' | 'user', "value" => string | number, ?"color" => 'blue' | 'green' | 'yellow' | 'orange' | 'red', }, ], } ], ?"linked_user": boolean }
This payload will be expected to contain the following fields:
Field Name | Description |
---|---|
| A collection of items available to the user, this can be empty if the app chooses to not unfurl this link for this user at all. |
| A boolean field indicating whether the third party is aware of the user - if this is set to |
| A unique identifying link for this item, must match the link in the request. |
| A canonical url representation of this content. If different from the link this content will be associated with the canonical content for easier querying of the related shares. |
| The title of this item, must be present except for items that have the privacy set to inaccessible. |
| A short description of the item that will be rendered in the rich preview. |
| 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. |
| A URL from which Workplace can download a PDF, JPEG or PNG representation of the item to convert it into a image post. This will be ignored for anything except |
| Denotes the object's privacy. This can either be |
| This can either be |
| A collection of metadata that will be rendered in the rich preview. Will be ignored for |
HTTP/1.1 200 OK Content-Type: application/json X-Hub-Signature: sha1=b5a6f32f084100ae5b355174b9bb8398f5fbe983 ... { "data": [ { "link": "https://taaskly.herokuapp.com/task/4", "title": "Launch Workplace Integration for F8", "privacy": "organization", "type": "task", "additional_data": [ { "title": "Owner", "format": "user", "value": "319922278498384" }, { "title": "Created", "format": "datetime", "value": "2018-02-28T03:35:40.827Z" }, { "title": "Priority", "format": "text", "value": "high", "color": "red" } ] } ], "linked_user": true }
The privacy mode determines the visibility, whether we require user auth for the current and subsequent users.
organization
: Visible To User, No user Auth requiredaccessible
: Visible to current user, but user identity mapping may be required for others.inaccessible
: Not visible to userTo add more information on a link preview, you can send up to three items of additional data. An additional data item is comprised of a set of key value elements. But the value can be formatted in different ways.
Currently four different formats are supported:
text
: Will render the value as is, the value must be a string. For this format additional data can also contain a property color
which must be one of the values blue
, green
, yellow
, orange
or red
. If present, this will render the value with the color as a background.date
: Will parse the value as ISO-8601 date format without time and render it without time indication.datetime
: Will parse the value as ISO-8601 date format with time and timezone and render with with time indication in the users timezone.user
: Will parse the value as a user id and render the user's name.The download_url
parameter is ignored if additional data is set.
If the privacy mode for your document is marked as either organization
or accessible
, and a download URL is provided, we will send an additional request to download the data.
GET /download/super-fancy-document HTTP/1.1 Host: provider.com Accept: <some mime types> User-Agent: Webhooks/1.0 (https://fb.me/webhooks) X-Hub-Signature: sha1=bf3102e52efd0fd4bd26277030aa180d7b5cf587
Workplace will then take this file and convert it to photos to make a multi-photo post out of it.
As seen above, providing authenticated previews requires some kind of identity mapping. Identity mapping controls whether a Workplace user has the permission to see the content being previewed, and ensures that the access rules of your content are respected on Workplace.
The simplest form of identity mapping is organization-wide mapping, where membership of a Workplace community is sufficient to allow previews to be shown to users on Workplace. This scenario is common when previewing links to a company-wide intranet, or any service where all objects (or at least their metadata) are visible to the entire company.
When your integration is installed on a Workplace community, the community ID can be checked via the /community
endpoint, using the access token you retrieved upon install. You can store this community ID along with the token, and map it to a tenant or organization identifier inside your service. This creates a mapping between a Workplace community and the organization in your service.
Then, when responding to authenticated preview webhook requests, you can check that the webhook payload's community ID matches that organization-linked community ID, then decide whether it's safe to return a metadata payload. Marking that payload's privacy as ORGANIZATION ensures that we won't need to send additional webhooks for each user in that Workplace community.
If more permission granularity is needed, you can support a per-user mapping, ensuring that you can choose whether to render metadata to each viewer on Workplace individually.Workplace sends over a user ID in each webhook payload for authenticated previews. To support per-user mapping, you'll need to know which user record in your system maps to the Workplace user ID sent in the webhook payload.
If this is your first encounter for a given Workplace user ID, you can respond with the boolean field linked_user
set to false
. This will instruct Workplace to show an Enable Preview button, prompting the user to link their account.
When the button is pressed, Workplace will open a dialog to an account linking endpoint that you define, where you can validate the user session in your service. Workplace will open this URL via a POST request, and will pass a signed request parameter, which contains the current user ID and community ID.
POST https://www.example.com/account_linking?redirect_uri=https%3A%2F%2Ffoxfabrics.facebook.com%2Flink_complete HTTP/1.1 Host: foxfabrics.third-party.com Origin: http://www.facebook.com Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 Gecko/20100101 Firefox/57.0 ... signed_request=238fsdfsd.oijdoifjsidf899
In the payload is a parameter signed_request which contains information about this user. This request can be decoded as follows:
The payload contains the following fields:
{ "algorithm": "HMAC-SHA256", "user_id": "88575656148087", "community_id": "138169208138649" }
At this point, you'll have a Workplace user ID and community ID, along with a validated user session in your service, and will be able to record the Workplace ID for this user beside their ID in your service. Upon completion, you should redirect to the url provided on the original request as query param redirect_uri.
GET {$redirect_uri} HTTP/1.1 Host: foxfabrics.facebook.com User-Agent: Mozilla/5.0 Gecko/20100101 Firefox/57.0 Referer: https://www.example.com/account_linking ...
Workplace will then recognize that the identity mapping is complete, and will attempt to request authenticated preview metadata again. This time, you'll be able to respond with linked_user
set to true
, and provide the metadata required.
This entire round-trip should only happen once each time an unrecognised user tries to preview a piece of content for the first time. Once the identity mapping is completed, subsequent previews should be able to bypass this round-trip.
No, Workplace Authenticated Previews do not have the same performance requirements or unsubscribe behavior as Messenger Platform webhooks.
So that people using Workplace have a good experience, the full HTTP roundtrip should take less than 5 seconds as measured from the Workplace side (i.e., the HTTP client side).
No, these requests are one-time only.
For estimating / expectation standpoint you can plan around this behavior. You may observe some differences in practice due to retries or race conditions.
No, Workplace will not automatically disable a link webhooks subscription.