web-push-notifications 3.40.3 → 3.44.2

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.
Files changed (149) hide show
  1. package/.editorconfig +11 -0
  2. package/.gitlab-ci.yml +190 -0
  3. package/babel.config.js +7 -0
  4. package/ci/cdn/Dockerfile +12 -0
  5. package/ci/dev/Dockerfile +30 -0
  6. package/ci/dev/rootfs/entrypoint.sh +18 -0
  7. package/ci/dev/rootfs/entrypoint.sh.d/nginx.sh +6 -0
  8. package/ci/dev/rootfs/entrypoint.sh.d/supervisor.sh +5 -0
  9. package/ci/dev/rootfs/etc/nginx/_real_ip.conf +2 -0
  10. package/ci/dev/rootfs/etc/nginx/conf.d/default.conf +20 -0
  11. package/ci/dev/rootfs/etc/supervisor.d/nginx.ini +11 -0
  12. package/ci/github/Dockerfile +59 -0
  13. package/ci/github/release-zip.js +61 -0
  14. package/ci/npm/Dockerfile +19 -0
  15. package/config/config.js +24 -0
  16. package/config/configBuilder.js +126 -0
  17. package/config/helpers.js +9 -0
  18. package/config/index.js +1 -0
  19. package/develop/README.md +42 -0
  20. package/develop/favicon.png +0 -0
  21. package/develop/index.html +511 -0
  22. package/eslint.config.mjs +114 -0
  23. package/package.json +4 -34
  24. package/{lib → public}/index.d.ts +10 -10
  25. package/scripts/zip.js +26 -0
  26. package/src/core/Pushwoosh.ts +768 -0
  27. package/src/core/Pushwoosh.types.ts +254 -0
  28. package/src/core/Safari.types.ts +26 -0
  29. package/src/core/constants.ts +58 -0
  30. package/src/core/events.types.ts +46 -0
  31. package/src/core/functions.ts +33 -0
  32. package/src/core/legacyEventsMap.ts +64 -0
  33. package/src/core/logger.ts +64 -0
  34. package/src/core/modules/EventBus/EventBus.ts +66 -0
  35. package/src/core/modules/EventBus/index.ts +1 -0
  36. package/src/core/storage.ts +254 -0
  37. package/src/helpers/logger.ts +81 -0
  38. package/src/helpers/pwlogger/Logger.constants.ts +31 -0
  39. package/src/helpers/pwlogger/Logger.ts +218 -0
  40. package/src/helpers/pwlogger/Logger.types.ts +66 -0
  41. package/src/helpers/pwlogger/handlers/handler-console/handler-console.ts +40 -0
  42. package/src/helpers/pwlogger/index.ts +2 -0
  43. package/src/helpers/unescape.ts +36 -0
  44. package/src/models/InboxMessages.ts +202 -0
  45. package/src/models/InboxMessages.types.ts +111 -0
  46. package/src/models/NotificationPayload.ts +216 -0
  47. package/src/models/NotificationPayload.types.ts +65 -0
  48. package/src/modules/Api/Api.ts +386 -0
  49. package/src/modules/Api/Api.types.ts +7 -0
  50. package/src/modules/ApiClient/ApiClient.ts +153 -0
  51. package/src/modules/ApiClient/ApiClient.types.ts +222 -0
  52. package/src/modules/Data/Data.ts +345 -0
  53. package/src/modules/DateModule.ts +53 -0
  54. package/src/modules/InboxMessagesPublic.ts +222 -0
  55. package/src/modules/PlatformChecker/PlatformChecker.ts +170 -0
  56. package/src/modules/PlatformChecker/PlatformChecker.types.ts +5 -0
  57. package/src/modules/PlatformChecker/index.ts +1 -0
  58. package/src/modules/storage/Storage.ts +164 -0
  59. package/src/modules/storage/Storage.types.ts +54 -0
  60. package/src/modules/storage/Store.ts +104 -0
  61. package/src/modules/storage/migrations/26-11-2018.ts +25 -0
  62. package/src/modules/storage/migrations/MigrationExecutor.ts +31 -0
  63. package/src/modules/storage/migrations/Migrations.ts +41 -0
  64. package/src/modules/storage/migrations/constants.ts +8 -0
  65. package/src/modules/storage/migrations/helpers.ts +16 -0
  66. package/src/modules/storage/migrations/initial.ts +47 -0
  67. package/src/modules/storage/version.ts +2 -0
  68. package/src/npm.ts +1 -0
  69. package/src/pushwoosh-web-notifications.ts +47 -0
  70. package/src/pushwoosh-widget-inbox.ts +8 -0
  71. package/src/pushwoosh-widget-subscribe-popup.ts +9 -0
  72. package/src/pushwoosh-widget-subscription-button.ts +8 -0
  73. package/src/pushwoosh-widget-subscription-prompt.ts +6 -0
  74. package/src/service-worker.ts +455 -0
  75. package/src/services/PushService/PushService.ts +2 -0
  76. package/src/services/PushService/PushService.types.ts +74 -0
  77. package/src/services/PushService/drivers/PushServiceDefault/PushServiceDefault.ts +235 -0
  78. package/src/services/PushService/drivers/PushServiceDefault/PushServiceDefault.types.ts +3 -0
  79. package/src/services/PushService/drivers/PushServiceSafari/PushServiceSafari.ts +125 -0
  80. package/src/services/PushService/drivers/PushServiceSafari/PushServiceSafari.types.ts +4 -0
  81. package/src/widget-inbox.ts +1 -0
  82. package/src/widget-subscribe-popup.ts +1 -0
  83. package/src/widget-subscription-button.ts +1 -0
  84. package/src/widget-subscription-prompt.ts +33 -0
  85. package/src/widgets/Inbox/InboxWidget.ts +564 -0
  86. package/src/widgets/Inbox/constants.ts +49 -0
  87. package/src/widgets/Inbox/css/inboxWidgetStyle.css +274 -0
  88. package/src/widgets/Inbox/helpers.ts +63 -0
  89. package/src/widgets/Inbox/inbox.d.ts +9 -0
  90. package/src/widgets/Inbox/inbox_widget.types.ts +41 -0
  91. package/src/widgets/Inbox/index.ts +1 -0
  92. package/src/widgets/Inbox/widgetTemplates.ts +55 -0
  93. package/src/widgets/SubscribePopup/SubscribePopup.ts +241 -0
  94. package/src/widgets/SubscribePopup/constants.ts +66 -0
  95. package/src/widgets/SubscribePopup/helpers.ts +11 -0
  96. package/src/widgets/SubscribePopup/index.ts +1 -0
  97. package/src/widgets/SubscribePopup/popupTemplates.ts +24 -0
  98. package/src/widgets/SubscribePopup/styles/popup.css +226 -0
  99. package/src/widgets/SubscribePopup/types/subscribe-popup.ts +68 -0
  100. package/src/widgets/SubscriptionButton/assets/css/main.css +205 -0
  101. package/src/widgets/SubscriptionButton/bell.ts +67 -0
  102. package/src/widgets/SubscriptionButton/constants.ts +28 -0
  103. package/src/widgets/SubscriptionButton/index.ts +377 -0
  104. package/src/widgets/SubscriptionButton/positioning.ts +165 -0
  105. package/src/widgets/SubscriptionButton/subscribe_widget.types.ts +53 -0
  106. package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.constants.ts +1 -0
  107. package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.helpers.ts +110 -0
  108. package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.ts +102 -0
  109. package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.types.ts +23 -0
  110. package/src/widgets/SubscriptionPrompt/constants.ts +22 -0
  111. package/src/widgets/SubscriptionPrompt/helpers.ts +42 -0
  112. package/src/widgets/widgets.d.ts +4 -0
  113. package/src/worker/global.ts +36 -0
  114. package/src/worker/notification.ts +34 -0
  115. package/src/worker/worker.types.ts +4 -0
  116. package/test/__helpers__/apiHelpers.ts +22 -0
  117. package/test/__helpers__/keyValueHelpers.ts +15 -0
  118. package/test/__helpers__/platformHelpers.ts +54 -0
  119. package/test/__helpers__/sinonHelpers.ts +7 -0
  120. package/test/__helpers__/storageHelpers.ts +56 -0
  121. package/test/__mocks__/apiRequests.ts +26 -0
  122. package/test/__mocks__/idbMock.ts +12 -0
  123. package/test/__mocks__/idbObjectStoreMock.ts +38 -0
  124. package/test/__mocks__/inboxMessages.ts +292 -0
  125. package/test/__mocks__/models/inboxModel.ts +71 -0
  126. package/test/__mocks__/modules/apiClientModule.ts +18 -0
  127. package/test/__mocks__/modules/dateModule.ts +34 -0
  128. package/test/__mocks__/modules/inboxParamsModule.ts +21 -0
  129. package/test/__mocks__/modules/paramsBuilder.ts +12 -0
  130. package/test/__mocks__/modules/paramsModule.ts +35 -0
  131. package/test/__mocks__/modules/payloadBuilderModule.ts +15 -0
  132. package/test/__mocks__/modules/storageModule.ts +58 -0
  133. package/test/__mocks__/navigator.ts +38 -0
  134. package/test/__mocks__/notification.ts +84 -0
  135. package/test/__mocks__/pushwoosh.ts +12 -0
  136. package/test/__mocks__/userAgents +8 -0
  137. package/test/functions.test.ts +22 -0
  138. package/test/ignore-html.js +6 -0
  139. package/test/mocha.opts +6 -0
  140. package/test/modules/DateModule/unit.test.ts +80 -0
  141. package/test/modules/storage/Storage/unit.test.ts +180 -0
  142. package/test/modules/storage/Store/unit.test.ts +192 -0
  143. package/testRegister.js +24 -0
  144. package/tsconfig.json +31 -0
  145. package/webpack.config.js +163 -0
  146. package/lib/index.js +0 -2
  147. package/lib/index.js.map +0 -1
  148. package/lib/service-worker.js +0 -2
  149. package/lib/service-worker.js.map +0 -1
