https://retellai.com/?utm_source=discord&utm_medium=seo logo
I have a retell voice AI automation for a barbersh...
# ❓・ai-evy-support
f
@AI Evy I have a retell voice AI automation for a barbershop. I need your help. My goal is to setup an automation for 20 barbers where the voice AI can find availability on Cal.com calendar and book it. I want this setup to be the simplest possible and I want to use Dynamic Variables. Each barber has a unique event type. Based on the barber the caller wants, there should be a hard coded event type ID. Also i want to use custom functions. Not the cal.com ones. Tell me how to set this up with as least nodes as possible. I want this to be build like a solid steel pipe that wont break. Ask me any questions if you need more content. Think hard.
a
Thanks for tagging me @Fares_McKarem. I'll look through relevant sources and get back to you shortly.
​ To learn more, see the sources I considered: [[1] Dynamic Variables](https://docs.retellai.com/build/dynamic-variables) [[2] Integrate any system with custom function](https://docs.retellai.com/build/single-multi-prompt/custom-function) [[3] Custom Function](https://docs.retellai.com/build/conversation-flow/custom-function) ​
### Answer Here's how to set this up with minimal complexity using custom functions and dynamic variables: ## Architecture Overview 1 agent + 2 custom functions — that's it. ## Setup Steps ### 1. Create a Dynamic Variable for Event Type ID Define a dynamic variable
{{barber_event_type_id}}
that maps to each barber's Cal.com event type ID. [(1) ]() In your prompt, include logic like:
Copy code
If the caller wants [Barber Name], use event type ID [hardcoded ID].
### 2. Create Two Custom Functions Function 1:
check_barber_availability
- HTTP Method: GET or POST to your endpoint [(2) ]() , [(3) ]() - Pass the
{{barber_event_type_id}}
as a const value or in query parameters [(2) ]() - Your endpoint calls Cal.com's API with the correct event type ID and returns available slots [(3) ]() Function 2:
book_barber_appointment
- HTTP Method: POST to your endpoint [(2) ]() , [(3) ]() - Parameters: selected time slot, customer details [(2) ]() - Your endpoint calls Cal.com's booking API with the event type ID [(3) ]() ### 3. Use Const Values for Hardcoded Mapping In your custom function parameters, you can use
"const"
to hardcode values:
Copy code
json
{
  "type": "object",
  "properties": {
    "event_type_id": {
      "type": "number",
      "const": "{{barber_event_type_id}}"
    }
  }
}
[(2) ]() , [(3) ]() ### 4. Prompt Engineering Include explicit instructions:
Copy code
When user states which barber they want, determine the barber's event type ID:
- John: 1234567
- Mike: 1234568
- [etc for all 20 barbers]

When user provides a time preference, call `check_barber_availability`.
When user confirms a slot, call `book_barber_appointment`.
[(2) ]() ## Why This Works Like "Solid Steel" - Single agent handles all 20 barbers [(1) ]() - Your backend controls all Cal.com API logic — if Cal.com changes, you update one place [(3) ]() - Const values + dynamic variables ensure the correct event type ID is always passed [(2) ]() - Response variables can extract booking confirmation data for use later in the conversation , [(3) ]() ## Questions I Need From You 1. Do you want the barber selection to happen via caller input during the call, or will it be pre-determined (passed via dynamic variables at call initiation) ? 2. Do you have a backend server ready to receive the custom function requests and call Cal.com's API?
Feel free to tag @AI Evy with additional questions. I also appreciate feedback, it helps me improve.
f
1. Happen via caller input during the call. 2. yes.
@AI Evy 1. Happen via caller input during the call. 2. yes.
a
Thanks for the follow-up, @Fares_McKarem. I'll get back to you soon.
### Answer Since the barber selection happens during the call, here's the refined setup: ## Final Implementation ### 1. Prompt Structure In your agent prompt, hardcode the barber-to-event-type mapping directly: [(1) ]()
Copy code
When the caller specifies which barber they want, identify the corresponding event type ID:
- Barber A: 111111
- Barber B: 222222
- Barber C: 333333
[...repeat for all 20 barbers]

When user provides the barber name, call `check_barber_availability` function.
When user confirms a time slot, call `book_barber_appointment` function.
### 2. Custom Function Parameter Schema For both functions, use a parameter where the LLM resolves the
event_type_id
based on the barber name from the conversation: , [(2) ]()
Copy code
json
{
  "type": "object",
  "required": ["event_type_id"],
  "properties": {
    "event_type_id": {
      "type": "number",
      "description": "The Cal.com event type ID for the selected barber"
    }
  }
}
[(1) ]() , [(2) ]() ### 3. Your Backend Logic Your endpoint receives the
event_type_id
in the
args
object: [(1) ]() , [(2) ]()
Copy code
javascript
const content = req.body;
// content.args.event_type_id contains the barber's event type ID
// Call Cal.com API with this ID
[(1) ]() ### 4. Response Variables (Optional) Extract booking confirmation data from your API response to use later in the conversation using response variables. , [(2) ]() ## Summary - 0 dynamic variables needed at call initiation — the LLM determines the event type ID from the conversation [(1) ]() - Prompt contains the hardcoded mapping — single source of truth - 2 custom functions — availability check + booking , [(2) ]() - Your backend — handles all Cal.com API calls
Feel free to tag @AI Evy with additional questions. I also appreciate feedback, it helps me improve.
​ To learn more, see the sources I considered: [[1] Integrate any system with custom function](https://docs.retellai.com/build/single-multi-prompt/custom-function) [[2] Custom Function](https://docs.retellai.com/build/conversation-flow/custom-function) ​
f
These are the nodes I have. But the dynamic variable values are not sending out. Am i missing a extract variable node? Node 0 — Welcome (Static) “Shear Brilliance Oshawa, Vanessa speaking… AI assistant… recorded… How can I help?” Node 1 — Main Reception / Intake (Conversation Node) Goal: detect intent (book vs info). For booking: collect service, barber, date, time preference. (One question at a time.) Node 2 — Function: check_barber_availability (Custom Function → Cal Slots) Calls: GET https://api.cal.com/v2/slots with query params to fetch open slots. Node 3 — Offer & Confirm Appointment Time (Conversation Node) Reads 2–3 slot options. Caller chooses one. Then Vanessa confirms full details and asks “Is that correct?” Node 4 — Function: book_barber_appointment (Custom Function → Create Booking) Calls: POST https://api.cal.com/v2/bookings with JSON body. Node 5 — Booking Result + Wrap Up (Conversation Node) If success: confirm booking + next steps. If fail: offer alternate time/date or end politely. End Call node Clean goodbye.
@AI Evy These are the nodes I have. But the dynamic variable values are not sending out. Am i missing a extract variable node? Node 0 — Welcome (Static) “Shear Brilliance Oshawa, Vanessa speaking… AI assistant… recorded… How can I help?” Node 1 — Main Reception / Intake (Conversation Node) Goal: detect intent (book vs info). For booking: collect service, barber, date, time preference. (One question at a time.) Node 2 — Function: check_barber_availability (Custom Function → Cal Slots) Calls: GET https://api.cal.com/v2/slots with query params to fetch open slots. Node 3 — Offer & Confirm Appointment Time (Conversation Node) Reads 2–3 slot options. Caller chooses one. Then Vanessa confirms full details and asks “Is that correct?” Node 4 — Function: book_barber_appointment (Custom Function → Create Booking) Calls: POST https://api.cal.com/v2/bookings with JSON body. Node 5 — Booking Result + Wrap Up (Conversation Node) If success: confirm booking + next steps. If fail: offer alternate time/date or end politely. End Call node Clean goodbye.
a
Thanks for the follow-up, @Fares_McKarem. I'll get back to you soon.
​ To learn more, see the sources I considered: [[1] Extract Dynamic Variable Node](https://docs.retellai.com/build/conversation-flow/extract-dv-node) [[2] Node Overview](https://docs.retellai.com/build/conversation-flow/node) [[3] Dynamic Variable is not sending via custom function.](https://discord.com/channels/1186424376300679209/1430715756030722149) ​
### Answer Yes, you likely need an Extract Dynamic Variable Node to capture values from the conversation before passing them to your custom functions. [(1) ]() ## The Issue The Extract Dynamic Variable Node is specifically designed to "extract information from conversation and store them as dynamic variable." Without this node, values collected during conversation (barber name, date, time preference) aren't being stored as variables that can be passed to your custom functions. ## Recommended Fix Add an Extract Dynamic Variable Node between Node 1 (Main Reception/Intake) and Node 2 (check_barber_availability) . , [(2) ]() Configure it to extract: - **Variable Name**: e.g.,
barber_name
,
event_type_id
,
date_preference
[(1) ]() - **Description**: Brief explanation of what each value should be - **Variable Type**: Choose from
Text
,
Number
,
Enum
, or
Boolean
## Passing Variables to Custom Functions In your custom function parameters, reference the extracted variable in the description field using the
{{variable_name}}
format. [(3) ]() Example description for a parameter:
Copy code
Use this as the event type ID: {{event_type_id}}
## Important Note A similar issue was reported where dynamic variables weren't sending via custom functions. The solution was to include the
{{variable_name}}
syntax in the parameter description field, not just the parameter name.
Feel free to tag @AI Evy with additional questions. I also appreciate feedback, it helps me improve.