Skip to content

Commit 94d42f7

Browse files
committed
processing by lastMembershipTimestamp
1 parent a3c7889 commit 94d42f7

File tree

1 file changed

+73
-80
lines changed

1 file changed

+73
-80
lines changed

components/hubspot/sources/new-contact-added-to-list/new-contact-added-to-list.mjs

Lines changed: 73 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default {
1111
name: "New Contact Added to List",
1212
description:
1313
"Emit new event when a contact is added to a HubSpot list. [See the documentation](https://developers.hubspot.com/docs/reference/api/crm/lists#get-%2Fcrm%2Fv3%2Flists%2F%7Blistid%7D%2Fmemberships%2Fjoin-order)",
14-
version: "0.0.1",
14+
version: "0.0.10",
1515
type: "source",
1616
dedupe: "unique",
1717
props: {
@@ -21,12 +21,13 @@ export default {
2121
alertType: "info",
2222
content: `Properties:\n\`${DEFAULT_CONTACT_PROPERTIES.join(", ")}\``,
2323
},
24-
lists: {
24+
listId: {
2525
propDefinition: [
2626
common.props.hubspot,
27-
"lists",
27+
"listId",
2828
],
29-
description: "Select the lists to watch for new contacts.",
29+
type: "string",
30+
description: "Select the list to watch for new contacts.",
3031
optional: false,
3132
},
3233
properties: {
@@ -43,21 +44,13 @@ export default {
4344
},
4445
methods: {
4546
...common.methods,
46-
_getAfterToken(listId) {
47-
const key = `list_${listId}_after_token`;
47+
_getLastMembershipTimestamp(listId) {
48+
const key = `list_${listId}_last_timestamp`;
4849
return this.db.get(key);
4950
},
50-
_setAfterToken(listId, afterToken) {
51-
const key = `list_${listId}_after_token`;
52-
this.db.set(key, afterToken);
53-
},
54-
_getLastRecordId(listId) {
55-
const key = `list_${listId}_last_record_id`;
56-
return this.db.get(key);
57-
},
58-
_setLastRecordId(listId, recordId) {
59-
const key = `list_${listId}_last_record_id`;
60-
this.db.set(key, recordId);
51+
_setLastMembershipTimestamp(listId, timestamp) {
52+
const key = `list_${listId}_last_timestamp`;
53+
this.db.set(key, timestamp);
6154
},
6255
getTs() {
6356
return Date.now();
@@ -129,22 +122,22 @@ export default {
129122
}
130123
},
131124
async processListMemberships(listId, listInfo) {
132-
const afterToken = this._getAfterToken(listId);
133-
const lastRecordId = this._getLastRecordId(listId);
125+
const lastMembershipTimestamp = this._getLastMembershipTimestamp(listId);
134126
const newMemberships = [];
135127

136128
let params = {
137129
limit: DEFAULT_LIMIT,
138130
};
139131

140-
if (afterToken) {
141-
params.after = afterToken;
142-
}
143-
144132
try {
145133
let hasMore = true;
146-
let latestAfterToken = afterToken;
147-
let latestRecordId = lastRecordId;
134+
let latestMembershipTimestamp = lastMembershipTimestamp;
135+
136+
if (!lastMembershipTimestamp) {
137+
const baselineTimestamp = new Date().toISOString();
138+
this._setLastMembershipTimestamp(listId, baselineTimestamp);
139+
return newMemberships;
140+
}
148141

149142
while (hasMore) {
150143
const {
@@ -160,30 +153,35 @@ export default {
160153
}
161154

162155
for (const membership of results) {
163-
if (lastRecordId && membership.recordId === lastRecordId) {
164-
continue;
156+
const { membershipTimestamp } = membership;
157+
158+
if (
159+
new Date(membershipTimestamp) > new Date(lastMembershipTimestamp)
160+
) {
161+
newMemberships.push({
162+
membership,
163+
listInfo,
164+
});
165+
166+
if (
167+
!latestMembershipTimestamp ||
168+
new Date(membershipTimestamp) >
169+
new Date(latestMembershipTimestamp)
170+
) {
171+
latestMembershipTimestamp = membershipTimestamp;
172+
}
165173
}
166-
167-
newMemberships.push({
168-
membership,
169-
listInfo,
170-
});
171-
latestRecordId = membership.recordId;
172174
}
173175

174176
if (paging?.next?.after) {
175-
latestAfterToken = paging.next.after;
176177
params.after = paging.next.after;
177178
} else {
178179
hasMore = false;
179180
}
180181
}
181182

182-
if (latestAfterToken !== afterToken) {
183-
this._setAfterToken(listId, latestAfterToken);
184-
}
185-
if (latestRecordId) {
186-
this._setLastRecordId(listId, latestRecordId);
183+
if (latestMembershipTimestamp !== lastMembershipTimestamp) {
184+
this._setLastMembershipTimestamp(listId, latestMembershipTimestamp);
187185
}
188186
} catch (error) {
189187
console.error(`Error processing list ${listId}:`, error);
@@ -192,55 +190,50 @@ export default {
192190
return newMemberships;
193191
},
194192
async processResults() {
195-
const { lists } = this;
193+
const { listId } = this;
196194

197-
if (!lists || lists.length === 0) {
198-
console.warn("No lists selected to monitor");
195+
if (!listId) {
196+
console.warn("No list selected to monitor");
199197
return;
200198
}
201199

202-
const allNewMemberships = [];
200+
const listInfo = {
201+
listId,
202+
name: `List ${listId}`,
203+
};
204+
205+
try {
206+
const newMemberships = await this.processListMemberships(
207+
listId,
208+
listInfo,
209+
);
203210

204-
for (const listId of lists) {
205-
try {
206-
const listInfo = {
207-
listId,
208-
name: `List ${listId}`,
209-
};
210-
211-
const newMemberships = await this.processListMemberships(
212-
listId,
213-
listInfo,
211+
if (newMemberships.length > 0) {
212+
const contactIds = newMemberships.map(
213+
({ membership }) => membership.recordId,
214214
);
215-
allNewMemberships.push(...newMemberships);
216-
} catch (error) {
217-
console.error(`Error processing list ${listId}:`, error);
218-
}
219-
}
215+
const contactDetails = await this.getContactDetails(contactIds);
216+
217+
for (const {
218+
membership, listInfo,
219+
} of newMemberships) {
220+
const contactDetail = contactDetails[membership.recordId] || {};
221+
222+
const eventData = {
223+
listId: listInfo.listId,
224+
listName: listInfo.name,
225+
contactId: membership.recordId,
226+
contact: contactDetail,
227+
membership,
228+
addedAt: new Date().toISOString(),
229+
};
220230

221-
if (allNewMemberships.length > 0) {
222-
const contactIds = allNewMemberships.map(
223-
({ membership }) => membership.recordId,
224-
);
225-
const contactDetails = await this.getContactDetails(contactIds);
226-
227-
for (const {
228-
membership, listInfo,
229-
} of allNewMemberships) {
230-
const contactDetail = contactDetails[membership.recordId] || {};
231-
232-
const eventData = {
233-
listId: listInfo.listId,
234-
listName: listInfo.name,
235-
contactId: membership.recordId,
236-
contact: contactDetail,
237-
membership,
238-
addedAt: new Date().toISOString(),
239-
};
240-
241-
const meta = this.generateMeta(membership, listInfo);
242-
this.$emit(eventData, meta);
231+
const meta = this.generateMeta(membership, listInfo);
232+
this.$emit(eventData, meta);
233+
}
243234
}
235+
} catch (error) {
236+
console.error(`Error processing list ${listId}:`, error);
244237
}
245238
},
246239
getParams() {

0 commit comments

Comments
 (0)