Reputation: 170
i'm currently setting up an automatic signature system for every user of a google organisation but I haven't succeed to do so. I followed this guide but I have the following error : Service_.getAccessToken @ Service.gs:454
. The problem is that: I don't have access to the file Service.gs
and when I googled my error, no answers, either on google's github or stack overflow's website suits me well.
Here is the code (from the guide, I of course changed the auth values):
var accountsToIgnore = [
'[email protected]',
'[email protected]'
];
var auth = {
"private_key": "-----BEGIN PRIVATE KEY-----\nABCDE\n-----END PRIVATE KEY-----\n",
"client_email": "[email protected]",
"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 protected]"
});
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');
}
The problem comes from the GMAIL API (100% errors on the google's API page) or from Google's OAuth2.
Here is some pages I found that are related to my problem:
Full error code from apps.google: Error: Access not granted or expired. Service_.getAccessToken @ Service.gs:454
The credentials API (the warning sign mean that it has been created automatically): https://prnt.sc/yy8kg5
The files and services I have on google's apps script editor: https://prnt.sc/yy9dyw
Thanks for the help.
Upvotes: 1
Views: 410
Reputation: 170
Thanks to the answers above and some personal research, I managed to set up an automatic signature with Google Console and Gmail API.
This is a step by step guide on how to set up the system.
DISCLAIMER: I'm not a professionnal and I may do mistakes (so feel free to correct me if i'm wrong :) ), but I still want to make this "guide"... maybe it can help someone, who knows ?
1. GOOGLE APPS SCRIPTS
The steps are for the "New" Editor.
appsscript.json
manifest file in editor"appsscript.json
and add the 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"
]
...
}
Gmail
and AdminDirectory
ServicesOAUTH2_SERVICE_ACCOUNT_PRIVATE_KEY
and OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL
(you'll get it in the next part)signature.html
2. GCP Project
json
key (this will make you dowload a file, save it in a safe place, sharing this will result in a security leak in your G Suite domain (don't forget to add the OAUTH2_SERVICE_ACCOUNT_PRIVATE_KEY
and OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL
in the script).3. Google Admin (G Suite's Organization page)
- 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. Conclusion
It's now the part where you test the stuff, don't forget to create your signature via the signature.html
file; look at the code.gs
file to create something with user's info, it's pretty explicit.
If you have any problems, feel free to post a comment, i'll do my best to answer you.
Upvotes: 2