Search code examples
google-apps-scriptgmail-apigoogle-workspaceworkspace

Add Gmail Signature usin AppScript


Hi I'm trying to add signatures to Workspace users. I'm using this solution. It's works but only with users that doesn't have any signatures and I would like to add new signatures (or override the previous ones). Another things is that it doesn't work for the owner either. I would appreciate your help.

This is my current code:

function setSignatureTest() {
  var user = {
    primaryEmail: "admin@domain.do",
    name: {
      fullName:'Admin Name',
      familyName:'Admin Last Name',
      givenName:'Admin Name'
    }
  };
  var test = setSignature(user.primaryEmail, user);

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

}

function listAllUsers() {
  var pageToken;
  var page;
  do {
    page = AdminDirectory.Users.list({
      domain: 'domain.com',
      orderBy: 'givenName',
      maxResults: 500,
      pageToken: pageToken
    });
    var users = page.users;

    var accountsToIgnore = [
      'test@example.com',
      'testtest@example.com'
    ];

    if (users) {
      for (var i = 0; i < users.length; i++) {
        var user = users[i];
        if (accountsToIgnore.indexOf(user.primaryEmail) == -1) {
          var userName = user.name.fullName;
          var userEmail = user.primaryEmail;
          var userOrgRole = user.organizations ? user.organizations[0].title : ''
          Logger.log('-- %s (%s) %s', userName, userEmail, userOrgRole);
          Logger.log('%s (%s)', user);
          setSignature(userEmail, user);
        }

      }
    } else {
      Logger.log('No users found.');
    }
    pageToken = page.nextPageToken;
  } while (pageToken);
}

function setSignature(email, userData) {
  var signatureSetSuccessfully = false;
  var authorizationScope = ['https://www.googleapis.com/auth/gmail.settings.sharing','https://www.googleapis.com/auth/gmail.settings.basic'];
  
  var service = getDomainWideDelegationService("Gmail: ", authorizationScope, 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 signatureTemplate = HtmlService.createHtmlOutputFromFile("signature").getContent();
  var userSig = signatureTemplate
          .replace(/(\r\n|\n|\r)/gm, "")
          .replace(/{email}/g, userData.primaryEmail)
          .replace(/{firstName}/g, userData.name.givenName)
          .replace(/{lastName}/g, userData.name.familyName)
          .replace(/{jobTitle}/g, userData.organizations ? userData.organizations[0].title : '')
  var resource = { 
    signature: userSig
  };
  
  var requestBody                = {};
  requestBody.headers            = {
    "Authorization": "Bearer " + service.getAccessToken(),
    "Accept": "application/json", 
    "Content-Type": "application/json",
  };
  requestBody.contentType        = "application/json";
  requestBody.method             = "PATCH";
  requestBody.payload            = JSON.stringify(resource);
  requestBody.muteHttpExceptions = false;

  var emailForUrl = encodeURIComponent(email);

  var url = `https://www.googleapis.com/gmail/v1/users/${email}/settings/sendAs/` + emailForUrl;

  try {
    var setSignatureResponse = UrlFetchApp.fetch(url, requestBody);
    signatureSetSuccessfully = true;
    Logger.log("setSignatureResponse on successful attempt:" + JSON.parse(setSignatureResponse).sendAsEmail);
  } catch (e) {
    Logger.log("Set signature with HTTP request failed: " + e);
  }
  
  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-----\n-----END PRIVATE KEY-----\n";
var OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL = 'SERVICE ACCOUNT CLIENTE EMAIL';

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);

}


Solution

  • You are doing a Method: users.settings.sendAs.create this is going to try to create a new one based upon the usersId, as far as i can tell from the docs you can only have one.

    POST https://gmail.googleapis.com/gmail/v1/users/{userId}/settings/sendAs
    

    Which will most likely fail if the user already has one set.

    I would try doing a sendAs List to see if the user has one set then if they do a users.settings.sendAs.patch to reset what every they have set personally. If they dont then use your create method.