Search code examples
kotlingmail-api

Gmail API returns "Delegation denied for my.email@email.com" when setting a different email as recipient


I am using the Gmail API to create drafts. When I create a draft message where the recipient is my own email (the one that generates the credential), everything works fine but when I try to use a different email, the following message is printed:

{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Delegation denied for my.email.here@gmail.com",
    "reason" : "forbidden"
  } ],
  "message" : "Delegation denied for my.email.here@gmail.com",
  "status" : "PERMISSION_DENIED"
}
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146)

That's how I'm assembling my MimeMessage:

val props = Properties()
val session = Session.getDefaultInstance(props, null)
val message = MimeMessage(session)
message.setFrom(message.sender)
message.addRecipient(JavaxMessage.RecipientType.TO, InternetAddress("different.email.here@gmail.com"))
message.subject = subject

The scopes I am using:

// "https://www.googleapis.com/auth/gmail.compose"
GmailScopes.GMAIL_COMPOSE

I've tried a lot of stuff to make it work, but I didn't have any success.


Solution

  • Delegation denied for my.email.here@gmail.com

    This email appears to be a standard gmail email address. You appear to be trying to delegate a service account to a user with a standard gmail email address.

    Service accounts only work with google workspace email accounts. You need to set up domain wide delegation to the serveries account and then you can set the delegation user.

    If you want to use a standard gmail account you will need to authorize the user using Oauth2.

    private fun getCredentials(httpTransport: NetHttpTransport): Credential? {
        val inputStream = File("credentials.json").inputStream()
        val clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, InputStreamReader(inputStream))
        val flow = GoogleAuthorizationCodeFlow.Builder(httpTransport, JSON_FACTORY, clientSecrets, SCOPES)
                .setDataStoreFactory(FileDataStoreFactory(File(TOKENS_DIRECTORY_PATH)))
                .setAccessType("offline")
                .build()
        val receiver = LocalServerReceiver.Builder().setPort(8888).build()
        return AuthorizationCodeInstalledApp(flow, receiver).authorize("user")
    }
    
    
    
     public static MimeMessage createEmail(String to,
                                              String from,
                                              String subject,
                                              String bodyText)
                throws MessagingException {
            Properties props = new Properties();
            Session session = Session.getDefaultInstance(props, null);
    
            MimeMessage email = new MimeMessage(session);
    
            email.setFrom(new InternetAddress(from));
            email.addRecipient(javax.mail.Message.RecipientType.TO,
                    new InternetAddress(to));
            email.setSubject(subject);
            email.setText(bodyText);
            return email;
        }
    

    Sending