【问题标题】:send email using gmail-api and google-api-php-client使用 gmail-api 和 google-api-php-client 发送电子邮件
【发布时间】:2014-09-16 10:30:26
【问题描述】:

我正在使用https://github.com/google/google-api-php-client,我想使用用户的授权 gmail 帐户发送测试电子邮件。

这是我目前所拥有的:

$msg = new Google_Service_Gmail_Message();  
$msg->setRaw('gp1');  
$service->users_messages->send('me', $msg);  

这会导致退回电子邮件,因为我不知道如何设置原始邮件。我在经过身份验证的用户的收件箱中看到了退回邮件。我想学习如何为电子邮件的“收件人”、“抄送”、“密送”、“主题”和“正文”设置值。我相信我也需要对这些原始数据进行 64 位编码。我可能想在我的电子邮件正文中使用一些 html。

请帮助提供一个使用 gmail-api 和 google-api-php-client 发送电子邮件的工作示例。

这是收件箱中退回的电子邮件:

Bounce -nobody@gmail.com- 12:58 PM(7 分钟前)
对我来说
发生错误。您的消息未发送。

‚ 日期:2014 年 7 月 24 日星期四 10:58:30 -0700 消息 ID:CABbXiyXhRBzzuaY82i9iODEiwxEJWO1=jCcDM_TH-

【问题讨论】:

    标签: google-api-php-client gmail-api


    【解决方案1】:

    我问了a more specific question,这让我得到了答案。我现在正在使用 PHPMailer 来构建消息。然后我从 PHPMailer 对象中提取原始消息。示例:

    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);
    

    【讨论】:

    【解决方案2】:

    我也使用过这个解决方案,经过一些调整后效果很好:

    创建 PHPMailer 对象时,默认编码设置为 '8bit'。 所以我不得不用以下方式推翻它:

    $mail->Encoding = 'base64';
    

    我必须做的另一件事是稍微调整 MIME 以使其 POST 为 Google API 做好准备,我使用了 ewein 的解决方案:

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

    不管怎样,我就是这样解决你的问题的:

    //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);
    

    【讨论】:

      【解决方案3】:

      在本地环境中使用 phpmailer 创建邮件对我来说效果很好。在生产中我收到此错误:

      Invalid value for ByteString
      

      要解决这个问题,请删除以下行:

      $mail->Encoding = 'base64';
      

      因为邮件被两次编码。

      另外,关于其他问题/问题,我发现了下一个:

      使用

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

      而不是

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

      【讨论】:

      • 确切错误:Error calling POST https://www.googleapis.com/gmail/v1/users/me/messages/send: (400) Invalid value for ByteString
      【解决方案4】:

      我用过https://developers.google.com/gmail/api/v1/reference/users/messages/send

      并且能够成功发送电子邮件。

      【讨论】:

      • 放链接而不是解释是一种不好的风格。请在此处描述解决方案。
      【解决方案5】:

      也许这有点超出最初的问题,但至少在我的情况下,“测试电子邮件”已经发展为定期“从”各个帐户发送自动欢迎电子邮件。虽然我在这里找到了很多有用的东西,但我不得不从各种来源拼凑起来。

      为了帮助其他人完成这个过程,这里是我提出的一个提炼版本。

      以下代码的几点说明:

      1. 这假设您已经完成了为 Google 服务帐户创建和下载 JSON 的过程(在 developer dashboard 的凭据下,它位于底部。)
      2. 为清楚起见,我将您需要在“用您自己的数据替换”部分中设置的所有位进行了分组。
      3. send() 方法中的 me 是一个关键字,意思是“使用当前帐户发送此电子邮件”。
      // 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...";
      
      

      【讨论】:

        猜你喜欢
        • 2017-04-14
        • 2014-10-30
        • 2017-05-25
        • 2017-12-19
        • 1970-01-01
        • 2018-01-26
        • 2014-08-27
        • 2018-08-20
        • 2021-09-11
        相关资源
        最近更新 更多