How to send a reply to an mail using Gmail API

2019-02-27 19:59发布

问题:

I am using gmail API to send an email .In this the sending is successfully done. i want to know how to reply to that person ( who already send ) using php.

Here i attach my code for sending :

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

Here i pass the To address as already sended person mail id and the subject is already used subject.

How to change this code to send an reply. Please Help me

回答1:

You need to pass the thread id of the message you want to reply to and set the same subject for the new message. I prefer using some library for generating the raw string for the message, instead of writing it manually in order to minimize the possibility of errors. Below is an example using 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 is the id of the logged in user, while threadId is the id of the thread of the message you want to reply to.

I've had a lot of difficulties with Google's PHP SDK and the lack of proper examples, so I wrote a PHP wrapper that covers most of the Gmail API's functions. It covers the explanation above, if you dig into it you'd find the logic that's omitted in the example above. You can find it here.



回答2:

The above answer from @trajchevska is pretty nice and I am glad that I found it (!) - but it will not "reveal the full truth". So I tried to put together my insights to create a snippet that should work as-it-is.

$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), '+/', '-_'), '=');
}


标签: php gmail-api