Hey there, fellow JavaScript enthusiasts! Ready to dive into the world of Salesmate integrations? Today, we're going to walk through building a rock-solid authorization flow for your user-facing Salesmate integration. Buckle up, because we're about to make API magic happen!
Salesmate's API is a powerful tool for extending your CRM capabilities, but before we can tap into that goldmine, we need to set up a secure authorization flow. This is crucial for protecting user data and ensuring smooth API interactions. Let's get started!
Before we jump in, make sure you've got:
First things first, let's get our project off the ground:
mkdir salesmate-integration cd salesmate-integration npm init -y npm install express axios dotenv
Great! Now we've got our basic structure and dependencies in place.
Head over to your Salesmate developer dashboard and grab your Client ID and Client Secret. These are your keys to the kingdom, so handle them with care!
Create a .env
file in your project root and add these credentials:
SALESMATE_CLIENT_ID=your_client_id_here
SALESMATE_CLIENT_SECRET=your_client_secret_here
Now for the fun part! Let's build our auth flow:
require('dotenv').config(); const express = require('express'); const axios = require('axios'); const app = express(); const SALESMATE_AUTH_URL = 'https://api.salesmate.io/oauth/authorize'; const SALESMATE_TOKEN_URL = 'https://api.salesmate.io/oauth/token'; app.get('/auth', (req, res) => { const authUrl = `${SALESMATE_AUTH_URL}?client_id=${process.env.SALESMATE_CLIENT_ID}&response_type=code&redirect_uri=http://localhost:3000/callback`; res.redirect(authUrl); }); app.get('/callback', async (req, res) => { const { code } = req.query; try { const response = await axios.post(SALESMATE_TOKEN_URL, { grant_type: 'authorization_code', client_id: process.env.SALESMATE_CLIENT_ID, client_secret: process.env.SALESMATE_CLIENT_SECRET, code, redirect_uri: 'http://localhost:3000/callback' }); const { access_token, refresh_token } = response.data; // Store these tokens securely (more on this later) res.send('Authorization successful!'); } catch (error) { console.error('Error exchanging code for tokens:', error); res.status(500).send('Authorization failed'); } }); app.listen(3000, () => console.log('Server running on http://localhost:3000'));
Now that we've got our tokens, we need to store them securely. In a production environment, you'd want to encrypt these and store them in a database. For now, let's keep it simple with in-memory storage:
let tokens = { access_token: null, refresh_token: null, expires_at: null }; // Add this to your /callback route tokens = { access_token: response.data.access_token, refresh_token: response.data.refresh_token, expires_at: Date.now() + response.data.expires_in * 1000 };
With our tokens in hand, let's make some API calls:
async function makeApiRequest(endpoint) { if (Date.now() > tokens.expires_at) { await refreshToken(); } try { const response = await axios.get(`https://api.salesmate.io${endpoint}`, { headers: { Authorization: `Bearer ${tokens.access_token}` } }); return response.data; } catch (error) { console.error('API request failed:', error); throw error; } } async function refreshToken() { try { const response = await axios.post(SALESMATE_TOKEN_URL, { grant_type: 'refresh_token', client_id: process.env.SALESMATE_CLIENT_ID, client_secret: process.env.SALESMATE_CLIENT_SECRET, refresh_token: tokens.refresh_token }); tokens = { access_token: response.data.access_token, refresh_token: response.data.refresh_token, expires_at: Date.now() + response.data.expires_in * 1000 }; } catch (error) { console.error('Token refresh failed:', error); throw error; } }
We've covered the basics of error handling in our code above, but in a production environment, you'd want to add more robust error handling and logging.
Set up a test route to try out your new API calls:
app.get('/test', async (req, res) => { try { const data = await makeApiRequest('/v1/deals'); res.json(data); } catch (error) { res.status(500).send('API request failed'); } });
And there you have it! You've just built a solid foundation for your Salesmate integration. From here, you can expand on this base to create powerful, custom integrations that leverage the full potential of the Salesmate API.
Remember, the world of API integrations is vast and exciting. Keep exploring, keep coding, and most importantly, keep having fun with it!
Happy coding, and may your integrations be ever smooth and your tokens always fresh!