2

I am supposed to replace the mailing service from an old project to GMail. However, the project is using PHP and the documentation for the PHP code is not yet available in the google documentation page. I wanted to test sending an e-mail with a simple mail body, here is the code:

require_once __DIR__."/google-api-php-client-2.2.1/vendor/autoload.php";

define("APPLICATION_NAME", "Gmail API PHP Quickstart");
define("CREDENTIALS_PATH", "~/.credentials/gmail-php-quickstart.json");
define("CLIENT_SECRET_PATH", __DIR__."/client_secret.json");

// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/gmail-php-quickstart.json
define('SCOPES', implode(' ', array(
    Google_Service_Gmail::GMAIL_READONLY)
));

date_default_timezone_set('America/New_York'); // Prevent DateTime tz exception
/*
if (php_sapi_name() != 'cli') {
    throw new Exception('This application must be run on the command line.');
}
*/

/**
* Returns an authorized API client.
* @return Google_Client the authorized client object
*/
function getClient() {
    $client = new Google_Client();
    $client->setApplicationName(APPLICATION_NAME);
    $client->setScopes(SCOPES);
    $client->setAuthConfig(CLIENT_SECRET_PATH);
    $client->setAccessType('offline');

    // Load previously authorized credentials from a file.
    $credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
    if (file_exists($credentialsPath)) {
        $accessToken = json_decode(file_get_contents($credentialsPath), true);
    }
    else {
        // Request authorization from the user.
        $authUrl = $client->createAuthUrl();
        printf("Open the following link in your browser:\n%s\n", $authUrl);
        print 'Enter verification code: ';
        $authCode = trim(fgets(STDIN));

        // Exchange authorization code for an access token.
        $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);

        // Store the credentials to disk.
        if(!file_exists(dirname($credentialsPath))) {
            mkdir(dirname($credentialsPath), 0700, true);
        }
        file_put_contents($credentialsPath, json_encode($accessToken));
        printf("Credentials saved to %s\n", $credentialsPath);
    }
    $client->setAccessToken($accessToken);

    // Refresh the token if it's expired.
    if ($client->isAccessTokenExpired()) {
        $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
        file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
    }
    return $client;
}

/**
* Expands the home directory alias '~' to the full path.
* @param string $path the path to expand.
* @return string the expanded path.
*/
function expandHomeDirectory($path) {
    $homeDirectory = getenv('HOME');
    if (empty($homeDirectory)) {
        $homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');
    }
    return str_replace('~', realpath($homeDirectory), $path);
}

// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Gmail($client);

// Print the labels in the user's account.
$user = 'me';
$message = new Google_Service_Gmail_Message();
$messagePart = new Google_Service_Gmail_MessagePart();
$messagePartBody = new Google_Service_Gmail_MessagePartBody();
$messagePartHeader = new Google_Service_Gmail_MessagePartHeader();

$messagePartBody->setData("TEST BY FAROUK");

$messagePart->setHeader($messagePartHeader);
$messagePart->setBody($messagePartBody);
$message->setPayLoad($messagePart);

$service->users_messages->send($user, $message, null);

The problem lies in this part, which is not finished yet:

$user = 'me';
$message = new Google_Service_Gmail_Message();
$messagePart = new Google_Service_Gmail_MessagePart();
$messagePartBody = new Google_Service_Gmail_MessagePartBody();
$messagePartHeader = new Google_Service_Gmail_MessagePartHeader();

$messagePartBody->setData("TEST BY ME");

$messagePart->setHeader($messagePartHeader);
$messagePart->setBody($messagePartBody);
$message->setPayLoad($messagePart);

$service->users_messages->send($user, $message, null);

I know I have to create object of those classes but, I don't know what kind of data I should set in the parameter using the setters of them.

Please give a simple code to send "Hello world!" to an e-mail address like foo@gmail.com. Thanks!

