Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nuzhy/CSIT-1702/intercom integration #857

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions src/javascript/_common/chat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import getFeatureFlag from '../app/common/getFeatureFlag';

const Chat = {
isFreshChat: async () => getFeatureFlag('enable_freshworks_live_chat'),
isIntercom : async () => getFeatureFlag('enable_intercom_st'),

getFlags: async () => {
const [isFreshChat, isIntercom] = await Promise.all([
Chat.isFreshChat(),
Chat.isIntercom(),
]);
return { isFreshChat, isIntercom };
},

open: async () => {
const { isFreshChat, isIntercom } = await Chat.getFlags();
if (isFreshChat) {
window.fcWidget?.open();
} else if (isIntercom) {
window.Intercom('show');
} else {
window.LC_API.open_chat_window();
}
},

openWithParam: async () => {
const { isFreshChat, isIntercom } = await Chat.getFlags();
const interval = setInterval(() => {
if (isFreshChat && window.fcWidget) {
window.fcWidget?.open();
clearInterval(interval);
} else if (isIntercom && window.Intercom) {
window.Intercom('show');
clearInterval(interval);
} else if (window.LiveChatWidget) {
window.LiveChatWidget?.on('ready', () => {
window.LC_API.open_chat_window();
});
clearInterval(interval);
}
}, 500);
},

clear: async () => {
const { isFreshChat, isIntercom } = await Chat.getFlags();
if (isFreshChat) {
window.fcWidget?.user.clear().then(
() => window.fcWidget.destroy()
);
} else if (isIntercom) {
window.Intercom('shutdown');
}
},

};

