Моя функция (развернутая как облачная функция Firebase) использует Nodemailer для отправки электронной почты с помощью Gmail.
- Я создал служебную учетную запись в консоли CCP project-name@appspot.gserviceaccount.com
- Я включил Gmail API в консоли GCP для этого проекта https://console.cloud.google.com/apis/library/gmail.googleapis.com
- Функция использует
googleapis
для генерации токенов с использованием сервиса Google OAuth 2 - Функция использует
nodemailer
используется для отправки электронной почты
Я получаю одну из двух ошибок:
Error: invalid_client
- при разрешении googleapis
генерировать refreshToken
и accessToken
Can't create new access token for user
- при разрешении nodemailer
генерировать refreshToken
и accessToken
Проблема может быть в моем коде или в том, как установлены учетные данные OAuth в консоли GCP.
function.js
// Based on https://github.com/akshaybhange/Firebase-Functions-sendMail-Google-OAuth2/blob/master/index.js
const nodemailer = require('nodemailer');
const ServiceAccount = require('./config/serviceAccount');
const mailConfig = require('./config/mailConfig');
const { google } = require("googleapis");
exports.sendMail = (subject, message, callback) => {
// Google APIs start
const refreshToken = "1//04tRp..."; // Obtained from "https://developers.google.com/oauthplayground"
const OAuth2 = google.auth.OAuth2;
const oAuth2Client = new OAuth2(
ServiceAccount.client_id,
ServiceAccount.private_key,
"https://developers.google.com/oauthplayground" // Redirect URL
);
oAuth2Client.setCredentials({
refresh_token: refreshToken
});
const accessToken = oAuth2Client.getAccessToken();
// Google APIs end
const authOptions = {
auth: {
type: 'OAuth2',
user: ServiceAccount.client_email, // mailConfig.from
clientId: ServiceAccount.client_id,
clientSecret: ServiceAccount.private_key,
refreshToken // from Google API
accessToken // from Google API
},
};
const transporterOptions = {
service: "gmail",
...authOptions
};
const transporter = nodemailer.createTransport(transporterOptions);
transporter.on('token', token => console.log(token));
const mailOptions = {
from: mailConfig.from,
to: mailConfig.to,
subject: subject,
text: message,
// ...authOptions // read this might help
};
return transporter.sendMail(mailOptions, (error, response) => {
error ? console.error(error) : console.log(info);
transporter.close();
return callback ? callback(error, response) : {error, response};
});
};
Журнал консоли:
> var {sendMail} = require('./sendMail');
undefined
> sendMail("Subject","Message")
undefined
> (node:88994) UnhandledPromiseRejectionWarning: Error: invalid_client
at Gaxios.<anonymous> (/Users/User/Developer/Project/functions/node_modules/googleapis/node_modules/gaxios/build/src/gaxios.js:73:27)
at Generator.next (<anonymous>)
at fulfilled (/Users/User/Developer/Project/functions/node_modules/googleapis/node_modules/gaxios/build/src/gaxios.js:16:58)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:88994) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:88994) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Error: invalid_client
at /Users/User/Developer/Project/functions/node_modules/nodemailer/lib/xoauth2/index.js:259:33
at PassThrough.<anonymous> (/Users/User/Developer/Project/functions/node_modules/nodemailer/lib/xoauth2/index.js:328:20)
at Object.onceWrapper (events.js:299:28)
at PassThrough.emit (events.js:210:5)
at PassThrough.EventEmitter.emit (domain.js:540:23)
at endReadableNT (_stream_readable.js:1200:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
code: 'EAUTH',
command: 'AUTH XOAUTH2'
}
Журнал консоли - при комментировании API Google и разрешении Nodemailer генерировать refreshToken
и accessToken
:
> var {sendMail} = require('./sendMail');
undefined
> sendMail("Subject","Message",(error, info)=>{console.log(error,info)})
undefined
> Error: Can't create new access token for user
at XOAuth2.generateToken (/Users/User/Developer/Project/functions/node_modules/nodemailer/lib/xoauth2/index.js:179:33)
at XOAuth2.getToken (/Users/User/Developer/Project/functions/node_modules/nodemailer/lib/xoauth2/index.js:123:18)
at SMTPConnection._handleXOauth2Token (/Users/User/Developer/Project/functions/node_modules/nodemailer/lib/smtp-connection/index.js:1679:27)
at SMTPConnection.login (/Users/User/Developer/Project/functions/node_modules/nodemailer/lib/smtp-connection/index.js:534:22)
at /Users/User/Developer/Project/functions/node_modules/nodemailer/lib/smtp-transport/index.js:271:32
at SMTPConnection.<anonymous> (/Users/User/Developer/Project/functions/node_modules/nodemailer/lib/smtp-connection/index.js:209:17)
at Object.onceWrapper (events.js:299:28)
at SMTPConnection.emit (events.js:210:5)
at SMTPConnection.EventEmitter.emit (domain.js:540:23)
at SMTPConnection._actionEHLO (/Users/User/Developer/Project/functions/node_modules/nodemailer/lib/smtp-connection/index.js:1298:14) {
code: 'EAUTH',
command: 'AUTH XOAUTH2'
} undefined