访问权限未授予或已过期 GMAIL API 和 Oauth2/如何使用 GMAIL API 和 GSuite 域设置电子邮件签名
Access not granted or expired GMAIL API and Oauth2 / How to set email signatures using GMAIL API with a GSuite domain
我目前正在为 google 组织的每个用户设置一个自动签名系统,但我没有成功。我遵循了 this 指南,但出现以下错误:Service_.getAccessToken @ Service.gs:454
。问题是:我无权访问文件 Service.gs
,当我 googled 我的错误时,在 google 的 github 或堆栈上没有答案overflow 的网站很适合我。
这是代码(来自指南,我当然更改了授权值):
var accountsToIgnore = [
'ignore-me@example.com',
'noreply@example.com'
];
var auth = {
"private_key": "-----BEGIN PRIVATE KEY-----\nABCDE\n-----END PRIVATE KEY-----\n",
"client_email": "name@project-id-XXX.iam.gserviceaccount.com",
"client_id": "INSERT_CLIENT_ID_HERE"
};
function go() {
var pageToken;
var page;
do {
page = AdminDirectory.Users.list({
domain: 'example.com',
orderBy: 'familyName',
maxResults: 250,
pageToken: pageToken,
projection: 'full',
// query: "email=your.email@example.com"
});
if (page.users) {
page.users.forEach( function (user){
if (accountsToIgnore.indexOf(user.primaryEmail) == -1) {
var service = getOAuthService(user.primaryEmail);
// Pull in the signatire template file contents into this variable
var signatureTemplate = HtmlService.createHtmlOutputFromFile("signature").getContent();
// Set up a userData variable, with some blank defaults as backups
var userData = {
email: user.primaryEmail,
firstName: user.name.givenName,
lastName: user.name.familyName,
jobTitle: "",
showJobTitle: true,
workingHours: "",
directPhone: ""
};
if (typeof user.customSchemas !== 'undefined') { // Email sig settings are set
if (typeof user.customSchemas.Email_signature !== 'undefined') {
if (typeof user.customSchemas.Email_signature.Show_job_title_in_signature !== 'undefined' && user.customSchemas.Email_signature.Show_job_title_in_signature == false) {
userData.showJobTitle = false;
}
if (typeof user.customSchemas.Email_signature.Working_Hours_Description !== 'undefined' && user.customSchemas.Email_signature.Working_Hours_Description != "") {
userData.workingHours = "<br /><br /><i>"+user.customSchemas.Email_signature.Working_Hours_Description+"</i><br />";
}
}
}
if (user.hasOwnProperty('organizations') && user.organizations[0].hasOwnProperty('title') && typeof user.organizations[0].title !== "undefined" && userData.showJobTitle == true) {
userData.jobTitle = user.organizations[0].title+"<br />";
}
if (user.hasOwnProperty('phones') && Array.isArray(user.phones) && user.phones.length >0) {
for (var p = 0; p < user.phones.length; p++) {
if (user.phones[p].customType == "Google Voice") {
// Depending on where in the world you are, you may need to adjust this formatting for your own needs... This replaces the +44 UK country code with a local "0" and adds a space after the local area code for formatting.
userData.directPhone = "<br />D: " + user.phones[p].value.replace('+44', '0').replace('1158', '1158 ');
}
}
}
// Replace the placeholders as seen in the signature.html file with the actual data from the userData variable set up earlier.
var userSig = signatureTemplate
.replace(/(\r\n|\n|\r)/gm, "")
.replace(/{email}/g, userData.email)
.replace(/{firstName}/g, userData.firstName)
.replace(/{lastName}/g, userData.lastName)
.replace(/{jobTitle}/g, userData.jobTitle)
.replace(/{workingHours}/g, userData.workingHours)
.replace(/{directNumber}/g, userData.directPhone);
var sigAPIUrl = Utilities.formatString('https://www.googleapis.com/gmail/v1/users/%s/settings/sendAs/%s',userData.email, userData.email);
var response = UrlFetchApp.fetch(sigAPIUrl, {
method: "PUT",
muteHttpExceptions: true,
contentType: "application/json",
headers: {
Authorization: 'Bearer ' + service.getAccessToken()
},
payload: JSON.stringify({
'signature': userSig
})
});
if (response.getResponseCode() !== 200) {
Logger.log('There was an error: ' + response.getContentText());
} else {
Logger.log("Signature updated for "+user.primaryEmail);
}
}
});
} else {
Logger.log('No users found.');
}
pageToken = page.nextPageToken;
} while (pageToken);
}
function getOAuthService(userId) {
return OAuth2.createService("Signature Setter "+userId)
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth') // Added thanks to research
.setClientId(auth.client_id) // same
.setCallbackFunction('authCallback') // same
.setPrivateKey(auth.private_key)
.setIssuer(auth.client_email)
.setPropertyStore(PropertiesService.getScriptProperties())
.setSubject(userId)
.setParam('access_type', 'offline')
.setScope('https://www.googleapis.com/auth/gmail.settings.basic https://www.googleapis.com/auth/gmail.settings.sharing');
}
问题来自 GMAIL API(google 的 API 页面 100% 错误)或来自 Google 的 OAuth2。
这是我发现的一些与我的问题相关的页面:
- github Issue
- Stack Overflow
来自 apps.google 的完整错误代码:Error: Access not granted or expired. Service_.getAccessToken @ Service.gs:454
凭据API(警告标志表示已自动创建):
https://prnt.sc/yy8kg5
我在 google 的应用程序脚本编辑器上拥有的文件和服务:https://prnt.sc/yy9dyw
感谢您的帮助。
感谢上面的回答和一些个人研究,我设法使用 Google 控制台和 Gmail API.
设置了自动签名
这是有关如何设置系统的分步指南。
免责声明:我不是专业人士,我 可能会 犯错(如果我错了,请随时纠正我 :)),但我仍然想这个“指南”...也许它可以帮助知道的人?
1. GOOGLE 应用程序脚本
这些步骤适用于“新”编辑器。
- 转到此 link (google apps scripts) 并创建一个新脚本。
- 转到设置 > 选中“在编辑器中显示
appsscript.json
清单文件”
- 编辑器 > 编辑
appsscript.json
并添加 oauthScopes:
{
...
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.settings.basic",
"https://www.googleapis.com/auth/gmail.settings.sharing",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/admin.directory.user",
"https://www.googleapis.com/auth/script.external_request"
]
...
}
- 在“编辑器”选项卡中: 添加 OAuth2 库
- 添加
Gmail
和 AdminDirectory
服务
- 复制此 code (based on this 页面)并添加您的
OAUTH2_SERVICE_ACCOUNT_PRIVATE_KEY
和 OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL
(您将在下一部分中获得)
- 创建一个名为
signature.html
的新文件 HTML
- 在“GCP Projet”下的“设置”选项卡中:添加您的项目编号(您将在下一部分中获得)
2。 GCP 项目
- 转到此 link 并创建一个项目
- 在项目信息卡上,您可以看到“项目编号”,将其复制并粘贴到 Google 脚本设置选项卡中。
- 转到“APIs & Services”> Credentials > 创建“Service Accounts”(您不需要角色)
- 编辑您刚刚创建的服务帐户并选中“服务帐户状态”下的“启用 G Suite 全域委派”并创建一个新的
json
密钥(这将使您下载一个文件,将其保存在安全的地方,共享它会导致您的 G Suite 域中出现安全漏洞(不要忘记在脚本中添加 OAUTH2_SERVICE_ACCOUNT_PRIVATE_KEY
和 OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL
).
3。 Google 管理员(G Suite 的组织页面)
- 转到安全 > API 控制 >“管理全域授权”
- 添加新的并添加此范围:
- https://www.googleapis.com/auth/gmail.settings.basic
- https://www.googleapis.com/auth/gmail.settings.sharing
- https://www.googleapis.com/auth/userinfo.email
- https://www.googleapis.com/auth/admin.directory.user
- https://www.googleapis.com/auth/script.external_request
4.结论
现在是测试内容的部分,不要忘记通过 signature.html
文件创建签名;查看 code.gs
文件以创建包含用户信息的内容,它非常明确。
如有任何问题,欢迎post评论,我会尽力为您解答。
我目前正在为 google 组织的每个用户设置一个自动签名系统,但我没有成功。我遵循了 this 指南,但出现以下错误:Service_.getAccessToken @ Service.gs:454
。问题是:我无权访问文件 Service.gs
,当我 googled 我的错误时,在 google 的 github 或堆栈上没有答案overflow 的网站很适合我。
这是代码(来自指南,我当然更改了授权值):
var accountsToIgnore = [
'ignore-me@example.com',
'noreply@example.com'
];
var auth = {
"private_key": "-----BEGIN PRIVATE KEY-----\nABCDE\n-----END PRIVATE KEY-----\n",
"client_email": "name@project-id-XXX.iam.gserviceaccount.com",
"client_id": "INSERT_CLIENT_ID_HERE"
};
function go() {
var pageToken;
var page;
do {
page = AdminDirectory.Users.list({
domain: 'example.com',
orderBy: 'familyName',
maxResults: 250,
pageToken: pageToken,
projection: 'full',
// query: "email=your.email@example.com"
});
if (page.users) {
page.users.forEach( function (user){
if (accountsToIgnore.indexOf(user.primaryEmail) == -1) {
var service = getOAuthService(user.primaryEmail);
// Pull in the signatire template file contents into this variable
var signatureTemplate = HtmlService.createHtmlOutputFromFile("signature").getContent();
// Set up a userData variable, with some blank defaults as backups
var userData = {
email: user.primaryEmail,
firstName: user.name.givenName,
lastName: user.name.familyName,
jobTitle: "",
showJobTitle: true,
workingHours: "",
directPhone: ""
};
if (typeof user.customSchemas !== 'undefined') { // Email sig settings are set
if (typeof user.customSchemas.Email_signature !== 'undefined') {
if (typeof user.customSchemas.Email_signature.Show_job_title_in_signature !== 'undefined' && user.customSchemas.Email_signature.Show_job_title_in_signature == false) {
userData.showJobTitle = false;
}
if (typeof user.customSchemas.Email_signature.Working_Hours_Description !== 'undefined' && user.customSchemas.Email_signature.Working_Hours_Description != "") {
userData.workingHours = "<br /><br /><i>"+user.customSchemas.Email_signature.Working_Hours_Description+"</i><br />";
}
}
}
if (user.hasOwnProperty('organizations') && user.organizations[0].hasOwnProperty('title') && typeof user.organizations[0].title !== "undefined" && userData.showJobTitle == true) {
userData.jobTitle = user.organizations[0].title+"<br />";
}
if (user.hasOwnProperty('phones') && Array.isArray(user.phones) && user.phones.length >0) {
for (var p = 0; p < user.phones.length; p++) {
if (user.phones[p].customType == "Google Voice") {
// Depending on where in the world you are, you may need to adjust this formatting for your own needs... This replaces the +44 UK country code with a local "0" and adds a space after the local area code for formatting.
userData.directPhone = "<br />D: " + user.phones[p].value.replace('+44', '0').replace('1158', '1158 ');
}
}
}
// Replace the placeholders as seen in the signature.html file with the actual data from the userData variable set up earlier.
var userSig = signatureTemplate
.replace(/(\r\n|\n|\r)/gm, "")
.replace(/{email}/g, userData.email)
.replace(/{firstName}/g, userData.firstName)
.replace(/{lastName}/g, userData.lastName)
.replace(/{jobTitle}/g, userData.jobTitle)
.replace(/{workingHours}/g, userData.workingHours)
.replace(/{directNumber}/g, userData.directPhone);
var sigAPIUrl = Utilities.formatString('https://www.googleapis.com/gmail/v1/users/%s/settings/sendAs/%s',userData.email, userData.email);
var response = UrlFetchApp.fetch(sigAPIUrl, {
method: "PUT",
muteHttpExceptions: true,
contentType: "application/json",
headers: {
Authorization: 'Bearer ' + service.getAccessToken()
},
payload: JSON.stringify({
'signature': userSig
})
});
if (response.getResponseCode() !== 200) {
Logger.log('There was an error: ' + response.getContentText());
} else {
Logger.log("Signature updated for "+user.primaryEmail);
}
}
});
} else {
Logger.log('No users found.');
}
pageToken = page.nextPageToken;
} while (pageToken);
}
function getOAuthService(userId) {
return OAuth2.createService("Signature Setter "+userId)
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth') // Added thanks to research
.setClientId(auth.client_id) // same
.setCallbackFunction('authCallback') // same
.setPrivateKey(auth.private_key)
.setIssuer(auth.client_email)
.setPropertyStore(PropertiesService.getScriptProperties())
.setSubject(userId)
.setParam('access_type', 'offline')
.setScope('https://www.googleapis.com/auth/gmail.settings.basic https://www.googleapis.com/auth/gmail.settings.sharing');
}
问题来自 GMAIL API(google 的 API 页面 100% 错误)或来自 Google 的 OAuth2。
这是我发现的一些与我的问题相关的页面:
- github Issue
- Stack Overflow
来自 apps.google 的完整错误代码:Error: Access not granted or expired. Service_.getAccessToken @ Service.gs:454
凭据API(警告标志表示已自动创建): https://prnt.sc/yy8kg5
我在 google 的应用程序脚本编辑器上拥有的文件和服务:https://prnt.sc/yy9dyw
感谢您的帮助。
感谢上面的回答和一些个人研究,我设法使用 Google 控制台和 Gmail API.
设置了自动签名这是有关如何设置系统的分步指南。
免责声明:我不是专业人士,我 可能会 犯错(如果我错了,请随时纠正我 :)),但我仍然想这个“指南”...也许它可以帮助知道的人?
1. GOOGLE 应用程序脚本
这些步骤适用于“新”编辑器。
- 转到此 link (google apps scripts) 并创建一个新脚本。
- 转到设置 > 选中“在编辑器中显示
appsscript.json
清单文件” - 编辑器 > 编辑
appsscript.json
并添加 oauthScopes:
{
...
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.settings.basic",
"https://www.googleapis.com/auth/gmail.settings.sharing",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/admin.directory.user",
"https://www.googleapis.com/auth/script.external_request"
]
...
}
- 在“编辑器”选项卡中: 添加 OAuth2 库
- 添加
Gmail
和AdminDirectory
服务 - 复制此 code (based on this 页面)并添加您的
OAUTH2_SERVICE_ACCOUNT_PRIVATE_KEY
和OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL
(您将在下一部分中获得) - 创建一个名为
signature.html
的新文件 HTML
- 在“GCP Projet”下的“设置”选项卡中:添加您的项目编号(您将在下一部分中获得)
2。 GCP 项目
- 转到此 link 并创建一个项目
- 在项目信息卡上,您可以看到“项目编号”,将其复制并粘贴到 Google 脚本设置选项卡中。
- 转到“APIs & Services”> Credentials > 创建“Service Accounts”(您不需要角色)
- 编辑您刚刚创建的服务帐户并选中“服务帐户状态”下的“启用 G Suite 全域委派”并创建一个新的
json
密钥(这将使您下载一个文件,将其保存在安全的地方,共享它会导致您的 G Suite 域中出现安全漏洞(不要忘记在脚本中添加OAUTH2_SERVICE_ACCOUNT_PRIVATE_KEY
和OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL
).
3。 Google 管理员(G Suite 的组织页面)
- 转到安全 > API 控制 >“管理全域授权”
- 添加新的并添加此范围:
- https://www.googleapis.com/auth/gmail.settings.basic
- https://www.googleapis.com/auth/gmail.settings.sharing
- https://www.googleapis.com/auth/userinfo.email
- https://www.googleapis.com/auth/admin.directory.user
- https://www.googleapis.com/auth/script.external_request
4.结论
现在是测试内容的部分,不要忘记通过 signature.html
文件创建签名;查看 code.gs
文件以创建包含用户信息的内容,它非常明确。
如有任何问题,欢迎post评论,我会尽力为您解答。