0

I am using Gmail API java for sending mails to the users from a specific account of my company. A StoredCredential file/token is also stored for the said account. But using 'me', as mentioned here, is not working for me. Code:

//set the Mimemessage
            MimeMessage email = new MimeMessage(session);
            email.setFrom(new InternetAddress("me"));                  //from
            email.addRecipient(javax.mail.Message.RecipientType.TO,
            new InternetAddress(to));                                  //to 

//sending mail
            Message message = createMessage(email);
            message = service.users().messages().send(userId, message).execute();

This says:

message: Delegation denied for user@mycompany.com

As far as I understand, if I have the said token and required permissions, I should be able to send the mails, right?

Also, when I set the 'from' to a mail-address of my company account instead of 'me', the error remains.

How can I overcome this? Any workaround for this? Thanks.

Edit

Actually I'm using 4 Google APIs(Google Sheets, Drive, Gmail, and Script API), and I'm using a single oAuth check.

Code:

For Credentials

final String TOKENS_DIRECTORY_PATH = "mydirectory\\tokens";
final List<String> SCOPES = Arrays.asList(SheetsScopes.SPREADSHEETS,DriveScopes.DRIVE,DriveScopes.DRIVE_FILE,DriveScopes.DRIVE_METADATA,GmailScopes.GMAIL_COMPOSE,GmailScopes.GMAIL_SEND,GmailScopes.GMAIL_LABELS,ScriptScopes.MAIL_GOOGLE_COM);

        final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();

        // build GoogleClientSecrets from JSON file
        final String CREDENTIALS_FILE_PATH = "/credentials.json";

//       Load client secrets.
         InputStream in = GoogleAuthorizeUtil.class.getResourceAsStream(CREDENTIALS_FILE_PATH);

         GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

         // Build flow and trigger user authorization request.
         GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                 HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
                 .setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
                 .setAccessType("offline")
                 .build();
         LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
         
        // build Credential object
        Credential credential =  new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
        
        return credential;

The above-mentioned code is returning Google Credentials Object. Next Step is to create service for each API seperately:

Creating Services

    public static Gmail getGMailService() throws IOException, GeneralSecurityException {
        Credential credential = GoogleAuthorizeUtil.authorize();
        return new Gmail.Builder(
          GoogleNetHttpTransport.newTrustedTransport(), 
          JacksonFactory.getDefaultInstance(), credential)
          .setApplicationName(APPLICATION_NAME)
          .build();
    } 
    public static Gmail setup() throws GeneralSecurityException, IOException {
        Gmail gmailService;
        gmailService = getGMailService();
        return gmailService;
    }

The above returns Gmail service (similar code is done for all four API's service).

Now using this service to send mails:

Using the Service object to send mails

Gmail gservice = setup(); //returns Gmail service
// finally using the mail service---------------------
Properties props = new Properties();
            Session session = Session.getDefaultInstance(props, null);
            String user = "me";
            MimeMessage email = new MimeMessage(session);
            
            email.setFrom(new InternetAddress(user));
            email.addRecipient(javax.mail.Message.RecipientType.TO,new InternetAddress(to));
            email.setSubject(subject);
            
            MimeBodyPart mimeBodyPart = new MimeBodyPart();
            mimeBodyPart.setContent(bodyText, "text/html");
            
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(mimeBodyPart);
            
            email.setContent(multipart);
            
            
            Message message = createMessage(email);
            message = service.users().messages().send(userId, message).execute();

And all of this is called in a servlet when I click a submit button.

This should give the idea about the issue but please do tell if any more info/code is needed.

Thanks.

JustCurious
  • 344
  • 5
  • 15
  • Did you set up [domain wide deligation](https://developers.google.com/admin-sdk/directory/v1/guides/delegation) on the service account? – Linda Lawton - DaImTo Sep 22 '20 at 07:00
  • thanks for this@DaImTo. Can you please suggest what to do next, after this? – JustCurious Sep 22 '20 at 08:02
  • Hey @DaImTo! Can you please explain your comment why do I need DWD(as you said) and why the normal authorization and mail-sending will not work. I'm a little confused about this. Thanks. – JustCurious Sep 22 '20 at 09:14
  • It sounds like the storedCredential belongs to a different user than the one authenticating when running the code - is this your case? Delete the token file -this will trigger the creation of a new one next time you run the code. If this does not solve the problem -show your complete code including authentication. – ziganotschka Sep 22 '20 at 11:52
  • Thanks for the advice, but I can't tell you how many times I have deleted the stored token. @ziganotschka. Will try to post the minimal code to reproduce the error. Thanks. – JustCurious Sep 22 '20 at 11:57
  • You are signed into your browser with multiple Google accounts simulateneously? – ziganotschka Sep 22 '20 at 11:59
  • Ummm... Yes. Would that be a problem? @ziganotschka. So you are saying if I try with an incognito window. the error should not occur? – JustCurious Sep 22 '20 at 12:00
  • Yes, it is a well-known problem, because there is often a silent switch between active acocunts in the backgrounds. Sign out of all accounts but one and go through the token creation process and authentication again. – ziganotschka Sep 22 '20 at 12:02
  • what is ```Address already in use: JVM_Bind``` now? @ziganotschka – JustCurious Sep 22 '20 at 12:14
  • This I don't know - how did you obtain this error message? – ziganotschka Sep 22 '20 at 12:25
  • As you recommended, I signed out of all the accounts and tried to create a fresh token. But it is giving me this error while running the authentication check.@ziganotschka – JustCurious Sep 22 '20 at 12:31
  • How di you try to create a fresh token? By running a code based on the [quickstart](https://developers.google.com/gmail/api/quickstart/java)? Can you show your full code please? – ziganotschka Sep 22 '20 at 12:36
  • I have added the flow of code (my approach) for getting the services and using a service. Please review @ziganotschka. – JustCurious Sep 22 '20 at 12:57
  • What is the value of `userId`? It should be the either `me` or your PRIMARY email address (not alias). – ziganotschka Sep 22 '20 at 13:38
  • I was under the impression that the ```userId``` will be the mail I'm sending mail to. Okay. Working now. Thanks a lot for your precious time, kind sir. Really appreciate it. – JustCurious Sep 22 '20 at 13:50

0 Answers0