Welcome to Part 11 of this series of guides on how to integrate Gmail with Angular and Spring Boot.

It's been a long journey, but now you'll finally get to show the end user some emails.

That's going to be fairly easy at this point. You've added all the support classes you need. Now all you have to do is set up an endpoint.

And you'll do that part in a controller class that you've also already created.

In this guide I'll walk you through that simple process.

Or, if you prefer, you can go straight to the code on GitHub.

Previously, on "This Series"

Thus far in the series, you have:

  • Created an OAuth2 client ID and secret on Google Cloud Console
  • Enabled the Gmail API via Google Cloud Console
  • Set the necessary properties in your Spring Boot application.properties file 
  • Set up a DataStore implementation with its associated factory
  • Set up a refresh listener
  • Created a utility class that handles the Google authorization code flow
  • Set up proper Gmail consent with the Google Cloud Platform
  • Created a controller that handles a request to get the Google authorization code flow URL
  • Used Postman to get the Google authorization code URL
  • Used that URL to authorize your application to access your Gmail inbox
  • Updated the controller so it handles a token request
  • Updated the utility class so it creates the credential from a token
  • Persisted that credential
  • Used Postman to retrieve the token
  • Learned why you didn't actually need to retrieve the token
  • Learned about the structure of the Message object
  • Learned about MIME
  • Created an Email type that gets sent back to the client
  • Wrote code that converts a Message object to an Email object
  • Instantiated the Gmail service
  • Used the Gmail service to retrieve just the messages you want to retrieve
  • Used the Gmail service to extracted full Message objects from very lightweight objects

And if you haven't done those things, then you should take a look at Part 1 and work forward from there.

Coming up, on "This Series"

In this part of the series, you will:

  • Add a new endpoint to listen for inbox requests
  • Use that endpoint to send back the user's most recent emails

And then you can go back to the beach.

Circling Back to the Controller

You've already created a controller class. Now it's time to add a new method to it. Make it look like this:

    @GetMapping("/email/inbox")
    public ResponseEntity<?> inbox() {
        LOG.debug("In inbox");

        try {
            List<Email> inbox = new ArrayList<Email>();
            User currentUser = authUtil.getCurrentUser();
            
            Credential credential = googleOauthUtil.getCredential(currentUser.getId());
            inbox = gmailUtil.getInbox(credential);
            
            return ResponseEntity.ok(inbox);
        } catch (IOException ie) {
            LOG.error("Problem retrieving inbox!", ie);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ie.getMessage());
        } catch (GeneralSecurityException ge) {
            LOG.error("Security issue!", ge);
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ge.getMessage());
        }
    }

That method maps to the email/inbox endpoint.

The incoming request will be a GET request so the code uses the @GetMapping annotation.

Also, take a look at the method signature. It's empty. That means (for now) the request isn't accepting any request parameters or path variables.

And since it's a GET, it's also not accepting a request body.

That keeps things pretty simple.

Just keep in mind that the underlying framework here is accepting a Bearer token. In fact, the microservice will insist on a Bearer token to validate that the user is authorized to use this endpoint.

But back to the code.

The method starts off by instantiating an empty List of Email objects. That list will get populated and eventually sent back to the user.

Next, the code uses our old friend AuthorizationUtil to instantiate a User object that reflects the current user.

After that, the method incokes the getCredential() method from GoogleOauthUtil to retrieve the user's credential from the MongoDB user document.

Then the code uses that Credential object to retrieve the latest 20 messages from his or her inbox via the getInbox() method from GmailUtil.

I covered the GmailUtil and GoogleOauthUtil classes fairly extensively in previous guides, so I won't rehash any of that here. Feel free to take a look at earlier guides if you need a refresher. 

Finally, the getInbox() method returns the List of Message objects that get sent back to the user.

Well, That Was Easy

Okay. That was pretty straightforward. But will it work?

To answer that question, you need to revisit your old friend Postman. Fire that up.

And then fire up both the ecosystem-user-service and ecosystem-email-service Spring Boot microservices.

Once again, use Postman to authenticate with the user service and get the Bearer token. I explained how to do that in Part 5 of this series.

Then, create a new request tab in Postman and add this endpoint:

Remember: the default configuration for the email service is that it's listening on Port 32050. So the endpoint you're looking for is http://localhost:32050/email/inbox.

And make sure it's a GET request.

Finally, set the Bearer token. Again, take a look at Part 5 if you don't remember how to do that.

Now you're all set. Smash that blue Send button.

You should get back something that looks like this:

 

Scroll down within that response window and you'll likely find that it contains quite a bit of content. That's normal.

Remember: you'll have two different formats for 20 emails. So the response will include a lot of text.

Why Didn't It Work for You?

I would put the odds at greater than 80% that most of the people reading this didn't get back a response that looks like the content I shared above.

You might be one of those people.

If you're staring at an empty array ([]) in your response instead of lots of content, take a look at your email service console. You'll probably find a 401 (Unauthorized) error in there. It will be sitting on top of a large exception stacktrace.

It's likely you got that because you went through the steps described in Parts 5 and 6 of this guide more than once.

I'll explain how to fix that permanently in the next guide. For now, though, just go through the steps in Parts 5 and 6 again. In other words, follow the flow to get the authorization code and the access token once more. You can do it all right there in Postman.

Then, go through the process above again and you should be in good shape.

But going forward, keep in mind that your credential won't include a refresh token. So you'll need to re-authorize every hour or so.

Again, I'll explain how to deal with that in the next guide.

Just watch out for that encoded authorization code in the URL. If you see that your authorization code begins with 4%2F you should change it to 4/.

Wrapping It Up

You finally have emails. Now, you've got to do something with them.

You'll do that something on the Angular side of the house. I'll cover that in future guides.

For now, though, recognize that you made great progress through this series and pat yourself on the back.

And have fun!

Photo by Karolina Grabowska from Pexels