ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Fonoster 开源可编程电信栈实战指南:用 Voice Application 与 NodeJS SDK 构建云通信服务

Fonoster 开源可编程电信栈实战指南:用 Voice Application 与 NodeJS SDK 构建云通信服务 后端音视频【免费下载链接】fonoster The open-source alternative to Twilio.项目地址https://gitcode.com/gh_mirrors/fo/fonoster点击查看免费下载Fonoster 是一个开源的、可作为 Twilio 替代方案的可编程电信栈Programmable Telecommunications Stack它让企业能够以云上工具的方式把电话业务与互联网无缝连接。本文以项目 README.md 为主线结合仓库源码完整讲解它的核心能力、12 个语音控制原语Verbs、可编程语音应用Voice Application的编写方法、基于 SDK 的外呼流程以及基于 Docker 的整套部署方案。平台概览从 PBX 到 API 优先的可编程电信栈Fonoster 的定位非常明确——它是一个API 优先的电信平台。与传统 PBX 设备不同Fonoster 把控制通话流程这件事彻底编程化开发者不接触交换机配置而是编写一个监听呼叫请求的 Voice Application用代码来决定呼叫的走向。从仓库根目录的 assets/architecture.png 架构图可以看到整个栈的分层结构架构中的关键层次包括SIPnet基于 Routr负责 SIP 信令的路由与注册是终端用户 SIP 设备接入的入口Asterisk RTPEngineAsterisk 通过 ARIAsterisk REST Interface提供呼叫控制RTPEngine 负责 RTP 媒体流的转发与处理APIServer以 gRPC 方式向 WebUI 与 SDK 暴露统一 API并通过 NATS 处理通话事件等异步消息见 mods/apiserver/src/voice/VoiceDispatcher.ts 与 mods/apiserver/src/events/nats.ts数据与基础设施Postgres 存放业务数据InfluxDB 存放通话统计详见 compose.yaml 中的服务编排。README 中列出的核心特性包括多租户Multitenancy支持便捷部署 PBX 功能可编程语音应用Programmable Voice ApplicationsNodeJS SDK支持 Amazon S3 存储使用 Lets Encrypt 保护 API 端点OAuth2 与 JWT 两种认证方式基于角色的访问控制RBAC插件化的命令行工具见 mods/ctl支持 Google Speech API。认识 Voice Application用代码接管通话流程Voice Application是 Fonoster 中控制通话流程的服务端程序。它可以组合使用以下任意数量的语音原语Verbs来编排通话原语作用Answer接听来电Hangup挂断通话Play取一个媒体文件的 URL把声音流式播放给呼叫方PlayDtmf取一段 DTMF 序列并播放给对方Say取一段文本合成语音后流式播放结果Gather等待 DTMF 或语音事件并返回结果SGather返回一个流用于后续的 DTMF 与语音识别结果Stream建立双向音频流与呼叫方收发音频Dial把呼叫转接给某个 Agent坐席或 PSTN 上的号码Record录制呼叫方语音并把音频保存到存储子系统Mute让通道停止发送媒体即静音通道Unmute恢复通道的媒体流这些 Verbs 在仓库中都有独立的实现文件位于 mods/voice/src/verbs 目录并通过 mods/voice/src/verbs/index.ts 统一导出。Answer、Hangup、PlayDtmf、Record、Stream、StreamGather、Mute、Unmute、StopSay、SetAudioFilters等也在其中与 README 的清单一一对应。一个完整的 Voice Application 示例README 给出了一个可运行的 Voice Application 示例它问候来电者、通过语音识别收集姓名、再通过按键收集 4 位 PIN 码const VoiceServer require(fonoster/voice).default; const { GatherSource, VoiceRequest, VoiceResponse } require(fonoster/voice); new VoiceServer().listen(async (req: VoiceRequest, voice: VoiceResponse) { const { ingressNumber, sessionRef, appRef } req; // When Answering Machine Detection is enabled, req.amd carries an early // verdict for outbound calls: { status: HUMAN | MACHINE | UNKNOWN, // confidence, detector, latencyMs }. It is absent when AMD did not run. if (req.amd?.status MACHINE) { return voice.hangup(); } await voice.answer(); await voice.say(Hi there! Whats your name?); const { speech: name } await voice.gather({ source: GatherSource.SPEECH }); await voice.say(Nice to meet you name !); await voice.say(Please enter your 4 digit pin.); const { digits } await voice.gather({ maxDigits: 4, finishOnKey: # }); await voice.say(Your pin is digits); await voice.hangup(); }); // Your app will live at tcp://127.0.0.1:50061 // and you can easily publish it to the Internet with: // ngrok tcp 50061这个例子展示了几个关键点事件回调模型VoiceServer().listen(handler)注册一个异步处理器每次来电都会触发请求上下文回调的第一个参数req携带ingressNumber来电号码、sessionRef会话引用和appRef应用引用同步式编程体验await voice.answer()、await voice.say(...)、await voice.gather(...)让复杂的 IVR 流程读起来像顺序代码双模式收集gather既支持source: GatherSource.SPEECH的语音识别也支持maxDigits/finishOnKey的 DTMF 按键收集网络拓扑应用默认监听tcp://127.0.0.1:50061可通过ngrok tcp 50061快速暴露到公网便于本地联调。底层原理Verb 如何通过 gRPC 会话流工作从源码看Voice Application 与 Fonoster 后端通过 gRPC 双向流会话交互。核心机制位于 mods/voice/src/verbs/Verb.ts每个 Verb 继承抽象基类Verb其run()方法把请求参数与mediaSessionRef合并后通过voice.write()写入会话流在写入前它会注册StreamEvent.DATA、StreamEvent.END、StreamEvent.ERROR三个监听器收到与自身期望内容getExpectedContent匹配的响应时 resolve 本次 Promise会话提前结束或传输失败时 reject避免 Promise 永远悬挂每个 Verb 通过getValidationSchema()定义自己的参数校验规则由 mods/voice/src/verbs/validateRequest.ts 执行。例如Gather要求finishOnKey必须是单个0-9*#字符、timeout和maxDigits必须是正整数见 mods/voice/src/verbs/Gather.tsSay要求text非空、playbackRef为合法 UUID见 mods/voice/src/verbs/Say.tsPlay要求url是合法 URL见 mods/voice/src/verbs/Play.tsDial则校验destination、正整数timeout与recordDirection枚举见 mods/voice/src/verbs/Dial.ts。服务端一侧mods/voice/src/VoiceServer.ts 负责构建 gRPC 服务默认情况下它会从 identity 服务获取公钥用createAuthInterceptor对请求做 JWT 鉴权可通过skipIdentity配置跳过并把createSession方法绑定到你的 handler 上同时注册 gRPC 健康检查。应答机检测AMD的早期判定README 示例中还展示了 Fonoster 的应答机检测Answering Machine Detection能力当外呼启用了 AMD 时请求对象req.amd会携带一个早期判定结果。仓库中 mods/common/src/voice/voice.ts 定义了对应的类型与枚举enum AmdStatus { UNSPECIFIED AMD_STATUS_UNSPECIFIED, HUMAN HUMAN, MACHINE MACHINE, VOICEMAIL VOICEMAIL, IVR IVR, UNKNOWN UNKNOWN } type Amd { status: AmdStatus; confidence: number; detector: string; latencyMs: number; };也就是说req.amd会携带status判定结果如HUMAN/MACHINE、confidence置信度、detector使用的检测器和latencyMs检测耗时当 AMD 未运行时该字段不存在。开发者在代码里通过req.amd?.status MACHINE即可在接通应答机时直接挂断典型应用场景是外呼营销时跳过机器应答。AMD 模块的独立实现位于 mods/amd其配置项如探测时长、超时、最低置信度在 compose.yaml 中通过AMD_*环境变量暴露。用 SDK 发起呼叫API 优先的一等公民Everything in Fonoster is an API first发起呼叫也不例外。README 给出了用 SDK 外呼的完整示例const SDK require(fonoster/sdk); async function main(request) { const apiKey your-api-key; const apiSecret your-api-secret const accessKeyId WO00000000000000000000000000000000; const client new SDK.Client({ accessKeyId }); await client.loginWithApiKey(apiKey, apiSecret); const calls new SDK.Calls(client); const response await calls.createCall(request); console.log(response); // successful response } const request { from: 18287854037, to: 17853178070, appRef: 3e61ecb7-a1b6-4a93-84c3-4f1979165bca, // Optional metadata to be sent to the Voice Application metadata: { name: John Doe, message: Please call me back. } }; main(request).catch(console.error);这段代码的关键流程与字段如下凭据apiKey/apiSecret用于换取访问令牌accessKeyId标识调用者所属的工作区/租户格式类似WO开头的 32 位字符串认证client.loginWithApiKey(apiKey, apiSecret)完成登录SDK 客户端负责维护令牌呼叫请求from为发起方号码to为目标号码appRef指向处理该呼叫的 Voice Application对应上文示例里的req.appRefmetadata为可选的透传数据——它会随请求一起送达 Voice Application可用于传递用户姓名、留言等业务上下文调用链Calls.createCall在 mods/sdk/src/Calls.ts 中实现底层通过 gRPC 调用 apiserver 的呼叫服务apiserver 一侧的完整实现位于 mods/apiserver/src/calls呼叫创建后会通过 NATS 发布通话事件并由 Voice Dispatcher 把会话接入对应的 Voice Application见 mods/apiserver/src/voice/VoiceDispatcher.ts。快速开始与 Docker 部署README 推荐的入门路径中自托管部署是第一步。仓库根目录的 compose.yaml 提供了一整套docker compose编排包含以下服务dashboard管理后台WebUIapiserver业务 API 服务gRPC 端口 50051挂载 config/keys 下的公私钥与 config/integrations.json 集成配置autopilotAI 语音助手服务端口 50061routrSIP 信令服务器暴露 5060 UDP 及 5060-5063并配置了健康检查rtpengineRTP 媒体引擎。由于 RTP 需要大范围端口Docker 下默认只开放 10000-10100 端口区间README 对应的部署建议是在 Linux 上改用network_mode: host并移除 ports 段以获得生产级媒体吞吐Windows/Mac 不支持 host 网络模式需用端口段方案amd应答机检测服务asterisk语音控制基于 Fonoster 的 asterisk 镜像配置了 ARI 代理、编解码与 DTMF 模式等环境变量postgres / influxdb关系型数据库与通话时序数据库nats异步事件总线envoy边缘网关默认暴露 8449 端口若启用 Lets Encrypt则需挂载 letsencrypt 目录并把 443 端口映射到 envoy注意挂载目录不支持符号链接autoheal配合 routr 的autohealtrue标签做崩溃自动重启。启动前需要准备好config/keys下的公钥/私钥routr、apiserver、asterisk 等组件通过挂载./config/keys/public.pem完成互信以及config/integrations.json集成配置文件示例见 config/integrations.example.json。部署完成后即可通过 SDK 或管理后台创建应用、号码与凭据开始编写自己的第一个 Voice Application。小结Fonoster 把可编程语音从设备配置解放出来交付为一段可运行的代码12 个 Verbs 覆盖接听、播放、合成、收集、转接、录制、静音等全部常见通话操作VoiceServer().listen()让 IVR、语音机器人、外呼营销等场景都能以顺序代码的方式编写SDK 的createCall让发起呼叫和调用任意云 API 一样简单而 compose.yaml 的一次性编排则提供了从信令Routr、媒体RTPEngine、控制Asterisk/APIServer到数据Postgres/InfluxDB的完整闭环。如果希望进一步深入建议继续阅读以下仓库内文档与源码mods/voice/README.md 与 mods/voice/src/VoiceResponse.tsVoice Application 的完整 API 与响应对象mods/sdk/README.md 与 mods/sdk/src/Calls.tsSDK 的全部资源类与呼叫接口mods/amd/README.md应答机检测模块的原理与配置CONTRIBUTING.md参与贡献的指南。赞分享后端音视频【免费下载链接】fonoster The open-source alternative to Twilio.项目地址https://gitcode.com/gh_mirrors/fo/fonoster点击查看免费下载相关推荐Fonoster NodeJS SDK终极指南10个实战场景快速上手开源通信平台Fonoster NodeJS SDK终极指南10个实战场景快速上手开源通信平台 Fonoster是一个功能强大的开源通信平台作为Twilio的替代方案它后端音视频Twilio 可编程通信 API 集成实战用 SMS / MMS / WhatsApp / Voice 构建 B2B SaaS 事务消息与自定义短信流程Twilio 可编程通信 API 集成实战用 SMS / MMS / WhatsApp / Voice 构建 B2B SaaS 事务消息与自定义短信流程 本文AI 技能人工智能WebRTC 信令服务实战用 socketio-over-nodejs 搭建 Socket.io 信令服务器WebRTC 信令服务实战用 socketio over nodejs 搭建 Socket.io 信令服务器 socketio over nodejs 是 W示例工程上一篇网盘直链下载助手八大网盘一键解析告别限速困扰下一篇华为光猫配置解密终极指南从加密文件到明文配置的完整解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表