用于在节点 js javascript 文件中发送用户消息的 gmail API
Posted
技术标签:
【中文标题】用于在节点 js javascript 文件中发送用户消息的 gmail API【英文标题】:gmail API for sending users messages in nodejs javascript failes 【发布时间】:2018-08-01 12:45:01 【问题描述】:我的 nodejs 程序无法使用 Gmail api 发送消息。
Gmail API for sending mails in Node.js 的解决方案对我不起作用。
我用
对电子邮件进行编码var google = require('googleapis');
// to and from = "some name <blaw.blaw.com"
function makeBody(to, from, subject, message)
var str = ["Content-Type: text/plain; charset=\"UTF-8\"\r\n",
"MIME-Version: 1.0\r\n",
"Content-Transfer-Encoding: 7bit\r\n",
"to: ", to, "\r\n",
"from: ", from, "\r\n",
"subject: ", subject, "\r\n\r\n",
message
].join('');
encodedMail = new Buffer(str).toString("base64").replace(/\+/g, '-').replace(/\//g, '_');
return encodedMail;
然后转到 Google API 资源管理器 https://developers.google.com/apis-explorer/#p/ 输入 gmail.users.messages.send 和上面 make_body 生成的字符串。
一封电子邮件将被成功发送。所以我知道上面的编码是 好的。
当我的程序尝试使用以下发送时,它失败并出现错误
错误:“原始”RFC822 有效负载消息字符串或通过上传消息 /upload/* 需要网址
function sendMessage(auth)
var gmail = google.gmail('v1');
var raw = makeBody('john g <asdfasdf@hotmail.com>', 'john g<asfasdgf@gmail.com>', 'test subject', 'test message #2');
gmail.users.messages.send(
auth: auth,
userId: 'me',
resource:
raw: raw
, function(err, response)
console.log(err || response)
);
身份验证令牌很好,因为我可以调用 gmail.users.labels.list 并且在使用 API 资源管理器时使用相同的授权。
Q1:有谁知道为什么上述方法不起作用?
Q2:Gmail API for sending mails in Node.js 没有解释为什么原始电子邮件消息被包装在资源字段中。我尝试了简单的原始方法,但没有帮助。
这失败了。
gmail.users.messages.send(
auth: auth,
userId: 'me',
resource:
raw: raw
, function(err, response)
console.log(err || response)
);
也是如此
gmail.users.messages.send(
auth: auth,
userId: 'me',
raw: raw
, function(err, response)
console.log(err || response)
);
GMAIL API for sending Email with attachment也是如此
gmail.users.messages.send(
auth: auth,
userId: 'me',
data: raw
, function(err, response)
console.log(err || response)
);
有谁知道它在哪里记录了如何传递 api explorer 要求的“请求的正文”?
Q3:为什么google api需要在base64编码中进行替换?
我尝试使用编码
const Base64 = require("js-base64").Base64
var encodedMail = Base64.encode(str);
当我将它输入 API 资源管理器时,我得到了错误
"message": "ByteString 的值无效:
【问题讨论】:
developers.google.com/gmail/api/v1/reference/users/messages/… 在 javascript 选项卡中给出了一个示例,但它显示“不使用客户端库。”。但它没有说它正在使用什么。它会调用 gapi.client.gmail.users.messages.send,但没有说明 gapi 的价值。 在继续之前,您能否检查一下您是否可以在这个SO post 和另一个SO post 中获得一些信息? 感谢您发现更多非常相似的问题。您找到的第一个解决方案建议使用 resource: raw: 是我尝试过的。您找到的第二个解决方案建议多部分/相关,但我试图发送一个简单的“hello world”没有附件,并且当我将编码字符串传递到操场时,内容类型有效。这个 API 绝对可以使用一些文档和一些示例来做一些简单的事情。 就像我在issue tracker说的,你可以参考this SO post ***.com/questions/48579566 似乎是一个几乎相同的问题,未解决,作者建议不要使用googleapi API?当我发布我的问题时,我没有看到这个。 【参考方案1】:哎呀!对于在这里绊倒的其他人,有几件事。首先 - 我们现在有一个完整的端到端发送邮件示例:
https://github.com/google/google-api-nodejs-client/blob/master/samples/gmail/send.js
其次,上面的答案大多是正确的 :) 而不是安装最新版本的 google-auth-library
... 只需将其从您的 package.json 中删除即可。入门指南非常非常错误(现已修复)。 googelapis
引入了它自己的兼容版本 google-auth-library
,所以你真的不想通过安装自己的版本来搞砸它:)
【讨论】:
【参考方案2】:快速入门指定:
npm install google-auth-library@0.* --save
当我把它改成
npm install google-auth-library -- save
它引入了 1.3.1 和 0.12.0 版本。一旦我更改了代码以解决重大更改,一切都开始工作了。最新版本的 googleapis 也有重大变化。这是我对快速入门的调整:
package.json
....
"dependencies":
"google-auth-library": "^1.3.1",
"googleapis": "^26.0.1"
quickstart.js
var fs = require('fs');
var readline = require('readline');
var google = require('googleapis');
const GoogleAuth, JWT, OAuth2Client = require('google-auth-library');
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'
];
var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
process.env.USERPROFILE) + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'gmail-nodejs-quickstart.json';
function authorize(credentials, callback)
var clientSecret = credentials.installed.client_secret;
var clientId = credentials.installed.client_id;
var redirectUrl = credentials.installed.redirect_uris[0];
var auth = new GoogleAuth();
var oauth2Client = new OAuth2Client(clientId, clientSecret, redirectUrl);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, function (err, token)
if (err)
getNewToken(oauth2Client, callback);
else
oauth2Client.credentials = JSON.parse(token);
callback(oauth2Client);
);
function getNewToken(oauth2Client, callback)
var authUrl = oauth2Client.generateAuthUrl(
access_type: 'offline',
scope: SCOPES
);
console.log('Authorize this app by visiting this url: ', authUrl);
var rl = readline.createInterface(
input: process.stdin,
output: process.stdout
);
rl.question('Enter the code from that page here: ', function (code)
rl.close();
oauth2Client.getToken(code, function (err, token)
if (err)
console.log('Error while trying to retrieve access token', err);
return;
oauth2Client.credentials = token;
storeToken(token);
callback(oauth2Client);
);
);
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 gmail = google.gmail('v1');
var raw = makeBody('xxxxxxxx@hotmail.com', 'xxxxxxx@gmail.com', 'test subject', 'test message');
gmail.users.messages.send(
auth: auth,
userId: 'me',
resource:
raw: raw
, function(err, response)
console.log(err || response)
);
const secretlocation = 'client_secret.json'
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);
);
现在当我运行时,我得到了响应
Object status: 200, statusText: "OK", headers: Object, config: Object, request: ClientRequest, …
【讨论】:
以上是关于用于在节点 js javascript 文件中发送用户消息的 gmail API的主要内容,如果未能解决你的问题,请参考以下文章