Авторизованный предпросмотр

Обзор

Авторизованные предпросмотры позволяют правильно организовать предварительный просмотр вашего контента в Workplace. Для этого требуются метаданные в определенном формате: при публикации URL вашего контента Workplace получает их и формирует предпросмотр. Этот процесс часто называют развертыванием ссылок.

Facebook может получать метаданные для развертывания общедоступного URL с помощью протокола Open Graph и краулера Facebook, но для частных URL, которые обычно публикуются в Workplace, такой метод не подходит. Если кто-то опубликовал частный URL в Workplace, на указанный вами URL обратного вызова отправляется уведомление Webhooks, в ответе на которое можно передать метаданные с описанием URL для человека, который его опубликовал, чтобы сгенерировать предпросмотр ссылки.

Этот процесс повторяется для каждого пользователя, просматривающего опубликованный URL в Workplace, что позволяет контролировать видимость предварительного просмотра для отдельных пользователей.

Аутентификация в Workplace позволяет людям легко и безопасно делиться информацией с соблюдением конфиденциальности исходного материала. Благодаря авторизованным предпросмотрам ваш контент будет правильно отображаться в Workplace с соблюдением всех правил безопасности.

Публикация частных URL

В Workplace пользователи часто делятся ссылками на внутренние ресурсы компании, которые должны быть видны не всем. Этим Workplace отличается от Facebook, где люди обычно публикуют общедоступный контент, например новости или записи в блоге.

Общедоступные и частные URL в Workplace

Чтобы платформа Workplace могла сгенерировать предпросмотр для конфиденциального контента компании, необходимо предоставить определенные метаданные. Вы как поставщик услуг должны определить, разрешено ли текущему пользователю Workplace просматривать контент и, соответственно, следует ли предоставить ему метаданные.

Содержание

В этом документе рассматриваются различные аспекты реализации авторизованных предпросмотров:

Конфигурация

Чтобы включить авторизованные предпросмотры, необходимо настроить приложение следующим образом:

  • установить его в сообществе Workplace или в одной или нескольких группах;
  • предоставить разрешение на развертывание ссылок;
  • указать домен или группу доменов, содержащие URL, которые будет развертывать ваша интеграция;
  • подписаться на тему Webhooks Link для предпросмотра полей и указать URL обратного вызова для предоставления метаданных.

Webhooks

Получение Webhooks

Мы отправляем запрос поставщику услуг в различных ситуациях:

  1. при публикации нового URL, который нам ещё не известен (из поля для публикаций);
  2. если мы не знаем, есть ли у нового пользователя доступ к контенту, который он пытается просмотреть (из ленты);
  3. при репосте контента (из поля для публикаций или ленты) или истечении срока его действия.

Формат запроса Webhooks

Во всех описанных выше случаях Webhooks отправляется как запрос POST в следующем формате:

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

Полезные данные содержат следующие поля:

Имя поляОписание

object

Тема Webhooks. В данном контексте это всегда link.

entry

Список запросов. Необходимо одно и только одно такое поле.

entry.time

Время отправки запроса.

entry.changes

Список изменений в запросе. Необходимо одно и только одно такое поле.

entry.changes.field

Поле Webhooks. Всегда имеет значение preview.

entry.changes.value

Фактический объект, содержащий контекст запроса.

entry.changes.value.field.community

Сообщество, к которому относится пользователь, инициировавший запрос.

entry.changes.value.field.user

Пользователь, инициировавший запрос.

entry.changes.value.field.link

Ссылка, которую пытается отобразить Workplace. Соответствует домену и регулярному выражению, настроенным в приложении.

Пример

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"
            }
        }]
    }]
}
    

Формат ответа Webhooks

Ответ на запрос Webhooks должен содержать метаданные в определенном формате:

{
  "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
}

Полезная нагрузка должна содержать следующие поля:

Имя поляОписание

data

Подборка объектов, доступных пользователю. Может быть пустой, если приложение вообще не развертывает ссылку для этого пользователя.

linked_user

Поле с логическим значением, указывающее, известен ли пользователь третьей стороне. Если задано значение false, выводится диалог привязки аккаунта.

