一尘不染

无法使用Gmail PHP API获取电子邮件正文

php

我在使用Gmail PHP API时遇到问题。

我想检索电子邮件的正文内容,但是我只能对具有附件的电子邮件检索它!我的问题是为什么?

到目前为止,这是我的代码:

// Authentication things above...
$client = getClient();
$gmail = new Google_Service_Gmail($client);    
$list = $gmail->users_messages->listUsersMessages('me', ['maxResults' => 1000]);

while ($list->getMessages() != null) {   
    foreach ($list->getMessages() as $mlist) {               
        $message_id = $mlist->id;   
        $optParamsGet2['format'] = 'full';
        $single_message = $gmail->users_messages->get('me', $message_id, $optParamsGet2);

        $threadId = $single_message->getThreadId();
        $payload = $single_message->getPayload();
        $headers = $payload->getHeaders();
        $parts = $payload->getParts();
        //print_r($parts); PRINTS SOMETHING ONLY IF I HAVE ATTACHMENTS...
        $body = $parts[0]['body'];
        $rawData = $body->data;
        $sanitizedData = strtr($rawData,'-_', '+/');
        $decodedMessage = base64_decode($sanitizedData); //should display my body content
    }

    if ($list->getNextPageToken() != null) {
        $pageToken = $list->getNextPageToken();
        $list = $gmail->users_messages->listUsersMessages('me', ['pageToken' => $pageToken, 'maxResults' => 1000]);
    } else {
        break;
    }
}

检索我知道的内容的第二种方法是使用位于“ 标题” 部分中的代码段,但它只能检索50个左右的前字符,这不是很有用。


阅读 491

收藏
2020-05-26

共1个答案

一尘不染

让我们做一个小实验。我已经给自己发了两条消息。一个带有附件,一个没有附件。

请求:

GET https://www.googleapis.com/gmail/v1/users/me/messages?maxResults=2

响应:

{
 "messages": [
  {
   "id": "14fe21fd6b3fb46f",
   "threadId": "14fe21fd6b3fb46f"
  },
  {
   "id": "14fe21f9341ed73c",
   "threadId": "14fe21f9341ed73c"
  }
 ],
 "nextPageToken": "08943597140129624594",
 "resultSizeEstimate": 3
}

我只要求提供有效负载,因为这是所有相关部分的位置:

fields = payload

GET https://www.googleapis.com/gmail/v1/users/me/messages/14fe21fd6b3fb46f?fields=payload

GET https://www.googleapis.com/gmail/v1/users/me/messages/14fe21f9341ed73c?fields=payload

不带附件的邮件:

{
 "payload": {
  "parts": [
   {
    "partId": "0",
    "mimeType": "text/plain",
    "filename": "",
    "headers": [
     {
      "name": "Content-Type",
      "value": "text/plain; charset=UTF-8"
     }
    ],
    "body": {
     "size": 22,
     "data": "aGVjaz8gTm8gYXR0YWNobWVudD8NCg=="
    }
   },
   {
    "partId": "1",
    "mimeType": "text/html",
    "filename": "",
    "headers": [
     {
      "name": "Content-Type",
      "value": "text/html; charset=UTF-8"
     }
    ],
    "body": {
     "size": 43,
     "data": "PGRpdiBkaXI9Imx0ciI-aGVjaz8gTm8gYXR0YWNobWVudD88L2Rpdj4NCg=="
    }
   }
  ]
 }
}

带有附件的邮件:

