@suprsend/web-sdk 1.5.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +0,0 @@
1
- /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
2
-
3
- /**
4
- * [js-md5]{@link https://github.com/emn178/js-md5}
5
- *
6
- * @namespace md5
7
- * @version 0.8.3
8
- * @author Chen, Yi-Cyuan [emn178@gmail.com]
9
- * @copyright Chen, Yi-Cyuan 2014-2023
10
- * @license MIT
11
- */
@@ -1,152 +0,0 @@
1
- function uuid() {
2
- var dt = new Date().getTime();
3
- var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
4
- /[xy]/g,
5
- function (c) {
6
- var r = (dt + Math.random() * 16) % 16 | 0;
7
- dt = Math.floor(dt / 16);
8
- return (c == "x" ? r : (r & 0x3) | 0x8).toString(16);
9
- }
10
- );
11
- return uuid;
12
- }
13
-
14
- function epoch_milliseconds() {
15
- return Math.round(Date.now());
16
- }
17
-
18
- function safe_get(cb, default_value) {
19
- var resp;
20
- try {
21
- resp = cb();
22
- } catch (err) {
23
- resp = default_value;
24
- }
25
- return resp;
26
- }
27
-
28
- var suprsend_config = {
29
- api_url: "https://hub.suprsend.com",
30
- imgkit_root: "https://ik.imagekit.io/l0quatz6utm/",
31
- api_events_route: "event/",
32
- workspace_key: "",
33
- };
34
-
35
- var valid_notification_params = [
36
- "title",
37
- "body",
38
- "icon",
39
- "image",
40
- "badge",
41
- "vibrate",
42
- "sound",
43
- "dir",
44
- "tag",
45
- "data",
46
- "requireInteraction",
47
- "renotify",
48
- "silent",
49
- "timestamp",
50
- "actions",
51
- ];
52
-
53
- var url_fields = ["image", "icon", "badge"];
54
-
55
- function init_workspace(key, url) {
56
- suprsend_config.workspace_key = key;
57
- if (url) {
58
- suprsend_config.api_url = url;
59
- }
60
- }
61
-
62
- function validate_notification(notification_obj) {
63
- var validated_notification_obj = {};
64
- for (var item in notification_obj) {
65
- if (valid_notification_params.includes(item)) {
66
- if (
67
- url_fields.includes(item) &&
68
- notification_obj[item] &&
69
- !notification_obj[item].startsWith("http")
70
- ) {
71
- validated_notification_obj[
72
- item
73
- ] = `${suprsend_config.imgkit_root}${notification_obj[item]}`;
74
- } else {
75
- validated_notification_obj[item] = notification_obj[item];
76
- }
77
- }
78
- }
79
- if (!(validated_notification_obj["actions"] instanceof Array)) {
80
- delete validated_notification_obj["actions"];
81
- }
82
- return validated_notification_obj;
83
- }
84
-
85
- function call_ss_api(body, method = "post") {
86
- var requested_date = new Date().toGMTString();
87
- var authorization = suprsend_config.workspace_key + ":";
88
- return fetch(
89
- `${suprsend_config.api_url}/${suprsend_config.api_events_route}`,
90
- {
91
- method: method,
92
- body: JSON.stringify(body),
93
- headers: {
94
- "Content-Type": "application/json",
95
- Authorization: authorization,
96
- "x-amz-date": requested_date,
97
- },
98
- }
99
- );
100
- }
101
-
102
- function send_notification_event(event_name, event_properties) {
103
- call_ss_api({
104
- event: event_name,
105
- env: suprsend_config.workspace_key,
106
- $insert_id: uuid(),
107
- $time: epoch_milliseconds(),
108
- properties: event_properties,
109
- });
110
- }
111
-
112
- self.addEventListener("push", function (e) {
113
- var notification = e.data.json();
114
- var validated_notification = validate_notification(notification);
115
- send_notification_event("$notification_delivered", {
116
- id: safe_get(() => validated_notification.data.notification_id),
117
- });
118
- e.waitUntil(
119
- self.registration.showNotification(
120
- validated_notification.title || "",
121
- validated_notification
122
- )
123
- );
124
- });
125
-
126
- self.addEventListener("notificationclose", function (e) {
127
- var notification = e.notification;
128
- send_notification_event("$notification_dismiss", {
129
- id: safe_get(() => notification.data.notification_id),
130
- });
131
- });
132
-
133
- self.addEventListener("notificationclick", function (e) {
134
- e.notification.close();
135
- var notification = e.notification;
136
- send_notification_event("$notification_clicked", {
137
- id: safe_get(() => notification.data.notification_id),
138
- label_id: e.action,
139
- });
140
- var launch_url_obj = safe_get(() => notification.data.launch_urls);
141
- var redirect_url = "/";
142
- if (launch_url_obj) {
143
- if (e.action && launch_url_obj[e.action]) {
144
- redirect_url = launch_url_obj[e.action];
145
- } else if (launch_url_obj["default"]) {
146
- redirect_url = launch_url_obj["default"];
147
- }
148
- } else {
149
- redirect_url = "/";
150
- }
151
- clients.openWindow(redirect_url);
152
- });
package/src/config.js DELETED
@@ -1,13 +0,0 @@
1
- const package_data = require("../package.json");
2
-
3
- const config = {
4
- api_url: "https://hub.suprsend.com",
5
- sdk_version: package_data.version,
6
- batch_size: 20,
7
- flush_interval: 3000, // in ms
8
- service_worker_file: "serviceworker.js",
9
- sw_delay: 5000, // in ms,
10
- preference_debounce: 1000, // in ms
11
- };
12
-
13
- export default config;
package/src/constants.js DELETED
@@ -1,50 +0,0 @@
1
- // suprsend sdk related constants
2
- export const constants = {
3
- distinct_id: "_suprsend_dist_id",
4
- bulk_events_key: "_bulk_api_call",
5
- api_events_route: "event/",
6
- super_properties_key: "_suprsend_super_props",
7
- device_id_key: "_suprsend_device_id",
8
- };
9
-
10
- export const internal_events = {
11
- app_launched: "$app_launched",
12
- user_login: "$user_login",
13
- user_logout: "$user_logout",
14
- purchase_made: "$purchase_made",
15
- };
16
-
17
- export const browser_useragent_map = {
18
- Edge: ["Edge"],
19
- "Opera Mini": ["Opera Mini"],
20
- "Opera Mobile": ["Opera Mobi"],
21
- Opera: ["Opera"],
22
- "Internet Explorer": ["Trident", "MSIE"],
23
- Chrome: ["Chrome", "CriOS"],
24
- Firefox: ["Firefox"],
25
- Safari: ["Safari"],
26
- Mozilla: ["Mozilla"],
27
- };
28
-
29
- export const browser_version_useragent_map = {
30
- Edge: [/Edge\/([0-9]+(\.[0-9]+)?)/],
31
- "Opera Mini": [/Opera Mini\/([0-9]+(\.[0-9]+)?)/],
32
- "Opera Mobile": [/Version\/([0-9]+(\.[0-9]+)?)/],
33
- Opera: [/Version\/([0-9]+(\.[0-9]+)?)/],
34
- "Internet Explorer": ["rv:"],
35
- Chrome: [/Chrome\/([0-9]+(\.[0-9]+)?)/, /CriOS\/([0-9]+(\.[0-9]+)?)/],
36
- Firefox: [/rv:([0-9]+(\.[0-9]+)?)/],
37
- Safari: [/Version\/([0-9]+(\.[0-9]+)?)/],
38
- Mozilla: [/rv:([0-9]+(\.[0-9]+)?)/],
39
- };
40
-
41
- export const os_useragent_map = {
42
- "Chrome OS": "CrOS",
43
- "Mac OS": "Macintosh",
44
- Windows: "Windows",
45
- iOS: "like Mac",
46
- Android: "Android",
47
- Linux: "Linux",
48
- };
49
-
50
- export const regex = { email: /\S+@\S+\.\S+/, mobile: /^\+[1-9]\d{1,14}$/ };
package/src/encryption.js DELETED
@@ -1,44 +0,0 @@
1
- import config from "./config";
2
- import { constants } from "./constants";
3
- import { md5 } from "js-md5";
4
-
5
- const getUtf8Bytes = (str) =>
6
- new Uint8Array(
7
- [...unescape(encodeURIComponent(str))].map((c) => c.charCodeAt(0))
8
- );
9
-
10
- export default async function create_signature(
11
- str,
12
- date,
13
- method,
14
- route = `/${constants.api_events_route}`
15
- ) {
16
- if (!window.crypto) {
17
- return;
18
- }
19
- const key = config.signing_key;
20
- const content_type = "application/json";
21
- let md5_str = "";
22
- if (str) {
23
- md5_str = md5(str);
24
- }
25
- const message = `${method}\n${md5_str}\n${content_type}\n${date}\n${route}`;
26
- const keyBytes = getUtf8Bytes(key);
27
- const messageBytes = getUtf8Bytes(message);
28
-
29
- const cryptoKey = await crypto.subtle.importKey(
30
- "raw",
31
- keyBytes,
32
- { name: "HMAC", hash: "SHA-256" },
33
- true,
34
- ["sign"]
35
- );
36
-
37
- const sig = await crypto.subtle.sign("HMAC", cryptoKey, messageBytes);
38
-
39
- // to lowercase hexits
40
- [...new Uint8Array(sig)].map((b) => b.toString(16).padStart(2, "0")).join("");
41
-
42
- // to base64
43
- return window.btoa(String.fromCharCode(...new Uint8Array(sig)));
44
- }
package/src/errors.js DELETED
@@ -1,20 +0,0 @@
1
- export class SuprsendError extends Error {
2
- constructor(message) {
3
- super(message);
4
- this.name = "SuprsendError";
5
- }
6
- }
7
-
8
- export class SSConfigurationError extends SuprsendError {
9
- constructor(message) {
10
- super(message);
11
- this.name = "SuprsendConfigurationError";
12
- }
13
- }
14
-
15
- export class SSValidationError extends SuprsendError {
16
- constructor(message) {
17
- super(message);
18
- this.name = "SuprsendValidationError";
19
- }
20
- }
package/src/index.d.ts DELETED
@@ -1,180 +0,0 @@
1
- import { Emitter } from "mitt";
2
-
3
- interface Dictionary {
4
- [key: string]: any;
5
- }
6
-
7
- export enum PreferenceOptions {
8
- OPT_IN = "opt_in",
9
- OPT_OUT = "opt_out",
10
- }
11
-
12
- export enum ChannelLevelPreferenceOptions {
13
- ALL = "all",
14
- REQUIRED = "required",
15
- }
16
-
17
- type EmitterEvents = {
18
- preferences_updated: PreferenceData;
19
- preferences_error: PreferenceErrorData;
20
- };
21
-
22
- interface CategoryChannel {
23
- channel: string;
24
- preference: PreferenceOptions;
25
- is_editable: boolean;
26
- }
27
-
28
- interface Category {
29
- name: string;
30
- category: string;
31
- description?: string | null;
32
- preference: PreferenceOptions;
33
- is_editable: boolean;
34
- channels?: CategoryChannel[] | null;
35
- }
36
-
37
- interface Section {
38
- name?: string | null;
39
- description?: string | null;
40
- subcategories?: Category[] | null;
41
- }
42
-
43
- interface ChannelPreference {
44
- channel: string;
45
- is_restricted: boolean;
46
- }
47
-
48
- interface PreferenceData {
49
- sections: Section[] | null;
50
- channel_preferences: ChannelPreference[] | null;
51
- }
52
-
53
- interface PreferenceErrorData {
54
- error: boolean;
55
- api_error?: boolean;
56
- message: string;
57
- status_code?: number | null;
58
- error_obj?: Error | null;
59
- }
60
-
61
- interface PreferencesResponse extends PreferenceData, PreferenceErrorData {}
62
-
63
- interface GetCategoriesResponse extends PreferenceErrorData {
64
- meta: { count: number; limit: number; offset: number };
65
- results: Category[] | null;
66
- }
67
-
68
- interface GetOverAllChannelPreferencesResponse extends PreferenceErrorData {
69
- channel_preferences: ChannelPreference[] | null;
70
- }
71
-
72
- interface Preferences {
73
- data: PreferenceData;
74
-
75
- get_preferences(args?: {
76
- tenant_id?: string;
77
- show_opt_out_channels?: boolean;
78
- }): Promise<PreferencesResponse>;
79
-
80
- get_categories(args?: {
81
- tenant_id?: string;
82
- limit?: number;
83
- offset?: number;
84
- show_opt_out_channels?: boolean;
85
- }): Promise<GetCategoriesResponse>;
86
-
87
- get_category(
88
- category: string,
89
- args?: { tenant_id?: string; show_opt_out_channels?: boolean }
90
- ): Promise<Category>;
91
-
92
- get_overall_channel_preferences(): Promise<GetOverAllChannelPreferencesResponse>;
93
-
94
- update_category_preference(
95
- category: string,
96
- preference: PreferenceOptions,
97
- args?: {
98
- tenant_id?: string;
99
- show_opt_out_channels?: boolean;
100
- }
101
- ): PreferencesResponse;
102
-
103
- update_channel_preference_in_category(
104
- channel: string,
105
- preference: PreferenceOptions,
106
- category: string,
107
- args?: {
108
- tenant_id?: string;
109
- show_opt_out_channels?: boolean;
110
- }
111
- ): PreferencesResponse;
112
-
113
- update_overall_channel_preference(
114
- channel: string,
115
- preference: ChannelLevelPreferenceOptions
116
- ): PreferencesResponse;
117
- }
118
-
119
- interface User {
120
- preferences: Preferences;
121
-
122
- set(key: string, value: any): void;
123
- set(prop: Dictionary): void;
124
-
125
- set_once(key: string, value: any): void;
126
- set_once(prop: Dictionary): void;
127
-
128
- increment(key: string, value: number): void;
129
- increment(prop: Dictionary): void;
130
-
131
- append(key: string, value: any): void;
132
- append(prop: Dictionary): void;
133
-
134
- remove(key: string, value: any): void;
135
- remove(prop: Dictionary): void;
136
-
137
- unset(key: string): void;
138
- unset(keys: string[]): void;
139
-
140
- add_email(email: string): void;
141
- remove_email(email: string): void;
142
-
143
- add_sms(mobile: string): void;
144
- remove_sms(mobile: string): void;
145
-
146
- add_whatsapp(mobile: string): void;
147
- remove_whatsapp(mobile: string): void;
148
-
149
- add_webpush(push: Dictionary): void;
150
- remove_webpush(push: Dictionary): void;
151
- }
152
-
153
- export interface WebPush {
154
- register_push(): void;
155
- notification_permission(): NotificationPermission;
156
- }
157
-
158
- export interface SuprSend {
159
- init(
160
- ENV_API_KEY: string,
161
- SIGNING_KEY: string,
162
- config_keys?: {
163
- api_url?: string;
164
- vapid_key?: string;
165
- service_worker_file?: string;
166
- }
167
- ): void;
168
- identify(unique_id: any): void;
169
- track(event: string, properties?: Dictionary): void;
170
- purchase_made(properties: Dictionary): void;
171
- reset(options?: { unsubscribe_push?: boolean }): void;
172
- set_super_properties(properties: Dictionary): void;
173
-
174
- user: User;
175
- web_push: WebPush;
176
- emitter: Emitter<EmitterEvents>;
177
- }
178
-
179
- declare const suprsend: SuprSend;
180
- export default suprsend;
package/src/index.js DELETED
@@ -1,182 +0,0 @@
1
- import utils from "./utils";
2
- import config from "./config";
3
- import User from "./user";
4
- import WebPush from "./web_push";
5
- import { constants, internal_events } from "./constants";
6
- import { SSConfigurationError } from "./errors";
7
- import mitt from "mitt";
8
- export {
9
- PreferenceOptions,
10
- ChannelLevelPreferenceOptions,
11
- } from "./preferences";
12
-
13
- var suprSendInstance;
14
- export var initialisedAt;
15
-
16
- class SuprSend {
17
- init(ENV_API_KEY, SIGNING_KEY, config_keys = {}) {
18
- config_keys.env = ENV_API_KEY;
19
- config_keys.signing_key = SIGNING_KEY;
20
- var distinct_id = utils.get_cookie(constants.distinct_id);
21
- if (!suprSendInstance) {
22
- suprSendInstance = {};
23
- this._set_custom_config(config_keys);
24
- }
25
- if (!distinct_id) {
26
- distinct_id = utils.uuid();
27
- utils.set_cookie(constants.distinct_id, distinct_id);
28
- }
29
- suprSendInstance.distinct_id = distinct_id;
30
-
31
- this.emitter = mitt();
32
- this.user = new User(suprSendInstance, this.emitter);
33
- this.web_push = new WebPush(suprSendInstance);
34
-
35
- this.web_push.update_subscription();
36
- SuprSend._set_env_properties();
37
- if (!initialisedAt) {
38
- utils.bulk_call_api();
39
- this.track(internal_events.app_launched);
40
- }
41
- initialisedAt = new Date();
42
- }
43
-
44
- static _set_env_properties() {
45
- let device_id = utils.get_local_storage_item(constants.device_id_key);
46
- if (!device_id) {
47
- device_id = utils.uuid();
48
- utils.set_local_storage_item(constants.device_id_key, device_id);
49
- }
50
- suprSendInstance.env_properties = {
51
- $os: utils.os(),
52
- $browser: utils.browser(),
53
- $browser_version: utils.browser_version(),
54
- $sdk_type: "Browser",
55
- $device_id: device_id,
56
- $sdk_version: config.sdk_version,
57
- };
58
- }
59
-
60
- _set_custom_config_property(key, value = "", mandatory = false) {
61
- if (value) {
62
- config[key] = value;
63
- } else {
64
- if (mandatory) {
65
- throw new SSConfigurationError(`Mandatory Key Missing: ${key}`);
66
- }
67
- }
68
- }
69
-
70
- _set_custom_config(config_keys) {
71
- this._set_custom_config_property("env_key", config_keys.env, true);
72
- this._set_custom_config_property(
73
- "signing_key",
74
- config_keys.signing_key,
75
- true
76
- );
77
- this._set_custom_config_property("api_url", config_keys?.api_url);
78
- this._set_custom_config_property("vapid_key", config_keys?.vapid_key);
79
- this._set_custom_config_property(
80
- "service_worker_file",
81
- config_keys?.sw_file_name
82
- );
83
- }
84
-
85
- set_super_properties(props = {}) {
86
- let existing_super_properties = utils.get_parsed_local_store_data(
87
- constants.super_properties_key
88
- );
89
- let new_super_props = { ...existing_super_properties, ...props };
90
- let formatted_super_props = {};
91
- for (let key in new_super_props) {
92
- if (!utils.has_special_char(key)) {
93
- formatted_super_props[key] = new_super_props[key];
94
- }
95
- }
96
- utils.set_local_storage_item(
97
- constants.super_properties_key,
98
- JSON.stringify(formatted_super_props)
99
- );
100
- suprSendInstance.env_properties = {
101
- ...suprSendInstance.env_properties,
102
- ...formatted_super_props,
103
- };
104
- }
105
-
106
- identify(unique_id) {
107
- if (!suprSendInstance._user_identified) {
108
- utils.batch_or_call({
109
- env: config.env_key,
110
- event: "$identify",
111
- $insert_id: utils.uuid(),
112
- $time: utils.epoch_milliseconds(),
113
- properties: {
114
- $identified_id: unique_id,
115
- $anon_id: suprSendInstance.distinct_id,
116
- },
117
- });
118
- utils.set_cookie(constants.distinct_id, unique_id);
119
- suprSendInstance.distinct_id = unique_id;
120
- suprSendInstance._user_identified = true;
121
- this.web_push.update_subscription();
122
- this.track(internal_events.user_login);
123
- }
124
- }
125
-
126
- track(event, props = {}) {
127
- if (event === undefined) {
128
- return;
129
- } else if (
130
- !utils.is_internal_event(event) &&
131
- utils.has_special_char(event)
132
- ) {
133
- console.log("SuprSend: key cannot start with $ or ss_");
134
- return;
135
- }
136
- const super_props = utils.get_parsed_local_store_data(
137
- constants.super_properties_key
138
- );
139
- const formatted_data = utils.format_props({ key: props });
140
- const final_data = {
141
- ...formatted_data,
142
- ...suprSendInstance.env_properties,
143
- ...super_props,
144
- $current_url: window.location.href,
145
- };
146
- utils.batch_or_call({
147
- event: String(event),
148
- distinct_id: suprSendInstance.distinct_id,
149
- env: config.env_key,
150
- properties: final_data,
151
- $insert_id: utils.uuid(),
152
- $time: utils.epoch_milliseconds(),
153
- });
154
- }
155
-
156
- purchase_made(props) {
157
- this.track(internal_events.purchase_made, props);
158
- }
159
-
160
- async reset(options = { unsubscribe_push: true }) {
161
- // unsubscribe push
162
- if (options?.unsubscribe_push) {
163
- const subscription = await this.web_push._get_subscription_without_wait();
164
- if (subscription) {
165
- this.user.remove_webpush(subscription);
166
- }
167
- }
168
- this.track(internal_events.user_logout);
169
- var distinct_id = utils.uuid();
170
- utils.set_cookie(constants.distinct_id, distinct_id);
171
- suprSendInstance = {
172
- distinct_id: distinct_id,
173
- _user_identified: false,
174
- };
175
- utils.remove_local_storage_item(constants.super_properties_key);
176
- this.user = new User(suprSendInstance, this.emitter);
177
- this.web_push = new WebPush(suprSendInstance);
178
- SuprSend._set_env_properties();
179
- }
180
- }
181
-
182
- export default new SuprSend();