Кросспостинг на нескольких Страницах Facebook

В этом документе показано, как можно использовать Live Video API для одновременной публикации видео на нескольких страницах.

Кросспостинг доступен только для страниц и профессиональных профилей, но не для личных профилей. Помимо прямых эфиров, можно делать кросспостинг видео по запросу.

Как это работает

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

  1. Пользователи приложения должны иметь возможность выполнять задачу CREATE_CONTENT на Странице.
  2. Пользователи приложения должны предоставить вашему приложению следующие разрешения с использованием входа через Facebook:
    • pages_manage_posts
    • pages_read_user_content
    • pages_manage_engagement
    • pages_show_list
    • publish_video
  3. Пользователи приложения должны обменяться разрешениями на кросспостинг с другими страницами или профессиональными профилями.
  4. Поиск страниц, для которых возможен кросспостинг

Обмен разрешениями на кросспостинг

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

Шаг 1. Отправка запроса на кросспостинг

Для отправки запроса кросспостинга отправьте запрос POST к конечной точке /<YOUR_PAGE_ID> со следующими параметрами:

  • begin_crossposting_handshake установлен для массива со списком страниц, разделенных запятыми, в котором partner_page_id установлен для ID Страницы, на которую вы отправляете запрос, а для allow_live установлено значение true

При тестировании вызова API можно добавить параметр access_token и задать в нем маркер доступа. Однако при выполнении безопасных вызовов из приложения следует использоваться класс маркера доступа.

В примере кода ниже для удобства чтения применено форматирование.
curl -i -X POST "https://graph.facebook.com/v21.0<PAGE_1_ID> \
      ?begin_crossposting_handshake=[{partner_page_id:<PAGE_2_ID>,allow_live:true}]"

В случае успеха ваше приложение получит ответ JSON, в котором параметр success будет иметь значение true.

Пример ответа

{
  "success": true
}

Укажите для параметра allow_live значение false и отправьте запрос на создание отношений кросспостинга. В этом случае другая Страница сможет делать кросспостинг прямых эфиров на вашу Страницу, только если ваши администраторы или редакторы одобрят соответствующее видео.

Принятие запроса кросспостинга

Чтобы принять запрос от другой страницы на кросспостинг ее видео на вашу страницу, отправьте запрос POST к конечной точке /<ID>, в котором параметр accept_crossposting_handshake установлен для ID Страницы, отправившей запрос, а для allow_live установлено значение true.

В примере кода ниже для удобства чтения применено форматирование.
curl -X POST "https://graph.facebook.com/v21.0/<PAGE_2_ID>
    ?accept_crossposting_handshake=[{partner_page_id:<PAGE_1_ID>, allow_live:true}]"

В случае успеха ваше приложение получит ответ JSON, в котором параметр success будет иметь значение true. Видео теперь будет отображаться на нескольких страницах.

Чтобы отклонить запрос, установите для параметра allow_live значение false.

Поиск Страниц, для которых возможен кросспостинг

Чтобы найти страницы, для которых у пользователя вашего приложения есть разрешение на кросспостинг, отправьте запрос GET к конечной точке /<PAGE_ID>/crosspost_whitelisted_pages со следующими полями:

  • allows_live_crossposts
  • id
  • name (необязательно)
curl "https://graph.facebook.com/v21.0/<PAGE_ID>/crosspost_whitelisted_pages" \
  -d "fields=id,name,allows_live_crossposts" 

В случае успеха ваше приложение получит список ID, имена и информацию о том, разрешено ли Странице делать кросспостинг, с указанием одного из значений — true или false. Значение true означает, что исходная страница может публиковать видео в прямом эфире, для которого выполнен кросспостинг, непосредственно на целевой странице без дополнительной авторизации. Значение false означает, что целевая страница должна вручную публиковать видео, опубликованное кросспостингом.

Пример ответа

{
  "data": [
    {
      "id": "107738621396466",
      "name": "Crossposting Page C",
      "allows_live_crossposts": false
    },
    {
      "id": "106589754846067",
      "name": "Crossposting Page B",
      "allows_live_crossposts": true
    },
    {
      "id": "106343288214714",
      "name": "Crossposting Target X",
      "allows_live_crossposts": true,
    }
  ],
  "paging": {
    "cursors": {
      "before": "&lt;PAGE_CURSOR>",
      "after": "&lt;PAGE_CURSOR>"
    }
  }
}

Добавление действий кросспостинга для прямого эфира

Прежде чем начать

Пользователь должен иметь возможность выполнять действия от имени страницы, а также редактировать и обновлять видео. Это значит, что у приложения должно быть разрешение pages_manage_posts, предоставленное пользователем.

Зная, на каких страницах возможен кросспостинг, можно добавить crossposting_actions в любой объект LiveVideo. Действия кросспостинга определяют, возможен ли кросспостинг прямого эфира и нужно ли делать его автоматически на целевой странице.

Чтобы обновить видео, выполните запрос POST /{video-id}.

