This workflow follows the HTTP Request → Slack recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "WF-OB-1B: Follow-Up Call Scheduler",
"nodes": [
{
"id": "schedule",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
0,
0
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "45 10 * * 1-5"
},
{
"field": "cronExpression",
"expression": "0 16 * * 1-5"
},
{
"field": "cronExpression",
"expression": "15 17 * * 1-5"
},
{
"field": "cronExpression",
"expression": "30 9 * * 6"
}
]
}
}
},
{
"id": "determine_tz",
"name": "Determine Timezone Window",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
224,
0
],
"parameters": {
"jsCode": "var now=new Date(); var day=now.getDay(); var timezone='ET'; var businessHoursOk=true; return [{ json: { timezone:timezone, maxPerBatch:4, businessHoursOk:businessHoursOk, dayOfWeek:day } }];"
}
},
{
"id": "query_convex",
"name": "Query Convex Follow-Ups",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
448,
0
],
"parameters": {
"method": "GET",
"url": "=https://YOUR_CONVEX_DEPLOYMENT/outbound-leads-due?timestamp={{ Date.now() }}&limit=20",
"sendBody": false,
"options": {
"response": {
"response": {
"neverError": true
}
},
"timeout": 15000
}
},
"onError": "continueRegularOutput"
},
{
"id": "process_followups",
"name": "Process Follow-Up Leads",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
672,
0
],
"parameters": {
"jsCode": "var response=$input.first().json; var leads=response.leads || []; return leads.map(function(lead){ return { json: { closeLeadId:lead.closeLeadId, callSequence:lead.callSequence, lastOutcome:lead.lastOutcome||'', lastCallSummary:lead.lastCallSummary||'', isFollowUp:true } }; });"
}
},
{
"id": "lookup_close",
"name": "Lookup Close Detail",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
896,
0
],
"parameters": {
"method": "GET",
"url": "=https://api.close.com/api/v1/lead/{{ $json.closeLeadId }}/?_fields=id,display_name,contacts,custom",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"sendBody": false,
"options": {
"response": {
"response": {
"neverError": true
}
},
"timeout": 15000
}
},
"onError": "continueRegularOutput"
},
{
"id": "enrich_followup",
"name": "Enrich Follow-Up Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1120,
0
],
"parameters": {
"jsCode": "var closeData=$json; var followUp=$('Process Follow-Up Leads').item.json; var result={}; var keys=Object.keys(closeData); for(var i=0;i<keys.length;i++){ result[keys[i]]=closeData[keys[i]]; } result.callSequence=followUp.callSequence||1; result.isFollowUp=true; result.previousOutcome=followUp.lastOutcome||''; result.previousCallSummary=followUp.lastCallSummary||''; return { json: result };"
}
},
{
"id": "filter_states",
"name": "Filter Blocked States",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1232,
0
],
"parameters": {
"jsCode": "var coveredStates=['OH']; var items=$input.all(); var allowed=[]; for(var i=0;i<items.length;i++){ allowed.push(items[i]); } return allowed;"
}
},
{
"id": "filter_tz",
"name": "Filter by TZ + Extract",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1344,
0
],
"parameters": {
"jsCode": "var leads=$input.all().map(function(item){return item.json;}); return leads.map(function(lead){ return { json: lead }; });"
}
},
{
"id": "has_leads",
"name": "Has Leads?",
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1568,
0
],
"parameters": {
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "hl1",
"leftValue": "={{ $json.no_leads }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "notEquals"
}
}
]
},
"options": {}
}
},
{
"id": "batch",
"name": "SplitInBatches",
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
1792,
0
],
"parameters": {
"options": {}
}
},
{
"id": "build_retell",
"name": "Build Retell Payload",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2016,
0
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "var lead=$json; var seq=lead.callSequence||1; var agentId='YOUR_RETELL_AGENT_ID'; var phone=''; var firstName='there'; var fromNumber='+15555550100'; var use216={'216':true,'614':true,'740':true,'380':true,'220':true}; return { json: { closeLeadId:lead.id, toNumber:phone, fromNumber:fromNumber, agentId:agentId, callSequence:seq, isFollowUp:true, retellPayload:{ from_number:fromNumber, to_number:phone, override_agent_id:agentId, retell_llm_dynamic_variables:{ firstName:firstName, callSequence:String(seq), callDirection:'outbound' } } } };"
}
},
{
"id": "call_retell",
"name": "Call Retell API",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2240,
0
],
"parameters": {
"method": "POST",
"url": "https://api.retellai.com/v2/create-phone-call",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_RETELL_API_KEY"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify($json.retellPayload) }}",
"options": {}
},
"onError": "continueRegularOutput"
},
{
"id": "log_convex",
"name": "Log Call to Convex",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2464,
0
],
"parameters": {
"method": "POST",
"url": "https://YOUR_CONVEX_DEPLOYMENT/outbound-call-log",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ retellCallId: $json.call_id || '', closeLeadId: $('Build Retell Payload').first().json.closeLeadId, callStatus: 'initiated' }) }}",
"options": {}
},
"onError": "continueRegularOutput"
},
{
"id": "update_close",
"name": "Update Close Call Fields",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2688,
0
],
"parameters": {
"method": "PUT",
"url": "=https://api.close.com/api/v1/lead/{{ $('Build Retell Payload').first().json.closeLeadId }}/",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ 'custom.cf_L6lj9vbbe1pnuRA2tAAeZs6eso00WI5MI8RNf23Bykn': ($('Build Retell Payload').first().json.callSequence || 1) + 1 }) }}",
"options": {
"response": {
"response": {
"neverError": true
}
},
"timeout": 30000
}
},
"onError": "continueRegularOutput"
},
{
"id": "wait_1s",
"name": "Wait 1s",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2912,
0
],
"parameters": {
"jsCode": "return $input.all();"
}
},
{
"id": "slack_summary",
"name": "Slack Summary",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
2016,
-220
],
"parameters": {
"resource": "message",
"operation": "post",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "id",
"value": "C08CZQV5QV7"
},
"text": "=*WF-OB-1B Follow-Up Call Batch*\n:phone: *Timezone*: {{ $('Determine Timezone Window').first().json.timezone }}\n:repeat: *Follow-Up Batch Complete*",
"otherOptions": {}
},
"onError": "continueRegularOutput"
},
{
"id": "sticky_overview",
"name": "WF-OB-1B Overview",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-208,
-350
],
"parameters": {
"content": "## WF-OB-1B: Follow-Up Call Scheduler\n\nFire FOLLOW-UP Retell AI calls (2nd-6th) for VoiceSDR. Source: Convex outbound-leads-due > Close CRM detail. Owner."
}
}
],
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "Determine Timezone Window",
"type": "main",
"index": 0
}
]
]
},
"Determine Timezone Window": {
"main": [
[
{
"node": "Query Convex Follow-Ups",
"type": "main",
"index": 0
}
]
]
},
"Query Convex Follow-Ups": {
"main": [
[
{
"node": "Process Follow-Up Leads",
"type": "main",
"index": 0
}
]
]
},
"Process Follow-Up Leads": {
"main": [
[
{
"node": "Lookup Close Detail",
"type": "main",
"index": 0
}
]
]
},
"Lookup Close Detail": {
"main": [
[
{
"node": "Enrich Follow-Up Data",
"type": "main",
"index": 0
}
]
]
},
"Enrich Follow-Up Data": {
"main": [
[
{
"node": "Filter Blocked States",
"type": "main",
"index": 0
}
]
]
},
"Filter Blocked States": {
"main": [
[
{
"node": "Filter by TZ + Extract",
"type": "main",
"index": 0
}
]
]
},
"Filter by TZ + Extract": {
"main": [
[
{
"node": "Has Leads?",
"type": "main",
"index": 0
}
]
]
},
"Has Leads?": {
"main": [
[
{
"node": "SplitInBatches",
"type": "main",
"index": 0
}
],
[]
]
},
"SplitInBatches": {
"main": [
[
{
"node": "Slack Summary",
"type": "main",
"index": 0
}
],
[
{
"node": "Build Retell Payload",
"type": "main",
"index": 0
}
]
]
},
"Build Retell Payload": {
"main": [
[
{
"node": "Call Retell API",
"type": "main",
"index": 0
}
]
]
},
"Call Retell API": {
"main": [
[
{
"node": "Log Call to Convex",
"type": "main",
"index": 0
}
]
]
},
"Log Call to Convex": {
"main": [
[
{
"node": "Update Close Call Fields",
"type": "main",
"index": 0
}
]
]
},
"Update Close Call Fields": {
"main": [
[
{
"node": "Wait 1s",
"type": "main",
"index": 0
}
]
]
},
"Wait 1s": {
"main": [
[
{
"node": "SplitInBatches",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"timezone": "America/New_York"
},
"active": false
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
WF-OB-1B: Follow-Up Call Scheduler. Uses httpRequest, slack. Scheduled trigger; 17 nodes.
Source: https://github.com/rafiulislam4246/voice-sdr-title-agent/blob/main/workflows/voice-02-followup-call-scheduler.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Template 14310. Uses httpRequest, stopAndError, slack, gmail. Scheduled trigger; 53 nodes.
It identifies SKUs with low inventory per source and sends daily alerts via:
Linear Router — Reconciler. Uses httpRequest, slack. Scheduled trigger; 17 nodes.
WF-OB-1: First Call Scheduler. Uses httpRequest, slack. Scheduled trigger; 17 nodes.
Agent Team Watchdog — Weekly Strategic-Routine Canary. Uses httpRequest, slack. Scheduled trigger; 10 nodes.