簡體   English   中英

使用 nodejs 中的服務帳戶域范圍委派通過 Google Apps Gmail 發送郵件

[英]Send mail via Google Apps Gmail using service account domain wide delegation in nodejs

我已經閱讀了 2 天的教程和示例,但沒有成功。 我想在 NodeJS 環境中使用 Google Apps Gmail 帳戶發送電子郵件,但是,我從 Google API 收到400響應:

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

這是我到目前為止所做的:

  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我添加了上面第4步中的Client ID
  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);
    }
});

我可以看到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 }

但是,響應仍然是400

所以我接近解決方案的一半,問題是在創建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我添加了上面第 4 步中的Client ID
  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);
     }
 });

希望對其他人有幫助

非常感謝@agoldis。 摘要步驟和代碼都非常有幫助。

它幫助我了解了需要在 GoogleWorkspace 和通信路徑的 ApplicationCode 端修復的一些問題。 下面是我為任何需要它的人提供的 c# 實現。

private static void Try4()
{
  try {
     //file included in project with properties:  CopyToOutputDirectory = CopyAlways
     var credential = GoogleCredential.FromFile("MyPrj-MyServiceAccount-Credentials.json")       
                      .CreateScoped(new[] { GmailService.Scope.GmailSend })
                      .CreateWithUser("WhoIAmImpersonating@bla.com")
                      .UnderlyingCredential as ServiceAccountCredential;

     var service = new GmailService(new BaseClientService.Initializer() { HttpClientInitializer = credential });

     var nl = Environment.NewLine;
     string plainText =         "From:         WhoIAmImpersonating@bla.com" 
                         + nl + "To:           myfriend@gmail.com,"
                         + nl + "Subject:      This is the Subject" 
                         + nl + "Content-Type: text/html; charset=us-ascii" 
                         + nl 
                         + nl + "This is the message text.";
     var newMsg = new Message() { Raw = Base64UrlEncode(plainText) };

     service.Users.Messages.Send(newMsg, "WhoIAmImpersonating@bla.com").Execute();
     Console.WriteLine("Message Sent OK");
  }
  catch (Exception ex) {
      Console.WriteLine("Message failed");
  }
}



private static string Base64UrlEncode(string input)
{
  var inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
  return Convert.ToBase64String(inputBytes)
                .Replace('+', '-')
                .Replace('/', '_')
                .Replace("=", "" );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM