Gmail API для отправки почты в Node.js
Отказ от ответственности:
- Я следовал собственному руководству Google по Node.js и успешно подключился и использую
gmail.users.labels.list()
функциональность. - Я проверил здесь вопросы / ответы, например, этот (который не использует API Node.js, о котором я спрашиваю), или этот (похожий на этот), который, по-видимому, является той же проблемой, что и у меня, но решение не дает Работа.
Моя проблема:
При использовании Google 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
из руководства Google, о котором я упоминал выше. Это читает мой .json
файл с моим access_token
а также refresh_token
, makeBody
Функция - это сделать закодированное тело сообщения.
В конфиге variabels у меня также:
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.
Мой вопрос:
Мои настройки неверны? Были ли изменения в API? Что мне не хватает?
1 ответ
Итак, я нашел проблему (ы).
Проблема № 1 Следуя краткому руководству по Node.js, приведенный в этом руководстве пример
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);
});
Итак, для тех, кто смотрит на это, пытается получить тестовое электронное письмо, отправленное из их 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. В конце примера кода Google добавьте следующее:
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', 'whereyou'resendingstufffrom@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.');
}
});
}
(Чтобы на консоли не появлялись случайные метки)