I am working on the following code, it a sample code for using Youtube Data API to list user broadcasts
it works for me and I have modified some parts but then the token expired and I had to clear my session and re-authenticate to be able to work again, I searched a lot and found some posts that say that the token expired after 1 hour
how can I make the token not expire at all?
<?php
include 'oauth.php';
/**
* Library Requirements
*
* 1. Install composer (https://getcomposer.org)
* 2. On the command line, change to this directory (api-samples/php)
* 3. Require the google/apiclient library
* $ composer require google/apiclient:~2.0
*/
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"');
}
require_once __DIR__ . '/vendor/autoload.php';
session_start();
/*
* You can acquire an OAuth 2.0 client ID and client secret from the
* {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
* For more information about using OAuth 2.0 to access Google APIs, please see:
* <https://developers.google.com/youtube/v3/guides/authentication>
* Please ensure that you have enabled the YouTube Data API for your project.
*/
$OAUTH2_CLIENT_ID = $clientid;
$OAUTH2_CLIENT_SECRET = $clientsecret;
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setScopes('https://www.googleapis.com/auth/youtube');
$redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'],
FILTER_SANITIZE_URL);
$client->setRedirectUri($redirect);
// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);
// Check if an auth token exists for the required scopes
$tokenSessionKey = 'token-' . $client->prepareScopes();
if (isset($_GET['code'])) {
if (strval($_SESSION['state']) !== strval($_GET['state'])) {
die('The session state did not match.');
}
$client->authenticate($_GET['code']);
$_SESSION[$tokenSessionKey] = $client->getAccessToken();
header('Location: ' . $redirect);
}
if (isset($_SESSION[$tokenSessionKey])) {
$client->setAccessToken($_SESSION[$tokenSessionKey]);
}
// Check to ensure that the access token was successfully acquired.
if ($client->getAccessToken()) {
try {
// Execute an API request that lists broadcasts owned by the user who
// authorized the request.
$broadcastsResponse = $youtube->liveBroadcasts->listLiveBroadcasts(
'id,snippet,contentDetails',
array(
'mine' => 'true',
));
$htmlBody = "<h3>Live Broadcasts</h3>";
foreach ($broadcastsResponse['items'] as $broadcastItem) {
//$htmlBody .= sprintf('<li>%s (%s) (%s)</li>', $broadcastItem['snippet']['title'],
//$broadcastItem['id'], $broadcastItem['snippet']['description']);
$htmlBody .= "<div><ul>";
$htmlBody .= "<li><b>Title:</b> ".$broadcastItem['snippet']['title']."</li>";
$htmlBody .= "<li><b>ID:</b> ".$broadcastItem['id']."</li>";
$htmlBody .= "<li><b>Description:</b> ".$broadcastItem['snippet']['description']."</li>";
$htmlBody .= "<li><b>Thumbnail</b> <img src='".$broadcastItem['snippet']['thumbnails']['default']['url']."' width='100px'/></li>";
$htmlBody .= "<li><b>Embed:</b><iframe width='560' height='315' src='https://www.youtube.com/embed/".$broadcastItem['id']."' title='YouTube video player' frameborder='0' allow='accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture' allowfullscreen></iframe></li>";
$htmlBody .= "</ul></div>";
}
$htmlBody .= '';
} catch (Google_Service_Exception $e) {
$htmlBody = sprintf('<p>A service error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
} catch (Google_Exception $e) {
$htmlBody = sprintf('<p>An client error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
}
$_SESSION[$tokenSessionKey] = $client->getAccessToken();
} elseif ($OAUTH2_CLIENT_ID == 'REPLACE_ME') {
$htmlBody = <<<END
<h3>Client Credentials Required</h3>
<p>
You need to set <code>\$OAUTH2_CLIENT_ID</code> and
<code>\$OAUTH2_CLIENT_ID</code> before proceeding.
<p>
END;
} else {
// If the user hasn't authorized the app, initiate the OAuth flow
$state = mt_rand();
$client->setState($state);
$_SESSION['state'] = $state;
$authUrl = $client->createAuthUrl();
$htmlBody = <<<END
<h3>Authorization Required</h3>
<p>You need to authorize access before proceeding.<p>
END;
}
?>
<!doctype html>
<html>
<head>
<title>My Live Broadcasts</title>
</head>
<body>
<?=$htmlBody?>
</body>
</html>
Access tokens by design expire. This is how they work. Googles access tokens expire after an hour.
If you are requesting offline access you will have a refresh token. You can then use your refresh token to request a new access token when ever you need.
Oauth2Authentication.php
function buildClient(){
$client = new Google_Client();
$client->setAccessType("offline"); // offline access. Will result in a refresh token
$client->setIncludeGrantedScopes(true); // incremental auth
$client->setAuthConfig(__DIR__ . '/client_secrets.json');
$client->addScope([YOUR SCOPES HERE]);
$client->setRedirectUri(getRedirectUri());
return $client;
}
Then its simply a matter of testing if the access token has expired and requesting a new one
$client = buildClient();
// Set the refresh token on the client.
if (isset($_SESSION['refresh_token']) && $_SESSION['refresh_token']) {
$client->refreshToken($_SESSION['refresh_token']);
}
// If the user has already authorized this app then get an access token
// else redirect to ask the user to authorize access to Google Analytics.
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
// Set the access token on the client.
$client->setAccessToken($_SESSION['access_token']);
// Refresh the access token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
$client->setAccessToken($client->getAccessToken());
$_SESSION['access_token'] = $client->getAccessToken();
}
return $client;
} else {
// We do not have access request access.
header('Location: ' . filter_var( $client->getRedirectUri(), FILTER_SANITIZE_URL));
}
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
Related
This is the code I have and it does not work for me, it returns the error commented on the subject. I have done the whole process by registering, delegating the entire domain and authorizing everything and it fails...
$REDIRECT_URI = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$KEY_LOCATION = $_SERVER['DOCUMENT_ROOT'].'/cada/includes/classes/google-api-php-client-2.1.1/client_secret_1050007893675-7bkmqjiqr1p57s9alr7fu7e016lrh5hc.apps.googleusercontent.com.json';
$TOKEN_FILE = $_SERVER['DOCUMENT_ROOT']."/cada/share/token.txt";
$SCOPES = array(
Google_Service_Calendar::CALENDAR
);
$client = new Google_Client();
$client->setApplicationName("SimesatSat");
$client->setAuthConfig($KEY_LOCATION);
// Incremental authorization
$client->setIncludeGrantedScopes(true);
// Allow access to Google API when the user is not present.
$client->setAccessType('offline');
$client->setRedirectUri($REDIRECT_URI);
$client->setScopes($SCOPES);
if (isset($_GET['code']) && !empty($_GET['code']))
{
try
{
// Exchange the one-time authorization code for an access token
$accessToken = $client->fetchAccessTokenWithAuthCode($_GET['code']);
// Save the access token and refresh token in local filesystem
file_put_contents($TOKEN_FILE, json_encode($accessToken));
$_SESSION['accessToken'] = $accessToken;
header('Location: ' . filter_var($REDIRECT_URI, FILTER_SANITIZE_URL));
exit();
}
catch (\Google_Service_Exception $e)
{
print_r($e);
}
}
if (!isset($_SESSION['accessToken']))
{
$token = #file_get_contents($TOKEN_FILE);
if ($token == null)
{
// Generate a URL to request access from Google's OAuth 2.0 server:
$authUrl = $client->createAuthUrl();
// Redirect the user to Google's OAuth server
header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
exit();
}
else
{
$_SESSION['accessToken'] = json_decode($token, true);
}
}
$client->setAccessToken($_SESSION['accessToken']);
/* Refresh token when expired */
if ($client->isAccessTokenExpired())
{
// the new access token comes with a refresh token as well
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($TOKEN_FILE, json_encode($client->getAccessToken()));
}
////////////CONSULTA DATOS ////////////////////////////
$service = new Google_Service_Calendar($client);
$results = $service->calendarList->listCalendarList();
print_r($results);
Can anybody help me? I have another project with another client with the same code and it works perfectly! I do not understand what's happening. The only difference is that this project is part of a subdomain. Could that be the mistake?
include ("header.php") ;
require_once 'vendor/autoload.php';
$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
$client->setRedirectUri('http://localhost/ecommerce/index.php');
$client->addScope('email');
$client->addScope('profile');
$login_button=' <div class="col-sm-4">
<div class="card">
<div class="card-body">
<a class="btn btn-social btn-google" href="'.$client->createAuthUrl().'" role="button">
<i class="fab fa-google"></i>
Sign in with Google
</a>
</div>
</div>
</div>';
if(isset($_GET['code'])){
$token=$client->fetchAccessTokenWithAuthCode($_GET['code']);
if(!isset($token['error'])){
$client->setAccessToken($token['access_token']);
$_SESSION['access_token']=$token['access_token'];
$google_service=new Google_Service_Oauth2($client);
$data=$google_service->userinfo->get();
if(!empty($data['given_name'])){
$_SESSION['uid']=$data['given_name'];
}
if(!empty($data['family_name'])){
$_SESSION['user_last_name']=$data['family_name'];
}
if(!empty($data['gender'])){
$_SESSION['gender']=$data['gender'];
}
}
}
?>
My code does not enter the if block: isset($_GET['code']) is returning false.
I want access to just the user name and gender.
I have installed composer and google api client 2.0.
Its not set probably because you haven't called auth yet. Code is only set after the user has clicked the consent screen and then it will never ben used again.
oauth2callback.php
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/Oauth2Authentication.php';
// Start a session to persist credentials.
session_start();
// Handle authorization flow from the server.
if (! isset($_GET['code'])) {
$client = buildClient();
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
$client = buildClient();
$client->authenticate($_GET['code']); // Exchange the authencation code for a refresh token and access token.
// Add access token and refresh token to seession.
$_SESSION['access_token'] = $client->getAccessToken();
$_SESSION['refresh_token'] = $client->getRefreshToken();
//Redirect back to main script
$redirect_uri = str_replace("oauth2callback.php",$_SESSION['mainScript'],$client->getRedirectUri());
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>
Oauth2Authentication.php
function getOauth2Client() {
try {
$client = buildClient();
// Set the refresh token on the client.
if (isset($_SESSION['refresh_token']) && $_SESSION['refresh_token']) {
$client->refreshToken($_SESSION['refresh_token']);
}
// If the user has already authorized this app then get an access token
// else redirect to ask the user to authorize access to Google Analytics.
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
// Set the access token on the client.
$client->setAccessToken($_SESSION['access_token']);
// Refresh the access token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
$client->setAccessToken($client->getAccessToken());
$_SESSION['access_token'] = $client->getAccessToken();
}
return $client;
} else {
// We do not have access request access.
header('Location: ' . filter_var( $client->getRedirectUri(), FILTER_SANITIZE_URL));
}
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
I am trying to create a simple automation for myself.
I want to send the title of my next YouTube video to telegram.
This will then be caught by a webhook on my website (Public accessible Domain) and auto-schedule the video respective to time specified.
My problem is that when using the YouTube's API, the Gmail account of the channel has to sign in. This creates a problem... I don't want to go through the authentication process.
I've read about service accounts, and how they can be used to do things similar to these; I've set up my "RIG" but it doesn't work. I keep getting error:
A service error occurred: { "error": "unauthorized_client", "error_description": "Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested." }
Please see code below.
(Google's Documentation on the subject is terrible.)
<?php
/**
* Library Requirements
*
* 1. Install composer (https://getcomposer.org)
* 2. On the command line, change to this directory (api-samples/php)
* 3. Require the google/apiclient library
* $ composer require google/apiclient:~2.0
*/
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"');
}
require_once __DIR__ . '/vendor/autoload.php';
session_start();
/*
* You can acquire an OAuth 2.0 client ID and client secret from the
* {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
* For more information about using OAuth 2.0 to access Google APIs, please see:
* <https://developers.google.com/youtube/v3/guides/authentication>
* Please ensure that you have enabled the YouTube Data API for your project.
*/
?>
<?PHP
$client = new Google_Client();
$user_to_impersonate = "sXXXXXXXXXm#gmail.com";
$client->setSubject($user_to_impersonate);
$client->setScopes('https://www.googleapis.com/auth/youtube');
$client->setAuthConfig('ultimate-figure-XXX-XXXXX.json'); //JSON OF THE SERVICE ACCOUNT
$redirect = filter_var('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'],
FILTER_SANITIZE_URL);
$client->setRedirectUri($redirect);
// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);
// Check if an auth token exists for the required scopes
$tokenSessionKey = 'token-' . $client->prepareScopes();
if (isset($_GET['code'])) {
if (strval($_SESSION['state']) !== strval($_GET['state'])) {
die('The session state did not match.');
}
$client->authenticate($_GET['code']);
$_SESSION[$tokenSessionKey] = $client->getAccessToken();
header('Location: ' . $redirect);
}
if (isset($_SESSION[$tokenSessionKey])) {
$client->setAccessToken($_SESSION[$tokenSessionKey]);
}
// Check to ensure that the access token was successfully acquired.
if ($client->getAccessToken()) {
try {
// Create an object for the liveBroadcast resource's snippet. Specify values
// for the snippet's title, scheduled start time, and scheduled end time.
$broadcastSnippet = new Google_Service_YouTube_LiveBroadcastSnippet();
$broadcastSnippet->setTitle('New Broadcast');
$broadcastSnippet->setScheduledStartTime('2034-01-30T00:00:00.000Z');
$broadcastSnippet->setScheduledEndTime('2034-01-31T00:00:00.000Z');
// Create an object for the liveBroadcast resource's status, and set the
// broadcast's status to "private".
$status = new Google_Service_YouTube_LiveBroadcastStatus();
$status->setPrivacyStatus('private');
// Create the API request that inserts the liveBroadcast resource.
$broadcastInsert = new Google_Service_YouTube_LiveBroadcast();
$broadcastInsert->setSnippet($broadcastSnippet);
$broadcastInsert->setStatus($status);
$broadcastInsert->setKind('youtube#liveBroadcast');
// Execute the request and return an object that contains information
// about the new broadcast.
$broadcastsResponse = $youtube->liveBroadcasts->insert('snippet,status',
$broadcastInsert, array());
// Create an object for the liveStream resource's snippet. Specify a value
// for the snippet's title.
$streamSnippet = new Google_Service_YouTube_LiveStreamSnippet();
$streamSnippet->setTitle('New Stream');
// Create an object for content distribution network details for the live
// stream and specify the stream's format and ingestion type.
$cdn = new Google_Service_YouTube_CdnSettings();
$cdn->setFormat("1080p");
$cdn->setIngestionType('rtmp');
// Create the API request that inserts the liveStream resource.
$streamInsert = new Google_Service_YouTube_LiveStream();
$streamInsert->setSnippet($streamSnippet);
$streamInsert->setCdn($cdn);
$streamInsert->setKind('youtube#liveStream');
// Execute the request and return an object that contains information
// about the new stream.
$streamsResponse = $youtube->liveStreams->insert('snippet,cdn',
$streamInsert, array());
// Bind the broadcast to the live stream.
$bindBroadcastResponse = $youtube->liveBroadcasts->bind(
$broadcastsResponse['id'],'id,contentDetails',
array(
'streamId' => $streamsResponse['id'],
));
$htmlBody .= "<h3>Added Broadcast</h3><ul>";
$htmlBody .= sprintf('<li>%s published at %s (%s)</li>',
$broadcastsResponse['snippet']['title'],
$broadcastsResponse['snippet']['publishedAt'],
$broadcastsResponse['id']);
$htmlBody .= '</ul>';
$htmlBody .= "<h3>Added Stream</h3><ul>";
$htmlBody .= sprintf('<li>%s (%s)</li>',
$streamsResponse['snippet']['title'],
$streamsResponse['id']);
$htmlBody .= '</ul>';
$htmlBody .= "<h3>Bound Broadcast</h3><ul>";
$htmlBody .= sprintf('<li>Broadcast (%s) was bound to stream (%s).</li>',
$bindBroadcastResponse['id'],
$bindBroadcastResponse['contentDetails']['boundStreamId']);
$htmlBody .= '</ul>';
} catch (Google_Service_Exception $e) {
$htmlBody = sprintf('<p>A service error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
} catch (Google_Exception $e) {
$htmlBody = sprintf('<p>An client error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
}
$_SESSION[$tokenSessionKey] = $client->getAccessToken();
} elseif ($OAUTH2_CLIENT_ID == 'REPLACE_ME') {
$htmlBody = <<<END
<h3>Client Credentials Required</h3>
<p>
You need to set <code>\$OAUTH2_CLIENT_ID</code> and
<code>\$OAUTH2_CLIENT_ID</code> before proceeding.
<p>
END;
} else {
// If the user hasn't authorized the app, initiate the OAuth flow
$state = mt_rand();
$client->setState($state);
$_SESSION['state'] = $state;
$authUrl = $client->createAuthUrl();
$htmlBody = <<<END
<h3>Authorization Required</h3>
<p>You need to authorize access before proceeding.<p>
END;
}
?>
When loading the token script :
token.php
<?php
require_once 'vendor/autoload.php';
session_start();
/*
* You can acquire an OAuth 2.0 client ID and client secret from the
* {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
* For more information about using OAuth 2.0 to access Google APIs, please see:
* <https://developers.google.com/youtube/v3/guides/authentication>
* Please ensure that you have enabled the YouTube Data API for your project.
*/
$OAUTH2_CLIENT_ID = '516195178663-5pgnd88unc38khttmgj67scinlhk7caf.apps.googleusercontent.com'; // Enter your Client ID here
$OAUTH2_CLIENT_SECRET = 'QLsIeOBhHLIee4_d-OOqjblK'; // Enter your Client Secret here
$REDIRECT = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'], FILTER_SANITIZE_URL);
$APPNAME = "BrickFame";
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setScopes('https://www.googleapis.com/auth/youtube');
$client->setRedirectUri($REDIRECT);
$client->setApplicationName($APPNAME);
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);
if (isset($_GET['code'])) {
if (strval($_SESSION['state']) !== strval($_GET['state'])) {
die('The session state did not match.');
}
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
echo "Access Token: " . json_encode($_SESSION['token']);
}
// Check to ensure that the access token was successfully acquired.
if ($client->getAccessToken()) {
try {
// Call the channels.list method to retrieve information about the
// currently authenticated user's channel.
$channelsResponse = $youtube->channels->listChannels('contentDetails', array('mine' => 'true'));
$htmlBody = '';
foreach ($channelsResponse['items'] as $channel) {
// Extract the unique playlist ID that identifies the list of videos
// uploaded to the channel, and then call the playlistItems.list method
// to retrieve that list.
$uploadsListId = $channel['contentDetails']['relatedPlaylists']['uploads'];
$playlistItemsResponse = $youtube->playlistItems->listPlaylistItems('snippet', array(
'playlistId' => $uploadsListId,
'maxResults' => 50
));
$htmlBody .= "<h3>Videos in list $uploadsListId</h3><ul>";
foreach ($playlistItemsResponse['items'] as $playlistItem) {
$htmlBody .= sprintf('<li>%s (%s)</li>', $playlistItem['snippet']['title'],
$playlistItem['snippet']['resourceId']['videoId']);
}
$htmlBody .= '</ul>';
}
} catch (Google_ServiceException $e) {
$htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
} catch (Google_Exception $e) {
$htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
}
$_SESSION['token'] = $client->getAccessToken();
} else {
$state = mt_rand();
$client->setState($state);
$_SESSION['state'] = $state;
$authUrl = $client->createAuthUrl();
$htmlBody = <<<END
<h3>Authorization Required</h3>
<p>You need to authorise access before proceeding.<p>
END;
}
?>
<!doctype html>
<html>
<head>
<title>My Uploads</title>
</head>
<body>
<?php echo $htmlBody;?>
</body>
</html>
I can fetch my access token and refresh token is shown and i saved it under token.txt
Access Token: {"access_token":"ya29.Ci8tA-3KvN7LE03mLLWsJJOsKHPr3ArvEw9xDaCX8wpFxGM-VpLswYwR1Mnhc7wS1Q","token_type":"Bearer","expires_in":3600,"refresh_token":"1\/BopX8bClCDuDkg0WO9KKyvxKMC-y1GiFhFOO8JQ5HkU","created":1469621552}
However when accessing the upload script:
api.php
<?php
$key = file_get_contents('token.txt');
require_once 'vendor/autoload.php';
$client_id = '516195178663-5pgnd88unc38khttmgj67scinlhk7caf.apps.googleusercontent.com'; // Enter your Client ID here
$client_secret = 'QLsIeOBhHLIee4_d-OOqjblK'; // Enter your Client Secret here
$videoPath = "videos/example.mkv";
$videoTitle = "Just an Example Title";
$videoDescription = "This is the YouTube video's description";
$videoCategory = "22";
$videoTags = array("first tag","second tag","third tag");
try{
// Client init
$client = new Google_Client();
$client->setClientId($client_id);
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->setAccessToken($key);
$client->setClientSecret($client_secret);
if ($client->getAccessToken()) {
/**
* Check to see if our access token has expired. If so, get a new one and save it to file for future use.
*/
if($client->isAccessTokenExpired()) {
$newToken = json_decode($client->getAccessToken());
$client->refreshToken($newToken->refresh_token);
file_put_contents($key, $client->getAccessToken());
}
$youtube = new Google_Service_YouTube($client);
// Create a snipet with title, description, tags and category id
$snippet = new Google_Service_YouTube_VideoSnippet();
$snippet->setTitle($videoTitle);
$snippet->setDescription($videoDescription);
$snippet->setCategoryId($videoCategory);
$snippet->setTags($videoTags);
$snippet->setDefaultLanguage("en");
$snippet->setDefaultAudioLanguage("en");
$recordingDetails = new Google_Service_YouTube_VideoRecordingDetails();
$recordingDetails->setLocationDescription("United States of America");
$recordingDetails->setRecordingDate("2016-01-20T12:34:00.000Z");
$locationdetails = new Google_Service_YouTube_GeoPoint();
$locationdetails->setLatitude("38.8833");
$locationdetails->setLongitude("77.0167");
$recordingDetails->setLocation($locationdetails);
// Create a video status with privacy status. Options are "public", "private" and "unlisted".
$status = new Google_Service_YouTube_VideoStatus();
$status->setPrivacyStatus("public");
$status->setPublicStatsViewable(false);
$status->setEmbeddable(false); // Google defect still not editable https://code.google.com/p/gdata-issues/issues/detail?id=4861
// Create a YouTube video with snippet and status
$video = new Google_Service_YouTube_Video();
$video->setSnippet($snippet);
$video->setRecordingDetails($recordingDetails);
$video->setStatus($status);
// Size of each chunk of data in bytes. Setting it higher leads faster upload (less chunks,
// for reliable connections). Setting it lower leads better recovery (fine-grained chunks)
$chunkSizeBytes = 1 * 1024 * 1024;
// Setting the defer flag to true tells the client to return a request which can be called
// with ->execute(); instead of making the API call immediately.
$client->setDefer(true);
// Create a request for the API's videos.insert method to create and upload the video.
$insertRequest = $youtube->videos->insert("status,snippet,recordingDetails", $video);
// Create a MediaFileUpload object for resumable uploads.
$media = new Google_Http_MediaFileUpload(
$client,
$insertRequest,
'video/*',
null,
true,
$chunkSizeBytes
);
$media->setFileSize(filesize($videoPath));
// Read the media file and upload it chunk by chunk.
$status = false;
$handle = fopen($videoPath, "rb");
while (!$status && !feof($handle)) {
$chunk = fread($handle, $chunkSizeBytes);
$status = $media->nextChunk($chunk);
}
fclose($handle);
/**
* Video has successfully been uploaded, now lets perform some cleanup functions for this video
*/
if ($status->status['uploadStatus'] == 'uploaded') {
// Actions to perform for a successful upload
}
// If you want to make other calls after the file upload, set setDefer back to false
$client->setDefer(true);
} else{
// #TODO Log error
echo 'Problems creating the client';
}
} catch(Google_Service_Exception $e) {
print "Caught Google service Exception ".$e->getCode(). " message is ".$e->getMessage();
print "Stack trace is ".$e->getTraceAsString();
}catch (Exception $e) {
print "Caught Google service Exception ".$e->getCode(). " message is ".$e->getMessage();
print "Stack trace is ".$e->getTraceAsString();
}
?>
It is when i encountered the error : Here is the return value
Caught Google service Exception 0 message is refresh token must be passed in or set as part of setAccessTokenStack trace is #0 /home/vol11_2/freecluster.eu/fceu_18534127/htdocs/vendor/google/apiclient/src/Google/Client.php(246): Google_Client->fetchAccessTokenWithRefreshToken(NULL) #1 /home/vol11_2/freecluster.eu/fceu_18534127/htdocs/api.php(29): Google_Client->refreshToken(NULL) #2 {main}
What might i have missed? Could it be possibly my files error?
I dont understand the line that says : refresh token must be passed in or set as part of setAccessTokenStack trace is #0
Can anyone guide me out?
Thanks ! :)
This question already has answers here:
How to obtain a feed of comments entered through the 'chat' box during a YouTube live broadcast?
(3 answers)
Closed 6 years ago.
Since this is a question about the new YouTube API that has just been released it is not a duplicate.
I am trying to fetch the chat messages from the YouTube API 3. I have tried everything I can and I am stuck.
I need the liveChatId to be able to fetch them but I don't know how to retrieve that value. The API says that you get it from liveBroadcast snippet.liveChatId, but with the code I've attached in this post there is no value in the liveChatId field. It is just empty. How do I properly retrieve the liveChatId?
<?php
session_start();
// Call set_include_path() as needed to point to your client library.
require_once 'Google/autoload.php';
require_once 'Google/Client.php';
require_once 'Google/Service/YouTube.php';
$OAUTH2_CLIENT_ID = 'MY-CLIENT-ID';
$OAUTH2_CLIENT_SECRET = 'MY-CLIENT-SECRET';
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setScopes('https://www.googleapis.com/auth/youtube');
$redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'],
FILTER_SANITIZE_URL);
$client->setRedirectUri($redirect);
// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);
$_SESSION['state'] = $_GET['state'];
if (isset($_GET['code'])) {
if (strval($_SESSION['state']) !== strval($_GET['state'])) {
die('The session state did not match.');
}
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
header('Location: ' . $redirect);
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
// Check to ensure that the access token was successfully acquired.
if ($client->getAccessToken()) {
try {
// Execute an API request that lists broadcasts owned by the user who
// authorized the request.
$broadcastsResponse = $youtube->liveBroadcasts->listLiveBroadcasts(
'id,snippet',
array(
'mine' => 'true',
));
var_dump($broadcastsResponse['items']);
$htmlBody .= "<h3>Live Broadcasts</h3><ul>";
foreach ($broadcastsResponse['items'] as $broadcastItem) {
$htmlBody .= $broadcastItem['snippet']['title'] ."<br />Chat ID: ". $broadcastItem['liveChatId'] ."<br />ID: ". $broadcastItem['id'];
}
$htmlBody .= '</ul>';
} catch (Google_Service_Exception $e) {
$htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
} catch (Google_Exception $e) {
$htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
}
$_SESSION['token'] = $client->getAccessToken();
} else {
// If the user hasn't authorized the app, initiate the OAuth flow
$state = mt_rand();
$client->setState($state);
$_SESSION['state'] = $state;
$authUrl = $client->createAuthUrl();
$htmlBody = <<<END
<h3>Authorization Required</h3>
<p>You need to authorize access before proceeding.<p>
END;
}
?>
<!doctype html>
<html>
<head>
<title>My Live Streams</title>
</head>
<body>
<?=$htmlBody?>
</body>
</html>
Where am I lost?
Your comment has exposed the problem. YouTube currently doesn't support mixing live calls with "Stream Now" and creating Events via the API. Complete live events using either one flow or the other, not interchanging both.