원클릭으로
voicebot
Build a VoiceBot data endpoint that the Voicenter Voice Agent calls mid-conversation to fetch dynamic CRM data
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Build a VoiceBot data endpoint that the Voicenter Voice Agent calls mid-conversation to fetch dynamic CRM data
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
Designs the structural skeleton of a Voicenter Bot via interview. Use this skill when the user wants to create, design, scope, or modify a Voicenter voice/chat bot — phrases like "design a bot", "create an agent spec", "build a Voicenter bot", "patch this bot", "add an intent", "change the bot's persona", "modify the flow graph", or any reference to the Agent Spec Designer / Skill 1 in the Voicenter bot generation pipeline. Produces an Agent Spec markdown file (sections 1-4, 4.5, section 5 stubs, section 6 initial, section 7 init). Two named entry modes — greenfield (no spec attached) and patch (spec attached). Does NOT author per-intent language content (validationPrompt, post-execution intentInstructions) — that's Skill 2 (Intent Detail Author). Does NOT emit wire-format JSON — that's Skill 3 (JSON Assembler).
Assembles a fully-detailed Voicenter Agent Spec into Bot JSON wire format — the final mechanical step in the three-skill pipeline. Use this skill when an Agent Spec exists with all section 5 entries marked `[detailed]` and the user wants the deployable JSON. Trigger phrases include "run Skill 3", "assemble the JSON", "emit the bot JSON", "publish the bot", "build the wire-format", "Skill 3 (JSON Assembler)", or any direct continuation from Skill 2's completion handoff. Produces a single `bot-<name>-<date>.json` file plus a banner identifying every fail-loud sentinel and any drift between spec section 6 and what Skill 3 regenerated. Refuses to assemble if any intent is still `[structural]` or `[detailed-revisit]`, or if the spec deviates from the strict template (Doc 2 §3.7). Runs the §15.4 cross-reference pass — 23 checks (8 §15.4 + 3 Compass + 3 botIntents-role + 1 duplicate-global-intent + 8 field-placement doctrine), checks 1–7, 11–13, 15, and 16–21 blocking. Does NOT author any text content (Skills 1 and
Authors the per-intent language content of a Voicenter Agent Spec — slot descriptions, validationPrompt, post-execution intentInstructions, and RT-specific Configuration text. Use this skill when an Agent Spec exists with section 5 entries marked `[structural]` or `[detailed-revisit]`, and the user wants to fill them in. Trigger phrases include "run Skill 2", "detail the intents", "fill in the per-intent fields", "Skill 2 (Intent Detail Author)", or any direct continuation from Skill 1's handoff hint. Walks intents in user-confirmed batches with a checkpoint after each batch. Reactivable — invoke as many times as needed; spec state is the resume point. Does NOT modify the structural skeleton (sections 1, 2, 3, 4, 4.5.1/.2/.4) — that's Skill 1 (Agent Spec Designer). Does NOT emit wire-format JSON — that's Skill 3 (JSON Assembler).
Pull call detail records (CDR) from Voicenter using the Call Log API
Receive and handle CDR push notifications from Voicenter after every call ends
Initiate or terminate outgoing calls using the Voicenter Click2Call API
SOC 직업 분류 기준
| name | voicebot |
| description | Build a VoiceBot data endpoint that the Voicenter Voice Agent calls mid-conversation to fetch dynamic CRM data |
Language. Reply in the user's language: detect what they write — Hebrew→Hebrew, English→English — and mirror it, switching if they switch mid-conversation. This shapes your prose, your questions, and your
AskUserQuestionoption labels only. It does not change the artifacts you produce — identifiers, JSON keys, BCP-47 language codes, API field names, and other data stay exactly as specified.
Help the developer implement a VoiceBot API endpoint — a URL that the Voicenter Voice Agent (AI bot) calls during a live conversation to retrieve dynamic CRM data before continuing.
Use this skill when the user wants to:
LAYER_ID to route logic# No outbound API token needed — Voicenter sends requests TO your server.
# Configure your endpoint URL in: Voice Agent intent settings → "URL" field under "תגובה" (Response)
Note: Pair with the External Layer API for the full pattern — External Layer passes CRM context (caller ID, tier, ticket) into CUSTOM_DATA at call start, and VoiceBot fetches dynamic data mid-conversation.
Method: POST
Content-Type: application/json
{
"CALL_INFO": {
"DID": "0722776772",
"CALLER_ID": "0501234567",
"IVR_UNIQUE_ID": "ssss1bcd7954224861f85a2d70612f2",
"DTMF": "1234",
"LAYER_ID": "10",
"PREVIOUS_LAYER_ID": "5"
},
"IntentParameters": {
"city": "Tel Aviv",
"product_interest": "Pro Plan"
},
"CUSTOM_DATA": {
"CRM_client_ID": "12345",
"Last_ticket_ID": "222",
"Last_representative": "John Doe"
}
}
| Field | Type | Description |
|---|---|---|
CALL_INFO.DID | String | The phone number the caller dialed |
CALL_INFO.CALLER_ID | String | Caller's phone number — use to look them up in CRM |
CALL_INFO.IVR_UNIQUE_ID | String | Unique call ID — correlates with CDR and other APIs |
CALL_INFO.DTMF | String | Digits the caller pressed. Default "0" if none. |
CALL_INFO.LAYER_ID | String | IVR layer ID — use to route different intents when multiple share the same endpoint |
CALL_INFO.PREVIOUS_LAYER_ID | String | Previous IVR layer ID |
IntentParameters | Object | Fields collected by the Voice Agent in this conversation so far |
CUSTOM_DATA | Object | Flat key-value data passed from External Layer API. No nested objects. |
All fields are optional. Return {} to let the agent continue with existing instructions.
| Field | Type | Description |
|---|---|---|
function_output | Object | Structured data for the agent to use. Any valid JSON — the agent reads field names and values. |
user | String[] | Instructions for the agent. Most commonly used field. Supports Markdown. |
assistant | Object | Additional influence on agent behavior. Rarely needed. |
system | Object | System-level instructions merged into the agent's base prompt. Supports Markdown. |
{
"user": [
"Tell the caller their order #123456 shipped this morning. Delivery is expected today between 2 PM and 4 PM. Ask if there is anything else they need."
]
}
{
"function_output": {
"account_balance": 180,
"plan": "Pro",
"renewal_date": "2024-08-01",
"open_tickets": 2
},
"user": [
"Read the caller their account balance and plan. Let them know they have 2 open support tickets and offer to transfer them to support."
]
}
{
"function_output": {
"orders": [
{ "id": "ORD-001", "status": "Shipped", "eta": "Today" },
{ "id": "ORD-002", "status": "Processing", "eta": "2-3 days" }
]
},
"user": [
"Read the caller their open orders. For each order, state the order ID and current status."
]
}
import express, { Request, Response } from 'express';
const app = express();
app.use(express.json());
interface VoiceBotRequest {
CALL_INFO: {
DID: string;
CALLER_ID: string;
IVR_UNIQUE_ID: string;
DTMF: string;
LAYER_ID: string;
PREVIOUS_LAYER_ID: string;
};
IntentParameters: Record<string, string>;
CUSTOM_DATA: Record<string, string>;
}
interface VoiceBotResponse {
function_output?: Record<string, unknown>;
user?: string[];
assistant?: Record<string, unknown>;
system?: Record<string, unknown>;
}
app.post('/webhooks/voicenter/voicebot', async (req: Request, res: Response) => {
const { CALL_INFO, IntentParameters, CUSTOM_DATA } = req.body as VoiceBotRequest;
try {
const crmClientId = CUSTOM_DATA.CRM_client_ID;
const layerId = CALL_INFO.LAYER_ID;
// Route logic by intent/layer ID
if (layerId === '10') {
// Order status intent
const order = await crm.getLatestOrder(crmClientId);
const response: VoiceBotResponse = {
function_output: {
order_id: order.id,
status: order.status,
eta: order.estimatedDelivery,
},
user: [
`Tell the caller their latest order (${order.id}) is currently ${order.status}. ` +
`Estimated delivery: ${order.estimatedDelivery}. Ask if they need anything else.`,
],
};
return res.json(response);
}
if (layerId === '11') {
// Account balance intent
const account = await crm.getAccount(crmClientId);
return res.json({
function_output: { balance: account.balance, currency: 'ILS', plan: account.plan },
user: ['Read the caller their account balance and current plan.'],
});
}
if (layerId === '12') {
// Appointment scheduling intent
const city = IntentParameters.city ?? '';
const slots = await crm.getAvailableSlots(city);
return res.json({
function_output: { available_slots: slots },
user: [
'Read the caller the available appointment slots in their city. ' +
'Ask which time works best and confirm the booking.',
],
});
}
// Default — agent continues with existing instructions
return res.json({});
} catch (err) {
console.error('VoiceBot endpoint error:', err);
// Always return a valid response — never let it hang or return 5xx
return res.json({});
}
});
app.listen(3000);
{} so the Voice Agent continues gracefully. Never return a 5xx or let the request hang.LAYER_ID is your routing key when multiple intents call the same endpoint — use it to run different CRM queries per intent.CUSTOM_DATA is flat — only supports simple key-value pairs (no nested objects). Use function_output in your response to return complex structured data.user field supports Markdown — use headers, bold, tables, and lists when guiding the agent through structured data like order lists or slot tables.IntentParameters contains what the agent has already collected — use it to look up records (e.g., an order number or ID the caller said aloud).CUSTOM_DATA before the VoiceBot is calledIVR_UNIQUE_ID to correlate voicebot calls with outbound Click2Call initiations