Using Google Open ID Connect to Access User's Gmail Account - google-apps-script

How can I run a google apps script API on multiple gmail accounts? I currently have a script that accesses a user's gmail when it is authorized by the two files shown below. I store the refresh token for the client once the code asks for authorization. However, how can I use Open ID to get authorization for various users' accounts? Do I need to store a client id in addition to a refresh token to gain authorization for a user's gmail account? Thanks for taking the time to help in advance!
read_email.php
<?php
require_once '../google-api-php-client/src/Google/autoload.php';
function getEmails (){
session_start();
$client = new Google_Client();
$client->setAuthConfigFile('client_secrets.json');
$client->setScopes(array(
'https://mail.google.com/'
));
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
if($client->isAccessTokenExpired()){
header('Location: http://' . $_SERVER['HTTP_HOST'] . '/email_database/php/oauth2callback.php');
}
// Get the API client and construct the service object.
$service = new Google_Service_Script($client);
$scriptId = '**********************';
// Create an execution request object.
$request = new Google_Service_Script_ExecutionRequest();
set_time_limit(0);
$request->setFunction('test');
$response = $service->scripts->run($scriptId, $request);
$response = $response->getResponse();
$response = $response['result'];
return ($response);
} else {
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/email_database/php/oauth2callback.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
}
?>
oauth2callback.php
<?php
require_once '../google-api-php-client/src/Google/autoload.php';
include 'functions.php';
$client = new Google_Client();
$client->setAuthConfigFile('client_secrets.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/email_database/dashboard/php/oauth2callback.php');
$client->setScopes(array(
'https://mail.google.com/'
));
$client->setAccessType('offline');
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/email_database/dashboard/php/read_email.php';
$username = $_SESSION['username'];
$user = getUser($username);
if($user['refresh_token'] == null){
if (! isset($_GET['code'])) {
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
//echo $_GET['code'];
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$google_token = json_decode($_SESSION['access_token']);
print_r($google_token);
$refresh_token = $google_token->refresh_token;
addRefreshToken($username,$refresh_token);
//header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
}
else {
$refresh_token = $user['refresh_token'];
$client->refreshToken($refresh_token);
$_SESSION['access_token']= $client->getAccessToken();
// header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>

Related

List of files from my google drive

I am writing PHP script which get files from my Google Drive folder and write list of them with download links on my website, but can not find solution which take files from my folder. Every solution I found need sign up from user, that is viewing page and get list of files from his google drive. Can anyone help me with solution?
Here is my code.
function printFilesInFolder($service, $folderId) {
$pageToken = NULL;
do {
try {
$parameters = array();
$parameters = array(
'q' => "'0B5NCdsbrL1VfQ00xY3pFS3BtOE0' in parents"
);
$children = $service->files->listFiles($parameters);
var_dump($children);
foreach ($children->getFiles() as $child) {
print 'File Id: ' . $child->getId();
}
$pageToken = $children->getNextPageToken();
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
$pageToken = NULL;
}
} while ($pageToken);
}
$client = new Google_Client();
$client->setApplicationName("Web client 1");
$client->setClientId('CLIENTID');
$client->setClientSecret('SECRET');
$client->setScopes(array('https://www.googleapis.com/auth/drive.file'));
$client->setRedirectUri('http://localhost/googledrive/drive/drive.php');
if (isset($_GET['code']) || (isset($_SESSION['access_token']) && $_SESSION['access_token'])) {
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
} else
$client->setAccessToken($_SESSION['access_token']);
$service = new Google_Service_Drive($client);
$ret = printFilesInFolder($service,"FOLDERID");
} else {
$authUrl = $client->createAuthUrl();
header('Location: ' . $authUrl);
exit();
}
But i still dont getting right data.
Second think is, that i want to remove need of authentication on every refresh of page, but i dont know how to do that.

Google drive Upload returns - (403) Insufficient Permission

I am trying to upload files to google drive using service account, but i am getting error like
(403) Insufficient Permission error
Although fetching list of files from drive is working fine.
require_once 'google-api-php-client-master/src/Google/autoload.php';
require_once 'google-api-php-client-master/src/Google/Service.php';
session_start();
$client = new Google_Client();
$client->setAuthConfigFile('client_secrets.json');
$service_account_name = '251181790499-1en2vs6jjovga1egu15tphm1m7g44m60#developer.gserviceaccount.com';
$key_file_location = 'key.p12'; //key.p12
$key = file_get_contents($key_file_location);;
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
//$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
//$client->setScopes(array('https://www.googleapis.com/auth/drive'));
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/drive'),
$key);
$client->setAssertionCredentials($cred);
$client->setAccessType("offline");
$file = new Google_Service_Drive_DriveFile();
$file->setTitle(uniqid().'.jpg');
$file->setDescription('A test document');
$file->setMimeType('image/jpeg');
$data = file_get_contents('a.jpg');
$service = new Google_Service_Drive($client);
$createdFile = $service->files->insert($file, array(
'data' => $data,
'mimeType' => 'image/jpeg',
'uploadType' => 'multipart'
));
print_r($createdFile);
}
else
{
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/googledrive/oauth2callback.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
I have reviewed similar questions in forum and tried suggestions but nothing seems to work.
Is there anything wrong with code?
Change your Google Drive Scope to
Google_Service_Drive::DRIVE
in PHP
$client->addScope(Google_Service_Drive::DRIVE);

quickbooks online interaction

I have a web app that I need to communicate with quickbooks online edition. I am able connect and receive data. The problem is is that the responce back that i get is not in a xml format or even better would be in json formate. How can I get it to respond back in one of those formats? Here is my code:
function request($xml, $certificate = null, $debug = false){
$ch = curl_init();
$header[] = 'Content-Type: application/x-qbxml';
$header[] = 'Content-Length: ' . strlen($xml);
$params = array();
$params[CURLOPT_HTTPHEADER] = $header;
$params[CURLOPT_POST] = true;
$params[CURLOPT_RETURNTRANSFER] = true;
$params[CURLOPT_URL] = $this->gateway;
$params[CURLOPT_TIMEOUT] = 30;
$params[CURLOPT_POSTFIELDS] = $xml;
$params[CURLOPT_VERBOSE] = $debug;
$params[CURLOPT_HEADER] = true;
// This is only for the HOSTED security model
if (file_exists($certificate))
{
$params[CURLOPT_SSL_VERIFYPEER] = false;
$params[CURLOPT_SSLCERT] = $certificate;
}
// Some Windows servers will fail with SSL errors unless we turn this off
$params[CURLOPT_SSL_VERIFYPEER] = false;
$params[CURLOPT_SSL_VERIFYHOST] = 0;
// Diagnostic information: https://merchantaccount.quickbooks.com/j/diag/http
// curl_setopt($ch, CURLOPT_INTERFACE, '<myipaddress>');
$ch = curl_init();
curl_setopt_array($ch, $params);
$response = curl_exec($ch);
if (curl_errno($ch))
{
$errnum = curl_errno($ch);
$errmsg = curl_error($ch);
_log('CURL error: ' . $errnum . ': ' . $errmsg, $debug);
return false;
}
// Close the connection
#curl_close($ch);
// Remove the HTTP headers from the response
$pos = strpos($response, "\r\n\r\n");
$response = ltrim(substr($response, $pos));
return $response;
}
function item_list(){
$xml =
'<?xml version="1.0"?>
<?qbxml version="6.0"?>
<QBXML>
<SignonMsgsRq>
<SignonTicketRq>
<ClientDateTime>' . date('Y-m-d') . 'T' . date('H:i:s') . '</ClientDateTime>
<SessionTicket>' . $this->session . '</SessionTicket>
<Language>English</Language>
<AppID>' . $this->application_id . '</AppID>
<AppVer>1</AppVer>
</SignonTicketRq>
</SignonMsgsRq>
<QBXMLMsgsRq onError="stopOnError">
<ItemQueryRq>
<OwnerID>0</OwnerID>
</ItemQueryRq>
</QBXMLMsgsRq>
</QBXML>';
$response = $this->request($xml, null, true);
echo $response;
}
Thanks
Here my xml request:
$xml =
'
' . date('Y-m-d') . 'T' . date('H:i:s') . '
' . $this->session . '
English
' . $this->application_id . '
1
0
</QBXMLMsgsRq>
</QBXML>';
Here is my responce:
2013-04-12T12:28:11 V1-115-Q03kydq32h22tnfqnd5izf:689712285 1 2013-04-10T06:02:40 2013-04-10T06:02:40 0 Sales Sales 0 0 1 Sales 2 2013-04-10T21:20:43 2013-04-10T21:20:43 0 test product test product 0 0 1 Sales
My stupid mistake. I was echoing my result to browser which interpreted xml tags as html tags. I used $xml = simplexml_load_string($response); print_r($xml); to view response in browser.

Google API for analytics invalid grant but works sometimes

I've been on this problem now for 2 days and have tried looking under google code and stackoverflow but still can come up with an answer.
My problem is when I try my google analytics api I get "Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }'"
But the weird part is that some times it will work. rarely but if I refresh and keep trying it, it will output.
The only thing I could find is that it could be the refresh token limit has been exceeded
Attached is my code if someone could help me out or point me to the right direction.
Thanks!
<?php
session_start();
require_once 'Google_Client.php';
require_once 'Google_AnalyticsService.php';
require_once 'config.php';
$keyFile = 'key.p12';
$client = new Google_Client();
$client->setApplicationName("test");
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
$client->setAssertionCredentials(new Google_AssertionCredentials(
GOOGLE_SERVICE_ACCOUNT,
array('https://www.googleapis.com/auth/analytics.readonly'),
file_get_contents($keyFile))
);
$client->setClientId(GOOGLE_CLIENT_ID);
$client->setAccessType('offline');
$client->setUseObjects(true);
$service = new Google_AnalyticsService($client);
try {
$results = $service->data_ga->get(
'ga:44444444',
date('Y-m-d', strtotime('-30 days '.date('Y-m-d', strtotime('-1 day '.date('Y-m- d'))))),
date('Y-m-d', strtotime('-1 day '.date('Y-m-d'))),
'ga:visits,ga:newVisits',
/*array(
'dimensions' => 'ga:source,ga:keyword',
'sort' => '-ga:visits,ga:keyword',
'filters' => 'ga:medium==organic',
'max-results' => '25'
)*/
array('dimensions' => 'ga:date')
);
} catch (Google_ServiceException $e) {
// echo $e->getMessage();
}
if ($client->getAccessToken()) {
$_SESSION['token'] = $client->getAccessToken();
}
$dateParsePattern = '/"Date.parse\(\\\"((\d{4})-(\d{2})-(\d{2})) UTC\\\"\)"/';
$dateParseReplacement = 'Date.parse("$1 UTC")';
$allVisitsItems = array();
$newVisitorsItems = array();
if ($results && count($results->getRows()) > 0) {
foreach ($results->getRows() as $row) {
$date = 'Date.parse("'.date("Y-m-d", strtotime($row[0])).' UTC")';
$allVisitsItems[] = array($date, intval(htmlspecialchars($row[1], ENT_NOQUOTES)));
$newVisitorsItems[] = array($date, intval(htmlspecialchars($row[2], ENT_NOQUOTES)));
}
}
header('Content-Type: application/json');
?>
<?php echo preg_replace($dateParsePattern, $dateParseReplacement, json_encode($allVisitsItems)) ?>
Edit - It's not the NTP, when I echoed date('l jS \of F Y h:i:s A'); it matched up.
The following works to generate output - make sure you are running PHP 5.3 or higher.
<?php
require_once './src/Google_Client.php';
require_once './src/contrib/Google_AnalyticsService.php';
$path_to_keyfile = '.p12';
$service_account_email = '7#developer.gserviceaccount.com';
$client_id = '7.apps.googleusercontent.com';
$analytics_profile_id = 'ga:IN URL OF ANALYTICS';
$client = new Google_Client();
$client->setApplicationName("API TEST");
$client->setAssertionCredentials(
new Google_AssertionCredentials(
$service_account_email,
array('https://www.googleapis.com/auth/analytics.readonly'),
file_get_contents($path_to_keyfile)
)
);
$client->setClientId($client_id);
$client->setAccessType('offline_access');
$service = new Google_AnalyticsService($client);
$from = date('Y-m-d', strtotime('-30 days '.date('Y-m-d', strtotime('-1 day '.date('Y-m-d'))))); // 30 days
$to = date('Y-m-d', strtotime('-1 day '.date('Y-m-d'))); // yesterday
$dateParsePattern = '/"Date.parse\(\\\"((\d{4})-(\d{2})-(\d{2})) UTC\\\"\)"/';
$dateParseReplacement = 'Date.parse("$1 UTC")';
$allVisitsItems = array();
$newVisitorsItems = array();
try {
$data = $service->data_ga->get(
//
$analytics_profile_id,
$from,
$to,
'ga:visits,ga:newVisits',
array('dimensions' => 'ga:date')
);
if($data && $data['totalResults'] > 0) {
foreach($data['rows'] as $row) {
$date = 'Date.parse("'.date("Y-m-d", strtotime($row[0])).' UTC")';
$allVisitsItems[] = array($date, intval(htmlspecialchars($row[1], ENT_NOQUOTES)));
$newVisitorsItems[] = array($date, intval(htmlspecialchars($row[2], ENT_NOQUOTES)));
}
}
header('Content-Type: application/json');
?>
<?php echo preg_replace($dateParsePattern, $dateParseReplacement, json_encode($allVisitsItems)) ?>
<?php echo preg_replace($dateParsePattern, $dateParseReplacement, json_encode($newVisitorsItems)) ?>
<?php
} catch(Exception $e) {
echo 'There was an error : - ' . $e->getMessage();
}

google drive api dont know where it saves the file but when fetched it shows the saved but not the others

I used the google drive api to insert a text file...
Build Service
function buildService() {
$DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive';
$SERVICE_ACCOUNT_EMAIL = 'xxxx#developer.gserviceaccount.com';
if($_SERVER['HTTP_HOST'] == 'localhost')
$SERVICE_ACCOUNT_PKCS12_FILE_PATH = 'xxxxxxxx-privatekey.p12';
else
$SERVICE_ACCOUNT_PKCS12_FILE_PATH = $_SERVER['DOCUMENT_ROOT'].'/xxxxx-privatekey.p12';
$key = file_get_contents($SERVICE_ACCOUNT_PKCS12_FILE_PATH);
$auth = new Google_AssertionCredentials(
$SERVICE_ACCOUNT_EMAIL,
array($DRIVE_SCOPE),
$key);
$client = new Google_Client();
$client->setUseObjects(true);
$client->setAssertionCredentials($auth);
return new Google_DriveService($client);
}
Retrieve Files
function retrieveAllFiles($service) {
$result = array();
$pageToken = NULL;
do {
try {
$parameters = array();
if ($pageToken) {
$parameters['pageToken'] = $pageToken;
}
$files = $service->files->listFiles($parameters);
$result = array_merge($result, $files->getItems());
$pageToken = $files->getNextPageToken();
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
$pageToken = NULL;
}
} while ($pageToken);
return $result;
}
Creating an instance and inserting
$service = buildService();
$file = new Google_DriveFile();
$file->setTitle('My document');
$file->setDescription('A test document');
$file->setMimeType('text/plain');
$data = "contents";
$createdFile = $service->files->insert($file, array('data' => $data,'mimeType' =>'text/plain',));
print_r($createdFile);
echo '<br>------<br>';
Retrieving files
$ret = retrieveAllFiles($service);
echo '<pre>';
print_r($ret);
As in the fist call i insert a file...
in the second call i am trying to list all files...
when i try to list i could see only the inserted file but not the others which i could see in my drive by logging into docs.google.com. i am already having 6 files online
as per the documentation i created service account with the private keys and the service account email.
so where will that file be store and how do i list all other files in the root of google drive?
You are inserting files in the application-owned account represented by the service account.
If you want to manage (insert/list/...) files in another domain user's Drive account, you'll have to perform Domain-wide delegation: https://developers.google.com/drive/delegation