Hubspot Visitor Identification API in Rails + React

Ruslan CoroliovRuslan Coroliov
3 min read

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!

0
Subscribe to my newsletter

Read articles from Ruslan Coroliov directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ruslan Coroliov
Ruslan Coroliov

Hi there! 👋 I'm Ruslan Coroliov, a passionate Software Engineer from Moldova. 🧑‍🌾 ( real, not AI 🤖 ) A full-stack web developer proficient in Ruby (Ruby on Rails) for the backend and Typescript/Javascript (React, Vue, Plain JS) for the front end. As a remote work enthusiast, I thrive on learning new tech while maintaining a healthy work-life balance, ensuring productivity and innovation go hand in hand in every daily task.