ProcurePro Example
The code below is an example of a process connecting to ProcurePro. ProcurePro authenticates with a static access token passed as a query parameter rather than through MODLR's built-in OAuth 2.0 flow, so this is an Advanced Integration.
INFO
This process requires a ProcurePro access token, stored as a Secret rather than hardcoded in the process.
Library Code
A small client for the ProcurePro API. Save this as a Process Library and load it with script.library.
js
class ProcurePro {
constructor(token) {
this.token = token;
this.baseUrl = "https://app.procurepro.co/external/api/customer-bi/v1/";
this.debug = false;
}
enableDebug(debug) {
this.debug = debug;
}
request(method, path, headers = {}, body = {}) {
const fullUrl = this.buildUrl(path);
const requestHeaders = {
"Accept": "application/json",
...headers
};
const response = web.request(method, fullUrl, requestHeaders, body, false);
if (this.debug) {
console.log(`[DEBUG] ${fullUrl}: ${response.status}`);
}
if (response.status >= 200 && response.status < 300) {
return JSON.parse(response.body);
}
if (response.status === 429) {
throw new Error("Rate limited by ProcurePro (HTTP 429).");
} else if (response.error) {
throw new Error(response.error);
} else {
throw new Error(`Unexpected response status: ${response.status}`);
}
}
get(path, parameters = {}, headers = {}) {
const queryString = this.buildQueryString(parameters);
return this.request("GET", path + queryString, headers);
}
post(path, data, headers = {}) {
return this.request("POST", path, headers, data);
}
buildQueryString(parameters) {
if (Object.keys(parameters).length === 0) {
return "";
}
return "?" + Object.entries(parameters)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join('&');
}
buildUrl(path) {
const trimmedPath = path.startsWith("/") ? path.substring(1) : path;
let fullUrl = `${this.baseUrl}${trimmedPath}`;
const hasQueryString = fullUrl.includes("?");
const separator = hasQueryString ? "&" : "?";
fullUrl += `${separator}access_token=${encodeURIComponent(this.token)}`;
return fullUrl;
}
}Process Code
js
script.library("api/procurepro.js");
function pre() {
// This function is called once before the process is executed.
// Use this to setup prompts.
script.log('process pre-execution parameters parsed.');
}
function begin() {
// This function is called once at the start of the process
script.log('process execution started.');
const api = new ProcurePro(security.getSecret("PROCUREPRO_ACCESS_TOKEN"));
try {
const projects = api.get("project.json");
console.log(`Projects returned: ${projects.length}`);
console.log(projects);
} catch (e) {
console.log("Something went wrong");
console.log(e);
}
}
function data(record) {
// This function is called once for each line of data on the second cycle
// Use this to build dimensions and push data into cubes
}
function end() {
// This function is called once at the end of the process
script.log('process execution finished.');
}