dtnmnw3697
2016-03-02 17:01 阅读 50
已采纳

克隆邮件并使用原始“发件人”标头发送邮件

I'm trying to develop a PHP script resting on the Gmail API that would make possible to snooze my messages at a specific time, i.e. archive and un-archive a message at a specific datetime.

Everything is in place and works but a detail, that is I cannot keep the "From" headers of the original message. More specifically:

  1. The ID of the message to snooze is retrieved at a specific time thanks to a CRON job;
  2. Using the message ID, the message in raw format is retrieved and cloned;
  3. The original message is deleted and the cloned message is sent (and received) => This ensures that the email is displayed at the top of the inbox.

Problem: the cloned email is a perfect copy of the original one but the "From" headers which display the email address of the authenticated user, i.e. myself (username@gmail.com).

//[...] object $this->message

private function cloneMail() {

   // GET RAW message
   $this->message->raw = $this->gmail->users_messages->get(
                                        $this->message->user, 
                                        $this->message->id,
                                        array('format'=>'raw')
                                       );

   try {

     // INSERT original message
     $inserted = $this->gmail->users_messages->delete(
                                              $this->message->user,
                                              $this->message->id
                                                 );

        // ONCE DELETED, SEND CLONED EMAIL    
        if ($deleted->getId()) {
            try {
                $this->gmail->users_messages->send(
                                           $this->message->user, 
                                           $this->message->raw
                                           );
                } catch (Exception $e) {
                    // -- Fallback...
                }
          }

    } catch(Exception $e) {}
}

[Updated] Working solution using messages.insert()

private function cloneMail() {

   // GET RAW message
   $this->message->raw = $this->gmail->users_messages->get(
                                        $this->message->user, 
                                        $this->message->id,
                                        array('format'=>'raw')
                                       );

   try {

     // DELETE original message
     $deleted = $this->gmail->users_messages->delete(
                                              $this->message->user,
                                              $this->message->id
                                                 );

        // ONCE DELETED, SEND CLONED EMAIL    
        if ($deleted->getId()) {
            try {
                $this->gmail->users_messages->insert(
                                           $this->message->user, 
                                           $this->message->raw
                                           );
                } catch (Exception $e) {
                    // -- Fallback...
                }
          }

    } catch(Exception $e) {}
}
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • 已采纳
    douxia5179 douxia5179 2016-03-02 17:33

    messages.send() requires that the From: address be under the control of the authenticated user. Use messages.import() instead.

    点赞 评论 复制链接分享
  • douhu2525 douhu2525 2016-08-12 06:08

    I am successfully using import() and getting thread support.

    I had a major issue when I was doing multi-part upload for large messages, though (how I landed on this post) with

    "code": 400, "message": "Expected a single 'From' header"

    while Import wants you to use raw (base64 encoded message), Google_Http_MediaFileUpload() wants you to use the ASCII version so you have to decode your raw message and do something like:

    $ret = $service->users_messages->import( $user, $newMessage, array( 'internalDateSource' => "dateHeader", 'uploadType'=>"multipart" ) );
    
    $media = new Google_Http_MediaFileUpload( $client, $ret, 'message/rfc822', $textMessage, true, $chunkSize );
    
    $media->setFileSize( strlen( $rawMessage ) );
    
    // upload
    $status = false;
    while( $status == false ) {
            try {
                    $status = $media->nextChunk();
            }  catch( Exception $e ) {
                    echo "An error occurred: {$e->getMessage()} 
    ";
    
                    exit();
    
            }
    }
    

    $newMessage has all the metadata including the labels and such but none of the actual data.

    Thanks to http://michiel.vanbaak.eu/2016/02/27/sending-big-email-using-google-php-api-client-and-gmail/

    I do think that using just import() when we can get away with it is better because it does save on API calls.

    点赞 评论 复制链接分享

相关推荐