Çağrı İşleme Komut Dosyası Nasıl Oluşturulur
Method group Task<CallControlResult> RouteToAsync(this ActiveConnection ac,<Destination>)
Method group Task<CallControlResult> DivertAsync(this ActiveConnection ac,<Destination>)
Method group Task<CallControlResult> ChangeWithAsync(this ActiveConnection ac,<Destination>)
Giriş
Rota Noktası olarak da adlandırılan çağrı işleme komut dosyaları, V20'nin güçlü ve yeni bir özelliğidir. Çağrıları yakalamanıza ve bunları standart C# kodunu kullanarak işlemenize olanak tanır; esasen size bir çağrıyı analiz etmek ve özel mantık uygulamak için sınırsız olanaklar sunar. Burada bir çift örnek var:
- Arayanın numarasını analiz edin ve belirli temsilcileri atayın
- Arayanın numarasına göre müşteri aramaları yapın ve buna göre yönlendirin
Çağrı İşleme API'sine Genel Bakış
API, çağrıları yeni hedefe ileten üç temel yöntemden oluşur.
Method group Task<CallControlResult>RouteToAsync(this ActiveConnection ac,<Destination>)
Bu yöntem belirtilen ac bağlantısına bağlı bir rota oluşturur
- ac - RoutePoint'e ait aktif bağlantı. Yeni hedef yanıt verdiğinde bağlantısı ac’nin yerini alır. (RoutePoint'in katılımı).
- Komut dosyası görev hatalarını ele almalıdır. Komut dosyası, arayanla kendi bağlantısını sonlandırmak için MyCall.Return’u çağırabilir.
- Komut dosyası ihtiyaç duyduğu kadar rota oluşturmaya çalışabilir, ancak ilk yanıtlanan rota diğer tüm rotaları iptal edecek ve RoutePoint'in çağrıya katılımının yerini alacaktır (RoutePoint çağrısını sonlandıracaktır).
- RouteToAsync, RoutePoint bağlantısının herhangi bir durumunda yürütülebilir. Dolayısıyla rota noktası, Arayan ile iletişim kurarken arka planda yönlendirme gerçekleştirebilir (istemleri oynatma, DTMF'leri yönetme vb.).
- Görev başarılı olduğunda, RoutePoint'ten çağrı iptal edilir (MyCall'ın bağlantısı kesilir) ve yeni hedef işlemeye devam eder.
Method group Task<CallControlResult> DivertAsync(this ActiveConnection ac,<Destination>)
Bu yöntem, bağlantı kurmadan (yanıtlamadan) (RoutePoint'te çalmadan) çağrıyı yeni hedefe yönlendirir.
- RoutePoint ile zaten bir çağrı kurulmuşsa yöntem başarısız olur ve RouteToAsyc/ReplaceWithAsync kullanılmalıdır.
- RoutePoint'e ait olan aktif bağlantı (çalma durumunda) yeni bir hedefle değiştirilecek ve RoutePoint'in çağrıyla bağlantısı kesilecektir.
- Bu yöntem, rota noktasının arayanla etkileşime girmesi gerekmiyorsa kullanışlıdır.
- Bir görev başarısız olursa, komut dosyası arayanla bağlantıyı sürdürmeye devam edebilir.
- Görev başarılı olduğunda, çağrı RoutePoint'ten iptal edilir (MyCall bağlantısı sonlandırılır) ve yeni hedef çağrıyı işlemeye başlar. RoutePoint betiği Sarma moduna geçirilir ve kendi işini bitirmesi gerekir.
Method group Task<CallControlResult> ChangeWithAsync(this ActiveConnection ac,<Destination>)
“Kör transfer” yöntemi olarak da bilinir.
- Yalnızca bağlı modda izin verilir (RoutePoint çağrıyı kabul eder ve kullanılanla etkileşime girer).
- Arayan beklemeye alınacaktır.
- Hedefe ulaşılamazsa görev başarısız olur.
- Komut dosyası, görev hatasından sonra çağrıyı işlemeye devam edebilir (eğer arayan hala RoutePoint'e bağlıysa).
- Bir görev başarılı olduğunda, komut dosyası bağlantısı (ICallHandler.MyCall) sonlandırılır ve komut dosyası çağrı yönetiminden ayrılır (yeni katılımcı arayanla ilgilenir).
Örnek Çağrı İşleme Komut Dosyası
Bu örnek, özel bir rota noktasının nasıl oluşturulacağını ve bunun nasıl programlanacağını gösterir:
- RoutePoint'e sağlanan C# kodunun temel yapısı
- ActiveConnection (ICall) arayüzü için TCX.PBXAPI.CallControlAPI abone yöntemlerinin Temel Kullanımı
- Temel CallFlowScriptingCore tarafından sağlanan MyCall nesnesiyle çalışma
- Temel Yapılandırmayla çalışma (PBX parametreleri)
- ActiveConnection Nesnesinin RouteToAsyc abone yöntemini kullanma
RoutePoint işlevselliğine bir örnek:
- Rota noktası yalnızca telefondan (Dahili) kör aktarım kullanılarak gönderilen çağrıları kabul etmektedir. Doğrudan aramalar reddedilir.
- Bu RoutePoint'e herhangi bir abone tarafından aynı anda sınırsız çağrı aktarılabilir (her çağrı ayrı ayrı ele alınır)
- Çağrı, 15 saniye sonra doğrudan aktarıcıya (dahili) geri döndürülür (yönlendirme uygulanmaz). Geri dönüş yapılan çağrıya 15 saniye içinde cevap verilmemesi durumunda çağrı iptal edilir ve 15 saniye içinde tekrarlanır.
- Arayan, PBX'te Park etme için yapılandırıldığı için bekleme müziğini duyar.
Nasıl çalıştırılır
- Herhangi bir sayı ile bir RoutingPoint oluşturun - örneğin#101 - ve RoutePoint.ScriptCode özelliğini aşağıdaki metne ayarlayın (Kullanıcı arayüzü hala özel (elle yazılmış kod) ile yönlendirme noktası oluşturmaya izin vermiyor, bir tür zip dosyası gerektirir, bu aslında gerekli değildir) basit komut dosyası için)
- RoutePoint ilgili listede (şu anda “CFD uygulamaları”) yeşil noktayla görünmelidir [derleme bu kod için başarısız olmamalıdır])
- Daha sonra:
- Herhangi bir abone çağrısını #101 numaralı aboneye aktarırsa, çağrıya 15 saniye içinde geri dönüş yapılacaktır.
- Arayan, Park etme için yapılandırıldığı için beklemedeki müziği duyacaktır. (Komut dosyası bu ayarı kullanır ancak arayan için başka içerik oluşturmak üzere kod değiştirilebilir).
- Geri dönen çağrı yanıtlanmazsa, RoutePoint önceki denemeden 15 saniye sonra, arayan kişi çağrıyı bırakana veya orijinal aktaran kişi yanıt verene (veya çağrısı alınana) kadar tekrar (ve tekrar) deneyecektir.
Kod için yorumlar
- “Scripted” nesnenin kodu (use, implements ve/veya inherits) temeline dayanır.
- CallFlow ad alanı
- CallFlow.ICall
- CallFlow.ICallHandler
- CallFlow.ICallHandlerEx
- CallFlow.ScriptBase<T>
- “Script object” sınıfı, CallFlow.ScriptBase<T>’yi devralmalı ve örneği için gereken tüm soyut yöntemleri uygulamalıdır.
- ScriptingHost, çağrı işleyicisini ICallHandler.Start yöntemini kullanarak yürüttüğünde nesne çalışıyor.
- Komut dosyası açıkça ICall.Return ile sonlandırılmalıdır.
- ICall.Start yönteminin tercih edilen uygulaması, bağımsız görevi çalıştıran "async void" yöntemidir (tüm istisnaları yakalamalıdır).
- Komut dosyası uygulaması yalnızca Komut Dosyası Ana Bilgisayarı tarafından sunulan MyCall nesnesini kontrol etmelidir. Çağrı komut dosyası oturumunun tek konusu budur.
- MyCall (çağrıya rota noktasının katılımı) sona erdiğinde, komut dosyası uygulaması tamamlanmalı ve oturumu sonlandırılmalıdır.
- Çağrı akışı komut dosyası, sistem yapılandırmasını veya herhangi bir dış kaynağı izlemenin bir yolu değildir.
- Sistemdeki tüm çağrıları izlemenin bir yolu değildir.
- Bu sadece diğer çağrı akışlarıyla entegre edilebilen bir RoutePoint mantığıdır.
- Başka bir deyişle: script, RoutePoint'e bağlı çağrılardan birini yönetir, ancak asla yeni bir çağrı başlatmaz.
- Yönlendirme API'si, abone yöntemlerini ortaya çıkaran TCX.PBXAPI.CallControlAPI statik sınıfına kapsüllenmiştir
- TCX.Configuration.ActiveCannection
- TCX.Yapılandırma.DN
- TCX.Configuration.RegistrarRecord
Örnek Kod
#nullable disable
using CallFlow;
using System;
using System.Threading;
using System.Threading.Tasks;
using TCX.Configuration;
using TCX.PBXAPI;
namespace dummy
{
public class ParkingRoutePointSample : ScriptBase<ParkingRoutePointSample>
{
async Task<CallControlResult> ProcessAutoPickup(RoutePoint sp, DestinationStruct returnTo, CancellationToken token)
{
while (true)
try
{
return await Task.Delay(TimeSpan.FromSeconds(15), token).ContinueWith(x =>
{
MyCall.Trace("{0} - automatic redirection of the call from {1}.{2} to '{3}'", MyCall.DN, MyCall.Caller?.CallerID, MyCall.Caller?.DN, returnTo);
return MyCall.RouteToAsync(new RouteRequest
{
RouteTarget = returnTo,
TimeOut = TimeSpan.FromSeconds(15) //will ring until failure
}
);
}
, TaskContinuationOptions.NotOnCanceled).Unwrap();
}
catch (OperationFailed ex)
{
MyCall.Trace("Automatic redirection failed: {0}", ex.TheResult);
MyCall.Trace("Continue hold call from {0}({1}) on {2}", MyCall.Caller?.CallerID, MyCall.Caller?.DN, MyCall.DN);
continue;
}
}
PhoneSystem ps = null;
/// <summary>
///
/// </summary>
public override async void Start()
{
await Task.Run(async () =>
{
try
{
MyCall.Debug($"Script start delay: {DateTime.UtcNow - MyCall.LastChangeStatus}");
MyCall.Debug($"Incoming connection {MyCall}");
ps = MyCall.PS as PhoneSystem;
CallControlResult lastresult = null;
DN referredBy = null;
RoutePoint thisPark = null;
string callerID = "";
DN callerDN = null;
bool scriptCompleted = true;
try
{
referredBy = MyCall.ReferredByDN?.GetFullSnapshot() as Extension;
thisPark = MyCall.DN?.Clone() as RoutePoint;
callerID = MyCall.Caller?.CallerID;
callerDN = MyCall.Caller?.DN?.Clone() as DN;
MyCall.Trace(
"Parked call from {0}({1}) on {2}", callerID, callerDN, thisPark
);
if (referredBy == null)
{
MyCall.Trace("{0} rejects call from {1}. Reason: No referrer specified", thisPark, callerDN);
return;
}
var cancelationToken = new CancellationTokenSource();
MyCall.OnTerminated += () =>
{
cancelationToken.Cancel();
};
lastresult = await MyCall.AssureMedia().ContinueWith(
x =>
{
if(!string.IsNullOrWhiteSpace(ps.GetParameterValue("PARK_MOH_SOURCE")))
MyCall.SetBackgroundAudio(true, new string[] { ps.GetParameterValue("PARK_MOH_SOURCE") });
else
MyCall.SetBackgroundAudio(true, new string[] { ps.GetParameterValue("MUSICONHOLDFILE") });
return ProcessAutoPickup(thisPark, new DestinationStruct(referredBy), cancelationToken.Token);
}, TaskContinuationOptions.OnlyOnRanToCompletion).Unwrap();
}
catch (PBXIsNotConnected ex)
{
MyCall.Error($"Call control API is not available:\n{ex}");
scriptCompleted = false;
}
catch (TaskCanceledException)
{
MyCall.Trace($"Call was disconnected from parking place");
}
catch (Exception ex)
{
MyCall.Error($"Parking failure:\n{ex}");
scriptCompleted = false;
}
finally
{
try
{
MyCall.Info("Call from {0}({1}) parked by {2} on {3} finished with result={4}", callerID, callerDN, referredBy, thisPark, lastresult?.ToString() ?? "terminated");
}
catch (Exception ex)
{
MyCall.Error($"SharedParkingFlow finalize exception {ex}");
}
MyCall.Return(scriptCompleted);
}
}
catch
{
MyCall.Return(false);
}
});
}
}
}
Son güncelleme
Bu belge en son 05 Mart 2024'te güncellendi
https://www.3cx.com.tr/docs/yonetici-kilavuzu/cagri-isleme-komut-dosyasi/
