Back

How to build a public Mailjet integration: Building the Auth Flow

Aug 14, 20247 minute read

Hey there, fellow JavaScript developer! Ready to dive into the world of Mailjet integrations? Today, we're going to focus on one of the most crucial parts of building a public integration: the authorization flow. Don't worry, I'll keep things concise and to the point – I know you've got code to write!

Prerequisites

Before we jump in, make sure you've got:

  • Mailjet API credentials
  • A Node.js and Express.js setup
  • A basic understanding of OAuth 2.0

Got all that? Great! Let's get started.

Setting up the project

First things first, let's get our project set up:

npm init -y npm install express axios dotenv

Now, create a basic Express server:

const express = require('express'); const app = express(); require('dotenv').config(); app.listen(3000, () => console.log('Server running on port 3000'));

Implementing the OAuth 2.0 flow

Register your application

Head over to Mailjet and register your application. You'll get a client ID and secret – keep these safe!

Configure OAuth 2.0 settings

In your .env file, add:

MAILJET_CLIENT_ID=your_client_id
MAILJET_CLIENT_SECRET=your_client_secret
REDIRECT_URI=http://localhost:3000/callback

Implement the authorization request

Let's create a route to start the auth process:

app.get('/auth', (req, res) => { const authUrl = `https://app.mailjet.com/oauth/authorize?client_id=${process.env.MAILJET_CLIENT_ID}&redirect_uri=${encodeURIComponent(process.env.REDIRECT_URI)}&response_type=code`; res.redirect(authUrl); });

Handle the callback

Now, let's handle the callback:

app.get('/callback', async (req, res) => { const { code } = req.query; try { const tokens = await exchangeCodeForTokens(code); // Store tokens securely (we'll cover this later) res.send('Authorization successful!'); } catch (error) { res.status(500).send('Authorization failed'); } });

Creating helper functions

Let's create some helper functions to make our lives easier:

const axios = require('axios'); async function exchangeCodeForTokens(code) { const response = await axios.post('https://api.mailjet.com/v3/REST/oauth/token', { grant_type: 'authorization_code', client_id: process.env.MAILJET_CLIENT_ID, client_secret: process.env.MAILJET_CLIENT_SECRET, code, redirect_uri: process.env.REDIRECT_URI }); return response.data; } async function refreshAccessToken(refreshToken) { const response = await axios.post('https://api.mailjet.com/v3/REST/oauth/token', { grant_type: 'refresh_token', client_id: process.env.MAILJET_CLIENT_ID, client_secret: process.env.MAILJET_CLIENT_SECRET, refresh_token: refreshToken }); return response.data; }

Implementing user authentication

For this example, we'll use a simple in-memory user store. In a real app, you'd want to use a database.

const users = new Map(); function createUser(id, email) { users.set(id, { id, email, mailjetTokens: null }); } function getUserById(id) { return users.get(id); }

Connecting Mailjet to user accounts

When you receive tokens, associate them with the user:

function storeMailjetTokens(userId, tokens) { const user = getUserById(userId); if (user) { user.mailjetTokens = tokens; } }

Error handling and edge cases

Always be prepared for things to go wrong:

app.get('/callback', async (req, res) => { const { code, error } = req.query; if (error) { return res.status(400).send(`Authorization error: ${error}`); } try { const tokens = await exchangeCodeForTokens(code); storeMailjetTokens(req.user.id, tokens); res.send('Authorization successful!'); } catch (error) { console.error('Token exchange failed:', error); res.status(500).send('Authorization failed'); } });

Testing the auth flow

Time to put it all together! Start your server and navigate to http://localhost:3000/auth. You should be redirected to Mailjet's authorization page. After granting access, you'll be redirected back to your app.

Security considerations

Remember:

  • Always use HTTPS in production
  • Store tokens securely (consider encryption)
  • Use the state parameter to prevent CSRF attacks

Here's a quick example of using the state parameter:

app.get('/auth', (req, res) => { const state = crypto.randomBytes(16).toString('hex'); // Store state in session or database const authUrl = `https://app.mailjet.com/oauth/authorize?client_id=${process.env.MAILJET_CLIENT_ID}&redirect_uri=${encodeURIComponent(process.env.REDIRECT_URI)}&response_type=code&state=${state}`; res.redirect(authUrl); }); app.get('/callback', async (req, res) => { const { code, state } = req.query; // Verify state matches the one we stored earlier // ...rest of the callback logic });

Wrapping up

And there you have it! You've just built the authorization flow for a Mailjet integration. Pretty cool, right? Remember, this is just the beginning. From here, you can start using the Mailjet API to send emails, manage contacts, and more.

Keep coding, keep learning, and most importantly, have fun building awesome integrations!