@@ -0,0 +1,36 @@
1
+ /** Used to map HTML entities to characters. */
2
+ const htmlUnescapes: { [key: string]: string } = {
3
+ '&': '&',
4
+ '&lt;': '<',
5
+ '&gt;': '>',
6
+ '&quot;': '"',
7
+ '&#39;': '\'',
8
+ };
9
+
10
+ /** Used to match HTML entities and HTML characters. */
11
+ const reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g;
12
+ const reHasEscapedHtml = RegExp(reEscapedHtml.source);
13
+
14
+ /**
15
+ * The inverse of `escape`this method converts the HTML entities
16
+ * `&amp;`, `&lt;`, `&gt;`, `&quot;` and `&#39;` in `string` to
17
+ * their corresponding characters.
18
+ *
19
+ * **Note:** No other HTML entities are unescaped. To unescape additional
20
+ * HTML entities use a third-party library like [_he_](https://mths.be/he).
21
+ *
22
+ * @since 0.6.0
23
+ * @category String
24
+ * @param {string} [string=''] The string to unescape.
25
+ * @returns {string} Returns the unescaped string.
26
+ * @see escape, escapeRegExp
27
+ * @example
28
+ *
29
+ * unescape('fred, barney, &amp; pebbles')
30
+ * // => 'fred, barney, & pebbles'
31
+ */
32
+ export function unescape(string: string) {
33
+ return (string && reHasEscapedHtml.test(string))
34
+ ? string.replace(reEscapedHtml, (entity) => htmlUnescapes[entity])
35
+ : string;
36
+ }
@@ -0,0 +1,202 @@
1
+ import {
2
+ type IGetInboxMessagesResponse, type IInboxMessage, type TInboxMessagesIDBStatusIndex,
3
+ type TInboxMessageStatusDelivered, type TInboxMessageStatusOpen,
4
+ type TInboxMessageStatusRead, type TReadInboxMessagesStatusRange,
5
+ } from './InboxMessages.types';
6
+ import { type EventBus } from '../core/modules/EventBus';
7
+ import { type Api } from '../modules/Api/Api';
8
+ import { type Data } from '../modules/Data/Data';
9
+ import DateModule from '../modules/DateModule';
10
+ import InboxMessagesPublic from '../modules/InboxMessagesPublic';
11
+ import Storage from '../modules/storage/Storage';
12
+ import { type TInboxMessagesStoreName } from '../modules/storage/Storage.types';
13
+
14
+ export default class InboxMessages {
15
+ eventBus: EventBus;
16
+ data: Data;
17
+ api: Api;
18
+ storage: Storage;
19
+ storeName: TInboxMessagesStoreName;
20
+ dateModule: DateModule;
21
+
22
+ constructor(
23
+ eventBus: EventBus,
24
+ data: Data,
25
+ api: Api,
26
+ storage: Storage = new Storage(),
27
+ dateModule: DateModule = new DateModule(),
28
+ ) {
29
+ this.eventBus = eventBus;
30
+ this.data = data;
31
+ this.api = api;
32
+
33
+ this.storage = storage;
34
+ this.storeName = 'inboxMessages';
35
+ this.dateModule = dateModule;
36
+ }
37
+
38
+ /**
39
+ * Get inbox messages by api
40
+ */
41
+ private async getInboxMessages(): Promise<IGetInboxMessagesResponse> {
42
+ // get inbox messages
43
+ const response: IGetInboxMessagesResponse = await this.api.getInboxMessages();
44
+ await this.storeGetInboxMessagesRequestParams(response.next, response.new_inbox);
45
+
46
+ return response;
47
+ }
48
+
49
+ /**
50
+ * Store parameters for next getInboxMessages request
51
+ * @param next
52
+ * @param newMessagesCount
53
+ */
54
+ private async storeGetInboxMessagesRequestParams(next: string, newMessagesCount: number): Promise<void> {
55
+ this.dateModule.date = new Date();
56
+ await this.data.setInboxLastRequestTime(this.dateModule.getUtcTimestamp());
57
+
58
+ await this.data.setInboxLastRequestCode(next);
59
+ await this.data.setInboxNewMessagesCount(newMessagesCount);
60
+ }
61
+
62
+ /**
63
+ * Put loaded messages. Add delete status to loaded messages if this status set locally.
64
+ * @param messages
65
+ */
66
+ private async putServerMessages(messages: Array<IInboxMessage>): Promise<Array<string>> {
67
+ const putTransactions = messages.map(async (message: IInboxMessage) => {
68
+ const localMessage = await this.storage.get<IInboxMessage, object>(this.storeName, message.inbox_id, {});
69
+ if ('status' in localMessage) {
70
+ message.status = localMessage.status;
71
+ }
72
+ return this.putMessage(message);
73
+ });
74
+
75
+ return Promise.all(putTransactions);
76
+ }
77
+
78
+ /**
79
+ * Create or update inbox message
80
+ */
81
+ putMessage(message: IInboxMessage): Promise<string> {
82
+ return <Promise<string>> this.storage.put(this.storeName, message);
83
+ }
84
+
85
+ /**
86
+ * Create or update messages pack
87
+ * @param messages
88
+ */
89
+ putBulkMessages(messages: Array<IInboxMessage>): Promise<Array<string>> {
90
+ const putTransactions = messages.map((message) => this.putMessage(message));
91
+ return Promise.all(putTransactions);
92
+ }
93
+
94
+ /**
95
+ * Delete messages by codes
96
+ * @param codes
97
+ */
98
+ deleteMessages(codes: Array<string>): Promise<Array<void>> {
99
+ const deleteTransactions = codes.map((code) => this.storage.delete(this.storeName, code));
100
+ return Promise.all(deleteTransactions);
101
+ }
102
+
103
+ /**
104
+ * Delete expired by removal time messages
105
+ */
106
+ async deleteExpiredMessages(): Promise<Array<void>> {
107
+ this.dateModule.date = new Date();
108
+ const upperBound = this.dateModule.getTimestamp().toString();
109
+ const allMessages = await this.storage
110
+ .getAll<IInboxMessage>(this.storeName);
111
+ const codesToDelete = allMessages
112
+ .filter((msg: IInboxMessage) => msg.rt < upperBound)
113
+ .map((msg) => msg.inbox_id);
114
+ return this.deleteMessages(codesToDelete);
115
+ }
116
+
117
+ /**
118
+ * Get message by code
119
+ * @param code - inbox_id
120
+ */
121
+ getMessage(code: string): Promise<IInboxMessage> {
122
+ return this.storage.get<IInboxMessage, IInboxMessage>(this.storeName, code);
123
+ }
124
+
125
+ /**
126
+ * Get all read messages
127
+ */
128
+ async getReadOpenMessages(): Promise<Array<IInboxMessage>> {
129
+ const allMessages = await this.storage
130
+ .getAll<IInboxMessage>(this.storeName);
131
+ return allMessages
132
+ .filter((msg: IInboxMessage) => <TInboxMessageStatusRead>msg.status === 2 || <TInboxMessageStatusOpen>msg.status === 3);
133
+ }
134
+
135
+ /**
136
+ * Get all unread messages
137
+ */
138
+ async getDeliveredMessages(): Promise<Array<IInboxMessage>> {
139
+ const allMessages = await this.storage
140
+ .getAll<IInboxMessage>(this.storeName);
141
+ return allMessages
142
+ .filter((msg: IInboxMessage) => <TInboxMessageStatusDelivered>msg.status === 1);
143
+ }
144
+
145
+ /**
146
+ * All messages count
147
+ */
148
+ async messagesCount(): Promise<number> {
149
+ return this.storage.count(this.storeName);
150
+ }
151
+
152
+ /**
153
+ * Get count of messages with status "Delivered"
154
+ */
155
+ async getDeliveredMessagesCount(): Promise<number> {
156
+ const deliveredStatus: TInboxMessageStatusDelivered = 1;
157
+ const statusIndexName: TInboxMessagesIDBStatusIndex = 'status';
158
+ return this.storage
159
+ .countByIndex(this.storeName, statusIndexName, deliveredStatus);
160
+ }
161
+
162
+ /**
163
+ * Get count of messages with status "Read"
164
+ */
165
+ async getReadMessagesCount(): Promise<number> {
166
+ const readStatus: TInboxMessageStatusRead = 2;
167
+ const statusIndexName: TInboxMessagesIDBStatusIndex = 'status';
168
+ return this.storage
169
+ .countByIndex(this.storeName, statusIndexName, readStatus);
170
+ }
171
+
172
+ /**
173
+ * Get count of messages with status "Delivered" and "Read"
174
+ */
175
+ async getDeliveredReadMessagesCount(): Promise<number> {
176
+ const [readStatus, openStatus]: TReadInboxMessagesStatusRange = [2, 3];
177
+ const keyRange = IDBKeyRange.bound(readStatus, openStatus);
178
+ const statusIndexName: TInboxMessagesIDBStatusIndex = 'status';
179
+
180
+ return this.storage.countByIndex(this.storeName, statusIndexName, keyRange);
181
+ }
182
+
183
+ /**
184
+ * Load messages and sync with locally
185
+ */
186
+ async updateMessages(): Promise<void> {
187
+ const response = await this.getInboxMessages();
188
+ await this.deleteExpiredMessages();
189
+ if (response.deleted) {
190
+ await this.deleteMessages(response.deleted); // deleted from cp
191
+ }
192
+ await this.putServerMessages(response.messages);
193
+
194
+ this.eventBus.dispatchEvent('update-inbox-messages', {
195
+ messages: new InboxMessagesPublic(
196
+ this.data,
197
+ this.api,
198
+ this,
199
+ ),
200
+ });
201
+ }
202
+ }
@@ -0,0 +1,111 @@
1
+ // Action types
2
+ export type TInboxActionLink = 1;
3
+ export type TInboxActionRichMedia = 2;
4
+ export type TInboxActionType = TInboxActionLink | TInboxActionRichMedia; // https://docs.pushwoosh.com/platform-docs/api-reference/message-inbox#getinboxmessages
5
+
6
+ // Statuses
7
+ export type TInboxMessageStatusDelivered = 1;
8
+ export type TInboxMessageStatusRead = 2; // set on message in viewport
9
+ export type TInboxMessageStatusOpen = 3; // set on message click
10
+ export type TInboxMessageStatusDeleted = 4; // set on message delete or expiry removal time
11
+ export type TInboxMessageStatus =
12
+ | TInboxMessageStatusDelivered
13
+ | TInboxMessageStatusRead
14
+ | TInboxMessageStatusOpen
15
+ | TInboxMessageStatusDeleted;
16
+ export type TReadInboxMessagesStatusRange = [TInboxMessageStatusRead, TInboxMessageStatusOpen]; // all inbox read messages
17
+
18
+ // Message
19
+ export interface IInboxMessageActionParams {
20
+ l?: string | null;
21
+ rm?: string;
22
+ h?: string;
23
+ r?: string;
24
+ }
25
+
26
+ export interface IInboxMessage {
27
+ inbox_id: string; // inbox message id
28
+ order: string; // id for ordering in inbox
29
+ rt: string; // timestamp. Remove date. UTC
30
+ send_date: string; // timestamp. UTC
31
+ title: string;
32
+ image: string;
33
+ text: string;
34
+ action_type: TInboxActionType;
35
+ action_params: string; // json string with IInboxMessageActionParams
36
+ status: TInboxMessageStatus;
37
+ }
38
+
39
+ // Inbox API types
40
+ export interface IGetInboxMessagesRequest {
41
+ application: string; // application code
42
+ userId: string; // use hwid or other custom string if no userId
43
+ hwid: string;
44
+ last_code: string; // For pagination purpose. "next" parameter from response. For first request send empty string
45
+ count?: number; // optional, default messages count on page
46
+ last_request_time: number; // for update new messages counter. UTC
47
+ }
48
+
49
+ export interface IGetInboxMessagesResponse {
50
+ messages: Array<IInboxMessage>;
51
+ next: string; // pagination code
52
+ deleted: Array<string>; // array of notifications codes deleted from cp
53
+ new_inbox: number; // inbox messages created since last request time
54
+ }
55
+
56
+ export interface IInboxStatusRequest {
57
+ userId: string; // use hwid or other custom string if no userId
58
+ hwid: string; // hwid
59
+ application: string; // app code
60
+ inbox_code: string; // order. Ugly logic for fast development.
61
+ time: number; // timestamp utc
62
+ status: TInboxMessageStatus;
63
+ hash?: string; // ??
64
+ device_type: number; // platform type from Pushwoosh system
65
+ }
66
+
67
+ export type TGetInboxMessagesMethod = 'getInboxMessages';
68
+ export type TInboxStatusMethod = 'inboxStatus';
69
+
70
+ // IndexedDB keys/indexes
71
+ export type TInboxMessagesIDBKeyPath = 'inbox_id';
72
+ export type TInboxMessagesIDBStatusIndex = 'status';
73
+ export type TInboxMessagesIDBRemovalTimeIndex = 'rt';
74
+
75
+ // Public Interface
76
+
77
+ export type TInboxMessageTypePlain = 0;
78
+ export type TInboxMessageTypeRichmedia = 1;
79
+ export type TInboxMessageTypeURL = 2;
80
+ export type TInboxMessageTypeDeeplink = 3;
81
+ export type TInboxMessageType = // depend from action_params
82
+ | TInboxMessageTypePlain
83
+ | TInboxMessageTypeRichmedia
84
+ | TInboxMessageTypeURL
85
+ | TInboxMessageTypeDeeplink;
86
+
87
+ export type TInboxDefaultLink = '/';
88
+
89
+ export interface IInboxMessagePublic {
90
+ code: string; // inbox_id
91
+ title: string; // title
92
+ message: string; // body
93
+ imageUrl: string; // image
94
+ sendDate: string; // send_date
95
+ type: TInboxMessageType; // depend from action_params
96
+ link: string | TInboxDefaultLink; // url or deeplink.
97
+ isRead: boolean; // true if status read or open
98
+ isActionPerformed: boolean; // true if status open
99
+ }
100
+
101
+ export interface IInboxMessages {
102
+ messagesWithNoActionPerformedCount(): Promise<number>; // opened messages count
103
+ unreadMessagesCount(): Promise<number>; // read messages count
104
+ messagesCount(): Promise<number>; // all messages count
105
+ loadMessages(): Promise<Array<IInboxMessagePublic>>; // all messages
106
+ readMessagesWithCodes(codes: Array<string>): Promise<void>; // set read status to messages by code
107
+ performActionForMessageWithCode(code: string): Promise<void>; // call message action. Set open status to messages
108
+ deleteMessagesWithCodes(codes: Array<string>): Promise<void>; // Set delete status to messages by code
109
+
110
+ publicMessageBuilder(message: IInboxMessage): Promise<IInboxMessagePublic>; // build public inbox message from base inbox message
111
+ }
@@ -0,0 +1,216 @@
1
+ import { type IInboxMessage, type TInboxActionLink, type TInboxMessageStatusDelivered } from './InboxMessages.types';
2
+ import {
3
+ type IChromeNotificationPayload,
4
+ type INotificationButton,
5
+ type INotificationOptionsPayload,
6
+ type INotificationPayload,
7
+ type INotificationPayloadInboxParams,
8
+ type IShowNotificationOptions,
9
+ } from './NotificationPayload.types';
10
+ import { parseSerializedNotificationParams } from '../core/functions';
11
+ import { unescape } from '../helpers/unescape';
12
+ import { Data } from '../modules/Data/Data';
13
+ import DateModule from '../modules/DateModule';
14
+
15
+ /**
16
+ * Build notification payload for different usage (show notification, use in sdk, inbox messages)
17
+ */
18
+ export default class NotificationPayload {
19
+ payload: INotificationPayload;
20
+ data: Data;
21
+ code: string;
22
+ dateModule: DateModule;
23
+
24
+ constructor(
25
+ payload: INotificationPayload | IChromeNotificationPayload,
26
+ data: Data = new Data(),
27
+ dateModule: DateModule = new DateModule(),
28
+ ) {
29
+ // Set payload
30
+ if ('data' in payload) {
31
+ const chromePayload = <IChromeNotificationPayload>payload;
32
+ this.payload = chromePayload.data;
33
+ } else {
34
+ this.payload = <INotificationPayload>payload;
35
+ }
36
+
37
+ this.data = data;
38
+ this.code = `notificationCode-${Date.now()}-${Math.random().toString(16).slice(2, 10)}`;
39
+ this.dateModule = dateModule;
40
+ }
41
+
42
+ async getIcon(): Promise<string> {
43
+ return this.payload.i || await this.data.getDefaultNotificationImage();
44
+ }
45
+
46
+ async getTitle(): Promise<string> {
47
+ return this.payload.header || await this.data.getDefaultNotificationTitle();
48
+ }
49
+
50
+ get silent(): boolean {
51
+ return Boolean(this.payload.silent);
52
+ }
53
+
54
+ get body(): string {
55
+ return this.payload.body;
56
+ }
57
+
58
+ get messageHash(): string {
59
+ return this.payload.p || '';
60
+ }
61
+
62
+ get metaData(): { [key: string]: any } {
63
+ return this.payload.md
64
+ ? parseSerializedNotificationParams(this.payload.md)
65
+ : {};
66
+ }
67
+
68
+ get image(): string {
69
+ return this.payload.image || '';
70
+ }
71
+
72
+ get buttons(): Array<INotificationButton> {
73
+ return this.payload.buttons
74
+ ? parseSerializedNotificationParams(this.payload.buttons)
75
+ : [];
76
+ }
77
+
78
+ get customData(): { [key: string]: any } {
79
+ return this.payload.u
80
+ ? parseSerializedNotificationParams(this.payload.u)
81
+ : {};
82
+ }
83
+
84
+ get campaignCode(): string {
85
+ return this.payload.pwcid || '';
86
+ }
87
+
88
+ get link(): string {
89
+ return this.payload.l ? unescape(this.payload.l) : '/';
90
+ }
91
+
92
+ get inboxId(): string {
93
+ return this.payload.pw_inbox || '';
94
+ }
95
+
96
+ get inboxParams(): INotificationPayloadInboxParams {
97
+ // Parse inbox params
98
+ if (this.payload.inbox_params) {
99
+ return parseSerializedNotificationParams(this.payload.inbox_params);
100
+ }
101
+
102
+ return {};
103
+ }
104
+
105
+ get inboxRemovalTime(): string {
106
+ if (this.inboxParams && this.inboxParams.rt) {
107
+ return this.inboxParams.rt;
108
+ }
109
+
110
+ this.dateModule.date = new Date();
111
+ this.dateModule.addDays(1); // one day removal time
112
+ return this.dateModule.getUtcTimestamp().toString();
113
+ }
114
+
115
+ async getInboxImage(): Promise<string> {
116
+ if (this.inboxParams && this.inboxParams.image) {
117
+ return this.inboxParams.image;
118
+ }
119
+
120
+ return '';
121
+ }
122
+
123
+ get rootParams(): { [key: string]: any } {
124
+ const {
125
+ body: _body,
126
+ p: _p,
127
+ header: _header,
128
+ i: _i,
129
+ u: _u,
130
+ l: _l,
131
+ pwcid: _pwcid,
132
+ image: _image,
133
+ buttons: _buttons,
134
+ pw_inbox: _pw_inbox,
135
+ inbox_params: _inbox_params,
136
+ ...rootParams
137
+ } = this.payload;
138
+ return rootParams;
139
+ }
140
+
141
+ async getNotificationOptionsPayload(): Promise<INotificationOptionsPayload> {
142
+ const title = await this.getTitle();
143
+ const icon = await this.getIcon();
144
+
145
+ return {
146
+ ...this.rootParams,
147
+ body: this.body,
148
+ title,
149
+ icon,
150
+ image: this.image,
151
+ buttons: this.buttons,
152
+ customData: this.customData,
153
+ metaData: this.metaData,
154
+ campaignCode: this.campaignCode,
155
+ openUrl: this.link,
156
+ messageHash: this.messageHash,
157
+ };
158
+ }
159
+
160
+ async getShowNotificationOptions(): Promise<IShowNotificationOptions> {
161
+ const icon = await this.getIcon();
162
+
163
+ const buttons = this.buttons.map((button: INotificationButton, key: number) => {
164
+ button.action = `action-${key}`;
165
+ return button;
166
+ });
167
+
168
+ return {
169
+ renotify: true,
170
+ ...this.rootParams,
171
+ body: this.body,
172
+ icon,
173
+ tag: JSON.stringify({
174
+ url: this.link,
175
+ messageHash: this.messageHash,
176
+ customData: this.customData,
177
+ metaData: this.metaData,
178
+ }),
179
+ data: {
180
+ code: this.code,
181
+ buttons,
182
+ image: this.image,
183
+ campaignCode: this.campaignCode,
184
+ inboxId: this.inboxId,
185
+ },
186
+ silent: this.silent,
187
+ actions: buttons,
188
+ image: this.image,
189
+ buttons, // old notification api artifact
190
+ };
191
+ }
192
+
193
+ async getInboxMessage(): Promise<IInboxMessage> {
194
+ this.dateModule.date = new Date();
195
+ const sendDate = this.dateModule.getTimestamp().toString();
196
+ const title = this.payload.header || '';
197
+ const image = await this.getInboxImage();
198
+ const actionType: TInboxActionLink = 1;
199
+ const status: TInboxMessageStatusDelivered = 1;
200
+
201
+ return {
202
+ title,
203
+ image,
204
+ status,
205
+ order: this.dateModule.getInboxFakeOrder(),
206
+ inbox_id: this.inboxId,
207
+ send_date: sendDate,
208
+ rt: this.inboxRemovalTime,
209
+ text: this.body,
210
+ action_type: actionType,
211
+ action_params: JSON.stringify({
212
+ l: this.link,
213
+ }),
214
+ };
215
+ }
216
+ }
@@ -0,0 +1,65 @@
1
+ export interface INotificationPayloadInboxParams {
2
+ image?: string; // custom icon for inbox message
3
+ rt?: string; // removal time. YYYY-MM-DD HH:mm
4
+ }
5
+
6
+ export interface INotificationPayload {
7
+ body: string; // message text
8
+ p?: string; // message hash. Not required for send message on concrete device.
9
+ silent?: string; // is it silent push notifications (no need to show it to user PUSH-19207)
10
+ header?: string; // message title
11
+ i?: string; // icon
12
+ u?: string; // custom data json string
13
+ md?: string; // meta data json string
14
+ l?: string; // deep link or URL
15
+ pwcid?: string; // campaign id
16
+ image?: string; // chrome big image
17
+ buttons?: string; // button json string. XMPP Chrome Sender payload contains buttons as string
18
+ pw_inbox?: string; // inbox code
19
+ inbox_params?: string; // inbox params json INotificationPayloadInboxParams
20
+ [key: string]: any; // root params
21
+ }
22
+
23
+ export interface IChromeNotificationPayload {
24
+ data: INotificationPayload;
25
+ from: string; // ??
26
+ }
27
+
28
+ export interface INotificationButton {
29
+ title: string;
30
+ action?: string;
31
+ url?: string;
32
+ }
33
+
34
+ export interface INotificationOptionsPayload {
35
+ body: string;
36
+ title: string;
37
+ icon: string;
38
+ image: string;
39
+ buttons: Array<INotificationButton>;
40
+ customData: { [key: string]: any };
41
+ metaData: { [key: string]: any };
42
+ campaignCode: string;
43
+ openUrl: string;
44
+ [key: string]: any;
45
+ }
46
+
47
+ export interface IShowNotificationOptionsData {
48
+ code: string; // message code
49
+ buttons: Array<INotificationButton>;
50
+ image: string;
51
+ campaignCode: string;
52
+ inboxId: string;
53
+ }
54
+
55
+ export interface IShowNotificationOptions {
56
+ body: string;
57
+ icon: string;
58
+ tag: string;
59
+ data: IShowNotificationOptionsData;
60
+ actions: Array<INotificationButton>;
61
+ image: string;
62
+ badge?: string; // android chrome badge icon,
63
+ silent?: boolean; // is it silent push notifications (no need to show it to user PUSH-19207)
64
+ [key: string]: any;
65
+ }