Logos
  • 334
  • 1
  • 7
  • 17
  • Please check this link : https://www.w3schools.com/php/func_mail_mail.asp and use the mail function . This is the simplest way of emailing. – Lalbhusan Yadav Mar 12 '18 at 10:21
  • https://developers.google.com/gmail/api/quickstart/php – Masivuye Cokile Mar 12 '18 at 10:25
  • @LalbhusanYadav, the client wants us to use GMail API. – Logos Mar 12 '18 at 10:30
  • @MasivuyeCokile, that page only gives the example on how to list the labels in the client mail. I've read that page and am using it to create the client object. – Logos Mar 12 '18 at 10:32
  • So your asking how to use an undocumented API? Tell client it's not documented and charge more for waist of time. – marshal craft Mar 12 '18 at 10:33
  • I'm not sure myself @marshalcraft, which is why I am asking. Has anyone been using this API before? – Logos Mar 12 '18 at 10:35
  • If you get something working how do you know it is right and not going to fail at some point? The documentation is also assurance your software works correctly to some extent. Otherwise you are being paid to hack together something based off of info from stack exchange ?!?! – marshal craft Mar 12 '18 at 10:39
  • 1
    @Logos What exactly is undocumented about this API? PHP reference: https://developers.google.com/resources/api-libraries/documentation/gmail/v1/php/latest/ And overall tutorials for creating emails and sending them: https://developers.google.com/gmail/api/guides/sending – Loek Mar 12 '18 at 10:43
  • @Loek, there are no clear explanations on what the methods parameter can accept and what it returns. Look at the `Google_Service_Gmail_Message` class for example at https://developers.google.com/resources/api-libraries/documentation/gmail/v1/php/latest/class-Google_Service_Gmail_Message.html – Logos Mar 12 '18 at 10:49
  • i dont think readonly scope is going to let you send emails. gmail api and php are quite well documented if you look https://developers.google.com/gmail/api/quickstart/php – Linda Lawton - DaImTo Mar 12 '18 at 10:49
  • @Loek, the link you gave me is for Java and Python, not PHP – Logos Mar 12 '18 at 10:51
  • 1
    @Logos I honestly don't know what's unclear about it. Also, the fact that the tutorial is in Java, doesn't mean that you can't rewrite it to PHP. Take a look at what the tutorial says and see if you can find the corresponding classes in the PHP client. Google is one of those companies you can trust on keeping their clients uniform. Java is a different syntax, but that's probably the only difference. Don't be one of those "It's not written in my favorite language, so it can't possibly work" programmers ;) – Loek Mar 12 '18 at 10:52
  • One of the attribute in `Google_Client` class is `$users_messages` which type is `Google_Service_Gmail_Resource_UsersMessages` that have the `public function send($userId, Google_Service_Gmail_Message $postBody, $optParams = array())` method. Which means I must create `Google_Service_Gmail_Message` object to use the `send()` method. The documentation does not even tell what the attributes in `Google_Service_Gmail_Message` class for and what options that `$optParams` accept – Logos Mar 12 '18 at 11:16
  • Possible duplicate of [How do I send email using gmail api php](https://stackoverflow.com/questions/24606988/how-do-i-send-email-using-gmail-api-php) – Francisco Luz Jun 20 '18 at 08:39

1 Answers1

6

This working example is using a service account, please adjust to suit your needs:

    $user_to_impersonate = "email_to_impersonate@yourdomain.com";
    putenv("GOOGLE_APPLICATION_CREDENTIALS=google-api-php-client/service-account-credentials.json");
    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();
    $client->setSubject($user_to_impersonate);
    $client->setApplicationName("My Mailer");
    $client->setScopes(["https://www.googleapis.com/auth/gmail.compose"]);
    $service = new Google_Service_Gmail($client);
    // Process data
    try {
        $strSubject = "Set the email subject here";
        $strRawMessage = "From: Me<myemail@mydomain.com>\r\n";
        $strRawMessage .= "To: Foo<foo@gmail.com>\r\n";
        $strRawMessage .= "CC: Bar<bar@gmail.com>\r\n";
        $strRawMessage .= "Subject: =?utf-8?B?" . base64_encode($strSubject) . "?=\r\n";
        $strRawMessage .= "MIME-Version: 1.0\r\n";
        $strRawMessage .= "Content-Type: text/html; charset=utf-8\r\n";
        $strRawMessage .= "Content-Transfer-Encoding: base64" . "\r\n\r\n";
        $strRawMessage .= "Hello World!" . "\r\n";
        // The message needs to be encoded in Base64URL
        $mime = rtrim(strtr(base64_encode($strRawMessage), '+/', '-_'), '=');
        $msg = new Google_Service_Gmail_Message();
        $msg->setRaw($mime);
        //The special value **me** can be used to indicate the authenticated user.
        $service->users_messages->send("me", $msg);
    } catch (Exception $e) {
        print "An error occurred: " . $e->getMessage();
    }

Hope this helps to get you started

EDIT

Further help https://stackoverflow.com/a/37256138/9482295

trueChazza
  • 489
  • 2
  • 8
  • Can you kindly explain what this part for? `$mime = rtrim(strtr(base64_encode($strRawMessage), '+/', '-_'), '=');` – Logos Mar 13 '18 at 03:15
  • How do I create `service-account-credentials.json` file? What is the content of the file? – Logos Mar 13 '18 at 03:57
  • 1
    you will need to implement your own authentication flow, depending on your application needs. Start here https://developers.google.com/identity/protocols/OAuth2 – trueChazza Mar 13 '18 at 04:26
  • 1
    I modified the credentials and deleted the file in `Users/MyUser/.credentials`, now it worked! Thank you! – Logos Mar 13 '18 at 06:32