用于在 Node.js 中发送邮件的 Gmail API
Posted
技术标签:
【中文标题】用于在 Node.js 中发送邮件的 Gmail API【英文标题】:Gmail API for sending mails in Node.js 【发布时间】:2016-04-05 09:48:52 【问题描述】:免责声明:
我已经关注了谷歌自己的Node.js quickstart guide,并成功连接并使用了gmail.users.labels.list()
功能。
我已经检查了这里的问题/答案,例如this one(没有使用我所询问的 Node.js API)或this one(类似于this one),这显然是我的同一个问题有,但解决方案不起作用。
我的问题:
使用Google's Node.js API 时,我在尝试发送电子邮件时遇到错误。错误是:
"code": 403,
"errors": [
"domain": "global",
"reason": "insufficientPermissions",
"message": "Insufficient Permission"
]
我的设置:
fs.readFile(secretlocation, function processClientSecrets(err, content)
if (err)
console.log('Error loading client secret file: ' + err);
return;
authorize(JSON.parse(content), sendMessage);
);
function sendMessage(auth)
var raw = makeBody('myrealmail@gmail.com', 'myrealmail@gmail.com', 'subject', 'message test');
gmail.users.messages.send(
auth: auth,
userId: 'me',
message:
raw: raw
, function(err, response)
res.send(err || response)
);
函数processClientSecrets
来自我上面提到的谷歌指南。它读取我的.json
文件,其中包含我的access_token
和refresh_token
。 makeBody
function 是用于制作编码正文消息。
在配置变量中我也有:
var SCOPES = [
'https://mail.google.com/',
'https://www.googleapis.com/auth/gmail.modify',
'https://www.googleapis.com/auth/gmail.compose',
'https://www.googleapis.com/auth/gmail.send'
];
为什么它应该起作用:
授权过程适用于gmail.users.labels.list()
方法。
如果我在 Google's test page 进行测试,我正在测试的消息正文可以正常工作。
我的问题:
我的设置错了吗? API有变化吗?我错过了什么?
【问题讨论】:
确保您已授权所需的范围:developers.google.com/gmail/api/v1/reference/users/messages/… @AboulEinein 我有,但还是不行,谢谢指点。在Google tool 中进行测试时,我也必须拥有它。目前我拥有这些 Auth 范围:https://mail.google.com/, gmail.compose, gmail.modify, gmail.send
@Sergio Darn :( 那我不知道。希望其他人可以加入。
@Tholle 发现了我的问题。感谢您检查这个!
@Sergio 太棒了!没问题。 :)
【参考方案1】:
好的,所以我找到了问题。
问题 #1 在遵循Node.js quickstart guide 的同时,该教程中的示例具有
var SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'];
当我得到.json
时,它看起来像:
"access_token": "xxx_a_long_secret_string_i_hided_xxx",
"token_type": "Bearer",
"refresh_token": "xxx_a_token_i_hided_xxx",
"expiry_date": 1451721044161
产生的那些令牌仅考虑到教程代码中的auth/gmail.readonly
范围。
所以我删除了第一个.json
,从我的最终范围数组中添加了范围(我在问题中发布)并再次运行教程设置,收到一个新令牌。
问题 #2
在传递给我发送的 API 的对象中:
auth: auth,
userId: 'me',
message:
raw: raw
但那是错误的,message
键应该被称为resource
。
最终设置:
这是我添加到教程代码中的内容:
function makeBody(to, from, subject, message)
var str = ["Content-Type: text/plain; charset=\"UTF-8\"\n",
"MIME-Version: 1.0\n",
"Content-Transfer-Encoding: 7bit\n",
"to: ", to, "\n",
"from: ", from, "\n",
"subject: ", subject, "\n\n",
message
].join('');
var encodedMail = new Buffer(str).toString("base64").replace(/\+/g, '-').replace(/\//g, '_');
return encodedMail;
function sendMessage(auth)
var raw = makeBody('myrealemail@gmail.com', 'myrealemail@gmail.com', 'test subject', 'test message');
gmail.users.messages.send(
auth: auth,
userId: 'me',
resource:
raw: raw
, function(err, response)
res.send(err || response)
);
然后调用所有内容:
fs.readFile(secretlocation, function processClientSecrets(err, content)
if (err)
console.log('Error loading client secret file: ' + err);
return;
// Authorize a client with the loaded credentials, then call the
// Gmail API.
authorize(JSON.parse(content), sendMessage);
);
【讨论】:
如何附加html有效载荷? @ArjunKava 只是设置了Content-Type: text/html;
而不是Content-Type: text/plain;
。
请您解释一下为什么需要对 base64 原始消息进行一些替换。谢谢
我也想知道他们为什么要替换 base64 内容。此外,您在哪里找到有关原始内容的文档在资源属性中。
您在sendMessage()
中忘记了const gmail = google.gmail(version: 'v1', auth);
。还没有定义sendMessage()
中的res
。注释掉后,我得到了这个错误:Error: Insufficient Permission
。其他人有这个问题吗?【参考方案2】:
因此,对于那些试图从他们的 API 发送测试电子邮件但无法完成这项工作的人来说,这就是你必须做的:
第 1 步: 替换
var SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'];
用这个:
var SCOPES = [
'https://mail.google.com/',
'https://www.googleapis.com/auth/gmail.modify',
'https://www.googleapis.com/auth/gmail.compose',
'https://www.googleapis.com/auth/gmail.send'
];
第 2 步: 在谷歌示例代码末尾添加:
function makeBody(to, from, subject, message)
var str = ["Content-Type: text/plain; charset=\"UTF-8\"\n",
"MIME-Version: 1.0\n",
"Content-Transfer-Encoding: 7bit\n",
"to: ", to, "\n",
"from: ", from, "\n",
"subject: ", subject, "\n\n",
message
].join('');
var encodedMail = new Buffer(str).toString("base64").replace(/\+/g, '-').replace(/\//g, '_');
return encodedMail;
function sendMessage(auth)
var raw = makeBody('Receiverofyouremail@mail.com', 'whereyouaresendingstufffrom@gmail.com', 'This is your subject', 'I got this working finally!!!');
const gmail = google.gmail(version: 'v1', auth);
gmail.users.messages.send(
auth: auth,
userId: 'me',
resource:
raw: raw
, function(err, response)
return(err || response)
);
fs.readFile('credentials.json', function processClientSecrets(err, content)
if (err)
console.log('Error loading client secret file: ' + err);
return;
// Authorize a client with the loaded credentials, then call the
// Gmail API.
authorize(JSON.parse(content), sendMessage);
);
第 3 步(可选)
删除这一行:
authorize(JSON.parse(content), listLabels);
还有这些:
/**
* Lists the labels in the user's account.
*
* @param google.auth.OAuth2 auth An authorized OAuth2 client.
*/
function listLabels(auth)
const gmail = google.gmail(version: 'v1', auth);
gmail.users.labels.list(
userId: 'me',
, (err, res) =>
if (err) return console.log('The API returned an error: ' + err);
const labels = res.data.labels;
if (labels.length)
console.log('Labels:');
labels.forEach((label) =>
console.log(`- $label.name`);
);
else
console.log('No labels found.');
);
(因此您不会在控制台中获得随机标签)
【讨论】:
以上是关于用于在 Node.js 中发送邮件的 Gmail API的主要内容,如果未能解决你的问题,请参考以下文章
多个用户如何在 Node.js 中使用 Gmail 别名发送电子邮件,而无需 Google 开发人员控制台对每个用户进行用户身份验证?