data.link

Ссылка, уникальным образом идентифицирующая объект. Должна совпадать со ссылкой в запросе.

data.canonical_link

Каноническое представление URL контента. Если отличается от ссылки, то контент ассоциируется с каноническим контентом, что упрощает запрос связанных публикаций.

data.title

Название объекта. Не требуется только для объектов со значением inaccessible в поле privacy.

data.description

Краткое описание объекта, которое будет отображаться в расширенном предпросмотре.

data.icon

Объект, используемый в Workplace в качестве значка для контента. Это должен быть общедоступный URL. Лучше всего использовать объект размером 16 x 16 пикселей.

data.download_url

URL, по которому Workplace может скачать представление объекта в формате PDF, JPEG или PNG для преобразования в публикацию с изображением. Игнорируется для всех типов объектов, кроме document и link.

data.privacy

Уровень конфиденциальности объекта. Возможные значения: organization, accessible и inaccessible. Значение organization означает, что объект можно показывать любому участнику сообщества Workplace, даже если его аккаунт не привязан, значение accessible — что объект доступен вошедшему пользователю, а остальным необязательно, и, наконец, значение inaccessible — что этот документ недоступен данному пользователю.

data.type

Возможные значения: document, folder, task и link. Папка — это набор документов или других папок. Не требуется только для объектов со значением inaccessible в поле privacy.

data.additional_data

Набор метаданных, отображаемых в расширенном предпросмотре. Игнорируется для document и folder. Используются только три первых элемента. Подробные сведения о формате этих полей см. в разделе Дополнительные данные.

Пример полного ответа

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
}
    

Режимы конфиденциальности

Режим конфиденциальности определяет видимость контента и необходимость аутентификации текущего и последующих пользователей.

  1. organization: контент виден пользователю, аутентификация не требуется
    В этом случае мы можем сразу показывать контент пользователю. Используется для контента, который должен быть доступен всем пользователям в домене (компании). Для каждого нового пользователя отправлять Webhooks нет необходимости.
  2. accessible: контент виден текущему пользователю, но для остальных может требоваться сопоставление идентификационных данных.
    Поставщику услуг известно, что данному пользователю разрешен просмотр этого контента, но это не значит, что просмотр разрешен всем. Мы показываем предпросмотр, но для остальных пользователей будем по-прежнему отправлять Webhooks.
  3. inaccessible: контент не виден пользователю
    Поставщику услуг известен этот пользователь, а также то, что ему запрещен просмотр этого контента. Мы отображаем уведомление о конфиденциальности (недоступности и т. п.).

Дополнительные данные

Вы можете отправить до трех объектов с дополнительными данными для предпросмотра ссылки. Такой объект состоит из набора элементов "ключ — значение". Значения могут иметь разный формат.

В настоящее время поддерживаются четыре формата.

  • text: значение отображается как есть; должно быть строкой. Дополнительные данные в этом формате также могут содержать свойство color с одним из следующих значений: blue, green, yellow, orange или red. В этом случае значение отображается на фоне указанного цвета.
  • date: значение интерпретируется и отображается как дата в формате ISO-8601 без указания времени.
  • datetime: значение интерпретируется и отображается как дата в формате ISO-8601 с указанием времени в часовом поясе пользователя.
  • user: значение интерпретируется как ID пользователя и отображается как его имя.

При наличии дополнительных данных параметр download_url игнорируется.

Отображение предпросмотров файлов (необязательно)

Если для документа установлен режим конфиденциальности organization или accessible и указан URL для скачивания, мы отправим дополнительный запрос на скачивание данных.

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 преобразует этот файл в фотографии, чтобы создать публикацию с несколькими фото.

Сопоставление идентификационных данных

Как упоминалось выше, для авторизованного предпросмотра требуется сопоставление идентификационных данных. Оно позволяет убедиться в том, что у пользователя Workplace есть разрешение на просмотр контента из предпросмотра, и обеспечить соблюдение правил доступа в Workplace.

Сопоставление на уровне компании

Это простейший способ сопоставления идентификационных данных: для показа предпросмотров пользователям достаточно того, чтобы они были участниками сообщества Workplace. Это обычная ситуация при предпросмотре ссылок в интрасети компании или любом сервисе, в котором все объекты (или по крайней мере их метаданные) видны всей компании.

Если интеграция установлена в сообществе Workplace, ID сообщества можно проверить через конечную точку /community с использованием маркера доступа, полученного при установке. Этот ID можно хранить вместе с маркером и сопоставлять его с идентификатором организации в вашем сервисе. Таким образом создается связь между сообществом Workplace и организацией в вашем сервисе.

Получив запрос Webhooks авторизованного предпросмотра, вы можете проверить, совпадает ли указанный в его полезных данных ID сообщества с ID сообщества, связанным с организацией, и решить, можно ли вернуть метаданные в ответе. Если указать в ответе уровень конфиденциальности ORGANIZATION, мы не будем отправлять дополнительные Webhooks для каждого участника этого сообщества Workplace.

Сопоставление на уровне пользователя

Этот способ подходит, когда требуется более детальная настройка разрешений: вы решаете, следует ли показывать метаданные каждому отдельному пользователю в Workplace. Workplace передает ID пользователя в каждом запросе Webhook на авторизованный предпросмотр. Для сопоставления на уровне пользователя необходимо знать, какой пользователь в вашей системе соответствует ID пользователя, переданному из Workplace в полезных данных запроса Webhooks.

Если данный ID пользователя Workplace встречается впервые, можно передать в ответе логическое поле linked_user со значением false. В результате в Workplace будет показана кнопка Включить предпросмотр, позволяющая пользователю привязать свой аккаунт.

По нажатию этой кнопки в Workplace открывается диалог, позволяющий подтвердить сеанс пользователя в вашем сервисе. Для этого используется указанная вами конечная точка привязки аккаунта. Чтобы открыть этот URL, Workplace отправляет запрос POST, в котором передает параметр signed_request, содержащий ID текущего пользователя и 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
    

Параметр signed_request в полезных данных содержит информацию о пользователе. Этот запрос декодируется следующим образом:

  1. Значение делится на две части, разделенные символом ".".
  2. Первая часть — подпись — декодируется из base64url.
  3. Вторая часть — полезные данные — декодируется из base64url, после чего декодируется полученный объект JSON.
  4. Подпись проверяется на соответствие HMAC закодированных полезных данных с использованием секрета приложения.

Полезные данные содержат следующие поля:

{
  "algorithm": "HMAC-SHA256",
  "user_id": "88575656148087",
  "community_id": "138169208138649"
}
    

В итоге вы получаете ID пользователя Workplace и ID сообщества, а также подтвержденный сеанс пользователя в вашем сервисе, и можете сопоставить ID пользователя в Workplace с его ID в вашем сервисе. По завершении необходимо перенаправить пользователя на URL, указанный в исходном запросе в параметре 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 определит, что сопоставление идентификационных данных завершено, и вновь попытается запросить метаданные для авторизованного предпросмотра. На этот раз вы сможете передать в ответе поле linked_user со значением true и необходимые метаданные.

Примечание.

Весь этот цикл обмена данными требуется только один раз, когда неизвестный пользователь впервые пытается выполнить предпросмотр контента. Для последующих предпросмотров после сопоставления идентификационных данных в нем нет необходимости.

Часто задаваемые вопросы

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).

For estimating / expectation standpoint you can plan around this behavior. You may observe some differences in practice due to retries or race conditions.

I. When a Person Views Organization-Privacy Content

  1. Workplace sends a webhook request when first person views this content
  2. Generally, no further webhooks requests will be sent for this same content until 30-60 minutes has elapsed

II. When a Person Views Restricted- or Inaccessible-Privacy Content

  1. Workplace sends a webhook request every time a person views that content for the first time
  2. Generally, no further webhook requests will be sent for this same person+content combination until 30-60 minutes has elapsed

III. When a Person Creates a Post That Links to Content

  1. Every time a person creates a new post Workplace will always query for metadata about linked content.