Open in
telephony.complete / web.complete
ಕರೆ ಮುಗಿದಾಗ, ಟ್ರಾನ್ಸ್ಕ್ರಿಪ್ಟ್, ರೆಕಾರ್ಡಿಂಗ್ URL ಮತ್ತು ಮೆಟ್ರಿಕ್ಗಳೊಂದಿಗೆ ತಡೆರಹಿತ ವೆಬ್ಹುಕ್ ವಿತರಿಸಲಾಗುತ್ತದೆ.
ಪ್ರತಿ ಕರೆ ಮುಗಿದ ನಂತರ ಪೂರ್ಣಗೊಳಿಸುವಿಕೆ ಈವೆಂಟ್ ಸಕ್ರಿಯಗೊಳ್ಳುತ್ತದೆ — ಒಳಬರುವ ಟೆಲಿಫೋನಿ, ಹೊರಹೋಗುವ ಟೆಲಿಫೋನಿ, ವೆಬ್ ಕರೆ, ಅಥವಾ ಪರೀಕ್ಷಾ ಕರೆ (ಬಿಲ್ಡರ್ ಮೈಕ್ ಸೆಷನ್). ಇದು ತಡೆಯಿಲ್ಲದ್ದು: ಯಾವುದೇ 2xx ನೊಂದಿಗೆ ಪ್ರತಿಕ್ರಿಯಿಸಿ.
ಈವೆಂಟ್ ಎರಡೂ ಮಾರ್ಗಗಳಲ್ಲಿ ವಿತರಿಸಲಾಗುತ್ತದೆ:
- ವೆಬ್ಹುಕ್ ಎಂಡ್ಪಾಯಿಂಟ್ಗಳು ಗೆ
telephony.complete(ಫೋನ್ ಕರೆಗಳು) ಅಥವಾweb.complete(ವೆಬ್ ಕರೆಗಳು ಮತ್ತು ಬಿಲ್ಡರ್ ಮೈಕ್ ಪರೀಕ್ಷಾ ಕರೆಗಳು) ಕೆಳಗೆ ದಾಖಲಿಸಿರುವ ಸ್ಥಿರ ಪೇಲೋಡ್ನೊಂದಿಗೆ, ಪ್ರತಿ ವಿತರಣೆಗೆ ಒಂದುevent_id, 30 ಸೆಕೆಂಡಿನ ಸಮಯಮಿತಿ, ಮತ್ತು 24 ಗಂಟೆಗಳವರೆಗೆ ಮರುಪ್ರಯತ್ನಗಳು ದೊರೆಯುತ್ತವೆ. - ಲೆಗಸಿ ಏಕ-URL ವೆಬ್ಹುಕ್ ಸ್ವಲ್ಪ ವಿಭಿನ್ನ ಪೇಲೋಡ್ನೊಂದಿಗೆ ಒಂದು ಸಮಕಾಲಿಕ ಪ್ರಯತ್ನವನ್ನು ಪಡೆಯುತ್ತದೆ (10 ಸೆಕೆಂಡಿನ ಸಮಯಮಿತಿ, ಮರುಪ್ರಯತ್ನಗಳಿಲ್ಲ) — ನೋಡಿ ಲೆಗಸಿ ಪೇಲೋಡ್ ವ್ಯತ್ಯಾಸಗಳು.
ವಿನಂತಿ ಪೇಲೋಡ್ (ಎಂಡ್ಪಾಯಿಂಟ್ ವಿತರಣೆಗಳು)
{
"data": {
"billable_minutes": 1.25,
"billing_total_cents": 8,
"call_id": 987654321,
"direction": "inbound",
"duration_seconds": 54,
"end_reason": "user_hangup",
"end_time": "2026-04-20T18:25:04.822Z",
"extracted_data": {
"status": "completed",
"fields": {
"customer_name": "Alex Morgan",
"appointment_date": "2026-04-23"
},
"evidence": {
"customer_name": {
"quote": "My name is Alex Morgan",
"speaker_role": "caller",
"turn_index": 4
},
"appointment_date": {
"quote": "April 23 works for me",
"speaker_role": "caller",
"turn_index": 7
}
},
"verification": "verified",
"field_reasons": {},
"schema_version": "92850758e231a3c95a..."
},
"from_number": "+14155550199",
"product": "spark",
"recording_url": "https://storage.example.com/…",
"start_time": "2026-04-20T18:24:10.113Z",
"status": "completed",
"to_number": "+15551234567",
"transcripts": [ /* see Transcript format */ ],
"transfer_number": null,
"unresolved_variables": ["campaign_owner"],
"variables": {"campaign_name": "Spring renewals"},
"voice": "john"
},
"event_id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
"type": "telephony.complete"
}| ಕ್ಷೇತ್ರ | ಪ್ರಕಾರ | ವಿವರಣೆ |
|---|---|---|
call_id | ಪೂರ್ಣಾಂಕ | ಈ ಕರೆಯ ಪ್ರತಿಯೊಂದು ಈವೆಂಟ್ನಲ್ಲಿಯೂ ಸ್ಥಿರವಾಗಿರುತ್ತದೆ |
agent_id | ಪೂರ್ಣಾಂಕ | null | ನಿಯೋಜಿಸಿದ್ದರೆ, ಕರೆಯನ್ನು ನಿರ್ವಹಿಸಿದ ಏಜೆಂಟ್ |
agent_name | ಸ್ಟ್ರಿಂಗ್ | null | ನಿಯೋಜಿಸಿದ್ದರೆ, ಕರೆಯನ್ನು ನಿರ್ವಹಿಸಿದ ಏಜೆಂಟ್ |
direction | ಸ್ಟ್ರಿಂಗ್ | inbound, outbound, web, test. ಐತಿಹಾಸಿಕ ಪೇಲೋಡ್ಗಳು ಹಳೆಯ mic ಅಥವಾ widget ಮೌಲ್ಯಗಳನ್ನು ಹೊಂದಿರಬಹುದು |
from_number, to_number | ಸ್ಟ್ರಿಂಗ್ | E.164. ವೆಬ್ ಕರೆಗಳು ಮತ್ತು ಪರೀಕ್ಷಾ ಕರೆಗಳಿಗೆ from_number ಅಕ್ಷರಶಃ "web" ಆಗಿರುತ್ತದೆ |
origin_domain | ಸ್ಟ್ರಿಂಗ್ | ವೆಬ್/ಪರೀಕ್ಷೆಗೆ ಮಾತ್ರ — ವಿಜೆಟ್ ಅನ್ನು ಹೋಸ್ಟ್ ಮಾಡಿದ ಪುಟದ ಒರಿಜಿನ್ (ಮೈಕ್ ಸೆಷನ್ಗಳಿಗೆ ಖಾಲಿ) |
start_time, end_time | ಟೈಮ್ಸ್ಟ್ಯಾಂಪ್ | ISO 8601 UTC |
duration_seconds | ಪೂರ್ಣಾಂಕ | null | ಪ್ರಾರಂಭ/ಅಂತ್ಯದಿಂದ ಪಡೆಯಲಾಗಿದೆ |
status | ಸ್ಟ್ರಿಂಗ್ | completed ಅಥವಾ failed |
end_reason | ಸ್ಟ್ರಿಂಗ್ | ಕೆಳಗಿನ ಕೋಷ್ಟಕವನ್ನು ನೋಡಿ |
product, voice | ಸ್ಟ್ರಿಂಗ್ | ಕರೆ ಸಮಯದಲ್ಲಿ ಜಾರಿಯಲ್ಲಿದ್ದ ಏಜೆಂಟ್ ಕಾನ್ಫಿಗರೇಶನ್ |
variables | ಆಬ್ಜೆಕ್ಟ್ | ಕರೆ ಪ್ರಾರಂಭವಾದಾಗ ಸ್ನ್ಯಾಪ್ಶಾಟ್ ಮಾಡಿದ ಇನ್ಪುಟ್ ವೇರಿಯಬಲ್ಗಳು |
unresolved_variables | ಅರೇ | ಕರೆ ಕಾನ್ಫಿಗ್ ಉಲ್ಲೇಖಿಸಿದ, ಆದರೆ ಕರೆ ಪ್ರಾರಂಭದಲ್ಲಿ ಒದಗಿಸದ ವೇರಿಯಬಲ್ ಹೆಸರುಗಳು |
transfer_number | ಸ್ಟ್ರಿಂಗ್ | null | ಕರೆಯನ್ನು ವರ್ಗಾಯಿಸಿದಾಗ ಹೊಂದಿಸಲಾಗುತ್ತದೆ |
recording_url | ಸ್ಟ್ರಿಂಗ್ | null | ಅವಧಿ ಮುಗಿಯುವ ಸಹಿ ಮಾಡಿದ URL; ತಕ್ಷಣ ಡೌನ್ಲೋಡ್ ಮಾಡಿ. ಯಾವುದೇ ರೆಕಾರ್ಡಿಂಗ್ ಆರ್ಟಿಫ್ಯಾಕ್ಟ್ ಲಭ್ಯವಿಲ್ಲದಾಗ null |
billable_minutes | ಸಂಖ್ಯೆ | ಬಿಲ್ ಮಾಡಲಾದ ನಿಮಿಷಗಳು, ಹತ್ತಿರದ ಕಾಲು ನಿಮಿಷಕ್ಕೆ ರೌಂಡ್ ಮಾಡಲಾಗಿದೆ (15-ಸೆಕೆಂಡ್ ಏರಿಕೆಗಳು, ಕನಿಷ್ಠ 0.25). ನೇರವಾಗಿ ವಾಯ್ಸ್ಮೇಲ್ಗೆ ಹೋಗುವ ಕರೆಗಳು ಸಹ ತಮ್ಮ ನಿಜವಾದ ಮೀಟರ್ ಮಾಡಿದ ನಿಮಿಷಗಳನ್ನು ಇಲ್ಲಿ ವರದಿ ಮಾಡುತ್ತವೆ, ಆದರೆ ಶುಲ್ಕವನ್ನು ಪ್ಲಾನ್ ದರದಲ್ಲಿ ಒಂದು ನಿಮಿಷಕ್ಕೆ ಮಿತಿಗೊಳಿಸಲಾಗುತ್ತದೆ. |
billing_total_cents | ಪೂರ್ಣಾಂಕ | USD ಸೆಂಟ್ಗಳು |
transcripts | ಅರೇ | ಪ್ರತಿ-ತಿರುವಿನ ಟ್ರಾನ್ಸ್ಕ್ರಿಪ್ಟ್ ನಮೂದುಗಳು; ಟ್ರಾನ್ಸ್ಕ್ರಿಪ್ಟ್ ಲಭ್ಯವಿಲ್ಲದಾಗ ಖಾಲಿಯಾಗಿರಬಹುದು |
extracted_data | ಆಬ್ಜೆಕ್ಟ್ | null | status, fields, evidence, verification, field_reasons, ಮತ್ತು schema_version ಹೊಂದಿರುವ ರಚನಾತ್ಮಕ ಹೊರತೆಗೆಯುವಿಕೆ ಫಲಿತಾಂಶ. ಪ್ರತಿ null-ಅಲ್ಲದ ಕ್ಷೇತ್ರವು ನಿಖರವಾದ ರಚನಾತ್ಮಕವಾಗಿ ಪರಿಶೀಲಿಸಿದ ಉಲ್ಲೇಖವನ್ನು (ಗರಿಷ್ಠ 1,000 ಅಕ್ಷರಗಳು) ಹಾಗೂ ಅದರ ಮಾತನಾಡುವವರ ಪಾತ್ರ ಮತ್ತು ತಿರುವಿನ ಸೂಚಿಯನ್ನು ಹೊಂದಿರುತ್ತದೆ; ದೀರ್ಘವಾದ ಮಾಡೆಲ್-ಹಿಂತಿರುಗಿಸಿದ ಉಲ್ಲೇಖಗಳನ್ನು ಮೊಟಕುಗೊಳಿಸುವ ಬದಲು ತಿರಸ್ಕರಿಸಲಾಗುತ್ತದೆ. ಕ್ಷೇತ್ರವು null ಆಗಿದ್ದಾಗ ಸಾಕ್ಷ್ಯವು null ಆಗಿರುತ್ತದೆ. verified ಎಂದರೆ ಪ್ರತಿ ಅಭ್ಯರ್ಥಿಯು ನಿಖರವಾಗಿ ಒಂದು ಮಾನ್ಯ ಸ್ವತಂತ್ರ ತೀರ್ಪನ್ನು ಪಡೆದಿದೆ ಎಂದರ್ಥ. unavailable ದೋಷಪೂರಿತ ಅಥವಾ ಭಾಗಶಃ ವೆರಿಫೈಯರ್ ಔಟ್ಪುಟ್ ಅನ್ನೂ ಒಳಗೊಂಡಿರುತ್ತದೆ; ಮಾನ್ಯ ಭಾಗಶಃ ತೀರ್ಪುಗಳು ಇನ್ನೂ ಅನ್ವಯವಾಗುತ್ತವೆ, ಆದರೆ ಒಂದು ಮಾನ್ಯ ತೀರ್ಪೂ ಇಲ್ಲದ ಅಭ್ಯರ್ಥಿಗಳನ್ನು null ಮಾಡಲಾಗುತ್ತದೆ. status ಎಂಬುದು completed, failed, exhausted, skipped, ಅಥವಾ skipped_recording_disabled; ಏಜೆಂಟ್ಗೆ ಯಾವುದೇ ಹೊರತೆಗೆಯುವಿಕೆ ಕ್ಷೇತ್ರಗಳಿಲ್ಲದಾಗ null |
ಅಂತ್ಯದ ಕಾರಣಗಳು
| ಮೌಲ್ಯ | ಅರ್ಥ |
|---|---|
user_hangup | ದೂರದ ಪಕ್ಷವು ಮೊದಲು ಕರೆ ಸ್ಥಗಿತಗೊಳಿಸಿತು |
ai_hangup | AI ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ ಕರೆಯನ್ನು ಕೊನೆಗೊಳಿಸಿತು |
ai_transfer | AI ಕರೆಯನ್ನು ವರ್ಗಾಯಿಸಿತು; transfer_number ಹೊಂದಿಸಲಾಗಿದೆ |
ai_warm_transfer | AI ವಾರ್ಮ್ (ಹಾಜರಿದ್ದು ನಡೆಸುವ) ವರ್ಗಾವಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿತು |
voicemail_hangup | ವಾಯ್ಸ್ಮೇಲ್ ಪತ್ತೆಯಾಯಿತು ಮತ್ತು ನಿಮ್ಮ voicemail_action ಪ್ರಕಾರ ಕರೆ ಕೊನೆಗೊಂಡಿತು |
max_duration | ಕರೆ ಗರಿಷ್ಠ ಅವಧಿಯ ಮಿತಿಯನ್ನು ತಲುಪಿತು |
superseded | ಸೆಷನ್ ಅನ್ನು ಹೊಸದಾದ ಸೆಷನ್ ಬದಲಿಸಿತು |
unknown | ಅಂತ್ಯದ ಕಾರಣವನ್ನು ನಿರ್ಧರಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ |
ಪ್ರತಿಲಿಪಿ ಸ್ವರೂಪ
transcripts ನಲ್ಲಿನ ಪ್ರತಿಯೊಂದು ನಮೂದು ಒಂದು ಸಂಭಾಷಣೆಯ ಸರದಿಯಾಗಿದೆ. ಪಾತ್ರಗಳು
user (ಕರೆಮಾಡುವವರ ಮಾತು), model (ಏಜೆಂಟ್ನ ಮಾತು ಮತ್ತು ಸಾಧನ ಕರೆಯುವಿಕೆಗಳು),
tool (ಸಾಧನ ಫಲಿತಾಂಶಗಳು), ಮತ್ತು system (ಭಾಷೆ ಬದಲಾವಣೆಗಳಂತಹ ಕರೆ
ಘಟನೆಗಳು) ಆಗಿವೆ.
[
{
"role": "user",
"content_type": "text/plain",
"content": "Hi, I'm calling about my appointment.",
"start_ms": 1200,
"end_ms": 4100,
"audio_url": "https://storage.example.com/…"
},
{
"role": "model",
"content_type": "text/plain",
"content": "Sure, what date works best?",
"start_ms": 4200,
"end_ms": 6100
},
{
"role": "model",
"content_type": "application/json",
"content": {
"tool_call": "search_appointments",
"arguments": { "date": "2026-04-21" }
}
},
{
"role": "tool",
"content_type": "application/json",
"content": {
"tool_name": "search_appointments",
"response": { "available_slots": ["9:00 AM", "2:00 PM"] }
}
}
]| ಕ್ಷೇತ್ರ | ಪ್ರಕಾರ | ವಿವರಣೆ |
|---|---|---|
role | ಸ್ಟ್ರಿಂಗ್ | user, model, tool, ಅಥವಾ system |
content_type | ಸ್ಟ್ರಿಂಗ್ | ಮಾತಿಗಾಗಿ text/plain; ಸಾಧನ ಕರೆಯುವಿಕೆಗಳು, ಸಾಧನ ಫಲಿತಾಂಶಗಳು ಮತ್ತು ಸಿಸ್ಟಮ್ ಘಟನೆಗಳಿಗಾಗಿ application/json |
content | ಸ್ಟ್ರಿಂಗ್ | ಆಬ್ಜೆಕ್ಟ್ | ಮಾತಿನ ಪಠ್ಯ, ಅಥವಾ ಮೇಲೆ ತೋರಿಸಿರುವ ರಚನಾತ್ಮಕ ಆಬ್ಜೆಕ್ಟ್. ಸಾಧನ ಕರೆಯುವಿಕೆಗಳು: {"tool_call": name, "arguments": {…}}. ಸಾಧನ ಫಲಿತಾಂಶಗಳು: {"tool_name": name, "response": {…}} |
start_ms, end_ms | ಪೂರ್ಣಾಂಕ | ಕರೆ ಆರಂಭದಿಂದ ಆಫ್ಸೆಟ್ಗಳು, ms. ಆಡಿಯೊ ಸಮಯದ ಮಾಹಿತಿ ತಿಳಿದಿರುವಾಗ ಇರುತ್ತವೆ |
ttfa_ms | ಪೂರ್ಣಾಂಕ | ಅಳತೆ ಮಾಡಿದಾಗ, model ಸರದಿಯ ಮೊದಲ ಆಡಿಯೊ ತಲುಪುವ ಸಮಯ |
audio_url, audio_urls | ಸ್ಟ್ರಿಂಗ್ / ಅರೆ | ಪ್ರತಿ ಸರದಿಗೆ ರೆಕಾರ್ಡ್ ಮಾಡಿದಾಗ, ಆ ಸರದಿಯ ಆಡಿಯೊಗಾಗಿ ಅವಧಿ ಮುಗಿಯುವ ಸಹಿ ಮಾಡಿದ URLಗಳು |
ಅಡಚಣೆ ಗುರುತುಗಳು, ದೃಢೀಕರಣ ಪ್ರಾಂಪ್ಟ್ಗಳು ಮತ್ತು ಮೂಲ ಸ್ಥಾನಗಳನ್ನು ಒಳಗೊಂಡ ಸಂಪೂರ್ಣ
ರಚನಾತ್ಮಕ ಸರದಿ ಇತಿಹಾಸಕ್ಕಾಗಿ,
GET /v1/calls/{call_id}/history ಬಳಸಿ.
ಹಳೆಯ ಪೇಲೋಡ್ ವ್ಯತ್ಯಾಸಗಳು
ಹಳೆಯ ಏಕ-URL ವೆಬ್ಹುಕ್ ಎನ್ವಲಪ್
{"type": "telephony.complete" | "web.complete", "data": {…}} ಆಗಿದ್ದು,
ಇದರಲ್ಲಿ event_id ಇರುವುದಿಲ್ಲ, ಮತ್ತು ಇದರ data ಎಂಡ್ಪಾಯಿಂಟ್ ಪೇಲೋಡ್ನಿಂದ ಭಿನ್ನವಾಗಿದೆ:
ಹಳೆಯ ಪೂರ್ಣಗೊಳಿಸುವಿಕೆ ಪೇಲೋಡ್ನಲ್ಲಿ agent_id ಮತ್ತು agent_name ಸಹ ಇರುತ್ತವೆ.
- ಸರದಿ ಅರೆ
transcriptsಅಡಿಯಲ್ಲಿ ಅಲ್ಲ,historyಅಡಿಯಲ್ಲಿರುತ್ತದೆ (ಮೇಲಿನಂತೆಯೇ ಸರದಿ ಸ್ಕೀಮಾ). - ಕ್ಷೇತ್ರಗಳ ಸೆಟ್ ಮೂಲ ಕರೆ-ಅಂತ್ಯ ವರದಿಯಾಗಿದ್ದು, ಮೇಲಿನ ಕೋಷ್ಟಕದ ಆಚೆಗೆ ಹೆಚ್ಚುವರಿ ಆಂತರಿಕ ಕ್ಷೇತ್ರಗಳನ್ನು ಒಳಗೊಂಡಿರಬಹುದು — ಅಜ್ಞಾತ ಕ್ಷೇತ್ರಗಳನ್ನು ಮಾಹಿತಿಗಾಗಿ ಮಾತ್ರವೆಂದು ಪರಿಗಣಿಸಿ.
- ವೆಬ್ ಕರೆಗಳು (
direction: "web")from_number/to_numberಅನ್ನು ಬಿಟ್ಟುಬಿಡುತ್ತವೆ ಮತ್ತುorigin_domainಅನ್ನು ಸೇರಿಸುತ್ತವೆ. - ಬಿಲ್ಡರ್ ಮೈಕ್ರೊಫೋನ್ ಪರೀಕ್ಷಾ ಕರೆಗಳು ಹಳೆಯ ಮಾರ್ಗದಲ್ಲಿ
telephony.completeಎಂದು ವರದಿಯಾಗುತ್ತವೆ (ಎಂಡ್ಪಾಯಿಂಟ್ ಸಿಸ್ಟಮ್ ಅವುಗಳನ್ನುweb.completeಗೆ ಮ್ಯಾಪ್ ಮಾಡುತ್ತದೆ). - ವರ್ಗಾವಣೆ ಸಮನ್ವಯ: ಒಂದು ಕರೆ ವರ್ಗಾವಣೆಯಲ್ಲಿ ಕೊನೆಗೊಂಡಾಗ, ಹಳೆಯ ವೆಬ್ಹುಕ್ ಅನ್ನು
ಸಿಂಕ್ರೋನಸ್ ಆಗಿ ಕರೆಯಲಾಗುತ್ತದೆ ಮತ್ತು ಹಸ್ತಾಂತರ ಗುರಿಯು ಸಿದ್ಧವಾಗಿಲ್ಲ ಎಂಬುದನ್ನು
ಸೂಚಿಸಲು
{"transfer_ready": false}ಎಂದು ಉತ್ತರಿಸಬಹುದು. ಇತರೆ ಯಾವುದೇ ಪ್ರತಿಕ್ರಿಯೆ (ಅಥವಾ ಹಳೆಯ ವೆಬ್ಹುಕ್ ಇಲ್ಲದಿರುವುದು) ವರ್ಗಾವಣೆಯನ್ನು ಮುಂದುವರಿಯಲು ಅನುಮತಿಸುತ್ತದೆ. ಇದಕ್ಕಾಗಿ ಎಂಡ್ಪಾಯಿಂಟ್ ವಿತರಣೆಗಳನ್ನು ಎಂದಿಗೂ ಪರಿಶೀಲಿಸಲಾಗುವುದಿಲ್ಲ.
ಉದಾಹರಣೆ ಹ್ಯಾಂಡ್ಲರ್
import hashlib
import hmac
import json
import os
from fastapi import FastAPI, HTTPException, Request
app = FastAPI()
SECRET = os.environ["THUNDERPHONE_WEBHOOK_SECRET"]
def verify(body: bytes, signature: str) -> bool:
expected = hmac.new(SECRET.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature or "")
@app.post("/thunderphone-webhook")
async def webhook(request: Request):
body = await request.body()
if not verify(body, request.headers.get("X-ThunderPhone-Signature", "")):
raise HTTPException(status_code=401)
event = json.loads(body)
if event["type"] in ("telephony.complete", "web.complete"):
data = event["data"]
# Endpoint deliveries use "transcripts"; the legacy webhook uses "history".
turns = data.get("transcripts") or data.get("history") or []
await persist_call_record(
call_id=data["call_id"],
turns=turns,
recording_url=data.get("recording_url"),
)
if data["end_reason"] in ("ai_transfer", "ai_warm_transfer"):
await notify_team(data.get("transfer_number"), data["call_id"])
return {"ok": True}import crypto from "node:crypto";
import express from "express";
const app = express();
const SECRET = process.env.THUNDERPHONE_WEBHOOK_SECRET;
function verify(body, signature) {
const expected = crypto.createHmac("sha256", SECRET).update(body).digest("hex");
return signature &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
app.post(
"/thunderphone-webhook",
express.raw({ type: "application/json" }),
async (req, res) => {
if (!verify(req.body, req.header("X-ThunderPhone-Signature"))) {
return res.sendStatus(401);
}
const event = JSON.parse(req.body.toString("utf8"));
if (["telephony.complete", "web.complete"].includes(event.type)) {
const data = event.data;
// Endpoint deliveries use "transcripts"; the legacy webhook uses "history".
const turns = data.transcripts ?? data.history ?? [];
await persistCallRecord({ ...data, turns });
if (["ai_transfer", "ai_warm_transfer"].includes(data.end_reason)) {
await notifyTeam(data.transfer_number, data.call_id);
}
}
res.json({ ok: true });
},
);ಸಾಮಾನ್ಯ ಬಳಕೆಯ ಸಂದರ್ಭಗಳು
ಪ್ರತಿ ಕರೆಯ ಟ್ರಾನ್ಸ್ಕ್ರಿಪ್ಟ್ ಮತ್ತು ರೆಕಾರ್ಡಿಂಗ್ URL ಅನ್ನು ನಿಮ್ಮ ಗ್ರಾಹಕ ದಾಖಲೆಗಳ ಜೊತೆಗೆ ಸಂಗ್ರಹಿಸಿ.
ವಿಷಯ ಮಾದರೀಕರಣ, CSAT ಸಿಗ್ನಲ್ ಹೊರತೆಗೆಯುವಿಕೆ ಅಥವಾ ವರ್ಗಾವಣೆ ದರ ಮೇಲ್ವಿಚಾರಣೆಗಾಗಿ ಟ್ರಾನ್ಸ್ಕ್ರಿಪ್ಟ್ಗಳನ್ನು ಪೈಪ್ಲೈನ್ಗೆ ಸ್ಟ್ರೀಮ್ ಮಾಡಿ.
ಮಾನವ ಪರಿಶೀಲನೆಗಾಗಿ ಕರೆಗಳನ್ನು QA ಉಪಕರಣದಲ್ಲಿ ತೆರೆಯಿರಿ, ಅಥವಾ ಅವುಗಳನ್ನು ನಿಮ್ಮ ಸ್ವಂತ ಮೌಲ್ಯಮಾಪನ ಮಾದರಿಯ ಮೂಲಕ ಚಲಾಯಿಸಿ.
ವರ್ಗಾವಣೆ / ವೈಫಲ್ಯದ ಸಂದರ್ಭದಲ್ಲಿ ಮಾನವ ತಂಡದ ಸದಸ್ಯರನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ.