I need a cron to run in my shared host which will scan my gmail account every 30 minutes and will reply all unread email using PHP
First I downloaded the apiclient with composer -> { "require": { "google/apiclient": "1.*" } } . Then I create the service account(https://console.developers.google.com/apis/credentials/serviceaccountkey?project=xxxxxx) and get a json file which has these values :
"type": "service_account",
"project_id": "xxxxxx",
"private_key_id": "xyxyxyxyyxyxy",
"private_key": "-----BEGIN PRIVATE KEY-----\ndddddddddddddddmr\n-----END PRIVATE KEY-----\n",
"client_email": "yy-yyy#zzzz-zzzzzz.iam.gserviceaccount.com",
"client_id": "11763887676776474",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/xxxx%40zzz-zzzzzz.iam.gserviceaccount.com"
Also made sure gmail api is enabled(from).
Now I wondering How I connect with gmail and just read the un-read email using php...
I was modifying a example code but stuck here($apiKey =)...
<?php
include_once "vendor/google/templates/base.php";
echo pageHeader("Simple API Access");
require_once realpath(dirname(__FILE__) . '/vendor/google/apiclient/src/Google/autoload.php');
$client = new Google_Client();
$client->setApplicationName("Gmail access test");
$apiKey = "<YOUR_API_KEY>"; // WHICH VALUE i SHOULD PUT HERE????.
// Warn if the API key isn't changed.
if (strpos($apiKey, "<") !== false) {
echo missingApiKeyWarning();
exit;
}
$client->setDeveloperKey($apiKey);
$service = new Google_Service_Books($client);
...
...
...
UPDATE : my updated code looks like this
<?php
require_once realpath(dirname(__FILE__) . '/vendor/google/apiclient/src/Google/autoload.php');
session_start();
$scopes = array(
Google_Service_Gmail::GMAIL_READONLY,
Google_Service_Gmail::GMAIL_COMPOSE,
Google_Service_Gmail::GMAIL_SEND,
Google_Service_Gmail::MAIL_GOOGLE_COM,
);
$client = new Google_Client();
$arDetails = $client->loadServiceAccountJson('99b15f1f2326.json', $scopes);
$client->setAssertionCredentials($arDetails);
$client->setScopes($scopes);
$fl = $client->getAuth()->isAccessTokenExpired() ;
if($fl) {
$client->getAuth()->refreshTokenWithAssertion($arDetails);
}
$client->setAccessType('offline');
$gmailService = new Google_Service_Gmail($client);
#$users = $gmailService->users;
$users = $gmailService->users_messages;
$optParams['maxResults'] = 5; // Return Only 5 Messages
$optParams['labelIds'] = 'INBOX'; // Only show messages in Inbox
$messages = $gmailService->users_messages->listUsersMessages('me',$optParams);
echo '<br/><pre>';
print_r($users);
print_r($messages);
----
---
---
But I am getting error -
PHP Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling GET https://www.googleapis.com/gmail/v1/users/me/messages?maxResults=5&labelIds=INBOX: (400) Bad Request' in /home3/shafico1/public_html/imsdev/frontend/web/atiq/vendor/google/apiclient/src/Google/Http/REST.php:110
Stack tra
Related
I've coded the script below. This code connects to a Gmail account, searches for emails with attachments, and saves the attachments to Google Drive. It also deletes the emails from the Gmail account.
But anytime I run it:
Fatal error: Uncaught Google\Service\Exception: { "error": { "errors": [ { "domain": "global", "reason": "required", "message": "Login Required", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Login Required" } }
I tried several changes. Nothing works. Even ChatGPT cannot find the fix/error.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Include the autoload file
require_once __DIR__ . '/vendor/autoload.php';
// Set your OAuth 2.0 Client IDs
$client_id = '123456789012-abcdefghijklmnopqrstuvwxyz.apps.googleusercontent.com';
$client_secret = 'ABC-XYZ_123';
// Set your redirect URI
$redirect_uri = 'https://example.com/invoices';
// Create a new Google_Client object
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
// Set the scopes for the API services you want to use
$client->addScope(Google_Service_Drive::DRIVE);
// Authorize the client
$client->authorize();
// Create a new Google_Service_Drive object
$driveService = new Google_Service_Drive($client);
// Connect to Gmail
$hostname = '{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX';
$username = 'email#gmail.com';
$password = 'password';
// Connect to Gmail
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
// Get all emails from inbox
$emails = imap_search($inbox,'ALL');
// If emails are returned
if($emails) {
// Sort emails by date
rsort($emails);
// Loop through emails
foreach($emails as $email_number) {
// Get the full header of the email
$header = imap_fetchheader($inbox, $email_number);
// Parse the header into an object
$header_obj = imap_rfc822_parse_headers($header);
// Get the original sender's name
$sender_name = $header_obj->from[0]->personal;
// Get the date the email was sent
$date_sent = strtotime($header_obj->date);
$formatted_date_sent = date("Y-m-d", $date_sent);
// Get the attachments
$attachments = imap_fetchstructure($inbox,$email_number);
// If attachments are found
if(isset($attachments->parts) && count($attachments->parts)) {
// Loop through attachments
for($i = 0; $i < count($attachments->parts); $i++) {
// Check if the attachment is an object
if (is_object($attachments->parts[$i])) {
// Get the attachment data
$attachment_data = imap_fetchbody($inbox,$email_number,$i+1);
// Decode the attachment data
$attachment_data = base64_decode($attachment_data);
// Create the filename
$filename = $formatted_date_sent . ' ' . $sender_name;
// Save the attachment to Google Drive
$file = new Google_Service_Drive_DriveFile();
$file->setName($filename);
$file->setDescription('Invoice attachment');
$file->setMimeType('application/pdf');
$file->setParents(array('1nkfPyEvFYR_DGUGJDiy8WLx_ANUNsAdW'));
$createdFile = $driveService->files->create($file, array(
'data' => $attachment_data,
'mimeType' => 'application/pdf',
'uploadType' => 'multipart'
));
}
}
}
// Delete the email
imap_delete($inbox,$email_number);
}
}
// Close the connection
imap_close($inbox);
?>
From what I can see you are simply creating a drive service object but not acutally calling any authorization on it.
// Create a new Google_Service_Drive object
$driveService = new Google_Service_Drive($client);
You need to request consent of the user who's drive account you want to write to. With out that your service object is not authorized and you will get a "Login Required" error messages becouse your not logged in.
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();
}
}
Code ripped from Oauth2Authentication.php
I need form PHP level, in background without user interaction login on google drive and get files list. I found similar topic and code for question working, but is required handly login, where I need login from php in background.
In second post with code for possibly login witout user interaction, but I don't know where is bug.
My code PHP:
<?php
require_once 'vendor/autoload.php';
require_once 'src/Google_Client.php';
require_once 'src/contrib/Google_DriveService.php';
require_once 'src/auth/Google_AssertionCredentials.php';
$client_email = 'xxxxxx#xxxxxxxxxxxxx.xxx.gserviceaccount.com';
$private_key = file_get_contents('key.p12');
$user_to_impersonate = 'xxxxxxxxxxxxxxx#gmail.com';
$scopes = array('https://www.googleapis.com/auth/drive');
$credentials = new Google_AssertionCredentials(
$client_email,
$scopes,
$private_key,
'notasecret', // Default P12 password
'http://oauth.net/grant_type/jwt/1.0/bearer', // Default grant type
$user_to_impersonate
);
$client = new Google_Client();
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion();
}
$service = new Google_Service_Drive($client);
$files = $service->files->listFiles();
echo "count files=".count($files)."<br>";
foreach( $files as $item ) {
echo "title=".$item['title']."<br>";
}
?>
Vendor directory I get from this instruction, and other files I get from this GitHub
I had problem with function Google_Auth_AssertionCredentials, PHP hasn't file with this function. I found that file src/auth/Google_AssertionCredentials.php has similar function Google_AssertionCredentials. I included Google_AssertionCredentials.php file and changed function name.
In finally I have new error:
PHP Fatal error: Cannot call constructor in
\google_drive\vendor\google\apiclient-services\src\Google\Service\Drive.php
on line 75
I don't know what doing again. I tried many other metod for login on google drive, eg. load file list GET method with API_KEY, or via json file.
As result I want get file list, download them. edit and upload.
Any sugestions?
EDIT:
I have part sucess. I found liblary this, and them work with this code:
<?php
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;
}
session_start();
require_once '/google-api-php-client/autoload.php';
$client_email = 'xxxx#xxxxx.iam.gserviceaccount.com';
$user_to_impersonate = 'xxxxxx#gmail.com';
$private_key = file_get_contents('key.p12');
$scopes = array('https://www.googleapis.com/auth/drive');
$credentials = new Google_Auth_AssertionCredentials(
$client_email,
$scopes,
$private_key,
'notasecret', // Default P12 password
'http://oauth.net/grant_type/jwt/1.0/bearer',
$user_to_impersonate
);
$client = new Google_Client();
if(isset($_SESSION['service_token'])==false && $_SESSION['service_token']=='') {
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($credentials);
}
$_SESSION['service_token'] = $client->getAccessToken();
}
if(isset($_SESSION['service_token']) && $_SESSION['service_token']) {
$client->setAccessToken($_SESSION['service_token']);
if ($client->isAccessTokenExpired()) {
$client->refreshToken($client->getRefreshToken());
$_SESSION['service_token'] = $client->getAccessToken();
}
$service = new Google_Service_Drive($client);
print_r(retrieveAllFiles($service));
}
?>
And in result I have only one file [originalFilename] => Getting started, this is PDF, but I don't see this file on Gogle dirve. On google drive I uploaded file: README.md.
I'm not sure, but maybe this file is on ` 'xxxx#xxxxx.iam.gserviceaccount.com' and script not logged to 'xxxxxx#gmail.com'?
I am trying to use google API to get events off calendars on an account. I am using a service account. I am receiving two errors when I attempt to manually echo the code or it will remain a blank page if I use foreach(...).
Here are the two errors:
Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling GET https://www.googleapis.com/calendar/v3/users/me/calendarList/primary: (404) Not Found' in C:\wamp\www\newOLP\scripts\oAuth2\Google\Http\REST.php on line 110
( ! ) Google_Service_Exception: Error calling GET https://www.googleapis.com/calendar/v3/users/me/calendarList/primary: (404) Not Found in C:\wamp\www\newOLP\scripts\oAuth2\Google\Http\REST.php on line 110
Here is my code:
require_once 'Google/autoload.php';
session_start();
/************************************************
The following 3 values an befound in the setting
for the application you created on Google
Developers console. Developers console.
The Key file should be placed in a location
that is not accessable from the web. outside of
web root.
In order to access your GA account you must
Add the Email address as a user at the
ACCOUNT Level in the GA admin.
************************************************/
$client_id = $jsonDecode['client_id'];
$Email_address = $jsonDecode['client_email'];
$key_file_location = 'privateKey.p12';
$client = new Google_Client();
$client->setApplicationName("CalCon");
$key = file_get_contents($key_file_location);
// separate additional scopes with a comma
$scopes ="https://www.googleapis.com/auth/calendar.readonly";
$cred = new Google_Auth_AssertionCredentials(
$Email_address,
array($scopes),
$key
);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$service = new Google_Service_Calendar($client);
?>
<html><body>
<?php
$calendarList = $service->calendarList->listCalendarList();
echo $service->calendars->get('primary')->getSummary()."<br />";
echo $service->calendarList->get('primary')->getSummary();
while(true) {
foreach ($calendarList->getItems() as $calendarListEntry) {
echo $calendarListEntry;
echo "hi";
echo $calendarListEntry->getSummary()."<br>\n";
// get events
$events = $service->events->listEvents($calendarListEntry->id);
foreach ($events->getItems() as $event) {
echo "-----".$event->getSummary()."<br>";
}
}
$pageToken = $calendarList->getNextPageToken();
if ($pageToken) {
$optParams = array('pageToken' => $pageToken);
$calendarList = $service->calendarList->listCalendarList($optParams);
} else {
break;
}
}
?>
</body></html>
I'm trying to connect to Gmail but server says:
Uncaught exception 'Google_Service_Exception' with message 'Error calling
GET https://www.googleapis.com/gmail/v1/users/{test}%40gmail.com/messages:
(400) Bad Request' in C:\...\google-api-php-client\src\Google\Http\REST.php on line 110
I can't seem to find the problem. Here's the code:
$google_accounts = $this->getGoogleAccounts();
if (count($google_accounts) > 0) {
require_once $_SERVER['DOCUMENT_ROOT'] . '/include/google-api-php-client/src/Google/autoload.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/include/google-api-php-client/src/Google/Client.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/include/google-api-php-client/src/Google/Service/Gmail.php';
$scopes = array(
'https://mail.google.com',
'https://www.googleapis.com/auth/gmail.readonly',
'https://www.googleapis.com/auth/gmail.modify',
);
$key_file_location = $_SERVER['DOCUMENT_ROOT'] . '/include/google-api-php-client/src/keys/';
foreach ($google_accounts as $one_account) {
if (!empty($one_account->client_id) && !empty($one_account->service_mail) && !empty($one_account->key_file)) {var_dump($one_account);
$key = file_get_contents($key_file_location . $one_account->key_file);
$client = new Google_Client();
$cred = new Google_Auth_AssertionCredentials($one_account->service_mail, $scopes, $key);
$client->setAssertionCredentials($cred);
$client->setClientId($one_account->client_id);
$client->setAccessType('offline_access');
$service = new Google_Service_Gmail($client);
$opt_param = array();
$messagesResponse = $service->users_messages->listUsersMessages($one_account->login, $opt_param);
var_dump($messagesResponse);
}
}
return $list;
}
else {
return false;
}
You need to add:
$cred->sub = $userEmail;
right after creating $cred where $userEmail is the email address of the user you are trying to impersonate. For reference, see the Google Drive Service Account documentation which uses a different scope and API call but is otherwise similar to what you'd want to do with Gmail API.
I'm trying to get access bigquery api using PHP library, but I always have this error:
Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling GET https://www.googleapis.com/bigquery/v2/projects/primeval-shadow-571/datasets/Test/tables: (401) Login Required' in ...
I have a web application, that needs to get some data from table in bigquery. The Remote account is not mine, but it was created by some guy (and I don't have login and pass to log in), who gave me the .json file which included thoose parameters:
auth_uri,
client_secret,
token_uri,
client_email,
client_x509_cert_url,
client_id and
auth_provider_x509_cert_url.
Here is my php code:
<?php
require_once 'Google/Client.php';
require_once 'Google/Service/Bigquery.php';
$client = new Google_Client();
$client->setAuthConfigFile('google-config.json');
$service = new Google_Service_Bigquery($client);
$service->tables->listTables('primeval-shadow-571', 'Test');
But finally I got error that's above.
Can anybody tell me where am I wrong?
P.S. I just started work with google api two days ago, so I'm just beginning learn it.
Thanks a lot.
Here is a sample code that works for us:
session_start();
define('PROJECT_ID', 'edited');
define('DATASET_ID', 'edited');
define('API_KEY', 'edited');
$client_id = 'edited';
$service_account_name = 'edited';
$key_file_location = '.ssh/privatekey-bigquery.p12';
$service_token_file_location = 'bigquery_current_service_token.json';
set_include_path("google-api-php/src/" . PATH_SEPARATOR . get_include_path());
require_once 'google-api-php/src/Google/Client.php';
require_once 'google-api-php/src/Google/Service/Bigquery.php';
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
//$client->setDeveloperKey(API_KEY);
if (!is_file($service_token_file_location)) {
if (!is_writable($service_token_file_location)) {
#chmod($service_token_file_location, 0777);
if (!is_writable($service_token_file_location)) {
die('Service token file is not writable: ' . $service_token_file_location);
}
}
file_put_contents($service_token_file_location, '');
} else {
if (!is_writable($service_token_file_location)) {
#chmod($service_token_file_location, 0777);
if (!is_writable($service_token_file_location)) {
die('Service token file is not writable: ' . $service_token_file_location);
}
}
}
$service_token = #file_get_contents($service_token_file_location);
if (!empty($service_token)) {
$client->setAccessToken($service_token);
}
if (!file_exists($key_file_location)) {
die('Key file is missing: ' . $key_file_location);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name, array(
'https://www.googleapis.com/auth/bigquery',
), $key
);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$service_token = $client->getAccessToken();
file_put_contents($service_token_file_location, $service_token);
// start using $client