Kolay otomatik arama için giden çağrı istemi kampanyası oluşturun.
Giden arama kampanyalarını otomatikleştirmek için 3CX Çağrı Kontrol API kullanın. Bir telefon numara listesini bir IVR’ye bağlayın, otomatik bir mesaj oynatın ve aramaları IVR menü seçimlerine göre farklı hedeflere aktarın. Geleneksel giden aramanın aksine, bu yöntem mesajlaşma, çağrı yönlendirme ve CRM veya veritabanı entegrasyonunda esneklik sağlar. Daha fazlasını öğrenmek ve nasıl başlayacağınızı öğrenmek için okumaya devam edin.
Giden İstem Kampanyası Komut Dosyası Ne Zaman Kullanılır

Uçuş iptali mükemmel bir örnektir. Bir havayolu yolcuları kayıtlı bir mesajla bilgilendirebilir ve onları desteğe bağlamak için menü seçenekleri sunabilir.
Bu temel bir kullanım örneğidir ancak genişletilebilir. Giden kampanyalar için DTMF giriş işleme ve ses akışı kontrolüne sahip özel bir IVR oluşturabilirsiniz.
Daha fazla örnek için Resmi 3CX GitHub deposuna bakın
Çağrı İşleme Kurulumu ve API Entegrasyonu
Bir 3CX IVR oluşturun, Çağrı Kontrol API Erişimine ekleyin ve Aboneler listesinden seçin.
Çağrı Başlatma
İstemci kullanıcı arayüzü, virgülle ayrılmış bir numara listesi girmek için basit bir metin alanı kullanır.
const destinations = source
.split(',')
.map((num) => num.trim())
.filter(Boolean);
Bir kuyruk yapısı çağrıları tek tek işler. Cevaplanmayan veya meşgul çağrılar yeniden arama için kuyruğa alınabilir.
destinations.forEach((destNumber) => this.callQueue.enqueue(destNumber));
Mantık Çağrısı
Aşağıdaki fonksiyon kuyruktan ilk numarayı alır ve işlemeye başlar.
public async makeCallsToDst() {
if (this.callQueue.isEmpty()) return;
const destNumber = this.callQueue.dequeue();
// …
Arama yapılmadan önce sistem PBX bağlantısını kontrol eder ve kaynak abonenin kullanımda olmadığından emin olur.
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;
}
//…
Arama Yapma
Arama, ilk mevcut cihaz kullanılarak yapılır.
Çağrı Kontrol Durumu içinde belirli bir DN için kullanılabilir cihazların listesini bulabilirsiniz.
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 yöntemi şu uç noktayı kullanır:
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',
},
},
);
}
Hata İşleme
PBX isteği kabul ederse, çağrı kimliği saklanır. Aksi halde, bir hata kaydedilir.
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,
});
}
//…
Uygulama ile PBX arasındaki hatalar burada ele alınır:
//...
} 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,
});
}
}
Katılımcı Etkinlik Yönetimi
Bir WebSocket bağlantısı IVR durumunu izler, yeni aramalar başlatır ve katılımcıları yönetir.
Bu kılavuzda WebSocket olay yapısı ve diğer ilgili yönler hakkında daha fazla ayrıntı bulabilirsiniz.
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);
//...
Bir güncelleme gerçekleştiğinde uygulama yeni verileri alır ve depolar.
case EventType.Upset:
{
this.externalApiSvc
.requestUpdatedEntityFromWebhookEvent(wsEvent)
.then((res) => {
const data = res.data;
set(this.fullInfo, wsEvent.event.entity, data); // update local state
if (dn === this.sourceDn) {
if (type === PARTICIPANT_TYPE_UPDATE) {
/**
* handle here update of participants
*/
}
}
})
.catch((err) => {
if (axios.isAxiosError(err)) {
console.error(`AXIOS ERROR code: ${err.response?.status}`);
} else console.error('Unknown error', err);
});
}
break;
Bu URL’yi, güncellenmiş varlığı talep etmek ve uygulamamız için artımlı bir durum güncellemesi gerçekleştirmek için kullanabilirsiniz (DN Güncelleme Talebini kontrol edin):
public requestUpdatedEntityFromWebhookEvent(ws: WSEvent) {
return this.fetch.get(ws.event.entity);
}
Bir katılımcı çıkarıldığında kampanya devam eder.
case EventType.Remove: {
const removed = set(this.fullInfo, wsEvent.event.entity, undefined);
if (dn === this.sourceDn) { // update related to our campaign handler
if (type === PARTICIPANT_TYPE_UPDATE) {// update related to call participant
/**
* handle here removed participants
*/
if (removed?.id) {
//...
if (!participants || participants?.size < 1) { // Handler is free
this.makeCallsToDst(); // continue with campaign
}
}
}
}
}
Bu olay işleyicisini WebSocket olay dinleyicisi içinde kullanabiliriz.
ws.on('message', (buffer) => {
const message = decoder.decode(buffer as Buffer);
wsEventHandler(message);
});
Daha Fazla Çağrı Akışı Komut Dosyası Mevcut
Web sitemizde bir çağrı akışı komut dosyası koleksiyonumuz var. Bunları inceleyin ve ihtiyaçlarınıza uyacak şekilde 3CX’i nasıl otomatikleştirebileceğinizi görün.



