Php 如何使用Gmail API发送邮件回复

Php 如何使用Gmail API发送邮件回复,php,gmail-api,Php,Gmail Api,我正在使用gmail API发送电子邮件。在此情况下,发送已成功完成。我想知道如何回复那个人(谁已经发送)使用php 在此附上我的发送代码: $line = "\n"; $strMailContent = $message; $strMailTextVersion = strip_tags($strMailContent, ''); $strRawMessage = ""; $boundary = uniqid(rand(), true); $subjectCharset = $charset

我正在使用gmail API发送电子邮件。在此情况下,发送已成功完成。我想知道如何回复那个人(谁已经发送)使用php

在此附上我的发送代码:

$line = "\n";
$strMailContent = $message;
$strMailTextVersion = strip_tags($strMailContent, '');

$strRawMessage = "";
$boundary = uniqid(rand(), true);
$subjectCharset = $charset = 'utf-8';

$strToMail = $to;

$strSubject = $subject;

$strRawMessage .= 'To: ' . ($strToMail)  . "\r\n";

if(!empty($_POST['cc']) || !empty($_POST['bcc'])){
    $cc = $_POST['cc'];
    $bcc = $_POST['bcc'];
    $strRawMessage .= "Cc: $cc". $line;
    $strRawMessage .= "Bcc: $bcc". $line;
}

$strRawMessage .= 'Subject: =?' . $subjectCharset . '?B?' . base64_encode($strSubject) . "?=\r\n";
$strRawMessage .= 'MIME-Version: 1.0' . "\r\n";
$strRawMessage .= 'Content-type: Multipart/Mixed; boundary="' . $boundary . '"' . "\r\n";



$filePath = $file_tmp_name;
$mimeType =  'text/plain; charset="UTF-8" ';
$fileName = $file_name;
$fileData = base64_encode(file_get_contents($filePath));

$strRawMessage .= "\r\n--{$boundary}\r\n";
$strRawMessage .= 'Content-Type: '. $mimeType .'; name="'. $fileName .'";' . "\r\n";            
$strRawMessage .= 'Content-Description: ' . $fileName . ';' . "\r\n";
$strRawMessage .= 'Content-Disposition: attachment; filename="' . $fileName . '"; size=' . filesize($filePath). ';' . "\r\n";
$strRawMessage .= 'Content-Transfer-Encoding: base64' . "\r\n\r\n";
$strRawMessage .= chunk_split(base64_encode(file_get_contents($filePath)), 76, "\n") . "\r\n";
$strRawMessage .= '--' . $boundary . "\r\n";



$strRawMessage .= $strMailContent;

$mime = rtrim(strtr(base64_encode($strRawMessage), '+/', '-_'), '=');

$base64 = base64_encode($mime);
$data = '{ "raw" : "'.$mime.'" }';
$send = Qassim_HTTP(1, $url, $header, $data);
在这里,我将收件人地址作为已发送的个人邮件id传递,并且主题已被用作主题


如何更改此代码以发送回复。请帮助我

您需要传递要回复的邮件的线程id,并为新邮件设置相同的主题。我更喜欢使用一些库来生成消息的原始字符串,而不是手动编写,以尽量减少出错的可能性。下面是一个使用PHPMailer的示例

$gmail = new Google_Service_Gmail($client);
$message = new Google_Service_Gmail_Message();
$optParam = array();
$referenceId = '';
$thread = $gmail->users_threads->get($userId, $threadId);
$optParam['threadId'] = $threadId;
$threadMessages = $thread->getMessages($optParam);
$messageId = $threadMessages[0]->getId();
$messageDetails = $this->getMessageDetails($messageId); //omitted for simplicity: returns prepared message data.
$messageDetails = $messageDetails['data'];
$subject = $messageDetails['headers']['Subject'];
$mail = new PHPMailer();
$mail->CharSet = 'UTF-8';
$mail->From = $from_email;
$mail->FromName = $from_name;
$mail->addAddress($to);
$mail->Subject = $subject;
$mail->Body = $body;
$mail->preSend();
$mime = $mail->getSentMIMEMessage();
$raw = $this->Base64UrlEncode($mime); //omitted for simplicity: Encodes the data in base 64 format for sending.
$message->setRaw($raw);
$message->setThreadId($threadId);
$response = $gmail->users_messages->send($userId, $message);
userId
是登录用户的id,而
threadId
是您要回复的消息的线程的id


