Skip to content

Commit 5193a5a

Browse files
Update retrieve_reports.php
Support command-line parameters to set content owner, job ID, download URL. Support option to include system-managed reports. Update auth flow.
1 parent 170530f commit 5193a5a

1 file changed

Lines changed: 130 additions & 129 deletions

File tree

php/retrieve_reports.php

Lines changed: 130 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
<?php
22

33
/**
4-
* This sample retrieves reports created by a specific job by:
4+
* This sample supports the following use cases:
55
*
6-
* 1. Listing the jobs using the "jobs.list" method.
7-
* 2. Retrieving reports using the "reports.list" method.
8-
*
9-
* @author Ibrahim Ulukaya
6+
* 1. Retrieve reporting jobs by content owner:
7+
* Ex: php retrieve_reports.php --contentOwner=="CONTENT_OWNER_ID"
8+
* Ex: php retrieve_reports.php --contentOwner=="CONTENT_OWNER_ID" --includeSystemManaged==True
9+
* 2. Retrieving list of downloadable reports for a particular job:
10+
* Ex: php retrieve_reports.php --contentOwner=="CONTENT_OWNER_ID" --jobId="JOB_ID"
11+
* 3. Download a report:
12+
* Ex: php retrieve_reports.php --contentOwner=="CONTENT_OWNER_ID" --downloadUrl="DOWNLOAD_URL" --outputFile="report.txt"
1013
*/
1114

1215
/**
@@ -18,180 +21,178 @@
1821
* $ composer require google/apiclient:~2.0
1922
*/
2023
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
21-
throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"');
24+
throw new \Exception('please run "composer require google/apiclient:~2.2.0" in "' . __DIR__ .'"');
2225
}
2326

2427
require_once __DIR__ . '/vendor/autoload.php';
2528
session_start();
2629

2730

