playov2-js-utilities 0.2.7 → 0.3.1-6.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/lib/constants.js CHANGED
@@ -12,7 +12,10 @@ const RATINGS_WEIGHTAGE = Object.freeze({
12
12
  'old': 0.1
13
13
  });
14
14
 
15
+ const DEFAULT_TIME_ZONE = 'Asia/Kolkata';
16
+
15
17
  module.exports = {
16
18
  USER_INDIVIDUAL_RATINGS,
17
- RATINGS_WEIGHTAGE
19
+ RATINGS_WEIGHTAGE,
20
+ DEFAULT_TIME_ZONE
18
21
  }
package/lib/cron.js ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * This file will have all cron related utilities - (e.g. - schedulers etc.).
3
+ * Try to contain service common utilities here.
4
+ */
5
+ const Constants = require('./constants');
6
+ const { CronJob } = require('cron');
7
+ const Utils = require('./util')
8
+
9
+ const cronner = (
10
+ cronTime,
11
+ onTime = Utils.noop,
12
+ onComplete = Utils.noop,
13
+ timeZone = Constants.DEFAULT_TIME_ZONE,
14
+ context = this,
15
+ runOnInit,
16
+ utcOffset,
17
+ ) => {
18
+ const job = new CronJob({
19
+ cronTime,
20
+ // when the time specified by pattern is matched
21
+ onTick: onTime,
22
+ // onComplete
23
+ onComplete,
24
+ // whether the cron should start on constructor invoke (or whether .start() needs to be called)
25
+ start: false,
26
+ // timezone -> defaults to Asia/Kolkata
27
+ timeZone,
28
+ // the context to bind the onTime method to
29
+ context,
30
+ // flat to start cron on invocation of the module
31
+ runOnInit,
32
+ // the utc offset to run the cron at
33
+ utcOffset
34
+ });
35
+ job.start();
36
+ return job;
37
+ };
38
+
39
+ module.exports = {
40
+ cronner
41
+ };
42
+
43
+
package/lib/index.js CHANGED
@@ -1,7 +1,14 @@
1
1
 
2
+ /*
3
+ * Naming terminology - While exporting constants use PascalCase while exporting functions/methods use camelCase
4
+ */
2
5
  module.exports = {
3
- ratings : require('./ratings/index'),
4
- constants : require('./constants'),
5
- playoUtils : require('./util'),
6
- NotificationTemplates : require('./notification-templates')
6
+ ratings: require('./ratings/index'),
7
+ Constants: require('./constants'),
8
+ playoUtils: require('./util'),
9
+ NotificationTemplates: require('./notification-templates'),
10
+ NotificationConfig: require('./notification.config'),
11
+ httpRequest: require('./request'),
12
+ Cron: require('./cron'),
13
+ MessagePublisher: require('./message_publisher')
7
14
  };