我在使用Google的PHPSDK时遇到了很多困难,并且缺少合适的示例,因此我编写了一个PHP包装器,涵盖了Gmail API的大部分功能。它涵盖了上面的解释,如果你深入研究,你会发现上面例子中省略的逻辑。您可以找到它。

您需要传递要回复的邮件的线程id,并为新邮件设置相同的主题。我更喜欢使用一些库来生成消息的原始字符串,而不是手动编写,以尽量减少出错的可能性。下面是一个使用PHPMailer的示例

$gmail = new Google_Service_Gmail($client);
$message = new Google_Service_Gmail_Message();
$optParam = array();
$referenceId = '';
$thread = $gmail->users_threads->get($userId, $threadId);
$optParam['threadId'] = $threadId;
$threadMessages = $thread->getMessages($optParam);
$messageId = $threadMessages[0]->getId();
$messageDetails = $this->getMessageDetails($messageId); //omitted for simplicity: returns prepared message data.
$messageDetails = $messageDetails['data'];
$subject = $messageDetails['headers']['Subject'];
$mail = new PHPMailer();
$mail->CharSet = 'UTF-8';
$mail->From = $from_email;
$mail->FromName = $from_name;
$mail->addAddress($to);
$mail->Subject = $subject;
$mail->Body = $body;
$mail->preSend();
$mime = $mail->getSentMIMEMessage();
$raw = $this->Base64UrlEncode($mime); //omitted for simplicity: Encodes the data in base 64 format for sending.
$message->setRaw($raw);
$message->setThreadId($threadId);
$response = $gmail->users_messages->send($userId, $message);
userId
是登录用户的id,而
threadId
是您要回复的消息的线程的id


我在使用Google的PHPSDK时遇到了很多困难,并且缺少合适的示例,因此我编写了一个PHP包装器,涵盖了Gmail API的大部分功能。它涵盖了上面的解释,如果你深入研究,你会发现上面例子中省略的逻辑。你可以找到它。

上面来自@trajchevska的答案非常好,我很高兴我找到了它(!)-但它不会“揭示全部真相”。因此,我试图将我的见解整合在一起,创建一个应该可以正常工作的片段

$user = 'me'; // or user@example.com
$emailId = 12301839123180983123;
$from = 'johndoe@foobar.com';
$fromName = 'John Doe';

// this is for first authentification of this app to the Google-universe in general
$client = getClient();

// an this is to actually start working with Gmail
$googleService = new Google_Service_Gmail($client);

try {

    // receive the message body and extract it's headers
    $message = $googleService->users_messages->get($user, $emailId);
    $messageDetails = $message->getPayload();
    $messageHeaders = $messageDetails->getHeaders();

    // get the subject from the original message header
    $subject = 'Re:'.$getMessageHeaderValue($messageHeaders, 'Subject');

    // if you use the from header, this may contain the complete email address like John Doe <john.doe@foobar.com> - phpMailer will not accept that, the tricky thing is: you will not notice it, because it will be left blank and the Gmail API will return an "Recipient address required"
    preg_match('/.*<(.*@.*)>/', $getMessageHeaderValue($messageHeaders, 'From'),$to);

    // now use the PHPMailer to build a valid email-body
    $mail = new PHPMailer();
    $mail->CharSet = 'UTF-8';
    $mail->From = $from;
    $mail->FromName = $fromName;
    $mail->addAddress($to[1]);
    $mail->Subject = $subject;
    $mail->Body = $body;
    // preSend will build and verify the email
    $mail->preSend();

    $mime = $mail->getSentMIMEMessage();
    // the base64-url-encode is important, otherwise you'll receive an "Invalid value for ByteString" error
    $raw = base64url_encode($mime);

    // now use the Gmail-Message object to actually 
    // for me it is not clear, why we cannot use Class Google_Service_Gmail for this
    $message = new Google_Service_Gmail_Message();

    $message->setRaw($raw);

    $message->setThreadId($emailId);

    // and finally provide encoded message and user to our global google service object - this will send the email
    $response = $googleService->users_messages->send($user, $message);

} catch (Exception $e) {

    print($e->getMessage());

}

function getMessageHeaderValue($headers, $headerName) {

        foreach ($headers as $header) {

            if ($header->name == $headerName) {

                return $header->value;

            }
        }

        return NULL;
    }

