@plusscommunities/pluss-core-aws 2.0.23-beta.2 → 2.0.23

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.
@@ -122,58 +122,13 @@ module.exports = async (
122
122
  config,
123
123
  });
124
124
 
125
- // Notification deduplication to prevent duplicate push notifications
126
- // Use a 5-minute deduplication window to prevent the same notification
127
- // from being sent multiple times for the same recipients and entity
128
-
129
- // Use MD5 hash of sorted recipients for consistent, size-limited identifier
130
- const recipientHash = crypto
131
- .createHash("md5")
132
- .update(receiverKeys.sort().join(","))
133
- .digest("hex")
134
- .substring(0, 8); // 8 hex chars = 4.3 billion combinations
135
-
136
- // Generate content hash from the entire value object for precise deduplication
125
+ // Generate content hash from the entire value object for per-user deduplication
137
126
  const contentHash = crypto
138
127
  .createHash("md5")
139
128
  .update(JSON.stringify(value))
140
129
  .digest("hex")
141
130
  .substring(0, 8); // 8 hex chars for content uniqueness
142
131
 
143
- // Combine both hashes for exact duplicate detection
144
- const notificationKey = getMultiRowId([
145
- "notification",
146
- recipientHash, // Fixed 8-character recipient identifier
147
- contentHash, // Fixed 8-character content identifier
148
- type,
149
- key,
150
- ]);
151
-
152
- // log("sendNotifications - core", "notificationKey", notificationKey, logId);
153
- const canSend = await checkRateLimit(
154
- notificationKey,
155
- 300000, // 5 minutes in milliseconds
156
- 1, // Allow only 1 notification in the timeframe
157
- false // Save this check to prevent duplicates
158
- );
159
-
160
- if (!canSend) {
161
- log(
162
- "sendNotifications",
163
- "duplicateSkipped",
164
- {
165
- notificationKey,
166
- recipientHash,
167
- contentHash,
168
- type,
169
- entityKey: key,
170
- recipientCount: receiverKeys.length,
171
- },
172
- logId
173
- );
174
- return; // Skip sending duplicate notification
175
- }
176
-
177
132
  const tokens = [];
178
133
  const promises = [];
179
134
  receiverKeys.forEach((uid) => {
@@ -182,8 +137,24 @@ module.exports = async (
182
137
  getUser(uid)
183
138
  .then(async (user) => {
184
139
  try {
140
+ // User-level rate limiting: check if this specific user can receive this notification
141
+ // Use user ID + content hash + notification type/key for fine-grained deduplication
142
+ const userNotificationKey = getMultiRowId([
143
+ "notification",
144
+ user.Id, // User-specific identifier
145
+ contentHash, // Content hash for this notification
146
+ type,
147
+ key,
148
+ ]);
149
+ const canSend = await checkRateLimit(
150
+ userNotificationKey,
151
+ 86400000, // 24 hours in milliseconds
152
+ 1, // Allow only 1 notification in the timeframe
153
+ false // Save this check to prevent duplicates
154
+ );
155
+
185
156
  const isMuted = await checkMuted(user.Id, config);
186
- if (!isMuted) {
157
+ if (!isMuted && canSend) {
187
158
  if (!user.tokens) {
188
159
  if (user.token) {
189
160
  tokens.push(user.token);
@@ -193,6 +164,18 @@ module.exports = async (
193
164
  tokens.push(entry.Token);
194
165
  });
195
166
  }
167
+ } else {
168
+ log(
169
+ "sendNotifications",
170
+ "userSkipped",
171
+ {
172
+ userId: user.Id,
173
+ isMuted,
174
+ canSend,
175
+ userNotificationKey,
176
+ },
177
+ logId
178
+ );
196
179
  }
197
180
  } catch (error) {
198
181
  log("sendNotifications", "error", error.toString());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plusscommunities/pluss-core-aws",
3
- "version": "2.0.23-beta.2",
3
+ "version": "2.0.23",
4
4
  "description": "Core extension package for Pluss Communities platform",
5
5
  "scripts": {
6
6
  "betapatch": "npm version prepatch --preid=beta",