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
                    
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="Bitzsoft.Integrations.OutboundCall.Twilio" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Bitzsoft.Integrations.OutboundCall.Twilio" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Bitzsoft.Integrations.OutboundCall.Twilio" />
                    
Project file
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 Bitzsoft.Integrations.OutboundCall.Twilio --version 1.0.1
                    
#r "nuget: Bitzsoft.Integrations.OutboundCall.Twilio, 1.0.1"
                    
#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 Bitzsoft.Integrations.OutboundCall.Twilio@1.0.1
                    
#: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=Bitzsoft.Integrations.OutboundCall.Twilio&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Bitzsoft.Integrations.OutboundCall.Twilio&version=1.0.1
                    
Install as a Cake Tool

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,注册 internal TwilioCallHttpClient 为 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 清洗分类
  • 状态回调 URLStatusCallback 必须为公网可达的 HTTPS 端点,用于接收 Twilio 异步状态推送
  • 白名单防护:开发 / 测试环境可通过 CallListFilter 过滤号码(白 / 黑名单由 OutboundCallOptions 携带)

依赖

说明
Bitzsoft.Integrations.OutboundCall 外呼抽象层(IOutboundCallService + CampaignDialer + CallListFilter
Bitzsoft.Integrations.RequestLogging 出站请求审计日志管道
Microsoft.Extensions.Logging.Abstractions 日志抽象
Microsoft.Extensions.Options 选项模式(IOptions<TwilioOutboundCallOptions>

相关包

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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