Google Cloud ETL Function To Pull IntuitAPI (Quickbooks) Data Without User Login Webpage Redirect

40 Views Asked by At

I have seen that there are many Intuit/Quickbooks questions on here but none of them have the answer I'm really looking for.

Is there a way to pull Quickbooks data, purely from a NodeJS cloud function in Google Cloud, without needing to literally redirect to a user login page?

I have two cloud functions, one to request authorization, and another to pull the data. I realize I have done something incorrectly, but my 1st function redirects to the 2nd function.

(1) Request Authorization Function:

var OAuthClient = require('intuit-oauth');

exports.res = {};

exports.requestAuth = (req, res) => {
  exports.res = res;
  try {
    var oauthClient = new OAuthClient({
      clientId: process.env.CLIENT_ID,
      clientSecret: process.env.CLIENT_SECRET,
      environment: process.env.ENVIRONMENT,
      redirectUri: process.env.FUNCTION_TWO_URI,
      logging: false
    });
    const authUri = oauthClient.authorizeUri({ scope: [OAuthClient.scopes.Accounting, OAuthClient.scopes.OpenId], state: "testState" });
    console.log("Redirecting to authUri: " + authUri);
    res.redirect(authUri);
  } catch (err) { exports.error("requestAuth", err); }
};

exports.error = (funcName, err) => {
  console.error(funcName, err);
  exports.res.status(500).send(err.message);
};

(2) Pull Data Function:

var OAuthClient = require('intuit-oauth');
const moment = require('moment');

exports.begin = (req, res) => {
  try {
    var oauthClient = new OAuthClient({
      clientId: process.env.CLIENT_ID,
      clientSecret: process.env.CLIENT_SECRET,
      environment: process.env.ENVIRONMENT,
      redirectUri: process.env.FUNCTION_TWO_URI,
      logging: false
    });
    const parseRedirect = req.url;
    console.log("Creating token from parseRedirect: " + parseRedirect);

    oauthClient.createToken(parseRedirect).then((authResponse) => {
      console.log("Created token. Validating token: " + JSON.stringify(authResponse.getJson()));

      exports.validateToken(oauthClient, authResponse.getJson(), (oauthClient) => {
        console.log("Validated token. Pulling data...");

        exports.pullData(oauthClient, (response) => {
          console.log('SUCCESS: The API response is: ' + response);
          res.status(200).send('SUCCESS: The API response is: ' + response);
        });
      });
    }).catch((e) => {
      exports.error("begin.oauthClient.createToken.catch", e);
    });
  } catch (err) { exports.error("begin", err); }
};

exports.validateToken = (oauthClient, token, completion) => {
  try {
    if (oauthClient.isAccessTokenValid()) {
      oauthClient.setToken(token);
      completion(oauthClient);
    } else {
        oauthClient.refresh().then((authResponse) => {
          oauthClient.setToken(authResponse.json());
          completion(oauthClient);
        }).catch(function (e) {
          exports.error("validateToken.oauthClient.refresh.catch", e);
        });
    }
  } catch (err) { exports.error("validateToken", err); }
};

exports.pullData = (oauthClient, completion) => {
  try {
    let companyId = process.env.COMPANY_ID;
    let date = moment().subtract(1, 'days').format('YYYY-MM-DD');
    oauthClient.makeApiCall({ 
      url: `/v3/company/${companyId}/reports/CustomerSales?start_date=${date}&end_date=${date}&minorversion=65`, 
      method: 'GET', headers: { 'Content-Type': 'application/json' }
    }).then((response) => { completion(response); }).catch((e) => {
      exports.error("pullData.oauthClient.makeApiCall.catch", e);
    });
  } catch (err) { console.error("pullData", err); }
};

exports.error = (funcName, err) => {
  console.error(funcName, err);
  res.status(500).send(`ERROR: ${funcName}: ` + JSON.stringify(err));
};

Upon testing this, I found that the 1st function does redirect to authUri, but then nothing happens.

I don't see any logs either.

When I go to the authUri in my browser, it just opens a log in page.

Any help is greatly appreciated!

0

There are 0 best solutions below