diff --git a/packages/browser-destinations/destinations/moengage-web/README.md b/packages/browser-destinations/destinations/moengage-web/README.md new file mode 100644 index 00000000000..65d5d0a3e3e --- /dev/null +++ b/packages/browser-destinations/destinations/moengage-web/README.md @@ -0,0 +1,31 @@ +# @segment/analytics-browser-actions-moengage-web + +The Moengage Web browser action destination for use with @segment/analytics-next. + +## License + +MIT License + +Copyright (c) 2025 Segment + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +## Contributing + +All third party contributors acknowledge that any contributions they provide will be made under the same open source license that the open source project is provided under. diff --git a/packages/browser-destinations/destinations/moengage-web/package.json b/packages/browser-destinations/destinations/moengage-web/package.json new file mode 100644 index 00000000000..9a7e7253d1e --- /dev/null +++ b/packages/browser-destinations/destinations/moengage-web/package.json @@ -0,0 +1,24 @@ +{ + "name": "@segment/analytics-browser-actions-moengage-web", + "version": "1.0.0", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/segmentio/action-destinations", + "directory": "packages/browser-destinations/destinations/moengage-web" + }, + "main": "./dist/cjs", + "module": "./dist/esm", + "scripts": { + "build": "yarn build:esm && yarn build:cjs", + "build:cjs": "tsc --module commonjs --outDir ./dist/cjs", + "build:esm": "tsc --outDir ./dist/esm" + }, + "typings": "./dist/esm", + "dependencies": { + "@segment/browser-destination-runtime": "^1.4.0" + }, + "peerDependencies": { + "@segment/analytics-next": ">=1.55.0" + } +} diff --git a/packages/browser-destinations/destinations/moengage-web/src/__tests__/index.test.ts b/packages/browser-destinations/destinations/moengage-web/src/__tests__/index.test.ts new file mode 100644 index 00000000000..72fed71b8e8 --- /dev/null +++ b/packages/browser-destinations/destinations/moengage-web/src/__tests__/index.test.ts @@ -0,0 +1,4 @@ +import { Analytics, Context } from '@segment/analytics-next' +import plugins, { destination } from '../index' + +describe('Moengage Web', () => {}) diff --git a/packages/browser-destinations/destinations/moengage-web/src/functions.ts b/packages/browser-destinations/destinations/moengage-web/src/functions.ts new file mode 100644 index 00000000000..45387dfb299 --- /dev/null +++ b/packages/browser-destinations/destinations/moengage-web/src/functions.ts @@ -0,0 +1,127 @@ +import { Settings } from './generated-types' + +export async function initializeSDK(settings: Settings): MoengageSDK { + const { + app_id, + env, + moeDataCenter, + project_id, + swPath, + enableSPA, + disable_onsite, + customProxyDomain, + bots_list, + disableCookies, + disableSdk, + cards_enabled, + css_selector_inbox_icon, + floating_bell_icon_desktop, + floating_bell_icon_mobile + } = settings + + !(function (e, n, i, t, a, r, o, d) { + if (!moeDataCenter || !moeDataCenter.match(/^dc_[0-9]+$/gm)) + return console.error( "Data center has not been passed correctly. Please follow the SDK installation instruction carefully." ); + var s = (e[a] = e[a] || []); + if (((s.invoked = 0), s.initialised > 0 || s.invoked > 0)) + return ( + console.error( + "MoEngage Web SDK initialised multiple times. Please integrate the Web SDK only once!" + ), + !1 + ); + e.moengage_object = a; + var l = {}, + g = function n(i) { + return function () { + for (var n = arguments.length, t = Array(n), a = 0; a < n; a++) + t[a] = arguments[a]; + (e.moengage_q = e.moengage_q || []).push({ f: i, a: t }); + }; + }, + u = [ + "track_event", + "add_user_attribute", + "add_first_name", + "add_last_name", + "add_email", + "add_mobile", + "add_user_name", + "add_gender", + "add_birthday", + "destroy_session", + "add_unique_user_id", + "update_unique_user_id", + "moe_events", + "call_web_push", + "track", + "location_type_attribute", + "identifyUser", + "getUserIdentities", + ], + m = { onsite: ["getData", "registerCallback", "getSelfHandledOSM"] }; + for (var c in u) l[u[c]] = g(u[c]); + for (var v in m) + for (var f in m[v]) + null == l[v] && (l[v] = {}), (l[v][m[v][f]] = g(v + "." + m[v][f])); + (r = n.createElement(i)), + (o = n.getElementsByTagName("head")[0]), + (r.async = 1), + (r.src = t), + o.appendChild(r), + (e.moe = + e.moe || + function () { + return ((s.invoked = s.invoked + 1), s.invoked > 1) + ? (console.error( + "MoEngage Web SDK initialised multiple times. Please integrate the Web SDK only once!" + ), + !1) + : ((d = arguments.length <= 0 ? void 0 : arguments[0]), l); + }), + r.addEventListener("load", function () { + if (d) + return ( + (e[a] = e.moe(d)), (e[a].initialised = e[a].initialised + 1 || 1), !0 + ); + }), + r.addEventListener("error", function () { + return console.error("Moengage Web SDK loading failed."), !1; + }); + })( + window, + document, + "script", + "https://cdn.moengage.com/release/" + + moeDataCenter + + "/moe_webSdk.min.latest.js", + "Moengage" + ); + + Moengage = moe({ + app_id, + env, + ...(project_id ? { project_id } : {}), + ...(typeof enableSPA === 'boolean' ? { enableSPA } : {}), + ...(typeof disable_onsite === 'boolean' ? { disable_onsite } : {}), + ...(typeof customProxyDomain === 'string' && customProxyDomain.length>0 ? { customProxyDomain } : {}), + ...(typeof bots_list === 'string' && bots_list.length>0 ? { bots_list: bots_list.split(',').map(bot => bot.trim()) } : {}), + ...(typeof disableCookies === 'boolean' ? { disableCookies } : {}), + ...(typeof disableSdk === 'boolean' ? { disableSdk } : {}), + ...(swPath ? { swPath } : {}), + ...(cards_enabled ? { + cards: { + enable: cards_enabled, + placeholder: css_selector_inbox_icon, + webFloating: { + enable: floating_bell_icon_desktop + }, + mWebFloating: { + enable: floating_bell_icon_mobile + } + } + } : {}) + }); + + return Moengage as MoengageSDK +} \ No newline at end of file diff --git a/packages/browser-destinations/destinations/moengage-web/src/generated-types.ts b/packages/browser-destinations/destinations/moengage-web/src/generated-types.ts new file mode 100644 index 00000000000..f59e8d9af0b --- /dev/null +++ b/packages/browser-destinations/destinations/moengage-web/src/generated-types.ts @@ -0,0 +1,62 @@ +// Generated file. DO NOT MODIFY IT BY HAND. + +export interface Settings { + /** + * Your Moengage Workspace ID. + */ + app_id: string + /** + * The environment for your Moengage account. + */ + env: string + /** + * The datacenter for your Moengage account. + */ + moeDataCenter: string + /** + * Your Moengage Project ID. + */ + project_id?: string + /** + * The path to the service worker file for MoEngage web push notifications. if provided here, you need to host this file on your server. + */ + swPath?: string + /** + * Enable Single Page Application (SPA) support in the Moengage SDK. Enable this if your website is a single page application to ensure proper tracking. + */ + enableSPA?: boolean + /** + * Disable Moengage from showing Onsite Messaging on your website. + */ + disable_onsite?: boolean + /** + * A custom domain name where the MoEngage web SDK is hosted. Data will be sent to this domain. + */ + customProxyDomain?: string + /** + * A comma delimited list of bot user agents to ignore when tracking events. + */ + bots_list?: string + /** + * Disable Moengage from setting cookies on your website when the page loads. + */ + disableCookies?: boolean + /** + * Disable the Moengage SDK from initializing on your website when the page loads. You can use this to conditionally load the SDK based on user consent. + */ + disableSdk?: boolean + + cards_enabled: boolean + /** + * The CSS selector for the MoEngage Inbox icon on your website. The user will click this icon to open the inbox. + */ + css_selector_inbox_icon?: string + /** + * Enable the floating bell icon for MoEngage notifications on desktop devices. + */ + floating_bell_icon_desktop?: boolean + /** + * Enable the floating bell icon for MoEngage notifications on mobile devices. + */ + floating_bell_icon_mobile?: boolean +} diff --git a/packages/browser-destinations/destinations/moengage-web/src/index.ts b/packages/browser-destinations/destinations/moengage-web/src/index.ts new file mode 100644 index 00000000000..32dacc8ab2f --- /dev/null +++ b/packages/browser-destinations/destinations/moengage-web/src/index.ts @@ -0,0 +1,162 @@ +import type { Settings } from './generated-types' +import type { BrowserDestinationDefinition } from '@segment/browser-destination-runtime/types' +import { browserDestination } from '@segment/browser-destination-runtime/shim' +import trackEvent from './trackEvent' +import { initializeSDK } from './functions' + +// Switch from unknown to the partner SDK client types +export const destination: BrowserDestinationDefinition = { + name: 'Moengage Web', + slug: 'actions-moengage-web', + mode: 'device', + + settings: { + app_id: { + description: 'Your Moengage Workspace ID.', + label: 'Workspace ID', + type: 'string', + format: 'password', + required: true + }, + env: { + description: 'The environment for your Moengage account.', + label: 'Environment', + type: 'string', + required: true, + default: 'LIVE', + choices: [ + { label: 'LIVE', value: 'LIVE' }, + { label: 'TEST', value: 'TEST' } + ] + }, + moeDataCenter: { + description: 'The datacenter for your Moengage account.', + label: 'Datacenter', + type: 'string', + required: true, + default: 'dc_1', + choices: [ + { label: 'DC-01', value: 'dc_1' }, + { label: 'DC-02', value: 'dc_2' }, + { label: 'DC-03', value: 'dc_3' }, + { label: 'DC-04', value: 'dc_4' }, + { label: 'DC-05', value: 'dc_5' }, + { label: 'DC-06', value: 'dc_6' } + ] + }, + project_id: { + description: 'Your Moengage Project ID.', + label: 'Project ID', + type: 'string', + format: 'password', + required: false + }, + swPath: { + label: 'Service Worker Path', + type: 'string', + description: 'The path to the service worker file for MoEngage web push notifications. if provided here, you need to host this file on your server.', + required: false + }, + enableSPA: { + label: 'Enable Single Page Application (SPA) Support', + type: 'boolean', + description: 'Enable Single Page Application (SPA) support in the Moengage SDK. Enable this if your website is a single page application to ensure proper tracking.', + required: false, + default: false + }, + disable_onsite: { + label: 'Disable Onsite Messaging', + type: 'boolean', + description: 'Disable Moengage from showing Onsite Messaging on your website.', + required: false, + default: false + }, + customProxyDomain: { + label: 'Custom Proxy Domain', + type: 'string', + description: 'A custom domain name where the MoEngage web SDK is hosted. Data will be sent to this domain.', + required: false + }, + bots_list: { + label: 'Bots List', + type: 'string', + description: 'A comma delimited list of bot user agents to ignore when tracking events.', + required: false + }, + disableCookies: { + label: 'Disable Cookies', + type: 'boolean', + description: 'Disable Moengage from setting cookies on your website when the page loads.', + required: false, + default: false + }, + disableSdk:{ + label: 'Disable SDK', + type: 'boolean', + description: 'Disable the Moengage SDK from initializing on your website when the page loads. You can use this to conditionally load the SDK based on user consent.', + required: false, + default: false + }, + cards_enabled: { + label: 'Enable Cards', + type: 'boolean', + description: 'Enable MoEngage Cards on your website to engage users with personalized content.', + required: false, + default: false + }, + css_selector_inbox_icon: { + label: 'CSS Selector for Inbox Icon', + type: 'string', + description: 'The CSS selector for the MoEngage Inbox icon on your website. The user will click this icon to open the inbox.', + required: false, + depends_on:{ + conditions: [ + { + fieldKey: 'cards_enabled', + operator: 'is', + value: true + } + ] + } + }, + floating_bell_icon_desktop: { + label: 'Enable Floating Bell Icon on Desktop', + type: 'boolean', + description: 'Enable the floating bell icon for MoEngage notifications on desktop devices.', + required: false, + depends_on:{ + conditions: [ + { + fieldKey: 'cards_enabled', + operator: 'is', + value: true + } + ] + } + }, + floating_bell_icon_mobile: { + label: 'Enable Floating Bell Icon on Mobile', + type: 'boolean', + description: 'Enable the floating bell icon for MoEngage notifications on mobile devices.', + required: false, + depends_on:{ + conditions: [ + { + fieldKey: 'cards_enabled', + operator: 'is', + value: true + } + ] + } + } + }, + initialize: async ({ settings, analytics }, deps) => { + return await initializeSDK(settings) + }, + + actions: { + trackEvent + } +} + +export default browserDestination(destination) diff --git a/packages/browser-destinations/destinations/moengage-web/src/trackEvent/__tests__/index.test.ts b/packages/browser-destinations/destinations/moengage-web/src/trackEvent/__tests__/index.test.ts new file mode 100644 index 00000000000..d254ff27765 --- /dev/null +++ b/packages/browser-destinations/destinations/moengage-web/src/trackEvent/__tests__/index.test.ts @@ -0,0 +1,6 @@ +import { Analytics, Context } from '@segment/analytics-next' +import { destination } from '../../index' + +describe('Src.trackEvent', () => { + // TODO: Test your action +}) diff --git a/packages/browser-destinations/destinations/moengage-web/src/trackEvent/generated-types.ts b/packages/browser-destinations/destinations/moengage-web/src/trackEvent/generated-types.ts new file mode 100644 index 00000000000..944d22b0857 --- /dev/null +++ b/packages/browser-destinations/destinations/moengage-web/src/trackEvent/generated-types.ts @@ -0,0 +1,3 @@ +// Generated file. DO NOT MODIFY IT BY HAND. + +export interface Payload {} diff --git a/packages/browser-destinations/destinations/moengage-web/src/trackEvent/index.ts b/packages/browser-destinations/destinations/moengage-web/src/trackEvent/index.ts new file mode 100644 index 00000000000..68ea37a131a --- /dev/null +++ b/packages/browser-destinations/destinations/moengage-web/src/trackEvent/index.ts @@ -0,0 +1,20 @@ +import type { BrowserActionDefinition } from '@segment/browser-destination-runtime/types' +import type { Settings } from '../generated-types' +import type { Payload } from './generated-types' + +// Change from unknown to the partner SDK types +const action: BrowserActionDefinition = { + title: 'Track Event', + description: 'Send Segment track events to Moengage.', + platform: 'web', + fields: { + + }, + perform: ({_client}) => { + + + // code which calls the moengage web SDK to send data to Moengage + } +} + +export default action diff --git a/packages/browser-destinations/destinations/moengage-web/src/types.ts b/packages/browser-destinations/destinations/moengage-web/src/types.ts new file mode 100644 index 00000000000..4950394cff5 --- /dev/null +++ b/packages/browser-destinations/destinations/moengage-web/src/types.ts @@ -0,0 +1,5 @@ + + +export interface MoengageSDK { + +} \ No newline at end of file diff --git a/packages/browser-destinations/destinations/moengage-web/tsconfig.json b/packages/browser-destinations/destinations/moengage-web/tsconfig.json new file mode 100644 index 00000000000..c2a7897afd6 --- /dev/null +++ b/packages/browser-destinations/destinations/moengage-web/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.build.json", + "compilerOptions": { + "rootDir": "./src", + "baseUrl": "." + }, + "include": ["src"], + "exclude": ["dist", "**/__tests__"] +}