用 React + Node.js + WebSocket 做实时语音转写,并把结果接入CRM/工单等自动化流程,小团队也能快速落地。

React + Node 语音识别:3步做出可用的团队工具
把语音识别加进产品里,最常见的失败原因不是模型不准,而是工作流没设计好:录音、传输、实时转写、错误处理、权限弹窗、以及“转写结果下一步要去哪”。小团队尤其容易卡在这里——需求很明确(会议纪要、客服记录、工单备注),但工程路径不清晰。
这篇文章属于「AI 语音助手与自动化工作流:小企业的效率倍增器」系列。我们会用一个非常现实的方式,把 RSS 里的 React + Node.js 实时语音转写教程,改造成能落地到小团队日常流程的做法:用浏览器采集麦克风音频,通过 WebSocket 传到 Node 服务端,再用 ASR(语音转文字)实时回传文本,最后把文本接到你的自动化链路里(CRM、工单、Notion、Slack、Webhook 都行)。
立场先说清:如果你只想“把语音变成文字”,随便找个录音转写工具就够了;但如果你想让语音变成业务动作(生成工单、自动摘要、同步客户档案),那就值得自己做一层轻量集成。
小团队为什么需要“嵌入式”语音转写
直接回答:因为语音是最快的输入方式,而嵌入式转写能把“输入”变成“流程”。
很多小企业的效率问题不在“没有工具”,而在“工具之间断层”:
- 销售把语音发在微信/Slack,之后没人整理进 CRM
- 客服电话要写通话纪要,写不完就靠记忆,容易漏信息
- 现场服务人员在路上,只能语音记录,回到电脑前已经忘了细节
语音转写嵌到你的 React 前端里,意味着你可以:
- 在任何业务表单旁边放一个“语音输入”按钮(备注、需求、回访、问题描述)。
- 转写结果实时显示,立刻校对。
- 提交时直接触发自动化:打标签、分派、生成摘要、发送提醒。
RSS 源文用“自我肯定”应用举例,其实很聪明:它证明了语音转写不仅能做严肃的客服/会议,也能做更贴近人的场景。对小团队来说,同一套技术可以复用在更广的业务动作里。
整体架构:浏览器录音 + WebSocket + Node 转写
直接回答:前端负责采集音频并推流,后端负责安全地调用 ASR,并把转写结果实时推回前端。
一个可靠的最小架构长这样:
-
React 前端
navigator.mediaDevices.getUserMedia({ audio: true })请求麦克风权限MediaRecorder把音频切成小片段(例如每 1000ms 一段)- 用
WebSocket把片段发送到你的 Node 服务 - 接收服务端推回的转写 JSON,更新 UI(文本框、字幕、实时提示)
-
Node.js 服务端
- 运行 WebSocket Server(例如
ws) - 在服务端初始化 ASR SDK(避免把 API Key 暴露在浏览器)
- 把客户端音频流转发给 ASR 的实时转写接口
- 把 ASR 返回的结果再推送给前端
- 运行 WebSocket Server(例如
为什么要用 WebSocket?因为它解决了两件事:
- 低延迟:不用等录完再上传。
- 双向:服务端能实时推回转写结果,前端体验明显更好。
关键安全点:API Key 只能放服务端
直接回答:任何能在浏览器跑到的 Key,都等于公开。
RSS 里也强调了这一点:用 .env 存 Key,并在 Node 服务端用 dotenv 读取。你真正要做的是:
- 只让前端连你的
ws://localhost:3002(开发环境)或wss://yourdomain(生产环境) - 前端永远不要直接调用 ASR 云接口
第1步:React 前端加“语音输入”按钮(可复用到任何表单)
直接回答:你要先把 UI 和录音入口建立起来,后端没好也能先把权限和录音链路跑通。
在业务上,我建议你把它当作一个通用组件:<VoiceInput onText={...} />。先按 RSS 的最小改动方式做:在表单下加一个按钮。
示意代码(RSS 原意):
<button
onClick={activateMicrophone}
type='button'
className='submit-button'>
Voice
</button>
然后创建 activateMicrophone,先只做两件事:
- 请求麦克风权限
- 创建
MediaRecorder
const activateMicrophone = () => {
navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
const mediaRecorder = new MediaRecorder(stream)
// 下一步:把音频片段通过 WebSocket 发到服务端
})
}
实际落地建议(经验之谈):
- 在按钮旁边显示状态:
未开始 / 录音中 / 连接中 / 失败重试 - 第一次弹权限时,用户很容易拒绝。你要给出可理解的提示:“需要麦克风权限来把语音转成文字,仅用于实时转写。”
第2步:Node.js 建一个“转写网关”服务
直接回答:服务端只干三件事:接收音频、调用实时转写、推回结果。
安装依赖(与 RSS 一致):
@deepgram/sdk(ASR SDK)dotenv(环境变量)ws(WebSocket)
你会创建 server/server.js,并做:
- 读取
.env - 启动 WebSocket server
- 每当有客户端连上时,新建一个实时转写 session
RSS 提供了示例逻辑:
interim_results: true:先出临时结果,体验更像“实时字幕”punctuate: true:自动加标点(对后续摘要很重要)endpointing: 500:把停顿当作分段的信号(影响“句子何时算结束”)
这里给一个更“业务向”的建议:
- 你要区分临时结果和最终结果。临时结果适合显示;最终结果适合落库、触发自动化。
- 你要给每条连接分配
sessionId,方便排查问题、串联日志。
生产环境必做:限制与保护
直接回答:实时转写是成本项,必须加护栏。
至少加这些:
- 连接鉴权(JWT、短期 token 或者登录态校验)
- 每用户/每 IP 并发限制
- 单次会话最长时长(例如 2-5 分钟),避免“忘记关录音”
- 日志脱敏(不要把完整敏感对话写进日志)
第3步:前端连 WebSocket,把转写结果接进表单
直接回答:你要做的就是:socket 打开后开始切片发送;收到消息就更新输入框。
RSS 用了 useRef 保存 socket,这很实用:提交表单或页面卸载时可以把连接关掉。
核心逻辑(与 RSS 同方向):
socket.onopen:开始mediaRecorder.start(1000),每秒送一次音频片段socket.onmessage:解析转写 JSON,取出transcript,更新setAffirmation(transcript)handleSubmit时:如果 socket 还开着就关闭,避免资源泄露
我会额外加两点让它更“能用”:
1)把转写写入“可编辑”的文本框,而不是直接覆盖
直接回答:用户需要校对,你不能一直把输入框覆盖成最新一句。
可行做法:
- 临时转写显示在灰色字幕区域
- 最终转写追加到 textarea(append)
- 用户可以手动修改,再点提交
2)断线重连策略
直接回答:WebSocket 在弱网下必断,做一次重连就能把投诉减少一半。
简单策略:
onclose时,如果仍在录音状态,延迟 1-2 秒重连- 重连次数限制(例如 3 次)
- UI 明确提示“连接断开,正在重试…”
把“转写文本”变成“自动化工作流”:3个小企业用例
直接回答:价值不在转写,而在转写后的下一步动作。
下面这三种是我最建议小团队先做的,ROI 清晰、实现难度不高。
用例A:销售通话/拜访纪要 → 自动写入 CRM
流程示例:
- 销售在客户详情页点“语音记录”说 30 秒
- 实时转写进备注框
- 提交时触发:
- 自动提取意向等级、预算、下一步日期
- 创建跟进任务(Task)
- @提醒负责人
你会发现一个很现实的变化:销售愿意记录了。因为打字 3 分钟的内容,说出来只要 30 秒。
用例B:客服对话 → 自动生成工单摘要
流程示例:
- 客服边聊边口述关键点
- 转写后提交
- 后端把文本丢给摘要/结构化模块(可接你现有 LLM)
- 自动生成:问题类型、紧急程度、复现步骤、建议处理人
这类场景尤其适合“AI 语音助手与自动化工作流”的主题:语音负责输入,自动化负责分发。
用例C:内部沟通(站会/现场记录)→ 自动同步到 Notion/飞书
流程示例:
- 会议主持人用网页开一个“语音纪要”
- 实时转写
- 会议结束点“生成纪要”
- 自动同步到知识库,并把待办拆分给对应成员
常见问题(你很可能会踩)
Q1:浏览器录音的格式能直接给 ASR 吗?
直接回答:多数情况下可以,但要留意编码与采样率。
MediaRecorder 输出常见是 webm/opus。有些 ASR 能直接吃,有些需要你在服务端转码(例如用 FFmpeg)。如果你发现识别质量异常、或服务端报格式错误,优先检查音频格式支持。
Q2:临时结果抖动很烦,怎么办?
直接回答:UI 上把“临时字幕”和“最终文本”分区显示。
临时结果本来就会改来改去,别把它当成最终输入。
Q3:怎么控制成本?
直接回答:限制时长 + 只在需要时开麦 + 只保存最终结果。
另外,别在每个页面都常驻连接。让用户“点一下才开始”,并在提交或超时后自动关闭。
下一步:从语音转写到“语音驱动的业务动作”
把语音识别加进 React + Node.js 项目,真正有价值的部分不是那段 SDK 代码,而是你把它嵌进了团队每天都会用的表单、工单和客户页面里。语音一旦变成默认输入方式,很多“应该记录但没记录”的信息会自动浮出水面。
如果你正在做一个小团队的内部系统,我建议你下一步就选一个最短闭环:语音备注 → 转写 → 自动创建任务。跑通一次,你就会发现这套模式几乎可以复制到任何流程节点。
你最想先用语音改造哪个环节:销售跟进、客服工单,还是内部会议记录?