diff --git a/app/javascript/packs/sdk.js b/app/javascript/packs/sdk.js index bd2d718aa..10e21741a 100755 --- a/app/javascript/packs/sdk.js +++ b/app/javascript/packs/sdk.js @@ -2,17 +2,12 @@ import Cookies from 'js-cookie'; import { IFrameHelper } from '../sdk/IFrameHelper'; import { getBubbleView } from '../sdk/bubbleHelpers'; import md5 from 'md5'; +import { getUserCookieName } from '../sdk/cookieHelpers'; const REQUIRED_USER_KEYS = ['avatar_url', 'email', 'name']; const ALLOWED_USER_ATTRIBUTES = [...REQUIRED_USER_KEYS, 'identifier_hash']; -export const getUserCookieName = () => { - const SET_USER_COOKIE_PREFIX = 'cw_user_'; - const { websiteToken: websiteIdentifier } = window.$chatwoot; - return `${SET_USER_COOKIE_PREFIX}${websiteIdentifier}`; -}; - export const getUserString = ({ identifier = '', user }) => { const userStringWithSortedKeys = ALLOWED_USER_ATTRIBUTES.reduce( (acc, key) => `${acc}${key}${user[key] || ''}`, diff --git a/app/javascript/sdk/IFrameHelper.js b/app/javascript/sdk/IFrameHelper.js index 8dba6b13d..a5a90dee7 100644 --- a/app/javascript/sdk/IFrameHelper.js +++ b/app/javascript/sdk/IFrameHelper.js @@ -23,8 +23,9 @@ import { removeUnreadClass, } from './bubbleHelpers'; import { dispatchWindowEvent } from 'shared/helpers/CustomEventHelper'; - -const EVENT_NAME = 'chatwoot:ready'; +import { CHATWOOT_ERROR, CHATWOOT_READY } from '../widget/constants/sdkEvents'; +import { SET_USER_ERROR } from '../widget/constants/errorTypes'; +import { getUserCookieName } from './cookieHelpers'; export const IFrameHelper = { getUrl({ baseUrl, websiteToken }) { @@ -129,7 +130,14 @@ export const IFrameHelper = { if (window.$chatwoot.user) { IFrameHelper.sendMessage('set-user', window.$chatwoot.user); } - dispatchWindowEvent(EVENT_NAME); + dispatchWindowEvent({ eventName: CHATWOOT_READY }); + }, + error: ({ errorType, data }) => { + dispatchWindowEvent({ eventName: CHATWOOT_ERROR, data: data }); + + if (errorType === SET_USER_ERROR) { + Cookies.remove(getUserCookieName()); + } }, setBubbleLabel(message) { diff --git a/app/javascript/sdk/cookieHelpers.js b/app/javascript/sdk/cookieHelpers.js new file mode 100644 index 000000000..d56448569 --- /dev/null +++ b/app/javascript/sdk/cookieHelpers.js @@ -0,0 +1,5 @@ +export const getUserCookieName = () => { + const SET_USER_COOKIE_PREFIX = 'cw_user_'; + const { websiteToken: websiteIdentifier } = window.$chatwoot; + return `${SET_USER_COOKIE_PREFIX}${websiteIdentifier}`; +}; diff --git a/app/javascript/sdk/specs/cookieHelpers.spec.js b/app/javascript/sdk/specs/cookieHelpers.spec.js new file mode 100644 index 000000000..c0edc1348 --- /dev/null +++ b/app/javascript/sdk/specs/cookieHelpers.spec.js @@ -0,0 +1,8 @@ +import { getUserCookieName } from '../cookieHelpers'; + +describe('#getUserCookieName', () => { + it('returns correct cookie name', () => { + global.$chatwoot = { websiteToken: '123456' }; + expect(getUserCookieName()).toBe('cw_user_123456'); + }); +}); diff --git a/app/javascript/shared/helpers/CustomEventHelper.js b/app/javascript/shared/helpers/CustomEventHelper.js index df5d4bb0c..1b1bb4c2f 100644 --- a/app/javascript/shared/helpers/CustomEventHelper.js +++ b/app/javascript/shared/helpers/CustomEventHelper.js @@ -1,15 +1,15 @@ -export const createEvent = eventName => { +export const createEvent = ({ eventName, data = null }) => { let event; if (typeof window.CustomEvent === 'function') { - event = new CustomEvent(eventName); + event = new CustomEvent(eventName, { detail: data }); } else { event = document.createEvent('CustomEvent'); - event.initCustomEvent(eventName, false, false, null); + event.initCustomEvent(eventName, false, false, data); } return event; }; -export const dispatchWindowEvent = eventName => { - const event = createEvent(eventName); +export const dispatchWindowEvent = ({ eventName, data }) => { + const event = createEvent({ eventName, data }); window.dispatchEvent(event); }; diff --git a/app/javascript/shared/helpers/specs/CustomEventHelper.spec.js b/app/javascript/shared/helpers/specs/CustomEventHelper.spec.js index f6fe0908f..09ea71c7e 100644 --- a/app/javascript/shared/helpers/specs/CustomEventHelper.spec.js +++ b/app/javascript/shared/helpers/specs/CustomEventHelper.spec.js @@ -3,7 +3,7 @@ import { dispatchWindowEvent } from '../CustomEventHelper'; describe('dispatchWindowEvent', () => { it('dispatches correct event', () => { window.dispatchEvent = jest.fn(); - dispatchWindowEvent('chatwoot:ready'); + dispatchWindowEvent({ eventName: 'chatwoot:ready' }); expect(dispatchEvent).toHaveBeenCalled(); }); }); diff --git a/app/javascript/specs/packs/sdk.spec.js b/app/javascript/specs/packs/sdk.spec.js index 68663e82f..c9c546cdb 100644 --- a/app/javascript/specs/packs/sdk.spec.js +++ b/app/javascript/specs/packs/sdk.spec.js @@ -1,11 +1,4 @@ -import { getUserCookieName, getUserString, hasUserKeys } from '../../packs/sdk'; - -describe('#getUserCookieName', () => { - it('returns correct cookie name', () => { - global.$chatwoot = { websiteToken: '123456' }; - expect(getUserCookieName()).toBe('cw_user_123456'); - }); -}); +import { getUserString, hasUserKeys } from '../../packs/sdk'; describe('#getUserString', () => { it('returns correct user string', () => { diff --git a/app/javascript/widget/constants/errorTypes.js b/app/javascript/widget/constants/errorTypes.js new file mode 100644 index 000000000..3e31acaf9 --- /dev/null +++ b/app/javascript/widget/constants/errorTypes.js @@ -0,0 +1 @@ +export const SET_USER_ERROR = 'SET_USER_ERROR'; diff --git a/app/javascript/widget/constants/sdkEvents.js b/app/javascript/widget/constants/sdkEvents.js new file mode 100644 index 000000000..3accb1123 --- /dev/null +++ b/app/javascript/widget/constants/sdkEvents.js @@ -0,0 +1,2 @@ +export const CHATWOOT_ERROR = 'chatwoot:error'; +export const CHATWOOT_READY = 'chatwoot:ready'; diff --git a/app/javascript/widget/store/modules/contacts.js b/app/javascript/widget/store/modules/contacts.js index 051061fc5..79fb36de6 100644 --- a/app/javascript/widget/store/modules/contacts.js +++ b/app/javascript/widget/store/modules/contacts.js @@ -1,5 +1,6 @@ +import { IFrameHelper } from 'widget/helpers/utils'; import ContactsAPI from '../../api/contacts'; - +import { SET_USER_ERROR } from '../../constants/errorTypes'; const state = { currentUser: {}, }; @@ -38,7 +39,14 @@ export const actions = { dispatch('conversation/fetchOldConversations', {}, { root: true }); } } catch (error) { - // Ignore error + const { + response: { data }, + } = error; + IFrameHelper.sendMessage({ + event: 'error', + errorType: SET_USER_ERROR, + data, + }); } }, setCustomAttributes: async (_, customAttributes = {}) => { diff --git a/app/javascript/widget/store/modules/specs/contact/actions.spec.js b/app/javascript/widget/store/modules/specs/contact/actions.spec.js index c16b0eb20..f116e03f7 100644 --- a/app/javascript/widget/store/modules/specs/contact/actions.spec.js +++ b/app/javascript/widget/store/modules/specs/contact/actions.spec.js @@ -2,6 +2,7 @@ import { API } from 'widget/helpers/axios'; import { actions } from '../../contacts'; const commit = jest.fn(); +const dispatch = jest.fn(); jest.mock('widget/helpers/axios'); describe('#actions', () => { @@ -11,11 +12,16 @@ describe('#actions', () => { email: 'thoma@sphadikam.com', name: 'Adu Thoma', avatar_url: '', - identifier_hash: 'malana_hash', + identifier_hash: 'random_hex_identifier_hash', }; API.patch.mockResolvedValue({ data: { pubsub_token: 'token' } }); - await actions.update({ commit }, { identifier: 1, user }); + await actions.update({ commit, dispatch }, { identifier: 1, user }); expect(commit.mock.calls).toEqual([]); + expect(dispatch.mock.calls).toEqual([ + ['get'], + ['conversation/clearConversations', {}, { root: true }], + ['conversation/fetchOldConversations', {}, { root: true }], + ]); }); }); }); diff --git a/app/views/widget_tests/index.html.erb b/app/views/widget_tests/index.html.erb index c1de883ee..b6283e992 100644 --- a/app/views/widget_tests/index.html.erb +++ b/app/views/widget_tests/index.html.erb @@ -36,14 +36,18 @@ window.chatwootSettings = { })(document,"script"); window.addEventListener('chatwoot:ready', function() { - console.log(window.$chatwoot); + console.log('chatwoot:ready', window.$chatwoot); if (window.location.search.includes('setUser')) { window.$chatwoot.setUser('<%= user_id %>', { - identifier_hash: '<%= user_hash %>', + identifier_hash: 'a<%= user_hash %>', email: 'jane@example.com', name: 'Jane Doe', phone_number: '' }); } }) + +window.addEventListener('chatwoot:error', function(e) { + console.log('chatwoot:error', e.details) +})