feat: add MiniMax TTS to DingTalk voice message script
This commit is contained in:
116
scripts/dingtalk_tts.sh
Executable file
116
scripts/dingtalk_tts.sh
Executable file
@@ -0,0 +1,116 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# MiniMax TTS → 钉钉语音消息
|
||||||
|
# 依赖: xxd, ffmpeg
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# 配置
|
||||||
|
MINIMAX_API_KEY="sk-cp-WDKUJN0CM7byxgNX8nzr5E8JOe0c3jZP_YVBt200sbYt9bEqsRAeY4O7VldTSg0RBYhNvneKLIttYHDy3YM6m04XWAz4JRW0ABlFHSKXKpuPgZPU02k0MfY"
|
||||||
|
DINGTALK_APP_KEY="dingklemniq8uqk5qbgx"
|
||||||
|
DINGTALK_APP_SECRET="_8EHgyhvHRHRMx6fZbh9LNpQoxyYl3At0b-fXXlQiahwupbt9oY5P6Grj8IM9Dx8"
|
||||||
|
USER_ID="121922510028034588"
|
||||||
|
|
||||||
|
# 临时文件
|
||||||
|
TMP_DIR="/tmp/dingtalk_voice_$$"
|
||||||
|
mkdir -p "$TMP_DIR"
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
rm -rf "$TMP_DIR"
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
# Step 1: 获取钉钉 Access Token
|
||||||
|
echo "[1/6] 获取钉钉 Access Token..."
|
||||||
|
TOKEN_RESPONSE=$(curl -s -X POST 'https://api.dingtalk.com/v1.0/oauth2/accessToken' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d "{\"appKey\":\"$DINGTALK_APP_KEY\",\"appSecret\":\"$DINGTALK_APP_SECRET\"}")
|
||||||
|
|
||||||
|
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('accessToken',''))")
|
||||||
|
if [ -z "$ACCESS_TOKEN" ]; then
|
||||||
|
echo "❌ 获取 Access Token 失败: $TOKEN_RESPONSE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "✓ 获取成功"
|
||||||
|
|
||||||
|
# Step 2: 调用 MiniMax TTS
|
||||||
|
TEXT="$1"
|
||||||
|
if [ -z "$TEXT" ]; then
|
||||||
|
echo "用法: $0 <要转换的文本>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[2/6] 生成 TTS 音频..."
|
||||||
|
TTS_RESPONSE=$(curl -s -X POST "https://api.minimaxi.com/v1/t2a_v2" \
|
||||||
|
-H "Authorization: Bearer $MINIMAX_API_KEY" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{
|
||||||
|
\"model\": \"speech-2.8-hd\",
|
||||||
|
\"text\": \"$TEXT\",
|
||||||
|
\"stream\": false,
|
||||||
|
\"voice_setting\": {
|
||||||
|
\"voice_id\": \"female-tianmei\",
|
||||||
|
\"speed\": 1,
|
||||||
|
\"vol\": 1,
|
||||||
|
\"pitch\": 0,
|
||||||
|
\"emotion\": \"happy\"
|
||||||
|
},
|
||||||
|
\"audio_setting\": {
|
||||||
|
\"sample_rate\": 32000,
|
||||||
|
\"bitrate\": 128000,
|
||||||
|
\"format\": \"mp3\",
|
||||||
|
\"channel\": 1
|
||||||
|
}
|
||||||
|
}")
|
||||||
|
|
||||||
|
HEX_AUDIO=$(echo "$TTS_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('audio',''))")
|
||||||
|
AUDIO_LENGTH=$(echo "$TTS_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('extra_info',{}).get('audio_length',0))")
|
||||||
|
|
||||||
|
if [ -z "$HEX_AUDIO" ]; then
|
||||||
|
echo "❌ TTS 调用失败: $TTS_RESPONSE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "✓ TTS 生成成功,时长: ${AUDIO_LENGTH}ms"
|
||||||
|
|
||||||
|
# Step 3: 转换格式 hex → MP3
|
||||||
|
echo "[3/6] 转换格式..."
|
||||||
|
echo "$HEX_AUDIO" | xxd -r -p > "$TMP_DIR/voice.mp3"
|
||||||
|
|
||||||
|
# 获取时长(秒)
|
||||||
|
DURATION_SEC=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$TMP_DIR/voice.mp3" 2>/dev/null | awk '{printf "%.0f", $1}')
|
||||||
|
if [ -z "$DURATION_SEC" ] || [ "$DURATION_SEC" = "0" ]; then
|
||||||
|
DURATION_SEC=$(echo "scale=0; $AUDIO_LENGTH / 1000" | bc)
|
||||||
|
fi
|
||||||
|
echo "✓ MP3 生成完成,时长: ${DURATION_SEC}秒"
|
||||||
|
|
||||||
|
# Step 4: 上传 MP3 到钉钉
|
||||||
|
echo "[4/6] 上传音频到钉钉..."
|
||||||
|
UPLOAD_RESPONSE=$(curl -s -X POST "https://oapi.dingtalk.com/media/upload?access_token=$ACCESS_TOKEN&type=voice" \
|
||||||
|
-F "media=@$TMP_DIR/voice.mp3;type=audio/mpeg;filename=voice.mp3")
|
||||||
|
|
||||||
|
MEDIA_ID=$(echo "$UPLOAD_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('media_id',''))")
|
||||||
|
if [ -z "$MEDIA_ID" ]; then
|
||||||
|
echo "❌ 上传失败: $UPLOAD_RESPONSE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "✓ 上传成功,mediaId: $MEDIA_ID"
|
||||||
|
|
||||||
|
# Step 5: 发送语音消息
|
||||||
|
echo "[5/6] 发送语音消息..."
|
||||||
|
SEND_RESPONSE=$(curl -s -X POST "https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "x-acs-dingtalk-access-token: $ACCESS_TOKEN" \
|
||||||
|
-d "{
|
||||||
|
\"robotCode\": \"$DINGTALK_APP_KEY\",
|
||||||
|
\"userIds\": [\"$USER_ID\"],
|
||||||
|
\"msgKey\": \"sampleAudio\",
|
||||||
|
\"msgParam\": \"{\\\"mediaId\\\":\\\"$MEDIA_ID\\\",\\\"duration\\\":\\\"$DURATION_SEC\\\"}\"
|
||||||
|
}")
|
||||||
|
|
||||||
|
PROCESS_KEY=$(echo "$SEND_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('processQueryKey',''))")
|
||||||
|
if [ -n "$PROCESS_KEY" ]; then
|
||||||
|
echo "✓ 语音消息发送成功!"
|
||||||
|
echo "[6/6] 完成 ✓"
|
||||||
|
else
|
||||||
|
echo "❌ 发送失败: $SEND_RESPONSE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user