- PVSM.RU - https://www.pvsm.ru -

Получение сообщений из трансляций youtube + авторизация google на PHP

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

image

Первое, что я нашел — это метод LiveChatMessages: list [1], казалось бы, все просто, но обязательным параметром требуется передать liveChatId, который вы можете получить сделав запрос на LiveBroadcasts: list [2], но что бы сделать туда запрос необходимо авторизовать пользователя через google с доступом на чтение аккаунта. В примерах все подробно прописано, но если вы читаете эту статью, возможно, не так уж и понятно как хотелось бы.

Авторизация

Консоль гугл

Using OAuth 2.0 for Web Server Applications [3], хочу сразу заметить, требуется именно Web Server авторизация, потому что ключ, передаваемый при авторизации на js живет час, а обновить его не выйдет (без участия юзера) т.к. не передается refresh token. Так же, рекомендую использовать одну из готовых библиотек, с ними все будет гораздо проще.

Первым делом создадим аккаунт. Перейдите на страницу console.developers.google.com [4], здесь в левом верхнем углу выберите проекты и нажмите «Создать проект».

Получение сообщений из трансляций youtube + авторизация google на PHP - 2

Введите название и сохраните. Теперь выберите свой проект и кликните «Включить API и сервисы» или перейдите на страницу библиотеки API [5]
Здесь в поисковом запросе найдите и включите YouTube Data API v3.

После чего во вкладке «Окно запроса доступа OAuth» на левой панели в консоли (или тут [6]) создайте окно.
На первом шаге выберите для User Type «Внешний»

Получение сообщений из трансляций youtube + авторизация google на PHP - 3

Далее, в этой форме необходимо заполнить 2 поля — название приложения и «Авторизованные домены», если у вас есть домен, можете оставить поле пустым, если таковых нет. Нажимаете сохранить. В результате должно получиться что-то вроде

Получение сообщений из трансляций youtube + авторизация google на PHP - 4

Теперь перейдите на вкладку «Учетные данные» (https://console.developers.google.com/apis/credentials)

Здесь вас встретит такая страница:

Получение сообщений из трансляций youtube + авторизация google на PHP - 5

Выберите кнопку «Создать учетные данные» -> «Идентификатор клиента OAuth»
Выберите нужный тип (для нас веб), введите название и «Разрешенные URI перенаправления» — это url на который будет отправляться код для авторизации клиента. Вы можете прописать сюда локальный url на время разработки, в моем случае это будет

http://localhost:8080/oauth2callback.php [7]

Результат

Получение сообщений из трансляций youtube + авторизация google на PHP - 6

После должно появиться окно с ID клиента и Секретным ключом. Пока это смело закрываем. Перед вами страница с учетными данными, только что созданными

Получение сообщений из трансляций youtube + авторизация google на PHP - 7

Нажимайте на кнопочку «Скачать» для идентификатора:

Получение сообщений из трансляций youtube + авторизация google на PHP - 8

Можете сразу переименовать в secret_json.json.

На этом с настройкой авторизации покончено, теперь приступаем к коду.

PHP

Создайте проект, откройте терминал и запустите команду:

php composer.phar require google/apiclient:^2.0

Если вы не знаете что такое composer и как с его помощью устанавливать — знакомьтесь [8]
После установки создайте 2 файла — index.php и oauth2callback.php
Можете, кстати, уже запустить ваш PHP сервер:

php -S localhost:8080

Так же переместите файл secret_json.json (который вы скачали ранее) в папку проекта.

Непосредственно на Index.php вы будете отправлять пользователя для авторизации. Содержание файла index.php

<?php
require_once __DIR__ . '/vendor/autoload.php';

$client = new Google_Client();
// это путь до нашего файла
$client->setAuthConfig('client_secret.json');
// чуть позже расскажу
$client->setScopes([
    'https://www.googleapis.com/auth/youtube.readonly',
]);
// Требуется для получения refresh_token
$client->setAccessType("offline");

if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
    $client->setAccessToken($_SESSION['access_token']);
} else {
    $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
    header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
    exit();
}

