What Happens on the Call
Prerequisites
- Python 3.10 or later
- A Guava account with an API key and a phone number — sign up at app.goguava.ai
- An AWS account with an Amazon Connect instance
Step 1: Install Guava
Choose whichever package manager you prefer:boto3 for the Amazon Connect API:
Step 2: Set Up Amazon Connect
If you already have a Connect instance configured, skip to the parts you haven’t done yet.2a. Create a Connect Instance
- Open the Amazon Connect console.
- Click Create instance and follow the setup wizard.
- Once the instance is created, open it and copy the Instance ID from the ARN shown in the overview — it’s the UUID at the end:
2b. Create a Contact Flow for Task Routing
Amazon Connect tasks need a dedicated contact flow — the default queue flow does not support tasks.- In your Connect instance, go to Routing → Contact flows → Create contact flow.
- Name it something like
Guava Task Routing Flow. - Add a Set working queue block and connect it to your scheduling queue.
- Add a Transfer to queue block after that.
- Add a Disconnect / hang up block at the end of the error branch.
- Save and publish the flow.
- Open the flow, click Show additional flow information, and copy the Contact flow ID (the UUID at the end of the ARN).
Tip: For a minimal test flow, you can also use any existing inbound contact flow — tasks will be routed to whatever queue the flow sets.
2c. Set Up a Scheduling Queue
- Go to Routing → Queues → Add new queue.
- Name it (e.g.,
Scheduling) and assign it to the hours of operation and outbound caller ID of your choice. - Copy the Queue ID from the queue’s ARN (the UUID at the end).
2d. Get a Transfer Number
This is the phone number Guava will transfer rescheduling patients to — typically your scheduling desk or the Amazon Connect direct dial number for your scheduling queue.- In Connect, go to Channels → Phone numbers to see claimed numbers.
- Or use any external scheduling desk number in E.164 format (e.g.,
+15551234567).
Step 3: Configure AWS Credentials
The example usesboto3, which reads credentials from the standard AWS credential chain. The easiest way for local development:
connect:GetCurrentMetricData— to check queue availabilityconnect:StartTaskContact— to create callback tasks
Step 4: Set Environment Variables
Step 5: Run the Example
+15559876543 with the phone number to call and adjust --name and --appointment as needed.
What to expect:
- Guava calls the patient and verifies they’re the right person
- If they confirm: you’ll see a confirmation logged and an SMS is sent
- If they need to reschedule: the example checks your Connect queue in real time
- If agents are free: Guava transfers the patient to
CONNECT_TRANSFER_NUMBER - If the queue is busy: Guava collects a callback preference and creates a task in your Connect instance — visible to agents in the Contact Control Panel (CCP)
- If agents are free: Guava transfers the patient to
- If no one picks up: Guava leaves a voicemail
How It Works
1. Defining the Agent and Kicking Off the Call
Agent is the top-level handle for the AI persona. call_phone places the call and binds the agent to that single conversation. The variables dict is passed into the call and made available throughout — handlers can read each value with call.get_variable(key).
2. Reaching the Right Person (reach_person)
reach_person handles the gatekeeper problem — it has the agent confirm they’re speaking with the intended patient before proceeding. If a family member answers, the agent politely asks for the patient by name. The reach result is delivered to the handler registered with @agent.on_reach_person.
3. Collecting the Appointment Response
set_task gives the agent a named objective and a checklist of items to work through. guava.Field tells the agent what information to collect — the patient might say “Yes, I’ll be there” or “Actually, I have a conflict that day” — and the agent normalizes that into a structured value you can inspect via call.get_field(...).
4. Classifying the Patient’s Response
remind task completes, the registered @agent.on_task_complete("remind") handler runs. Rather than matching against a list of keywords, IntentRecognizer uses an LLM to classify what the patient actually meant — natural phrasing like “I actually have a conflict that day” or “Can we move it?” still maps to needs to reschedule without enumerating every variant. The recognizer is instantiated once at module level and reused across calls.
5. Checking the Connect Queue in Real Time
GetCurrentMetricData returns a real-time snapshot of the queue — how many agents are available and how many contacts are already waiting. This snapshot updates every ~15 seconds.
6. Routing Decision: Transfer vs. Task
callback task; its completion handler creates a Connect task via StartTaskContact — complete with the patient’s name, original appointment, and preferred callback window. The task appears in your agents’ Contact Control Panel (CCP) just like any other contact.
7. SMS Confirmation
call_phone() returns, if the patient confirmed, we send an SMS reminder via the Guava client. This runs after the call ends, so it never blocks the voice interaction.
Customization Ideas
Pull patient data from a database or CRM Replace the hardcoded--name and --appointment CLI args with a database query or CRM API call, and call patients in a loop:
Call object.