@aws-amplify/notifications 1.0.25 → 1.0.26-unstable.1116fef.4

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 (208) hide show
  1. package/lib/InAppMessaging/InAppMessaging.d.ts +10 -8
  2. package/lib/InAppMessaging/InAppMessaging.js +9 -11
  3. package/lib/InAppMessaging/InAppMessaging.js.map +1 -1
  4. package/lib/InAppMessaging/Providers/AWSPinpointProvider/index.d.ts +5 -25
  5. package/lib/InAppMessaging/Providers/AWSPinpointProvider/index.js +37 -252
  6. package/lib/InAppMessaging/Providers/AWSPinpointProvider/index.js.map +1 -1
  7. package/lib/InAppMessaging/Providers/AWSPinpointProvider/types.d.ts +0 -9
  8. package/lib/InAppMessaging/Providers/AWSPinpointProvider/types.js.map +1 -1
  9. package/lib/InAppMessaging/Providers/AWSPinpointProvider/utils.js +3 -9
  10. package/lib/InAppMessaging/Providers/AWSPinpointProvider/utils.js.map +1 -1
  11. package/lib/InAppMessaging/index.d.ts +1 -3
  12. package/lib/InAppMessaging/index.js +0 -2
  13. package/lib/InAppMessaging/index.js.map +1 -1
  14. package/lib/InAppMessaging/types.d.ts +30 -42
  15. package/lib/InAppMessaging/types.js +2 -0
  16. package/lib/InAppMessaging/types.js.map +1 -1
  17. package/lib/Notifications.d.ts +6 -2
  18. package/lib/Notifications.js +45 -0
  19. package/lib/Notifications.js.map +1 -1
  20. package/lib/PushNotification/NotEnabledError.d.ts +3 -0
  21. package/lib/PushNotification/NotEnabledError.js +16 -0
  22. package/lib/PushNotification/NotEnabledError.js.map +1 -0
  23. package/lib/PushNotification/Platform/index.d.ts +2 -0
  24. package/lib/PushNotification/Platform/index.js +26 -0
  25. package/lib/PushNotification/Platform/index.js.map +1 -0
  26. package/lib/PushNotification/Platform/index.native.d.ts +2 -0
  27. package/lib/PushNotification/Platform/index.native.js +8 -0
  28. package/lib/PushNotification/Platform/index.native.js.map +1 -0
  29. package/lib/PushNotification/Platform/types.d.ts +5 -0
  30. package/lib/PushNotification/Platform/types.js +5 -0
  31. package/lib/PushNotification/Platform/types.js.map +1 -0
  32. package/lib/PushNotification/PlatformNotSupportedError.d.ts +3 -0
  33. package/lib/PushNotification/PlatformNotSupportedError.js +16 -0
  34. package/lib/PushNotification/PlatformNotSupportedError.js.map +1 -0
  35. package/lib/PushNotification/Providers/AWSPinpointProvider/index.d.ts +15 -0
  36. package/lib/PushNotification/Providers/AWSPinpointProvider/index.js +115 -0
  37. package/lib/PushNotification/Providers/AWSPinpointProvider/index.js.map +1 -0
  38. package/lib/PushNotification/Providers/AWSPinpointProvider/types.d.ts +9 -0
  39. package/lib/PushNotification/Providers/AWSPinpointProvider/types.js +16 -0
  40. package/lib/PushNotification/Providers/AWSPinpointProvider/types.js.map +1 -0
  41. package/lib/PushNotification/Providers/AWSPinpointProvider/utils.d.ts +7 -0
  42. package/lib/PushNotification/Providers/AWSPinpointProvider/utils.js +58 -0
  43. package/lib/PushNotification/Providers/AWSPinpointProvider/utils.js.map +1 -0
  44. package/lib/PushNotification/Providers/index.d.ts +1 -0
  45. package/lib/PushNotification/Providers/index.js +7 -0
  46. package/lib/PushNotification/Providers/index.js.map +1 -0
  47. package/lib/PushNotification/PushNotification.d.ts +39 -0
  48. package/lib/PushNotification/PushNotification.js +91 -0
  49. package/lib/PushNotification/PushNotification.js.map +1 -0
  50. package/lib/PushNotification/PushNotification.native.d.ts +63 -0
  51. package/lib/PushNotification/PushNotification.native.js +327 -0
  52. package/lib/PushNotification/PushNotification.native.js.map +1 -0
  53. package/lib/PushNotification/index.d.ts +2 -0
  54. package/lib/PushNotification/index.js +9 -0
  55. package/lib/PushNotification/index.js.map +1 -0
  56. package/lib/PushNotification/types.d.ts +77 -0
  57. package/lib/PushNotification/types.js +12 -0
  58. package/lib/PushNotification/types.js.map +1 -0
  59. package/lib/PushNotification/utils.d.ts +3 -0
  60. package/lib/PushNotification/utils.js +81 -0
  61. package/lib/PushNotification/utils.js.map +1 -0
  62. package/lib/common/AWSPinpointProviderCommon/index.d.ts +34 -0
  63. package/lib/common/AWSPinpointProviderCommon/index.js +281 -0
  64. package/lib/common/AWSPinpointProviderCommon/index.js.map +1 -0
  65. package/lib/common/AWSPinpointProviderCommon/types.d.ts +9 -0
  66. package/lib/common/AWSPinpointProviderCommon/types.js +5 -0
  67. package/lib/common/AWSPinpointProviderCommon/types.js.map +1 -0
  68. package/lib/common/constants.d.ts +1 -0
  69. package/lib/common/constants.js +6 -0
  70. package/lib/common/constants.js.map +1 -0
  71. package/lib/common/eventListeners/index.d.ts +4 -0
  72. package/lib/common/eventListeners/index.js +55 -0
  73. package/lib/common/eventListeners/index.js.map +1 -0
  74. package/lib/common/eventListeners/types.d.ts +7 -0
  75. package/lib/common/eventListeners/types.js +5 -0
  76. package/lib/common/eventListeners/types.js.map +1 -0
  77. package/lib/common/index.d.ts +4 -0
  78. package/lib/common/index.js +13 -0
  79. package/lib/common/index.js.map +1 -0
  80. package/lib/index.d.ts +5 -2
  81. package/lib/index.js +4 -0
  82. package/lib/index.js.map +1 -1
  83. package/lib/types.d.ts +34 -2
  84. package/lib/types.js +2 -0
  85. package/lib/types.js.map +1 -1
  86. package/lib-esm/InAppMessaging/InAppMessaging.d.ts +10 -8
  87. package/lib-esm/InAppMessaging/InAppMessaging.js +9 -11
  88. package/lib-esm/InAppMessaging/InAppMessaging.js.map +1 -1
  89. package/lib-esm/InAppMessaging/Providers/AWSPinpointProvider/index.d.ts +5 -25
  90. package/lib-esm/InAppMessaging/Providers/AWSPinpointProvider/index.js +39 -254
  91. package/lib-esm/InAppMessaging/Providers/AWSPinpointProvider/index.js.map +1 -1
  92. package/lib-esm/InAppMessaging/Providers/AWSPinpointProvider/types.d.ts +0 -9
  93. package/lib-esm/InAppMessaging/Providers/AWSPinpointProvider/types.js.map +1 -1
  94. package/lib-esm/InAppMessaging/Providers/AWSPinpointProvider/utils.js +2 -8
  95. package/lib-esm/InAppMessaging/Providers/AWSPinpointProvider/utils.js.map +1 -1
  96. package/lib-esm/InAppMessaging/index.d.ts +1 -3
  97. package/lib-esm/InAppMessaging/index.js +0 -1
  98. package/lib-esm/InAppMessaging/index.js.map +1 -1
  99. package/lib-esm/InAppMessaging/types.d.ts +30 -42
  100. package/lib-esm/InAppMessaging/types.js +2 -0
  101. package/lib-esm/InAppMessaging/types.js.map +1 -1
  102. package/lib-esm/Notifications.d.ts +6 -2
  103. package/lib-esm/Notifications.js +48 -3
  104. package/lib-esm/Notifications.js.map +1 -1
  105. package/lib-esm/PushNotification/NotEnabledError.d.ts +3 -0
  106. package/lib-esm/PushNotification/NotEnabledError.js +14 -0
  107. package/lib-esm/PushNotification/NotEnabledError.js.map +1 -0
  108. package/lib-esm/PushNotification/Platform/index.d.ts +2 -0
  109. package/lib-esm/PushNotification/Platform/index.js +24 -0
  110. package/lib-esm/PushNotification/Platform/index.js.map +1 -0
  111. package/lib-esm/PushNotification/Platform/index.native.d.ts +2 -0
  112. package/lib-esm/PushNotification/Platform/index.native.js +6 -0
  113. package/lib-esm/PushNotification/Platform/index.native.js.map +1 -0
  114. package/lib-esm/PushNotification/Platform/types.d.ts +5 -0
  115. package/lib-esm/PushNotification/Platform/types.js +3 -0
  116. package/lib-esm/PushNotification/Platform/types.js.map +1 -0
  117. package/lib-esm/PushNotification/PlatformNotSupportedError.d.ts +3 -0
  118. package/lib-esm/PushNotification/PlatformNotSupportedError.js +14 -0
  119. package/lib-esm/PushNotification/PlatformNotSupportedError.js.map +1 -0
  120. package/lib-esm/PushNotification/Providers/AWSPinpointProvider/index.d.ts +15 -0
  121. package/lib-esm/PushNotification/Providers/AWSPinpointProvider/index.js +113 -0
  122. package/lib-esm/PushNotification/Providers/AWSPinpointProvider/index.js.map +1 -0
  123. package/lib-esm/PushNotification/Providers/AWSPinpointProvider/types.d.ts +9 -0
  124. package/lib-esm/PushNotification/Providers/AWSPinpointProvider/types.js +14 -0
  125. package/lib-esm/PushNotification/Providers/AWSPinpointProvider/types.js.map +1 -0
  126. package/lib-esm/PushNotification/Providers/AWSPinpointProvider/utils.d.ts +7 -0
  127. package/lib-esm/PushNotification/Providers/AWSPinpointProvider/utils.js +56 -0
  128. package/lib-esm/PushNotification/Providers/AWSPinpointProvider/utils.js.map +1 -0
  129. package/lib-esm/PushNotification/Providers/index.d.ts +1 -0
  130. package/lib-esm/PushNotification/Providers/index.js +4 -0
  131. package/lib-esm/PushNotification/Providers/index.js.map +1 -0
  132. package/lib-esm/PushNotification/PushNotification.d.ts +39 -0
  133. package/lib-esm/PushNotification/PushNotification.js +89 -0
  134. package/lib-esm/PushNotification/PushNotification.js.map +1 -0
  135. package/lib-esm/PushNotification/PushNotification.native.d.ts +63 -0
  136. package/lib-esm/PushNotification/PushNotification.native.js +325 -0
  137. package/lib-esm/PushNotification/PushNotification.native.js.map +1 -0
  138. package/lib-esm/PushNotification/index.d.ts +2 -0
  139. package/lib-esm/PushNotification/index.js +5 -0
  140. package/lib-esm/PushNotification/index.js.map +1 -0
  141. package/lib-esm/PushNotification/types.d.ts +77 -0
  142. package/lib-esm/PushNotification/types.js +10 -0
  143. package/lib-esm/PushNotification/types.js.map +1 -0
  144. package/lib-esm/PushNotification/utils.d.ts +3 -0
  145. package/lib-esm/PushNotification/utils.js +79 -0
  146. package/lib-esm/PushNotification/utils.js.map +1 -0
  147. package/lib-esm/common/AWSPinpointProviderCommon/index.d.ts +34 -0
  148. package/lib-esm/common/AWSPinpointProviderCommon/index.js +279 -0
  149. package/lib-esm/common/AWSPinpointProviderCommon/index.js.map +1 -0
  150. package/lib-esm/common/AWSPinpointProviderCommon/types.d.ts +9 -0
  151. package/lib-esm/common/AWSPinpointProviderCommon/types.js +3 -0
  152. package/lib-esm/common/AWSPinpointProviderCommon/types.js.map +1 -0
  153. package/lib-esm/common/constants.d.ts +1 -0
  154. package/lib-esm/common/constants.js +4 -0
  155. package/lib-esm/common/constants.js.map +1 -0
  156. package/lib-esm/common/eventListeners/index.d.ts +4 -0
  157. package/lib-esm/common/eventListeners/index.js +53 -0
  158. package/lib-esm/common/eventListeners/index.js.map +1 -0
  159. package/lib-esm/common/eventListeners/types.d.ts +7 -0
  160. package/lib-esm/common/eventListeners/types.js +3 -0
  161. package/lib-esm/common/eventListeners/types.js.map +1 -0
  162. package/lib-esm/common/index.d.ts +4 -0
  163. package/lib-esm/common/index.js +6 -0
  164. package/lib-esm/common/index.js.map +1 -0
  165. package/lib-esm/index.d.ts +5 -2
  166. package/lib-esm/index.js +2 -0
  167. package/lib-esm/index.js.map +1 -1
  168. package/lib-esm/types.d.ts +34 -2
  169. package/lib-esm/types.js +2 -0
  170. package/lib-esm/types.js.map +1 -1
  171. package/package.json +11 -50
  172. package/src/InAppMessaging/InAppMessaging.ts +27 -36
  173. package/src/InAppMessaging/Providers/AWSPinpointProvider/index.ts +45 -245
  174. package/src/InAppMessaging/Providers/AWSPinpointProvider/types.ts +0 -12
  175. package/src/InAppMessaging/Providers/AWSPinpointProvider/utils.ts +3 -12
  176. package/src/InAppMessaging/index.ts +0 -3
  177. package/src/InAppMessaging/types.ts +52 -56
  178. package/src/Notifications.ts +42 -4
  179. package/src/PushNotification/NotEnabledError.ts +11 -0
  180. package/src/PushNotification/Platform/index.native.ts +9 -0
  181. package/src/PushNotification/Platform/index.ts +22 -0
  182. package/src/PushNotification/Platform/types.ts +15 -0
  183. package/src/PushNotification/PlatformNotSupportedError.ts +9 -0
  184. package/src/PushNotification/Providers/AWSPinpointProvider/index.ts +137 -0
  185. package/src/PushNotification/Providers/AWSPinpointProvider/types.ts +13 -0
  186. package/src/PushNotification/Providers/AWSPinpointProvider/utils.ts +79 -0
  187. package/src/PushNotification/Providers/index.ts +4 -0
  188. package/src/PushNotification/PushNotification.native.ts +381 -0
  189. package/src/PushNotification/PushNotification.ts +107 -0
  190. package/src/PushNotification/index.ts +9 -0
  191. package/src/PushNotification/types.ts +114 -0
  192. package/src/PushNotification/utils.ts +112 -0
  193. package/src/common/AWSPinpointProviderCommon/index.ts +295 -0
  194. package/src/common/AWSPinpointProviderCommon/types.ts +14 -0
  195. package/src/common/constants.ts +5 -0
  196. package/src/common/eventListeners/index.ts +44 -0
  197. package/src/common/eventListeners/types.ts +12 -0
  198. package/src/common/index.ts +11 -0
  199. package/src/index.ts +9 -3
  200. package/src/types.ts +47 -2
  201. package/CHANGELOG.md +0 -215
  202. package/lib/InAppMessaging/eventListeners.d.ts +0 -3
  203. package/lib/InAppMessaging/eventListeners.js +0 -28
  204. package/lib/InAppMessaging/eventListeners.js.map +0 -1
  205. package/lib-esm/InAppMessaging/eventListeners.d.ts +0 -3
  206. package/lib-esm/InAppMessaging/eventListeners.js +0 -26
  207. package/lib-esm/InAppMessaging/eventListeners.js.map +0 -1
  208. package/src/InAppMessaging/eventListeners.ts +0 -42
