diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 53c0abb02..d00aafc18 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -23,7 +23,9 @@ class DashboardController < ActionController::Base 'CREATE_NEW_ACCOUNT_FROM_DASHBOARD', 'CHATWOOT_INBOX_TOKEN', 'API_CHANNEL_NAME', - 'API_CHANNEL_THUMBNAIL' + 'API_CHANNEL_THUMBNAIL', + 'ANALYTICS_TOKEN', + 'ANALYTICS_HOST' ).merge( APP_VERSION: Chatwoot.config[:version] ) diff --git a/app/javascript/dashboard/components/layout/Sidebar.vue b/app/javascript/dashboard/components/layout/Sidebar.vue index 0d258fe98..e8c0e21f8 100644 --- a/app/javascript/dashboard/components/layout/Sidebar.vue +++ b/app/javascript/dashboard/components/layout/Sidebar.vue @@ -255,19 +255,11 @@ export default { return frontendURL(`accounts/${this.accountId}/dashboard`); }, }, - watch: { - currentUser(newUserInfo, oldUserInfo) { - if (!oldUserInfo.email && newUserInfo.email) { - this.setChatwootUser(); - } - }, - }, mounted() { this.$store.dispatch('labels/get'); this.$store.dispatch('inboxes/get'); this.$store.dispatch('notifications/unReadCount'); this.$store.dispatch('teams/get'); - this.setChatwootUser(); }, methods: { @@ -288,17 +280,6 @@ export default { toggleSupportChatWindow() { window.$chatwoot.toggle(); }, - setChatwootUser() { - if (!this.currentUser.email || !this.globalConfig.chatwootInboxToken) { - return; - } - window.$chatwoot.setUser(this.currentUser.email, { - name: this.currentUser.name, - email: this.currentUser.email, - avatar_url: this.currentUser.avatar_url, - identifier_hash: this.currentUser.hmac_identifier, - }); - }, filterMenuItemsByRole(menuItems) { if (!this.currentRole) { return []; diff --git a/app/javascript/dashboard/components/layout/sidebarComponents/OptionsMenu.vue b/app/javascript/dashboard/components/layout/sidebarComponents/OptionsMenu.vue index 52c1ede28..3fb66c14e 100644 --- a/app/javascript/dashboard/components/layout/sidebarComponents/OptionsMenu.vue +++ b/app/javascript/dashboard/components/layout/sidebarComponents/OptionsMenu.vue @@ -94,10 +94,6 @@ export default { methods: { logout() { Auth.logout(); - - if (this.globalConfig.chatwootInboxToken) { - window.$chatwoot.reset(); - } }, }, }; diff --git a/app/javascript/dashboard/helper/scriptHelpers.js b/app/javascript/dashboard/helper/scriptHelpers.js new file mode 100644 index 000000000..7bbc15e12 --- /dev/null +++ b/app/javascript/dashboard/helper/scriptHelpers.js @@ -0,0 +1,43 @@ +import posthog from 'posthog-js'; + +export const CHATWOOT_SET_USER = 'CHATWOOT_SET_USER'; +export const CHATWOOT_RESET = 'CHATWOOT_RESET'; + +export const ANALYTICS_IDENTITY = 'ANALYTICS_IDENTITY'; +export const ANALYTICS_RESET = 'ANALYTICS_RESET'; + +export const initializeAnalyticsEvents = () => { + window.bus.$on(ANALYTICS_IDENTITY, ({ user }) => { + if (window.analyticsConfig) { + posthog.identify(user.id, { name: user.name, email: user.email }); + } + }); + + window.bus.$on(ANALYTICS_RESET, () => { + if (window.analyticsConfig) { + posthog.reset(); + } + }); +}; + +export const initializeChatwootEvents = () => { + window.bus.$on(CHATWOOT_RESET, () => { + if (window.$chatwoot) { + window.$chatwoot.reset(); + } + }); + window.bus.$on(CHATWOOT_SET_USER, ({ user }) => { + if (window.$chatwoot) { + window.$chatwoot.setUser(user.email, { + avatar_url: user.avatar_url, + email: user.email, + identifier_hash: user.hmac_identifier, + name: user.name, + }); + window.$chatwoot.setCustomAttributes({ + signedUpAt: user.created_at, + cloudCustomer: 'true', + }); + } + }); +}; diff --git a/app/javascript/dashboard/store/modules/auth.js b/app/javascript/dashboard/store/modules/auth.js index 1ed23a41a..e0691049c 100644 --- a/app/javascript/dashboard/store/modules/auth.js +++ b/app/javascript/dashboard/store/modules/auth.js @@ -81,7 +81,9 @@ export const actions = { async validityCheck(context) { try { const response = await authAPI.validityCheck(); - setUser(response.data.payload.data, getHeaderExpiry(response)); + setUser(response.data.payload.data, getHeaderExpiry(response), { + setUserInSDK: true, + }); context.commit(types.default.SET_CURRENT_USER); } catch (error) { if (error?.response?.status === 401) { diff --git a/app/javascript/dashboard/store/utils/api.js b/app/javascript/dashboard/store/utils/api.js index 9c529808d..fefb6c136 100644 --- a/app/javascript/dashboard/store/utils/api.js +++ b/app/javascript/dashboard/store/utils/api.js @@ -3,6 +3,12 @@ import fromUnixTime from 'date-fns/fromUnixTime'; import differenceInDays from 'date-fns/differenceInDays'; import Cookies from 'js-cookie'; import { frontendURL } from '../../helper/URLHelper'; +import { + ANALYTICS_IDENTITY, + ANALYTICS_RESET, + CHATWOOT_RESET, + CHATWOOT_SET_USER, +} from '../../helper/scriptHelpers'; Cookies.defaults = { sameSite: 'Lax' }; @@ -11,10 +17,15 @@ export const setLoadingStatus = (state, status) => { state.fetchAPIloadingStatus = status; }; -export const setUser = (userData, expiryDate) => - Cookies.set('user', userData, { +export const setUser = (user, expiryDate, options = {}) => { + if (options && options.setUserInSDK) { + window.bus.$emit(CHATWOOT_SET_USER, { user }); + window.bus.$emit(ANALYTICS_IDENTITY, { user }); + } + Cookies.set('user', user, { expires: differenceInDays(expiryDate, new Date()), }); +}; export const getHeaderExpiry = response => fromUnixTime(response.headers.expiry); @@ -28,6 +39,9 @@ export const setAuthCredentials = response => { }; export const clearCookiesOnLogout = () => { + window.bus.$emit(CHATWOOT_RESET); + window.bus.$emit(ANALYTICS_RESET); + Cookies.remove('auth_data'); Cookies.remove('user'); window.location = frontendURL('login'); diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index 2b7b3cc30..200e40c74 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -34,6 +34,11 @@ import { import * as Sentry from '@sentry/vue'; import 'vue-easytable/libs/theme-default/index.css'; import { Integrations } from '@sentry/tracing'; +import posthog from 'posthog-js'; +import { + initializeAnalyticsEvents, + initializeChatwootEvents, +} from '../dashboard/helper/scriptHelpers'; Vue.config.env = process.env; @@ -45,6 +50,12 @@ if (window.errorLoggingConfig) { }); } +if (window.analyticsConfig) { + posthog.init(window.analyticsConfig.token, { + api_host: window.analyticsConfig.host, + }); +} + Vue.use(VueRouter); Vue.use(VueI18n); Vue.use(WootUiKit); @@ -75,6 +86,9 @@ commonHelpers(); window.WootConstants = constants; window.axios = createAxios(axios); window.bus = new Vue(); +initializeChatwootEvents(); +initializeAnalyticsEvents(); + window.onload = () => { window.WOOT = new Vue({ router, @@ -85,6 +99,7 @@ window.onload = () => { }).$mount('#app'); vueActionCable.init(); }; + window.addEventListener('load', () => { verifyServiceWorkerExistence(registration => registration.pushManager.getSubscription().then(subscription => { diff --git a/app/views/devise/token.json.jbuilder b/app/views/devise/token.json.jbuilder index 1de4594cd..7de1c51fd 100644 --- a/app/views/devise/token.json.jbuilder +++ b/app/views/devise/token.json.jbuilder @@ -1,4 +1,7 @@ json.payload do json.success true json.partial! 'auth.json.jbuilder', resource: @resource + json.data do + json.created_at @resource.created_at + end end diff --git a/app/views/layouts/vueapp.html.erb b/app/views/layouts/vueapp.html.erb index 621c62029..808b9c15a 100644 --- a/app/views/layouts/vueapp.html.erb +++ b/app/views/layouts/vueapp.html.erb @@ -48,6 +48,14 @@ } window.errorLoggingConfig = '<%= ENV.fetch('SENTRY_DSN', '')%>' + <% if @global_config['ANALYTICS_TOKEN'].present? && @global_config['ANALYTICS_HOST'].present? %> + + <% end %> <%= javascript_pack_tag 'application' %> <%= stylesheet_pack_tag 'application' %> @@ -55,21 +63,14 @@
<%= yield %> - <% @global_config['CHATWOOT_INBOX_TOKEN'] %> - <% if @global_config['CHATWOOT_INBOX_TOKEN'] %> + <% if @global_config['CHATWOOT_INBOX_TOKEN'].present? %>