使用Google Apps脚本设置域用户的电子邮件签名

时间:2017-04-24 20:54:33

标签: google-apps-script gmail-api

我确定这里有一些简单的东西,我在这里失踪了,但我已经在这一段时间内待了一个多星期了。&无法理解它,所以我问。我将问题作为前提,我不是真正的程序员!我是网络/系统管理员,需要使用Google Apps脚本为我们的G Suite域中的所有用户配置签名。我已经有了相当多的bash /命令行/ PowerShell体验但是当谈到"真正的"编程语言我什么都不知道。

据说我在另一个SO页面How to use the Gmail API, OAuth2 for Apps Script, and Domain-Wide Delegation to set email signatures for users in a G Suite domain上阅读有关如何设置电子邮件签名的信息。当我第一次尝试这个剧本时,我根本无法使用它。我修改了它&设法让它现在进行身份验证但是当它到达应该设置签名的部分时没有任何反应,它似乎只是退出&那就是它!这是我的修改后的代码减去任何私有位:

// Adapted from script at https://stackoverflow.com/questions/40936257/how-to-use-the-gmail-api-oauth2-for-apps-script-and-domain-wide-delegation-to

// 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-----\n_MY_KEY_GOES_HERE_\n-----END PRIVATE KEY-----\n';
var OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL = 'somethingsomethingsomething@project-id-xxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com';

function setSignatureTest() {
  var email = 'user@domain.com';
  var signature = 'my 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', OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL);
  if (!service.hasAccess()) {
    Logger.log('failed to authenticate as user ' + OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL);
    Logger.log(service.getLastError());
    signatureSetSuccessfully = service.getLastError();
    return signatureSetSuccessfully;
  } else Logger.log('successfully authenticated as user ' + OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL);
  var resource = { 'sendAsEmail' : email, 'userId' : OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL, 'signature' : signature };
  var options = 
      {
        'method' : 'put',
        'contentType' : 'application/json',
        'Authorization' : 'Bearer ' + service.getAccessToken(),
        'payload' : resource
      };
  var emailForUrl = encodeURIComponent(email);
  var url = 'https://www.googleapis.com/gmail/v1/users/me/settings/sendAs/' + emailForUrl;
  var maxSetSignatureAttempts     = 1;
  var currentSetSignatureAttempts = 0;
  do {
    try {
      currentSetSignatureAttempts++;
      Logger.log('currentSetSignatureAttempts: ' + currentSetSignatureAttempts);
      var setSignatureResponse = UrlFetchApp.fetch(url, JSON.stringify(options));
      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');
      Logger.log('URL:  ' + url);
      Logger.log('Value of JSON.stringify(options):' + JSON.stringify(options));
      Logger.log('Value of setSignatureResponse:' + setSignatureResponse);
      throw new Error('Something went wrong when setting their email signature.');
    }
  } while (!signatureSetSuccessfully);
  return signatureSetSuccessfully;
}

function getDomainWideDelegationService(serviceName, scope, OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL) {
  Logger.log('starting getDomainWideDelegationService for email: ' + OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL);
  return OAuth2.createService(serviceName + OAUTH2_SERVICE_ACCOUNT_CLIENT_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(OAUTH2_SERVICE_ACCOUNT_CLIENT_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);
}

有人对此有任何想法吗?我确定其他人之前已做过这件事。我在某个地方犯了一个简单的错误。我觉得这个问题出现在我的有效载荷选项中,但是我真的不确定如何解决这个问题。我尝试的一切都没有。

编辑:请参阅下面的清理日志输出。

[17-04-24 18:24:27:087 PDT] starting setSignature
[17-04-24 18:24:27:088 PDT] starting getDomainWideDelegationService for email: somethingsomethingsomething@project-id-xxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com
[17-04-24 18:24:27:521 PDT] successfully authenticated as user somethingsomethingsomething@project-id-xxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com
[17-04-24 18:24:27:550 PDT] currentSetSignatureAttempts: 1
[17-04-24 18:24:27:552 PDT] set signature failed attempt, waiting 3 seconds and re-trying
[17-04-24 18:24:30:554 PDT] exceeded 1 set signature attempts, deleting user and ending script
[17-04-24 18:24:30:554 PDT] URL:  https://www.googleapis.com/gmail/v1/users/me/settings/sendAs/user%40domain.com
[17-04-24 18:24:30:555 PDT] Value of JSON.stringify(options):{"method":"put","contentType":"application/json","Authorization":"Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”,”payload":{"sendAsEmail”:”user@domain.com”,”userId":"somethingsomethingsomething@project-id-xxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com","signature":"my test signature"}}
[17-04-24 18:24:30:556 PDT] Value of setSignatureResponse:undefined

更改后的日志输出2017.04.25.16:00:

[17-04-25 12:37:00:260 PDT] starting setSignature
[17-04-25 12:37:00:261 PDT] starting getDomainWideDelegationService for email: somethingsomethingsomething@project-id-xxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com
[17-04-25 12:37:00:278 PDT] successfully authenticated as user somethingsomethingsomething@project-id-xxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com
[17-04-25 12:37:00:289 PDT] currentSetSignatureAttempts: 1
[17-04-25 12:37:00:343 PDT] setSignatureResponse on successful attempt:{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "failedPrecondition",
    "message": "Bad Request"
   }
  ],
  "code": 400,
  "message": "Bad Request"
 }
}

[17-04-25 12:37:00:343 PDT] test result: true

2 个答案:

答案 0 :(得分:0)

授权需要像这样进入请求标题

var options = 
      {
        'headers' : {'Authorization' : 'Bearer ' + service.getAccessToken()},
        'method' : 'put',
        'contentType' : 'application/json',
        'payload' : JSON.stringify(resource)
      };

最后你对api的调用将如下所示:

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

希望能解决问题

答案 1 :(得分:0)

尝试将contenType更改为ctAPPLICATION_JSON

"contentType": "ctAPPLICATION_JSON",