// this function comes from https://developers.google.com/people/quickstart/php
/**
 * Returns an authorized API client.
 * @return Google_Client the authorized client object
 */
function getClient()
{
    // first get a credentials.json from here:
    // https://console.developers.google.com/apis/
    //
    // if you change scope or before first use, run the script on CLI
    // it will return an URL that you need to call 
    // which will return an access token that you can use for future use
    $client = new Google_Client();
    $client->setApplicationName('Gmail API');

    // see scopes: https://developers.google.com/gmail/api/auth/scopes
    $client->setScopes(array(Google_Service_Gmail::GMAIL_READONLY,Google_Service_GMail::GMAIL_COMPOSE));

    $client->setAuthConfig('credentials.json');

    $client->setAccessType('offline');

    // Load previously authorized credentials from a file.
    $credentialsPath = 'token.json';
    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;
}

function base64url_encode($mime) {
    return rtrim(strtr(base64_encode($mime), '+/', '-_'), '=');
}
$user='me';//或user@example.com
$emailId=12301839123180983123;
$fromjohndoe@foobar.com';
$fromName='johndoe';
//这是首次向Google universe认证此应用程序
$client=getClient();
//这是一个真正开始使用Gmail的方法
$googleService=新的Google\u服务\u Gmail($client);
试一试{
//接收消息正文并提取其标题
$message=$googleService->users\u messages->get($user,$emailId);
$messageDetails=$message->getPayload();
$messageHeaders=$messageDetails->getHeaders();
//从原始消息头获取主题
$subject='Re:'。$getMessageHeaderValue($messageHeaders,'subject');
//如果你使用from头,它可能包含完整的电子邮件地址,比如johndoe-phpMailer不会接受它,棘手的是:你不会注意到它,因为它将留空,Gmail API将返回一个“需要的收件人地址”
preg_匹配('/.*/',$getMessageHeaderValue($messageHeaders,'From'),$to);
//现在使用PHPMailer构建有效的电子邮件正文
$mail=new PHPMailer();
$mail->CharSet='UTF-8';
$mail->From=$From;
$mail->FromName=$FromName;
$mail->addAddress($to[1]);
$mail->Subject=$Subject;
$mail->Body=$Body;
//preSend将生成并验证电子邮件
$mail->preSend();
$mime=$mail->getSentMIMEMessage();
//base64 url编码很重要,否则将收到“ByteString的值无效”错误
$raw=base64url\u编码($mime);
//现在使用Gmail消息对象
//对我来说,这还不清楚,为什么我们不能用谷歌服务Gmail来做这件事
$message=新的Google_服务_Gmail_消息();
$message->setRaw($raw);
$message->setThreadId($emailId);
//最后,向我们的全球谷歌服务对象提供编码信息和用户-这将发送电子邮件
$response=$googleService->users\u messages->send($user,$message);
}捕获(例外$e){
打印($e->getMessage());
}
函数getMessageHeaderValue($headers,$headerName){
foreach($headers作为$header){
如果($header->name==$headerName){
返回$header->value;
}
}
返回NULL;
}
//此函数来自https://developers.google.com/people/quickstart/php
/**
*返回授权的API客户端。
*@return Google_Client授权客户端对象
*/
函数getClient()
{
//首先从这里获取credentials.json:
// https://console.developers.google.com/apis/
//
//如果更改范围或在首次使用之前,请在CLI上运行脚本
//它将返回您需要调用的URL
//这将返回一个访问令牌,供将来使用
$client=新的Google_客户端();
$client->setApplicationName('gmailapi');
//参见范围:https://developers.google.com/gmail/api/auth/scopes
$client->setScopes(数组(Google\u Service\u Gmail::Gmail\u READONLY,Google\u Service\u Gmail::Gmail\u COMPOSE));
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
//从文件加载以前授权的凭据。
$credentialsPath='token.json';
如果(文件_存在($credentialsPath)){
$accessToken=json_decode(file_get_contents($credentialsPath),true);
}否则{
//请求用户的授权。
$authUrl=$client->createAuthUrl();
printf(“在浏览器中打开以下链接:\n%s\n”,$authUrl);
打印“输入验证码:”;
$authCode=trim(fgets(STDIN));
//交换访问令牌的授权代码。
$accessToken=$client->fetchAccessTokenWithAuthCode($authCode);
//将凭据存储到磁盘。
如果(!file_存在(dirname($credentialsPath))){