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

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

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

image

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

Авторизация


Консоль гугл


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

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



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

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



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



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

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



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

Результат




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



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



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

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

PHP


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

php composer.phar require google/apiclient:^2.0

Если вы не знаете что такое composer и как с его помощью устанавливать — знакомьтесь
После установки создайте 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 содержится вся нужная информация, а ссылка на статью вот.

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

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

Github проект с бд (останется только закинуть файл client_secret.json)
Источник: https://habr.com/ru/post/492884/


Интересные статьи

Интересные статьи

В старые времена, когда компания Google (или любой из её плохо настроенных ИИ) хотела убить ваш бизнес, то обычно отказывала вам в доступе к какому-то из своих сервисов, и это работало. В...
Быстрое питание, быстрые встречи, быстрые результаты, быстрый интернет… В 21 веке мы хотим, чтобы все было быстро и просто. И еще одно: нам нужна быстрая коммуникация. Лучшее решение эт...
Периодически возникал вопрос по защите от ботов различных форм на сайте: регистрация, авторизация, подписка на рассылку, обратная связь, комментирование и т.д. Стандартная капча — ...
Этот пост будет из серии, об инструментах безопасности, которые доступны в Битриксе сразу «из коробки». Перечислю их все, скажу какой инструмент в какой редакции Битрикса доступен, кратко и не очень р...
Я присоединился к команде разработчиков Google Plus вскоре после появления этого проекта в 2010 году, перейдя из команды Blogger. Я участвовал в проекте три года, сначала поработав в команде ра...