Gmail API - 使用 Javascript 解析邮件内容(Base64 解码?)
Posted
技术标签:
【中文标题】Gmail API - 使用 Javascript 解析邮件内容(Base64 解码?)【英文标题】:Gmail API - Parse message content (Base64 decoding?) with Javascript 【发布时间】:2014-09-04 20:52:18 【问题描述】:我正在尝试使用 Gmail API 获取用户的电子邮件,获取邮件主题和正文,然后将其显示在网页上。我会用它做其他事情,但这是我遇到困难的部分。我正在使用 Angular.js。
这是我的 API 调用:
function makeApiCall()
gapi.client.load('gmail', 'v1', function()
var request = gapi.client.gmail.users.messages.list(
labelIds: ['INBOX']
);
request.execute(function(resp)
var content = document.getElementById("message-list");
angular.forEach(resp, function(message)
var email = gapi.client.gmail.users.messages.get('id': message.id);
// var raw = email.payload.parts;
// console.log(raw);
content.innerhtml += JSON.stringify(email) + "<br>";
)
);
);
所以gapi.client.gmail.users.messages.list
返回一个我的消息数组,以及它们的 ID 号。这是有效的。
对gapi.client.gmail.users.messages.get(<specific message ID>)
的调用会输出这个 - "B":"method":"gmail.users.messages.get","rpcParams":,"transport":"name":"googleapis"
。
不确定那是什么,但尝试获取消息有效负载 (email.payload.parts
) 时,结果为 undefined
。那么,如何获取消息内容呢?
另外,我假设如果我可以获取消息内容,我将不得不对内容进行 Base64 解码以从中获取一些英文。对此的任何建议也会有很大帮助。我发现了这个:https://github.com/kvz/phpjs,但由于我不确定如何获取消息内容以便我可以尝试解码它们,所以不确定 php.js 在这方面是否有帮助。
【问题讨论】:
对于那些正在寻找 npm 包的人,试试这个npmjs.com/package/gmail-api-parse-message 【参考方案1】:关于Base64解码,可以使用
atob(dataToDecode)
对于 Gmail,您还需要替换一些字符:
atob( dataToDecode.replace(/-/g, '+').replace(/_/g, '/') );
您可以在 javascript 中使用上述功能(请参阅ref)。我自己用它来解码 Gmail 邮件。无需安装额外的东西。作为一个有趣的切线,如果您想将消息编码为 Base64,请使用 btoa。
现在,为了访问您的消息负载,您可以编写一个函数:
var extractField = function(json, fieldName)
return json.payload.headers.filter(function(header)
return header.name === fieldName;
)[0].value;
;
var date = extractField(response, "Date");
var subject = extractField(response, "Subject");
引用自我之前的SO Question 和
var part = message.parts.filter(function(part)
return part.mimeType == 'text/html';
);
var html = atob(part.body.data.replace(/-/g, '+').replace(/_/g, '/'));
【讨论】:
哦,我的 gOoOd 谢谢你的 GMail 提示。我试图弄清楚为什么我的解码在raw
消息上出现乱码。
天哪,你的 gmail 替换提示刚刚救了我【参考方案2】:
根据您的电子邮件的外观(单个文本/纯文本部分?带有文本/html 的多部分?附件等?)您的 email.payload 中可能有也可能没有任何“部分”,相反,您将拥有什么您正在“email.payload.body.data”(用于单部分消息)中寻找。这一切都假设您正在使用默认格式(“完整”)执行 message.get。如果您想在 message.raw 字段中获取整个电子邮件并在您的语言的电子邮件库中处理它,您可以调用 message.get(format=raw)。
有关更多信息,请查看https://developers.google.com/gmail/api/v1/reference/users/messages“消息”的“正文”和“部件[]”字段文档
【讨论】:
当尝试记录gapi.client.gmail.users.messages.get(<message id>).payload.body.data
时,它会输出Uncaught TypeError: Cannot read property 'body' of undefined
。但是,当在 Try it 上测试 Gmail API 文档(我知道您发布的那个链接)上的 .get 方法调用时!在messages.get 部分的部分,我可以在我的消息对象的有效负载字段中看到内容,所以它不应该是未定义的。虽然对于parts[],它说For...text/plain, this field is empty.
一个基本的电子邮件消息将包含纯文本,对吗?所以也许那不是我应该去的地方..【参考方案3】:
啊!我想到了。 parts
是一个数组,所以我应该这样称呼它:gapi.client.gmail.users.messages.get('id': <message ID>).payload.parts[0].body.data
现在我的问题是解码电子邮件,这在纯文本电子邮件中被证明是成功的,但在来自非个人位置(企业、社交媒体更新电子邮件等)的电子邮件中却失败了。但我会提出一个新问题来获得答案。
【讨论】:
您应该使用library 进行编码和解码 查看我上面的编码/解码答案【参考方案4】:您需要搜索给定 mime 类型的主体在哪里,我为此编写了一个递归函数:
function searchBodyRec(payload, mimeType)
if (payload.body && payload.body.size && payload.mimeType === mimeType)
return payload.body.data;
else if (payload.parts && payload.parts.length)
return payload.parts.flatMap(function(part)
return searchBodyRec(part, mimeType);
).filter(function(body)
return body;
);
所以现在你可以打电话了
var encodedBody = searchBodyRec(this.message.payload, 'text/plain');
看到上面的 flatMap 方法了吗? js中缺少经典的FP方法,这里是如何添加它(或者你可以使用lodash.js,或者如果你不想与原生对象混淆,可以使用underscore.js)
Array.prototype.flatMap = function(lambda)
return Array.prototype.concat.apply([], this.map(lambda));
;
【讨论】:
以上是关于Gmail API - 使用 Javascript 解析邮件内容(Base64 解码?)的主要内容,如果未能解决你的问题,请参考以下文章
在 javascript/node.js 中连接到 Gmail IMAP API
在 Javascript 中使用 GMAIL API 发送带有附件文件(超过 10 MB)的电子邮件
Javascript fetch 无法从 GMail API Batch 请求中读取 Multipart 响应