{
 "payload": {
  "parts": [
   {
    "mimeType": "multipart/alternative",
    "filename": "",
    "headers": [
     {
      "name": "Content-Type",
      "value": "multipart/alternative; boundary=001a1142e23c551e8e05200b4be0"
     }
    ],
    "body": {
     "size": 0
    },
    "parts": [
     {
      "partId": "0.0",
      "mimeType": "text/plain",
      "filename": "",
      "headers": [
       {
        "name": "Content-Type",
        "value": "text/plain; charset=UTF-8"
       }
      ],
      "body": {
       "size": 9,
       "data": "V293IG1hbg0K"
      }
     },
     {
      "partId": "0.1",
      "mimeType": "text/html",
      "filename": "",
      "headers": [
       {
        "name": "Content-Type",
        "value": "text/html; charset=UTF-8"
       }
      ],
      "body": {
       "size": 30,
       "data": "PGRpdiBkaXI9Imx0ciI-V293IG1hbjwvZGl2Pg0K"
      }
     }
    ]
   },
   {
    "partId": "1",
    "mimeType": "image/jpeg",
    "filename": "feelthebern.jpg",
    "headers": [
     {
      "name": "Content-Type",
      "value": "image/jpeg; name=\"feelthebern.jpg\""
     },
     {
      "name": "Content-Disposition",
      "value": "attachment; filename=\"feelthebern.jpg\""
     },
     {
      "name": "Content-Transfer-Encoding",
      "value": "base64"
     },
     {
      "name": "X-Attachment-Id",
      "value": "f_ieq3ev0i0"
     }
    ],
    "body": {
     "attachmentId": "ANGjdJ_2xG3WOiLh6MbUdYy4vo2VhV2kOso5AyuJW3333rbmk8BIE1GJHIOXkNIVGiphP3fGe7iuIl_MGzXBGNGvNslwlz8hOkvJZg2DaasVZsdVFT_5JGvJOLefgaSL4hqKJgtzOZG9K1XSMrRQAtz2V0NX7puPdXDU4gvalSuMRGwBhr_oDSfx2xljHEbGG6I4VLeLZfrzGGKW7BF-GO_FUxzJR8SizRYqIhgZNA6PfRGyOhf1s7bAPNW3M9KqWRgaK07WTOYl7DzW4hpNBPA4jrl7tgsssExHpfviFL7yL52lxsmbsiLe81Z5UoM",
     "size": 100446
    }
   }
  ]
 }
}

这些响应与$parts您代码中的相对应。如您所见,如果您幸运的话,$parts[0]['body']->data会给您想要的东西,但大多数时候不会。

通常有两种方法可以解决此问题。您可以实现以下算法(您在PHP上比我要好得多,但这是它的概述):

  1. 遍历,payload.parts并检查其中是否包含part具有您要查找的正文(text/plaintext/html)。如果有的话,您就可以完成搜索。如果您解析的是上面没有附件的邮件,这就足够了。
  2. 再次执行步骤1,但这一次是partsparts您刚才找到的内容递归检查。您最终会找到自己的part。如果您要解析上述带有附件的邮件,最终将找到您的body

该算法可能类似于以下内容(JavaScript中的示例):

var response = {

 "payload": {

  "parts": [

   {

    "mimeType": "multipart/alternative",

    "filename": "",

    "headers": [

     {

      "name": "Content-Type",

      "value": "multipart/alternative; boundary=001a1142e23c551e8e05200b4be0"

     }

    ],

    "body": {

     "size": 0

    },

    "parts": [

     {

      "partId": "0.0",

      "mimeType": "text/plain",

      "filename": "",

      "headers": [

       {

        "name": "Content-Type",

        "value": "text/plain; charset=UTF-8"

       }

      ],

      "body": {

       "size": 9,

       "data": "V293IG1hbg0K"

      }

     },

     {

      "partId": "0.1",

      "mimeType": "text/html",

      "filename": "",

      "headers": [

       {

        "name": "Content-Type",

        "value": "text/html; charset=UTF-8"

       }

      ],

      "body": {

       "size": 30,

       "data": "PGRpdiBkaXI9Imx0ciI-V293IG1hbjwvZGl2Pg0K"

      }

     }

    ]

   },

   {

    "partId": "1",

    "mimeType": "image/jpeg",

    "filename": "feelthebern.jpg",

    "headers": [

     {

      "name": "Content-Type",

      "value": "image/jpeg; name=\"feelthebern.jpg\""

     },

     {

      "name": "Content-Disposition",

      "value": "attachment; filename=\"feelthebern.jpg\""

     },

     {

      "name": "Content-Transfer-Encoding",

      "value": "base64"

     },

     {

      "name": "X-Attachment-Id",

      "value": "f_ieq3ev0i0"

     }

    ],

    "body": {

     "attachmentId": "ANGjdJ_2xG3WOiLh6MbUdYy4vo2VhV2kOso5AyuJW3333rbmk8BIE1GJHIOXkNIVGiphP3fGe7iuIl_MGzXBGNGvNslwlz8hOkvJZg2DaasVZsdVFT_5JGvJOLefgaSL4hqKJgtzOZG9K1XSMrRQAtz2V0NX7puPdXDU4gvalSuMRGwBhr_oDSfx2xljHEbGG6I4VLeLZfrzGGKW7BF-GO_FUxzJR8SizRYqIhgZNA6PfRGyOhf1s7bAPNW3M9KqWRgaK07WTOYl7DzW4hpNBPA4jrl7tgsssExHpfviFL7yL52lxsmbsiLe81Z5UoM",

     "size": 100446

    }

   }

  ]

 }

};



