用 Wixzel Voice 執行 AI 潛在客戶篩選活動
完成後,您會上傳一份潛在客戶名單,讓您撰寫的代理透過您自己的 SIP 中繼逐一撥打並詢問您的篩選問題,再讀回每通電話的狀態和逐字稿。用 Node.js 搭配 wixzel-voice SDK 約需 30 分鐘,另加通話所需的時間。簡短的腳本式通話是最便宜的使用方式:在 classic 引擎上每接通一分鐘 $0.0867,1,000 通兩分鐘的通話,引擎時間約 $173,從預付餘額按秒計費,另加電信業者的費率。無人接聽的通話不收費。
作者:Aqeel Shamsudheen · 發布於 · 更新於
- 所需時間
- 約 30 分鐘,另加通話時間
- 引擎
- classic
- 引擎時間
- 每接通分鐘 $0.0867
開始之前需要準備什麼?
- 一個 SIP 中繼,以及登記在其上的外撥號碼。Twilio 指南和 SIP 中繼文件都有說明。
- 一把有點數的 Wixzel Voice API 金鑰,以及 Node.js 20 或更新版本,並執行
npm install wixzel-voice。 - 在法律要求的情況下,取得名單上每位潛在客戶的通話同意。下方的法規遵循步驟摘要說明了可接受使用政策的要求。
如何在 Wixzel Voice 上逐步打造?
01撰寫撥話代理
代理就是腳本。合併欄位讓每通電話都個人化:
agent.mjsimport { WixzelVoice } from 'wixzel-voice'; const client = new WixzelVoice({ apiKey: process.env.WIXZEL_API_KEY }); const agent = await client.agents.create({ name: 'Demo follow-up', outbound_phone_number_id: process.env.NUMBER_ID, system_prompt: [ 'You are calling {{name}} from {{company}}, who asked for a demo of Acme Scheduling.', 'Ask three questions, one at a time: how many staff take bookings,', 'what they use for bookings today, and when they would want to switch.', 'Keep replies short. If they are not interested, thank them and end the call.', 'If they ask not to be called again, confirm that you have noted it and end the call.', 'Finish by thanking them and saying a person will follow up by email.', ].join('\n'), opening_message: 'Hi {{name}}, this is an automated assistant calling for Acme about the demo you requested. Is now a good time?', voice: { stt: { model: 'deepgram/nova-3', language: 'en-US' }, llm: { model: 'openrouter/gpt-4o-mini' }, tts: { model: 'elevenlabs/eleven_flash_v2_5' }, }, }); console.log('AGENT_ID', agent.id);{{name}}取自潛在客戶,潛在客戶fields中的每個鍵也都會成為合併欄位,因此{{company}}來自下方的上傳資料。開場白說明來電者是自動系統,若法律要求揭露,就應放在這裡。活動必須設定outbound_phone_number_id:它是每通電話顯示的來電號碼。02上傳潛在客戶
其餘的建置都在同一個腳本
campaign.mjs中,從上傳開始:campaign.mjs, part 1import { WixzelVoice } from 'wixzel-voice'; const client = new WixzelVoice({ apiKey: process.env.WIXZEL_API_KEY }); // From your CRM or a CSV: only people you have consent to call. const rows = [ { name: 'Priya Nair', phone_number: '+14155550111', fields: { company: 'Northside Physio' } }, { name: 'Sam Carter', phone_number: '+14155550112', fields: { company: 'Carter Auto' } }, ]; const upload = await client.leads.bulkCreate({ leads: rows }); console.log('created', upload.created_count, 'failed', upload.failed_count); for (const e of upload.errors) console.log('row', e.index, e.phone_number, e.error); const leadIds = upload.data.map((lead) => lead.id);單一請求最多可上傳 1,000 位潛在客戶。資料列會逐一驗證,因此請檢查
failed_count和errors,不要假設整份名單都已上傳。批次上傳不會觸發任何 webhook。03依同時通話上限分批執行活動
一個活動就是一個代理加上一份潛在客戶名單。建立活動不會撥打任何電話;
start才會,並在每通電話接通時消耗點數。目前活動會連續快速撥出電話,而不是排隊等候,且每通電話都計入帳號的同時通話上限(預設五通)。超出上限的潛在客戶會被記錄為失敗的通話,而不會等候輪到它。因此請以不超過上限的批次執行名單,並在上一批結束後再開始下一批:
campaign.mjs, part 2const LIMIT = 5; // your account's concurrent-call limit, minus any calls you expect meanwhile const DONE = new Set(['completed', 'failed', 'busy', 'no-answer', 'canceled']); const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); async function finishedCalls(campaignId) { let finished = 0; for await (const call of await client.calls.list({ campaign_id: campaignId, limit: 100 })) { if (DONE.has(call.status)) finished++; } return finished; } const campaignIds = []; for (let i = 0; i < leadIds.length; i += LIMIT) { const batch = leadIds.slice(i, i + LIMIT); const campaign = await client.campaigns.create({ name: 'Demo follow-up ' + (i / LIMIT + 1), agent_id: process.env.AGENT_ID, lead_ids: batch, }); await client.campaigns.start(campaign.id); campaignIds.push(campaign.id); const giveUpAt = Date.now() + 30 * 60 * 1000; while ((await finishedCalls(campaign.id)) < batch.length && Date.now() < giveUpAt) { await sleep(15000); } }start回應的活動狀態為status: "running"。若要提前停止某一批,client.campaigns.pause(campaign.id)會停止活動並掛斷進行中的通話,之後活動狀態為status: "stopped"。再次啟動已停止的活動會重新撥打其中每位潛在客戶,包括已撥過的,所以若要繼續,請用尚未聯繫到的潛在客戶建立新活動。建立時設定scheduled_at,活動就會在指定時間開始,而不是在start時開始。04讀回每通電話
每通電話都是一筆紀錄,包含狀態、費用和逐字稿,並以
lead_id連結到潛在客戶:campaign.mjs, part 3for (const campaignId of campaignIds) { for await (const call of await client.calls.list({ campaign_id: campaignId, limit: 100 })) { const detail = await client.calls.retrieve(call.id); const answers = detail.transcript .filter((line) => line.role === 'user') .map((line) => line.content) .join(' / '); console.log(call.lead_id, call.status, call.duration_seconds, call.failure_code, answers); } }status表示通話是否接通,failure_code說明未接通的原因(17 忙線、19 無人接聽、21 遭電信業者拒絕),cost_micros則是費用。在撥號前因同時通話上限或點數不足而被拒絕的潛在客戶,會顯示為failed且沒有failure_code。篩選結果由您判斷。Wixzel Voice 會記錄對話;逐字稿包含三個問題的答案,請用您自己的規則或模型評分,並將結果寫入您的 CRM。
summary欄位可能是空的,請不要依賴它。若想在通話結束時即時處理而不是輪詢,請訂閱callCompletedwebhook,它會帶有潛在客戶和活動的 id,以及通話的狀態和時長。05遵守通話規範
可接受使用政策將以下責任歸於撥話方,也就是您。以下是該政策的摘要,並非法律建議。
在法律要求的情況下,只撥打給已取得同意的人。在美國,依 TCPA 規定,對手機號碼撥打行銷電話通常需要事先取得明確的書面同意;在印度,適用 TRAI 的客戶偏好規範;在英國和歐盟,則適用 PECR 和 GDPR。
每次上傳前,請比對國家及州級的拒接來電登記名單,以及您自己的排除名單。當有人要求不要再來電時,請立即且永久地移除:代理可以禮貌地結束通話,但移除潛在客戶是您程式碼的工作。
在法律要求時,於通話開始時說明來電者是自動系統(如上方的開場白),遵守通話時段限制,並依法律要求的期間保存同意的證明。
在 Wixzel Voice 上打造這個要花多少錢?
在 classic 引擎上進行 2 分鐘通話的引擎時間,以每接通分鐘 $0.0867 計算:每通約 $0.17。 電信使用您自己的中繼,按您電信業者的費率計算,不包含在內。
| 每月通話數 | 接通分鐘數 | 每月引擎費用 |
|---|---|---|
| 1,000 | 2,000 | $173 |
| 5,000 | 10,000 | $867 |
| 20,000 | 40,000 | $3,468 |
只有接通的時間會按秒計費。忙線、無人接聽或在撥號前被拒絕的通話不收費,因為引擎從未啟動。線路費用由電信業者依其費率另行收取,不加價。
預付制,沒有訂閱,也沒有免費方案:從 $5 起儲值點數,使用時從中扣除。估算您自己的使用組合。
這個實作適用哪些 Wixzel Voice 限制?
- 活動會連續快速撥打潛在客戶,不會在同時通話上限(每個帳號預設五通)之後排隊;超出的潛在客戶會被記錄為失敗。請依上限分批,或申請提高上限。
- 再次啟動已停止的活動會重新撥打其中每位潛在客戶。請用尚未聯繫到的潛在客戶建立新活動來繼續。
- 每個活動最多可包含 10,000 位潛在客戶,每個帳號預設最多 500 個活動,可申請提高。
- Wixzel Voice 會記錄通話和逐字稿。判斷誰符合資格,以及維護您的拒接來電名單,是您程式碼的工作。
- Wixzel Voice 的行為變更一律透過附日期的
Wixzel-Version標頭推出。
常見問題
如何在 Wixzel Voice 上執行外撥 AI 通話活動?
POST /v1/leads/bulk 上傳潛在客戶,以一個代理和這些潛在客戶建立活動,接著 POST /v1/campaigns/{id}/start 就會讓代理透過您自己的 SIP 中繼逐一撥打。每個活動的規模請不要超過您的同時通話上限,因為超出的潛在客戶會被標記為失敗,而不是排隊。每通電話都是一筆紀錄,包含狀態、逐字稿和費用,並以 lead_id 連結到潛在客戶。單通電話則透過 POST /v1/calls 撥打。同時可以進行多少通外撥電話?
應該用活動還是單通電話?
POST /v1/calls 能提供更細的控制:每通電話都帶有 lead_id 和冪等金鑰,由您決定何時開始下一通。AI 外撥通話合法嗎?
延伸閱讀
關於 Wixzel Voice
Wixzel Voice 是一個語音 AI API,用於打造 AI 代理,透過您自己的 SIP 中繼撥打和接聽真實的電話,或在您的網頁和行動應用程式中與人對話。一把 API 金鑰和一份預付餘額即可使用所有語音引擎,依實際用量按秒計費。
更多指南
Claude 在 Claude Code 或 claude.ai 中透過您的 SIP 中繼撥打真實電話並讀回逐字稿,撥號前一律先徵求確認。
AI 接待員接聽您現有的 Twilio 號碼,並透過 API 安排預約,以 Node.js 打造。
兩個電話代理,一個說印地語、一個說馬拉雅拉姆語,使用 Sarvam 的印度語言模型,透過您的 SIP 中繼接聽或撥出電話。
一個讓使用者透過 WebSocket 與您的語音代理對話的 Flutter 應用程式,API 金鑰保存在您的伺服器上,完全不需要電話號碼。
透過四個 cURL 請求,讓 Gemini Live 代理經由您的 SIP 中繼撥打真實電話,並取得包含逐字稿與費用的通話紀錄。
網站角落有一個會說話的吉祥物,訪客可從瀏覽器撥打給它,僅限您的網域並受每日上限約束,每位來電者都會列出。
一個有代理吉祥物的 Flutter 畫面,吉祥物在即時通話中隨代理的語音動嘴,API 金鑰保存在您的伺服器上。

