Okay folks, this is going to be a big one.

In this series of guides, I'm going to show you how to integrate a Gmail inbox into your Angular application. 

And yes, you'll set it up like a regular inbox so the user can send and receive emails.

All the heavy lifting will get delegated to a Spring Boot microservice appropriately called "Email Service."

You can view the source for that microservice on GitHub.

For starters, the Spring Boot service will just handle Gmail integration. Ultimately, though, you'll use it to integrate with other email providers as well.

Fair warning: if you're here looking for a 5-minute solution on how to make all this happen, then you might as well just go back to whichever search engine brought you here. This is going to take some time to explain.

But I'll walk you through it every step of the way.

If you want to follow all the articles, just visit the gmail integration tag.

Now let's get started.

Prerequisites

Before we get started, I need to go over a couple of prerequisites. Simply put: this tutorial isn't for beginniners.

So in spite of Benny Hill's warning, I'll assume the following:

  • You know how to create a basic Spring Boot application from scratch
  • You already have an account on the Google Cloud Platform
  • You can create (and have created) a project on the Google Cloud Platform
  • You understand the basics of REST requests
  • You have a fundamental understanding of OAuth2 (but you don't need to be an expert)
  • You have a basic understanding of TypeScript
  • You know how to create an Angular application from scratch
  • You have an active Gmail account that you can test with
  • You know the basics of JWT
  • You have access to, and a working knowledge of, Postman

Okay, the warning is out of the way. Now let's really get started.

What We Have Here

As you can tell from the title, you're not getting the whole story in this one article. This article is the first in a series.

So here's what you'll accomplish after reading this guide:

  • Creating an OAuth2 client ID and secret in Google Cloud Console
  • Enabliing the Gmail API via Google Cloud Console
  • Setting the appropriate properties in your Spring Boot project

Getting to Cloud 9

You're going to do this integration thing via the Gmail API. That means you're going to need to need to get credentials so users can grant your application access to their Gmail accounts.

That's all handled via OAuth2.

So get the ball rolling by setting up a client ID and secret with the Google Cloud Console.

If you click that Google Cloud Console link, it will probably take you to a credentials page specific to whatever project you're actively working with. Here's what the screen looks like:

 

That red arrow points to the active project. Make sure it's the one you want to use.

If not, just select the correct project from the dropdown.

As you can see from the image above, I've already created an OAuth2 Client ID. But I'll walk you through the process of creating one so you can see how to do it.

Start by clicking Create Credentials towards the top of the page. Then select OAuth Client ID from the dropdown that appears.

Now you need to select the application type from the dropdown. Select Web application.

Why Web application? Because, as I noted above, you're going to let the back-end microservice do all the heavy lifting. For a couple of reasons.

First of all, it's cleaner. You get to deploy a single service that multiple front-end apps can use to integrate with Gmail.

But more importantly, it's a best-practice from a security standpoint. If you decide to integrate with Gmail directly from your Angular app, you'll need to include your client secret on the client side deployment. That means it could be compromised as users can easily watch the data that gets sent back and forth between the client and server.

So yeah, go ahead and select Web application.

Once you're done with that, you'll need to give your OAuth2 client a name. Enter "Email Service Client".

So your screen on Google Cloud Platform should look like this:

 

Now scroll down a bit and you should see something about Authorized Redirect URIs. Click the ADD URI button and add http://localhost:4200 as the URI. 

That's just a placeholder for now. You'll update it later.

 

Finally, click that CREATE button at the bottom and you should see a popup with your client ID and secret.

Click OK on the popup and you'll see your new client under OAuth 2.0 Client IDs.

Enable the API

Next, head up to the Dashboard on the left-hand sidebar of that screen you see above. Scroll down a bit to see which APIs you have enabled for your project.

 

Make sure you have Gmail API as one of your APIs on that list. If not, you can add it right now.

Just click on ENABLE APIS AND SERVICES at the very top of the page. You'll see a screen that looks like this:

 

Type the word "Gmail" in that text field at the top and you should get a couple of options.

 

Pick the top one. You'll see a screen that looks like this:

 

My blue button says MANAGE but yours will say ENABLE because you haven't yet enabled the API. Go ahead and click the blue button.

Excellent. Now you're all set to integrate with Gmail!

Boot-Scootin' Spring

I mentioned above that you need to know how to create a Spring Boot application from scratch to make this happen. You should know how to do that, but, truth be told, it's probably best if you just grab the Spring Boot project I've already created and let me explain to you what's going on with it.

It's a microservice that handles email integration. For the purposes of this guide (and the branch I linked to above), I'll just cover Gmail integration.

In fact, I'll only cover the first step of Gmail integration in this post. Stay tuned for further updates.

Let's start with the properties file. I haven't checked in my latest properties file because it's got sensitive information in it. But I'll show you what it should look like here:

server.port=32050

ecosystem.properties.file.location=/etc/careydevelopment/ecosystem.properties

mongo.db.name=ecosystem
mongo.user.collection=users

google.api.oauth2.token.url=https://www.googleapis.com/oauth2/v4/token
google.api.oauth2.auth.url=https://accounts.google.com/o/oauth2/v2/auth
google.api.oauth2.client.id=66666090437-e5pp8srigrgnv5c7jjjjjjjjfuj.apps.googleusercontent.com
google.api.oauth2.client.secret=kbbbbbbbbddddXxz1Snc

The server.port property is the port that the Spring Boot application listens on.

The ecosystem.properties.file property points to a properties file that contains important info for all applications running in the ecosystem. I'll cover that file in a moment.

The application uses MongoDB for persistence so that's why you see the mongo.db.name and mongo.user.collection properties.

Now you might be thinking to yourself: "What does that have to do with Gmail?"

Here's what it has to do with Gmail: the user needs credentials to access his or her Gmail inbox. The application can recreate those credentials every time the user wants access or the application can persist the credentials in the user document in MongoDB and just retrieve the credentials from there.

That's what it has to do with Gmail.

Those last four lines are unsurprisingly related to OAuth2. You can copy the first two of those lines verbatim.

For the last two lines, you'll get the data from the OAuth2 client you just created in the Google Cloud Platform. Just click on Email Service Client from the credentials page (which you can see above) and you'll find the ID and secret in the upper, right-hand corner. Paste those values into their respective properties in your properties file.

Now I mentioned above that the application relies on an external properties file identified by ecosystem.properties.file. At a minimum, you'll need to include this stuff in that file:

jwt.secret=secret
mongodb.carey-ecosystem.connection=mongodb://user:password@myhost:port

The Spring Boot application uses JWT so the jwt.secret property is the secret that's used to sign the token.

If you want to learn more about how to use JWT, feel free to read my guide on using Spring Boot with JWT.

The second property is the MongoDB connection URL. Set it accordingly.

Why All the Security?

At this point you might be wondering: what does all this JWT security stuff have to do with Gmail integration?

It has a lot to do with it.

Simply put: you don't want to give just anybody access to one of your user's Gmail inbox. That would be catastrophic.

So you need your local security to play nicely with OAuth2 and the Google API. Otherwise, you're opening the door for a world of hurt.

If you're unclear about how local security works, feel free to take a look at that JWT guide I linked to above. Just keep in mind: the way that the Email Service is designed right out of the box you'll need to a token that includes an authority named CAREYDEVELOPMENT_CRM_USER.

You can verify that by heading over to any JWT parser and plugging in your token. You should see something like this in the payload data section:

{
  "sub": "milton",
  "id": "6014032",
  "exp": 1616775992,
  "iat": 1616689592,
  "authorities": [
    "CAREYDEVELOPMENT_CRM_USER"
  ]
}

That authorities part is what's relevant here. 

If you want to use your own authority name instead of that one, just update WebSecurityConfig. Specifically, this part:

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
            .cors().and()
            .csrf().disable()
            .addFilter(new BearerTokenAuthenticationFilter(authenticationManager()))
            .authorizeRequests() 
            .anyRequest().access("hasAuthority('CAREYDEVELOPMENT_CRM_USER')").and()
            .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

Note the anyRequest().access() line. Change that to whatever authority name you want.

Wrapping It Up

Well that concludes Part 1.

If it doesn't seem like you got a whole lot done, keep in mind this is going to be long, hard slog. But you'll learn a lot along the way.

And once again, feel free to browse through the code on GitHub.

Have fun!

Photo by Torsten Dettlaff from Pexels