Back

How to build a public SimplyBook.me integration: Building the Auth Flow

Aug 17, 20247 minute read

Hey there, fellow JavaScript enthusiasts! Ready to dive into the world of SimplyBook.me integrations? Today, we're going to tackle one of the most crucial aspects of building a public integration: the authorization flow. Don't worry, it's not as daunting as it sounds, and by the end of this article, you'll be auth-flow wizards!

Introduction

SimplyBook.me's API is a powerful tool for building scheduling and booking integrations. But before we can start making those sweet, sweet API calls, we need to set up a robust authorization flow. This is what allows your users to securely connect their SimplyBook.me accounts to your application. Let's get started!

Prerequisites

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

  • A SimplyBook.me developer account (if you don't have one, go grab it!)
  • Node.js and npm installed on your machine
  • A basic understanding of OAuth 2.0 (don't sweat it if you're rusty, we'll cover the essentials)

Setting up the project

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

mkdir simplybook-integration cd simplybook-integration npm init -y npm install express axios dotenv

Great! We've got our basic Node.js project with the necessary dependencies.

Configuring SimplyBook.me API credentials

Head over to your SimplyBook.me developer dashboard and create a new application. You'll get a client ID and secret - guard these with your life! (Or at least, don't commit them to public repos.)

Create a .env file in your project root:

SIMPLYBOOK_CLIENT_ID=your_client_id_here
SIMPLYBOOK_CLIENT_SECRET=your_client_secret_here

Implementing the authorization flow

Now for the fun part! Let's build out our auth flow:

require('dotenv').config(); const express = require('express'); const axios = require('axios'); const app = express(); const AUTHORIZE_URL = 'https://user-api.simplybook.me/oauth2/authorize'; const TOKEN_URL = 'https://user-api.simplybook.me/oauth2/token'; app.get('/auth', (req, res) => { const authUrl = `${AUTHORIZE_URL}?client_id=${process.env.SIMPLYBOOK_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(TOKEN_URL, { grant_type: 'authorization_code', code, client_id: process.env.SIMPLYBOOK_CLIENT_ID, client_secret: process.env.SIMPLYBOOK_CLIENT_SECRET, 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'); } }); app.listen(3000, () => console.log('Server running on http://localhost:3000'));

Building the frontend

For our frontend, we'll keep it simple with a login button:

<!DOCTYPE html> <html> <body> <button onclick="location.href='/auth'">Connect SimplyBook.me</button> </body> </html>

Securing the integration

To make our integration more secure, let's implement PKCE and 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, ''); } app.get('/auth', (req, res) => { const state = crypto.randomBytes(16).toString('hex'); const codeVerifier = generateCodeVerifier(); const codeChallenge = generateCodeChallenge(codeVerifier); // Store state and codeVerifier in session or database const authUrl = `${AUTHORIZE_URL}?client_id=${process.env.SIMPLYBOOK_CLIENT_ID}&response_type=code&redirect_uri=http://localhost:3000/callback&state=${state}&code_challenge=${codeChallenge}&code_challenge_method=S256`; res.redirect(authUrl); });

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

Testing the auth flow

Fire up your server and click that "Connect SimplyBook.me" button. If all goes well, you should be redirected to SimplyBook.me, asked to authorize your app, and then redirected back with a successful authorization message.

Error handling and edge cases

Remember to handle token expiration and refreshing:

async function refreshAccessToken(refreshToken) { try { const response = await axios.post(TOKEN_URL, { grant_type: 'refresh_token', refresh_token: refreshToken, client_id: process.env.SIMPLYBOOK_CLIENT_ID, client_secret: process.env.SIMPLYBOOK_CLIENT_SECRET }); return response.data.access_token; } catch (error) { console.error('Error refreshing token:', error); throw error; } }

Conclusion

And there you have it! You've successfully implemented the authorization flow for a SimplyBook.me integration. Pat yourself on the back - you're well on your way to building some amazing scheduling features for your users.

Remember, this is just the beginning. From here, you can start making API calls to SimplyBook.me, build out your user interface, and create a seamless booking experience for your users.

Keep exploring, keep coding, and most importantly, keep having fun with it!

Additional resources

Happy coding, and may your bookings always be on time!