ops-voice について
ops-voiceは、curl経由のAPI呼び出しで音声関連の操作を行うClaudeスキルです。Bland AIでの通話、ElevenLabsによる音声合成、Groqでの音声文字起こし、APIキーの設定に対応します。
主な機能
- 01Bland AIによる電話発信
- 02ElevenLabsによるテキスト読み上げ
- 03Groq Whisperによる音声文字起こし
- 04APIキーの検出と検証
活用シーン
- 01プロンプトに基づく電話発信
- 02テキストから音声ファイルを作成
- 03音声ファイルを文字起こし
- 04音声サービスの認証情報を設定・確認
MCP 対応
API認証情報の取得元の一つとしてDoppler MCPツールを利用できます。音声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 環境変数、または Doppler に bland_ai_api_key があること。
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 環境変数、または Doppler に elevenlabs_api_key があること。
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 環境変数、または Doppler に groq_api_key があること。
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"
出力: 標準出力に表示される文字起こしテキスト。
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] ✓ 接続済み、または [service] ✗ 無効なキー — [error]
実行
$ARGUMENTSからサブコマンドを解決します(最初の単語:call / tts / transcribe / setup)- 順序に従って認証情報を解決します:環境変数 → Doppler
- 該当する上記の curl ブロックを実行します
- 必須のキーがなく、
setupが実行されていない場合は、/ops:ops-voice setupを提案します