关于 ops-voice
ops-voice 是用于 Claude 的语音操作技能,通过 curl 发起 API 调用。它支持 Bland AI 电话呼叫、ElevenLabs 文本转语音、Groq 音频转录,以及 API 密钥配置。
主要功能
- 01通过 Bland AI 拨打电话
- 02使用 ElevenLabs 将文本转语音
- 03通过 Groq Whisper 转录音频
- 04扫描并验证 API 密钥
适用场景
- 01根据提示词发起电话呼叫
- 02将文本生成音频文件
- 03转录音频文件
- 04配置并检查语音服务凭据
MCP 相关
该技能可将 Doppler MCP 工具用作 API 凭据来源之一;语音 API 请求通过 curl 发起。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ davepoon/ buildwithclaude --skill ops-voice安装后在 Claude Code 中输入/ops-voice确认已加载。
详细介绍
OPS:VOICE — 语音操作
语音界面命令。所有 API 调用均通过 curl 完成,不依赖 SDK。
凭证解析顺序: userConfig → 环境变量 → Doppler MCP 工具(mcp__doppler__*)→ Doppler CLI 回退(doppler secrets get <KEY> --plain)→ 密码管理器
子命令
解析 $ARGUMENTS,获取命令关键字,然后执行:
call [phone] [prompt] — Bland AI 电话呼叫
需要: userConfig 中的 bland_ai_api_key、BLAND_AI_API_KEY 环境变量或 Doppler 中的密钥。
BLAND_KEY="${BLAND_AI_API_KEY:-$(doppler secrets get BLAND_AI_API_KEY --plain 2>/dev/null || true)}"
PHONE="<extracted from $ARGUMENTS>"
PROMPT="<extracted from $ARGUMENTS or ask user>"
MAX_DURATION="${BLAND_MAX_DURATION:-300}" # seconds
VOICE="${BLAND_VOICE:-male}"
# Make the call
RESPONSE=$(curl -s -X POST "https://api.bland.ai/v1/calls" \
-H "authorization: $BLAND_KEY" \
-H "Content-Type: application/json" \
-d "{
\"phone_number\": \"$PHONE\",
\"task\": \"$PROMPT\",
\"voice\": \"$VOICE\",
\"max_duration\": $MAX_DURATION,
\"record\": true
}")
CALL_ID=$(echo "$RESPONSE" | python3 -c "import json,sys; print(json.load(sys.stdin).get('call_id',''))" 2>/dev/null)
# Poll for completion (up to 5 min)
if [ -n "$CALL_ID" ]; then
echo "Call initiated: $CALL_ID"
for i in $(seq 1 30); do
sleep 10
STATUS=$(curl -s "https://api.bland.ai/v1/calls/$CALL_ID" \
-H "authorization: $BLAND_KEY" | \
python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('status',''), d.get('transcripts','')[-1].get('text','') if d.get('transcripts') else '')" 2>/dev/null)
echo "Status: $STATUS"
[[ "$STATUS" == completed* ]] && break
done
fi
输出: 通话 ID、实时状态,以及通话完成后的转录文本。
tts [text] [--voice voice_id] [--out file.mp3] — ElevenLabs 文本转语音
需要: userConfig 中的 elevenlabs_api_key、ELEVENLABS_API_KEY 环境变量或 Doppler 中的密钥。
EL_KEY="${ELEVENLABS_API_KEY:-$(doppler secrets get ELEVENLABS_API_KEY --plain 2>/dev/null || true)}"
VOICE_ID="${ELEVENLABS_VOICE_ID:-21m00Tcm4TlvDq8ikWAM}" # Rachel (default)
TEXT="<extracted from $ARGUMENTS>"
OUT_FILE="${OUT_FILE:-/tmp/ops-tts-$(date +%s).mp3}"
# List voices if voice name provided (not an ID)
# Synthesize
curl -s -X POST "https://api.elevenlabs.io/v1/text-to-speech/${VOICE_ID}" \
-H "xi-api-key: $EL_KEY" \
-H "Content-Type: application/json" \
-d "{
\"text\": \"$TEXT\",
\"model_id\": \"eleven_monolingual_v1\",
\"voice_settings\": {\"stability\": 0.5, \"similarity_boost\": 0.75}
}" \
--output "$OUT_FILE"
echo "Audio saved to: $OUT_FILE"
# Auto-play on macOS
command -v afplay &>/dev/null && afplay "$OUT_FILE" &
输出: 音频文件路径。在 macOS 上会通过 afplay 自动播放。
transcribe [file_path] — Groq Whisper 转录
需要: userConfig 中的 groq_api_key、GROQ_API_KEY 环境变量或 Doppler 中的密钥。
GROQ_KEY="${GROQ_API_KEY:-$(doppler secrets get GROQ_API_KEY --plain 2>/dev/null || true)}"
AUDIO_FILE="<extracted from $ARGUMENTS>"
if [ ! -f "$AUDIO_FILE" ]; then
echo "ERROR: File not found: $AUDIO_FILE"
exit 1
fi
TRANSCRIPT=$(curl -s -X POST "https://api.groq.com/openai/v1/audio/transcriptions" \
-H "Authorization: Bearer $GROQ_KEY" \
-F "file=@$AUDIO_FILE" \
-F "model=whisper-large-v3" \
-F "response_format=json" | \
python3 -c "import json,sys; print(json.load(sys.stdin).get('text',''))" 2>/dev/null)
echo "$TRANSCRIPT"
输出: 将转录文本打印到 stdout。
setup — 配置语音 API 密钥
在询问任何信息之前,在单个后台批处理中自动扫描所有来源:
# Env vars
printenv BLAND_AI_API_KEY BLAND_API_KEY ELEVENLABS_API_KEY GROQ_API_KEY 2>/dev/null
# Shell profiles
grep -h 'BLAND\|ELEVENLABS\|GROQ' ~/.zshrc ~/.bashrc ~/.zprofile ~/.envrc 2>/dev/null | grep -v '^#'
# Doppler — ALL projects
for proj in $(doppler projects --json 2>/dev/null | jq -r '.[].slug'); do
for cfg in dev stg prd; do
doppler secrets --project "$proj" --config "$cfg" --json 2>/dev/null | \
jq -r --arg proj "$proj" --arg cfg "$cfg" 'to_entries[] | select(.key | test("BLAND|ELEVENLABS|GROQ"; "i")) | "\(.key)=\(.value.computed | .[0:12])... (doppler:\($proj)/\($cfg))"'
done
done
# Dashlane
dcli password bland --output json 2>/dev/null | jq -r '.[] | select(.password != null) | "\(.title): key found"'
dcli password elevenlabs --output json 2>/dev/null | jq -r '.[] | select(.password != null) | "\(.title): key found"'
dcli password groq --output json 2>/dev/null | jq -r '.[] | select(.password != null) | "\(.title): key found"'
# Keychain
security find-generic-password -s "bland-ai-api-key" -w 2>/dev/null
security find-generic-password -s "elevenlabs-api-key" -w 2>/dev/null
security find-generic-password -s "groq-api-key" -w 2>/dev/null
展示所有发现结果。仅询问在所有来源中都未找到的密钥。然后在后台验证每个找到的密钥:
- Bland AI:
curl -s -H "authorization: $KEY" https://api.bland.ai/v1/me— 检查余额 - ElevenLabs:
curl -s -H "xi-api-key: $KEY" https://api.elevenlabs.io/v1/voices?page_size=1— 列出语音 - Groq:
curl -s -H "Authorization: Bearer $KEY" https://api.groq.com/openai/v1/models— 列出模型
报告:[service] ✓ connected 或 [service] ✗ invalid key — [error]
执行
- 根据
$ARGUMENTS解析子命令(第一个词:call / tts / transcribe / setup) - 按顺序解析凭证:环境变量 → Doppler
- 执行上方对应的 curl 代码块
- 如果缺少必需密钥且未调用
setup,建议使用/ops:ops-voice setup