@@ -0,0 +1,93 @@
1
+ /*
2
+ Read this and associated queue configs before deploying a new queue
3
+ https://cloud.google.com/tasks/docs/reference/rest/v2beta3/projects.locations.queues.tasks#resource:-task
4
+ */
5
+
6
+ const { CloudTasksClient } = require('@google-cloud/tasks');
7
+ const { v4: uuidv4 } = require('uuid');
8
+
9
+ const PLAYO_LOGGER = require("@playo/logger");
10
+ const LOGGER = new PLAYO_LOGGER("playo-message-publisher");
11
+
12
+ const client = new CloudTasksClient();
13
+
14
+ const PROJECT = process.env.GCP_PROJECT;
15
+ const LOCATION = process.env.GCP_LOCATION;
16
+
17
+ if (!PROJECT || !LOCATION) {
18
+ console.warn('You need to pass - GCP_PROJECT, GCP_LOCATION in env for message queue to work!');
19
+ }
20
+ /**
21
+ *
22
+ * @param {String} queueId - Name of the queue being targeted
23
+ * @param {Object} payload - {
24
+ * httpMethod: String <POST, GET, PUT>
25
+ * url: String,
26
+ * headers: Object,
27
+ * body: Object, // not needed if GET request
28
+ * ttl: Optional, date in utc format, consumer will check if the ttl has been exceeded or not and then will respond accordingly
29
+ * ...
30
+ *
31
+ * }
32
+ * @param {Object} messageProcessingProperties - {
33
+ * delay
34
+ * }
35
+ * @param {String} taskId -used as de-duplication key
36
+ * @param {String} requestId
37
+ */
38
+ async function createHttpTask(queueId, payload, messageProcessingProperties, taskId, requestId) {
39
+
40
+ try {
41
+ const project = PROJECT;
42
+ const queue = queueId;
43
+ const location = LOCATION;
44
+
45
+ const { delay = 0 } = messageProcessingProperties
46
+
47
+ const parent = client.queuePath(project, location, queue);
48
+
49
+ const task = {
50
+ httpRequest: payload,
51
+ name: ''
52
+ };
53
+
54
+ task.name = getTaskId(project, location, queue, taskId);
55
+
56
+ if (payload.body) {
57
+ task.httpRequest.body = Buffer.from(payload.body).toString('base64');
58
+ }
59
+
60
+ if (delay) {
61
+ // The time when the task is scheduled to be attempted.
62
+ task.scheduleTime = {
63
+ seconds: delay + Date.now() / 1000,
64
+ };
65
+ };
66
+
67
+ LOGGER.info(requestId, task, `Sending task to queue ${queueId}}`)
68
+
69
+ const request = { parent: parent, task: task };
70
+ const [response] = await client.createTask(request);
71
+
72
+ LOGGER.info(requestId, { name: response.name, response }, `Added task to queue ${queueId}}`)
73
+ } catch (err) {
74
+ LOGGER.error(requestId, err, err.message)
75
+ }
76
+ };
77
+
78
+ /**
79
+ * Returns a unique string for name of a task in task queues, to be used for task de-duplication purpose.
80
+ * @param {String} projectId
81
+ * @param {String} locationId
82
+ * @param {String} queueId
83
+ * @param {String} taskId
84
+ * @returns {String}
85
+ */
86
+ const getTaskId = (projectId, locationId, queueId, taskId = uuidv4()) => {
87
+ return `projects/${projectId}/locations/${locationId}/queues/${queueId}/tasks/${taskId}`;
88
+ };
89
+
90
+ module.exports = {
91
+ createHttpTask,
92
+ getTaskId
93
+ };
@@ -39,10 +39,10 @@ const host_response_to_query = {
39
39
  * @param {String} date - Activity's date
40
40
  */
41
41
  const activity_join_request = {
42
- heading: 'You have a new game request! 🙌',
42
+ heading: 'New game request! 🙌',
43
43
  text: '{{user_first_name}} has requested to join your {{sport_name}} game happening on {{date}}.',
44
44
  additional_message_text: {
45
- text: 'They have a message for you! Tap to read',
45
+ text: 'They have a message for you! Tap to read.',
46
46
  default: 'Let them know if you\'re game.'
47
47
  },
48
48
  buttons: [],
@@ -58,7 +58,7 @@ const activity_join_request = {
58
58
  * @param {String} date - Activity's date
59
59
  */
60
60
  const activity_request_accepted = {
61
- heading: '{{host_first_name}} has accepted your request! 🥳',
61
+ heading: 'Request accepted! 🥳',
62
62
  text: 'You\'re on for the {{sport_name}} game on {{date}}. You can now chat with your game squad.',
63
63
  buttons: [],
64
64
  notificationId: notificationIds.ACTIVITY_REQUEST_RESPONSE
@@ -73,11 +73,11 @@ const activity_request_accepted = {
73
73
  * @param {String} date - Activity's date
74
74
  */
75
75
  const activity_request_declined = {
76
- heading: 'Your request has been declined. 😟',
76
+ heading: 'Request declined. 😟',
77
77
  text: '{{host_first_name}} declined your request to join the {{sport_name}} game on {{date}}.',
78
78
  additional_message_text: {
79
- text: 'They have a message for you! Tap to read',
80
- default: 'No worries, other games are waiting for you to join! Join them now. 😀'
79
+ text: 'They have a message for you! Tap to read.',
80
+ default: 'No worries, other games are waiting for you! Join them now. 😀'
81
81
  },
82
82
  buttons: [],
83
83
  notificationId: notificationIds.HOST_RETIRED
@@ -92,7 +92,7 @@ const activity_request_declined = {
92
92
  * @param {String} date - Activity's date
93
93
  */
94
94
  const user_invited_by_host = {
95
- heading: 'You have a new invite! 📩',
95
+ heading: 'New game invite! 📩',
96
96
  text: '{{host_first_name}} has invited you to the {{sport_name}} game on {{date}}. Are you game? 💪',
97
97
  buttons: [],
98
98
  notificationId: notificationIds.ACTIVITY_INVITATION
@@ -107,8 +107,8 @@ const user_invited_by_host = {
107
107
  * @param {String} date - Activity's date
108
108
  */
109
109
  const user_accepted_invite = {
110
- heading: 'Your invite has been accepted! 🤝',
111
- text: '{{user_first_name}} has accepted your request for the {{sport_name}} game on {{date}}.',
110
+ heading: 'Game invite accepted! 🤝',
111
+ text: '{{user_first_name}} has accepted your invite for the {{sport_name}} game on {{date}}.',
112
112
  buttons: [],
113
113
  notificationId: notificationIds.ACTIVITY_INVITATION_RESPONSE
114
114
  };
@@ -122,11 +122,11 @@ const user_accepted_invite = {
122
122
  * @param {String} date - Activity's date
123
123
  */
124
124
  const user_declined_invite = {
125
- heading: 'Your invite has been declined. 😟',
126
- text: '{{user_first_name}} has declined your request for the {{sport_name}} game on {{date}}.',
125
+ heading: 'Game invite declined. 😟',
126
+ text: '{{user_first_name}} has declined your invite for the {{sport_name}} game on {{date}}.',
127
127
  additional_message_text: {
128
- text: 'They have a message for you! Tap to read',
129
- default: ''
128
+ text: 'They have a message for you! Tap to read.',
129
+ default: 'Tap to invite other players.'
130
130
  },
131
131
  buttons: [],
132
132
  notificationId: notificationIds.HOST_RETIRED
@@ -141,10 +141,10 @@ const user_declined_invite = {
141
141
  * @param {String} date - Activity's date
142
142
  */
143
143
  const host_revoked_invite = {
144
- heading: 'Your invite has been cancelled 😕 ',
144
+ heading: 'Game invite cancelled 😕',
145
145
  text: '{{host_first_name}} has cancelled your invitation to the {{sport_name}} game on {{date}}.',
146
146
  additional_message_text: {
147
- text: 'They have a message for you! Tap to read',
147
+ text: 'They have a message for you! Tap to read.',
148
148
  default: 'But, you can always join another game!'
149
149
  },
150
150
  buttons: [],
@@ -160,7 +160,7 @@ const host_revoked_invite = {
160
160
  * @param {String} date - Activity's date
161
161
  */
162
162
  const host_retired_user = {
163
- heading: 'You have been made to retire. 😕 ',
163
+ heading: 'You have been made to retire.😕',
164
164
  text: 'You are no longer a part of {{sport_name}} game on {{date}}.',
165
165
  additional_message_text: {
166
166
  text: '{{host_first_name}} has a message for you! Tap to read',
@@ -182,8 +182,8 @@ const user_left_game = {
182
182
  heading: 'Player has left the game.',
183
183
  text: '{{user_first_name}} has left {{date}}\'s {{sport_name}} game.',
184
184
  additional_message_text: {
185
- text: '{{user_first_name}} has a message for you! Tap to read',
186
- default: ''
185
+ text: 'They have a message for you! Tap to read.',
186
+ default: 'Tap to invite other players.'
187
187
  },
188
188
  buttons: [],
189
189
  notificationId: notificationIds.HOST_RETIRED
@@ -204,6 +204,20 @@ const host_cancelled_activity = {
204
204
  notificationId: notificationIds.ACTIVITY_CANCEL
205
205
  };
206
206
 
207
+ /**
208
+ * Template for sending activity reminder.
209
+ * Notification is received by all the players of the activity.
210
+ * Text render only
211
+ * @param {String} sport_name
212
+ * @param {String} date
213
+ */
214
+ const activity_reminder = {
215
+ heading: 'Activity Reminder',
216
+ text: 'You have a {{sport_name}} game coming up at {{date}}. Gear up for some fun!',
217
+ buttons: [],
218
+ notificationId: notificationIds.ACTIVITY_REMINDER
219
+ };
220
+
207
221
  const host_updated_activity_details = {
208
222
  // ??
209
223
  };
@@ -228,5 +242,6 @@ module.exports = {
228
242
  host_revoked_invite,
229
243
  host_retired_user,
230
244
  user_left_game,
231
- host_cancelled_activity
245
+ host_cancelled_activity,
246
+ activity_reminder
232
247
  }
@@ -2,37 +2,51 @@
2
2
  //\-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_- Private -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-\//
3
3
  const notificationCategories = {
4
4
  GROUP: 'group',
5
- ACTIVITY: 'activity'
5
+ ACTIVITY: 'activity',
6
+ KARMA: 'karma',
7
+ SPLIT_PAYMENTS: 'split_payments'
6
8
  };
7
9
 
8
10
  // Android notification channels will be bound to categories
9
11
  const notificationChannels = {
10
- [notificationCategories.ACTIVITY]: '9704a3d8-e86a-4bd5-9141-cd50972f3d4f'
11
- };
12
-
13
- const notificationButtons = {
14
- [notificationIds.ACTIVITY_NOTIFY_PUSH]: []
12
+ 'karma': '8a9c67b9-1cdc-46a2-bb90-6f00f0e848eb', // done - 1 notification tagged
13
+ 'activity_query': '99863ba1-88ba-44f6-b8b3-6df51d97ae03', // done - 2 notifications tagged
14
+ 'activity_player_in_out': '5e6c5f64-1413-46ed-829d-763a3b7cab22',
15
+ 'activity_updates': '14d7a740-2da3-4bb5-888f-80ed487d6567',// done - 8 notifications tagged
16
+ 'activity_post_game': '23131b6a-2cf0-4a34-bc78-dd6f8676e319', // done - 1 notification tagged
17
+ 'activity_suggestions': '3ab98c37-b93c-4d39-ab55-bb2cc6279cb8', // done - 1 notifications tagged
18
+ 'expenses': '1eb30f33-2b3b-40ce-8798-fce55c1275e2', // done - 6 notifications tagged
19
+ 'groups_manage_requests': '83c024d1-2cb7-47fa-989d-1d8ef343a51c', // done - 6 notifications tagged
20
+ 'group_updates': '9e023a20-deab-4bc4-bd33-08a8d9316322', // done - 3 notifications tagged
21
+ 'activity_reminders': '53c55399-a73c-4800-b824-3c750ac57b98'
15
22
  };
16
23
 
17
24
  // ------------------------------------------ Exported (public) -----------------------------------------//
18
25
 
19
26
  const notificationIds = {
20
- ACTIVITY_NOTIFY_PUSH: 'activity-notify-push',
21
- ACTIVITY_NOTIFY_DRAWER: 'activity-notify-drawer',
27
+ ACTIVITY_NOTIFY_PUSH: 'activity-notify-push', // > DEPRECATED
28
+ ACTIVITY_NOTIFY_DRAWER: 'activity-notify-drawer', // > DEPRECATED
29
+ ACTIVITY_NOTIFY: 'activity-notify',
22
30
  GROUP_INVITATION: 'group-invitation',
23
- GROUP_INVITATION_RESPONSE_PUSH: 'group-invitation-response-push',
24
- GROUP_INVITATION_RESPONSE_DRAWER: 'group-invitation-response-drawer',
25
- GROUP_REQUEST_PUSH: 'group-request-push',
26
- GROUP_REQUEST_DRAWER: 'group-request-drawer',
31
+ GROUP_INVITATION_RESPONSE: 'group-invitation-response',
32
+ GROUP_INVITATION_RESPONSE_PUSH: 'group-invitation-response-push', // > DEPRECATED
33
+ GROUP_INVITATION_RESPONSE_DRAWER: 'group-invitation-response-drawer', // > DEPRECATED
34
+ GROUP_REQUEST_PUSH: 'group-request-push', // > DEPRECATED
35
+ GROUP_REQUEST_DRAWER: 'group-request-drawer', // > DEPRECATED
36
+ GROUP_REQUEST: 'group-request',
27
37
  GROUP_REQUEST_RESPONSE: 'group-request-response',
28
- GROUP_NAME_PUSH: 'group-name-push',
29
- GROUP_NAME_DRAWER: 'group-name-drawer',
30
- ADMIN_STATUS_PUSH: 'admin-status-push',
31
- ADMIN_STATUS_DRAWER: 'admin-status-drawer',
32
- NEW_MESSAGE_PUSH: 'new-message-push',
33
- NEW_MESSAGE_DRAWER: 'new-message-drawer',
34
- NEW_COMMENT_PUSH: 'new-comment-push',
35
- NEW_COMMENT_DRAWER: 'new-comment-drawer',
38
+ GROUP_NAME: 'group-name',
39
+ GROUP_NAME_PUSH: 'group-name-push', // > DEPRECATED
40
+ GROUP_NAME_DRAWER: 'group-name-drawer', // > DEPRECATED
41
+ ADMIN_STATUS: 'admin-status',
42
+ ADMIN_STATUS_PUSH: 'admin-status-push', // > DEPRECATED
43
+ ADMIN_STATUS_DRAWER: 'admin-status-drawer',// > DEPRECATED
44
+ NEW_MESSAGE_PUSH: 'new-message-push', // > DEPRECATED
45
+ NEW_MESSAGE_DRAWER: 'new-message-drawer', // > DEPRECATED
46
+ NEW_MESSAGE: 'new-message',
47
+ NEW_COMMENT_PUSH: 'new-comment-push', // > DEPRECATED
48
+ NEW_COMMENT_DRAWER: 'new-comment-drawer', // > DEPRECATED
49
+ NEW_COMMENT: 'new-comment',
36
50
  ACTIVITY_INVITATION: 'activity-invitation',
37
51
  ACTIVITY_INVITATION_RESPONSE: 'activity-invitation-response',
38
52
  ACTIVITY_REQUEST: 'activity-request',
@@ -65,331 +79,374 @@ const notificationIds = {
65
79
  SPLIT_EXPENSE_DELETED: 'split-expense-deleted',
66
80
  HOST_ACTIVITY_PAYOUT: 'host-activity-payout',
67
81
  KARMA_CASHBACK: 'karma-cashback',
68
- ACTIVITY_QUERY_ANSWERED: 'activity-query-answered'
82
+ ACTIVITY_QUERY_ANSWERED: 'activity-query-answered',
83
+ ACTIVITY_REMINDER: 'activity-reminder'
69
84
  };
70
85
 
86
+ // TODO - Check targets against current value
87
+
71
88
  const config = {
72
- [notificationIds.ACTIVITY_NOTIFY_PUSH]: {
73
- category: notificationCategories,
74
- target: "group",
75
- path: "timeline",
76
- title: "Group Update",
77
- type: ["push"],
78
- channel: notificationChannels[notificationCategories.ACTIVITY],
79
- buttons: []
80
- },
81
- [notificationIds.ACTIVITY_NOTIFY_DRAWER]: {
89
+ [notificationIds.ACTIVITY_NOTIFY]: {
82
90
  category: notificationCategories.GROUP,
83
91
  target: "group",
84
92
  path: "timeline",
85
93
  title: "Group Update",
86
- type: ["drawer"]
94
+ type: ["drawer", "push"],
95
+ buttons: [],
96
+ android_channel_id: notificationChannels.activity_suggestions
87
97
  },
88
98
  [notificationIds.GROUP_INVITATION]: {
89
99
  category: notificationCategories.GROUP,
90
100
  target: "group",
91
101
  path: "manage",
92
102
  title: "Group Invitation",
93
- type: ["push"]
94
- },
95
- [notificationIds.GROUP_INVITATION_RESPONSE_PUSH]: {
96
- category: notificationCategories.GROUP,
97
- target: "group",
98
- path: "manage",
99
- title: "Group Update",
100
- type: ["push"]
101
- },
102
- [notificationIds.GROUP_INVITATION_RESPONSE_DRAWER]: {
103
- category: notificationCategories.GROUP,
104
- target: "group",
105
- path: "manage",
106
- title: "Group Update",
107
- type: ["drawer"]
103
+ type: ["push"],
104
+ buttons: [],
105
+ android_channel_id: notificationChannels.groups_manage_requests
108
106
  },
109
- [notificationIds.GROUP_REQUEST_PUSH]: {
107
+ [notificationIds.GROUP_INVITATION_RESPONSE]: {
110
108
  category: notificationCategories.GROUP,
111
109
  target: "group",
112
110
  path: "manage",
113
111
  title: "Group Update",
114
- type: ["push"]
112
+ type: ["push", "drawer"],
113
+ buttons: [],
114
+ android_channel_id: notificationChannels.groups_manage_requests
115
115
  },
116
- [notificationIds.GROUP_REQUEST_DRAWER]: {
116
+ [notificationIds.GROUP_REQUEST]: {
117
117
  category: notificationCategories.GROUP,
118
118
  target: "group",
119
119
  path: "manage",
120
120
  title: "Group Update",
121
- type: ["drawer"]
121
+ type: ["push", "drawer"],
122
+ buttons: [],
123
+ android_channel_id: notificationChannels.groups_manage_requests
122
124
  },
123
125
  [notificationIds.GROUP_REQUEST_RESPONSE]: {
124
126
  category: notificationCategories.GROUP,
125
127
  target: "group",
126
128
  path: "manage",
127
129
  title: "Group Update",
128
- type: ["push", "drawer"]
129
- },
130
- [notificationIds.GROUP_NAME_PUSH]: {
131
- category: notificationCategories.GROUP,
132
- target: "group",
133
- path: "manage",
134
- title: "Group Update",
135
- type: ["push"]
136
- },
137
- [notificationIds.GROUP_NAME_DRAWER]: {
138
- category: notificationCategories.GROUP,
139
- target: "group",
140
- path: "manage",
141
- title: "Group Update",
142
- type: ["drawer"]
130
+ type: ["push", "drawer"],
131
+ buttons: [],
132
+ android_channel_id: notificationChannels.groups_manage_requests
143
133
  },
144
- [notificationIds.ADMIN_STATUS_PUSH]: {
134
+ [notificationIds.GROUP_NAME]: {
145
135
  category: notificationCategories.GROUP,
146
136
  target: "group",
147
137
  path: "manage",
148
138
  title: "Group Update",
149
- type: ["push"]
139
+ type: ["push", "drawer"],
140
+ buttons: [],
141
+ android_channel_id: notificationChannels.group_updates
150
142
  },
151
- [notificationIds.ADMIN_STATUS_DRAWER]: {
143
+ [notificationIds.ADMIN_STATUS]: {
152
144
  category: notificationCategories.GROUP,
153
145
  target: "group",
154
146
  path: "manage",
155
147
  title: "Group Update",
156
- type: ["drawer"]
148
+ type: ["drawer", "push"],
149
+ buttons: [],
150
+ android_channel_id: notificationChannels.group_updates
157
151
  },
158
- [notificationIds.NEW_MESSAGE_PUSH]: {
152
+ [notificationIds.NEW_MESSAGE]: {
159
153
  category: notificationCategories.GROUP,
160
154
  target: "group",
161
155
  path: "board",
162
156
  title: "Group Update",
163
- type: ["push"]
157
+ type: ["push", "drawer"],
158
+ buttons: [],
159
+ android_channel_id: notificationChannels.group_updates
164
160
  },
165
- [notificationIds.NEW_COMMENT_DRAWER]: {
161
+ [notificationIds.NEW_COMMENT]: {
166
162
  category: notificationCategories.GROUP,
167
163
  target: "group",
168
164
  path: "board",
169
165
  title: "Group Update",
170
- type: ["drawer"]
171
- },
172
- [notificationIds.NEW_COMMENT_PUSH]: {
173
- category: notificationCategories.GROUP,
174
- target: "group",
175
- path: "message",
176
- title: "Group Update",
177
- type: ["push"]
178
- },
179
- [notificationIds.NEW_COMMENT_DRAWER]: {
180
- category: notificationCategories.GROUP,
181
- target: "group",
182
- path: "message",
183
- title: "Group Update",
184
- type: ["drawer"]
166
+ type: ["drawer","push"],
167
+ buttons: [],
168
+ android_channel_id: notificationChannels.group_updates
185
169
  },
186
170
  [notificationIds.ACTIVITY_INVITATION]: {
187
171
  category: notificationCategories.ACTIVITY,
188
172
  target: "match",
189
173
  title: "You've been invited to a game! 📩",
190
174
  type: ["push", "drawer"],
191
- ios_attachments: {
192
- "mediaUrl": "https://playov2.imgix.net/marketing/squid-game-notification02.jpg"
193
- },
194
- big_picture: "https://playov2.imgix.net/marketing/squid-game-notification02.jpg"
195
-
175
+ buttons: [],
176
+ android_channel_id: notificationChannels.activity_player_in_out
196
177
  },
197
178
  [notificationIds.ACTIVITY_INVITATION_RESPONSE]: {
198
179
  category: notificationCategories.ACTIVITY,
199
180
  target: "match",
200
181
  path: "manage",
201
182
  title: "Activity Update",
202
- type: ["push", "drawer"]
183
+ type: ["push", "drawer"],
184
+ buttons: [],
185
+ android_channel_id: notificationChannels.activity_player_in_out
203
186
  },
204
187
  [notificationIds.ACTIVITY_REQUEST]: {
205
188
  category: notificationCategories.ACTIVITY,
206
189
  target: "match",
207
190
  title: "Activity Update",
208
- type: ["push", "drawer"]
191
+ type: ["push", "drawer"],
192
+ buttons: [],
193
+ android_channel_id: notificationChannels.activity_player_in_out
209
194
  },
210
195
  [notificationIds.ACTIVITY_REQUEST_RESPONSE]: {
211
196
  category: notificationCategories.ACTIVITY,
212
197
  target: "match",
213
198
  title: "Activity Update",
214
- type: ["push", "drawer"]
199
+ type: ["push", "drawer"],
200
+ buttons: [],
201
+ android_channel_id: notificationChannels.activity_player_in_out
215
202
  },
216
203
  [notificationIds.HOST_RETIRED]: {
217
204
  category: notificationCategories.ACTIVITY,
218
205
  target: "match",
219
206
  title: "Activity Update",
220
- type: ["push", "drawer"]
207
+ type: ["push", "drawer"],
208
+ buttons: [],
209
+ android_channel_id: notificationChannels.activity_player_in_out
221
210
  },
222
211
  [notificationIds.EDIT_ACTIVITY]: {
223
212
  category: notificationCategories.ACTIVITY,
224
213
  target: "match",
225
214
  title: "Activity Update",
226
- type: ["push", "drawer"]
215
+ type: ["push", "drawer"],
216
+ buttons: [],
217
+ android_channel_id: notificationChannels.activity_updates
227
218
  },
228
219
  [notificationIds.ACTIVITY_FULL]: {
229
220
  category: notificationCategories.ACTIVITY,
230
221
  target: "match",
231
222
  path: "manage",
232
223
  title: "Activity Update",
233
- type: ["push", "drawer"]
224
+ type: ["push", "drawer"],
225
+ buttons: [],
226
+ android_channel_id: notificationChannels.activity_updates
234
227
  },
235
228
  [notificationIds.VENUE_TAGGED]: {
236
229
  category: notificationCategories.ACTIVITY,
237
230
  target: "match",
238
231
  title: "Activity Update",
239
- type: ["push", "drawer"]
232
+ type: ["push", "drawer"],
233
+ buttons: [],
234
+ android_channel_id: notificationChannels.activity_updates
240
235
  },
241
236
  [notificationIds.VENUE_BOOKED]: {
242
237
  category: notificationCategories.ACTIVITY,
243
238
  target: "match",
244
239
  title: "Activity Update",
245
- type: ["push", "drawer"]
240
+ type: ["push", "drawer"],
241
+ buttons: [],
242
+ android_channel_id: notificationChannels.activity_updates
246
243
  },
247
244
  [notificationIds.BOOKING_CANCELLED]: {
248
245
  category: notificationCategories.ACTIVITY,
249
246
  target: "match",
250
247
  title: "Activity Update",
251
- type: ["push", "drawer"]
248
+ type: ["push", "drawer"],
249
+ buttons: [],
250
+ android_channel_id: notificationChannels.activity_updates
252
251
  },
253
252
  [notificationIds.COHOST_ADDED]: {
254
253
  category: notificationCategories.ACTIVITY,
255
254
  target: "match",
256
255
  title: "Activity Update",
257
- type: ["push", "drawer"]
256
+ type: ["push", "drawer"],
257
+ buttons: [],
258
+ android_channel_id: notificationChannels.activity_updates
258
259
  },
259
260
  [notificationIds.COHOST_DELETED]: {
260
261
  category: notificationCategories.ACTIVITY,
261
262
  target: "match",
262
263
  title: "Activity Update",
263
- type: ["push", "drawer"]
264
+ type: ["push", "drawer"],
265
+ buttons: [],
266
+ android_channel_id: notificationChannels.activity_updates
264
267
  },
265
268
  [notificationIds.ACTIVITY_QUERY]: {
266
269
  category: notificationCategories.ACTIVITY,
267
270
  target: "match",
268
271
  title: "Activity Update",
269
- type: ["push", "drawer"]
272
+ type: ["push", "drawer"],
273
+ buttons: [],
274
+ android_channel_id: notificationChannels.activity_query
270
275
  },
271
276
  [notificationIds.ACTIVITY_CANCEL]: {
272
277
  category: notificationCategories.ACTIVITY,
273
278
  target: "match",
274
279
  title: "Activity Update",
275
- type: ["push", "drawer"]
280
+ type: ["push", "drawer"],
281
+ buttons: [],
282
+ android_channel_id: notificationChannels.activity_updates
276
283
  },
277
284
  [notificationIds.ACTIVITY_REMINDER]: {
278
285
  category: notificationCategories.ACTIVITY,
279
286
  target: "match",
280
287
  title: "Activity Reminder",
281
- type: ["push"]
288
+ type: ["push"],
289
+ buttons: [],
290
+ android_channel_id: notificationChannels.activity_player_in_out
282
291
  },
283
292
  [notificationIds.ACTIVITY_HOSTED]: {
284
293
  category: "playpal-activity",
285
294
  target: "match",
286
295
  title: "Activity Update",
287
- type: ["push", "drawer"]
296
+ type: ["push", "drawer"],
297
+ buttons: [],
298
+ android_channel_id: notificationChannels.activity_suggestions
288
299
  },
289
300
  [notificationIds.ACTIVITY_REQUEST_MANAGE]: {
290
301
  category: notificationCategories.ACTIVITY,
291
302
  target: "match",
292
303
  path: "manage",
293
304
  title: "Activity Update",
294
- type: ["push", "drawer"]
305
+ type: ["push", "drawer"],
306
+ buttons: [],
307
+ android_channel_id: notificationChannels.activity_player_in_out
295
308
  },
296
309
  [notificationIds.ACTIVITY_JOINED]: {
297
310
  category: notificationCategories.ACTIVITY,
298
311
  target: "match",
299
312
  title: "Activity Update",
300
- type: ["push", "drawer"]
313
+ type: ["push", "drawer"],
314
+ buttons: [],
315
+ android_channel_id: notificationChannels.activity_player_in_out
301
316
  },
302
317
  [notificationIds.MATCH_RATING]: {
303
318
  category: notificationCategories.ACTIVITY,
304
319
  target: "match",
305
320
  path: "gamebook",
306
321
  title: "Rate Activity",
307
- type: ["push", "drawer"]
322
+ type: ["push", "drawer"],
323
+ buttons: [],
324
+ android_channel_id: notificationChannels.activity_post_game
308
325
  },
309
326
  [notificationIds.BOOKING_RECEIPT]: {
310
327
  category: notificationCategories.ACTIVITY,
311
328
  target: "booking",
312
329
  title: "Booking Update",
313
- type: ["push", "drawer"]
330
+ type: ["push", "drawer"],
331
+ buttons: [],
332
+ android_channel_id: ''
314
333
  },
315
334
  [notificationIds.LOUNGE_QUESTION_SUGGEST]: {
316
335
  category: "lounge",
317
336
  target: "lounge/question",
318
337
  title: "Community Update",
319
- type: ["push"]
338
+ type: ["push"],
339
+ buttons: [],
340
+ android_channel_id: ''
320
341
  },
321
342
  [notificationIds.LOUNGE_ANSWER]: {
322
343
  category: "lounge",
323
344
  target: "lounge/answer",
324
345
  title: "Community Update",
325
- type: ["push", "drawer"]
346
+ type: ["push", "drawer"],
347
+ buttons: [],
348
+ android_channel_id: ''
326
349
  },
327
350
  [notificationIds.LOUNGE_COMMENT]: {
328
351
  category: "lounge",
329
352
  target: "lounge/answer",
330
353
  title: "Community Update",
331
- type: ["push", "drawer"]
354
+ type: ["push", "drawer"],
355
+ buttons: [],
356
+ android_channel_id: ''
332
357
  },
333
358
  [notificationIds.LOUNGE_QUESTION_APPROVED]: {
334
359
  category: "lounge",
335
360
  target: "lounge/question",
336
361
  title: "Community Update",
337
- type: ["push", "drawer"]
362
+ type: ["push", "drawer"],
363
+ buttons: [],
364
+ android_channel_id: ''
338
365
  },
339
366
  [notificationIds.SPLIT_MARK_PAID]: {
340
367
  category: notificationCategories.ACTIVITY,
341
368
  target: "activity/logs",
342
369
  title: "Expense Update",
343
- type: ["push", "drawer"]
370
+ type: ["push", "drawer"],
371
+ buttons: [],
372
+ android_channel_id: notificationChannels.expenses
344
373
  },
345
374
  [notificationIds.SPLIT_REVERT_SETTLEMENT]: {
346
375
  category: notificationCategories.ACTIVITY,
347
376
  target: "activity/logs",
348
377
  title: "Expense Update",
349
- type: ["push", "drawer"]
378
+ type: ["push", "drawer"],
379
+ buttons: [],
380
+ android_channel_id: notificationChannels.expenses
350
381
  },
351
382
  [notificationIds.SPLIT_EXPENSE_COMMENT]: {
352
383
  category: notificationCategories.ACTIVITY,
353
384
  target: "activity/expenses/comments",
354
385
  title: "Expense Update",
355
- type: ["push", "drawer"]
386
+ type: ["push", "drawer"],
387
+ buttons: [],
388
+ android_channel_id: notificationChannels.expenses
356
389
  },
357
390
  [notificationIds.SPLIT_EXPENSE_ADDED]: {
358
391
  category: notificationCategories.ACTIVITY,
359
392
  target: "activity/expenses",
360
393
  title: "Expense Update",
361
- type: ["push", "drawer"]
394
+ type: ["push", "drawer"],
395
+ buttons: [],
396
+ android_channel_id: notificationChannels.expenses
362
397
  },
363
398
  [notificationIds.SPLIT_EXPENSE_EDITED]: {
364
399
  category: notificationCategories.ACTIVITY,
365
400
  target: "activity/expenses",
366
401
  title: "Expense Update",
367
- type: ["push", "drawer"]
402
+ type: ["push", "drawer"],
403
+ buttons: [],
404
+ android_channel_id: notificationChannels.expenses
368
405
  },
369
406
  [notificationIds.SPLIT_EXPENSE_DELETED]: {
370
407
  category: notificationCategories.ACTIVITY,
371
408
  target: "activity/logs",
372
409
  title: "Expense Update",
373
- type: ["push", "drawer"]
410
+ type: ["push", "drawer"],
411
+ buttons: [],
412
+ android_channel_id: notificationChannels.expenses
374
413
  },
375
414
  [notificationIds.HOST_ACTIVITY_PAYOUT]: {
376
415
  category: notificationCategories.ACTIVITY,
377
416
  target: "playocredits",
378
417
  title: "Activity Update",
379
- type: ["push", "drawer"]
418
+ type: ["push", "drawer"],
419
+ buttons: [],
420
+ android_channel_id: ''
380
421
  },
381
422
  [notificationIds.KARMA_CASHBACK]: {
382
423
  category: notificationCategories.ACTIVITY,
383
424
  target: "passbook",
384
425
  title: "Karma Update",
385
- type: ["push", "drawer"]
426
+ type: ["push", "drawer"],
427
+ android_channel_id: notificationChannels.karma,
428
+ buttons: []
386
429
  },
387
430
  [notificationIds.ACTIVITY_QUERY_ANSWERED]: {
388
431
  category: notificationCategories.ACTIVITY,
389
432
  target: "match",
390
433
  title: "Activity Update",
391
- type: ["push", "drawer"]
434
+ type: ["push", "drawer"],
435
+ buttons: [],
436
+ android_channel_id: notificationChannels.activity_query
437
+ },
438
+ [notificationIds.ACTIVITY_REMINDER] : {
439
+ category: notificationCategories.ACTIVITY,
440
+ target: "match",
441
+ title: "Activity Reminder",
442
+ type: ["push"],
443
+ buttons: [],
444
+ android_channel_id: notificationChannels.activity_reminders
392
445
  }
393
446
  };
394
447
 
448
+ const notificationButtons = {
449
+ [notificationIds.ACTIVITY_NOTIFY_PUSH]: []
450
+ };
451
+
395
452
  module.exports = { config, notificationIds };
@@ -77,7 +77,7 @@ const getUserAverageRatingForASport = (currentAvg, prevAvg) => {
77
77
  let oldAvg = prevAvg ? prevAvg * Constants.RATINGS_WEIGHTAGE.old : 0;
78
78
 
79
79
  // If for any reason any player doesn't have any old rating/ new rating, send back both ratings with 100% weightage (as one of them will be zero)
80
- if (!prevAvg || !currentAvg) {
80
+ if (!prevAvg || !currentAvg) {
81
81
  latest25Avg = currentAvg;
82
82
  oldAvg = prevAvg;
83
83
  }
package/lib/request.js ADDED
@@ -0,0 +1,136 @@
1
+ const Axios = require('axios');
2
+ const TIMEOUT_DURATION = 10 * 1000 // milliseconds, used as default
3
+ const PLAYO_LOGGER = require("@playo/logger");
4
+
5
+ const LOGGER = new PLAYO_LOGGER("playo-http-request-handler");
6
+
7
+ /**
8
+ * This function assumes the external api being called gives response,
9
+ * following same structure as being used in playo currently for showing success/failure , i.e. -
10
+ * for successful http request, { requestStatus : 1 } & http failure/ error would be recorded otherwise
11
+ * the responses for external services should be logged for requestId tracing , and analytics purpose later on
12
+ * @param {*} resp
13
+ */
14
+ const playoResponseHandler = (resp, requestId) => {
15
+ const { status, data, config } = resp;
16
+ const { url } = config;
17
+ if (status === 200) {
18
+ const { requestStatus } = data;
19
+ LOGGER.info(requestId, data, `Api call to url to ${url} succeeded with status ${status}`);
20
+ if (!requestStatus) {
21
+ data['requestStatus'] = 1; // assume request status of 1 if any service doesn't provide requestStatus.
22
+ }
23
+ return data;
24
+ } else {
25
+ LOGGER.error(requestId, data, `Api call to url to ${url} failed with status : ${status}`);
26
+ data['requestStatus'] = 0;
27
+ return Promise.reject(data);
28
+ }
29
+ };
30
+
31
+ /**
32
+ * Makes a get http request - throws error to be handled by calling function
33
+ * @param {String} url
34
+ * @param {Object} headers
35
+ * @param {Object} query
36
+ * @param {String} requestId
37
+ * @param {Boolean} shouldTimeOut - Defaults to false
38
+ * @param {Number} timeout - in seconds, Defaults to 10 seconds
39
+ * @param {Function} responseHandler - Caller should pass it's own http response handler. Defaults to playo's response function handler
40
+ */
41
+ const get = async (url, headers = {}, query = {}, requestId = '', responseHandler = playoResponseHandler, shouldTimeOut = false, timeout = TIMEOUT_DURATION) => {
42
+ try {
43
+ if (!shouldTimeOut) {
44
+ timeout = 0; // no timeout
45
+ }
46
+ const resp = await Axios.get(url, { headers, params: query, timeout });
47
+ return responseHandler(resp, requestId);
48
+ } catch (error) {
49
+ LOGGER.error(requestId, error, `Api call to url to ${url} failed due to ${error.message}`);
50
+ return Promise.reject(error);
51
+ }
52
+ };
53
+
54
+ /**
55
+ * Makes a POST http request - throws error to be handled by calling function
56
+ * @param {String} url
57
+ * @param {Object} headers
58
+ * @param {Object} query
59
+ * @param {Object} body
60
+ * @param {String} requestId
61
+ * @param {Boolean} shouldTimeOut - Defaults to false
62
+ * @param {Number} timeout - in seconds, Defaults to 10 seconds
63
+ * @param {Function} responseHandler - Caller should pass it's own http response handler. Defaults to playo's response function handler
64
+ */
65
+ const post = async (url, headers = {}, query = {}, body = {}, requestId = '', responseHandler = playoResponseHandler, shouldTimeOut = false, timeout = TIMEOUT_DURATION) => {
66
+ try {
67
+ if (!shouldTimeOut) {
68
+ timeout = 0; // no timeout
69
+ }
70
+ const options = { headers, query, timeout };
71
+ const resp = await Axios.post(url, body, options);
72
+ return responseHandler(resp, requestId);
73
+ } catch (err) {
74
+ LOGGER.error(requestId, err, `Api call to url to ${url} failed due to ${err.message}`);
75
+ return Promise.reject(err);
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Makes a PUT http request - throws error to be handled by calling function
81
+ * @param {String} url
82
+ * @param {Object} headers
83
+ * @param {Object} query
84
+ * @param {Object} body
85
+ * @param {String} requestId
86
+ * @param {Boolean} shouldTimeOut - Defaults to false
87
+ * @param {Number} timeout - in seconds, Defaults to 10 seconds
88
+ * @param {Function} responseHandler - Caller should pass it's own http response handler. Defaults to playo's response function handler
89
+ */
90
+ const put = async (url, headers = {}, query = {}, body = {}, requestId = '', responseHandler = playoResponseHandler, shouldTimeOut = false, timeout = TIMEOUT_DURATION) => {
91
+ try {
92
+ if (!shouldTimeOut) {
93
+ timeout = 0; // no timeout
94
+ }
95
+ const options = { headers, query, timeout };
96
+ const resp = await Axios.put(url, body, options);
97
+
98
+ return responseHandler(resp, requestId);
99
+ } catch (error) {
100
+ LOGGER.error(requestId, error, `Api call to url to ${url} failed due to ${error.message}`);
101
+ return Promise.reject(error);
102
+ }
103
+ };
104
+
105
+ /**
106
+ * Makes a DELETE http request - throws error to be handled by calling function
107
+ * @param {String} url
108
+ * @param {Object} headers
109
+ * @param {Object} query
110
+ * @param {Object} body
111
+ * @param {String} requestId
112
+ * @param {Boolean} shouldTimeOut - Defaults to false
113
+ * @param {Number} timeout - in seconds, Defaults to 10 seconds
114
+ * @param {Function} responseHandler - Caller should pass it's own http response handler. Defaults to playo's response function handler
115
+ */
116
+ const remove = async (url, headers = {}, query = {}, body, requestId = '', responseHandler = playoResponseHandler, shouldTimeOut = false, timeout = TIMEOUT_DURATION) => {
117
+ try {
118
+ if (!shouldTimeOut) {
119
+ timeout = 0; // no timeout
120
+ }
121
+ const options = { headers, params: query, data: body, timeout };
122
+ const resp = await Axios.delete(url, options);
123
+ return responseHandler(resp, requestId);
124
+ } catch (error) {
125
+ LOGGER.error(requestId, error, `Api call to url to ${url} failed due to ${error.message}`);
126
+ return Promise.reject(error);
127
+ }
128
+ };
129
+
130
+
131
+ module.exports = {
132
+ get,
133
+ post,
134
+ put,
135
+ remove
136
+ }
package/lib/util.js CHANGED
@@ -1,9 +1,11 @@
1
1
  /**\
2
2
  * This module is not imported in PlayoLib directly as there are already many imports in individual repositories
3
3
  * named util/utils and importing this alongside might cause unforeseen errors or poor readability
4
- * Ideally new repositories should import utils from here only. Todo- look for a workaround
4
+ * Ideally new repositories should import utils from here only. Todo- look for a workaround - named imports
5
5
  */
6
6
 
7
+ const hbs = require('handlebars');
8
+
7
9
  /**
8
10
  * Finds rating given to a user for a sport by playpals <Assumes playpalDocs supplied are already filtered for a user>
9
11
  * @param {Array} playpalDocs
@@ -70,6 +72,9 @@ const getRecentRatingDictOfPals = (postActivityDocs) => {
70
72
  // pals array contains ratings object as per given by other playpals for a particular activity, check schema for further details
71
73
  const { pals = [] } = postActivityDoc;
72
74
 
75
+ /**
76
+ * Description for code below we are try to get a dictionary of latest non-zero rating the user has received to be processed later
77
+ */
73
78
  if (Array.isArray(pals)) {
74
79
  pals.forEach((palRating) => {
75
80
  const { palId = '', rating = 0, timestamp } = palRating;
@@ -78,7 +83,7 @@ const getRecentRatingDictOfPals = (postActivityDocs) => {
78
83
  rating: rating,
79
84
  timestamp: timestamp
80
85
  }
81
- } else if (palRatingDict[palId] && timestamp >= palRatingDict[palId]["timestamp"]) {
86
+ } else if (palRatingDict[palId] && timestamp >= palRatingDict[palId]["timestamp"] && rating > 0) {
82
87
  // If user received any rating more recent then consider that instead
83
88
  palRatingDict[palId]["rating"] = rating;
84
89
  }
@@ -118,11 +123,30 @@ const getCategoricalBreakUpFromRecentUserRatings = (palRatingDict, levelCategori
118
123
  }
119
124
 
120
125
  return categoricalBreakUp;
121
- }
126
+ };
127
+
128
+ const noop = () => {
129
+ return undefined;
130
+ };
131
+
132
+ /**
133
+ *
134
+ * @param {String} template - Handlebars compatible template
135
+ * @param {Object} data - Data points containing key value pairs of data required in template supplied
136
+ * @returns {String}
137
+ */
138
+ const renderTemplate = (template, data) => {
139
+
140
+ const temp = hbs.compile(template);
141
+
142
+ return temp(data);
143
+ };
122
144
 
123
145
  module.exports = {
124
146
  getRatingsFromPlaypalDocs,
125
147
  findAverage,
126
148
  getRecentRatingDictOfPals,
127
- getCategoricalBreakUpFromRecentUserRatings
128
- }
149
+ getCategoricalBreakUpFromRecentUserRatings,
150
+ noop,
151
+ renderTemplate
152
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playov2-js-utilities",
3
- "version": "0.2.7",
3
+ "version": "0.3.16.0",
4
4
  "description": "Private package for JS utility functions",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -16,9 +16,16 @@
16
16
  "author": "Saurabh Agrawal",
17
17
  "license": "ISC",
18
18
  "homepage": "https://bitbucket.org/techmash/playov2-js-utilities#readme",
19
-
20
19
  "devDependencies": {
21
20
  "faker": "^5.5.3",
22
21
  "jest": "^27.1.0"
22
+ },
23
+ "dependencies": {
24
+ "@google-cloud/tasks": "^2.5.0",
25
+ "@playo/logger": "^0.9.18",
26
+ "axios": "^0.24.0",
27
+ "cron": "^1.8.2",
28
+ "handlebars": "^4.7.7",
29
+ "uuid": "^8.3.2"
23
30
  }
24
31
  }