MCPcopy Index your code
hub / github.com/simstudioai/sim / pollListMembership

Function pollListMembership

apps/sim/lib/webhooks/polling/hubspot.ts:350–486  ·  view source on GitHub ↗
(
  ctx: PollWebhookContext,
  config: HubSpotWebhookConfig,
  accessToken: string
)

Source from the content-addressed store, hash-verified

348}
349
350async function pollListMembership(
351 ctx: PollWebhookContext,
352 config: HubSpotWebhookConfig,
353 accessToken: string
354): Promise<'success' | 'failure'> {
355 const { webhookData, workflowData, requestId, logger } = ctx
356 const webhookId = webhookData.id
357
358 const listId = config.listId?.trim()
359 if (!listId) {
360 throw new Error(`HubSpot list_membership trigger ${webhookId} is missing listId`)
361 }
362 const nowMs = Date.now()
363 const seedComplete = config.membershipSeedComplete === true
364 const maxRecords = Math.min(
365 Math.max(config.maxRecordsPerPoll ?? DEFAULT_MAX_RECORDS, 1),
366 MAX_MAX_RECORDS
367 )
368
369 // The HubSpot endpoint walks ASC by default. We resume from a stored `after` cursor —
370 // empty cursor means "from the beginning of the list". During the seed pass we paginate
371 // forward without emitting; once we reach the end (no `paging.next.after`) we mark the
372 // seed complete and re-fetch from the cursor-to-last-page on each normal poll. New
373 // members appended to the list show up on subsequent fetches; the idempotency layer
374 // dedups the records we've already seen on the boundary page.
375 const result = await fetchListMembershipPages({
376 listId,
377 accessToken,
378 initialAfter: config.lastSeenMembershipCursor?.trim() || undefined,
379 pageLimit: seedComplete ? maxRecords : MAX_PAGES_PER_POLL * HUBSPOT_PAGE_LIMIT,
380 requestId,
381 logger,
382 })
383
384 if (!seedComplete) {
385 // Seed phase: don't emit. Just save the cursor and (when reached) flip the flag.
386 const update: Record<string, unknown> = {
387 lastCheckedTimestamp: new Date(nowMs).toISOString(),
388 lastSeenMembershipCursor: result.resumeCursor ?? '',
389 }
390 if (result.reachedEnd) {
391 update.membershipSeedComplete = true
392 logger.info(
393 `[${requestId}] HubSpot list_membership ${webhookId} seed complete (list=${listId})`
394 )
395 } else {
396 logger.info(
397 `[${requestId}] HubSpot list_membership ${webhookId} seed in progress (list=${listId}, scanned ${result.scanned})`
398 )
399 }
400 await updateWebhookProviderConfig(webhookId, update, logger)
401 await markWebhookSuccess(webhookId, logger)
402 return 'success'
403 }
404
405 if (result.records.length === 0) {
406 await updateWebhookProviderConfig(
407 webhookId,

Callers 1

pollWebhookFunction · 0.85

Calls 9

markWebhookSuccessFunction · 0.90
getErrorMessageFunction · 0.90
markWebhookFailedFunction · 0.90
fetchListMembershipPagesFunction · 0.85
infoMethod · 0.80
errorMethod · 0.80

Tested by

no test coverage detected