Back to skills
SKILL.md
Voice Stt Tts
ASecurityFull voice message setup (STT + TTS) for OpenClaw using faster-whisper and Edge TTS
- 33 stars
- 0 votes
- 0 copies
- 1 view
- Added September 5, 2026
Works with
Security analysis
96/100- Installs packages at runtime which could introduce malicious dependencies
npx -y skills add dvcrn/openclaw-skills-marketplace --skill voice-stt-tts --agent claude-codeAre you the author of Voice Stt Tts?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/dvcrn-voice-stt-tts)---
name: voice-stt-tts
description: "Full voice message setup (STT + TTS) for OpenClaw using faster-whisper and Edge TTS"
homepage: https://docs.openclaw.ai/nodes/audio
---
# Voice Messages (STT + TTS) for OpenClaw ποΈ
Complete voice message setup using **faster-whisper** for transcription and **Edge TTS** for voice replies.
## What we configure
- β
**STT** (Speech-to-Text) β transcribe voice messages via faster-whisper
- β
**TTS** (Text-to-Speech) β voice replies via Edge TTS
- π― **Result:** voice β text β reply with voice
---
## Installation
### 1. Create virtual environment (venv)
For Ubuntu create an isolated venv:
```bash
python3 -m venv ~/.openclaw/workspace/voice-messages
```
### 2. Install faster-whisper
Install packages in venv:
```bash
~/.openclaw/workspace/voice-messages/bin/pip install faster-whisper
```
**What gets installed:**
- `faster-whisper` β Python library for transcription
- Dependencies: `ctranslate2`, `onnxruntime`, `huggingface-hub`, `av`, `numpy`, and others.
- Size: ~250 MB
---
## Transcription Script
### Path and content
**File:** `~/.openclaw/workspace/voice-messages/transcribe.py`
```python
#!/usr/bin/env python3
import argparse
from faster_whisper import WhisperModel
def transcribe(audio_path: str, model_name: str = "small", lang: str = "en", device: str = "cpu") -> str:
model = WhisperModel(
model_name,
device=device,
compute_type="int8" if device == "cpu" else "float16",
)
segments, _ = model.transcribe(audio_path, language=lang, vad_filter=True)
text = " ".join(seg.text.strip() for seg in segments if seg.text and seg.text.strip()).strip()
return text
def main():
p = argparse.ArgumentParser()
p.add_argument("--audio", required=True)
p.add_argument("--model", default="small")
p.add_argument("--lang", default="en")
p.add_argument("--device", default="cpu", choices=["cpu", "cuda"])
args = p.parse_args()
text = transcribe(args.audio, args.model, args.lang, args.device)
print(text if text else "")
if __name__ == "__main__":
main()
```
**What the script does:**
1. Accepts audio file path (`--audio`)
2. Loads Whisper model (`--model`): `small` by default
3. Sets language (`--lang`): `en` for English
4. Transcribes with VAD filter (Voice Activity Detection)
5. Outputs clean text to stdout
### Make file executable:
```bash
chmod +x ~/.openclaw/workspace/voice-messages/transcribe.py
```
---
## OpenClaw Configuration
### 1. Configure STT (`tools.media.audio`)
Add to `~/.openclaw/openclaw.json`:
```json5
{
"tools": {
"media": {
"audio": {
"enabled": true,
"maxBytes": 20971520,
"models": [
{
"type": "cli",
"command": "~/.openclaw/workspace/voice-messages/bin/python",
"args": [
"~/.openclaw/workspace/voice-messages/transcribe.py",
"--audio",
"{{MediaPath}}",
"--lang",
"en",
"--model",
"small"
],
"timeoutSeconds": 120
}
]
}
}
}
}
```
**Parameters:**
| Parameter | Value | Description |
|-----------|----------|-----------|
| `enabled` | `true` | Enable audio transcription |
| `maxBytes` | `20971520` | Max file size (20 MB) |
| `type` | `"cli"` | Model type: CLI command |
| `command` | Python path | Path to python in venv |
| `args` | argument array | Arguments for script |
| `{{MediaPath}}` | placeholder | Replaced with audio file path |
| `timeoutSeconds` | `120` | Transcription timeout (2 minutes) |
### 2. Configure TTS (`messages.tts`)
Add to `~/.openclaw/openclaw.json`:
```json5
{
"messages": {
"tts": {
"auto": "inbound",
"provider": "edge",
"edge": {
"voice": "en-US-JennyNeural",
"lang": "en-US"
}
}
}
}
```
**Parameters:**
| Parameter | Value | Description |
|-----------|----------|-----------|
| `auto` | `"inbound"` | **Key mode!** β reply with voice only on incoming voice messages |
| `provider` | `"edge"` | TTS provider (free, no API key) |
| `voice` | `"en-US-JennyNeural"` | Voice (see available below) |
| `lang` | `"en-US"` | Locale (en-US for US english) |
### 3. Full configuration example
```json5
{
"tools": {
"media": {
"audio": {
"enabled": true,
"maxBytes": 20971520,
"models": [
{
"type": "cli",
"command": "~/.openclaw/workspace/voice-messages/bin/python",
"args": [
"~/.openclaw/workspace/voice-messages/transcribe.py",
"--audio",
"{{MediaPath}}",
"--lang",
"en",
"--model",
"small"
],
"timeoutSeconds": 120
}
]
}
},
},
"messages": {
"tts": {
"auto": "inbound",
"provider": "edge",
"edge": {
"voice": "en-US-JennyNeural",
"lang": "en-US"
}
},
"ackReactionScope": "group-mentions"
}
}
```
---
## Apply Changes
### Restart Gateway
```bash
# Method 1: via openclaw CLI
openclaw gateway restart
# Method 2: via systemd
systemctl --user restart openclaw-gateway
# Check status
systemctl --user status openclaw-gateway
# Should show: active (running)
```
---
## Testing
### Test STT (transcription)
**Action:** Send a voice message to your Telegram bot
**Expected result:**
```
[Audio] User text: [Telegram ...] <media:audio> Transcript: <transcribed text>
```
**Example response:**
```
[Audio] User text: [Telegram kd (@someuser) id:12345678 +5s ...] <media:audio> Transcript: Hello. How are you?
```
### Test TTS (voice replies)
**Action:** After successful transcription, bot should send a voice reply
**Expected result:**
- Voice file arrives in Telegram
- Voice note (round bubble)
**Expected behavior:**
- Incoming voice β bot replies with voice
- Text messages β bot replies with text (this is normal!)
---
## Available Edge TTS Voices
### Female voices
| Voice | ID | Usage example |
|--------|-----|------------------|
| Jenny | `en-US-JennyNeural` | β current |
| Ana | `en-US-AnaNeural` | Softer |
### Male voices
| Voice | ID | Usage example |
|--------|-----|------------------|
| Dmitry | `en-US-RogerNeural` | More bass |
**How to change voice:**
```bash
cat ~/.openclaw/openclaw.json | \
jq '.messages.tts.edge.voice = "en-US-MichelleNeural"' > ~/.openclaw/openclaw.json.tmp
mv ~/.openclaw/openclaw.json.tmp ~/.openclaw/openclaw.json
systemctl --user restart openclaw-gateway
```
---
## Additional Edge TTS Parameters
### Adjusting speed, pitch, volume
```json5
{
"messages": {
"tts": {
"edge": {
"voice": "en-US-JennyNeural",
"lang": "en-US",
"rate": "+10%", // Speed: -50% to +100%
"pitch": "-5%", // Pitch: -50% to +50%
"volume": "+5%" // Volume: -100% to +100%
}
}
}
}
```
---
## Troubleshooting
### Problem: Voice not transcribed
**Logs show:**
```
[ERROR] Transcription failed
```
**Possible causes:**
1. **File too large** β > 20 MB
```bash
# Solution: Increase maxBytes in config
maxBytes: 52428800 # 50 MB
```
2. **Timeout** β transcription took > 2 minutes
```bash
# Solution: Increase timeoutSeconds
timeoutSeconds: 180 # 3 minutes
```
3. **Model not downloaded** β first run
```bash
# Solution: Wait while it downloads (1-2 minutes)
# Models are cached in ~/.cache/huggingface/
```
### Problem: No voice reply
**Possible causes:**
1. **Reply too short** (< 10 characters)
- TTS skips very short replies
- Solution: this is expected behavior
2. **auto: "inbound"** but text message
- TTS in `inbound` mode replies with voice only on **voice messages**
- Text messages get text replies β this is correct!
3. **Edge TTS unavailable**
```bash
# Check
curl -s "https://speech.platform.bing.com/consumer/api/v1/tts" | head -c 100
# If error β temporarily unavailable
```
---
## Performance
### Transcription time (Raspberry Pi 4/ARM)
| Whisper Model | Est. time | Quality |
|---------------|--------------|---------|
| `tiny` | ~5-10 sec | Low |
| `base` | ~10-20 sec | Medium |
| `small` | ~20-40 sec | High β current |
| `medium` | ~40-80 sec | Very high |
| `large` | ~80-160 sec | Maximum |
**Recommendation:** For Raspberry Pi use `small` or `base`. `medium`/`large` will be very slow.
### Where Whisper models are stored
```bash
~/.cache/huggingface/
```
Models download automatically on first run.
## Done! π
After completing these steps:
1. β
faster-whisper installed in venv
2. β
`transcribe.py` script created
3. β
OpenClaw configured (STT + TTS)
4. β
Gateway restarted
5. β
Voice messages working
Now your Telegram bot:
- ποΈ **Accepts voice** β transcribes via faster-whisper
- π€ **Replies with voice** β generates via Edge TTS
- π¬ **Accepts text** β replies with text (as usual)
---
**Useful links:**
- OpenClaw docs: https://docs.openclaw.ai
- TTS docs: https://docs.openclaw.ai/tts
- Audio docs: https://docs.openclaw.ai/nodes/audio
- Install skills: `npx clawhub search voice`
---
*Created: 2026-03-01 for OpenClaw 2026.2.26*
Attribution
Comments
Loading commentsβ¦