手把手教 AI 助手给你发飞书语音条
让你的 AI 助手学会「说话」—— 从 TTS 到飞书语音条的全链路实践
一、能做什么?
想象一下:你的 AI 助手不再是冷冰冰的文字回复,而是能直接给你发一条飞书原生语音条,点开就能听,像朋友发微信语音一样自然。
本文教你如何完整打通这条链路:
AI 想说的文字 → Noiz TTS 语音合成 → 飞书语音条最终效果:AI 以你的身份给你发飞书语音消息。
二、你需要准备什么?
三、整体流程
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ 想说的 │ │ Noiz TTS │ │ 转码为 │ │ 飞书上传 │ │ 文字内容 │ ──→ │ 生成语音 │ ──→ │ opus格式 │ ──→ │ 获取文件 │ └──────────┘ └──────────┘ └──────────┘ └────┬─────┘ │ ┌──────────┐ ┌──────────┐ │ │ 听到语音 │ │ 飞书群里 │ │ │ 条回复 │ ←── │ 显示语音 │ ←─────────────────────────┘ └──────────┘ └──────────┘四、详细步骤
步骤 1:获取 Noiz API Key
打开 noiz.ai → 注册/登录(支持 Google / 邮箱) 进入开发者后台 developers.noiz.ai 左侧菜单点击 API Keys → Create API Key 复制生成的 Key(长 base64 字符串,形如 ZWNkMzVh...)
🎁 新用户自动获得 100,000 免费额度,无需绑信用卡。
步骤 2:生成语音(TTS)
使用 Noiz 的文本转语音 API:
# 使用正式 API Key(推荐)curl -X POST "https://noiz.ai/v1/text-to-speech" \ -H "Authorization: 你的Noiz_API_Key" \ -F "text=大家好,这是通过AI生成的语音消息" \ -F "voice_id=3b9f1e27" \ -F "output_format=mp3" \ -F "target_lang=zh" \ --output speech.mp3参数说明:
text | ||
voice_id | 3b9f1e27 | |
output_format | wavmp3 | |
target_lang | zhen / ja | |
speed |
中文可用音色:
3b9f1e27 | |
b4775100 | |
ac09aeb4 |
免认证体验(限 5 次/月):
curl -X POST "https://noiz.ai/v1/guest/text-to-speech" \ -F "text=测试语音" \ -F "output_format=mp3" \ --output speech.mp3免认证接口限制:每次最多 400 字符,每个 IP 每月 5 次。
步骤 3:转码为飞书要求的 Opus 格式
飞书的语音条要求 opus 格式,用 ffmpeg 转换:
ffmpeg -i speech.mp3 -acodec libopus -ac 1 -ar 16000 speech.opus参数说明:
-acodec libopus | |
-ac 1 | |
-ar 16000 |
这是飞书官方推荐的转换参数,详见飞书文档-上传文件。
步骤 4:获取飞书 tenant_access_token
调用飞书 API 需要先获取身份令牌:
import requestsAPP_ID = "你的飞书 App ID"APP_SECRET = "你的飞书 App Secret"resp = requests.post("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal", json={"app_id": APP_ID, "app_secret": APP_SECRET})token = resp.json()["tenant_access_token"]或者用 curl:
curl -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \ -H "Content-Type: application/json" \ -d '{"app_id":"你的AppID","app_secret":"你的AppSecret"}'返回示例:
{"code": 0,"msg": "ok","tenant_access_token": "t-g1045i9k..."}步骤 5:上传 Opus 文件到飞书
这是最关键的一步——用 file_type=opus 上传音频文件:
import requeststoken = "上一步获取的 tenant_access_token"duration_ms = 3081# 从 ffprobe 获取音频时长(毫秒)with open("speech.opus", "rb") as f: file_data = f.read()files = {"file_type": (None, "opus"),"file_name": (None, "voice.opus"),"duration": (None, str(duration_ms)),"file": ("voice.opus", file_data, "application/octet-stream"),}resp = requests.post("https://open.feishu.cn/open-apis/im/v1/files", headers={"Authorization": f"Bearer {token}"}, files=files)file_key = resp.json()["data"]["file_key"]print(f"✅ 文件上传成功,file_key: {file_key}")用 curl 的等效方式:
curl -X POST "https://open.feishu.cn/open-apis/im/v1/files" \ -H "Authorization: Bearer 你的tenant_access_token" \ -F "file_type=opus" \ -F "file_name=voice.opus" \ -F "duration=3000" \ -F "file=@speech.opus"⚠️ 重要:file_type 必须设为 opus!飞书官方说明:*"如需上传其他格式的音频文件,需先将音频文件转为 OPUS 格式"*。
返回示例:
{"code": 0,"data": {"file_key": "file_v3_0011q_767d0a9d-4104-4f40-9bde-2677156c692g" },"msg": "success"}获取音频时长的命令:
ffprobe -v error -show_entries format=duration -of csv=p=0 speech.opus# 输出类似:3.081313(秒)# 转为毫秒:3081步骤 6:发送语音消息
最后,用获取到的 file_key 和 duration 发送飞书语音条:
{"receive_id": "对方的 open_id 或 chat_id","msg_type": "audio","content": "{\"file_key\":\"上一步获取的file_key\",\"duration\":\"3081\"}"}飞书 OpenAPI 调用方式:
curl -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id" \ -H "Authorization: Bearer 你的tenant_access_token" \ -H "Content-Type: application/json" \ -d '{ "receive_id": "ou_xxxxxxxxxxxxxx", "msg_type": "audio", "content": "{\"file_key\":\"file_v3_0011q_xxxx\",\"duration\":\"3081\"}" }'五、完整 Python 脚本
把以上步骤整合成一个可直接运行的脚本:
import requestsimport subprocessimport json# ====== 配置 ======APP_ID = "你的飞书 App ID"APP_SECRET = "你的飞书 App Secret"NOIZ_API_KEY = "你的 Noiz API Key"VOICE_ID = "3b9f1e27"# 中文音色TARGET_USER = "ou_xxxxxxxxxxxxx"# 接收语音的用户 open_idTEXT = "你好,这是一条来自AI助手的语音消息"# ====== 1. TTS 生成 ======print("🎤 正在生成语音...")resp = requests.post("https://noiz.ai/v1/text-to-speech", headers={"Authorization": NOIZ_API_KEY}, files={"text": (None, TEXT),"voice_id": (None, VOICE_ID),"output_format": (None, "mp3"),"target_lang": (None, "zh"), })with open("/tmp/speech.mp3", "wb") as f: f.write(resp.content)print("✅ 语音已生成")# ====== 2. 转码为 opus ======print("🔄 正在转码...")subprocess.run(["ffmpeg", "-y", "-i", "/tmp/speech.mp3","-acodec", "libopus", "-ac", "1", "-ar", "16000","/tmp/speech.opus"], capture_output=True)print("✅ 转码完成")# ====== 3. 获取时长 ======result = subprocess.run( ["ffprobe", "-v", "error", "-show_entries", "format=duration","-of", "csv=p=0", "/tmp/speech.opus"], capture_output=True, text=True)duration_ms = int(float(result.stdout.strip()) * 1000)print(f"⏱ 时长: {duration_ms}ms")# ====== 4. 获取飞书 token ======print("🔑 获取飞书 token...")resp = requests.post("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal", json={"app_id": APP_ID, "app_secret": APP_SECRET})token = resp.json()["tenant_access_token"]# ====== 5. 上传文件 ======print("📤 上传语音文件...")with open("/tmp/speech.opus", "rb") as f: file_data = f.read()resp = requests.post("https://open.feishu.cn/open-apis/im/v1/files", headers={"Authorization": f"Bearer {token}"}, files={"file_type": (None, "opus"),"file_name": (None, "voice.opus"),"duration": (None, str(duration_ms)),"file": ("voice.opus", file_data, "application/octet-stream"), })file_key = resp.json()["data"]["file_key"]print(f"✅ 文件上传成功: {file_key}")# ====== 6. 发送语音消息 ======print("📨 发送语音消息...")resp = requests.post("https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id", headers={"Authorization": f"Bearer {token}","Content-Type": "application/json", }, json={"receive_id": TARGET_USER,"msg_type": "audio","content": json.dumps({"file_key": file_key, "duration": str(duration_ms)}), })if resp.json().get("code") == 0: print("🎉 语音消息发送成功!")else: print(f"❌ 发送失败: {resp.json()}")六、常见问题
Q1:语音条发出去但对方看不到?
检查 receive_id 是否正确。如果是发给用户本人,用对方飞书的 open_id;如果是发到群里,用群的 chat_id 并修改 receive_id_type。
Q2:上传文件报错 234001 "Invalid request param"?
通常是 file_type、file_name、duration 没有正确传递为 multipart/form-data 字段。确认这些字段都在请求体里,而不是作为 URL 参数。
Q3:收到的语音需要下载才能听?
表示消息类型被识别为文件而非语音条。检查 msg_type 是否为 audio,以及 content 中的 file_key 和 duration 格式是否正确(duration 是字符串)。
Q4:飞书 API 返回 401?
令牌过期或未正确设置。重新获取 tenant_access_token(有效期通常 2 小时)。
Q5:Noiz API 返回 401?
确认 API Key 是原始 base64 字符串,不要 decode。格式如 ZWNkMzVhZWItNjRiMy00Y2QzLWI4NjgtOGE2NzZkNzBkMjRkJHdvZGVodW50ZXJAMTYzLmNvbQ==。
Q6:ffmpeg 没有安装?
macOS:brew install ffmpegUbuntu/Debian:sudo apt install ffmpegWindows:从 ffmpeg.org 下载
七、总结
文字 → Noiz TTS(mp3) → ffmpeg转opus → 飞书上传 → 飞书语音条整条链路的核心要点:
音频格式:飞书语音条只认 opus( -acodec libopus -ac 1 -ar 16000)上传参数: file_type=opus,传duration(毫秒)让飞书正确显示时长消息类型:发送时用 msg_type=audio身份令牌:使用 tenant_access_token调用飞书 API
掌握了这套流程,你的 AI 助手就能「开口说话」了。试试看,让你的下一个 AI 应用不再沉默 🎧
本文内容经过全链路实战验证。
夜雨聆风