CMS Development

saleh_muhammad
Member

Chatflow integration issues with ReactJS

In the doc i saw very limited options to trigger different chat flows and there was no option with SDK, so I picked query string in my case.

Chatflows:

We have different chatflow connected to different service team inboxes

  • "ABC logout" (unknown users who are yet not logged in)
  • "ABC login" (Known users who have an account)
    • abc_trial_en
    • abc_trial_de
    • abc_paid_en
    • abc_paid_de

Expected behavior:

  • If the User is not logged in he should see chatflow with the display name "ABC logout"
  • Once the user login he should see chatflow with the display name "ABC login"


Current behavior:

  • The script gets loaded but chat doesn't appear, instead it shows status as pending don't know why and only appears when you refresh the page.
  • If you have loaded a specific chatflow and then performed login or logout operation it doesn't refresh to new chatflow which means if it's loaded as an unknown user it stays like that and vice versa.
  • I see a weird warning in the console when the widget is loaded.


Code:
Component:

 

import React, { FunctionComponent, ScriptHTMLAttributes } from 'react';

const w: any = window;
// eslint-disable-next-line no-underscore-dangle, no-multi-assign
const _hsp = (w._hsp = w._hsp || []);
// eslint-disable-next-line no-underscore-dangle, no-multi-assign
const _hsq = (w._hsq = w._hsq || []);

const HubSpotPortalId = '1111'; //Add your portal-id
const HubSpotElementId = 'hs-script-loader';

const startsWith = (str1: string) => (str2: string) => str1.startsWith(str2);
const createScriptNode = (
  props: ScriptHTMLAttributes<HTMLScriptElement> = {}
): HTMLElement => {
  const scriptNode: HTMLScriptElement = document.createElement('script');
  scriptNode.type = 'text/javascript';
  Object.keys(props).forEach((key) => {
    const keyName = key;
    // TODO: fix to proper typing
    (scriptNode as any)[keyName] = (props as any)[keyName];
  });
  return scriptNode;
};

const setQueryStringParameter = (
  name: string,
  value: string,
  append = false
) => {
  const url = new URL(window.document.URL);
  // Delete name to avoid duplicate entries
  url.searchParams.delete(name);
  if (append) url.searchParams.append(name, value);
  else url.searchParams.set(name, value);
  window.history.replaceState(null, '', url.toString());
};

const HubSpot = {
  execute: (action: () => void) => {
    // If external API methods are already available, use them.
    if (w.HubSpotConversations) {
      action();
      return;
    }
    /*
      Otherwise, callbacks can be added to the hsConversationsOnReady on the window object.
      These callbacks will be called once the external API has been initialized.
    */
    w.hsConversationsOnReady = w.hsConversationsOnReady || [];
    w.hsConversationsOnReady.push(action);
  },
  // On logout clear cookies so we can work on different chatflows
  resetWidget: () => {
    const status = w.HubSpotConversations?.widget.status();
    if (status?.loaded) {
      _hsp.push(['revokeCookieConsent']);
      w.HubSpotConversations.clear({ resetWidget: true });
    }
  },
  loadWidget: () => {
    const status = w.HubSpotConversations?.widget.status();
    if (status?.loaded) {
      w.HubSpotConversations.widget.refresh({ openToNewThread: true });
    } else {
      w.HubSpotConversations.widget.load({ widgetOpen: true });
    }
  },
  setUserIdentity: ({
    email,
    accountId,
  }: {
    email: string;
    accountId: string;
  }) => {
    // Identify current user on chat
    _hsq.push([
      'identify',
      {
        email,
        accountId,
      },
    ]);
  },
  setChatflow: ({
    isTrialUser,
    locale,
  }: {
    locale: string;
    isTrialUser?: boolean;
  }) => {
    const chatflowUser = isTrialUser ? 'trial' : 'paid';
    const chatflowLocale = ['en', 'es', 'de'].some(startsWith(locale))
      ? locale.slice(0, 2)
      : 'zu';
    const chatFlow = `abc_${chatflowUser}_${chatflowLocale}`;
    setQueryStringParameter('chatflow', chatFlow, true);
  },
};

type HubSpotWidgetProps = {
  email?: string;
  locale: string;
  accountId?: string;
  isTrialUser?: boolean;
};
const HubSpotWidget: FunctionComponent<HubSpotWidgetProps> = ({
  email,
  locale,
  accountId,
  isTrialUser,
}) => {
  const onConversationsAPIReady = () => {
    if (email && accountId) {
      HubSpot.setUserIdentity({ email, accountId });
      HubSpot.setChatflow({ locale, isTrialUser });
      HubSpot.loadWidget();
    }
    return HubSpot.loadWidget();
  };

  React.useEffect(() => {
    w.hsConversationsSettings = { loadImmediately: false };
    const script = document.getElementById(HubSpotElementId);

    if (!script) {
      const scriptNode = createScriptNode({
        src: `//js.hs-scripts.com/${HubSpotPortalId}.js`,
        id: HubSpotElementId,
        async: true,
        defer: true,
      });
      document.body.appendChild(scriptNode);
    }
    
    // Load Widget when ready
    HubSpot.execute(onConversationsAPIReady);

    return () => {
      if (email && w.HubSpotConversations && w.HubSpotConversations.resetAndReloadWidget) {
        w.HubSpotConversations.resetAndReloadWidget();
      }
    }

  }, [email]);

  return null;
};

export {  HubSpotWidget };

 

 

 

<HubSpotWidget
  email="test@test.com"
  locale="de"
  accountId="122344"
  isTrialUser={false}
/>;

 


Can you please help me with that.
Thanks,
Saleh

1 Reply 1
dennisedson
HubSpot Product Team
HubSpot Product Team

Chatflow integration issues with ReactJS

@miljkovicmisa ,

Is this type of question in your ballpark 😜

0 Upvotes