Bitzsoft.Integrations.OutboundCall.Twilio
1.0.1
dotnet add package Bitzsoft.Integrations.OutboundCall.Twilio --version 1.0.1
NuGet\Install-Package Bitzsoft.Integrations.OutboundCall.Twilio -Version 1.0.1
<PackageReference Include="Bitzsoft.Integrations.OutboundCall.Twilio" Version="1.0.1" />
<PackageVersion Include="Bitzsoft.Integrations.OutboundCall.Twilio" Version="1.0.1" />
<PackageReference Include="Bitzsoft.Integrations.OutboundCall.Twilio" />
paket add Bitzsoft.Integrations.OutboundCall.Twilio --version 1.0.1
#r "nuget: Bitzsoft.Integrations.OutboundCall.Twilio, 1.0.1"
#:package Bitzsoft.Integrations.OutboundCall.Twilio@1.0.1
#addin nuget:?package=Bitzsoft.Integrations.OutboundCall.Twilio&version=1.0.1
#tool nuget:?package=Bitzsoft.Integrations.OutboundCall.Twilio&version=1.0.1
Bitzsoft.Integrations.OutboundCall.Twilio
Twilio Programmable Voice 外呼实现 — per-call 模型 + 客户端 campaign 编排,手写 HttpClient + HTTP Basic 鉴权,实现 IOutboundCallService 统一接口。
功能特性
- 实现
IOutboundCallService统一接口:创建 / 启动 / 暂停 / 恢复 / 停止活动 + 活动列表 / 详情 + 话单查询 - per-call 模型:Twilio 无原生 campaign 概念,campaign 元数据与联系人维护在本库内存中;
StartCampaign经共享CampaignDialer按 CPS 节流逐个发起外呼 - 暂停 / 恢复 / 停止:代次守卫(Generation)防止暂停 / 恢复后新旧循环重叠与重复记账;停止即终态
- TwiML 内容:支持内联 TwiML(
Twiml)或回调 URL(Url)指定呼叫内容;提供BuildInlineTwiml(text)生成中文Say语音 - 答答检测(AMD):可选启用
EnableMachineDetection,用于预测式外呼场景 - 429 退避重试:内置指数退避,429 触发重试最多 3 次(退避基数 200ms × attempt)
- 白名单 / 黑名单过滤:复用
CallListFilter - 手写 HttpClient:不依赖 Twilio SDK(net5.0 兼容)
限制:campaign 状态存内存(
ConcurrentDictionary),进程重启后丢失;StartCampaign可凭已导入联系人重跑,话单仍可从 Twilio 查询。已结束 / 停止的 campaign 仍驻留内存伴随 Singleton 生命周期,长时间高吞吐主机需按内存预算或定期重启。
安装
.NET CLI
dotnet add package Bitzsoft.Integrations.OutboundCall.Twilio
PackageReference
<PackageReference Include="Bitzsoft.Integrations.OutboundCall.Twilio" Version="1.0.0" />
配置
appsettings.json
{
"TwilioOutboundCall": {
"AccountSid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"AuthToken": "your-auth-token",
"From": "+12025550123",
"Twiml": "<Response><Say language=\"zh-CN\">您好</Say></Response>",
"Url": null,
"Cps": 1,
"EnableMachineDetection": false,
"StatusCallback": "https://your-host/twilio/status",
"Domain": "api.twilio.com",
"Version": "2010-04-01"
}
}
| 配置项 | 说明 | 必填 | 默认值 |
|---|---|---|---|
AccountSid |
Twilio 账户 SID | 是 | 空字符串 |
AuthToken |
Twilio 鉴权 Token(HTTP Basic 密码) | 是 | 空字符串 |
From |
默认主叫号(E.164 格式,如 +12025550123) |
是 | 空字符串 |
Twiml |
内联 TwiML(与 Url 二选一) |
否 | null |
Url |
TwiML 回调 URL(与 Twiml 二选一,有 Url 时优先走路由) |
否 | null |
Cps |
每秒并发呼叫数(账号级节流) | 否 | 1 |
EnableMachineDetection |
是否启用答答检测(预测式外呼) | 否 | false |
StatusCallback |
状态回调 URL | 否 | null |
Domain |
API 域名 | 否 | api.twilio.com |
Version |
API 版本 | 否 | 2010-04-01 |
注册服务
委托配置
using Bitzsoft.Integrations.OutboundCall.Twilio;
// 命名空间 Microsoft.Extensions.DependencyInjection
builder.Services.AddTwilioOutboundCall(options =>
{
options.AccountSid = "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
options.AuthToken = "your-auth-token";
options.From = "+12025550123";
options.Twiml = TwilioOutboundCallOptions.BuildInlineTwiml("您好,这是外呼通知");
options.Cps = 1;
});
从 IConfiguration 绑定
builder.Services.AddTwilioOutboundCall(
builder.Configuration.GetSection("TwilioOutboundCall"));
说明:
AddTwilioOutboundCall接收Action<TwilioOutboundCallOptions>配置委托,绑定TwilioOutboundCallOptions,注册 internalTwilioCallHttpClient为 typed client(挂载请求审计日志),并将TwilioOutboundCallService注册为IOutboundCallService单例。
使用示例
创建活动并启动拨号
using Bitzsoft.Integrations.OutboundCall;
using Bitzsoft.Integrations.OutboundCall.Dtos;
using Bitzsoft.Integrations.OutboundCall.PhoneNumber;
public class NotifyService
{
private readonly IOutboundCallService _outbound;
public NotifyService(IOutboundCallService outbound) => _outbound = outbound;
public async Task RunAsync(string[] rawPhones)
{
var (_, oversea) = PhoneNumberClassifier.Classify(rawPhones);
// 创建活动(号码入内存,未开始拨号)
var resp = await _outbound.CreateCampaignAsync(new CreateCampaignRequest
{
Name = "通知外呼",
Region = PhoneRegion.Overseas,
Callees = oversea.ToList()
});
// 启动:后台按 CPS 节流逐个 POST /Calls
await _outbound.StartCampaignAsync(new StartCampaignRequest { CampaignId = resp.CampaignId });
}
}
暂停 / 恢复 / 停止 + 话单查询
// 暂停(保留断点)→ 恢复(从断点继续)→ 停止(终态)
await _outbound.PauseCampaignAsync(campaignId);
await _outbound.ResumeCampaignAsync(campaignId);
await _outbound.StopCampaignAsync(campaignId);
// 查询话单(从 Twilio 账号级 call 列表拉取,非 campaign 维度)
var records = await _outbound.QueryCallRecordsAsync(new QueryCallRecordsRequest { PageSize = 50 });
// 查询内存中的活动列表 / 详情
var campaigns = await _outbound.ListCampaignsAsync(pageIndex: 1, pageSize: 20);
var detail = await _outbound.GetCampaignAsync(campaignId);
内联 TwiML 生成
// 生成中文 Say 语音 TwiML(HTML 编码文本)
var twiml = TwilioOutboundCallOptions.BuildInlineTwiml("您有一笔订单待处理");
// <Response><Say language="zh-CN">您有一笔订单待处理</Say></Response>
请求审计
内置 Bitzsoft.Integrations.RequestLogging 出站请求记录管道,默认使用 NullRequestLogStore 不持久化。
// ① 默认:启用记录管道但不持久化(日志丢弃)
services.AddTwilioOutboundCall(options => { /* ... */ });
// ② 持久化:宿主注册 IRequestLogStore 实现后,所有出站请求自动落库
services.AddRequestLogging<MyRequestLogStore>(opts =>
{
opts.MaxInMemoryBodyBytes = 64 * 1024; // 仅控制内存/加密临时文件切换,不截断正文
opts.SensitiveFields.Add("AuthToken"); // 额外脱敏字段
});
services.AddTwilioOutboundCall(options => { /* ... */ });
安全说明
- AccountSid / AuthToken:Twilio 凭据必须通过环境变量或 Secret Manager 注入,禁止硬编码;鉴权使用 HTTP Basic(
Base64(AccountSid:AuthToken)),AuthToken仅出现在Authorization头 - 内存 campaign 持久性:campaign 状态存内存,进程重启后丢失;高可用场景需外部系统持久化联系人并在重启后重跑
StartCampaign - 被叫号码 E.164:号码自动归一化为
+前缀的 E.164 格式,调用前应使用PhoneNumberClassifier清洗分类 - 状态回调 URL:
StatusCallback必须为公网可达的 HTTPS 端点,用于接收 Twilio 异步状态推送 - 白名单防护:开发 / 测试环境可通过
CallListFilter过滤号码(白 / 黑名单由OutboundCallOptions携带)
依赖
| 包 | 说明 |
|---|---|
Bitzsoft.Integrations.OutboundCall |
外呼抽象层(IOutboundCallService + CampaignDialer + CallListFilter) |
Bitzsoft.Integrations.RequestLogging |
出站请求审计日志管道 |
Microsoft.Extensions.Logging.Abstractions |
日志抽象 |
Microsoft.Extensions.Options |
选项模式(IOptions<TwilioOutboundCallOptions>) |
相关包
- Bitzsoft.Integrations.OutboundCall -- 外呼抽象层
- Bitzsoft.Integrations.OutboundCall.Tencent -- 腾讯云 CCC 实现
- Bitzsoft.Integrations.OutboundCall.Aliyun -- 阿里云 CCC 实现
- Bitzsoft.Integrations.OutboundCall.All -- 聚合包(全部供应商)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 is compatible. 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 is compatible. 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 is compatible. 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. |
-
net10.0
- Bitzsoft.Integrations.OutboundCall (>= 1.0.1)
- Bitzsoft.Integrations.RequestLogging (>= 1.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Options (>= 10.0.10)
-
net5.0
- Bitzsoft.Integrations.OutboundCall (>= 1.0.1)
- Bitzsoft.Integrations.RequestLogging (>= 1.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 5.0.0)
- Microsoft.Extensions.Options (>= 5.0.0)
-
net8.0
- Bitzsoft.Integrations.OutboundCall (>= 1.0.1)
- Bitzsoft.Integrations.RequestLogging (>= 1.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Options (>= 10.0.10)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Bitzsoft.Integrations.OutboundCall.Twilio:
| Package | Downloads |
|---|---|
|
Bitzsoft.Integrations.OutboundCall.All
外呼服务聚合包 — 包含全部供应商实现(腾讯云/阿里云/火山引擎/容联云/华为云/国际 Twilio/Vonage) |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.1 | 0 | 8/3/2026 |
| 1.0.0 | 35 | 8/2/2026 |
| 1.0.0-alpha.10 | 48 | 7/26/2026 |
| 1.0.0-alpha.9 | 59 | 7/12/2026 |
| 1.0.0-alpha.8 | 57 | 7/1/2026 |
| 1.0.0-alpha.7 | 74 | 6/16/2026 |