Setting up Gmail OAuth

In this post I'm going to show you how to set up a Gmail OAuth2 application and to generate credentials to use with EmailEngine.

In this post, I'm going to show you how to set up a Gmail OAuth application and to generate credentials to use with EmailEngine. There are going to be a lot of screenshots, so beware, things will change over time and if you're reading this post in the future, then these screenshots might not match reality anymore. The general concept has remained the same for the last 10 years though, so I guess it'll stay this way for now.

To start go to Google Cloud Console and "Select a Project" in the top menu. Depending on if you have already created a project or not, the text might be different but the drop-down menu should be there.

There's not much to see at first, so let's generate a new project.

In the project settings screen, all you can do is name your project. In this example, we'll be using "IMAP API" as the project's name.

At first, the project is empty, so we have to configure it. Click on the top-left hamburger menu, find "APIs & Services" and select "OAuth consent screen".

Now we have to decide which kind of users do we give access to. In this section, we select "External", so that non-organization accounts could also be used but beware, making this app actually public would mean a months-long security audit and boatloads of money to pay for it. So for test purposes, we are keeping it semi-public, which means we can list up to 100 Gmail/G-Suite accounts that are allowed to use our app.

NB! You should not use external user type in production without going through the audit. Until the project is in "testing" mode OAuth2 refresh tokens expire in 7 days. This means that registered users need to re-login after every 7 days to keep their connections active.

App name again, we'll just go with the project's name, that is "IMAP API". We also need to provide support and developer email addresses.

Next, we can select our required scopes. This is a bit tricky, you'll see why in the next screen.

The thing is that the scope we need to select is not listed and can't be searched for. So we have to add it manually. The exact scope to add is "https://mail.google.com/" (without quotes).

Now that we added the missing scope we can select it.

By the way, the scope we used gives us access to IMAP and SMTP, also to the public user profile. No more no less.

Anyway, after confirming that the Gmail scopes table includes the required scope we can save and continue.

This is the step I mentioned before. It is only shown for the "External" type of apps. You can manually list Gmail or G-Suite user accounts here that are allowed to use your app.

Anyone who is not listed, can not log in to EmailEngine via the OAuth consent screen. If you'd try it anyway then you'd get some weird error 400 response. So make sure that each user you need to be able to register in EmailEngine is listed here.

A final look at the resulting users table and we can save and continue.

Now that our app is configured we need to create some credentials for EmailEngine.

From the left side menu, under APIs & Services, select Credentials.

The credentials list is empty at first, so we need to create some by clicking on the "Create credentials" button and then selecting "OAuth client ID" from the drop-down list.

The application type is "Web application".

We also need to provide some URIs. First is the application URI without any path part. The default for EmailEngine is "http://127.0.01:3000" but you might have something else, depending on your setup.

Next is the Oauth redirect URL. Once the user has given consent, Google will be redirecting the user to this URL with appropriate tokens, so it must point to the EmailEngine's OAuth handling page. Basically, it's the app URI + "/oauth", eg. "http://127.0.0.1:3000/oauth".

And that's it, we have our credentials!

Next, we can take these credentials and add these to the OAuth section in the EmailEngine's settings page.

Having OAuth properly set up we can finally try to add a new account.

We skip the IMAP and SMTP tabs entirely and instead only check the OAuth account checkbox. This disables normal IMAP and SMTP settings.

Next, we have the standard Google authentication screen. Let's log in.

Make sure that you only use an account that was added to the list of test users in a previous step when logging in. You could try to use some other account but it will surely fail with a cryptic error message.

Once we have authenticated ourselves Google will warn us that this is a test app. Be daring and hit that "Continue" link.

Now Google presents us an opportunity to not give EmailEngine the permissions to use IMAP and SMTP. As this would be pointless we'll mark that checkbox manually.

And that's about it, once we hit Continue and everything checks out we would be redirected back to the EmailEngine's dashboard.

By the way, if you'd scroll up a few screens you'd notice that the account count used to be 4. Now it is 5. Great success!

If you have not used Google APIs before you might end up with the following error message instead:

Gmail API has not been used in project xxxxxx before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/gmail.googleapis.com/overview?project=xxxxxx then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.

This means you have to enable Gmail API in the Google Developers Console. To do that go back to your project page and click on the "Library" link on the left menu.

Next search for "gmail api" and click on the Gmail API search result once it appears.

You should see an "Enable" button on the API page. Click it to activate the API for your project.

Then wait a minute or two and try again adding that account.

That's about it!

The described approach is fine to use if you only need to link a few specific email accounts to EmailEngine. Eg. you are tracking support@yourdomain or sales@yourdomain or similar accounts.

For any public production use, it is advised to use the authentication server approach where you manage OAuth tokens yourself but this is a bit out of scope for this blog post. Go see the README for specifications.