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

时间:2016-07-21 15:46:41

标签: php gmail-api

我正在使用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);

在这里,我将To地址作为已发送的人邮件ID传递,并且主题已经使用了主题。

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

2 个答案:

答案 0 :(得分:4)

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

test

$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); 是登录用户的ID,而userId是您要回复的邮件的主题ID。

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

答案 1 :(得分:2)

以上来自@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), '+/', '-_'), '=');
}