Back

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

Aug 17, 20247 minute read

Hey there, fellow JavaScript enthusiasts! Ready to dive into the world of Sendy integrations? Today, we're going to walk through building a rock-solid auth flow for your Sendy integration. Buckle up, because we're about to make authentication both secure and smooth as butter.

Why bother with Sendy integration?

Sendy's a powerhouse for email marketing, and integrating it into your app can seriously level up your user experience. But here's the kicker: without a proper auth flow, your integration is about as useful as a chocolate teapot. So let's get that sorted, shall we?

Before we jump in

I'm assuming you're already comfortable with Node.js and Express.js, and you've got a basic grasp of OAuth 2.0. If not, no worries! Take a quick detour to brush up on these, and then come right back. We'll be waiting.

Setting the stage

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

npm init -y npm install express axios dotenv

Create an index.js file, and let's get this party started!

Sendy API: Your golden ticket

Head over to your Sendy account and grab your API key and secret. These are your VIP passes to the Sendy API.

Create a .env file and stash those credentials:

SENDY_API_KEY=your_api_key
SENDY_API_SECRET=your_api_secret

Remember, treat these like your deepest, darkest secrets. No sharing on GitHub!

OAuth 2.0: The main event

Alright, time to implement the OAuth flow. It's not as scary as it sounds, promise!

Step 1: The Authorization Request

First, we need to redirect users to Sendy's auth page. Here's how:

const authUrl = `https://app.sendy.com/oauth/authorize?client_id=${process.env.SENDY_API_KEY}&response_type=code&redirect_uri=http://localhost:3000/callback`; app.get('/auth', (req, res) => { res.redirect(authUrl); });

Step 2: Handling the Callback

Sendy will send the user back to your app with an authorization code. Let's catch that:

app.get('/callback', async (req, res) => { const { code } = req.query; // We'll use this code in the next step });

Step 3: Token Exchange

Now, let's swap that code for an access token:

const tokenUrl = 'https://app.sendy.com/oauth/token'; app.get('/callback', async (req, res) => { const { code } = req.query; try { const response = await axios.post(tokenUrl, { grant_type: 'authorization_code', client_id: process.env.SENDY_API_KEY, client_secret: process.env.SENDY_API_SECRET, code, redirect_uri: 'http://localhost:3000/callback' }); const { access_token, refresh_token } = response.data; // Store these tokens securely } catch (error) { console.error('Token exchange failed:', error); res.status(500).send('Authentication failed'); } });

Keeping it fresh

Access tokens don't last forever. When they expire, use the refresh token to get a new one:

async function refreshAccessToken(refresh_token) { try { const response = await axios.post(tokenUrl, { grant_type: 'refresh_token', client_id: process.env.SENDY_API_KEY, client_secret: process.env.SENDY_API_SECRET, refresh_token }); return response.data.access_token; } catch (error) { console.error('Token refresh failed:', error); throw error; } }

Locking it down

Security is key, folks. Let's add PKCE (Proof Key for Code Exchange) and a state parameter:

const crypto = require('crypto'); function generateCodeVerifier() { return crypto.randomBytes(32).toString('hex'); } function generateCodeChallenge(verifier) { return crypto.createHash('sha256').update(verifier).digest('base64') .replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); } const codeVerifier = generateCodeVerifier(); const codeChallenge = generateCodeChallenge(codeVerifier); const state = crypto.randomBytes(16).toString('hex'); const authUrl = `https://app.sendy.com/oauth/authorize?client_id=${process.env.SENDY_API_KEY}&response_type=code&redirect_uri=http://localhost:3000/callback&code_challenge=${codeChallenge}&code_challenge_method=S256&state=${state}`;

Don't forget to verify the state parameter in your callback route!

Taking it for a spin

Time to test this bad boy out. Fire up your server and navigate to /auth. If all goes well, you should be redirected to Sendy, then back to your app with an access token. Boom!

When things go sideways

Error handling is crucial. Always provide clear error messages and implement proper logging. Your future self will thank you.

app.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('Something broke!'); });

Wrapping up

And there you have it! You've just built a secure auth flow for your Sendy integration. Pat yourself on the back, you OAuth wizard, you!

Remember, this is just the beginning. Now that you've got authentication sorted, the world of Sendy integration is your oyster. Go forth and build amazing things!

Happy coding, and may your email campaigns be ever successful! 🚀📧