HubSpot provides a powerful platform that uses React to build user interfaces (UI) and serverless capabilities, allowing users to develop highly customizable pages and forms directly within the CRM itself.
This approach enables the creation of customized solutions without the need for additional servers or infrastructure. Using React provides a smooth interactive experience, allowing you to customize elements easily and efficiently.
This integration provides greater flexibility and control, allowing marketing, sales, and customer service professionals to build pages that meet their exact needs, all within the HubSpot environment.
For this project, the prerequisites are a HubSpot developer account and in-depth understanding of React, JavaScript, and serverless functionality. These skills are essential for building and customizing pages and forms in HubSpot CRM.
First, HubSpot provides a detailed quick start guide that will walk you through the process of setting up your development environment and building your first private application. You can access the guide here.
Serverless functions are an efficient way to handle lightweight backend logic without having to manage a complete server infrastructure. In this guide, we will build a serverless function to obtain business group information based on the CNPJ (Cadastro Nacional da Pessoa Jurídica, Brazil’s company registration number).
Step 1: Define Serverless functions serverless.json
The file is in your project
To integrate functionality into your application, you first need to register it with serverless.json
document. This file informs your system of available serverless features and where to find their implementations. This file is located in the app.functions folder.
Add the following configuration to your serverless.json
:
{
"handleGetCommercialGroupFunc": {
"file": "get-commercial-group.js",
"secrets": []
}
}
This entry maps function name handleGetCommercialGroupFunc
to file get-commercial-group.js
which we will create next.
Step 2: Create a serverless function
In the app.functions folder, create a file called get-commercial-group.js
And implement the following logic:
exports.main = async (context = {}) => {
const { cnpj } = context.parameters;
if (!cnpj) {
return {
statusCode: 400,
body: { error: "CNPJ is required." },
};
}
try {
// Replace with your actual API URL
const apiUrl = `https://YOUR-API-ENDPOINT?cnpj=${encodeURIComponent(cnpj)}`;
// Make the API request
const apiResponse = await fetch(apiUrl, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!apiResponse.ok) {
throw new Error(`API Error: ${apiResponse.status} - ${apiResponse.statusText}`);
}
const data = await apiResponse.json();
return {
statusCode: 200,
body: data,
};
} catch (error) {
console.error("Serverless function error:", error);
return {
statusCode: 500,
body: { error: "Failed to fetch data.", details: error.message },
};
}
};
explain:
-
Input validation: This function checks whether
cnpj
Parameters are provided. If not, return a400 Bad Request
mistake. - API call: It makes a GET request to the specified API using the provided CNPJ.
- Error handling: This function handles errors gracefully and returns meaningful error messages for debugging.
- reply: On success, it returns the API response as-is, allowing the frontend to process it.
Step 3: Front-end integration
We used React to build a simple interface in HubSpot that allows users to provide a CNPJ and retrieve information about the business group associated with that key.
The following code uses @hubspot/ui-extensions
Library for building interfaces, including input fields and buttons that trigger serverless functions. Call the serverless function with CNPJ as parameter and display the response in the interface.
import React, { useState } from "react";
import {
Divider,
Button,
Text,
Input,
Flex,
hubspot,
} from "@hubspot/ui-extensions";
hubspot.extend(({ context, runServerlessFunction, actions }) => (
<Extension
context={context}
runServerless={runServerlessFunction}
sendAlert={actions.addAlert}
openIframe={actions.openIframeModal}
/>
));
// Define the Extension component, taking in runServerless, context, & sendAlert as props
const Extension = ({ context, runServerless, sendAlert, openIframe }) => {
const [cnpj, setCnpj] = useState("");
const [commercialGroup, setCommercialGroup] = useState("");
const handleGetCommercialGroup = async () => {
try {
console.log('Calling handleGetCommercialGroupFunc with CNPJ:', cnpj);
const { response } = await runServerless({ name: "handleGetCommercialGroupFunc", parameters: { cnpj } });
console.log('Serverless function response:', response);
setCommercialGroup(JSON.stringify(response));
sendAlert({ message: JSON.stringify(response, null, 2) });
} catch (error) {
console.error('Error searching for business group:', error);
sendAlert({ message: error.message });
}
};
return (
<>
<Text>
<Text format={{ fontWeight: "bold" }}>
My Custom Form on HubSpot
</Text>
</Text>
<Flex direction="row" align="end" gap="small">
<Input name="cnpj" label="CNPJ" onInput={(cnpj) => setCnpj(cnpj)} />
<Button type="submit" onClick={handleGetCommercialGroup}>
Get Commercial Group
</Button>
</Flex>
<Divider />
<Flex direction="row" align="end" gap="small">
<Input name="commercial_group" label="Commercial Group" value={commercialGroup} />
</Flex>
<Divider />
</>
);
};
));
explain:
- Status management:cnpj and CommercialGroup values are stored in the component’s state using useState. The cnpj input is updated as the user types in the input field, and the commercialGroup value is updated when a serverless function response is received.
- Calling a serverless function: When the user clicks the “Get Business Group” button, the runServerless function will be called. It sends CNPJ as a parameter to the serverless function (handleGetCommercialGroupFunc).
- Response processing: After no server function responds, the component will retrieve the response and use the response data to update the CommercialGroup state. The results are displayed in the CommercialGroup input field. Additionally, if an error occurs, the sendAlert function is used to capture the error and display it as an alert.
Step 4: Test the functionality
- Run the frontend: Launch your application and enter CNPJ in the input field.
- Check logs: Monitor console logs in frontend and serverless functions to debug issues.
- Verify API response: Make sure the API returns the expected data format:
{
"name": "Company Name",
"value": 12345.67,
"type": "Business Type"
}
in conclusion
This serverless function demonstrates how to use CNPJ as input to get data on Hubspot from an external API. By following the steps above, you can integrate similar serverless functionality into your project, reducing backend complexity and increasing scalability. For further improvements, consider adding caching or input sanitization to make the functionality more robust.
Leveraging this approach in HubSpot CRM provides users with an extremely high level of customization. Not only can you create dynamic user interfaces directly within the CRM page, but you can also dynamically manipulate values and data through the API, giving you complete flexibility to customize the CRM experience to your specific needs and workflows. This integration streamlines your processes and provides greater control and efficiency for your CRM operations.
photography: event creator exist Not splashed