@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.
- package/lib/InAppMessaging/InAppMessaging.d.ts +10 -8
- package/lib/InAppMessaging/InAppMessaging.js +9 -11
- package/lib/InAppMessaging/InAppMessaging.js.map +1 -1
- package/lib/InAppMessaging/Providers/AWSPinpointProvider/index.d.ts +5 -25
- package/lib/InAppMessaging/Providers/AWSPinpointProvider/index.js +37 -252
- package/lib/InAppMessaging/Providers/AWSPinpointProvider/index.js.map +1 -1
- package/lib/InAppMessaging/Providers/AWSPinpointProvider/types.d.ts +0 -9
- package/lib/InAppMessaging/Providers/AWSPinpointProvider/types.js.map +1 -1
- package/lib/InAppMessaging/Providers/AWSPinpointProvider/utils.js +3 -9
- package/lib/InAppMessaging/Providers/AWSPinpointProvider/utils.js.map +1 -1
- package/lib/InAppMessaging/index.d.ts +1 -3
- package/lib/InAppMessaging/index.js +0 -2
- package/lib/InAppMessaging/index.js.map +1 -1
- package/lib/InAppMessaging/types.d.ts +30 -42
- package/lib/InAppMessaging/types.js +2 -0
- package/lib/InAppMessaging/types.js.map +1 -1
- package/lib/Notifications.d.ts +6 -2
- package/lib/Notifications.js +45 -0
- package/lib/Notifications.js.map +1 -1
- package/lib/PushNotification/NotEnabledError.d.ts +3 -0
- package/lib/PushNotification/NotEnabledError.js +16 -0
- package/lib/PushNotification/NotEnabledError.js.map +1 -0
- package/lib/PushNotification/Platform/index.d.ts +2 -0
- package/lib/PushNotification/Platform/index.js +26 -0
- package/lib/PushNotification/Platform/index.js.map +1 -0
- package/lib/PushNotification/Platform/index.native.d.ts +2 -0
- package/lib/PushNotification/Platform/index.native.js +8 -0
- package/lib/PushNotification/Platform/index.native.js.map +1 -0
- package/lib/PushNotification/Platform/types.d.ts +5 -0
- package/lib/PushNotification/Platform/types.js +5 -0
- package/lib/PushNotification/Platform/types.js.map +1 -0
- package/lib/PushNotification/PlatformNotSupportedError.d.ts +3 -0
- package/lib/PushNotification/PlatformNotSupportedError.js +16 -0
- package/lib/PushNotification/PlatformNotSupportedError.js.map +1 -0
- package/lib/PushNotification/Providers/AWSPinpointProvider/index.d.ts +15 -0
- package/lib/PushNotification/Providers/AWSPinpointProvider/index.js +115 -0
- package/lib/PushNotification/Providers/AWSPinpointProvider/index.js.map +1 -0
- package/lib/PushNotification/Providers/AWSPinpointProvider/types.d.ts +9 -0
- package/lib/PushNotification/Providers/AWSPinpointProvider/types.js +16 -0
- package/lib/PushNotification/Providers/AWSPinpointProvider/types.js.map +1 -0
- package/lib/PushNotification/Providers/AWSPinpointProvider/utils.d.ts +7 -0
- package/lib/PushNotification/Providers/AWSPinpointProvider/utils.js +58 -0
- package/lib/PushNotification/Providers/AWSPinpointProvider/utils.js.map +1 -0
- package/lib/PushNotification/Providers/index.d.ts +1 -0
- package/lib/PushNotification/Providers/index.js +7 -0
- package/lib/PushNotification/Providers/index.js.map +1 -0
- package/lib/PushNotification/PushNotification.d.ts +39 -0
- package/lib/PushNotification/PushNotification.js +91 -0
- package/lib/PushNotification/PushNotification.js.map +1 -0
- package/lib/PushNotification/PushNotification.native.d.ts +63 -0
- package/lib/PushNotification/PushNotification.native.js +327 -0
- package/lib/PushNotification/PushNotification.native.js.map +1 -0
- package/lib/PushNotification/index.d.ts +2 -0
- package/lib/PushNotification/index.js +9 -0
- package/lib/PushNotification/index.js.map +1 -0
- package/lib/PushNotification/types.d.ts +77 -0
- package/lib/PushNotification/types.js +12 -0
- package/lib/PushNotification/types.js.map +1 -0
- package/lib/PushNotification/utils.d.ts +3 -0
- package/lib/PushNotification/utils.js +81 -0
- package/lib/PushNotification/utils.js.map +1 -0
- package/lib/common/AWSPinpointProviderCommon/index.d.ts +34 -0
- package/lib/common/AWSPinpointProviderCommon/index.js +281 -0
- package/lib/common/AWSPinpointProviderCommon/index.js.map +1 -0
- package/lib/common/AWSPinpointProviderCommon/types.d.ts +9 -0
- package/lib/common/AWSPinpointProviderCommon/types.js +5 -0
- package/lib/common/AWSPinpointProviderCommon/types.js.map +1 -0
- package/lib/common/constants.d.ts +1 -0
- package/lib/common/constants.js +6 -0
- package/lib/common/constants.js.map +1 -0
- package/lib/common/eventListeners/index.d.ts +4 -0
- package/lib/common/eventListeners/index.js +55 -0
- package/lib/common/eventListeners/index.js.map +1 -0
- package/lib/common/eventListeners/types.d.ts +7 -0
- package/lib/common/eventListeners/types.js +5 -0
- package/lib/common/eventListeners/types.js.map +1 -0
- package/lib/common/index.d.ts +4 -0
- package/lib/common/index.js +13 -0
- package/lib/common/index.js.map +1 -0
- package/lib/index.d.ts +5 -2
- package/lib/index.js +4 -0
- package/lib/index.js.map +1 -1
- package/lib/types.d.ts +34 -2
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -1
- package/lib-esm/InAppMessaging/InAppMessaging.d.ts +10 -8
- package/lib-esm/InAppMessaging/InAppMessaging.js +9 -11
- package/lib-esm/InAppMessaging/InAppMessaging.js.map +1 -1
- package/lib-esm/InAppMessaging/Providers/AWSPinpointProvider/index.d.ts +5 -25
- package/lib-esm/InAppMessaging/Providers/AWSPinpointProvider/index.js +39 -254
- package/lib-esm/InAppMessaging/Providers/AWSPinpointProvider/index.js.map +1 -1
- package/lib-esm/InAppMessaging/Providers/AWSPinpointProvider/types.d.ts +0 -9
- package/lib-esm/InAppMessaging/Providers/AWSPinpointProvider/types.js.map +1 -1
- package/lib-esm/InAppMessaging/Providers/AWSPinpointProvider/utils.js +2 -8
- package/lib-esm/InAppMessaging/Providers/AWSPinpointProvider/utils.js.map +1 -1
- package/lib-esm/InAppMessaging/index.d.ts +1 -3
- package/lib-esm/InAppMessaging/index.js +0 -1
- package/lib-esm/InAppMessaging/index.js.map +1 -1
- package/lib-esm/InAppMessaging/types.d.ts +30 -42
- package/lib-esm/InAppMessaging/types.js +2 -0
- package/lib-esm/InAppMessaging/types.js.map +1 -1
- package/lib-esm/Notifications.d.ts +6 -2
- package/lib-esm/Notifications.js +48 -3
- package/lib-esm/Notifications.js.map +1 -1
- package/lib-esm/PushNotification/NotEnabledError.d.ts +3 -0
- package/lib-esm/PushNotification/NotEnabledError.js +14 -0
- package/lib-esm/PushNotification/NotEnabledError.js.map +1 -0
- package/lib-esm/PushNotification/Platform/index.d.ts +2 -0
- package/lib-esm/PushNotification/Platform/index.js +24 -0
- package/lib-esm/PushNotification/Platform/index.js.map +1 -0
- package/lib-esm/PushNotification/Platform/index.native.d.ts +2 -0
- package/lib-esm/PushNotification/Platform/index.native.js +6 -0
- package/lib-esm/PushNotification/Platform/index.native.js.map +1 -0
- package/lib-esm/PushNotification/Platform/types.d.ts +5 -0
- package/lib-esm/PushNotification/Platform/types.js +3 -0
- package/lib-esm/PushNotification/Platform/types.js.map +1 -0
- package/lib-esm/PushNotification/PlatformNotSupportedError.d.ts +3 -0
- package/lib-esm/PushNotification/PlatformNotSupportedError.js +14 -0
- package/lib-esm/PushNotification/PlatformNotSupportedError.js.map +1 -0
- package/lib-esm/PushNotification/Providers/AWSPinpointProvider/index.d.ts +15 -0
- package/lib-esm/PushNotification/Providers/AWSPinpointProvider/index.js +113 -0
- package/lib-esm/PushNotification/Providers/AWSPinpointProvider/index.js.map +1 -0
- package/lib-esm/PushNotification/Providers/AWSPinpointProvider/types.d.ts +9 -0
- package/lib-esm/PushNotification/Providers/AWSPinpointProvider/types.js +14 -0
- package/lib-esm/PushNotification/Providers/AWSPinpointProvider/types.js.map +1 -0
- package/lib-esm/PushNotification/Providers/AWSPinpointProvider/utils.d.ts +7 -0
- package/lib-esm/PushNotification/Providers/AWSPinpointProvider/utils.js +56 -0
- package/lib-esm/PushNotification/Providers/AWSPinpointProvider/utils.js.map +1 -0
- package/lib-esm/PushNotification/Providers/index.d.ts +1 -0
- package/lib-esm/PushNotification/Providers/index.js +4 -0
- package/lib-esm/PushNotification/Providers/index.js.map +1 -0
- package/lib-esm/PushNotification/PushNotification.d.ts +39 -0
- package/lib-esm/PushNotification/PushNotification.js +89 -0
- package/lib-esm/PushNotification/PushNotification.js.map +1 -0
- package/lib-esm/PushNotification/PushNotification.native.d.ts +63 -0
- package/lib-esm/PushNotification/PushNotification.native.js +325 -0
- package/lib-esm/PushNotification/PushNotification.native.js.map +1 -0
- package/lib-esm/PushNotification/index.d.ts +2 -0
- package/lib-esm/PushNotification/index.js +5 -0
- package/lib-esm/PushNotification/index.js.map +1 -0
- package/lib-esm/PushNotification/types.d.ts +77 -0
- package/lib-esm/PushNotification/types.js +10 -0
- package/lib-esm/PushNotification/types.js.map +1 -0
- package/lib-esm/PushNotification/utils.d.ts +3 -0
- package/lib-esm/PushNotification/utils.js +79 -0
- package/lib-esm/PushNotification/utils.js.map +1 -0
- package/lib-esm/common/AWSPinpointProviderCommon/index.d.ts +34 -0
- package/lib-esm/common/AWSPinpointProviderCommon/index.js +279 -0
- package/lib-esm/common/AWSPinpointProviderCommon/index.js.map +1 -0
- package/lib-esm/common/AWSPinpointProviderCommon/types.d.ts +9 -0
- package/lib-esm/common/AWSPinpointProviderCommon/types.js +3 -0
- package/lib-esm/common/AWSPinpointProviderCommon/types.js.map +1 -0
- package/lib-esm/common/constants.d.ts +1 -0
- package/lib-esm/common/constants.js +4 -0
- package/lib-esm/common/constants.js.map +1 -0
- package/lib-esm/common/eventListeners/index.d.ts +4 -0
- package/lib-esm/common/eventListeners/index.js +53 -0
- package/lib-esm/common/eventListeners/index.js.map +1 -0
- package/lib-esm/common/eventListeners/types.d.ts +7 -0
- package/lib-esm/common/eventListeners/types.js +3 -0
- package/lib-esm/common/eventListeners/types.js.map +1 -0
- package/lib-esm/common/index.d.ts +4 -0
- package/lib-esm/common/index.js +6 -0
- package/lib-esm/common/index.js.map +1 -0
- package/lib-esm/index.d.ts +5 -2
- package/lib-esm/index.js +2 -0
- package/lib-esm/index.js.map +1 -1
- package/lib-esm/types.d.ts +34 -2
- package/lib-esm/types.js +2 -0
- package/lib-esm/types.js.map +1 -1
- package/package.json +11 -50
- package/src/InAppMessaging/InAppMessaging.ts +27 -36
- package/src/InAppMessaging/Providers/AWSPinpointProvider/index.ts +45 -245
- package/src/InAppMessaging/Providers/AWSPinpointProvider/types.ts +0 -12
- package/src/InAppMessaging/Providers/AWSPinpointProvider/utils.ts +3 -12
- package/src/InAppMessaging/index.ts +0 -3
- package/src/InAppMessaging/types.ts +52 -56
- package/src/Notifications.ts +42 -4
- package/src/PushNotification/NotEnabledError.ts +11 -0
- package/src/PushNotification/Platform/index.native.ts +9 -0
- package/src/PushNotification/Platform/index.ts +22 -0
- package/src/PushNotification/Platform/types.ts +15 -0
- package/src/PushNotification/PlatformNotSupportedError.ts +9 -0
- package/src/PushNotification/Providers/AWSPinpointProvider/index.ts +137 -0
- package/src/PushNotification/Providers/AWSPinpointProvider/types.ts +13 -0
- package/src/PushNotification/Providers/AWSPinpointProvider/utils.ts +79 -0
- package/src/PushNotification/Providers/index.ts +4 -0
- package/src/PushNotification/PushNotification.native.ts +381 -0
- package/src/PushNotification/PushNotification.ts +107 -0
- package/src/PushNotification/index.ts +9 -0
- package/src/PushNotification/types.ts +114 -0
- package/src/PushNotification/utils.ts +112 -0
- package/src/common/AWSPinpointProviderCommon/index.ts +295 -0
- package/src/common/AWSPinpointProviderCommon/types.ts +14 -0
- package/src/common/constants.ts +5 -0
- package/src/common/eventListeners/index.ts +44 -0
- package/src/common/eventListeners/types.ts +12 -0
- package/src/common/index.ts +11 -0
- package/src/index.ts +9 -3
- package/src/types.ts +47 -2
- package/CHANGELOG.md +0 -215
- package/lib/InAppMessaging/eventListeners.d.ts +0 -3
- package/lib/InAppMessaging/eventListeners.js +0 -28
- package/lib/InAppMessaging/eventListeners.js.map +0 -1
- package/lib-esm/InAppMessaging/eventListeners.d.ts +0 -3
- package/lib-esm/InAppMessaging/eventListeners.js +0 -26
- package/lib-esm/InAppMessaging/eventListeners.js.map +0 -1
- package/src/InAppMessaging/eventListeners.ts +0 -42
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { isEmpty } from 'lodash';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
NormalizedValues,
|
|
8
|
+
PushNotificationMessage,
|
|
9
|
+
PushNotificationPermissionStatus,
|
|
10
|
+
} from './types';
|
|
11
|
+
|
|
12
|
+
const DEEP_LINK_ACTION = 'deeplink';
|
|
13
|
+
const URL_ACTION = 'url';
|
|
14
|
+
|
|
15
|
+
export const normalizeNativePermissionStatus = (
|
|
16
|
+
nativeStatus?
|
|
17
|
+
): PushNotificationPermissionStatus => {
|
|
18
|
+
switch (nativeStatus) {
|
|
19
|
+
case 'ShouldRequest':
|
|
20
|
+
return PushNotificationPermissionStatus.SHOULD_REQUEST;
|
|
21
|
+
case 'NotDetermined':
|
|
22
|
+
case 'ShouldExplainThenRequest':
|
|
23
|
+
return PushNotificationPermissionStatus.SHOULD_EXPLAIN_THEN_REQUEST;
|
|
24
|
+
case 'Authorized':
|
|
25
|
+
case 'Granted':
|
|
26
|
+
return PushNotificationPermissionStatus.GRANTED;
|
|
27
|
+
case 'Denied':
|
|
28
|
+
return PushNotificationPermissionStatus.DENIED;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const normalizeNativeMessage = (
|
|
33
|
+
nativeMessage?
|
|
34
|
+
): PushNotificationMessage | null => {
|
|
35
|
+
let normalized: NormalizedValues;
|
|
36
|
+
if (nativeMessage?.aps) {
|
|
37
|
+
normalized = normalizeApnsMessage(nativeMessage);
|
|
38
|
+
}
|
|
39
|
+
if (nativeMessage?.rawData) {
|
|
40
|
+
normalized = normalizeFcmMessage(nativeMessage);
|
|
41
|
+
}
|
|
42
|
+
if (!normalized) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const { body, imageUrl, title, action, options, data } = normalized;
|
|
46
|
+
return {
|
|
47
|
+
...(body && { body }),
|
|
48
|
+
...(imageUrl && { imageUrl }),
|
|
49
|
+
...(title && { title }),
|
|
50
|
+
...action,
|
|
51
|
+
...options,
|
|
52
|
+
...(!isEmpty(data) && { data }),
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const normalizeApnsMessage = (apnsMessage): NormalizedValues => {
|
|
57
|
+
const { aps, data = {} } = apnsMessage;
|
|
58
|
+
const { body, title } = aps.alert ?? {};
|
|
59
|
+
const action = getApnsAction(data.pinpoint) ?? {};
|
|
60
|
+
const imageUrl = data['media-url'];
|
|
61
|
+
const options = getApnsOptions(apnsMessage);
|
|
62
|
+
return { body, imageUrl, title, action, options, data };
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const normalizeFcmMessage = (fcmMessage): NormalizedValues => {
|
|
66
|
+
const { body, imageUrl, rawData: data, title } = fcmMessage;
|
|
67
|
+
const action = getFcmAction(fcmMessage.action) ?? {};
|
|
68
|
+
const options = getFcmOptions(fcmMessage);
|
|
69
|
+
return { body, imageUrl, title, action, options, data };
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const getApnsAction = (
|
|
73
|
+
action = {}
|
|
74
|
+
): Pick<PushNotificationMessage, 'deeplinkUrl'> => {
|
|
75
|
+
if (action[DEEP_LINK_ACTION]) {
|
|
76
|
+
return { deeplinkUrl: action[DEEP_LINK_ACTION] };
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const getFcmAction = (
|
|
81
|
+
action = {}
|
|
82
|
+
): Pick<PushNotificationMessage, 'goToUrl' | 'deeplinkUrl'> => {
|
|
83
|
+
if (action[URL_ACTION]) {
|
|
84
|
+
return { goToUrl: action[URL_ACTION] };
|
|
85
|
+
}
|
|
86
|
+
if (action[DEEP_LINK_ACTION]) {
|
|
87
|
+
return { deeplinkUrl: action[DEEP_LINK_ACTION] };
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const getApnsOptions = ({
|
|
92
|
+
aps,
|
|
93
|
+
}): Pick<PushNotificationMessage, 'apnsOptions'> => {
|
|
94
|
+
const { subtitle } = aps.alert ?? {};
|
|
95
|
+
const apnsOptions = { ...(subtitle && { subtitle }) };
|
|
96
|
+
return { ...(!isEmpty(apnsOptions) && { apnsOptions }) };
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const getFcmOptions = ({
|
|
100
|
+
channelId,
|
|
101
|
+
messageId,
|
|
102
|
+
senderId,
|
|
103
|
+
sendTime,
|
|
104
|
+
}): Pick<PushNotificationMessage, 'fcmOptions'> => {
|
|
105
|
+
const fcmOptions = {
|
|
106
|
+
...(channelId && { channelId }),
|
|
107
|
+
...(messageId && { messageId }),
|
|
108
|
+
...(senderId && { senderId }),
|
|
109
|
+
...(sendTime && { sendTime: new Date(sendTime) }),
|
|
110
|
+
};
|
|
111
|
+
return { ...(!isEmpty(fcmOptions) && { fcmOptions }) };
|
|
112
|
+
};
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
ClientDevice,
|
|
6
|
+
ConsoleLogger,
|
|
7
|
+
Credentials,
|
|
8
|
+
getAmplifyUserAgent,
|
|
9
|
+
StorageHelper,
|
|
10
|
+
transferKeyToUpperCase,
|
|
11
|
+
} from '@aws-amplify/core';
|
|
12
|
+
import { Cache } from '@aws-amplify/cache';
|
|
13
|
+
import {
|
|
14
|
+
Event as AWSPinpointAnalyticsEvent,
|
|
15
|
+
UpdateEndpointCommand,
|
|
16
|
+
UpdateEndpointCommandInput,
|
|
17
|
+
PinpointClient,
|
|
18
|
+
PutEventsCommand,
|
|
19
|
+
PutEventsCommandInput,
|
|
20
|
+
} from '@aws-sdk/client-pinpoint';
|
|
21
|
+
import { v4 as uuid } from 'uuid';
|
|
22
|
+
|
|
23
|
+
import {
|
|
24
|
+
NotificationsCategory,
|
|
25
|
+
NotificationsSubCategory,
|
|
26
|
+
NotificationsProvider,
|
|
27
|
+
UserInfo,
|
|
28
|
+
} from '../../types';
|
|
29
|
+
import { AWSPinpointUserInfo } from './types';
|
|
30
|
+
|
|
31
|
+
export default abstract class AWSPinpointProviderCommon
|
|
32
|
+
implements NotificationsProvider
|
|
33
|
+
{
|
|
34
|
+
static category: NotificationsCategory = 'Notifications';
|
|
35
|
+
static providerName = 'AWSPinpoint';
|
|
36
|
+
|
|
37
|
+
protected clientInfo;
|
|
38
|
+
protected config: Record<string, any> = {};
|
|
39
|
+
protected endpointInitialized = false;
|
|
40
|
+
protected initialized = false;
|
|
41
|
+
protected logger: ConsoleLogger;
|
|
42
|
+
|
|
43
|
+
constructor(logger) {
|
|
44
|
+
this.config = { storage: new StorageHelper().getStorage() };
|
|
45
|
+
this.clientInfo = ClientDevice.clientInfo() ?? {};
|
|
46
|
+
this.logger = logger;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* get the category of the plugin
|
|
51
|
+
*/
|
|
52
|
+
getCategory() {
|
|
53
|
+
return AWSPinpointProviderCommon.category;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* get the sub-category of the plugin
|
|
58
|
+
*/
|
|
59
|
+
abstract getSubCategory(): NotificationsSubCategory;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* get provider name of the plugin
|
|
63
|
+
*/
|
|
64
|
+
getProviderName(): string {
|
|
65
|
+
return AWSPinpointProviderCommon.providerName;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
configure(config = {}): Record<string, any> {
|
|
69
|
+
this.config = { ...this.config, ...config };
|
|
70
|
+
this.logger.debug(
|
|
71
|
+
`configure ${this.getProviderName()}${this.getSubCategory()}Provider`,
|
|
72
|
+
this.config
|
|
73
|
+
);
|
|
74
|
+
return this.config;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
identifyUser = async (userId: string, userInfo: UserInfo): Promise<void> => {
|
|
78
|
+
if (!this.initialized) {
|
|
79
|
+
await this.init();
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
await this.updateEndpoint(userId, userInfo);
|
|
83
|
+
} catch (err) {
|
|
84
|
+
this.logger.error('Error identifying user', err);
|
|
85
|
+
throw err;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
protected init = async (): Promise<void> => {
|
|
90
|
+
const { endpointId, storage } = this.config;
|
|
91
|
+
const providerName = this.getProviderName();
|
|
92
|
+
try {
|
|
93
|
+
// Only run sync() if it's available (i.e. React Native)
|
|
94
|
+
if (typeof storage.sync === 'function') {
|
|
95
|
+
await storage.sync();
|
|
96
|
+
}
|
|
97
|
+
// If an endpoint was not provided via configuration, try to get it from cache
|
|
98
|
+
if (!endpointId) {
|
|
99
|
+
this.config.endpointId = await this.getEndpointId();
|
|
100
|
+
}
|
|
101
|
+
this.initialized = true;
|
|
102
|
+
} catch (err) {
|
|
103
|
+
this.logger.error(`Failed to initialize ${providerName}`, err);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
protected recordAnalyticsEvent = async (
|
|
108
|
+
event: AWSPinpointAnalyticsEvent
|
|
109
|
+
): Promise<void> => {
|
|
110
|
+
const { appId, credentials, endpointId, pinpointClient } = this.config;
|
|
111
|
+
const currentCredentials = await this.getCredentials();
|
|
112
|
+
// Shallow compare to determine if credentials stored here are outdated
|
|
113
|
+
const credentialsUpdated =
|
|
114
|
+
!credentials ||
|
|
115
|
+
Object.keys(currentCredentials).some(
|
|
116
|
+
key => currentCredentials[key] !== credentials[key]
|
|
117
|
+
);
|
|
118
|
+
// Update credentials
|
|
119
|
+
this.config.credentials = currentCredentials;
|
|
120
|
+
try {
|
|
121
|
+
// Initialize a new pinpoint client if one isn't already configured or if credentials changed
|
|
122
|
+
if (!pinpointClient || credentialsUpdated) {
|
|
123
|
+
await this.initPinpointClient();
|
|
124
|
+
}
|
|
125
|
+
// Create the PutEvents input
|
|
126
|
+
const input: PutEventsCommandInput = {
|
|
127
|
+
ApplicationId: appId,
|
|
128
|
+
EventsRequest: {
|
|
129
|
+
BatchItem: {
|
|
130
|
+
[endpointId]: {
|
|
131
|
+
Endpoint: {},
|
|
132
|
+
Events: {
|
|
133
|
+
[uuid()]: event,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
const command: PutEventsCommand = new PutEventsCommand(input);
|
|
140
|
+
this.logger.debug('recording analytics event');
|
|
141
|
+
await this.config.pinpointClient.send(command);
|
|
142
|
+
} catch (err) {
|
|
143
|
+
this.logger.error('Error recording analytics event', err);
|
|
144
|
+
throw err;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
protected updateEndpoint = async (
|
|
149
|
+
userId: string = null,
|
|
150
|
+
userInfo: AWSPinpointUserInfo = null
|
|
151
|
+
): Promise<void> => {
|
|
152
|
+
const {
|
|
153
|
+
appId,
|
|
154
|
+
credentials,
|
|
155
|
+
endpointId,
|
|
156
|
+
endpointInfo = {},
|
|
157
|
+
pinpointClient,
|
|
158
|
+
} = this.config;
|
|
159
|
+
const currentCredentials = await this.getCredentials();
|
|
160
|
+
// Shallow compare to determine if credentials stored here are outdated
|
|
161
|
+
const credentialsUpdated =
|
|
162
|
+
!credentials ||
|
|
163
|
+
Object.keys(currentCredentials).some(
|
|
164
|
+
key => currentCredentials[key] !== credentials[key]
|
|
165
|
+
);
|
|
166
|
+
// If endpoint is already initialized, and nothing else is changing, just early return
|
|
167
|
+
if (
|
|
168
|
+
this.endpointInitialized &&
|
|
169
|
+
!credentialsUpdated &&
|
|
170
|
+
!userId &&
|
|
171
|
+
!userInfo
|
|
172
|
+
) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
// Update credentials
|
|
176
|
+
this.config.credentials = currentCredentials;
|
|
177
|
+
try {
|
|
178
|
+
// Initialize a new pinpoint client if one isn't already configured or if credentials changed
|
|
179
|
+
if (!pinpointClient || credentialsUpdated) {
|
|
180
|
+
this.initPinpointClient();
|
|
181
|
+
}
|
|
182
|
+
const { address, attributes, demographic, location, metrics, optOut } =
|
|
183
|
+
userInfo ?? {};
|
|
184
|
+
const { appVersion, make, model, platform, version } = this.clientInfo;
|
|
185
|
+
// Create the UpdateEndpoint input, prioritizing passed in user info and falling back to
|
|
186
|
+
// defaults (if any) obtained from the config
|
|
187
|
+
const input: UpdateEndpointCommandInput = {
|
|
188
|
+
ApplicationId: appId,
|
|
189
|
+
EndpointId: endpointId,
|
|
190
|
+
EndpointRequest: {
|
|
191
|
+
RequestId: uuid(),
|
|
192
|
+
EffectiveDate: new Date().toISOString(),
|
|
193
|
+
ChannelType: endpointInfo.channelType,
|
|
194
|
+
Address: address ?? endpointInfo.address,
|
|
195
|
+
Attributes: {
|
|
196
|
+
...endpointInfo.attributes,
|
|
197
|
+
...attributes,
|
|
198
|
+
},
|
|
199
|
+
Demographic: {
|
|
200
|
+
AppVersion: appVersion,
|
|
201
|
+
Make: make,
|
|
202
|
+
Model: model,
|
|
203
|
+
ModelVersion: version,
|
|
204
|
+
Platform: platform,
|
|
205
|
+
...transferKeyToUpperCase({
|
|
206
|
+
...endpointInfo.demographic,
|
|
207
|
+
...demographic,
|
|
208
|
+
}),
|
|
209
|
+
},
|
|
210
|
+
Location: transferKeyToUpperCase({
|
|
211
|
+
...endpointInfo.location,
|
|
212
|
+
...location,
|
|
213
|
+
}),
|
|
214
|
+
Metrics: {
|
|
215
|
+
...endpointInfo.metrics,
|
|
216
|
+
...metrics,
|
|
217
|
+
},
|
|
218
|
+
OptOut: optOut ?? endpointInfo.optOut,
|
|
219
|
+
User: {
|
|
220
|
+
UserId:
|
|
221
|
+
userId ?? endpointInfo.userId ?? currentCredentials.identityId,
|
|
222
|
+
UserAttributes: attributes ?? endpointInfo.userAttributes,
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
const command: UpdateEndpointCommand = new UpdateEndpointCommand(input);
|
|
227
|
+
this.logger.debug('updating endpoint');
|
|
228
|
+
await this.config.pinpointClient.send(command);
|
|
229
|
+
this.endpointInitialized = true;
|
|
230
|
+
} catch (err) {
|
|
231
|
+
throw err;
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
private initPinpointClient = (): void => {
|
|
236
|
+
const { appId, credentials, pinpointClient, region } = this.config;
|
|
237
|
+
|
|
238
|
+
if (!appId || !credentials || !region) {
|
|
239
|
+
throw new Error(
|
|
240
|
+
'One or more of credentials, appId or region is not configured'
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (pinpointClient) {
|
|
245
|
+
pinpointClient.destroy();
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
this.config.pinpointClient = new PinpointClient({
|
|
249
|
+
region,
|
|
250
|
+
credentials,
|
|
251
|
+
customUserAgent: getAmplifyUserAgent(`/${this.getSubCategory()}`),
|
|
252
|
+
});
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
private getEndpointId = async (): Promise<string> => {
|
|
256
|
+
const { appId } = this.config;
|
|
257
|
+
// Each Pinpoint channel requires its own Endpoint ID
|
|
258
|
+
// However, Push will share the Analytics endpoint for now so as to not break existing customers
|
|
259
|
+
const cacheKey =
|
|
260
|
+
this.getSubCategory() === 'PushNotification'
|
|
261
|
+
? `${this.getProviderName()}_${appId}`
|
|
262
|
+
: `${this.getSubCategory()}:${this.getProviderName()}:${appId}`;
|
|
263
|
+
// First attempt to retrieve the ID from cache
|
|
264
|
+
const cachedEndpointId = await Cache.getItem(cacheKey);
|
|
265
|
+
// Found in cache, just return it
|
|
266
|
+
if (cachedEndpointId) {
|
|
267
|
+
return cachedEndpointId;
|
|
268
|
+
}
|
|
269
|
+
// Otherwise, generate a new ID and store it in long-lived cache before returning it
|
|
270
|
+
const endpointId = uuid();
|
|
271
|
+
// Set a longer TTL to avoid endpoint id being deleted after the default TTL (3 days)
|
|
272
|
+
// Also set its priority to the highest to reduce its chance of being deleted when cache is full
|
|
273
|
+
const ttl = 1000 * 60 * 60 * 24 * 365 * 100; // 100 years
|
|
274
|
+
const expiration = new Date().getTime() + ttl;
|
|
275
|
+
Cache.setItem(cacheKey, endpointId, {
|
|
276
|
+
expires: expiration,
|
|
277
|
+
priority: 1,
|
|
278
|
+
});
|
|
279
|
+
return endpointId;
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
private getCredentials = async () => {
|
|
283
|
+
try {
|
|
284
|
+
const credentials = await Credentials.get();
|
|
285
|
+
if (!credentials) {
|
|
286
|
+
this.logger.debug('no credentials found');
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
return Credentials.shear(credentials);
|
|
290
|
+
} catch (err) {
|
|
291
|
+
this.logger.error('Error getting credentials:', err);
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { UserInfo } from '../../types';
|
|
5
|
+
|
|
6
|
+
export interface AWSPinpointProviderConfig {
|
|
7
|
+
appId: string;
|
|
8
|
+
region: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface AWSPinpointUserInfo extends UserInfo {
|
|
12
|
+
address?: string;
|
|
13
|
+
optOut?: 'ALL' | 'NONE';
|
|
14
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { EventListener, EventType } from './types';
|
|
5
|
+
|
|
6
|
+
const eventListeners: Record<string, Set<EventListener<Function>>> = {};
|
|
7
|
+
|
|
8
|
+
export const notifyEventListeners = (type: EventType, ...args: any[]): void => {
|
|
9
|
+
eventListeners[type]?.forEach(listener => {
|
|
10
|
+
listener.handleEvent(...args);
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const notifyEventListenersAndAwaitHandlers = (
|
|
15
|
+
type: EventType,
|
|
16
|
+
...args: any[]
|
|
17
|
+
): Promise<void[]> =>
|
|
18
|
+
Promise.all<void>(
|
|
19
|
+
Array.from(eventListeners[type] ?? []).map(async listener => {
|
|
20
|
+
try {
|
|
21
|
+
await listener.handleEvent(...args);
|
|
22
|
+
} catch (err) {
|
|
23
|
+
throw err;
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export const addEventListener = <EventHandler extends Function>(
|
|
29
|
+
type: EventType,
|
|
30
|
+
handler: EventHandler
|
|
31
|
+
): EventListener<EventHandler> => {
|
|
32
|
+
// If there is no listener set for the event type, just create it
|
|
33
|
+
if (!eventListeners[type]) {
|
|
34
|
+
eventListeners[type] = new Set<EventListener<EventHandler>>();
|
|
35
|
+
}
|
|
36
|
+
const listener = {
|
|
37
|
+
handleEvent: handler,
|
|
38
|
+
remove: () => {
|
|
39
|
+
eventListeners[type].delete(listener);
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
eventListeners[type].add(listener);
|
|
43
|
+
return listener;
|
|
44
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { InAppMessageInteractionEvent } from '../../InAppMessaging/types';
|
|
5
|
+
import { PushNotificationEvent } from '../../PushNotification/types';
|
|
6
|
+
|
|
7
|
+
export interface EventListener<EventHandler extends Function> {
|
|
8
|
+
handleEvent: EventHandler;
|
|
9
|
+
remove: () => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type EventType = InAppMessageInteractionEvent | PushNotificationEvent;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
export { default as AWSPinpointProviderCommon } from './AWSPinpointProviderCommon';
|
|
5
|
+
export { AMPLIFY_SYMBOL } from './constants';
|
|
6
|
+
export {
|
|
7
|
+
addEventListener,
|
|
8
|
+
notifyEventListeners,
|
|
9
|
+
notifyEventListenersAndAwaitHandlers,
|
|
10
|
+
} from './eventListeners';
|
|
11
|
+
export { EventListener, EventType } from './eventListeners/types';
|
package/src/index.ts
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
export { default as Notifications } from './Notifications';
|
|
5
|
+
|
|
6
|
+
export { AWSPinpointProviderCommon } from './common';
|
|
7
|
+
export { AWSPinpointUserInfo } from './common/AWSPinpointProviderCommon/types';
|
|
5
8
|
export {
|
|
6
|
-
AWSPinpointUserInfo,
|
|
7
9
|
InAppMessage,
|
|
8
10
|
InAppMessageAction,
|
|
9
11
|
InAppMessageButton,
|
|
@@ -15,6 +17,10 @@ export {
|
|
|
15
17
|
InAppMessageTextAlign,
|
|
16
18
|
InAppMessagingConfig,
|
|
17
19
|
InAppMessagingEvent,
|
|
18
|
-
UserInfo,
|
|
19
20
|
} from './InAppMessaging';
|
|
20
|
-
export {
|
|
21
|
+
export {
|
|
22
|
+
PushNotificationMessage,
|
|
23
|
+
PushNotificationPermissions,
|
|
24
|
+
PushNotificationPermissionStatus,
|
|
25
|
+
} from './PushNotification/types';
|
|
26
|
+
export { NotificationsConfig, UserInfo } from './types';
|
package/src/types.ts
CHANGED
|
@@ -1,11 +1,56 @@
|
|
|
1
1
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
import { InAppMessagingConfig } from './InAppMessaging/types';
|
|
5
|
+
import { PushNotificationConfig } from './PushNotification/types';
|
|
4
6
|
|
|
5
7
|
export type NotificationsCategory = 'Notifications';
|
|
6
8
|
|
|
7
|
-
export
|
|
9
|
+
export type NotificationsSubCategory = 'InAppMessaging' | 'PushNotification';
|
|
10
|
+
|
|
11
|
+
export interface NotificationsProvider {
|
|
12
|
+
// configure provider
|
|
13
|
+
configure(config: object): object;
|
|
14
|
+
|
|
15
|
+
// return category ('Notifications')
|
|
16
|
+
getCategory(): NotificationsCategory;
|
|
17
|
+
|
|
18
|
+
// return sub-category
|
|
19
|
+
getSubCategory(): NotificationsSubCategory;
|
|
20
|
+
|
|
21
|
+
// return the name of you provider
|
|
22
|
+
getProviderName(): string;
|
|
23
|
+
|
|
24
|
+
// identify the current user with the provider
|
|
25
|
+
identifyUser(userId: string, userInfo: UserInfo): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface NotificationsConfig {
|
|
8
29
|
Notifications?: {
|
|
9
30
|
InAppMessaging?: InAppMessagingConfig;
|
|
31
|
+
PushNotification?: PushNotificationConfig;
|
|
10
32
|
};
|
|
11
33
|
}
|
|
34
|
+
|
|
35
|
+
export type UserInfo = {
|
|
36
|
+
attributes?: Record<string, string[]>;
|
|
37
|
+
demographic?: {
|
|
38
|
+
appVersion?: string;
|
|
39
|
+
locale?: string;
|
|
40
|
+
make?: string;
|
|
41
|
+
model?: string;
|
|
42
|
+
modelVersion?: string;
|
|
43
|
+
platform?: string;
|
|
44
|
+
platformVersion?: string;
|
|
45
|
+
timezone?: string;
|
|
46
|
+
};
|
|
47
|
+
location?: {
|
|
48
|
+
city?: string;
|
|
49
|
+
country?: string;
|
|
50
|
+
latitude?: number;
|
|
51
|
+
longitude?: number;
|
|
52
|
+
postalCode?: string;
|
|
53
|
+
region?: string;
|
|
54
|
+
};
|
|
55
|
+
metrics?: Record<string, number>;
|
|
56
|
+
};
|