【发布时间】:2017-09-21 16:38:23
【问题描述】:
我确定我在这里遗漏了一些简单的东西,但我已经做了一个多星期了,无法弄清楚,所以我在问。我将以我不是真正的程序员作为我的问题的序言!我是一名网络/系统管理员,需要使用 Google Apps 脚本为我们 G Suite 域中的所有用户配置签名。我有相当多的 bash/命令行/PowerShell 经验,但对于“真正的”编程语言,我几乎一无所知。
话虽如此,我在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 的另一个 SO 页面上阅读了有关如何设置电子邮件签名的信息。当我第一次尝试这个脚本时,我根本无法让它工作。我已经对其进行了修改并设法让它现在进行身份验证,但是当它到达应该设置签名的部分时没有任何反应,它似乎只是退出了,就是这样!这是我修改后的代码减去任何私有位:
// 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
【问题讨论】:
-
您的日志或执行记录说什么? (查看>日志/执行记录)
-
请查看我刚刚所做的编辑,谢谢 Jack!
-
您需要将其更改为有效的 id
var email = 'user@domain.com';或者您的 id 以确保它更改您的签名 -
我在这里用“user@domain.com”替换了一个真实的电子邮件地址来隐藏帐户。当我运行脚本时,我在这里使用的是我的真实电子邮件。
-
我的最终建议是在'catch(e) { }' 块中添加以下
Logger.log(e.message),以找出我们的错误到底是什么。代码原样跳过错误,实际上并没有告诉您错误是什么。等效地,您可以删除 try 和 catch(e) 并让函数运行,它会在运行时向您显示错误。
标签: google-apps-script gmail-api