// In e.g. a plain text message, the payload is the only part.

var parts = [response.payload];



while (parts.length) {

  var part = parts.shift();

  if (part.parts) {

    parts = parts.concat(part.parts);

  }



  if(part.mimeType === 'text/html') {

    var decodedPart = decodeURIComponent(escape(atob(part.body.data.replace(/\-/g, '+').replace(/\_/g, '/'))));

    console.log(decodedPart);

  }

}

更简单的选择是只获取邮件的原始数据,然后让一个已经编写好的库为您完成工作:

请求:

format = raw
fields = raw

GET https://www.googleapis.com/gmail/v1/users/me/messages/14fe21fd6b3fb46f?format=raw&fields=raw

响应:

{
 "raw": "TUlNRS1WZXJzaW9uOiAxLjANClJlY2VpdmVkOiBieSAxMC4yOC45OS4xOTYgd2l0aCBIVFRQOyBGcmksIDE4IFNlcCAyMDE1IDEzOjIzOjAxIC0wNzAwIChQRFQpDQpEYXRlOiBGcmksIDE4IFNlcCAyMDE1IDIyOjIzOjAxICswMjAwDQpEZWxpdmVyZWQtVG86IGVtdGhvbGluQGdtYWlsLmNvbQ0KTWVzc2FnZS1JRDogPENBRHNaTFJ5eGk2UGt0MHZnUS1iZHd1N2FNLWNHRmZKcEwrRHYyb3ZKOGp4SGN4VWhfQUBtYWlsLmdtYWlsLmNvbT4NClN1YmplY3Q6IFdoYXQgZGENCkZyb206IEVtaWwgVGhvbGluIDxlbXRob2xpbkBnbWFpbC5jb20-DQpUbzogRW1pbCBUaG9saW4gPGVtdGhvbGluQGdtYWlsLmNvbT4NCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L2FsdGVybmF0aXZlOyBib3VuZGFyeT0wMDFhMTE0NjhmMTY1YzUwNDUwNTIwMGI0YzYxDQoNCi0tMDAxYTExNDY4ZjE2NWM1MDQ1MDUyMDBiNGM2MQ0KQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PVVURi04DQoNCmhlY2s_IE5vIGF0dGFjaG1lbnQ_DQoNCi0tMDAxYTExNDY4ZjE2NWM1MDQ1MDUyMDBiNGM2MQ0KQ29udGVudC1UeXBlOiB0ZXh0L2h0bWw7IGNoYXJzZXQ9VVRGLTgNCg0KPGRpdiBkaXI9Imx0ciI-aGVjaz8gTm8gYXR0YWNobWVudD88L2Rpdj4NCg0KLS0wMDFhMTE0NjhmMTY1YzUwNDUwNTIwMGI0YzYxLS0="
}

第二种方法的最大缺点是,如果您收到原始消息,则将立即下载所有附件数据,对于您的用例而言,这些数据可能远远不够。

我不太擅长PHP,但是如果您想使用第二种解决方案,看起来很有希望!祝好运!

2020-05-26