Back

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

Aug 12, 20247 minute read

Hey there, fellow JavaScript enthusiast! Ready to dive into the world of Keap integrations? Today, we're going to tackle one of the most crucial aspects of building a public integration: the authorization flow. Buckle up, because we're about to make your integration secure and user-friendly in no time!

The Lowdown on Keap Integration

Before we jump in, let's quickly touch on why we're here. Keap (formerly Infusionsoft) is a powerful CRM and marketing automation tool, and by building an integration, you're opening up a world of possibilities for your users. But to make it all work smoothly and securely, we need to nail the auth flow. Trust me, it's not as daunting as it sounds!

Prerequisites: Get Your Ducks in a Row

First things first, make sure you've got:

  • A Keap Developer Account (if you don't have one, go grab it!)
  • An application registered in the Keap Developer Portal
  • Node.js installed on your machine
  • Your favorite package manager (npm or yarn) ready to roll

Setting Up Your Project

Let's start with a basic Express.js server. Don't worry, we'll keep it simple:

const express = require('express'); const app = express(); require('dotenv').config(); const PORT = process.env.PORT || 3000; app.listen(PORT, () => console.log(`Server running on port ${PORT}`));

Don't forget to create a .env file for your client ID and secret:

KEAP_CLIENT_ID=your_client_id_here
KEAP_CLIENT_SECRET=your_client_secret_here

The OAuth 2.0 Flow: Let's Break It Down

Step 1: Redirect to Keap's Authorization Page

First, we need to send users to Keap's authorization page. Here's how:

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

Step 2: Handle the Callback

Once the user authorizes your app, Keap will redirect them back to your specified callback URL. 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: Exchange the Code for an Access Token

Now for the fun part - let's get that access token:

const axios = require('axios'); app.get('/callback', async (req, res) => { const { code } = req.query; try { const response = await axios.post('https://api.infusionsoft.com/token', { client_id: process.env.KEAP_CLIENT_ID, client_secret: process.env.KEAP_CLIENT_SECRET, code, grant_type: 'authorization_code', redirect_uri: 'http://localhost:3000/callback' }); const { access_token, refresh_token } = response.data; // Store these tokens securely! res.send('Authorization successful!'); } catch (error) { console.error('Error exchanging code for token:', error); res.status(500).send('Authorization failed'); } });

Keeping It Fresh: Token Refresh

Access tokens don't last forever, so let's implement a refresh mechanism:

async function refreshAccessToken(refresh_token) { try { const response = await axios.post('https://api.infusionsoft.com/token', { grant_type: 'refresh_token', refresh_token, client_id: process.env.KEAP_CLIENT_ID, client_secret: process.env.KEAP_CLIENT_SECRET }); return response.data.access_token; } catch (error) { console.error('Error refreshing token:', error); throw error; } }

Making Authenticated Requests

Now that we have our access token, let's use it to make an API call:

async function getUserInfo(access_token) { try { const response = await axios.get('https://api.infusionsoft.com/crm/rest/v1/oauth/connect/userinfo', { headers: { Authorization: `Bearer ${access_token}` } }); return response.data; } catch (error) { console.error('Error fetching user info:', error); throw error; } }

Handling Errors Like a Pro

Always be prepared for things to go sideways. Here's a quick error handler:

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

Security First!

Remember, keep your client secret... well, secret! Always use HTTPS in production, and consider implementing PKCE for an extra layer of security.

Testing, Testing, 1-2-3

Before you ship it, make sure to test your integration thoroughly. Try different scenarios, like:

  • Happy path: successful authorization and API calls
  • Error handling: invalid tokens, network issues
  • Token refresh: make sure it works smoothly

Wrapping Up

And there you have it! You've just built a secure authorization flow for your Keap integration. Pretty cool, right? Remember, this is just the beginning. From here, you can expand your integration to do all sorts of awesome things with the Keap API.

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