@@ -0,0 +1,381 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { AppRegistry, NativeEventEmitter } from 'react-native';
5
+ import { ConsoleLogger as Logger } from '@aws-amplify/core';
6
+ import {
7
+ AmplifyRTNPushNotification,
8
+ PushNotificationNativeModule,
9
+ } from '@aws-amplify/rtn-push-notification';
10
+
11
+ import {
12
+ addEventListener,
13
+ EventListener,
14
+ notifyEventListeners,
15
+ notifyEventListenersAndAwaitHandlers,
16
+ } from '../common';
17
+ import { UserInfo } from '../types';
18
+ import NotEnabledError from './NotEnabledError';
19
+ import { AWSPinpointProvider } from './Providers';
20
+ import {
21
+ NotificationsSubCategory,
22
+ OnPushNotificationMessageHandler,
23
+ OnTokenReceivedHandler,
24
+ PushNotificationConfig,
25
+ PushNotificationEvent,
26
+ PushNotificationInterface,
27
+ PushNotificationMessage,
28
+ PushNotificationPermissions,
29
+ PushNotificationPermissionStatus,
30
+ PushNotificationProvider,
31
+ } from './types';
32
+ import {
33
+ normalizeNativePermissionStatus,
34
+ normalizeNativeMessage,
35
+ } from './utils';
36
+
37
+ const logger = new Logger('Notifications.PushNotification');
38
+ const RTN_MODULE = '@aws-amplify/rtn-push-notification';
39
+ const BACKGROUND_TASK_TIMEOUT = 25; // seconds
40
+
41
+ export default class PushNotification implements PushNotificationInterface {
42
+ private isEnabled = false;
43
+ private config: Record<string, any> = {};
44
+ private nativeEvent: Record<string, string>;
45
+ private nativeEventEmitter: NativeEventEmitter;
46
+ private nativeHeadlessTaskKey: string;
47
+ private nativeModule: PushNotificationNativeModule;
48
+ private pluggables: PushNotificationProvider[] = [];
49
+ private token: string;
50
+
51
+ constructor() {
52
+ try {
53
+ this.nativeModule = AmplifyRTNPushNotification;
54
+ const { NativeEvent, NativeHeadlessTaskKey } =
55
+ this.nativeModule.getConstants();
56
+ this.nativeEvent = NativeEvent;
57
+ this.nativeHeadlessTaskKey = NativeHeadlessTaskKey;
58
+ this.nativeEventEmitter = new NativeEventEmitter(
59
+ AmplifyRTNPushNotification
60
+ );
61
+ } catch (err) {
62
+ err.message = `Unable to find ${RTN_MODULE}. ${err.message}`;
63
+ throw err;
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Configure PushNotification
69
+ * @param {Object} config - PushNotification configuration object
70
+ */
71
+ configure = (config: PushNotificationConfig = {}): PushNotificationConfig => {
72
+ this.config = { ...this.config, ...config };
73
+
74
+ logger.debug('configure PushNotification', this.config);
75
+
76
+ this.pluggables.forEach(pluggable => {
77
+ pluggable.configure(this.config[pluggable.getProviderName()]);
78
+ });
79
+
80
+ if (this.pluggables.length === 0) {
81
+ this.addPluggable(new AWSPinpointProvider());
82
+ }
83
+
84
+ return this.config;
85
+ };
86
+
87
+ /**
88
+ * Get the name of this module
89
+ * @returns {string} name of this module
90
+ */
91
+ getModuleName(): NotificationsSubCategory {
92
+ return 'PushNotification';
93
+ }
94
+
95
+ /**
96
+ * Get a plugin from added plugins
97
+ * @param {string} providerName - the name of the plugin to get
98
+ */
99
+ getPluggable = (providerName: string): PushNotificationProvider => {
100
+ const pluggable =
101
+ this.pluggables.find(
102
+ pluggable => pluggable.getProviderName() === providerName
103
+ ) ?? null;
104
+
105
+ if (!pluggable) {
106
+ logger.debug(`No plugin found with name ${providerName}`);
107
+ }
108
+
109
+ return pluggable;
110
+ };
111
+
112
+ /**
113
+ * Add plugin into PushNotification
114
+ * @param {PushNotificationProvider} pluggable - an instance of the plugin
115
+ */
116
+ addPluggable = (pluggable: PushNotificationProvider): void => {
117
+ if (
118
+ pluggable &&
119
+ pluggable.getCategory() === 'Notifications' &&
120
+ pluggable.getSubCategory() === 'PushNotification'
121
+ ) {
122
+ if (this.getPluggable(pluggable.getProviderName())) {
123
+ throw new Error(
124
+ `Pluggable ${pluggable.getProviderName()} has already been added.`
125
+ );
126
+ }
127
+ this.pluggables.push(pluggable);
128
+ pluggable.configure(this.config[pluggable.getProviderName()]);
129
+ }
130
+ };
131
+
132
+ /**
133
+ * Remove a plugin from added plugins
134
+ * @param {string} providerName - the name of the plugin to remove
135
+ */
136
+ removePluggable = (providerName: string): void => {
137
+ const index = this.pluggables.findIndex(
138
+ pluggable => pluggable.getProviderName() === providerName
139
+ );
140
+ if (index === -1) {
141
+ logger.debug(`No plugin found with name ${providerName}`);
142
+ } else {
143
+ this.pluggables.splice(index, 1);
144
+ }
145
+ };
146
+
147
+ enable = (): void => {
148
+ if (this.isEnabled) {
149
+ logger.info('Notification listeners have already been enabled');
150
+ return;
151
+ }
152
+ const {
153
+ BACKGROUND_MESSAGE_RECEIVED,
154
+ FOREGROUND_MESSAGE_RECEIVED,
155
+ LAUNCH_NOTIFICATION_OPENED,
156
+ NOTIFICATION_OPENED,
157
+ TOKEN_RECEIVED,
158
+ } = this.nativeEvent;
159
+ if (this.nativeHeadlessTaskKey) {
160
+ // on platforms that can handle headless tasks, register one to broadcast background message received to
161
+ // library listeners
162
+ AppRegistry.registerHeadlessTask(
163
+ this.nativeHeadlessTaskKey,
164
+ () => async message => {
165
+ // keep headless task running until handlers have completed their work
166
+ await notifyEventListenersAndAwaitHandlers(
167
+ PushNotificationEvent.BACKGROUND_MESSAGE_RECEIVED,
168
+ normalizeNativeMessage(message)
169
+ );
170
+ }
171
+ );
172
+ } else if (BACKGROUND_MESSAGE_RECEIVED) {
173
+ // on platforms that can't handle headless tasks, listen for native background message received event and
174
+ // broadcast to library listeners
175
+ this.nativeEventEmitter.addListener(
176
+ BACKGROUND_MESSAGE_RECEIVED,
177
+ async message => {
178
+ // keep background task running until handlers have completed their work
179
+ try {
180
+ await Promise.race([
181
+ notifyEventListenersAndAwaitHandlers(
182
+ PushNotificationEvent.BACKGROUND_MESSAGE_RECEIVED,
183
+ normalizeNativeMessage(message)
184
+ ),
185
+ // background tasks will get suspended and all future tasks be deprioritized by the OS if they run for
186
+ // more than 30 seconds so we reject with a error in a shorter amount of time to prevent this from
187
+ // happening
188
+ new Promise((_, reject) => {
189
+ setTimeout(
190
+ () =>
191
+ reject(
192
+ `onNotificationReceivedInBackground handlers should complete their work within ${BACKGROUND_TASK_TIMEOUT} seconds, but they did not.`
193
+ ),
194
+ BACKGROUND_TASK_TIMEOUT * 1000
195
+ );
196
+ }),
197
+ ]);
198
+ } catch (err) {
199
+ logger.error(err);
200
+ } finally {
201
+ // notify native module that handlers have completed their work (or timed out)
202
+ this.nativeModule.completeNotification?.(
203
+ message.completionHandlerId
204
+ );
205
+ }
206
+ }
207
+ );
208
+ }
209
+
210
+ this.nativeEventEmitter.addListener(
211
+ // listen for native foreground message received event and broadcast to library listeners
212
+ FOREGROUND_MESSAGE_RECEIVED,
213
+ message => {
214
+ notifyEventListeners(
215
+ PushNotificationEvent.FOREGROUND_MESSAGE_RECEIVED,
216
+ normalizeNativeMessage(message)
217
+ );
218
+ }
219
+ );
220
+
221
+ const launchNotificationOpenedListener = LAUNCH_NOTIFICATION_OPENED
222
+ ? this.nativeEventEmitter.addListener(
223
+ // listen for native notification opened app (user tapped on notification, opening the app from quit -
224
+ // not background - state) event. This is broadcasted to an internal listener only as it is not intended
225
+ // for use otherwise as it produces inconsistent results when used within React Native app context
226
+ LAUNCH_NOTIFICATION_OPENED,
227
+ message => {
228
+ notifyEventListeners(
229
+ PushNotificationEvent.LAUNCH_NOTIFICATION_OPENED,
230
+ normalizeNativeMessage(message)
231
+ );
232
+ // once we are done with it we can remove the listener
233
+ launchNotificationOpenedListener?.remove();
234
+ }
235
+ )
236
+ : null;
237
+
238
+ this.nativeEventEmitter.addListener(
239
+ // listen for native notification opened (user tapped on notification, opening the app from background -
240
+ // not quit - state) event and broadcast to library listeners
241
+ NOTIFICATION_OPENED,
242
+ message => {
243
+ notifyEventListeners(
244
+ PushNotificationEvent.NOTIFICATION_OPENED,
245
+ normalizeNativeMessage(message)
246
+ );
247
+ // if we are in this state, we no longer need the listener as the app was launched via some other means
248
+ launchNotificationOpenedListener?.remove();
249
+ }
250
+ );
251
+
252
+ this.nativeEventEmitter.addListener(
253
+ // listen for native new token event, automatically re-register device with provider using new token and
254
+ // broadcast to library listeners
255
+ TOKEN_RECEIVED,
256
+ ({ token }) => {
257
+ // avoid a race condition where two endpoints are created with the same token on a fresh install
258
+ if (this.token === token) {
259
+ return;
260
+ }
261
+ this.token = token;
262
+ this.registerDevice();
263
+ notifyEventListeners(PushNotificationEvent.TOKEN_RECEIVED, token);
264
+ }
265
+ );
266
+ this.isEnabled = true;
267
+ };
268
+
269
+ identifyUser = (userId: string, userInfo: UserInfo): Promise<void[]> => {
270
+ this.assertIsEnabled();
271
+ return Promise.all<void>(
272
+ this.pluggables.map(async pluggable => {
273
+ try {
274
+ await pluggable.identifyUser(userId, userInfo);
275
+ } catch (err) {
276
+ logger.error('Failed to identify user', err);
277
+ throw err;
278
+ }
279
+ })
280
+ );
281
+ };
282
+
283
+ getLaunchNotification = async (): Promise<PushNotificationMessage | null> => {
284
+ this.assertIsEnabled();
285
+ return normalizeNativeMessage(
286
+ await this.nativeModule.getLaunchNotification?.()
287
+ );
288
+ };
289
+
290
+ getBadgeCount = async (): Promise<number | null> => {
291
+ this.assertIsEnabled();
292
+ return this.nativeModule.getBadgeCount?.();
293
+ };
294
+
295
+ setBadgeCount = (count: number): void => {
296
+ this.assertIsEnabled();
297
+ return this.nativeModule.setBadgeCount?.(count);
298
+ };
299
+
300
+ getPermissionStatus = async (): Promise<PushNotificationPermissionStatus> => {
301
+ this.assertIsEnabled();
302
+ return normalizeNativePermissionStatus(
303
+ await this.nativeModule.getPermissionStatus?.()
304
+ );
305
+ };
306
+
307
+ requestPermissions = async (
308
+ permissions: PushNotificationPermissions = {
309
+ alert: true,
310
+ badge: true,
311
+ sound: true,
312
+ }
313
+ ): Promise<boolean> => {
314
+ this.assertIsEnabled();
315
+ return this.nativeModule.requestPermissions?.(permissions);
316
+ };
317
+
318
+ /**
319
+ * Background notifications on will start the app (as a headless JS instance running on a background service on
320
+ * Android) in the background. Handlers registered via `onNotificationReceivedInBackground` should return Promises if
321
+ * it needs to be asynchronous (e.g. to perform some network requests). The app should run in the background as long
322
+ * as there are handlers still running (however, if they run for more than 30 seconds on iOS, subsequent tasks could
323
+ * get deprioritized!). If it is necessary for a handler to execute while the app is in quit state, it should be
324
+ * registered in the application entry point (e.g. index.js) since the application will not fully mount in that case.
325
+ *
326
+ * @param handler a function to be run when a BACKGROUND_MESSAGE_RECEIVED event is received
327
+ * @returns an event listener which should be removed when no longer needed
328
+ */
329
+ onNotificationReceivedInBackground = (
330
+ handler: OnPushNotificationMessageHandler
331
+ ): EventListener<OnPushNotificationMessageHandler> => {
332
+ this.assertIsEnabled();
333
+ return addEventListener(
334
+ PushNotificationEvent.BACKGROUND_MESSAGE_RECEIVED,
335
+ handler
336
+ );
337
+ };
338
+
339
+ onNotificationReceivedInForeground = (
340
+ handler: OnPushNotificationMessageHandler
341
+ ): EventListener<OnPushNotificationMessageHandler> => {
342
+ this.assertIsEnabled();
343
+ return addEventListener(
344
+ PushNotificationEvent.FOREGROUND_MESSAGE_RECEIVED,
345
+ handler
346
+ );
347
+ };
348
+
349
+ onNotificationOpened = (
350
+ handler: OnPushNotificationMessageHandler
351
+ ): EventListener<OnPushNotificationMessageHandler> => {
352
+ this.assertIsEnabled();
353
+ return addEventListener(PushNotificationEvent.NOTIFICATION_OPENED, handler);
354
+ };
355
+
356
+ onTokenReceived = (
357
+ handler: OnTokenReceivedHandler
358
+ ): EventListener<OnTokenReceivedHandler> => {
359
+ this.assertIsEnabled();
360
+ return addEventListener(PushNotificationEvent.TOKEN_RECEIVED, handler);
361
+ };
362
+
363
+ private registerDevice = async (): Promise<void[]> => {
364
+ return Promise.all<void>(
365
+ this.pluggables.map(async pluggable => {
366
+ try {
367
+ await pluggable.registerDevice(this.token);
368
+ } catch (err) {
369
+ logger.error('Failed to register device for push notifications', err);
370
+ throw err;
371
+ }
372
+ })
373
+ );
374
+ };
375
+
376
+ private assertIsEnabled = (): void => {
377
+ if (!this.isEnabled) {
378
+ throw new NotEnabledError();
379
+ }
380
+ };
381
+ }
@@ -0,0 +1,107 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import PlatformNotSupportedError from './PlatformNotSupportedError';
5
+ import {
6
+ NotificationsSubCategory,
7
+ OnPushNotificationMessageHandler,
8
+ OnTokenReceivedHandler,
9
+ PushNotificationConfig,
10
+ PushNotificationInterface,
11
+ PushNotificationMessage,
12
+ PushNotificationPermissions,
13
+ PushNotificationPermissionStatus,
14
+ PushNotificationProvider,
15
+ } from './types';
16
+
17
+ export default class PushNotification implements PushNotificationInterface {
18
+ /**
19
+ * Configure PushNotification
20
+ * @param {Object} config - PushNotification configuration object
21
+ */
22
+ configure = (_: PushNotificationConfig = {}): PushNotificationConfig => {
23
+ throw new PlatformNotSupportedError();
24
+ };
25
+
26
+ /**
27
+ * Get the name of this module
28
+ * @returns {string} name of this module
29
+ */
30
+ getModuleName(): NotificationsSubCategory {
31
+ throw new PlatformNotSupportedError();
32
+ }
33
+
34
+ /**
35
+ * Get a plugin from added plugins
36
+ * @param {string} providerName - the name of the plugin to get
37
+ */
38
+ getPluggable = (_: string) => {
39
+ throw new PlatformNotSupportedError();
40
+ };
41
+
42
+ /**
43
+ * Add plugin into PushNotification
44
+ * @param {PushNotificationProvider} pluggable - an instance of the plugin
45
+ */
46
+ addPluggable = (_: PushNotificationProvider): void => {
47
+ throw new PlatformNotSupportedError();
48
+ };
49
+
50
+ /**
51
+ * Remove a plugin from added plugins
52
+ * @param {string} providerName - the name of the plugin to remove
53
+ */
54
+ removePluggable = (): void => {
55
+ throw new PlatformNotSupportedError();
56
+ };
57
+
58
+ enable = (): void => {
59
+ throw new PlatformNotSupportedError();
60
+ };
61
+
62
+ identifyUser = (): Promise<void[]> => {
63
+ throw new PlatformNotSupportedError();
64
+ };
65
+
66
+ getLaunchNotification = async (): Promise<PushNotificationMessage> => {
67
+ throw new PlatformNotSupportedError();
68
+ };
69
+
70
+ getBadgeCount = async (): Promise<number | null> => {
71
+ throw new PlatformNotSupportedError();
72
+ };
73
+
74
+ setBadgeCount = (_: number): void => {
75
+ throw new PlatformNotSupportedError();
76
+ };
77
+
78
+ getPermissionStatus = async (): Promise<PushNotificationPermissionStatus> => {
79
+ throw new PlatformNotSupportedError();
80
+ };
81
+
82
+ requestPermissions = async (
83
+ _?: PushNotificationPermissions
84
+ ): Promise<boolean> => {
85
+ throw new PlatformNotSupportedError();
86
+ };
87
+
88
+ onNotificationReceivedInBackground = (
89
+ _: OnPushNotificationMessageHandler
90
+ ): any => {
91
+ throw new PlatformNotSupportedError();
92
+ };
93
+
94
+ onNotificationReceivedInForeground = (
95
+ _: OnPushNotificationMessageHandler
96
+ ): any => {
97
+ throw new PlatformNotSupportedError();
98
+ };
99
+
100
+ onTokenReceived = (_: OnTokenReceivedHandler): any => {
101
+ throw new PlatformNotSupportedError();
102
+ };
103
+
104
+ onNotificationOpened = (_: OnPushNotificationMessageHandler): any => {
105
+ throw new PlatformNotSupportedError();
106
+ };
107
+ }
@@ -0,0 +1,9 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export { default } from './PushNotification';
5
+ export {
6
+ PushNotificationEvent,
7
+ PushNotificationMessage,
8
+ PushNotificationPermissionStatus,
9
+ } from './types';
@@ -0,0 +1,114 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { EventListener } from '../common';
5
+ import { AWSPinpointProviderConfig } from '../common/AWSPinpointProviderCommon/types';
6
+ import {
7
+ NotificationsProvider,
8
+ NotificationsSubCategory as NotificationsSubCategories,
9
+ UserInfo,
10
+ } from '../types';
11
+
12
+ export type NotificationsSubCategory = Extract<
13
+ NotificationsSubCategories,
14
+ 'PushNotification'
15
+ >;
16
+
17
+ export interface PushNotificationInterface {
18
+ configure: (config: PushNotificationConfig) => PushNotificationConfig;
19
+ getModuleName: () => NotificationsSubCategory;
20
+ getPluggable: (providerName: string) => PushNotificationProvider;
21
+ addPluggable: (pluggable: PushNotificationProvider) => void;
22
+ removePluggable: (providerName: string) => void;
23
+ enable: () => void;
24
+ identifyUser: (userId: string, userInfo: UserInfo) => Promise<void[]>;
25
+ getLaunchNotification: () => Promise<PushNotificationMessage>;
26
+ getBadgeCount: () => Promise<number>;
27
+ setBadgeCount: (count: number) => void;
28
+ getPermissionStatus: () => Promise<PushNotificationPermissionStatus>;
29
+ requestPermissions: (
30
+ permissions?: PushNotificationPermissions
31
+ ) => Promise<boolean>;
32
+ onNotificationReceivedInBackground: (
33
+ handler: OnPushNotificationMessageHandler
34
+ ) => EventListener<OnPushNotificationMessageHandler>;
35
+ onNotificationReceivedInForeground: (
36
+ handler: OnPushNotificationMessageHandler
37
+ ) => EventListener<OnPushNotificationMessageHandler>;
38
+ onNotificationOpened: (
39
+ handler: OnPushNotificationMessageHandler
40
+ ) => EventListener<OnPushNotificationMessageHandler>;
41
+ onTokenReceived: (
42
+ handler: OnTokenReceivedHandler
43
+ ) => EventListener<OnTokenReceivedHandler>;
44
+ }
45
+
46
+ export interface PushNotificationProvider extends NotificationsProvider {
47
+ // return sub-category ('PushNotification')
48
+ getSubCategory(): NotificationsSubCategory;
49
+
50
+ // register device with provider
51
+ registerDevice(token: string): Promise<void>;
52
+ }
53
+
54
+ export interface PushNotificationConfig {
55
+ AWSPinpoint?: AWSPinpointProviderConfig;
56
+ }
57
+
58
+ export interface PushNotificationMessage {
59
+ title?: string;
60
+ body?: string;
61
+ imageUrl?: string;
62
+ deeplinkUrl?: string;
63
+ goToUrl?: string;
64
+ fcmOptions?: FcmPlatformOptions;
65
+ apnsOptions?: ApnsPlatformOptions;
66
+ data?: Record<string, unknown>;
67
+ }
68
+
69
+ interface FcmPlatformOptions {
70
+ channelId: string;
71
+ messageId: string;
72
+ senderId: string;
73
+ sendTime: Date;
74
+ }
75
+
76
+ interface ApnsPlatformOptions {
77
+ subtitle?: string;
78
+ }
79
+
80
+ export interface PushNotificationPermissions extends Record<string, boolean> {
81
+ alert?: boolean;
82
+ badge?: boolean;
83
+ sound?: boolean;
84
+ }
85
+
86
+ export enum PushNotificationPermissionStatus {
87
+ DENIED = 'DENIED',
88
+ GRANTED = 'GRANTED',
89
+ SHOULD_REQUEST = 'SHOULD_REQUEST',
90
+ SHOULD_EXPLAIN_THEN_REQUEST = 'SHOULD_EXPLAIN_THEN_REQUEST',
91
+ }
92
+
93
+ export type OnTokenReceivedHandler = (token: string) => any;
94
+
95
+ export type OnPushNotificationMessageHandler = (
96
+ message: PushNotificationMessage
97
+ ) => any;
98
+
99
+ export const enum PushNotificationEvent {
100
+ BACKGROUND_MESSAGE_RECEIVED,
101
+ FOREGROUND_MESSAGE_RECEIVED,
102
+ LAUNCH_NOTIFICATION_OPENED,
103
+ NOTIFICATION_OPENED,
104
+ TOKEN_RECEIVED,
105
+ }
106
+
107
+ export interface NormalizedValues {
108
+ body?: string;
109
+ imageUrl?: string;
110
+ title?: string;
111
+ action?: Pick<PushNotificationMessage, 'goToUrl' | 'deeplinkUrl'>;
112
+ options?: Pick<PushNotificationMessage, 'apnsOptions' | 'fcmOptions'>;
113
+ data?: Record<string, unknown>;
114
+ }