notifly-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/index.js +279 -0
- package/namespace.js +6 -0
- package/package.json +20 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# notifly-node-package
|
package/index.js
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import messaging from "@react-native-firebase/messaging";
|
|
2
|
+
import notifee, { AndroidImportance } from "@notifee/react-native";
|
|
3
|
+
import { Linking, Platform } from 'react-native';
|
|
4
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
5
|
+
import rnDeviceInfo from 'react-native-device-info';
|
|
6
|
+
import { v5 } from 'uuid';
|
|
7
|
+
import { NAMESPACE } from './namespace';
|
|
8
|
+
|
|
9
|
+
exports.trackEvent = logEvent;
|
|
10
|
+
|
|
11
|
+
exports.setUserProperties = _setUserProperties
|
|
12
|
+
|
|
13
|
+
exports.setUserId = async userId => await _setUserProperties({
|
|
14
|
+
external_user_id: userId,
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
exports.sessionStart = async function () {
|
|
18
|
+
const apiLevel = rnDeviceInfo.getApiLevel(); // only android
|
|
19
|
+
const brand = rnDeviceInfo.getBrand(); // apple samsung
|
|
20
|
+
const model = rnDeviceInfo.getModel(); // 기종 SM-G960N or iPhone 8
|
|
21
|
+
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
22
|
+
const platform = Platform.OS;
|
|
23
|
+
const deviceInfo = await Promise.all([model, brand, apiLevel]);
|
|
24
|
+
const openAppEventParams = {
|
|
25
|
+
"timezone": timezone,
|
|
26
|
+
"app_id": 'test_app',
|
|
27
|
+
"platform": platform,
|
|
28
|
+
"device_model": deviceInfo[0],
|
|
29
|
+
"properties": {
|
|
30
|
+
"device_brand": deviceInfo[1],
|
|
31
|
+
"api_level": deviceInfo[2],
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
await logEvent("session_start", openAppEventParams, true)
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
exports.initialize = async function (prjId, userName, password) {
|
|
39
|
+
try {
|
|
40
|
+
messaging().onNotificationOpenedApp(async (remoteMessage) => {
|
|
41
|
+
await logEvent("push_click", { "campaign_id": remoteMessage.data.campaign_id, "status": "background" }, true);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
messaging().getToken()
|
|
45
|
+
|
|
46
|
+
messaging()
|
|
47
|
+
.getInitialNotification()
|
|
48
|
+
.then(async (remoteMessage) => {
|
|
49
|
+
if (remoteMessage) {
|
|
50
|
+
const link = remoteMessage.notification?.android?.link;
|
|
51
|
+
if (link) {
|
|
52
|
+
Linking.openURL(remoteMessage.notification?.android?.link);
|
|
53
|
+
}
|
|
54
|
+
await logEvent("push_click", { "campaign_id": remoteMessage.data.campaign_id, "status": "quit" }, true);
|
|
55
|
+
await logEvent("push_delivered", { "campaign_id": remoteMessage.data.campaign_id, "status": "quit" }, true);
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
messaging().setBackgroundMessageHandler(async (remoteMessage) => {
|
|
61
|
+
await logEvent("push_delivered", { "campaign_id": remoteMessage.data.campaign_id, "status": "background" }, true);
|
|
62
|
+
return
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
await Promise.all([
|
|
66
|
+
AsyncStorage.setItem('notiflyProjectId', prjId),
|
|
67
|
+
AsyncStorage.setItem('notiflyUserName', userName),
|
|
68
|
+
AsyncStorage.setItem('notiflyUserPassword', password),
|
|
69
|
+
])
|
|
70
|
+
|
|
71
|
+
notifee.requestPermission()
|
|
72
|
+
if (Platform.OS === 'android') {
|
|
73
|
+
notifee.createChannel({
|
|
74
|
+
id: "foreground",
|
|
75
|
+
name: "foreground",
|
|
76
|
+
importance: AndroidImportance.HIGH,
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
notifee.onBackgroundEvent(async ({ type, detail }) => {
|
|
80
|
+
const { notification } = detail;
|
|
81
|
+
const campaign_id = notification.data.campaign_id;
|
|
82
|
+
if (!campaign_id) {
|
|
83
|
+
return
|
|
84
|
+
}
|
|
85
|
+
switch (type) {
|
|
86
|
+
case 3:
|
|
87
|
+
try {
|
|
88
|
+
await logEvent("push_delivered", { "campaign_id": campaign_id, "status": "background-notifee" }, true);
|
|
89
|
+
} catch (err) {
|
|
90
|
+
console.error('[Notifly]: ', err);
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
} catch (err) {
|
|
96
|
+
console.error("[Notifly]: ", err);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
exports.foregroundSetting = function () {
|
|
101
|
+
messaging().onMessage(async remoteMessage => {
|
|
102
|
+
await notifee.displayNotification({
|
|
103
|
+
title: remoteMessage.notification.title,
|
|
104
|
+
body: remoteMessage.notification.body,
|
|
105
|
+
data: remoteMessage.data,
|
|
106
|
+
android: {
|
|
107
|
+
channelId: "foreground",
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
await logEvent("push_delivered", { "campaign_id": remoteMessage.data.campaign_id, "status": "foreground" }, true);
|
|
111
|
+
});
|
|
112
|
+
notifee.onForegroundEvent(async ({ type, detail }) => {
|
|
113
|
+
const { notification } = detail;
|
|
114
|
+
const campaign_id = notification.data.campaign_id;
|
|
115
|
+
if (!campaign_id) {
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
if (type == 1) {
|
|
119
|
+
try {
|
|
120
|
+
if (notification.data.link) {
|
|
121
|
+
Linking.openURL(notification.data.link)
|
|
122
|
+
await logEvent("push_click", { "campaign_id": campaign_id, "status": "foreground" }, true);
|
|
123
|
+
} else {
|
|
124
|
+
await logEvent("push_click", { "campaign_id": campaign_id, "status": "foreground" }, true);
|
|
125
|
+
}
|
|
126
|
+
} catch (err) {
|
|
127
|
+
console.error('[Notifly]: ', err);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async function getCognitoIdToken(userName, password) {
|
|
134
|
+
const myHeaders = new Headers();
|
|
135
|
+
myHeaders.append("X-Amz-Target", "AWSCognitoIdentityProviderService.InitiateAuth");
|
|
136
|
+
myHeaders.append("Content-Type", "application/x-amz-json-1.1");
|
|
137
|
+
|
|
138
|
+
const raw = `{\n \"AuthFlow\":\"USER_PASSWORD_AUTH\",\n \"AuthParameters\": {\n \"PASSWORD\": \"${password}\",\n \"USERNAME\":\"${userName}\"\n },\n \"ClientId\":\"2pc5pce21ec53csf8chafknqve\"\n}`;
|
|
139
|
+
|
|
140
|
+
const requestOptions = {
|
|
141
|
+
method: 'POST',
|
|
142
|
+
headers: myHeaders,
|
|
143
|
+
body: raw,
|
|
144
|
+
redirect: 'follow'
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const token = fetch("https://cognito-idp.ap-northeast-2.amazonaws.com/", requestOptions)
|
|
148
|
+
.then(response => response.text())
|
|
149
|
+
.then(result => {
|
|
150
|
+
const tokens = JSON.parse(result).AuthenticationResult.IdToken
|
|
151
|
+
return tokens;
|
|
152
|
+
})
|
|
153
|
+
.catch(error => console.error('[Notifly]: ', error));
|
|
154
|
+
|
|
155
|
+
return token;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async function _getNotiflyUserId() {
|
|
159
|
+
const encodedUserId = await AsyncStorage.getItem('notiflyUserId');
|
|
160
|
+
if (encodedUserId) {
|
|
161
|
+
return encodedUserId;
|
|
162
|
+
}
|
|
163
|
+
const [prjId, externalUserId] = await Promise.all([AsyncStorage.getItem('notiflyProjectId'), AsyncStorage.getItem('notiflyExternalUserId')])
|
|
164
|
+
let notiflyUserId
|
|
165
|
+
if (externalUserId) {
|
|
166
|
+
notiflyUserId = v5(`${prjId}${externalUserId}`, NAMESPACE.REGISTERED_USERID).replace(/-/g, '');
|
|
167
|
+
} else {
|
|
168
|
+
notiflyUserId = v5(`${prjId}${await messaging().getToken()}`, NAMESPACE.UNREGISTERED_USERID).replace(/-/g, '');
|
|
169
|
+
}
|
|
170
|
+
return notiflyUserId;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async function _setUserProperties(params) {
|
|
174
|
+
if (params.external_user_id) {
|
|
175
|
+
await Promise.all([
|
|
176
|
+
AsyncStorage.setItem('notiflyExternalUserId', params.external_user_id),
|
|
177
|
+
AsyncStorage.removeItem('notiflyUserId'),
|
|
178
|
+
]);
|
|
179
|
+
}
|
|
180
|
+
return await logEvent("set_user_properties", params, true);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async function logEvent(eventName, eventParams, isInternalEvent = false) {
|
|
184
|
+
try {
|
|
185
|
+
let token;
|
|
186
|
+
const [savedCognitoToken, notiflyUserId, externalUserId, prjId, externalDeviceId, osVersion, appVersion] = await Promise.all([
|
|
187
|
+
AsyncStorage.getItem('notiflyCognitoIdToken'),
|
|
188
|
+
_getNotiflyUserId(),
|
|
189
|
+
AsyncStorage.getItem('notiflyExternalUserId'),
|
|
190
|
+
AsyncStorage.getItem('notiflyProjectId'),
|
|
191
|
+
rnDeviceInfo.getUniqueId(),
|
|
192
|
+
rnDeviceInfo.getSystemVersion(),
|
|
193
|
+
rnDeviceInfo.getVersion(),
|
|
194
|
+
]);
|
|
195
|
+
|
|
196
|
+
const [eventId, notiflyDeviceId, deviceToken] = await Promise.all([
|
|
197
|
+
v5(`${notiflyUserId}${eventName}${new Date().valueOf()}`, NAMESPACE.EVENTID).replace(/-/g, ''),
|
|
198
|
+
v5(externalDeviceId, NAMESPACE.DEVICEID).replace(/-/g, ''),
|
|
199
|
+
messaging().getToken(),
|
|
200
|
+
]);
|
|
201
|
+
|
|
202
|
+
if (!savedCognitoToken) {
|
|
203
|
+
const [userName, password] = await Promise.all([AsyncStorage.getItem('notiflyUserName'), AsyncStorage.getItem('notiflyUserPassword')])
|
|
204
|
+
newToken = await getCognitoIdToken(userName, password);
|
|
205
|
+
await AsyncStorage.setItem("notiflyCognitoIdToken", newToken);
|
|
206
|
+
token = newToken;
|
|
207
|
+
} else {
|
|
208
|
+
token = savedCognitoToken;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (!token || !notiflyUserId || !prjId || !eventId || !externalDeviceId || !notiflyDeviceId || !deviceToken) {
|
|
212
|
+
throw new Error("null value");
|
|
213
|
+
}
|
|
214
|
+
const myHeaders = new Headers();
|
|
215
|
+
myHeaders.append("Authorization", token);
|
|
216
|
+
myHeaders.append("Content-Type", "application/json");
|
|
217
|
+
|
|
218
|
+
const eventDataWithoutExternalUserId = {
|
|
219
|
+
"event_params": eventParams,
|
|
220
|
+
"id": eventId,
|
|
221
|
+
"name": eventName,
|
|
222
|
+
"notifly_user_id": notiflyUserId,
|
|
223
|
+
"time": parseInt(new Date().valueOf() / 1000),
|
|
224
|
+
"notifly_device_id": notiflyDeviceId,
|
|
225
|
+
"external_device_id": externalDeviceId,
|
|
226
|
+
"device_token": deviceToken,
|
|
227
|
+
"is_internal_event": isInternalEvent,
|
|
228
|
+
"project_id": prjId,
|
|
229
|
+
"platform": Platform.OS,
|
|
230
|
+
"os_version": osVersion,
|
|
231
|
+
"app_version": appVersion,
|
|
232
|
+
}
|
|
233
|
+
const eventData = JSON.stringify(
|
|
234
|
+
externalUserId ?
|
|
235
|
+
{
|
|
236
|
+
...eventDataWithoutExternalUserId,
|
|
237
|
+
"external_user_id": externalUserId,
|
|
238
|
+
}
|
|
239
|
+
:
|
|
240
|
+
eventDataWithoutExternalUserId
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
const body = JSON.stringify({
|
|
244
|
+
"records": [{
|
|
245
|
+
"data": eventData,
|
|
246
|
+
"partitionKey": notiflyUserId,
|
|
247
|
+
}]
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
const requestOptions = {
|
|
251
|
+
method: 'POST',
|
|
252
|
+
headers: myHeaders,
|
|
253
|
+
body: body,
|
|
254
|
+
redirect: 'follow'
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const response = await _apiCall("https://12lnng07q2.execute-api.ap-northeast-2.amazonaws.com/prod/records", requestOptions);
|
|
258
|
+
const result = JSON.parse(response)
|
|
259
|
+
console.log(result)
|
|
260
|
+
if (result.message == "The incoming token has expired") {
|
|
261
|
+
const [userName, password] = await Promise.all([AsyncStorage.getItem('notiflyUserName'), AsyncStorage.getItem('notiflyUserPassword')])
|
|
262
|
+
const newToken = await getCognitoIdToken(userName, password);
|
|
263
|
+
await AsyncStorage.setItem("notiflyCognitoIdToken", newToken);
|
|
264
|
+
await logEvent(eventName, eventParams)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
} catch (err) {
|
|
268
|
+
console.log(err)
|
|
269
|
+
if (err == 'Error: null value') {
|
|
270
|
+
throw new Error("[Notifly] Fail to log the event.");
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
async function _apiCall(apiUrl, requestOptions) {
|
|
276
|
+
const result = fetch(apiUrl, requestOptions)
|
|
277
|
+
.then(response => response.text());
|
|
278
|
+
return result;
|
|
279
|
+
}
|
package/namespace.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "notifly-sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"peerDependencies": {
|
|
10
|
+
"@notifee/react-native": "^7.3.0",
|
|
11
|
+
"@react-native-async-storage/async-storage": "^1.17.11",
|
|
12
|
+
"@react-native-firebase/app": "^16.5.0",
|
|
13
|
+
"@react-native-firebase/messaging": "^16.5.0",
|
|
14
|
+
"react-native-device-info": "^10.3.0",
|
|
15
|
+
"uuid": "^9.0.0"
|
|
16
|
+
},
|
|
17
|
+
"author": "daeseongKim",
|
|
18
|
+
"license": "ISC",
|
|
19
|
+
"type": "module"
|
|
20
|
+
}
|