0

I am trying to use a service account that has domain wide delegation so I can impersonate a user and do work on their G-Suite account (specifically trash emails). It seems like I can authenticate using the service account but when I go to run the code, I tells me that my account (not the service account) does not have domain wide delegation and fails. I don't know where I am going wrong or maybe this isn't possible on App Script. Code and Error message are below.

function run() {
  var service = getService();
  if (service.hasAccess()) {
    var url = 'https://www.googleapis.com/gmail/v1/users/' + '[impersonation_email]' + '/threads';
    var response = UrlFetchApp.fetch(url, {
      headers: {
        Authorization: 'Bearer ' + service.getAccessToken()
      },
      muteHttpExceptions: true
    });
    Gmail.Users.Threads.trash(userId=[impersonation_email], id=[specific_email_id]);
  } else {
    Logger.log(service.getLastError());
  }
}

function getService() {
  return OAuth2.createService('Gmail:' + '[impersonation_email]')
      .setTokenUrl('https://accounts.google.com/o/oauth2/token')      
      .setPrivateKey([service_account_PRIVATE_KEY_location])
      .setIssuer([service_account_CLIENT_EMAIL])
      .setSubject([impersonation_email ])
      .setPropertyStore(PropertiesService.getScriptProperties())
      .setScope('https://mail.google.com/')
}

Error Message:

API call to gmail.users.threads.trash failed with error: Delegation denied for [my email account]
  • Typo: `muteHttpExceptions` – TheMaster Mar 25 '19 at 12:24
  • `service_account_PRIVATE_KEY_location` Where is this location? Also just try executing `Logger.log(service.getLastError());` in a another function. – TheMaster Mar 25 '19 at 12:38
  • You can check this [SO post](https://stackoverflow.com/questions/26135310/gmail-api-returns-403-error-code-and-delegation-denied-for-user-email) wherein it says that this error should only occur if you're using a `userId` param that differs from the authorized user. That style of delegation isn't supported. Correct way is to impersonate the user when fetching the access token which you have tried and then stick to using '**me**' as `userId`. – Jessica Rodriguez Mar 25 '19 at 14:30

1 Answers1

1

Domain-wide delegation is only applicable to users in a GSuite domain and it can only be configured by an administrator within said domain.

Assuming the above statement describes your setup then you probably skipped a step.

I suspect you forgot to update your client API access from the Admin console.

You'll have to set every scope you intend to use in that dialog (in the link above) in your Admin console.

TheAddonDepot
  • 8,408
  • 2
  • 20
  • 30