让我们做一个小实验。我已经给自己发了两条消息。一个带有附件,一个没有附件。
请求:
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 = payloadGET https://www.googleapis.com/gmail/v1/users/me/messages/14fe21fd6b3fb46f?fields=payloadGET 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上比我要好得多,但这是它的概述):
- 遍历,
payload.parts
并检查其中是否包含part
具有您要查找的正文(text/plain
或text/html
)。如果有的话,您就可以完成搜索。如果您解析的是上面没有附件的邮件,这就足够了。 - 再次执行步骤1,但这一次是
parts
将parts
您刚才找到的内容递归检查。您最终会找到自己的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 depredPart = depreURIComponent(escape(atob(part.body.data.replace(/-/g, '+').replace(/_/g, '/')))); console.log(depredPart); }}更简单的选择是只获取邮件的原始数据,然后让一个已经编写好的库为您完成工作:
请求:
format = rawfields = rawGET https://www.googleapis.com/gmail/v1/users/me/messages/14fe21fd6b3fb46f?format=raw&fields=raw
响应:
{ "raw": "TUlNRS1WZXJzaW9uOiAxLjANClJlY2VpdmVkOiBieSAxMC4yOC45OS4xOTYgd2l0aCBIVFRQOyBGcmksIDE4IFNlcCAyMDE1IDEzOjIzOjAxIC0wNzAwIChQRFQpDQpEYXRlOiBGcmksIDE4IFNlcCAyMDE1IDIyOjIzOjAxICswMjAwDQpEZWxpdmVyZWQtVG86IGVtdGhvbGluQGdtYWlsLmNvbQ0KTWVzc2FnZS1JRDogPENBRHNaTFJ5eGk2UGt0MHZnUS1iZHd1N2FNLWNHRmZKcEwrRHYyb3ZKOGp4SGN4VWhfQUBtYWlsLmdtYWlsLmNvbT4NClN1YmplY3Q6IFdoYXQgZGENCkZyb206IEVtaWwgVGhvbGluIDxlbXRob2xpbkBnbWFpbC5jb20-DQpUbzogRW1pbCBUaG9saW4gPGVtdGhvbGluQGdtYWlsLmNvbT4NCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L2FsdGVybmF0aXZlOyBib3VuZGFyeT0wMDFhMTE0NjhmMTY1YzUwNDUwNTIwMGI0YzYxDQoNCi0tMDAxYTExNDY4ZjE2NWM1MDQ1MDUyMDBiNGM2MQ0KQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PVVURi04DQoNCmhlY2s_IE5vIGF0dGFjaG1lbnQ_DQoNCi0tMDAxYTExNDY4ZjE2NWM1MDQ1MDUyMDBiNGM2MQ0KQ29udGVudC1UeXBlOiB0ZXh0L2h0bWw7IGNoYXJzZXQ9VVRGLTgNCg0KPGRpdiBkaXI9Imx0ciI-aGVjaz8gTm8gYXR0YWNobWVudD88L2Rpdj4NCg0KLS0wMDFhMTE0NjhmMTY1YzUwNDUwNTIwMGI0YzYxLS0="}第二种方法的最大缺点是,如果您收到原始消息,则将立即下载所有附件数据,对于您的用例而言,这些数据可能远远不够。
我不太擅长PHP,但是如果您想使用第二种解决方案,这看起来很有希望!祝好运!



