Outh: Sometimes Code verification failes

In roughly 20% of cases trying to get tokens by code fails with “Incorrect code error”

Hello @CalliperTony

Yes, I can understand your problem. I have been giving you a problem-solution code. It can help you.

Try this code

require('dotenv').config();const express = require('express');const request = require('request-promise-native');const NodeCache = require('node-cache');const session = require('express-session');const opn = require('open');const app = express();const PORT = 3000;const refreshTokenStore = {};const accessTokenCache = new NodeCache({ deleteOnExpire: true });if (!process.env.CLIENT_ID || !process.env.CLIENT_SECRET) {throw new Error('Missing CLIENT_ID or CLIENT_SECRET environment variable.')}//===========================================================================//// HUBSPOT APP CONFIGURATION//// All the following values must match configuration settings in your app.// They will be used to build the OAuth URL, which users visit to begin// installing. If they don't match your app's configuration, users will// see an error page.// Replace the following with the values from your app auth config, // or set them as environment variables before running.const CLIENT_ID = process.env.CLIENT_ID;const CLIENT_SECRET = process.env.CLIENT_SECRET;// Scopes for this app will default to crm.objects.contacts.read// To request others, set the SCOPE environment variable insteadlet SCOPES = ['crm.objects.contacts.read'];if (process.env.SCOPE) {SCOPES = (process.env.SCOPE.split(/ |, ?|%20/)).join(' ');}// On successful install, users will be redirected to /oauth-callbackconst REDIRECT_URI = http://localhost:${PORT}/oauth-callback;//===========================================================================//// Use a session to keep track of client IDapp.use(session({secret: Math.random().toString(36).substring(2),resave: false,saveUninitialized: true}));//================================//// Running the OAuth 2.0 Flow ////================================//// Step 1// Build the authorization URL to redirect a user// to when they choose to install the appconst authUrl ='https://app.hubspot.com/oauth/authorize' +?client_id=${encodeURIComponent(CLIENT_ID)} + // app's client ID&scope=${encodeURIComponent(SCOPES)} + // scopes being requested by the app&redirect_uri=${encodeURIComponent(REDIRECT_URI)}; // where to send the user after the consent page// Redirect the user from the installation page to// the authorization URLapp.get('/install', (req, res) => {console.log('');console.log('=== Initiating OAuth 2.0 flow with HubSpot ===');console.log('');console.log("===> Step 1: Redirecting user to your app's OAuth URL");res.redirect(authUrl);console.log('===> Step 2: User is being prompted for consent by HubSpot');});// Step 2// The user is prompted to give the app access to the requested// resources. This is all done by HubSpot, so no work is necessary// on the app's end// Step 3// Receive the authorization code from the OAuth 2.0 Server,// and process it based on the query parameters that are passedapp.get('/oauth-callback', async (req, res) => {console.log('===> Step 3: Handling the request sent by the server');// Received a user authorization code, so now combine that with the other// required values and exchange both for an access token and a refresh tokenif (req.query.code) {console.log(' > Received an authorization token');const authCodeProof = {grant_type: 'authorization_code',client_id: CLIENT_ID,client_secret: CLIENT_SECRET,redirect_uri: REDIRECT_URI,code: req.query.code};// Step 4// Exchange the authorization code for an access token and refresh tokenconsole.log('===> Step 4: Exchanging authorization code for an access token and refresh token');const token = await exchangeForTokens(req.sessionID, authCodeProof);if (token.message) {return res.redirect(/error?msg=${token.message});}// Once the tokens have been retrieved, use them to make a query// to the HubSpot APIres.redirect(/);}});//==========================================//// Exchanging Proof for an Access Token ////==========================================//const exchangeForTokens = async (userId, exchangeProof) => {try {const responseBody = await request.post('https://api.hubapi.com/oauth/v1/token', {form: exchangeProof});// Usually, this token data should be persisted in a database and associated with// a user identity.const tokens = JSON.parse(responseBody);refreshTokenStore[userId] = tokens.refresh_token;accessTokenCache.set(userId, tokens.access_token, Math.round(tokens.expires_in * 0.75));console.log(' > Received an access token and refresh token');return tokens.access_token;} catch (e) {console.error( > Error exchanging ${exchangeProof.grant_type} for access token);return JSON.parse(e.response.body);}};const refreshAccessToken = async (userId) => {const refreshTokenProof = {grant_type: 'refresh_token',client_id: CLIENT_ID,client_secret: CLIENT_SECRET,redirect_uri: REDIRECT_URI,refresh_token: refreshTokenStore[userId]};return await exchangeForTokens(userId, refreshTokenProof);};const getAccessToken = async (userId) => {// If the access token has expired, retrieve// a new one using the refresh tokenif (!accessTokenCache.get(userId)) {console.log('Refreshing expired access token');await refreshAccessToken(userId);}return accessTokenCache.get(userId);};const isAuthorized = (userId) => {return refreshTokenStore[userId] ? true : false;};//====================================================//// Using an Access Token to Query the HubSpot API ////====================================================//const getContact = async (accessToken) => {console.log('');console.log('=== Retrieving a contact from HubSpot using the access token ===');try {const headers = {Authorization: Bearer ${accessToken},'Content-Type': 'application/json'};console.log('===> Replace the following request.get() to test other API calls');console.log('===> request.get(\'https://api.hubapi.com/contacts/v1/lists/all/contacts/all?count=1\')');const result = await request.get('https://api.hubapi.com/contacts/v1/lists/all/contacts/all?count=1', {headers: headers});return JSON.parse(result).contacts[0];} catch (e) {console.error(' > Unable to retrieve contact');return JSON.parse(e.response.body);}};//========================================//// Displaying information to the user ////========================================//const displayContactName = (res, contact) => {if (contact.status === 'error') {res.write(

Unable to retrieve contact! Error Message: ${contact.message}

);return;}const { firstname, lastname } = contact.properties;res.write(

Contact name: ${firstname.value} ${lastname.value}

);};app.get('/', async (req, res) => {res.setHeader('Content-Type', 'text/html');res.write(

HubSpot OAuth 2.0 Quickstart App

);if (isAuthorized(req.sessionID)) {const accessToken = await getAccessToken(req.sessionID);const contact = await getContact(accessToken);res.write(

Access token: ${accessToken}

);displayContactName(res, contact);} else {res.write(

Install the app

);}res.end();});app.get('/error', (req, res) => {res.setHeader('Content-Type', 'text/html');res.write(

Error: ${req.query.msg}

);res.end();});app.listen(PORT, () => console.log(=== Starting your app on http://localhost:${PORT} ===));opn(http://localhost:${PORT});

References Link : https://github.com/HubSpot/oauth-quickstart-nodejs/blob/master/index.js

I hope it can help you.