DoodSoft.CallCenterApi
3.0.0
dotnet add package DoodSoft.CallCenterApi --version 3.0.0
NuGet\Install-Package DoodSoft.CallCenterApi -Version 3.0.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="DoodSoft.CallCenterApi" Version="3.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DoodSoft.CallCenterApi" Version="3.0.0" />
<PackageReference Include="DoodSoft.CallCenterApi" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add DoodSoft.CallCenterApi --version 3.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: DoodSoft.CallCenterApi, 3.0.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package DoodSoft.CallCenterApi@3.0.0
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=DoodSoft.CallCenterApi&version=3.0.0
#tool nuget:?package=DoodSoft.CallCenterApi&version=3.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
CallCenterApi
DotNet.CallCenterApi 用于对接广州多度软件科技有限公司的 AXB 直拨、双向回拨、SIP 直拨以及 AI 外呼平台,便于快速集成到业务系统。
支持平台
netstandard2.0- 可用于
.NET Framework 4.6.1+、.NET 6+及其他兼容netstandard2.0的运行时
安装
dotnet add package DoodSoft.CallCenterApi
快速开始
1)注册服务
using DotNet.CallCenterApi;
// 注册内存缓存服务,仅AI外呼时才需要,需引用依赖包:Microsoft.Extensions.Caching.Memory,也可以注入其它 IDistributedCache 缓存实现,例如 Redis,可以使用 services.AddDistributedRedisCache
// builder.Services.AddDistributedMemoryCache();
// 注册呼叫中心组件
builder.Services.AddCallCenter();
2)配置接口凭证
方式 A:直接创建凭证
var verify = new Verify("accessKey", "accessSecret");
// 如需自定义指定当前请求服务地址:
// var verify = new Verify("https://xxx.com", "accessKey", "accessSecret");
方式 B:使用 VerifyContainer 管理多线路、多凭证
// 需要引入依赖包 Microsoft.Extensions.Configuration.Json
// 创建 IConfiguration 实例,从配置文件中加载凭证,一个线路可以多个凭证
var verifyService = serviceProvider.GetRequiredService<VerifyContainer>();
verifyService.SetVerify(ApiLineType.AXB, configuration.GetSection("CallCenterApiSettings:AXB").Get<Verify[]>());
verifyService.SetVerify(ApiLineType.SIP, configuration.GetSection("CallCenterApiSettings:SIP").Get<Verify[]>());
verifyService.SetVerify(ApiLineType.AI, configuration.GetSection("CallCenterApiSettings:AI").Get<Verify[]>());
// 获取指定线路所有凭证
//var verifyList = verifyService.GetVerify(ApiLineType.AXB);
// 获取指定线路所有座席,一般用于给员工分配电话座席时,需要选择电话座席
//var agentList = verifyService.GetAllAgentInfoByLineType(ApiLineType.AXB);
// 根据座席ID获取对应的凭证,一般用于拨打电话时,可以直接根据员工电话座席ID获取到凭证
//var verify = verifyService.GetVerifyByAgentId(ApiLineType.AXB, 1001);
// 根据座席手机号或SIP分机号获取线路凭证,一般用于拨打电话时,可以直接根据员工的座席号码获取到凭证
//var verify = verifyService.GetVerifyByAgentPhone(ApiLineType.AXB, "13888888888");
// 根据座席手机号或SIP分机号获取对应的座席ID,一般用于拨打电话时,通过号码转换为座席ID
//var agentId = verifyService.GetAgentIdByPhone(ApiLineType.AXB, "13888888888");
// 根据座席手机号或SIP分机号获取对应的凭证和座席ID,好处是一次性获取,无需多调用
var valueTuple = await verifyService.GetVerifyAndAgentIdByAgentPhone(ApiLineType.AXB, "13888888888");
Debug.WriteLine(valueTuple.Verify);//接口凭证,可能为null
Debug.WriteLine(valueTuple.AgentId);//座席ID
if(valueTuple.AgentId == null)
{
Debug.WriteLine($"主叫号码 【13888888888】 未开通座席,请咨询客服人员");
}
// 根据凭证Key获取凭证信息
//var verify = service.GetVerifyByAccessKey(ApiLineType.AXB, "accessKey");
appsettings.json 配置文件示例:
{
"CallCenterApiSettings": {
"AXB": [
{
"AccessKey": "key1",
"AccessSecret": "secret1"
}
],
"SIP": [
{
"AccessKey": "key2",
"AccessSecret": "secret2"
}
],
"AI": [
{
"AccessKey": "key3",
"AccessSecret": "secret3"
}
]
}
}
3)常用业务调用
var type = ApiLineType.AXB;
//参考第2步中的方案,获取凭证信息,也可以直接创建
var verify = new Verify("accessKey", "accessSecret");
// 查询余额
var service = ServiceProvider.GetRequiredKeyedService<ICallCenterBase>(type);
var result = await service.GetBalance(verify);
Debug.WriteLine($"{result.Success} {result.Message}");
Debug.WriteLine($"企业帐户余额为 {result.Data.Balance.ToString()}");
// 发起呼叫
var service = ServiceProvider.GetRequiredKeyedService<ICallCenter>(type);
var result = await service.CallNumber(verify, callNumber);
Debug.WriteLine($"{result.Success} {result.Message}");
if (result.Success)
{
Debug.WriteLine($"BindId: {result.Data.BindId} 座席ID:{result.Data.AgentId} 座席号码: {callNumber.Caller} 小号/分机号: {result.Data.ExtNumber}");
}
// 获取座席列表
var service = ServiceProvider.GetRequiredKeyedService<ICallCenterBase>(type);
var result = await service.GetAgent(verify);
Debug.WriteLine($"{result.Success} {result.Message}");
// 获取企业小号列表
var service = ServiceProvider.GetRequiredKeyedService<ICallCenter>(type);
var result = await service.GetTelX(verify, new ApiTelXQuery());
foreach (var info in result.Data)
{
Debug.WriteLine($"{info.Phone} {info.AreaCode} {info.AreaName}");
}
// 修改座席小号
var service = ServiceProvider.GetRequiredKeyedService<ICallCenter>(type);
var result = await service.EditAgentTelX(DefaultVerify, new ApiAgentTelXEdit() { AgentId = agent.AgentId, Phone = "13888888888,02088888888" });
Debug.WriteLine($"{result.Success} {result.Message}");
回调推送解析
建议将回调接口配置为匿名访问,收到请求后先构造 ApiHttpContext,再通过 GetCmd 识别命令并解析数据。
/// <summary>
/// 获取请求的上下文信息
/// </summary>
/// <returns></returns>
private async Task<ApiHttpContext> GetApiHttpContext()
{
var body = await this.ActionContext.Request.Content.ReadAsStringAsync();
var nameValueCollection = new NameValueCollection();
foreach (var item in this.ActionContext.Request.Headers)
{
nameValueCollection.Add(item.Key, item.Value.FirstOrDefault());
}
var httpContext = new ApiHttpContext(this.ActionContext.Request.RequestUri.ToString(),
this.ActionContext.Request.Method.Method, nameValueCollection, body);
return httpContext;
}
/// <summary>
/// 用于AXB系统话单推送
/// </summary>
/// <returns></returns>
[AllowAnonymous]
[HttpPost, ActionName("callLogs")]
public async Task<IHttpActionResult> CallLogs()
{
ApiHttpContext httpContext = null;
httpContext = await GetApiHttpContext();
var callcenter = ServiceProvider.GetRequiredKeyedService<ICallCenter>(ApiLineType.AXB);
var cmd = callcenter.GetCmd(httpContext);
if (cmd == ApiCommand.PushCallInfo)
{
var list = callcenter.ResolveCallInfo(httpContext);
if (list != null)
{
foreach (var callerDto in list)
{
//保存话单到数据库
SaveCallCdr(callerDto);
}
}
}
this.ActionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
{
Content = new StringContent(httpContext.Response, Encoding.UTF8, "application/json")
};
return this.ResponseMessage(this.ActionContext.Response);
}
/// <summary>
/// 用于SIP系统话单推送
/// </summary>
/// <returns></returns>
[AllowAnonymous]
[HttpPost, ActionName("pushCallDetail")]
public async Task<IHttpActionResult> PushCallDetail()
{
ApiHttpContext httpContext = await GetApiHttpContext();
var callcenter = ServiceProvider.GetRequiredKeyedService<ICallCenter>(ApiLineType.SIP);
var cmd = callcenter.GetCmd(httpContext);
if (cmd == ApiCommand.PushCallInfo)
{
var list = callcenter.ResolveCallInfo(httpContext);
if (list != null)
{
foreach (var callerDto in list)
{
//保存话单到数据库
SaveCallCdr(callerDto);
}
}
}
this.ActionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
{
Content = new StringContent(httpContext.Response, Encoding.UTF8, "application/json")
};
return this.ResponseMessage(this.ActionContext.Response);
}
/// <summary>
/// 用于AI系统话单推送
/// </summary>
/// <returns></returns>
[AllowAnonymous]
[HttpPost, ActionName("aiCallback")]
public async Task<IHttpActionResult> AiCallback()
{
ApiHttpContext httpContext = await GetApiHttpContext();
var callcenter = ServiceProvider.GetRequiredKeyedService<IAiCallCenter>(ApiLineType.AI);
var cmd = callcenter.GetCmd(httpContext);
if (cmd == ApiCommand.PushCallInfo)
{
var aiCallInfo = callcenter.ResolveCallInfo(httpContext);
if (aiCallInfo != null)
{
//保存话单到数据库
SaveCallCdr(aiCallInfo);
}
}
else if (cmd == ApiCommand.CallTaskInfo)
{
var taskStatusInfo = callcenter.ResolveTaskStatusInfo(httpContext);
if (taskStatusInfo != null)
{
//保存任务状态到数据库
SaveCallTaskByTaskId(taskStatusInfo.TaskId);
}
}
this.ActionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
{
Content = new StringContent(httpContext.Response, Encoding.UTF8, "application/json")
};
return this.ResponseMessage(this.ActionContext.Response);
}
自定义服务地址
默认无需配置,组件已内置官方服务地址。若需动态覆盖,可使用以下方式。
1)注册时指定
builder.Services.AddCallCenter(options =>
{
options.AXB_ServerUrl = "https://axb.xxx.com";
options.SIP_ServerUrl = "https://sip.xxx.com";
options.AI_ServerUrl = "https://aicall.xxx.com";
});
2)创建凭证时指定(优先级最高)
var verify = new Verify("https://xxx.com", "accessKey", "accessSecret");
AI 供应商切换
支持三种实现:Default、PsyAi、AICC。
builder.Services.AddCallCenter(options =>
{
options.AI_Provider = AiProvider.PsyAi;
});
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- Microsoft.Extensions.Caching.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Http (>= 10.0.8)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.8)
- Newtonsoft.Json (>= 13.0.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.