#!/bin/bash# 飞书音频消息发送脚本# 将文本转换为语音并发送到飞书set -e# 参数检查TEXT="$1"VOICE="${2:-zh-CN-XiaoxiaoNeural}"BITRATE="${3:-24k}"if [ -z "$TEXT" ]; then echo "❌ 错误:缺少文本参数" echo "" echo "用法: $0 \"要发送的文本\" [语音类型] [比特率]" echo "" echo "参数:" echo " 文本 - 要转换为语音的文字(必需)" echo " 语音类型 - edge-tts语音类型(默认: zh-CN-XiaoxiaoNeural)" echo " 比特率 - Opus编码比特率(默认: 24k)" echo "" echo "示例:" echo " $0 \"你好,这是一条语音消息\"" echo " $0 \"Hello\" en-US-JennyNeural 32k" exit 1fi# 显示任务信息echo "🎤 飞书音频消息发送"echo "━━━━━━━━━━━━━━━━━━━━━━━━━━"echo "📝 文本: $TEXT"echo "🎙️ 语音: $VOICE"echo "⚡ 比特率: $BITRATE"echo ""# 检查工具echo "🔧 检查工具..."if ! python3 -m edge_tts --version &> /dev/null; then echo "❌ edge-tts 未安装" echo " 安装: pip3 install edge-tts" exit 1fiif ! command -v ffmpeg &> /dev/null; then echo "❌ ffmpeg 未安装" exit 1fi# 检查飞书凭证echo "🔑 检查飞书凭证..."if [ -z "$FEISHU_APP_ID" ] || [ -z "$FEISHU_APP_SECRET" ]; then echo "❌ 缺少飞书凭证" echo " 请设置环境变量:" echo " export FEISHU_APP_ID=\"你的App ID\"" echo " export FEISHU_APP_SECRET=\"你的App Secret\"" exit 1fi# 接收者(默认为当前用户)RECEIVER="${FEISHU_RECEIVER:-}"if [ -z "$RECEIVER" ]; then echo "❌ 缺少接收者" echo " 请设置环境变量:" echo " export FEISHU_RECEIVER=\"接收者open_id\"" exit 1fiecho "👤 接收者: $RECEIVER"# 1. 获取飞书访问令牌echo ""echo "🔑 获取飞书 token..."TOKEN_RESPONSE=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \ -H "Content-Type: application/json" \ -d "{\"app_id\": \"$FEISHU_APP_ID\", \"app_secret\": \"$FEISHU_APP_SECRET\"}")TOKEN=$(echo "$TOKEN_RESPONSE" | python3 -c "import sys,json;print(json.load(sys.stdin).get('tenant_access_token', ''))" 2>/dev/null || echo "")CODE=$(echo "$TOKEN_RESPONSE" | python3 -c "import sys,json;print(json.load(sys.stdin).get('code', ''))" 2>/dev/null || echo "")if [ "$CODE" != "0" ] || [ -z "$TOKEN" ]; then echo "❌ 获取 token 失败" echo "错误信息:$TOKEN_RESPONSE" exit 1fiecho "✅ Token 获取成功"# 2. 生成 MP3 音频(使用 edge-tts)echo ""echo "🎙️ 使用 edge-tts 生成音频..."MP3_FILE="/tmp/feishu-audio-$$.mp3"# 使用edge-tts生成音频python3 -m edge_tts --text "$TEXT" --voice "$VOICE" --write-media "$MP3_FILE" --rate=+0% --pitch=+0Hz > /dev/null 2>&1if [ ! -f "$MP3_FILE" ] || [ ! -s "$MP3_FILE" ]; then echo "❌ TTS 生成失败" exit 1fiecho "✅ TTS 音频生成完成: $(stat -f%z "$MP3_FILE") bytes"# 3. 转换为 opus 格式echo ""echo "🔄 转换为 opus 格式..."OPUS_FILE="/tmp/feishu-audio-$$.opus"ffmpeg -y -i "$MP3_FILE" \ -c:a libopus \ -b:a "$BITRATE" \ "$OPUS_FILE" > /dev/null 2>&1if [ ! -f "$OPUS_FILE" ] || [ ! -s "$OPUS_FILE" ]; then echo "❌ 格式转换失败" exit 1fiecho "✅ 格式转换完成: $(stat -f%z "$OPUS_FILE") bytes"# 4. 读取音频时长并转换为毫秒echo ""echo "⏱️ 读取音频时长..."EXACT_DURATION=$(ffmpeg -i "$OPUS_FILE" 2>&1 | grep Duration | awk '{print $2}' | tr -d , | awk -F: '{print ($1*3600)+($2*60)+$3}')if [ -z "$EXACT_DURATION" ]; then echo "❌ 无法读取时长" exit 1fi# 转换为毫秒(飞书 API 要求)DURATION_MS=$(awk "BEGIN {printf \"%.0f\", $EXACT_DURATION * 1000}")echo "✅ 时长: ${EXACT_DURATION}秒 (${DURATION_MS}毫秒)"# 5. 上传文件到飞书(duration 用毫秒)echo ""echo "📤 上传到飞书服务器..."UPLOAD_RESPONSE=$(curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/files" \ -H "Authorization: Bearer $TOKEN" \ -F "file=@$OPUS_FILE" \ -F "file_type=opus" \ -F "file_name=voice.opus" \ -F "duration=$DURATION_MS")FILE_KEY=$(echo "$UPLOAD_RESPONSE" | python3 -c "import sys,json;data=json.load(sys.stdin);print(data.get('data', {}).get('file_key', ''))" 2>/dev/null || echo "")if [ -z "$FILE_KEY" ]; then echo "❌ 上传失败" echo "$UPLOAD_RESPONSE" exit 1fiecho "✅ 文件上传成功 (file_key: ${FILE_KEY:0:30}...)"# 6. 发送音频消息(duration 用毫秒)echo ""echo "📨 发送音频消息..."SEND_RESPONSE=$(curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"receive_id\": \"$RECEIVER\", \"msg_type\": \"audio\", \"content\": \"{\\\"file_key\\\": \\\"$FILE_KEY\\\", \\\"duration\\\": $DURATION_MS}\" }")MESSAGE_ID=$(echo "$SEND_RESPONSE" | python3 -c "import sys,json;data=json.load(sys.stdin);print(data.get('data', {}).get('message_id', ''))" 2>/dev/null || echo "")if [ -z "$MESSAGE_ID" ]; then echo "❌ 发送失败" echo "$SEND_RESPONSE" exit 1fi# 7. 清理临时文件rm -f "$MP3_FILE" "$OPUS_FILE" 2>/dev/null || true# 8. 完成echo ""echo "━━━━━━━━━━━━━━━━━━━━━━━━━━"echo "🎉 音频消息发送成功!"echo ""echo "📊 统计信息:"echo " • 文本长度: ${#TEXT} 字符"DUR_SEC=$(awk "BEGIN {printf \"%.1f\", $DURATION_MS / 1000}")echo " • 音频时长: ${DUR_SEC} 秒"echo " • 语音: $VOICE"echo " • 格式: Opus (${BITRATE})"echo " • 消息ID: ${MESSAGE_ID:0:20}..."echo ""# 返回消息ID供后续使用echo "$MESSAGE_ID"