What is Hubspot CRM?
HubSpot CRM (Customer Relationship Management) is a robust platform that helps businesses manage their customer interactions and streamline sales processes. One of its key features is the HubSpot Chat Widget, which enables real-time communication between businesses and website visitors.
How to add chat widget to Rails app:
In your Rails layout file (e.g., application.html.erb), add the HubSpot provided script tag:
<script type="text/javascript" id="hs-script-loader" async defer src="HUBSPOT_SCRIPT.js"></script>
This script loads the necessary HubSpot widget script asynchronously, ensuring optimal performance.
The Need for Visitor Identification API
By default, users interacting with the chat widget are treated as new guest users. However, what if you want to distinguish between existing customers and new visitors? This is where the Visitor Identification API comes into play.
Enabling the Visitor Identification API
To enable the Visitor Identification API in your Rails application, follow these steps:
In your Rails layout file (e.g., application.html.erb), add the following code after the script code above:
<script type="text/javascript">
window.hsConversationsSettings = {
loadImmediately: false
};
</script>
Setting loadImmediately: false
ensures that the identification step is awaited before loading the widget.
Next, within your React application, implement the following code to receive the token from the backend (using user email as an identifier ) and pass it to the chat widget.
export const initChatWidget = () => {
window.HubSpotConversations?.clear();
window.HubSpotConversations?.widget?.load();
};
export const fetchChatWidgetToken = async () => {
try {
const response = await fetch('/chat_widget/token', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error('Failed to fetch chat widget token');
}
const data = await response.json();
return data.token;
} catch (error) {
console.error('Error fetching chat widget token:', error);
throw error;
}
};
const useChatWidgetToken = () => {
useEffect(() => {
const fetchTokenAndInitChatWidget = async () => {
try {
const token = await fetchChatWidgetToken();
window.hsConversationsSettings = {
identificationEmail: 'your-user@email.com',
identificationToken: token,
};
initChatWidget();
} catch (error) {
console.error('Error initializing chat widget:', error);
}
};
fetchTokenAndInitChatWidget();
}, []);
};
const MyComponent = () => {
useChatWidgetToken();
// ...
};
The useChatWidgetToken
hook fetches a token from the backend /chat_widget/token
endpoint upon the component mount. This token is then used to initialize the HubSpot chat widget through the initChatWidget
function, ensuring seamless integration of chat functionality into your React application.
Add Rails Backend:
class ChatWidgetController < ApplicationController
def token
api_client = ::Hubspot::Client.new(access_token: 'YOUR_TOKEN')
body = {
email: current_user.email,
firstName: current_user.first_name, # optional
lastName: current_user.last_name # optional
}
response = api_client.conversations.visitor_identification.generate_api.generate_token(body: body)
render json: { token: response.token }
rescue => e
render json: { error: e.message }, status: :unprocessable_entity
end
end
In your existing project, consider moving the controller logic to a separate service logic class.
Contacts API:
It's important to note that we need to have the current customers as customers on the HubSpot side else on the identification step Hubspot will identify the user as a new guest user. You can create them manually or add a script to synchronize your existing customers to them.
properties = {
"email": user.email,
"firstname": user.first_name,
"lastname": user.last_name
}
body = { properties: properties }
api_client.crm.contacts.basic_api.create(body: body)
Conclusion
That's it! Now, when users interact with the chat widget as customers or guests, their details will be automatically displayed in the HubSpot chat header, enhancing communication and fostering trust.
Thanks for reading!