Analysis, purchase and utility workflows
nooksCallAnalysis
- File
-
lib/workflows/functions/nooks-call-analysis.ts - Event
-
nooks/call.logged - Config
-
retries: 0,concurrency: { limit: 10 },rateLimit: { key: "event.data.callId", limit: 1, period: "24h" } - Payload
-
{ callId, subscriptionId, disposition }
A single run-ai-analysis step calls CallAnalysisService.runAndSave(callId, null). The null
campaign id matters: a Nooks call has no campaign, so the workspace’s default analysis agent is used and
the result is persisted with campaignId = null.
Because there is no caller agent either, the system prompt is
DEFAULT_HUMAN_CALL_ANALYSIS_SYSTEM_PROMPT — a sales-coaching frame that asks whether the logged
disposition matches the conversation, how objections and rapport were handled, and whether there are
compliance or tone issues.
The event is only emitted for dispositions outside NOOKS_ANALYSIS_SKIP_DISPOSITIONS
("No Answer", "Voicemail", "Busy") — the handler filters before emitting. See
Nooks events.
purchasePhoneNumber
- File
-
lib/workflows/functions/purchase-phone-number.ts - Event
-
phone-number/purchase.requested - Config
-
retries: 0,concurrency: { limit: 1 },idempotency: 'event.data.subscriptionId + "-" + event.data.state + "-" + event.data.areaCode' - Payload
-
{ state, areaCode, subscriptionId, campaignId, targetId }
|
The function body is entirely commented out — phone-number purchasing is currently manual. The function is still registered, so events are consumed and complete without doing anything. |
The intended design, preserved in the comments:
-
check-existing— decide whether a purchase is needed:-
the state already has 3 or more active numbers → skip (
enough_numbers); -
the state has none → purchase (
no_numbers_in_state); -
some numbers exist and at least one has never called this target → skip (
unused_number_available), because the selector can use that fresh number on the next tick; -
all existing numbers in the state have already called this target → purchase (
all_numbers_used_for_target).
-
-
purchase— buy from MessagingApp and register with Retell; throws on failure. -
store— persist to the database; on failure, clean up at both Retell and the phone service.
The idempotency key stops two targets in the same state and area code from triggering two purchases,
and concurrency: { limit: 1 } serialises purchasing globally so a burst cannot overspend.
To re-enable: uncomment the body, then enable both Configs keys — purchase_new_phone_numbers and
daily_phone_number_purchase_limit. The selector’s skipForPurchase branch and
CallSkipReason.NO_PHONE_NUMBER_AVAILABLE are still in place for that path.
batchCallAnalysisWorkflow
- File
-
lib/workflows/batch-call-analysis-workflow.ts
Not an Inngest function. It uses the 'use workflow' / 'use step' directive runtime (the workflow
package) and is started fire-and-forget from POST /api/calls/batch-analyze.
export interface BatchCallAnalysisFilters {
campaign_id?: string | null
status?: string | null
date_from?: string | null
date_to?: string | null
hubspot_sync_status?: string | null
}
export interface BatchCallAnalysisWorkflowResult {
total: number
saved: number
errors: Array<{ callId: string; error: string }>
}
Steps:
-
getCallsToAnalyzeStep(filters)—CallRepository.findCallsForBatchAnalysis(…), then filters out calls with a nullcampaignIdand maps to{ callId, campaignId }. The workflow never touches Prisma; the repository is imported dynamically inside the step. -
runCallAnalysisAndSaveStep(callId, campaignId)—CallAnalysisService.runAndSave, the same code path as per-call analysis, so there is no second implementation to drift.
The loop accumulates saved and pushes { callId, error } for failures, so a partial run reports
exactly which calls could not be analysed.
findCallsForBatchAnalysis and countCallsForBatchAnalysis share the private
buildBatchAnalysisWhere(filters) helper, which is why the GET preview count and the executed set
cannot disagree.
Calls whose campaignId is null — Nooks calls — are excluded from batch re-analysis. Re-run those
individually with POST /api/calls/{id}/analyze.
Scaffolding functions
| Function | File |
|---|---|
|
|
|
|
Registered so the Inngest wiring can be exercised end to end. lib/workflows/call-target-workflow.ts
is an older directive-runtime variant of the dial pipeline, superseded by the callTarget Inngest
function.