31+
define('CREDENTIALS_PATH', '~/.credentials/youtube-php.json');
32+
33+
$longOptions = array(
34+
'contentOwner::',
35+
'downloadUrl::',
36+
'includeSystemManaged::',
37+
'jobId::',
38+
'outputFile::',
39+
);
40+
41+
$options = getopt('', $longOptions);
42+
43+
$CONTENT_OWNER_ID = ($options['contentOwner'] ? $options['contentOwner'] : '');
44+
$DOWNLOAD_URL = (array_key_exists('downloadUrl', $options) ?
45+
$options['downloadUrl'] : '');
46+
$INCLUDE_SYSTEM_MANAGED = (array_key_exists('includeSystemManaged', $options) ?
47+
$options['includeSystemManaged'] : '');
48+
$JOB_ID = (array_key_exists('jobId', $options) ? $options['jobId'] : '');
49+
$OUTPUT_FILE = (array_key_exists('outputFile', $options) ?
50+
$options['outputFile'] : '');
51+
2852
/*
29-
* You can acquire an OAuth 2.0 client ID and client secret from the
53+
* You can obtain an OAuth 2.0 client ID and client secret from the
3054
* {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
3155
* For more information about using OAuth 2.0 to access Google APIs, please see:
3256
* <https://developers.google.com/youtube/v3/guides/authentication>
3357
* Please ensure that you have enabled the YouTube Data API for your project.
3458
*/
35-
$OAUTH2_CLIENT_ID = 'REPLACE_ME';
36-
$OAUTH2_CLIENT_SECRET = 'REPLACE_ME';
37-
38-
$client = new Google_Client();
39-
$client->setClientId($OAUTH2_CLIENT_ID);
40-
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
41-
42-
/*
43-
* This OAuth 2.0 access scope allows for full read/write access to the
44-
* authenticated user's account.
45-
*/
46-
$client->setScopes('https://www.googleapis.com/auth/yt-analytics-monetary.readonly');
47-
$redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'],
48-
FILTER_SANITIZE_URL);
49-
$client->setRedirectUri($redirect);
50-
51-
// YouTube Reporting object used to make YouTube Reporting API requests.
52-
$youtubeReporting = new Google_Service_YoutubeReporting($client);
59+
function getClient() {
60+
$client = new Google_Client();
61+
$client->setAuthConfigFile('client_secrets_php.json');
62+
$client->addScope(
63+
'https://www.googleapis.com/auth/yt-analytics-monetary.readonly');
64+
$client->setRedirectUri('urn:ietf:wg:oauth:2.0:oob');
65+
$client->setAccessType('offline');
66+
67+
// Load previously authorized credentials from a file.
68+
$credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
69+
if (file_exists($credentialsPath)) {
70+
$accessToken = json_decode(file_get_contents($credentialsPath), true);
71+
} else {
72+
// Request authorization from the user.
73+
$authUrl = $client->createAuthUrl();
74+
printf('Open the following link in your browser:\n%s\n', $authUrl);
75+
print 'Enter verification code: ';
76+
$authCode = trim(fgets(STDIN));
77+
78+
// Exchange authorization code for an access token.
79+
$accessToken = $client->authenticate($authCode);
80+
$refreshToken = $client->getRefreshToken();
81+
82+
// Store the credentials to disk.
83+
if(!file_exists(dirname($credentialsPath))) {
84+
mkdir(dirname($credentialsPath), 0700, true);
85+
}
86+
file_put_contents($credentialsPath, json_encode($accessToken));
87+
printf('Credentials saved to %s\n', $credentialsPath);
5388

54-
// Check if an auth token exists for the required scopes
55-
$tokenSessionKey = 'token-' . $client->prepareScopes();
56-
if (isset($_GET['code'])) {
57-
if (strval($_SESSION['state']) !== strval($_GET['state'])) {
58-
die('The session state did not match.');
89+
//fclose($fp);
5990
}
91+
$client->setAccessToken($accessToken);
6092

61-
$client->authenticate($_GET['code']);
62-
$_SESSION[$tokenSessionKey] = $client->getAccessToken();
63-
header('Location: ' . $redirect);
64-
}
93+
// Refresh the token if it's expired.
94+
if ($client->isAccessTokenExpired()) {
95+
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
96+
file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
97+
}
6598

66-
if (isset($_SESSION[$tokenSessionKey])) {
67-
$client->setAccessToken($_SESSION[$tokenSessionKey]);
99+
return $client;
68100
}
69101

70-
// Check to ensure that the access token was successfully acquired.
71-
if ($client->getAccessToken()) {
72-
$htmlBody = '';
73-
try {
74-
if (empty(listReportingJobs($youtubeReporting, $htmlBody))) {
75-
$htmlBody .= sprintf('<p>No jobs found.</p>');
76-
} else if ($_GET['reportUrl']){
77-
downloadReport($youtubeReporting, $_GET['reportUrl'], $htmlBody);
78-
} else if ($_GET['jobId']){
79-
retrieveReports($youtubeReporting, $_GET['jobId'], $htmlBody);
80-
}
81-
} catch (Google_Service_Exception $e) {
82-
$htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
83-
htmlspecialchars($e->getMessage()));
84-
} catch (Google_Exception $e) {
85-
$htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
86-
htmlspecialchars($e->getMessage()));
102+
/**
103+
* Expands the home directory alias '~' to the full path.
104+
* @param string $path the path to expand.
105+
* @return string the expanded path.
106+
*/
107+
function expandHomeDirectory($path) {
108+
$homeDirectory = getenv('HOME');
109+
if (empty($homeDirectory)) {
110+
$homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');
87111
}
88-
$_SESSION[$tokenSessionKey] = $client->getAccessToken();
89-
} elseif ($OAUTH2_CLIENT_ID == 'REPLACE_ME') {
90-
$htmlBody = <<<END
91-
<h3>Client Credentials Required</h3>
92-
<p>
93-
You need to set <code>\$OAUTH2_CLIENT_ID</code> and
94-
<code>\$OAUTH2_CLIENT_ID</code> before proceeding.
95-
<p>
96-
END;
97-
} else {
98-
// If the user hasn't authorized the app, initiate the OAuth flow
99-
$state = mt_rand();
100-
$client->setState($state);
101-
$_SESSION['state'] = $state;
102-
103-
$authUrl = $client->createAuthUrl();
104-
$htmlBody = <<<END
105-
<h3>Authorization Required</h3>
106-
<p>You need to <a href="$authUrl">authorize access</a> before proceeding.<p>
107-
END;
112+
return str_replace('~', realpath($homeDirectory), $path);
108113
}
109114

110-
111115
/**
112116
* Returns a list of reporting jobs. (jobs.listJobs)
113117
*
114118
* @param Google_Service_YouTubereporting $youtubeReporting YouTube Reporting service object.
115-
* @param $htmlBody - html body.
119+
* @param string $onBehalfOfContentOwner A content owner ID.
116120
*/
117-
function listReportingJobs(Google_Service_YouTubeReporting $youtubeReporting, &$htmlBody) {
118-
// Call the YouTube Reporting API's jobs.list method to retrieve reporting jobs.
119-
$reportingJobs = $youtubeReporting->jobs->listJobs();
120-
121-
$htmlBody .= "<h3>Reporting Jobs</h3><ul>";
121+
function listReportingJobs(Google_Service_YouTubeReporting $youtubeReporting,
122+
$onBehalfOfContentOwner = '', $includeSystemManaged = False) {
123+
$reportingJobs = $youtubeReporting->jobs->listJobs(
124+
array('onBehalfOfContentOwner' => $onBehalfOfContentOwner,
125+
'includeSystemManaged' => $includeSystemManaged));
126+
print ('REPORTING JOBS' . PHP_EOL . '**************' . PHP_EOL);
122127
foreach ($reportingJobs as $job) {
123-
$htmlBody .= sprintf('<li>id: "%s", name: "%s" report type: "%s"</li>', $job['id'],
124-
$job['name'], $job['reportTypeId']);
128+
print($job['reportTypeId'] . ':' . $job['id'] . PHP_EOL);
125129
}
126-
$htmlBody .= '</ul>';
127-
128-
return $reportingJobs;
130+
print(PHP_EOL);
129131
}
130132

131-
132133
/**
133134
* Lists reports created by a specific job. (reports.listJobsReports)
134135
*
135136
* @param Google_Service_YouTubereporting $youtubeReporting YouTube Reporting service object.
136137
* @param string $jobId The ID of the job.
137-
* @param $htmlBody - html body.
138+
* @param string $onBehalfOfContentOwner A content owner ID.
138139
*/
139-
function retrieveReports(Google_Service_YouTubeReporting $youtubeReporting, $jobId, &$htmlBody) {
140-
// Call the YouTube Reporting API's reports.list method to retrieve reports created by a job.
141-
$reports = $youtubeReporting->jobs_reports->listJobsReports($jobId);
142-
143-
if (empty($reports)) {
144-
$htmlBody .= sprintf('<p>No reports found.</p>');
145-
} else {
146-
$htmlBody .= sprintf('<h2>Reports for the job "%s"</h2><ul>', $jobId);
147-
foreach ($reports as $report) {
148-
$htmlBody .= sprintf('<li>From "%s" to "%s" downloadable at "%s"</li>',
149-
$report['startTime'], $report['endTime'], $report['downloadUrl']);
150-
$htmlBody .= '</ul>';
151-
}
140+
function listReportsForJob(Google_Service_YouTubeReporting $youtubeReporting,
141+
$jobId, $onBehalfOfContentOwner = '') {
142+
$reports = $youtubeReporting->jobs_reports->listJobsReports($jobId,
143+
array('onBehalfOfContentOwner' => $onBehalfOfContentOwner));
144+
print ('DOWNLOADABLE REPORTS' . PHP_EOL . '********************' . PHP_EOL);
145+
foreach ($reports['reports'] as $report) {
146+
print('Created: ' . date('d M Y', strtotime($report['createTime'])) .
147+
' (' . date('d M Y', strtotime($report['startTime'])) .
148+
' to ' . date('d M Y', strtotime($report['endTime'])) . ')' .
149+
PHP_EOL . ' ' . $report['downloadUrl'] . PHP_EOL . PHP_EOL);
152150
}
153151
}
154152

155-
156153
/**
157154
* Download the report specified by the URL. (media.download)
158155
*
159156
* @param Google_Service_YouTubereporting $youtubeReporting YouTube Reporting service object.
160157
* @param string $reportUrl The URL of the report to be downloaded.
158+
* @param string $outputFile The file to write the report to locally.
161159
* @param $htmlBody - html body.
162160
*/
163-
function downloadReport(Google_Service_YouTubeReporting $youtubeReporting, $reportUrl, &$htmlBody) {
161+
function downloadReport(Google_Service_YouTubeReporting $youtubeReporting,
162+
$reportUrl, $outputFile) {
164163
$client = $youtubeReporting->getClient();
165-
// Setting the defer flag to true tells the client to return a request which can be called
166-
// with ->execute(); instead of making the API call immediately.
164+
// Setting the defer flag to true tells the client to return a request that
165+
// can be called with ->execute(); instead of making the API call immediately.
167166
$client->setDefer(true);
168167

169-
// Call the YouTube Reporting API's media.download method to download a report.
170-
$request = $youtubeReporting->media->download("", array("alt" => "media"));
168+
// Call YouTube Reporting API's media.download method to download a report.
169+
$request = $youtubeReporting->media->download('', array('alt' => 'media'));
171170
$request = $request->withUri(new \GuzzleHttp\Psr7\Uri($reportUrl));
172-
$response = $client->execute($request);
173-
174-
file_put_contents("reportFile", $response->getBody());
171+
$responseBody = '';
172+
try {
173+
$response = $client->execute($request);
174+
$responseBody = $response->getBody();
175+
} catch (Google_Service_Exception $e) {
176+
$responseBody = $e->getTrace()[0]['args'][0]->getResponseBody();
177+
}
178+
file_put_contents($outputFile, $responseBody);
175179
$client->setDefer(false);
176180
}
177-
?>
178181

179-
<!doctype html>
180-
<html>
181-
<head>
182-
<title>Retrieve reports</title>
183-
</head>
184-
<body>
185-
<form method="GET">
186-
<div>
187-
Job Id: <input type="text" id="jobId" name="jobId" placeholder="Enter Job Id">
188-
</div>
189-
<br>
190-
<div>
191-
Report URL: <input type="text" id="reportUrl" name="reportUrl" placeholder="Enter Report Url">
192-
</div>
193-
<br> <input type="submit" value="Retrieve!">
194-
</form>
195-
<?=$htmlBody?>
196-
</body>
197-
</html>
182+
// Define an object that will be used to make all API requests.
183+
$client = getClient();
184+
// YouTube Reporting object used to make YouTube Reporting API requests.
185+
$youtubeReporting = new Google_Service_YouTubeReporting($client);
186+
187+
if ($CONTENT_OWNER_ID) {
188+
if (!$DOWNLOAD_URL && !$JOB_ID) {
189+
listReportingJobs($youtubeReporting, $CONTENT_OWNER_ID,
190+
$INCLUDE_SYSTEM_MANAGED);
191+
} else if ($JOB_ID) {
192+
listReportsForJob($youtubeReporting, $JOB_ID, $CONTENT_OWNER_ID);
193+
} else if ($DOWNLOAD_URL && $OUTPUT_FILE) {
194+
downloadReport($youtubeReporting, $DOWNLOAD_URL, $OUTPUT_FILE);
195+
}
196+
}
197+
198+
?>

0 commit comments

Comments
 (0)