A map reduce script to auto populate the access token in FedEx and UPS Integration custom record in NetSuite.
This script can be scheduled to execute in 1 hour for getting access token from FedEx and UPS API.
define([‘N/https’, ‘N/record’, ‘N/search’, ‘N/log’, ‘N/encode’],
/**
* @param{https} https
* @param{record} record
* @param{search} search
* @param{log} log
* @param{encode} encode
*/
(https, record, search, log, encode) => {
/**
* @description Get the configuration details of the Neural Logistix API from the custom record.
* @returns {Object} configObj
*/
const getConfigDetails = (recordId) => {
try {
let configObj = {};
let customrecord_jj_fedex_api_detailsSearchObj = search.create({
type: “customrecord_jj_fedex_api_details”,
filters: [
[“internalid”, “anyof”, recordId]
],
columns: [
search.createColumn({ name: “custrecord_jj_client_id”, label: “Client Id” }),
search.createColumn({ name: “custrecord_jj_client_secret”, label: ” Client Secret” }),
search.createColumn({ name: “custrecord_jj_api_endpoint_url”, label: “API Endpoint URL” })
]
});
let searchResultCount = customrecord_jj_fedex_api_detailsSearchObj.runPaged().count;
if (searchResultCount > 0) {
customrecord_jj_fedex_api_detailsSearchObj.run().each(function (result) {
configObj.client_id = result.getValue({ name: “custrecord_jj_client_id”, label: “Client Id” });
configObj.client_secret = result.getValue({ name: “custrecord_jj_client_secret”, label: ” Client Secret” });
configObj.posturl = result.getValue({ name: “custrecord_jj_api_endpoint_url”, label: “API Endpoint URL” });
return true;
});
return configObj;
} else {
return configObj;
}
} catch (e) {
log.error(“error@getConfigDetails”, e);
return {};
}
};
/**
* @description Get the access token of the Neural Logistix API based on configuration details.
* @param {Object} configDetails
* @param {string} requestType – Type of request to differentiate API requests.
* @returns {Object} accessToken
*/
const getAccessToken = (configDetails, requestType) => {
try {
let body;
let headersValue;
let responseAccessToken;
if (requestType === ‘FedEx’) {
body = {
‘grant_type’: ‘client_credentials’,
‘client_id’: configDetails.client_id,
‘client_secret’: configDetails.client_secret
};
headersValue = {
‘Accept’: ‘application/json’,
‘Content-Type’: ‘application/x-www-form-urlencoded’
};
responseAccessToken = https.post({
url: configDetails.posturl,
headers: headersValue,
body: body
});
}
else if (requestType === ‘UPS’) {
body = {
‘grant_type’: ‘client_credentials’,
‘code’: ’25M2kKG1′,
‘redirect_uri’: ‘https://test.com’
};
// Create the base64-encoded authorization header
let encodedCredentials = encode.convert({
string: configDetails.client_id + ‘:’ + configDetails.client_secret,
inputEncoding: encode.Encoding.UTF_8,
outputEncoding: encode.Encoding.BASE_64
});
headersValue = {
‘Content-Transfer-Encoding’: ‘application/x-www-form-urlencoded’,
‘Authorization’: ‘Basic ‘ + encodedCredentials
};
responseAccessToken = https.post({
url: configDetails.posturl,
headers: headersValue,
body: body
});
}
let responseBody = JSON.parse(responseAccessToken.body);
if (Object.keys(responseBody).length > 0) {
return responseBody;
} else {
return {};
}
} catch (e) {
log.error(“error@getAccessToken”, e);
return {};
}
};
/**
* Defines the function that is executed at the beginning of the map/reduce process and generates the input data.
* @param {Object} inputContext
* @returns {Array} The input data to use in the map/reduce process
* @since 2015.2
*/
const getInputData = (inputContext) => {
try {
let configDetails1 = getConfigDetails(1);
let configDetails2 = getConfigDetails(2);
let accessToken1 = getAccessToken(configDetails1, ‘FedEx’);
let accessToken2 = getAccessToken(configDetails2, ‘UPS’);
return [
{ recordId: 1, token: accessToken1.access_token },
{ recordId: 2, token: accessToken2.access_token }
];
} catch (e) {
log.error(“error@getInputData”, e);
}
};
/**
* Defines the function that is executed when the reduce entry point is triggered.
* @param {Object} reduceContext
* @since 2015.2
*/
const reduce = (reduceContext) => {
try {
let values = JSON.parse(reduceContext.values[0]);
record.submitFields({
type: ‘customrecord_jj_fedex_api_details’,
id: values.recordId,
values: {
custrecord_jj_access_token: values.token || ”
},
options: {
enableSourcing: true,
ignoreMandatoryFields: true
}
});
} catch (e) {
log.error(“error@reduce”, e);
}
};
/**
* Defines the function that is executed when the summarize entry point is triggered.
* @param {Object} summaryContext
* @since 2015.2
*/
const summarize = (summaryContext) => {
log.audit(“Summary”, {
concurrency: summaryContext.concurrency,
dateCreated: summaryContext.dateCreated,
isRestarted: summaryContext.isRestarted,
seconds: summaryContext.seconds,
usage: summaryContext.usage,
yields: summaryContext.yields
});
if (summaryContext.inputSummary.error) {
log.error(“Input Summary Error”, summaryContext.inputSummary.error);
}
if (summaryContext.mapSummary.error) {
log.error(“Map Summary Error”, summaryContext.mapSummary.error);
}
if (summaryContext.reduceSummary.error) {
log.error(“Reduce Summary Error”, summaryContext.reduceSummary.error);
}
};
return { getInputData, reduce, summarize };
});