$refreshToken = $_SESSION['access_token']['refresh_token'];
$accessToken = $_SESSION['access_token']['access_token'];
$tknType = $_SESSION['access_token']['token_type'];
$clientId = $client->getClientId();
$created = $_SESSION['access_token']['created'];
unset($_SESSION['access_token']);
unset($_SESSION['user']);
session_destroy();

$data = json_encode([
  'refreshToken' => $refreshToken,
    'accessToken' => $accessToken,
    'tknType' => $tknType,
    'clientId' => $clientId,
    'created' => $created
]);
echo $data;

По сути, этот код отдаст пользователю все необходимые данные, вы же можете их записать в базу (или блокнот).

Файл oauth2callback.php:

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google_Client();
$client->setAuthConfigFile('client_secret.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
$client->setScopes([
    'https://www.googleapis.com/auth/youtube.readonly',
]);
$client->setApprovalPrompt('force');
$client->setAccessType("offline");

if (!isset($_GET['code'])) {
    $auth_url = $client->createAuthUrl();
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
    $client->authenticate($_GET['code']);
    $_SESSION['access_token'] = $client->getAccessToken();
    $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
    header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

Этот файл перенаправит юзера на страницу авторизации гугл и запишет данные о токене в сессию. После, вернет пользователя обратно, где index.php уже продолжит работу с ними.
Вы, конечно, можете записывать все данные прямо в oauth2callback и не перенаправлять пользователя обратно на index или можете указать следующей точкой любой удобный для вас адрес. Так же, в этом коде не учтены ошибки при авторизации, учтите это.

На этом с авторизацией покончено. У вас уже есть access_token и refresh_token, давайте возьмемся за ютуб.

Ютубе

Сразу PHP

getStreams.php:

<?php
require_once __DIR__ . '/vendor/autoload.php';
// об этом позже
require_once __DIR__ . '/refreshToken.php';

$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
$client->setScopes([
    'https://www.googleapis.com/auth/youtube.readonly',
]);
$client->setAccessType("offline");

// массив $data содержит информацию после прошлой авторизации (я пишу в бд)
if (($data['created'] - time()) <= -3600) {
    $data = refreshToken($data['refreshToken'], $db);
}

$client->setAccessToken($data['accessToken']);
$service = new Google_Service_YouTube($client);
// делаем 2 запроса потому что гугол отдает или идущие или запланированные трансляции, 
// но нам нужны и те и другие.
$queryParams = [
    'broadcastStatus' => 'upcoming',
    'maxResults' => 50
];
$response = $service->liveBroadcasts->listLiveBroadcasts('id,snippet,status', $queryParams);
$items = $response['items'];
$streamsUpcoming = itemsGenerator($items);

$queryParams = [
    'broadcastStatus' => 'active',
    'maxResults' => 50
];
$response = $service->liveBroadcasts->listLiveBroadcasts('id,snippet,status', $queryParams);
$items = $response['items'];
$streamsActive = itemsGenerator($items);
$streams = array_merge($streamsUpcoming, $streamsActive);

// отдаем данные
echo json_encode($streams);

// приводим ответ гугла к виду, который требуется нам.
function itemsGenerator($items) {
    $streams = [];
    foreach ($items as $item) {
        // значит трансляция в эфире или заплпнированна (законченные не выводим)
        if (!isset($item['snippet']['actualEndTime'])) {
            $streams[] = [
                'id' => $item['id'],
                'title' => $item['snippet']['title'],
                'description' => $item['snippet']['description'],
                'image' => $item['snippet']['thumbnails']['medium']['url'],
                'liveChatId' => $item['snippet']['liveChatId'],
                'channelId' => $item['snippet']['channelId']
            ];
        }
    }
    return $streams;
}

Помните вот эти строки еще при авторизации?

$client->setScopes([
    'https://www.googleapis.com/auth/youtube.readonly',
]);

Так вот, они отвечают за то какой доступ вам требуется. Например, такая запись разрешает только чтение информации, есть еще https://www.googleapis.com/auth/youtube.upload и другие.

refreshToken.php:

<?php
require_once __DIR__ . '/vendor/autoload.php';

/**
 * @param string $refreshToken
 * @param $db
 * @return array
 * @throws Google_Exception
 */
function refreshToken($refreshToken, $db)
{
    $client = new Google_Client();
    $client->setAuthConfig('client_secret.json');
    $client->setScopes([
        'https://www.googleapis.com/auth/youtube.readonly',
    ]);
    $client->setAccessType("offline");

    $client->refreshToken($refreshToken);
    $accessToken = $client->getAccessToken();

    $refreshToken = $accessToken['refresh_token'];
    $accessToken = $accessToken['access_token'];
    $clientId = $client->getClientId();
    $data = [
        'refreshToken' => $refreshToken,
        'accessToken' => $accessToken,
        'tknType' => 'Bearer',
        'clientId' => $clientId,
        'created' => time()
    ];

    // тут можно перезаписать значение в бд, например.

    return $data;
}

Токен, выданный гуглом действует только час. В течении суток вы можете сделать только 25 запросов на обновление токена, эта функция как раз обновляет наш токен и возвращает новые значения с которыми и можно будет продолжать работать. В getStreams демонстрируется его работа.

И наконец
getStreamMessages.php:

<?php
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/refreshToken.php';

$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
$client->setScopes([
    'https://www.googleapis.com/auth/youtube.readonly',
]);
$client->setAccessType("offline");
// $data - массив с авторизационными данными из бд
if (($data['created'] - time()) <= -3600) {
    $data = refreshToken($data['refreshToken'], $db);
}
$client->setAccessToken($data['accessToken']);

$service = new Google_Service_YouTube($client);

$queryParams = [
    'maxResults' => 2000,
    'profileImageSize' => 120
];

$response = $service->liveChatMessages->listLiveChatMessages($liveChatId, 'id,snippet,authorDetails', $queryParams);

echo json_encode($response);

Здесь я уже не стал приводить в нужный формат сообщения, можете заняться этим сами, в массиве $response содержится вся нужная информация, а ссылка на статью вот [1].

Что меня расстроило так это то что нет метода по получению хуков (если он есть, оставьте ссылку, пожалуйста) и приходится делать постоянные запросы.

Так же, я рекомендую прочесть документацию liveChatMessages, в нем присутствуют некоторые ограничения, вроде делать нужно запрос на каждую страницу с новым кодом который пришел в предыдущем запросе.

Github проект [9] с бд (останется только закинуть файл client_secret.json)

Автор: Александр

Источник [10]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/php-2/350078

Ссылки в тексте:

[1] LiveChatMessages: list: https://developers.google.com/youtube/v3/live/docs/liveChatMessages/list

[2] LiveBroadcasts: list: https://developers.google.com/youtube/v3/live/docs/liveBroadcasts/list?apix_params=%7B%22part%22%3A%22id%2Csnippet%2CcontentDetails%22%2C%22broadcastStatus%22%3A%22all%22%7D

[3] Using OAuth 2.0 for Web Server Applications: https://developers.google.com/identity/protocols/oauth2/web-server

[4] console.developers.google.com: https://console.developers.google.com/

[5] библиотеки API: https://console.developers.google.com/apis/library

[6] или тут: https://console.developers.google.com/apis/credentials/consent

[7] http://localhost:8080/oauth2callback.php: http://localhost:8080/oauth2callback.php

[8] знакомьтесь: https://habr.com/ru/post/439200/

[9] Github проект: https://github.com/Aleksandr-yask/youtube-LiveChatMessages-php

[10] Источник: https://habr.com/ru/post/492884/?utm_source=habrahabr&utm_medium=rss&utm_campaign=492884