I expected the code below to send an email, but I\'m only getting this:
An error occurred: Error calling POST https://www.googleapis.com/gmail/v1/us
use URL Endocde in string and url.
This error is space in url.
This is a full working example, just make sure to change all the appropriate info and use PHPMailer to format a valid mail.
<?php
// this the link to gmail-api-client or whatever you have...
require 'vendor/autoload.php';
// download PHPMailer
// https://github.com/PHPMailer/PHPMailer and uncomment the line below.
// require 'PHPMailer/PHPMailerAutoload.php';
define('FROM', 'aseptik@gmail.com'); //email of sender
define('TO', 'XXXXXXX@XXXXX.com');//email of receiver
$client_email = 'XXXXX@developer.gserviceaccount.com';
$private_key = file_get_contents('tmp/XXXXXXX.p12');
$scopes = array(
'https://www.googleapis.com/auth/gmail.send',
'https://www.googleapis.com/auth/gmail.compose'
);
$credentials = new \Google_Auth_AssertionCredentials($client_email, $scopes, $private_key);
$credentials->sub = FROM;
$client = new Google_Client();
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion();
}
function create_message() {
$mail = new PHPMailer();
$mail->setFrom(FROM, 'John Doe 1');
$mail->addAddress(TO, 'John Doe 2');
$mail->Subject = 'Saying Hello';
$mail->Body = 'This is a message just to say hello. So, "Hello"';
$mail->preSend();
$mime = $mail->getSentMIMEMessage();
return urlsafe_b64encode($mime);
}
function sendMessage($service, $userId, $message) {
try {
$message = $service->users_messages->send($userId, $message);
print 'Message with ID: ' . $message->getId() . ' sent.';
return $message;
}
catch(Exception $e) {
print 'An error occurred: ' . $e->getMessage();
}
}
function urlsafe_b64encode($string) {
$data = base64_encode($string);
$data = str_replace(array('+','/','=') , array('-','_','') , $data);
return $data;
}
$service = new \Google_Service_Gmail($client);
$msg = new \Google_Service_Gmail_Message();
$msg->setRaw(create_message());
sendMessage($service, 'me', $msg);
?>
finally got to send Mails with your code:
I think you have misunderstood the GMail API a little bit.
To use it, you must authenticate to the API. To do this, there are two ways:
So what you're currently trying is to send mails from the service account, but this is not an GMail Account.
The Developer Console uses the OAuth method, so there's no problem to try this.
Please also note: With regular GMail Accounts, you can not use 'Service Accounts'. You'll have to use OAuth. To use Service Accounts, you need to be a Google Apps customer.
I won't conver OAuth authorization here, because it's completely different, and there are many examples out there.
To grant your Service Account Permissions to send mails on behalf of your GMails/Google Apps accounts, please follow
this document. For One or More API Scopes
, you'll have to enter
https://mail.google.com/,https://www.googleapis.com/auth/gmail.modify,https://www.googleapis.com/auth/gmail.compose,https://www.googleapis.com/auth/gmail.send
.
After you've setup this, it's possible to send mails, just modify the code as follows:
$results = $service->users_messages->send("me", $msg);
won't work, because 'me' referrs to the service account, which can't send mail (see above).
Replace me
with the user id (mail-address) of the account from which the mails should be send.:
$results = $service->users_messages->send("senders_mail@domain.com", $msg);
Then, you'll need to add
$cred->sub = 'senders_mail@domain.com';
below
$cred = new \Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/gmail.send', 'https://www.googleapis.com/auth/gmail.compose'),
$key
);
Please also note that $message
should be $msg
in the try...catch
-Block.
Below, you'll find the the complete, working code for me:
<?php
require_once realpath(dirname(__FILE__) . '/../src/Google/autoload.php');
$client_id = '*censored*.apps.googleusercontent.com';
$service_account_name = '*censored*@developer.gserviceaccount.com';
$key_file_location = '/tmp/apiKey.p12';
$userid_from='*censored*';
$client = new \Google_Client();
$client->setApplicationName("Client_Library_Examples");
//hmmm, really don't know whether these lines are necessary
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new \Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/gmail.send', 'https://www.googleapis.com/auth/gmail.compose', 'https://www.googleapis.com/auth/gmail.modify','https://www.googleapis.com/auth/gmail.readonly'),
$key
);
$cred->sub=$userid_from; //<-- Important!
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
//check if you want the validity of this string at: http://www.komeil.com/toolbox/base64decoder
//it is web safe base64 encoded email
$mime = "*censored*, same content as you posted, but another recipient ;-)";
$service = new \Google_Service_Gmail($client);
$msg = new \Google_Service_Gmail_Message();
$msg->setRaw($mime);
try {
$results = $service->users_messages->send($userid_from, $msg);
print 'Message with ID: ' . $results->id . ' sent.';
} catch (\Exception $e) {
print 'An error occurred: ' . $e->getMessage();
}
If there are any questions left, feel free to ask!
One thing that I needed to get my service account client working that wasn't obvious was adding this:
// you MUST do this to avoid 400 error
$user_to_impersonate = 'junk@example.net';
$client->setSubject($user_to_impersonate);
I think you are forgetting to assign the $client_id
to your $client
variable.
$client = new Google_Client();
$client->setApplicationName('Gmail API test');
$client->setDeveloperKey('<YOUR_API_KEY>');
$client->setClientSecret('<YOUR_CLIENT_SECRET>');
$client->SetClientId('599901532082-js1r50n20q6n5mir9fo1g81qkj9kfn3j.apps.googleusercontent.com');
$client->setScopes(array('https://www.googleapis.com/auth/gmail.send'));
$client->setAccessToken('{"access_token":"<YOUR_ACCESS_TOKEN>",
"token_type":"Bearer","expires_in":3600,
"refresh_token":"<YOUR_REFRESH_TOKEN>","created":12344556}');
$service = new Google_Service_Gmail($client);
$raw = "RnJvbTogSm9obiBEb2UgPHRpcmVuZ2FyZmlvQGdtYWlsLmVzPiANClRvOiBNYXJ5IFNtaXRoIDx0aXJlbmdhcmZpb0BnbWFpbC5jb20-IA0KU3ViamVjdDogU2F5aW5nIEhlbGxvIA0KRGF0ZTogRnJpLCAyMSBOb3YgMTk5NyAwOTo1NTowNiAtMDYwMCANCk1lc3NhZ2UtSUQ6IDwxMjM0QGxvY2FsLm1hY2hpbmUuZXhhbXBsZT4NCg0KVGhpcyBpcyBhIG1lc3NhZ2UganVzdCB0byBzYXkgaGVsbG8uIFNvLCAiSGVsbG8iLg==";
$msg = new Google_Service_Gmail_Message();
$msg->setRaw($raw);
$results = $service->users_messages->send("me", $msg);
print 'Message with ID: ' . $message->getId() . ' sent.';