Enviar correo a través de Gmail de Google Apps mediante la delegación de todo el dominio de la cuenta de servicio en nodejs

He estado leyendo tutoriales y viendo ejemplos durante 2 días ya, sin éxito. Quiero enviar un correo electrónico utilizando la cuenta de Gmail de Google Apps en el entorno nodeJS, sin embargo, obtengo respuesta de la API de Google:400

{[Error: Bad Request]
code: 400,
errors:
  [{ 
    domain: 'global',
    reason: 'failedPrecondition',
    message: 'Bad Request'
  }]
}

Esto es lo que he hecho hasta ahora:

  1. Creación de un proyecto en Google Cloud Platform
  2. Creación de una cuenta de servicio
  3. Habilitado para la cuenta de servicioDomain Wide Delegation
  4. Descargó la clave de la cuenta de servicio en formatoJSON
  5. API Manager > Credentials He creado OAuth 2.0 client ID
  6. API de Gmail habilitada para el proyecto

En la consola de administración de Google Apps:

  1. En > > he añadido el paso de arribaSecurityAdvanced SettingsManage API client accessClient ID4
  2. He añadido todos los alcances posibles para el Client ID

Este es el código que intenta enviar un correo electrónico:

const google = require('googleapis');
const googleKey = require('./google-services.json');
const jwtClient = new google.auth.JWT(googleKey.client_email, null, googleKey.private_key, ['https://www.googleapis.com/auth/gmail.send'], null);

jwtClient.authorize((err, tokens) => {
  if (err) {
    console.err(err);
    return;
  }
  console.log('Google auth success')
  var gmail = google.gmail({version: 'v1', auth: jwtClient})
  var raw = <build base64 string according to RFC 2822 specification>

  var sendMessage = gmail.users.messages.send({
    auth: jwtClient,
    userId: '[email protected]',
    message: {
      raw: raw
    }
  }, (err, res) => {
    if (err) {
      console.error(err);
    } else {
      console.log(res);
    }
});

Puedo ver el mensaje y la solicitud se envía con el token inicializado correctamente:Google auth success

headers:
{ Authorization: 'Bearer ya29.CjLjAtVjGNJ8fcBnMSS8AEXAvIm4TbyNTc6g_S99HTxRVmzKpWrAv9ioTI4BsLKXW7uojQ',
 'User-Agent': 'google-api-nodejs-client/0.9.8',
 host: 'www.googleapis.com',
 accept: 'application/json',
 'content-type': 'application/json',
 'content-length': 2 }

Pero aún así, la respuesta es 400

Respuestas:2 Respuestas 2
Tiempo:hace 6 años, 3 meses
Última modificación:hace 1 año, 9 meses

Solución

Así que estaba medio paso cerca de la solución, el problema era que al crear no mencionaba la cuenta a suplantar. const jwtClient = new google.auth.JWT(googleKey.client_email, null, googleKey.private_key, ['https://www.googleapis.com/auth/gmail.send'], null);

La inicialización correcta debe ser: const jwtClient = new google.auth.JWT(googleKey.client_email, null, googleKey.private_key, ['https://www.googleapis.com/auth/gmail.send'], '[email protected]');

Para resumir, los pasos correctos son:

  1. Creación de un proyecto en Google Cloud Platform
  2. Creación de una cuenta de servicio
  3. Habilitado para la cuenta de servicioDomain Wide Delegation
  4. Descargó la clave de la cuenta de servicio en formato JSON
  5. API Manager > Credentials He creado OAuth 2.0 Client ID
  6. API de Gmail habilitada para el proyecto

En la consola de administración de Google Apps:

  1. En > > he añadido el paso 4 anteriorSecurityAdvanced SettingsManage API client accessClient ID
  2. He añadido todos los alcances posibles para el Client ID

Este es el código que envía los correos:

const google = require('googleapis');
const googleKey = require('./google-services.json');
const jwtClient = new google.auth.JWT(googleKey.client_email, null, googleKey.private_key, ['https://www.googleapis.com/auth/gmail.send'], '<user to impersonate>');

jwtClient.authorize((err, tokens) => {
  if (err) {
    console.err(err);
    return;
  }
  console.log('Google auth success')
  var gmail = google.gmail({version: 'v1'})
  var raw = <build base64 string according to RFC 2822 specification>

  var sendMessage = gmail.users.messages.send({
    auth: jwtClient,
    userId: '<user to impersonate>',
    resource: {
      raw: raw
    }
  }, (err, res) => {
     if (err) {
       console.error(err);
     } else {
       console.log(res);
     }
 });

Esperanza que sería útil para otros

Otras respuestas

Deja un comentario