export default Chat;
24 changes: 0 additions & 24 deletions src/javascript/_common/utility.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,28 +289,6 @@ class PromiseClass {
const lc_licenseID = 12049137;
const lc_clientID = '66aa088aad5a414484c1fd1fa8a5ace7';

const openChat = () => {
if (window.fcWidget) {
window.fcWidget.open();
} else {
window.LC_API.open_chat_window();
}
};

const openChatWithParam = () => {
const interval = setInterval(() => {
if (window.fcWidget) {
window.fcWidget.open();
clearInterval(interval);
} else if (window.LiveChatWidget) {
window.LiveChatWidget?.on('ready', () => {
window.LC_API.open_chat_window();
});
clearInterval(interval);
}
}, 500);
};

module.exports = {
showLoadingImage,
getHighestZIndex,
Expand All @@ -336,6 +314,4 @@ module.exports = {
getHostname,
lc_licenseID,
lc_clientID,
openChat,
openChatWithParam,
};
16 changes: 8 additions & 8 deletions src/javascript/app/base/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const mapCurrencyName = require('../../_common/base/currency_base').map
const isEuCountry = require('../common/country_base').isEuCountry;
const DerivIFrame = require('../pages/deriv_iframe.jsx');
const DerivLiveChat = require('../pages/livechat.jsx');
const openChat = require('../../_common/utility.js').openChat;
const Chat = require('../../_common/chat.js').default;
const getRemoteConfig = require('../hooks/useRemoteConfig').getRemoteConfig;

const header_icon_base_path = '/images/pages/header/';
Expand Down Expand Up @@ -352,7 +352,9 @@ const Header = (() => {

hamburger_menu.addEventListener('click', () => showMobileMenu(true));
mobile_menu_close.addEventListener('click', () => showMobileMenu(false));
mobile_menu_livechat.addEventListener('click', () => {openChat();});
mobile_menu_livechat.addEventListener('click', async () => {
await Chat.open();
});

// Mobile Menu Livechat Icon
mobile_menu__livechat_logo.src = Url.urlForStatic(`images/common/livechat.svg?${process.env.BUILD_HASH}`);
Expand Down Expand Up @@ -570,8 +572,8 @@ const Header = (() => {

// Livechat Launcher
const livechat = getElementById('livechat');
livechat.addEventListener('click', () => {
openChat();
livechat.addEventListener('click', async () => {
await Chat.open();
});

// Language Popup.
Expand Down Expand Up @@ -656,10 +658,8 @@ const Header = (() => {
};

const logoutOnClick = async () => {
window.fcWidget?.user.clear().then(
() => window.fcWidget.destroy(),
() => {}
);
await Chat.clear();

// This will wrap the logout call Client.sendLogoutRequest with our own logout iframe, which is to inform Hydra that the user is logging out
// and the session should be cleared on Hydra's side. Once this is done, it will call the passed-in logout handler Client.sendLogoutRequest.
// If Hydra authentication is not enabled, the logout handler Client.sendLogoutRequest will just be called instead.
Expand Down
4 changes: 2 additions & 2 deletions src/javascript/app/base/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const scrollToTop = require('../../_common/scroll').scrollToTop;
const toISOFormat = require('../../_common/string_util').toISOFormat;
const Url = require('../../_common/url');
const Analytics = require('../../_common/analytics');
const { openChatWithParam } = require('../../_common/utility');
const Chat = require('../../_common/chat.js').default;
const createElement = require('../../_common/utility').createElement;
const isLoginPages = require('../../_common/utility').isLoginPages;
const isProduction = require('../../config').isProduction;
Expand Down Expand Up @@ -111,7 +111,7 @@ const Page = (() => {
// Handle opening livechat via URL
const is_livechat_open = url_query_strings.is_livechat_open === 'true';
if (is_livechat_open) {
openChatWithParam();
Chat.openWithParam();
}
}
Header.onLoad();
Expand Down
21 changes: 9 additions & 12 deletions src/javascript/app/hooks/useFreshChat.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import { useEffect, useState } from 'react';
import { useScript } from 'usehooks-ts';
import useGrowthbookGetFeatureValue from './useGrowthbookGetFeatureValue';

const useFreshChat = (token) => {
const scriptStatus = useScript('https://static.deriv.com/scripts/freshchat/freshchat-1.0.1.js');
const [isReady, setIsReady] = useState(false);
const [isFreshChatEnabled] = useGrowthbookGetFeatureValue({
featureFlag: 'enable_freshworks_live_chat',
});
const useFreshChat = (token, flag) => {
const freshchat_script = 'https://static.deriv.com/scripts/freshchat/v1.0.2.js';
const script_status = useScript(flag ? freshchat_script : null);
const [is_ready, setIsReady] = useState(false);

useEffect(() => {
const checkFcWidget = (intervalId) => {
if (typeof window !== 'undefined') {
if (window.fcWidget?.isInitialized() === true && !isReady) {
if (window.fcWidget?.isInitialized() === true && !is_ready) {
setIsReady(true);
clearInterval(intervalId);
}
}
};

const initFreshChat = () => {
if (scriptStatus === 'ready' && window.FreshChat && window.fcSettings) {
if (script_status === 'ready' && window.FreshChat && window.fcSettings) {
window.FreshChat.initialize({
token,
hideButton: true,
Expand All @@ -33,11 +30,11 @@ const useFreshChat = (token) => {
return null;
};

if (isFreshChatEnabled) initFreshChat();
}, [isFreshChatEnabled, isReady, scriptStatus, token]);
if (flag) initFreshChat();
}, [flag, script_status, token]);

return {
isReady,
is_ready,
widget: window.fcWidget,
};
};
Expand Down
22 changes: 22 additions & 0 deletions src/javascript/app/hooks/useInterComChat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useEffect } from 'react';
import { useScript } from 'usehooks-ts';

const useInterComChat = (token, flag) => {
const intercom_script = 'https://static.deriv.com/scripts/intercom/v1.0.1.js';
const script_status = useScript(flag ? intercom_script : null);

useEffect(() => {
if (!flag || script_status !== 'ready' || !window.DerivInterCom) return;

window.DerivInterCom.initialize({
token,
hideLauncher: true,
});
}, [
flag,
script_status,
token,
]);
};

export default useInterComChat;
30 changes: 23 additions & 7 deletions src/javascript/app/pages/livechat.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
import React from 'react';
import React, { useMemo } from 'react';
import ReactDOM from 'react-dom';
import useFreshChat from '../hooks/useFreshChat';
import useInterComChat from '../hooks/useInterComChat';
import useGrowthbookGetFeatureValue from '../hooks/useGrowthbookGetFeatureValue';
import { getElementById } from '../../_common/common_functions';

const LiveChat = ({ cs_live_chat }) => {

const loginid = localStorage.getItem('active_loginid');
const client_info = loginid && JSON.parse(localStorage.getItem('client.accounts') || '{}')[loginid];
const token = client_info?.token ?? null;
const loginid = useMemo(() => localStorage.getItem('active_loginid'), []);
const client_accounts = useMemo(
() => JSON.parse(localStorage.getItem('client.accounts') || '{}'),
[]
);
const client_data = useMemo(
() => (loginid ? client_accounts[loginid] : null),
[loginid, client_accounts]
);
const token = client_data?.token ?? null;

const [isFreshChatEnabled] = useGrowthbookGetFeatureValue({
featureFlag: 'enable_freshworks_live_chat',
});
useFreshChat(token);
const [isICEnabled] = useGrowthbookGetFeatureValue({
featureFlag: 'enable_intercom_st',
});

if (!isFreshChatEnabled && !cs_live_chat) return null;
const freshChat = useFreshChat(token, isFreshChatEnabled);
useInterComChat(token, isICEnabled);

if (!isFreshChatEnabled && !isICEnabled && !cs_live_chat) return null;
getElementById('livechat').style.display =
isFreshChatEnabled && !freshChat?.is_ready ? 'none' : 'flex';

return (
<React.Fragment>
{!isFreshChatEnabled && <script
{!isFreshChatEnabled && !isICEnabled && <script
dangerouslySetInnerHTML={{
__html: `
window.__lc = window.__lc || {};
Expand Down
2 changes: 1 addition & 1 deletion src/templates/app/endpoint.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const Endpoint = () => (
className='input-class'
type='text'
label={it.L('OAuth App ID')}
attributes={{ maxLength: 5 }}
attributes={{ maxLength: 7 }}
hint={it.L(
'You have to register and get App ID before you can use different OAuth server for authentication. For more information refer to OAuth details on https://api.deriv.com/.'
)}
Expand Down
Loading