Requirement:
When a new customer or a new item (inventory & assembly items) is created in NetSuite, it should be created in HubSpot in real time.
Solution:
Library used: Library file containing API’s to connect with HubSpot CRM. – Jobin & Jismi IT Services – Knowledge Base (jobinandjismi.in)
Written a User Event script that triggers when a customer or item is created.
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
*/
/**
* Script Description
* This User Event is to create company record in hubspot whenever a new customer or item is created in netsuite
*
/*******************************************************************************
* VCPP-43 HubSpot Integration
* *******************************************************************************
* $Author: Jobin & Jismi IT Services LLP $
*
* Date: 24-06-2022
* DESCRIPTION
* This User Event is to create company record in hubspot whenever a new customer is created in netsuite
*
******************************************************************************/
define(['N/email', 'N/error', 'N/file', 'N/https', 'N/record', 'N/search', './Hubspot Integration-Library.js'],
/**
* @param{email} email
* @param{error} error
* @param{file} file
* @param{https} https
* @param{record} record
* @param{search} search
*/
(email, error, file, https, record, search, HubLibrary) => {
let library = HubLibrary.Library;
function CustomerData(customer) {
try {
let company;
//load customer
let customerRec = record.load({
type: record.Type.CUSTOMER,
id: customer
})
let type = customerRec.getValue({fieldId: 'isperson'})
if (type == "T") {
let firstName = customerRec.getValue({fieldId: 'firstname'})
let middleNAme = customerRec.getValue({fieldId: 'middlename'})
let lastname = customerRec.getValue({fieldId: 'lastname'})
if (middleNAme)
company = firstName +" "+ middleNAme +" "+ lastname
else
company = firstName +" "+ lastname
}
else
company = customerRec.getValue({fieldId: 'companyname'})
let phone = customerRec.getValue({fieldId: 'phone'})
//fetch address fields
let lineCount = customerRec.getLineCount({sublistId: 'addressbook'})
let address, address2, country, state, city, zip;
for (let i=0; i<lineCount; i++) {
let defaultShipping = customerRec.getSublistValue({
sublistId: 'addressbook',
fieldId: 'defaultshipping',
line: i
})
log.debug("default shipping", defaultShipping)
if (defaultShipping == true) {
let subRecord = customerRec.getSublistSubrecord({
sublistId: "addressbook",
fieldId: "addressbookaddress",
line: i
})
address = subRecord.getValue({
fieldId: "addr1",
});
address2 = subRecord.getValue({
fieldId: "addr2",
});
address = address + " " + address2
country = subRecord.getValue({
fieldId: "country",
});
state = subRecord.getValue({
fieldId: "state",
});
city = subRecord.getValue({
fieldId: "city",
});
zip = subRecord.getValue({
fieldId: "zip",
});
}
}
//create a JSON object for request body
let body = {
"properties": {
"name": company,
"domain": "",
"industry": "",
"phone": phone,
"address": address,
"country": country,
"state": state,
"city": city,
"zip": zip,
"netsuite_customer_id": customer
}
}
log.debug("body", body)
return body;
} catch (e) {
log.error("Error@CustomerData", e)
}
}
/**
* Function that fetches item details
* @param item
* @param type
* @returns {{properties: {}}}
*/
function productData(item, type) {
try {
let body;
var itemSearchObj = search.create({
type: "item",
filters:
[
["internalid", "anyof", item]
],
columns:
[
search.createColumn({name: "itemid", label: "Name"}),
search.createColumn({name: "salesdescription", label: "Description"}),
search.createColumn({name: "type", label: "Type"})
// search.createColumn({name: "baseprice", label: "Base Price"}),
// search.createColumn({name: "averagecost", label: "Average Cost"})
]
});
var searchResultCount = itemSearchObj.runPaged().count;
log.debug("itemSearchObj result count", searchResultCount);
//create a JSON object for request body
let bodyObj = {};
itemSearchObj.run().each(function (result) {
bodyObj.name = result.getValue({name: "itemid", label: "Name"})
bodyObj.description = result.getValue({name: "salesdescription", label: "Description"})
bodyObj.netsuite_internal_id = item
bodyObj.hs_cost_of_goods_sold = result.getValue({name: "averagecost", label: "Average Cost"})
bodyObj.hs_price_pkr = result.getValue({name: "baseprice", label: "Base Price"})
bodyObj.hs_sku = result.getValue({name: "itemid", label: "Name"})
return false;
});
//create a JSON object for request body
log.debug("body", bodyObj)
body = {
"properties": bodyObj
}
return body;
} catch (e) {
log.error("Error@productData", e)
}
}
/**
* function to create API
* @param API
* @param body
* @param type
* @param typeVal
* @param method
*/
function apiCreation(API, body, type, typeVal, method) {
try {
let response
let url = library.HUBSPOT_API_REQUESTS[API]
if (checkForParameter(type) && checkForParameter(typeVal))
url = url.replace(type, typeVal)
// url += apiKey;
//API request call
if (checkForParameter(body))
response = library.getRequestResults(url, JSON.stringify(body), method)
else
response = library.getRequestResults(url, "", method)
return response;
} catch (e) {
log.error("Error@apiCreation", e)
return false;
}
}
/**
* Function that checks if the passed parameter has value or not
* @param parameter
* @param parameterName
* @returns {boolean}
*/
function checkForParameter(parameter, parameterName) {
if (parameter !== "" && parameter !== null && parameter !== undefined && parameter !== false && parameter !== "null" && parameter !== "undefined" && parameter !== " " && parameter !== 'false') {
return true;
} else {
if (parameterName)
log.debug('Empty Value found', 'Empty Value for parameter ' + parameterName);
return false;
}
}
/**
* Defines the function definition that is executed after record is submitted.
* @param {Object} scriptContext
* @param {Record} scriptContext.newRecord - New record
* @param {Record} scriptContext.oldRecord - Old record
* @param {string} scriptContext.type - Trigger type; use values from the context.UserEventType enum
* @since 2015.2
*/
const afterSubmit = (scriptContext) => {
if (scriptContext.type == scriptContext.UserEventType.CREATE) {
let recordID = scriptContext.newRecord.id;
let type = scriptContext.newRecord.type;
if (type == 'customer') {
try{
//get the customer field values from customer record
let requestBody = CustomerData(recordID);
let response = apiCreation('POST_COMPANY', requestBody, "", "", "POST")
log.debug("response", response)
if (response[1] == 200 || response[1] == 201) {
let companyID = response.id;
//set the company id in the customer record
record.submitFields({
type: record.Type.CUSTOMER,
id: recordID,
values: {
custentity_jj_hs_companyid: response[0].id,
custentity_jj_error_customer_sync: null
},
options: {
enableSourcing: false,
ignoreMandatoryFields: true
}
});
} else {
//set the error in a custom field in the customer record
record.submitFields({
type: record.Type.CUSTOMER,
id: recordID,
values: {
custentity_jj_error_customer_sync: response[0],
custentity_jj_hs_companyid: null
},
options: {
enableSourcing: false,
ignoreMandatoryFields: true
}
});
}
} catch (e) {
log.error("Error@customer", e.message)
}
}
else {
try{
//get the item field values from item record(Inventory item and assembly item)
let requestBody = productData(recordID, type);
log.debug('requestBody', requestBody)
let response = apiCreation('POST_PRODUCT', requestBody, "", "", "POST")
log.debug("response", response)
let id;
if (response[1] == 200 || response[1] == 201) {
let productID = response.id;
//set the company id in the customer record
id = record.submitFields({
type: type,
id: recordID,
values: {
custitem_jj_hubspot_id: response[0].id,
custitem_jj_error_item_integration: null
},
options: {
enableSourcing: false,
ignoreMandatoryFields: true
}
});
} else {
//set the error in a custom field in the item record
id = record.submitFields({
type: type,
id: recordID,
values: {
custitem_jj_error_item_integration: response[2].message,
custitem_jj_hubspot_id: null
},
options: {
enableSourcing: false,
ignoreMandatoryFields: true
}
});
}
} catch (e) {
log.error("Error@inventory", e.message)
}
}
}
}
return {afterSubmit}
});