send email using gmail-api and google-api-php-client

后端 未结 5 1359
感动是毒
感动是毒 2021-01-16 03:24

I am using https://github.com/google/google-api-php-client and I want to send a test email with a user\'s authorized gmail account.

This is what I have so far:

相关标签:
5条回答
  • 2021-01-16 04:01

    Perhaps this is a bit beyond the original question, but at least in my case that "test email" progressed to regularly sending automated welcome emails "from" various accounts. Though I've found much that is helpful here, I've had to cobble things together from various sources.

    In the hope of helping others navigate this process, here's a distilled version of what I came up with.

    A few notes on the following code:

    1. This assumes that you've jumped through the hoops to create and download the JSON for a Google Service Account (under credentials in the developer dashboard it's the bottom section.)
    2. For clarity, I've grouped all the bits you should need to set in the "Replace this with your own data" section.
    3. That me in the send() method is a key word that means something like "send this email with the current account."
    // This block is only needed if you're working outside the global namespace
    use \Google_Client as Google_Client;
    use \Google_Service_Gmail as Google_Service_Gmail;
    use \Google_Service_Gmail_Message as Google_Service_Gmail_Message;
    
    // Prep things for PHPMailer
    use PHPMailer\PHPMailer\Exception;
    use PHPMailer\PHPMailer\PHPMailer;
    
    // Grab the needed files
    require_once 'path/to/google-api/vendor/autoload.php';
    require_once 'path/to/php-mailer/Exception.php';
    require_once 'path/to/php-mailer/PHPMailer.php';
    
    // Replace this with your own data
    $pathToServiceAccountCredentialsJSON = "/path/to/service/account/credentials.json";
    $emailUser = "sender@yourdomain.com"; // the user who is "sending" the email...
    $emailUserName = "Sending User's Name"; // ... and their name
    $emailSubjectLine = "My Email's Subject Line";
    $recipientEmail = "recipient@somdomain.com";
    $recipientName = "Recipient's Name";
    $bodyHTML = "<p>Paragraph one.</p><p>Paragraph two!</p>";
    $bodyText = "Paragraph one.\n\nParagraph two!";
    
    // Set up credentials and client
    putenv("GOOGLE_APPLICATION_CREDENTIALS={$pathToServiceAccountCredentialsJSON}");
    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();
    // We're only sending, so this works fine
    $client->addScope(Google_Service_Gmail::GMAIL_SEND);
    // Set the user we're going to pretend to be (Subject is confusing here as an email also has a "Subject"
    $client->setSubject($emailUser);
    
    // Set up the service
    $mailService = new Google_Service_Gmail($client);
    
    // We'll use PHPMailer to build the raw email (since Google's API doesn't do that) so prep it
    $mailBuilder = new PHPMailer();
    $mailBuilder->CharSet = "UTF-8";
    $mailBuilder->Encoding = "base64";
    
    // Not set up the email you want to send
    $mailBuilder->Subject = $emailSubjectLine;
    $mailBuilder->From = $emailUser;
    $mailBuilder->FromName = $emailUserName;
    try {
        $mailBuilder->addAddress($recipientEmail, $recipientName);
    } catch (Exception $e) {
        // Handle any problems adding the email address here
    }
    // Add additional recipients, CC, BCC, ReplyTo, if desired
    
    // Then add the main body of the email...
    $mailBuilder->isHTML(true);
    $mailBuilder->Body = $bodyHTML;
    $mailBuilder->AltBody = $bodyText;
    
    // Prep things so we have a nice, raw message ready to send via Google's API
    try {
        $mailBuilder->preSend();
        $rawMessage = base64_encode($mailBuilder->getSentMIMEMessage());
        $rawMessage = str_replace(['+', '/', '='], ['-', '_', ''], $rawMessage); // url safe
        $gMessage = new Google_Service_Gmail_Message();
        $gMessage->setRaw($rawMessage);
        // Send it!
        $result = $mailService->users_messages->send('me', $gMessage);
    } catch (Exception $e) {
        // Handle any problems building or sending the email here
    }
    
    if ($result->labelIds[0] == "SENT") echo "Message sent!";
    else echo "Something went wrong...";
    
    
    0 讨论(0)
  • 2021-01-16 04:03

    I Used https://developers.google.com/gmail/api/v1/reference/users/messages/send

    and able to send email successfully.

    0 讨论(0)
  • 2021-01-16 04:07

    I asked a more specific question which has led me to an answer. I am now using PHPMailer to build the message. I then extract the raw message from the PHPMailer object. Example:

    require_once 'class.phpmailer.php';
    $mail = new PHPMailer();
    $mail->CharSet = "UTF-8";
    $subject = "my subject";
    $msg = "hey there!";
    $from = "myemail@gmail.com";
    $fname = "my name";
    $mail->From = $from;
    $mail->FromName = $fname;
    $mail->AddAddress("tosomeone@somedomain.com");
    $mail->AddReplyTo($from,$fname);
    $mail->Subject = $subject;
    $mail->Body    = $msg;
    $mail->preSend();
    $mime = $mail->getSentMIMEMessage();
    $m = new Google_Service_Gmail_Message();
    $data = base64_encode($mime);
    $data = str_replace(array('+','/','='),array('-','_',''),$data); // url safe
    $m->setRaw($data);
    $service->users_messages->send('me', $m);
    
    0 讨论(0)
  • 2021-01-16 04:10

    Create the mail with phpmailer works fine for me in a local enviroment. On production I get this error:

    Invalid value for ByteString
    

    To solve this, remove the line:

    $mail->Encoding = 'base64';
    

    because the mail is two times encoded.

    Also, on other questions/issues I found the next:

    use

    strtr(base64_encode($val), '+/=', '-_*')
    

    instead of

    strtr(base64_encode($val), '+/=', '-_,')
    
    0 讨论(0)
  • 2021-01-16 04:18

    I've used this solution as well, worked fine with a few tweaks:

    When creating the PHPMailer object, the default encoding is set to '8bit'. So I had to overrule that with:

    $mail->Encoding = 'base64';
    

    The other thing i had to do was tweaking the MIME a little to make it POST ready for the Google API, I've used the solution by ewein:

    Invalid value for ByteString error when calling gmail send API with base64 encoded < or >

    Anyway, this is how I've solved your problem:

    //prepare the mail with PHPMailer
    $mail = new PHPMailer();
    $mail->CharSet = "UTF-8";
    $mail->Encoding = "base64";
    
    //supply with your header info, body etc...
    $mail->Subject = "You've got mail!";
    ...
    
    //create the MIME Message
    $mail->preSend();
    $mime = $mail->getSentMIMEMessage();
    $mime = rtrim(strtr(base64_encode($mime), '+/', '-_'), '=');
    
    //create the Gmail Message
    $message = new Google_Service_Gmail_Message();
    $message->setRaw($mime);
    $message = $service->users_messages->send('me',$message);
    
    0 讨论(0)
提交回复
热议问题