UNPKG

@textback/notification-widget

Version:

TODO: Give a short introduction of your project. Let this section explain the objectives or the motivation behind this project.

203 lines (171 loc) 6.18 kB
import UUID from 'uuid-js'; import assign from 'lodash/assign'; import apiErrorHandler from '../utils/apiErrorHandler.js'; import loadConfig from '../utils/loadConfig.js'; import loadDeepLink from '../utils/loadDeepLink.js'; import loadSubscriptions from '../utils/loadSubscriptions.js'; import cookies from '../utils/cookies.js'; import constants from '../utils/constants.js'; import parseQueryString from '../utils/parseQueryString.js'; import find from '../utils/find.js'; import appInsights from '../utils/appInsights.js'; import channelsFactory from '../channels/factory.js'; const INITIAL_CONFIG_DEFAULTS = { apiPath: 'https://api.textback.io/api', }; export default class Widget { constructor(config, sdk) { this.initialConfig = assign({}, INITIAL_CONFIG_DEFAULTS, config); this.sdk = sdk; this.config = {}; this.channels = []; this.initialized = false; this.initPromise = null; this.id = this.initialConfig.widgetId; this.widgetUserId = Widget.getWidgetUserId(); this.insecureContext = Widget.createInsecureContext(this.initialConfig.insecureContext); this.secureContextToken = this.initialConfig.secureContextToken; } getConfig() { return this.config; } initialize() { this.initPromise = Promise.all([ this.initializeConfig(), loadSubscriptions(this.widgetUserId, this.initialConfig.widgetId, this.initialConfig.apiPath), ]).then(([config, subscriptions]) => { this.config = config.$value; this.subscriptions = subscriptions.$items; this.useVKApi = this.config.type === constants.WIDGET_TYPE_API_CALL; this.aiKey = Widget.getAiKey(config); let customDeeplinkData = this.config.channels.filter( c => c.hasOwnProperty('additionalProperties') && c.additionalProperties.hasOwnProperty('customDeeplinkValue') ).filter( c => c.channel === 'whatsapp' || c.channel === 'whatsappb' ).filter( c => c.enabled ).map( ({additionalProperties, channel, channelId}) => { return { channel: channel, channelId: channelId, customDeeplinkValue: additionalProperties.customDeeplinkValue }; } ); let deeplinkData = { accountId: this.config.accountId, insecureContext: this.insecureContext, widgetId: this.config.id, secureContextToken: this.secureContextToken, user: { id: this.widgetUserId } }; if(customDeeplinkData.length > 0) { deeplinkData.customDeeplinkValue = customDeeplinkData; } return Promise.all([ loadDeepLink( this.initialConfig.apiPath, deeplinkData ), appInsights.init(this.aiKey, this.widgetUserId, this.config.accountId) ]); }).then(([deeplink, ai]) => { this.deeplink = `subscribe_${deeplink.$value.id}`; this.channels = this.config.channels.map(channel => channelsFactory.create(channel, this.deeplink, this)) .filter(channel => !!channel); const channelInitPromises = this.channels.filter( channel => !!channel.initPromise ).map( channel => channel.initPromise ); return Promise.all(channelInitPromises); }).then(channelPromises => { return this; }, err => { appInsights.trackWidgetEvent(this.config.id, 'Widget.initialize.error', err); return Promise.reject(err); }); return this.initPromise; } initializeConfig() { let promise; if (!this.initialConfig.overrideConfig) { promise = loadConfig(this.initialConfig.widgetId, this.initialConfig.apiPath); } else { promise = Promise.resolve({ $value: this.initialConfig.overrideConfig }); } return promise; } subscribe(channelCode) { const channel = find(this.getEnabledChannels(), chan => chan.channel === channelCode); if (channel) { channel.subscribe(); } } getChannels() { return this.channels; } getEnabledChannels() { return this.channels.filter(channel => channel.enabled && !channel.hasError); } runWahunter(phoneNumber, sendPersonalType, sendMarketingType) { const body = { notificationWidgetId: this.initialConfig.widgetId, phone: phoneNumber, insecureContext: this.insecureContext, deeplinkId: this.deeplink, consentsGranted: [], }; if (sendPersonalType) { body.consentsGranted.push({type: 'personal'}) } if (sendMarketingType) { body.consentsGranted.push({type: 'marketing'}) } return fetch(`${this.initialConfig.apiPath}/wahunter`, { method: 'POST', headers: { 'Content-Type': 'application/json;charset=utf-8' }, body: JSON.stringify(body), }).then((resp) => { if (resp.ok) { cookies.setCookie(`${constants.COOKIE_NAME_PREFIX + this.id}_wahunter_was_run`, true, this.config.showWidgetSetting.showSessionLength * 60); } else { return Promise.reject(resp); } }) } static getWidgetUserId() { let widgetUserId = cookies.getCookie(constants.COOKIE_WIDGET_USER_ID); if (widgetUserId === null) { let uuid = UUID.create(4); widgetUserId = uuid.hex; cookies.setCookie(constants.COOKIE_WIDGET_USER_ID, widgetUserId, constants.WIDGET_USER_ID_COOKIE_TTL); } return widgetUserId; } static createInsecureContext(insecureContext = {}) { const ctx = assign({}, insecureContext);//Object.assign({}, insecureContext); ctx.pageTitle = window.document.title; ctx.pageUrl = window.location.protocol + '//' + window.location.host + window.location.pathname; ctx.params = parseQueryString(window.location.search.substring(1)); ctx.timezoneOffset = new Date().getTimezoneOffset(); ctx.cookies = cookies.getCookieObject(); const roistatVisitCookie = cookies.getCookie("roistat_visit"); if (roistatVisitCookie) { ctx.roistatVisit = roistatVisitCookie; } return ctx; } static getAiKey(config) { let aiKey = undefined; try { aiKey = config.headers.get('X-TB-AIKEY'); } catch (e) { } return aiKey; } }