I try to update a video's title and description in php calling the Youtube data API.
Here is my php script :
<?php
/**
* This sample sets and retrieves localized metadata for a video by:
*
* 1. Updating language of the default metadata and setting localized metadata
* for a video via "videos.update" method.
* 2. Getting the localized metadata for a video in a selected language using the
* "videos.list" method and setting the "hl" parameter.
* 3. Listing the localized metadata for a video using the "videos.list" method and
* including "localizations" in the "part" parameter.
*
* #author Ibrahim Ulukaya
*/
$htmlBody = <<<END
<form method="GET">
<div>
Action:
<select id="action" name="action">
<option value="set">Set Localization - Fill in: video ID, default language, language, title and description</option>
<option value="get">Get Localization- Fill in: video ID, language</option>
<option value="list">List Localizations - Fill in: video ID, language</option>
</select>
</div>
<br>
<div>
Video ID: <input type="text" id="videoId" name="videoId" placeholder="Enter Video ID">
</div>
<br>
<div>
Default Language: <input type="text" id="defaultLanguage" name="defaultLanguage" placeholder="Enter Default Language (BCP-47 language code)">
</div>
<br>
<div>
Language: <input type="text" id="language" name="language" placeholder="Enter Local Language (BCP-47 language code)">
</div>
<br>
<div>
Title: <input type="text" id="title" name="title" placeholder="Enter Title">
</div>
<br>
<div>
Description: <input type="text" id="description" name="description" placeholder="Enter Description">
</div>
<br>
<input type="submit" value="GO!">
</form>
END;
// Call set_include_path() as needed to point to your client library.
include $_SERVER["DOCUMENT_ROOT"] . '/youtube-test/google-api-php-client/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 = 'xxxxxxxxxxxxxxxxx';
$OAUTH2_CLIENT_SECRET = 'xxxxxxxxxxxxxxxxx';
$action = $_GET['action'];
$videoId = $_GET['videoId'];
$language = $_GET['language'];
$defaultLanguage = 'en';
$title = $_GET['title'];
$description = $_GET['description'];
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
/*
* This OAuth 2.0 access scope allows for full read/write access to the
* authenticated user's account.
*/
$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);
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()) {
// This code executes if the user enters an action in the form
// and submits the form. Otherwise, the page displays the form above.
if ($_GET['action']) {
try {
switch ($action) {
case 'set':
setVideoLocalization($youtube, $videoId, $defaultLanguage,
$language, $title, $description, $htmlBody);
break;
case 'get':
getVideoLocalization($youtube, $videoId, $language, $htmlBody);
break;
case 'list':
listVideoLocalizations($youtube, $videoId, $htmlBody);
break;
}
} 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;
}
/**
* Updates a video's default language and sets its localized metadata.
*
* #param Google_Service_YouTube $youtube YouTube service object.
* #param string $videoId The id parameter specifies the video ID for the resource
* that is being updated.
* #param string $defaultLanguage The language of the video's default metadata
* #param string $language The language of the localized metadata
* #param string $title The localized title to be set
* #param string $description The localized description to be set
* #param $htmlBody - html body.
*/
function setVideoLocalization(Google_Service_YouTube $youtube, $videoId, $defaultLanguage,
$language, $title, $description, &$htmlBody) {
// Call the YouTube Data API's videos.list method to retrieve videos.
$videos = $youtube->videos->listVideos("snippet,localizations", array(
'id' => $videoId
));
// If $videos is empty, the specified video was not found.
if (empty($videos)) {
$htmlBody .= sprintf('<h3>Can\'t find a video with video id: %s</h3>', $videoId);
} else {
// Since the request specified a video ID, the response only
// contains one video resource.
$updateVideo = $videos[0];
// Modify video's default language and localizations properties.
// Ensure that a value is set for the resource's snippet.defaultLanguage property.
$updateVideo['snippet']['defaultLanguage'] = $defaultLanguage;
$localizations = $updateVideo['localizations'];
if (is_null($localizations)) {
$localizations = array();
}
$localizations[$language] = array('title' => $title, 'description' => $description);
$updateVideo['localizations'] = $localizations;
// Call the YouTube Data API's videos.update method to update an existing video.
$videoUpdateResponse = $youtube->videos->update("snippet,localizations", $updateVideo);
$htmlBody .= "<h2>Updated video</h2><ul>";
$htmlBody .= sprintf('<li>(%s) default language: %s</li>', $videoId,
$videoUpdateResponse['snippet']['defaultLanguage']);
$htmlBody .= sprintf('<li>title(%s): %s</li>', $language,
$videoUpdateResponse['localizations'][$language]['title']);
$htmlBody .= sprintf('<li>description(%s): %s</li>', $language,
$videoUpdateResponse['localizations'][$language]['description']);
$htmlBody .= '</ul>';
}
}
/**
* Returns localized metadata for a video in a selected language.
* If the localized text is not available in the requested language,
* this method will return text in the default language.
*
* #param Google_Service_YouTube $youtube YouTube service object.
* #param string $videoId The videoId parameter instructs the API to return the
* localized metadata for the video specified by the video id.
* #param string language The language of the localized metadata.
* #param $htmlBody - html body.
*/
function getVideoLocalization(Google_Service_YouTube $youtube, $videoId, $language, &$htmlBody) {
// Call the YouTube Data API's videos.list method to retrieve videos.
$videos = $youtube->videos->listVideos("snippet", array(
'id' => $videoId,
'hl' => $language
));
// If $videos is empty, the specified video was not found.
if (empty($videos)) {
$htmlBody .= sprintf('<h3>Can\'t find a video with video id: %s</h3>', $videoId);
} else {
// Since the request specified a video ID, the response only
// contains one video resource.
$localized = $videos[0]["snippet"]["localized"];
$htmlBody .= "<h3>Video</h3><ul>";
$htmlBody .= sprintf('<li>title(%s): %s</li>', $language, $localized['title']);
$htmlBody .= sprintf('<li>description(%s): %s</li>', $language, $localized['description']);
$htmlBody .= '</ul>';
}
}
/**
* Returns a list of localized metadata for a video.
*
* #param Google_Service_YouTube $youtube YouTube service object.
* #param string $videoId The videoId parameter instructs the API to return the
* localized metadata for the video specified by the video id.
* #param $htmlBody - html body.
*/
function listVideoLocalizations(Google_Service_YouTube $youtube, $videoId, &$htmlBody) {
// Call the YouTube Data API's videos.list method to retrieve videos.
$videos = $youtube->videos->listVideos("snippet,localizations", array(
'id' => $videoId
));
// If $videos is empty, the specified video was not found.
if (empty($videos)) {
$htmlBody .= sprintf('<h3>Can\'t find a video with video id: %s</h3>', $videoId);
} else {
// Since the request specified a video ID, the response only
// contains one video resource.
$localizations = $videos[0]["localizations"];
$htmlBody .= "<h3>Video</h3><ul>";
foreach ($localizations as $language => $localization) {
$htmlBody .= sprintf('<li>title(%s): %s</li>', $language, $localization['title']);
$htmlBody .= sprintf('<li>description(%s): %s</li>', $language, $localization['description']);
}
$htmlBody .= '</ul>';
}
}
?>
<!doctype html>
<html>
<head>
<title>Set and retrieve localized metadata for a video</title>
</head>
<body>
<?=$htmlBody?>
</body>
</html>
Of course, I have replaced the $OAUTH2_CLIENT_ID & $OAUTH2_CLIENT_SECRET with the ones Google gave me at console.developers.google.com.
The fact is, when I just ask to retrieve content from the API, it works well.
But when I try setting or updating, it comes with the following error :
A service error occurred: Error calling PUT https://www.googleapis.com/youtube/v3/videos?part=snippet%2Clocalizations: (403) Forbidden
Is there something else I should do to allow my videos to be updated by a php script?
Thank you in advance for your help.
Related
Using the YouTube API to upload videos to a single channel is straightforward. This is how I currently do it using the PHP Client Library:
<?php
/**
* This sample adds new tags to a YouTube video by:
*
* 1. Retrieving the video resource by calling the "youtube.videos.list" method
* and setting the "id" parameter
* 2. Appending new tags to the video resource's snippet.tags[] list
* 3. Updating the video resource by calling the youtube.videos.update method.
*
* #author Ibrahim Ulukaya
*/
/**
* 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 = 'REPLACE_ME';
$OAUTH2_CLIENT_SECRET = 'REPLACE_ME';
$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()) {
$htmlBody = '';
try{
// REPLACE this value with the video ID of the video being updated.
$videoId = "VIDEO_ID";
// Call the API's videos.list method to retrieve the video resource.
$listResponse = $youtube->videos->listVideos("snippet",
array('id' => $videoId));
// If $listResponse is empty, the specified video was not found.
if (empty($listResponse)) {
$htmlBody .= sprintf('<h3>Can\'t find a video with video id: %s</h3>', $videoId);
} else {
// Since the request specified a video ID, the response only
// contains one video resource.
$video = $listResponse[0];
$videoSnippet = $video['snippet'];
$tags = $videoSnippet['tags'];
// Preserve any tags already associated with the video. If the video does
// not have any tags, create a new list. Replace the values "tag1" and
// "tag2" with the new tags you want to associate with the video.
if (is_null($tags)) {
$tags = array("tag1", "tag2");
} else {
array_push($tags, "tag1", "tag2");
}
// Set the tags array for the video snippet
$videoSnippet['tags'] = $tags;
// Update the video resource by calling the videos.update() method.
$updateResponse = $youtube->videos->update("snippet", $video);
$responseTags = $updateResponse['snippet']['tags'];
$htmlBody .= "<h3>Video Updated</h3><ul>";
$htmlBody .= sprintf('<li>Tags "%s" and "%s" added for video %s (%s) </li>',
array_pop($responseTags), array_pop($responseTags),
$videoId, $video['snippet']['title']);
$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;
}
?>
<!doctype html>
<html>
<head>
<title>Video Updated</title>
</head>
<body>
<?=$htmlBody?>
</body>
</html>
update_video.php
The very first time the script runs, I am prompted with a window to authenticate the request, a token is granted and expires in 60 minutes.
I want to use the same script to upload videos to different channels which I own. For example if I have 3 different channels I can sign in to different browsers to authenticate the application. I currently have more than 10 YouTube channels that I want to upload content to after every few hours.
Is there a way I can manage all these channels from a central service so as to avoid authenticating each time I add a new channel. Or is there a way to authenticate the YouTube API using my YouTube login details?
The YouTube API is slightly different then other Google APIs. Normally authentication is user account based. So if I authenticate you to access my Google calendar you have access to all my Google calendars.
The YouTube API is how ever User channel based. Your going to have to authenticate your application once for each channel. Then make sure you have a refresh token. Store the refresh token someplace associated with the name of the channel. Then you your automated script will be able to use the refresh token to request a new access token and gain access to your account when ever it needs.
This question is for the Analytics api but the code should work for YouTube as well with a few minor alterations to point to the YouTube API instead. How to refresh token with Google API client?
I am receiving an error message when trying to download YouTube Reporting API bulk reports on behalf of a content owner.
I have successfully created report jobs and report job returns download URLs but the download fails with the following error message:
A service error occurred: Invalid json in service response:
date,channel_id,video_id,claimed_status,uploader_type,country_code,ad_type,estimated_youtube_ad_revenue,ad_impressions,estimated_cpm
Please can someone help me understand what this error means and how to resolve the issue? I've tracked issue down to failure in function downloadReport. The line that fails is:
response = $client->execute($request);
I have used the PHP sample code provided on Google developers here:
https://developers.google.com/youtube/reporting/v1/reports/#code-samples
My version of code for "Retrieve a report" follows:
<?php
/**
* This sample retrieves reports created by a specific job by:
*
* 1. Listing the jobs using the "jobs.list" method.
* 2. Retrieving reports using the "reports.list" method.
*
* #author Ibrahim Ulukaya
*/
// Call set_include_path() as needed to point to your client library.
require_once '/../src/Google/autoload.php';
require_once '/../src/Google/Client.php';
require_once '/../src/Google/Service/YouTubeReporting.php';
session_start();
/*
* You can acquire an OAuth 2.0 client ID and client secret from the
* Google Developers Console <https://console.developers.google.com/>
* 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 = 'REPLACE_ME';
$OAUTH2_CLIENT_SECRET = 'REPLACE_ME';
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
/*
* This OAuth 2.0 access scope allows for full read/write access to the
* authenticated user's account.
*/
$client->setScopes('https://www.googleapis.com/auth/yt-analytics-monetary.readonly https://www.googleapis.com/auth/yt-analytics.readonly https://www.googleapis.com/auth/youtubepartner https://www.googleapis.com/auth/youtube.readonly https://www.googleapis.com/auth/youtubepartner-channel-audit https://www.googleapis.com/auth/youtubepartner-content-owner-readonly');
$redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'],
FILTER_SANITIZE_URL);
$client->setRedirectUri($redirect);
// YouTube Reporting object used to make YouTube Reporting API requests.
$youtubeReporting = new Google_Service_YoutubeReporting($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();
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 {
if (empty(listReportingJobs($youtubeReporting, $htmlBody)))
{
$htmlBody .= sprintf('<p>No jobs found.</p>');
}
else
{
if ($_GET['reportUrl'])
{
downloadReport($youtubeReporting, $_GET['reportUrl'], $htmlBody);
}
else
{
if ($_GET['jobId'])
{
retrieveReports($youtubeReporting, $_GET['jobId'], $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['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;
}
/**
* Returns a list of reporting jobs. (jobs.listJobs)
*
* #param Google_Service_YouTubereporting $youtubeReporting YouTube Reporting service object.
* #param $htmlBody - html body.
*/
function listReportingJobs(Google_Service_YouTubeReporting $youtubeReporting, &$htmlBody) {
// Call the YouTube Reporting API's jobs.list method to retrieve reporting jobs.
$optParams=array("onBehalfOfContentOwner"=>"REPLACE_ME");
$reportingJobs = $youtubeReporting->jobs->listJobs($optParams);
$htmlBody .= "<h3>Reporting Jobs</h3><ul>";
foreach ($reportingJobs as $job) {
$htmlBody .= sprintf('<li>id: "%s", name: "%s" report type: "%s"</li>', $job['id'],
$job['name'], $job['reportTypeId']);
}
$htmlBody .= '</ul>';
return $reportingJobs;
}
/**
* Lists reports created by a specific job. (reports.listJobsReports)
*
* #param Google_Service_YouTubereporting $youtubeReporting YouTube Reporting service object.
* #param string $jobId The ID of the job.
* #param $htmlBody - html body.
*/
function retrieveReports(Google_Service_YouTubeReporting $youtubeReporting, $jobId, &$htmlBody) {
// Call the YouTube Reporting API's reports.list method to retrieve reports created by a job.
$optParams=array("onBehalfOfContentOwner"=>"REPLACE_ME");
$reports = $youtubeReporting->jobs_reports->listJobsReports($jobId, $optParams);
if (empty($reports)) {
$htmlBody .= sprintf('<p>No reports found.</p>');
} else {
$htmlBody .= sprintf('<h2>Reports for the job "%s"</h2>', $jobId);
foreach ($reports as $report) {
$htmlBody .= sprintf('<ul><li>From "%s" to "%s" downloadable at "%s"</li>',
$report['startTime'], $report['endTime'], $report['downloadUrl']);
$htmlBody .= '</ul>';
}
}
}
/**
* Download the report specified by the URL. (media.download)
*
* #param Google_Service_YouTubereporting $youtubeReporting YouTube Reporting service object.
* #param string $reportUrl The URL of the report to be downloaded.
* #param $htmlBody - html body.
*/
function downloadReport(Google_Service_YouTubeReporting $youtubeReporting, $reportUrl, &$htmlBody) {
$client = $youtubeReporting->getClient();
// 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);
// Call the YouTube Reporting API's media.download method to download a report.
$request = $youtubeReporting->media->download("");
$request->setUrl($reportUrl);
$response = $client->execute($request);
file_put_contents("reportFile", $response->getResponseBody());
$client->setDefer(false);
}
?>
<!doctype html>
<html>
<head>
<title>Retrieve reports</title>
</head>
<body>
<form method="GET">
<div>
Job Id: <input type="text" id="jobId" name="jobId" placeholder="Enter Job Id">
</div>
<br>
<div>
Report URL: <input type="text" id="reportUrl" name="reportUrl" placeholder="Enter Report Url">
</div>
<br> <input type="submit" value="Retrieve!">
</form>
<?=$htmlBody?>
</body>
</html>
I'm trying to create an authentication with google API. I always get my page refreshed I can't get access to the user information I see always the two alerts "here 1" and "here 2" any idea to help ?
<?php
/* GOOGLE LOGIN BASIC - Tutorial
* file - index.php
* Developer - Krishna Teja G S
* Website - http://packetcode.com/apps/google-login/
* Date - 28th Aug 2015
* license - GNU General Public License version 2 or later
*/
// REQUIREMENTS - PHP v5.3 or later
// Note: The PHP client library requires that PHP has curl extensions configured.
/*
* DEFINITIONS
*
* load the autoload file
* define the constants client id,secret and redirect url
* start the session
*/
require_once __DIR__.'/gplus-lib/vendor/autoload.php';
const CLIENT_ID = 'my code';
const CLIENT_SECRET = 'my code';
const REDIRECT_URI = 'http://www.servicebigdeals.com/google-login/';
session_start();
/*
* INITIALIZATION
*
* Create a google client object
* set the id,secret and redirect uri
* set the scope variables if required
* create google plus object
*/
$client = new Google_Client();
$client->setClientId(CLIENT_ID);
$client->setClientSecret(CLIENT_SECRET);
$client->setRedirectUri(REDIRECT_URI);
$client->setScopes('email');
$plus = new Google_Service_Plus($client);
/*
* PROCESS
*
* A. Pre-check for logout
* B. Authentication and Access token
* C. Retrieve Data
*/
/*
* A. PRE-CHECK FOR LOGOUT
*
* Unset the session variable in order to logout if already logged in
*/
if (isset($_REQUEST['logout'])) {
session_unset();
}
/*
* B. AUTHORIZATION AND ACCESS TOKEN
*
* If the request is a return url from the google server then
* 1. authenticate code
* 2. get the access token and store in session
* 3. redirect to same url to eliminate the url variables sent by google
*/
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
else {
echo "<script>alert(\"here 1 \")</script>";
}
/*
* C. RETRIEVE DATA
*
* If access token if available in session
* load it to the client object and access the required profile data
*/
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
$me = $plus->people->get('me');
// Get User data
$id = $me['id'];
$name = $me['displayName'];
$email = $me['emails'][0]['value'];
$profile_image_url = $me['image']['url'];
$cover_image_url = $me['cover']['coverPhoto']['url'];
$profile_url = $me['url'];
}
else {
echo "<script>alert(\"here 2 \")</script>";
// get the login url
$authUrl = $client->createAuthUrl();
}
?>
<!-- HTML CODE with embedded PHP-->
<div>
<?php
/*
* If login url is there then display login button
* else print the retrieved data
*/
if (isset($authUrl)) {
echo "<a class='login' href='" . $authUrl . "'><img src='gplus-lib/signin_button.png' height='50px'/></a>";
} else {
print "ID: {$id} <br>";
print "Name: {$name} <br>";
print "Email: {$email } <br>";
print "Image : {$profile_image_url} <br>";
print "Cover :{$cover_image_url} <br>";
print "Url: {$profile_url} <br><br>";
echo "<a class='logout' href='?logout'><button>Logout</button></a>";
}
?>
</div>
I am managing a Google account and it has a YouTube channel connected to a Google+ profile, and a YouTube channel connected to a Google+ page. Using a OAuth key of this account, I want to upload videos to the "page"'s channel, so far I've only managed with the "profile"'s channel. The "page" channel has our company name and logo, so I don't want it to be a personal (at least appear to be) "profile"'s channel
I'm using a script almost identical to the video upload sample script:
https://developers.google.com/youtube/v3/code_samples/php?hl=en#upload_a_video
<?php
// Call set_include_path() as needed to point to your client library.
require_once 'Google/Client.php';
require_once 'Google/Service/YouTube.php';
session_start();
/*
* You can acquire an OAuth 2.0 client ID and client secret from the
* Google Developers Console <https://console.developers.google.com/>
* 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 = 'REPLACE_ME';
$OAUTH2_CLIENT_SECRET = 'REPLACE_ME';
$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);
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{
// REPLACE this value with the path to the file you are uploading.
$videoPath = "/path/to/file.mp4";
// Create a snippet with title, description, tags and category ID
// Create an asset resource and set its snippet metadata and type.
// This example sets the video's title, description, keyword tags, and
// video category.
$snippet = new Google_Service_YouTube_VideoSnippet();
$snippet->setTitle("Test title");
$snippet->setDescription("Test description");
$snippet->setTags(array("tag1", "tag2"));
// Numeric video category. See
// https://developers.google.com/youtube/v3/docs/videoCategories/list
$snippet->setCategoryId("22");
// Set the video's status to "public". Valid statuses are "public",
// "private" and "unlisted".
$status = new Google_Service_YouTube_VideoStatus();
$status->privacyStatus = "public";
// Associate the snippet and status objects with a new video resource.
$video = new Google_Service_YouTube_Video();
$video->setSnippet($snippet);
$video->setStatus($status);
// Specify the size of each chunk of data, in bytes. Set a higher value for
// reliable connection as fewer chunks lead to faster uploads. Set a lower
// value for better recovery on less reliable connections.
$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", $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);
// If you want to make other calls after the file upload, set setDefer back to false
$client->setDefer(false);
$htmlBody .= "<h3>Video Uploaded</h3><ul>";
$htmlBody .= sprintf('<li>%s (%s)</li>',
$status['snippet']['title'],
$status['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>Video Uploaded</title>
</head>
<body>
<?=$htmlBody?>
</body>
</html>
As mentioned, the script works for the channel that was connected to the "profile" .. I've since deleted this as it was just for testing. I want to upload videos instead to the other Google+ "page"'s channel which is also owned by this account. So far I've tried setting the desired channel as the default of this account, but do I need to actually move the channel to the Google+ "profile"? .. unless I can specify channel in the above script? If I move the channel, will it retain the channel's name though? I don't want anything about the channel to change (name, logo). From what I see it will change the channel name (see image) which is not ideal, I just want to upload to this channel - that's all
Checkout this:
https://developers.google.com/youtube/v3/docs/videos/insert
And notice the onBehalfOfContentOwner and the onBehalfOfContentOwnerChannel parameters for the request, i think this is what you need.
This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.
I am using Youtube data api its properly working on localhost but when I am trying to access this code on live server its not working. giving an exception :
Uncaught exception 'Google_IO_Exception' with message 'Protocol
"https" not supported or disabled in libcurl' in
/home/legenddude/public_html/newUpload/Google/IO/Curl.php:115 Stack
trace: #0
/home/legenddude/public_html/newUpload/Google/IO/Abstract.php(136):
Google_IO_Curl->executeRequest(Object(Google_Http_Request)) #1
/home/legenddude/public_html/newUpload/Google/Auth/OAuth2.php(111):
Google_IO_Abstract->makeRequest(Object(Google_Http_Request)) #2
/home/legenddude/public_html/newUpload/Google/Client.php(128):
Google_Auth_OAuth2->authenticate('4/x7_AOHFKvmlea...', false) #3
/home/legenddude/public_html/newUpload/youtube.php(44):
Google_Client->authenticate('4/x7_AOHFKvmlea...') #4 {main} thrown in
Here is my code youtube.php-:
<?php
// Call set_include_path() as needed to point to your client library.
ini_set('display_errors',1);
error_reporting(E_ALL|E_STRICT);
set_include_path($_SERVER['DOCUMENT_ROOT'] . '/newUpload/');
require_once 'Google/autoload.php';
require_once 'Google/Client.php';
require_once 'Google/Service/YouTube.php';
session_start();
ini_set('display_errors',1);
error_reporting(E_ALL|E_STRICT);
/*
* 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 = '619899784025-5nn2tqomt3cr6g231qd93nr0lsojdvq9.apps.googleusercontent.com';
$OAUTH2_CLIENT_SECRET = '49K6Ou9PK9n1aamAeg27fnIC';
$REDIRECT = 'http://www.legenddude.com/newUpload/youtube.php';
$APPNAME = "legenddudes";
$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('online');
$client->setDeveloperKey('619899784025-5nn2tqomt3cr6g231qd93nr0lsojdvq9#developer.gserviceaccount.com');
// 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.');
}
//echo $_SESSION['state'];exit;
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
echo '<code>' . $_SESSION['token'] . '</code>';
}
// 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>`enter code here`
From curl_faq:
When passing on a URL to curl to use, it may respond that the particular protocol is not supported or disabled. The particular way this error message is phrased is because curl doesn't make a distinction internally of whether a particular protocol is not supported (i.e. never got any code added that knows how to speak that protocol) or if it was explicitly disabled. curl can be built to only support a given set of protocols, and the rest would then be disabled or not supported.
And more:
To get the https:// support into a curl that was previously built but that reports that https:// is not supported, you should dig through the document and logs and check out why the configure script doesn't find the SSL libs and/or include files.