使用nodejs中的服务帐户域范围委派,通过Google Apps Gmail发送邮件

ago*_*dis 2 gmail google-apps node.js jwt service-accounts

我已经阅读了教程并且已经看了两天的例子,但没有成功.我想在NodeJS环境中使用Google Apps Gmail帐户发送电子邮件,但是,我得到400了Google API的回复:

{[Error: Bad Request]
code: 400,
errors:
  [{ 
    domain: 'global',
    reason: 'failedPrecondition',
    message: 'Bad Request'
  }]
}
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止所做的:

  1. 在Google Cloud Platform中创建了一个项目
  2. 创建了一个服务帐户
  3. 已启用Domain Wide Delegation服务帐户
  4. JSON格式下载服务帐户的密钥
  5. API Manager> Credentials我创造了OAuth 2.0 client ID
  6. 为项目启用了Gmail API

在Google Apps管理控制台中:

  1. Security> Advanced Settings> Manage API client access我已经添加了Client ID从步骤4上述
  2. 我添加了所有可能的范围 Client ID

这是尝试发送电子邮件的代码:

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: 'user@domain.com',
    message: {
      raw: raw
    }
  }, (err, res) => {
    if (err) {
      console.error(err);
    } else {
      console.log(res);
    }
});
Run Code Online (Sandbox Code Playgroud)

我可以看到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 }
Run Code Online (Sandbox Code Playgroud)

但是,答案仍然是 400

ago*_*dis 12

所以我离解决方案只有半步,问题是在创建时const jwtClient = new google.auth.JWT(googleKey.client_email, null, googleKey.private_key, ['https://www.googleapis.com/auth/gmail.send'], null);我没有提到要冒充的帐户.

正确的初始化应该是: const jwtClient = new google.auth.JWT(googleKey.client_email, null, googleKey.private_key, ['https://www.googleapis.com/auth/gmail.send'], 'user@domain.com');

总而言之,正确的步骤是:

  1. 在Google Cloud Platform中创建了一个项目
  2. 创建了一个服务帐户
  3. 已启用Domain Wide Delegation服务帐户
  4. 以JSON格式下载服务帐户的密钥
  5. API Manager> Credentials我创造了OAuth 2.0 Client ID
  6. 为项目启用了Gmail API

在Google Apps管理控制台中:

  1. Security> Advanced Settings> Manage API client access我已经添加了Client ID从上述步骤4
  2. 我添加了所有可能的范围 Client ID

这是发送邮件的代码:

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);
     }
 });
Run Code Online (Sandbox Code Playgroud)

希望这对其他人有所帮助