创建一个简便的自动外呼提示活动。
使用3CX Call Control API来自动化外呼活动。将电话号码列表连接到IVR系统,播放自动消息,并根据IVR菜单选择将通话转接到不同目的地。与传统外呼相比,这种方法在消息传递、呼叫路由和CRM或数据库集成方面提供了更大的灵活性。继续阅读了解更多详情和入门指南。
何时使用外呼提示活动脚本
航班取消是一个很好的例子。航空公司可以通过录制的消息通知乘客,并提供菜单选项以便连接到支持人员。
这只是一个基本用例,但可以进行扩展。您可以使用DTMF输入处理和音频流控制为外呼活动构建自定义IVR。
查看3CX官方GitHub仓库获取更多示例 呼叫处理设置和API集成
创建3CX IVR,将其添加到Call Control API访问中,并从分机列表中选择它。 呼叫初始化
客户端UI使用一个简单的文本区域来输入以逗号分隔的号码列表。
const destinations = source
.split(',')
.map((num) => num.trim())
.filter(Boolean);
队列结构逐个处理呼叫。未应答或忙线的呼叫可以排队重拨。
destinations.forEach((destNumber) => this.callQueue.enqueue(destNumber));
呼叫逻辑
下面的函数从队列中检索第一个号码并开始处理。
public async makeCallsToDst() {
if (this.callQueue.isEmpty()) return;
const destNumber = this.callQueue.dequeue();
// …
在拨号之前,系统会检查PBX连接并确保源分机未被使用。
if (!this.sourceDn || !this.externalApiSvc.connected) {
if (destNumber)
this.failedCalls.push({
callerId: destNumber,
reason: NO_SOURCE_OR_DISCONNECTED,
});
return;
}
const participants = this.getParticipantsOfDn(this.sourceDn);
if (participants && participants.size > 0) { if (destNumber) this.failedCalls.push({ callerId: destNumber, reason: CAMPAIGN_SOURCE_BUSY, }); return; }
//…
发起呼叫
呼叫使用第一个可用设备发起。
您可以在 呼叫控制状态 中找到特定DN的可用设备列表。
try {
const source = this.fullInfo?.callcontrol.get(this.sourceDn);
const device: DNDevice | undefined = source?.devices?.values().next().value;
if (!device?.device_id) {
throw new BadRequest('Devices not found');
}
const response = await this.externalApiSvc.makeCallFromDevice(
this.sourceDn,
encodeURIComponent(device.device_id),
destNumber,
);
//…
makeCallFromDevice方法使用此端点:
public makeCallFromDevice(source: string, deviceId: string, dest: string) {
const url = '/callcontrol' + `/${source}` + '/devices' + `/${deviceId}` + '/makecall';
return this.fetch!.post( url, { destination: dest, }, { headers: { ‘Content-Type’: ‘application/json; charset=utf-8’, }, }, ); }
错误处理
-------
如果**PBX接受请求**,则**存储呼叫ID**。否则,记录错误。
if (response.data.result?.id) { this.incomingCallsParticipants.set(response.data.result.id, response.data.result); } else { this.failedCalls.push({ callerId: destNumber!, reason: response?.data?.reasontext || UNKNOWN_CALL_ERROR, }); } //…
**应用程序和PBX**之间的错误在这里处理:
//… } catch (error: unknown) { if (axios.isAxiosError(error)) { this.failedCalls.push({ callerId: destNumber!, reason: error.response?.data.reasontext || UNKNOWN_CALL_ERROR, }); } else { this.failedCalls.push({ callerId: destNumber!, reason: UNKNOWN_CALL_ERROR, }); } }
参与者事件处理
------------
**(<https://www.3cx.com/docs/call-control-api-endpoints/#h.dh9ktn455jkz>)**用于跟踪IVR状态、启动新呼叫和管理参与者。
您可以在此[指南](<https://www.3cx.com/docs/call-control-api/>)中找到有关**WebSocket事件结构**和其他相关方面的更多详细信息。
private wsEventHandler = (json: string) => { try { const wsEvent: WSEvent = JSON.parse(json); if (!this.externalApiSvc.connected || !wsEvent?.event?.entity) { return; } const { dn, type } = determineOperation(wsEvent.event.entity); //…
当发生更新时,应用程序**获取并存储**新数据。
case EventType.Upset: { this.externalApiSvc .requestUpdatedEntityFromWebhookEvent(wsEvent) .then((res) => { const data = res.data; set(this.fullInfo, wsEvent.event.entity, data); // 更新本地状态 if (dn === this.sourceDn) { if (type === PARTICIPANT_TYPE_UPDATE) { /**
- 在此处理参与者更新 */ if (removed?.id) { //… if (!participants || participants?.size < 1) { // 处理程序空闲 this.makeCallsToDst(); // 继续活动 } } } } }
我们可以在WebSocket事件监听器中使用这个**事件处理程序**。
ws.on(‘message’, (buffer) => { const message = decoder.decode(buffer as Buffer); wsEventHandler(message);});
更多的呼叫流程脚本
我们的网站上有一系列呼叫流程脚本。查看它们并了解如何自动化 3CX 以满足您的需求。