google-apps-script - 如何使用 Gmail API、OAuth2 for Apps 脚本和域范围委派为 G Suite 域中的用户设置电子邮件签名

标签 google-apps-script google-oauth gmail-api google-workspace

这是我发布的上一个问题/答案( How to use the Google Email Settings API and the OAuth2 for Apps Script Library to set email signatures for users in a Google Apps domain )的后续,但自 Email Settings API 以来我正在创建一个新问题已被弃用,现在的过程有很大不同。

作为 G Suite 域的管理员,您如何使用 Gmail API通过 Google Apps 脚本以编程方式设置您域中用户的电子邮件签名?

最佳答案

此方法使用 Gmail API、OAuth2 for Apps 脚本库和“域范围的授权”,这是 G Suite 管理员代表域内用户进行 API 调用的一种方式。

第一步:确保 OAuth2 For Apps Script库已添加到您的项目中。

第 2 步:设置“域范围的授权”。有一个页面here解释如何为 Drive API 执行此操作,但对于任何 Google API(包括 Gmail API)几乎都是相同的。按照该页面上的步骤直到并包括“将域范围的权限委派给您的服务帐户”步骤。

第 3 步:下面的代码包括了在前面的步骤完成后如何设置签名:

function setSignatureTest() {

  var email = 'test@test.com';

  var signature = 'test signature';

  var test = setSignature(email, signature);

  Logger.log('test result: ' + test);

}


function setSignature(email, signature) {

  Logger.log('starting setSignature');

  var signatureSetSuccessfully = false;

  var service = getDomainWideDelegationService('Gmail: ', 'https://www.googleapis.com/auth/gmail.settings.basic', email);

  if (!service.hasAccess()) {

    Logger.log('failed to authenticate as user ' + email);

    Logger.log(service.getLastError());

    signatureSetSuccessfully = service.getLastError();

    return signatureSetSuccessfully;

  } else Logger.log('successfully authenticated as user ' + email);

  var username = email.split("@")[0];

  var resource = { signature: signature };

  var requestBody                = {};
  requestBody.headers            = {'Authorization': 'Bearer ' + service.getAccessToken()};
  requestBody.contentType        = "application/json";
  requestBody.method             = "PUT";
  requestBody.payload            = JSON.stringify(resource);
  requestBody.muteHttpExceptions = false;

  var emailForUrl = encodeURIComponent(email);

  var url = 'https://www.googleapis.com/gmail/v1/users/me/settings/sendAs/' + emailForUrl;

  var maxSetSignatureAttempts     = 20;
  var currentSetSignatureAttempts = 0;

  do {

    try {

      currentSetSignatureAttempts++;

      Logger.log('currentSetSignatureAttempts: ' + currentSetSignatureAttempts);

      var setSignatureResponse = UrlFetchApp.fetch(url, requestBody);

      Logger.log('setSignatureResponse on successful attempt:' + setSignatureResponse);

      signatureSetSuccessfully = true;

      break;

    } catch(e) {

      Logger.log('set signature failed attempt, waiting 3 seconds and re-trying');

      Utilities.sleep(3000);

    }

    if (currentSetSignatureAttempts >= maxSetSignatureAttempts) {

      Logger.log('exceeded ' + maxSetSignatureAttempts + ' set signature attempts, deleting user and ending script');

      throw new Error('Something went wrong when setting their email signature.');

    }

  } while (!signatureSetSuccessfully);

  return signatureSetSuccessfully;

}

// these two things are included in the .JSON file that you download when creating the service account and service account key
var OAUTH2_SERVICE_ACCOUNT_PRIVATE_KEY  = '-----BEGIN PRIVATE KEY-----\nxxxxxxxxxxxxxxxxxxxxx\n-----END PRIVATE KEY-----\n';
var OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL = 'xxxxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com';


function getDomainWideDelegationService(serviceName, scope, email) {

  Logger.log('starting getDomainWideDelegationService for email: ' + email);

  return OAuth2.createService(serviceName + email)
      // Set the endpoint URL.
      .setTokenUrl('https://accounts.google.com/o/oauth2/token')

      // Set the private key and issuer.
      .setPrivateKey(OAUTH2_SERVICE_ACCOUNT_PRIVATE_KEY)
      .setIssuer(OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL)

      // Set the name of the user to impersonate. This will only work for
      // Google Apps for Work/EDU accounts whose admin has setup domain-wide
      // delegation:
      // https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority
      .setSubject(email)

      // Set the property store where authorized tokens should be persisted.
      .setPropertyStore(PropertiesService.getScriptProperties())

      // Set the scope. This must match one of the scopes configured during the
      // setup of domain-wide delegation.
      .setScope(scope);

}

请注意:带有 maxSetSignatureAttempts 的 do-while 循环和 currentSetSignatureAttempts变量不是必需的。我添加它是因为如果您在创建 Google 帐户并分配 G Suite 许可证后立即尝试设置签名,有时 Gmail API 会返回一个错误,就好像用户尚未创建一样。如果出现错误,do-while 循环基本上会等待 3 秒,然后再试一次,最多 x 次。如果您为现有用户设置签名,则不应该有这个问题。另外,原本我只是有一个固定的10秒 sleep ,但大部分时间不需要那么长时间,但其他时候它仍然会失败。所以这个循环比固定的 sleep 量要好。

关于google-apps-script - 如何使用 Gmail API、OAuth2 for Apps 脚本和域范围委派为 G Suite 域中的用户设置电子邮件签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40936257/

相关文章:

gmail-api - 如何获取新邮件的ID

google-apps-script - 自定义连接器 getData : undocumented 中的 Google Data Studio 分页

php - 是否可以使用 Google Docs API 插入水平规则?

google-apps-script - 更新 Google 表格 "Filter View"并添加新范围

google-api - Google OAuth2 重新授权在同意页面上缺少权限

api - Google REST API - RFC 2822 格式和 base64url 编码字符串中的消息

google-apps-script - 使用 GAS 和 API 创建自定义 "from"发送别名

javascript - 形成 html 谷歌脚本

android - 无法实例化 GoogleApiClient

python - 使用 Python 3.4 和 Django 1.7 的 Oauth2