curl -i -X POST \
 "https://graph.facebook.com/v10.0/112103234301221?fields=crosspost_shared_pages,crossposted_broadcasts%7Bstatus,from%7Bname%7D%7D&access_token=${access_token}" \
 -H "Content-Type: application/json" \
 -d @- << HEREDOC
{"crossposting_actions": [
  {
    "page_id": "107738621396466",
    "action": "enable_crossposting"
  },
  {
    "page_id": "106589754846067",
    "action": "enable_crossposting_and_create_post"
  },
  {
    "page_id": "106343288214714",
    "action": "disable_crossposting"
  }
]}
HEREDOC
GraphRequest request = GraphRequest.newPostRequest(
  accessToken,
  "/112103234301221",
  new JSONObject("{\"crossposting_actions\":\"[\\n  {\\n    \\\"page_id\\\": \\\"107738621396466\\\",\\n    \\\"action\\\": \\\"enable_crossposting\\\"\\n  },\\n  {\\n    \\\"page_id\\\": \\\"106589754846067\\\",\\n    \\\"action\\\": \\\"enable_crossposting_and_create_post\\\"\\n  },\\n  {\\n    \\\"page_id\\\": \\\"106343288214714\\\",\\n    \\\"action\\\": \\\"disable_crossposting\\\"\\n  }\\n]\"}"),
  new GraphRequest.Callback() {
    @Override
    public void onCompleted(GraphResponse response) {
      // Insert your code here
    }
});
request.executeAsync();
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
    initWithGraphPath:@"/112103234301221"
           parameters:@{ @"fields": @"crosspost_shared_pages,crossposted_broadcasts{status,from{name}}",@"crossposting_actions": @"[
  {
    "page_id": "107738621396466",
    "action": "enable_crossposting"
  },
  {
    "page_id": "106589754846067",
    "action": "enable_crossposting_and_create_post"
  },
  {
    "page_id": "106343288214714",
    "action": "disable_crossposting"
  }
]",}
           HTTPMethod:@"POST"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
    // Insert your code here
}];
FB.api(
  '/112103234301221',
  'POST',
  {"fields":"crosspost_shared_pages,crossposted_broadcasts{status,from{name}}","crossposting_actions":"[\n  {\n    \"page_id\": \"107738621396466\",\n    \"action\": \"enable_crossposting\"\n  },\n  {\n    \"page_id\": \"106589754846067\",\n    \"action\": \"enable_crossposting_and_create_post\"\n  },\n  {\n    \"page_id\": \"106343288214714\",\n    \"action\": \"disable_crossposting\"\n  }\n]"},
  function(response) {
      // Insert your code here
  }
);
try {
  // Returns a `FacebookFacebookResponse` object
  $response = $fb->post(
    '/112103234301221',
    array (
      'fields' => 'crosspost_shared_pages,crossposted_broadcasts{status,from{name}}',
      'crossposting_actions' => '[
        {
          "page_id": "107738621396466",
          "action": "enable_crossposting"
        },
        {
          "page_id": "106589754846067",
          "action": "enable_crossposting_and_create_post"
        },
        {
          "page_id": "106343288214714",
          "action": "disable_crossposting"
        }
      ]'
    ),
    '{access-token}'
  );
} catch(FacebookExceptionsFacebookResponseException $e) {
  echo 'Graph returned an error: ' . $e->getMessage();
  exit;
} catch(FacebookExceptionsFacebookSDKException $e) {
  echo 'Facebook SDK returned an error: ' . $e->getMessage();
  exit;
}
$graphNode = $response->getGraphNode();

Здесь показаны возможные действия. Первое из них позволяет странице 107738621396466 делать кросспостинг видео из Creator Studio или через API, но автоматический кросспостинг не выполняется. Второе запрещает странице 106589754846067 делать кросспостинг видео, а третье автоматически публикует видео на целевой странице (106343288214714).

Пример ответа в случае успеха

Возвращается объект LiveVideo. Мы использовали границу контекста crosspost_shared_pages, чтобы узнать, на каких страницах доступен кросспостинг, и границу контекста crossposted_broadcasts, чтобы узнать, на каких страницах публикации уже размещены.

Важное примечание

Если отношения кросспостинга изменились или недействительны, выполнить кросспостинг не удастся, но ошибки вы не увидите. Единственный способ узнать, успешно ли завершилось действие, — проверить ответ.

{
  "crosspost_shared_pages": {
    "data": [
      {
        "name": "Crossposting Page C",
        "id": "107738621396466"
      },
      {
        "name": "[FB Test Page] Crossposting Page B",
        "id": "106589754846067"
      }
    ]
  },
  "crossposted_broadcasts": {
    "data": [
      {
        "status": "UNPUBLISHED",
        "from": {
          "name": "[FB Test Page] Crossposting Page B",
          "id": "106589754846067"
        },
        "id": "114820814022961"
      }
    ]
  },
  "id": "112103234301221"
}

Пример ответа в случае ошибки

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

{
  "error": {
    "message": "Fatal",
    "type": "OAuthException",
    "code": -1,
    "error_subcode": 1363103,
    "is_transient": false,
    "error_user_title": "Invalid Parameters",
    "error_user_msg": "The request does not specify valid parameters, no action has been taken.",
    "fbtrace_id": "AnI03n5n0Px-ihrZjkWMeTP"
  }
}