Quick Dial (Call Intents)
One-click bridged calling to a company's IVR menu, pre-loaded with the DTMF tones so you land at the right department without navigating.
Quick Dial is a pre-mapped IVR shortcut. Instead of navigating a phone menu yourself ("press 1 for English, press 5 for billing, press 1 for existing customer…"), you click the shortcut you want and Teleperson dials you in at the right level automatically.
It lives at the top of the Call Tree tab. The two surfaces are complementary:
- Quick Dial — "Teleperson, please connect me to American Express billing." One click, your phone rings, you pick up and you're at the right menu level.
- Verified Call Tree — "I'll navigate the menu myself but show me the path." Hand-mapped IVR tree with per-step phone numbers and scripts.
How it works
- Click a Quick Dial row (e.g. "Billing Questions" at American Express).
- A confirmation modal appears: "We'll call you at •••• 4567, then connect you to American Express → Billing Questions."
- Click Call me. Behind the scenes:
- The panel sends
{ intentId, callbackNumber }to Supabase. - Supabase asks Twilio to ring your phone first.
- Twilio attaches inline TwiML that says, after you pick up: "connecting
you to Billing Questions" → dials the company's IVR number → plays the
stored DTMF sequence (
wwwwww5ww1= wait 3s, press 5, wait 1s, press 1).
- The panel sends
- The modal polls status once per second: Setting up your call → Calling your phone → Connected. Listen for the menu prompts.
- Pick up. You're already at the right department.
If you want to back out before pickup, Cancel call in the modal asks Twilio to drop both legs.
Requirements
- Signed in to TelepersonLens, with a verified phone number on your profile. If your profile doesn't have a phone, the modal swaps the primary CTA for Add a phone number and routes to the profile editor.
- The company has at least one intent mapped. Admins seed intents in the company editor; see "Admin: adding intents" below. Companies with no intents show an empty Quick Dial card with an explanation.
Caching and freshness
The list of intents for a domain is cached locally for 24 hours on a hit, 1 hour on a miss (domains with no intents). Click the refresh icon on the Quick Dial card to bust the cache and re-fetch.
When an admin adds a new intent for a company, all users with that company in cache will see it within 24 hours (or immediately on refresh). The backend doesn't push to clients — the cache is pull-only.
Admin: bulk-importing from CSV
For seeding many companies at once (e.g. the Algo Intent.csv master list),
open Admin → Companies and click the phone-with-arrow icon in the
header row (next to the company-import upload button). The modal accepts a
CSV file with this header:
companyName,websiteURL,algorithm,intentNameWhere algorithm packs the phone number and Twilio DTMF string in one
quoted field separated by a comma — e.g. "+19256593200,www5w1" = dial
+19256593200, then wait three seconds, press 5, wait one second, press
1. Server-side parser handles the quoted comma, the BOM, and Excel-style
escaped quotes.
The flow has two phases:
- Preview runs automatically when you pick a file. Reports total rows, valid rows, unique companies, and any parse errors with their row numbers. No writes yet.
- Import applies the changes: for each unique (companyName, domain)
pair the function resolves the existing company (by domain match OR by
normalized name) or creates a new one. Domain is attached via
company_domains. Each CSV row becomes acall_intentsrow, withverified_at = now()(CSV is admin-curated).
Re-importing the same CSV is idempotent — companies and intents that
already exist are skipped, not duplicated. The result panel reports
intents_skipped so you can see how many were deduped.
Admin: adding intents
For one-off additions, open Admin → Companies → [company] → edit. Scroll to the Call Intents card. Click + to add a new shortcut. Fields:
| Field | What |
|---|---|
| Intent name | Label users see, e.g. "Billing Questions". |
| Phone | E.164 number Twilio dials. Validated at save. |
| sendDigits | Twilio DTMF string. Digits 0-9, *, #, and w (0.5s wait). E.g. wwwwww5ww1. |
| ~seconds to reach | Rough seconds to navigate. Surfaces in the panel as "~7s to reach". |
| Category | Used to group intents in the UI (support / billing / cancel / etc.). |
| Mark as verified | Stamps verified_at = now(). Shows a green checkmark in the panel. |
Each row also has inline edit + delete. Changes propagate to new users immediately; cached users see them on next refresh.
Twilio DTMF format (not AWS Connect)
The sendDigits field is Twilio-native syntax — passed directly to
<Dial sendDigits="…"> inside the inline TwiML the
extension-initiate-call-intent function generates. Allowed characters:
| Char | Meaning |
|---|---|
0–9 | DTMF digit, plays near-instantly |
*, # | DTMF tones |
w (case-insensitive) | Wait 0.5 seconds |
So wwwwww5ww1 = 3-second wait → press 5 → 1-second wait → press 1.
This is not the same as AWS Connect or tel: URI syntax — Connect
uses , for pauses and has its own dialplan vocabulary. The CSV format
shipped in Algo Intent.csv is already Twilio-formatted; the importer
validates against /^[\d*#w]*$/i so anything outside that set is
rejected with a per-row error.
The admin "Add intent" form labels the sendDigits field with "(Twilio)" and shows the legend inline so the format is unambiguous on future hand-entries.
Admin: Call Tree Intel
Admin → Call Tree Intel is the analytics dashboard for the
call_intents and call_intent_calls tables. One round trip via
admin-call-tree-analytics. Sections:
- Coverage — total companies, companies with vs without intents, coverage %, total intents, average + median intents per covered company. The "Companies without intents" tile turns amber when > 0 so it's an obvious next-import target.
- By sector — companies + intents grouped by
companies.sector, sorted by intent count. Long tail collapses to a single "+ N more" row. - By industry — same shape, grouped by
companies.industry. Useful fallback whensectoris sparse. - Usage — rolling-window stats for the last 24 hours, 7 days, 14 days, and 30 days. For each window: calls placed, completed, failed, canceled, distinct users, distinct companies.
- Top called intents (last 30 days) — the ten most-bridged intents with call counts, ranked.
The data refreshes on tab open and via the Refresh button. Every metric is computed at request time — no caching layer between the panel and Postgres — so the snapshot is always live.
Admin: Twilio diagnostics
Outbound calling depends on the Twilio account that backs the project. Admin → Voice → Outbound calling (Call Intents) → Run diagnostics checks credential validity, that the outbound number is owned by this account and has Voice capability, trial-account caller-ID verification status, and any recent failed calls. Read-only — never places a real call. The detail line on each row is Twilio's response verbatim, so a failure can be pasted into a support thread without any translation step.
Security
- The user's phone number is never sent to the page context. The panel reads it from the Supabase users table via the existing profile endpoint and passes it to the initiate function over HTTPS.
- Twilio credentials live as Supabase Edge Function env vars
(
TWILIO_ACCOUNT_SID,TWILIO_AUTH_TOKEN,TWILIO_PHONE_NUMBER). The extension never sees them. - Clients pass only the intent id when initiating a call. The server
re-reads the canonical phone + sendDigits from
call_intentsso a tampered client cannot dial arbitrary numbers. - Every outbound call is logged to
call_intent_callswith the initiating user and the Twilio CallSid for audit + cancel ownership. - Phone numbers and CallSids are never logged at info level per the spec's data-handling rules.
Related
- Verified Call Trees — the navigate-yourself companion surface for the same data.
- Company Hub — where companies live in
your account; intents are seeded against
companies.id. - Privacy & retention — what's logged when, and for how long.