ஒவ்வொரு அழைப்புக்கும் டைனமிக் உள்ளமைவு
இயல்பாக, ஒவ்வொரு தொலைபேசி எண்ணுக்கும் வெளியிடக்கூடிய விசைக்கும் ஒரு நிலையான ஏஜென்ட் ஒதுக்கப்பட்டிருக்கும். ஒவ்வொரு அழைப்பாளருக்கும் அல்லது ஒவ்வொரு பார்வையாளருக்கும் தனிப்பயனாக்கம் தேவைப்படும்போது — VIP வழிமாற்றம், உள்நுழைந்த பயனர் சூழல், A/B prompt சோதனைகள் — வெப்ஹுக் பயன்முறைக்கு மாறி, உங்கள் சர்வரை முடிவெடுக்க விடுங்கள்.
இது எப்படி செயல்படுகிறது
- நீங்கள்
telephony.incoming(தொலைபேசி) அல்லதுweb.incoming(விட்ஜெட்) நிகழ்வுக்கு சந்தா செய்கிறீர்கள். இரண்டும் தடுக்கும் வெப்ஹுக்குகள்: அழைப்பைத் தொடர்வதற்கு முன் ThunderPhone உங்கள் பதிலுக்காக அதிகபட்சம் 10 வினாடிகள் காத்திருக்கும். - ThunderPhone உங்களுக்கு
{call_id, from_number, to_number}அனுப்பும் (விட்ஜெட் அமர்வுகள் எண்களுக்குப் பதிலாக விட்ஜெட்டுக்கான புலங்களைக் கொண்டிருக்கும் — கோரிக்கை வடிவமைப்பைப் பார்க்கவும்). - உங்கள் சர்வர் ஒரு ஏஜென்ட் உள்ளமைவுடன் (prompt, குரல், தயாரிப்பு, கருவிகள்) பதிலளிக்கும். ThunderPhone அந்த உள்ளமைவை அழைப்பிற்குப் பயன்படுத்தும்.
- நீங்கள்
{}-ஐத் திருப்பியனுப்பினால், நேரம் முடிந்தால் அல்லது பிழை ஏற்பட்டால், நிலையாக ஒதுக்கப்பட்ட ஏஜென்ட் மாற்று வழியாகப் பயன்படுத்தப்படும். பாதுகாப்பான இயல்புநிலை.
1. வெப்ஹுக் இலக்கை உள்ளமைக்கவும்
தொலைபேசி அழைப்புகள்
தொலைபேசி எண்களுக்காக, உங்கள் எண்ட்பாயிண்ட்டை telephony.incoming-க்கு சந்தா செய்யுங்கள்:
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "Prod call-incoming",
"url": "https://example.com/thunderphone/incoming",
"events": ["telephony.incoming"]
}'
பதில் ஒருமுறை மட்டுமே பயன்படும் secret-ஐக் கொண்டிருக்கும் — அதைச் சேமியுங்கள்; கையொப்பச் சரிபார்ப்புக்கு அதைப் பயன்படுத்துவீர்கள்.
வலை விட்ஜெட்
விட்ஜெட் அமர்வுகளுக்காக, உங்கள் எண்ட்பாயிண்ட் URL உட்பொதிக்கப்பட்ட mode="webhook"-இல் ஒரு வெளியிடக்கூடிய விசையை உருவாக்குங்கள்:
curl -X POST https://api.thunderphone.com/v1/publishable-key \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Dynamic widget",
"mode": "webhook",
"webhook_url": "https://example.com/thunderphone/widget-incoming",
"allowed_domains": ["example.com"]
}'
ஒவ்வொரு அமர்வு தொடக்கத்திலும் விட்ஜெட் இந்த URL-க்கு POST செய்யும்.
2. ஹேண்ட்லரை செயல்படுத்துங்கள்
மூன்று நடைமுறை விதிகள்:
- ஒவ்வொரு கோரிக்கையிலும் கையொப்பத்தைச் சரிபார்க்கவும் (webhook கையொப்பங்களைச் சரிபார்க்கவும் என்பதைப் பார்க்கவும்). டெவலப்மெண்டில் இதைத் தவிர்க்காதீர்கள் — ஒருமுறை சரியாக அமைத்து மீண்டும் பயன்படுத்துங்கள்.
- விரைவாகப் பதிலளிக்கவும். பத்து விநாடிகள் என்பது கடுமையான வரம்பு; ஒவ்வொரு விநாடியும் அழைப்பாளருக்கு அமைதியான நேரமாகும். தேவைப்பட்டால் தரவுத்தளத் தேடல்களைச் செய்யுங்கள், ஆனால் கீழ்நிலை LLMகளை ஒத்திசைவாக அழைக்காதீர்கள் — டைனமிக் prompt உருவாக்கம் தேவைப்பட்டால், முன்கூட்டியே கணக்கிட்டு கேஷ் செய்யுங்கள்.
- சரியாக ஃபால்பேக் செய்யவும். எதிர்பாராத எந்த நிலையிலும்
{}-ஐத் திருப்பி அனுப்ப வேண்டும்; அப்போது நிலையாக ஒதுக்கப்பட்ட ஏஜென்ட் அழைப்பைக் கையாளும்.
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, sig: str) -> bool:
expected = hmac.new(SECRET.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sig or "")
@app.post("/thunderphone/incoming")
async def incoming(request: Request):
body = await request.body()
if not verify(body, request.headers.get("X-ThunderPhone-Signature", "")):
raise HTTPException(401)
event = json.loads(body)
if event["type"] not in ("telephony.incoming", "web.incoming"):
return {} # fall back to default
caller = event["data"]["from_number"]
# Cheap DB lookup: is this a known VIP?
customer = lookup_customer(caller)
if customer and customer.tier == "vip":
return {
"prompt": f"You are a VIP concierge for {customer.name}. Be proactive…",
"voice": "john",
"product": "storm-base",
}
return {} # default agent handles non-VIPs
def lookup_customer(phone: str):
# ... your CRM integration ...
pass
import crypto from "node:crypto";
import express from "express";
const app = express();
const SECRET = process.env.THUNDERPHONE_WEBHOOK_SECRET;
function verify(body, sig) {
const expected = crypto.createHmac("sha256", SECRET).update(body).digest("hex");
return sig &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
}
app.post(
"/thunderphone/incoming",
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"));
const IMPORTANT_TYPES = new Set([
"telephony.incoming",
"web.incoming",
]);
if (!IMPORTANT_TYPES.has(event.type)) return res.json({});
const customer = await lookupCustomer(event.data.from_number);
if (customer?.tier === "vip") {
return res.json({
prompt: `You are a VIP concierge for ${customer.name}. Be proactive…`,
voice: "john",
product: "storm-base",
});
}
res.json({}); // fall back to default agent
},
);
3. பதில் ஸ்கீமா
பதில் உடல் வரும் அழைப்பு பதில் ஸ்கீமா-வுடன் துல்லியமாகப் பொருந்தும். பொதுவாகப் பயன்படுத்தப்படும் புலங்கள்:
| புலம் | வகை | விளக்கம் |
|---|---|---|
prompt | string (தேவை) | ஏஜென்ட்டிற்கான சிஸ்டம் prompt |
voice | string (தேவை) | GET /v1/voices-இலிருந்து குரல் id |
product | string | இயல்புநிலை spark |
background_track | string | null | சூழல் ஆடியோ id |
acknowledgement_prompt_mode | string | auto அல்லது manual (ack-உடன் Storm மட்டும்) |
acknowledgement_prompt | string | பயன்முறை manual ஆக இருக்கும்போது தேவை |
tools | array | இன்லைன் செயல்பாட்டு-கருவி ஸ்கீமாக்கள் — செயல்பாட்டு கருவிகள் என்பதைப் பார்க்கவும் |
வடிவங்கள்
உள்நுழைந்த பயனர் சூழல்
Webhook பயன்முறை விட்ஜெட்களில், வருகையாளரின் பக்கத்திற்கே அவர்கள் யார் என்பது ஏற்கனவே தெரியும். விட்ஜெட் SDK முன்னனுப்பும் query string அளவுருவுடன் (?customer_id=123) உங்கள் webhook-ஐ அழைத்து, சர்வர் பக்கத்தில் வாடிக்கையாளரைத் தேடுங்கள்.
A/B prompt வெளியீடு
இதை நீங்களே உருவாக்குவதற்கு முன், ThunderPhone-இல் வகைகளை வரையறுத்து, டிராஃபிக்கைப் பிரித்து, ஒவ்வொரு வகைக்குமான விளைவுகளை ஒப்பிடும் சொந்த சோதனைகள் அம்சம் (/dashboard/experiments மற்றும் ஏஜென்ட் பில்டரின் A/B தாவல்) உள்ளது என்பதை நினைவில் கொள்ளுங்கள் — webhook தேவையில்லை.
எப்படியும் webhook-பக்கக் கட்டுப்பாடு தேவைப்பட்டால்: call_id-ஐ hash செய்து → bucket-ஆகப் பிரியுங்கள்; 0..49 க்கு prompt A-ஐயும் 50..99 க்கு prompt B-ஐயும் வழங்குங்கள். நீங்கள் தேர்ந்தெடுத்த bucket-ஐ உங்கள் சொந்த DB-யில் பதிவு செய்து, பின்னர் முடிக்கப்பட்ட அழைப்பின் தரத்துடன் தொடர்புபடுத்துங்கள்.
நேர அடிப்படையிலான வழிமாற்றம்
வணிக நேரம் → "நேரடி ஆதரவு" ஏஜென்ட்; வணிக நேரத்திற்குப் பிறகு → "செய்தியைப் பெறும்" ஏஜென்ட். உங்கள் handler-இல் new Date().getUTCHours() அடிப்படையில் எளிய switch பயன்படுத்துங்கள்.
அடுத்த படிகள்
ஒவ்வொரு உள்ளமைவு விசையையும் உள்ளடக்கிய துல்லியமான கோரிக்கை + பதில் schema-கள்.
HMAC-ஐ ஒருமுறை சரியாக அமைத்து, எல்லா இடங்களிலும் மீண்டும் பயன்படுத்துங்கள்.
டைனமிக் வழிமாற்றத்தை ஒவ்வொரு ஏஜென்டுக்குமான tool-களுடன் இணைக்குங்கள்.
மீண்டும் முயற்சிகள், வரிசைப்படுத்தல், நேரம் முடிவுகள்.