Skill: kaqzsd/feishu-voice-reply-huoshan (version 1.0.0)

# 飞书语音回复技能 (Feishu Voice Reply) ## 描述 使用火山引擎 TTS 生成特色音色语音，通过飞书 API 发送语音消息的完整流程技能。支持 MP3 转 Opus 格式、自动上传和发送。 ## 触发词 - `语音回复` - `发送语音` - `TTS 语音` - `飞书语音` - `@voice` ## 前置配置 ### 1. 环境变量设置 在 `~/.openclaw/.env` 或系统环境变量中配置： ```bash # 火山引擎 TTS 配置 export VOLC_API_KEY="你的火山引擎 API Key" export VOLC_RESOURCE_ID="volc.service_type.10029" # 飞书应用配置 export FEISHU_APP_ID="你的飞书 App ID" export FEISHU_APP_SECRET="你的飞书 App Secret" # 可选：默认接收者 Open ID export FEISHU_DEFAULT_USER_ID="ou_xxxxxx" ``` ### 2. 安装依赖 ```bash # 安装 ffmpeg（用于音频格式转换） # Ubuntu/Debian sudo apt install ffmpeg # macOS brew install ffmpeg # CentOS/RHEL sudo yum install ffmpeg ``` ### 3. 火山引擎开通 1. 访问 https://www.volcengine.com/ 2. 注册/登录账号 3. 开通语音合成服务 4. 获取 API Key 5. 创建资源包并获取 Resource ID ### 4. 飞书应用配置 1. 访问 https://open.feishu.cn/app 2. 创建企业自建应用 3. 获取 App ID 和 App Secret 4. 添加权限： - `im:resource` - 上传资源文件 - `im:message` - 发送消息 - `contact:user.base:readonly` - 读取用户信息 5. 发布应用 ## 使用方法 ### 命令行方式 ```bash # 基本用法（使用默认音色） ./scripts/feishu-voice-reply.sh "你好呀，这是测试语音" # 指定音色 ./scripts/feishu-voice-reply.sh "你好" "ICL_zh_female_tiaopigongzhu_tob" # 指定音色和接收者 ./scripts/feishu-voice-reply.sh "你好" "ICL_zh_female_tiaopigongzhu_tob" "ou_xxxxxx" ``` ### OpenClaw 方式 ``` 语音回复 "你好呀，我是语音助手" ``` ## 可用音色 ### 当前资源包可用音色 | 音色 ID | 名称 | 风格 | 性别 | |--------|------|------|------| | `ICL_zh_female_tiaopigongzhu_tob` | 调皮公主 | 活泼可爱 | 女 | | [REDACTED_SECRET] | 北京小爷 | emo 北京腔 | 男 | ### 更多音色 **完整音色列表**: [火山引擎音色列表](https://www.volcengine.com/docs/6561/1257544?lang=zh) #### 女声音色（部分） - 弯弯笑 [REDACTED_SECRET] - 甜美 - 晶晶 `zh_female_jingjing_mars_bigtts` - 清新 - 轻婉 `zh_female_qingwan_mars_bigtts` - 温柔 - 新晴 `zh_female_xinqing_mars_bigtts` - 阳光 - 甜美 `zh_female_tianmei_mars_bigtts` - 甜美 #### 男声音色（部分） - 北京小爷 [REDACTED_SECRET] - 北京腔 - 爽快 `zh_male_shuangkuai_mars_bigtts` - 爽朗 - 青春 `zh_male_qingchun_mars_bigtts` - 青春 > **注意**: 以上音色需要开通对应的资源包才能使用。 ## 执行流程 ``` 用户输入文本 ↓ 1. 调用火山引擎 TTS API → 生成 MP3 音频 ↓ 2. 使用 ffmpeg 转换 → Opus 格式 (32kbps) ↓ 3. 调用飞书 API → 获取 Access Token ↓ 4. 上传 Opus 文件 → 获取 file_key ↓ 5. 发送语音消息 → 飞书用户 ``` ## 文件结构 ``` feishu-voice-reply-clean/ ├── SKILL.md # 技能说明（本文件） ├── README.md # 使用文档 ├── package.json # 包配置 ├── scripts/ │ └── feishu-voice-reply.sh # 自动化脚本 └── config/ └── feishu-voice-config.json # 配置模板 ``` ## 错误处理 | 错误 | 原因 | 解决方案 | |------|------|----------| | `resource ID is mismatched` | 音色不在资源包中 | 更换可用音色 | | `99991661` | 缺少 access token | 检查飞书应用配置 | | `99992402` | 缺少 receive_id_type | 已自动处理 | | `ffmpeg not found` | 未安装 ffmpeg | 安装 ffmpeg | | `VOLC_API_KEY not set` | 未配置环境变量 | 设置环境变量 | ## 配置文件说明 ### 环境变量 | 变量名 | 说明 | 是否必需 | |--------|------|----------| | `VOLC_API_KEY` | 火山引擎 API Key | ✅ 必需 | | `VOLC_RESOURCE_ID` | 火山引擎资源 ID | ✅ 必需 | | `FEISHU_APP_ID` | 飞书应用 App ID | ✅ 必需 | | `FEISHU_APP_SECRET` | 飞书应用 App Secret | ✅ 必需 | | `FEISHU_DEFAULT_USER_ID` | 默认接收者 Open ID | ❌ 可选 | ### 配置模板 复制 `config/feishu-voice-config.json` 为 `config/feishu-voice-config.local.json` 并进行个性化配置。 ## 安全提示 - ⚠️ **不要将 API Key 和 App Secret 提交到代码仓库** - ⚠️ **使用环境变量存储敏感信息** - ✅ 配置文件已加入 `.gitignore` - ✅ 生产环境使用独立的密钥管理 ## 相关文档 - [火山引擎 TTS 文档](https://www.volcengine.com/docs/6561/195562) - [火山引擎音色列表](https://www.volcengine.com/docs/6561/1257544?lang=zh) - [飞书开放平台](https://open.feishu.cn/document/home) - [飞书消息类型](https://open.feishu.cn/document/ukTMukTMukTM/uEjNwUjLxYDM14SM2ATN) ## 更新日志 ### v1.0.0 (2026-03-13) - ✅ 初始版本发布 - ✅ 支持火山引擎 TTS 多音色 - ✅ 支持飞书语音消息发送 - ✅ 自动 MP3 转 Opus 格式 - ✅ 完整错误处理 - ✅ 详细文档 --- *最后更新：2026-03-13 | 作者：沉寂 (chenji) | License: MIT*

path: package.json
content: {
  "name": "feishu-voice-reply-clean",
  "displayName": "Feishu Voice Reply",
  "description": "飞书语音回复技能 - 使用火山引擎 TTS 生成特色音色语音并通过飞书 API 发送。支持 MP3 转 Opus 格式、自动上传和发送。",
  "version": "1.0.0",
  "author": "沉寂 (chenji)",
  "license": "MIT",
  "keywords": [
    "feishu",
    "voice",
    "tts",
    "语音",
    "飞书",
    "火山引擎",
    "audio",
    "reply"
  ],
  "repository": {
    "type": "git",
    "url": "https://github.com/chenji/openclaw-skills"
  },
  "engines": {
    "openclaw": ">=2026.3.0"
  },
  "scripts": {
    "test": "bash scripts/feishu-voice-reply.sh \"测试语音\""
  },
  "dependencies": {
    "ffmpeg": "*"
  },
  "config": {
    "volcengine": {
      "api_key": "环境变量：VOLC_API_KEY",
      "resource_id": "volc.service_type.10029",
      "default_speaker": "ICL_zh_female_tiaopigongzhu_tob"
    },
    "feishu": {
      "app_id": "环境变量：FEISHU_APP_ID",
      "app_secret": "环境变量：FEISHU_APP_SECRET"
    }
  }
}


path: README.md
content: # 飞书语音回复技能

使用火山引擎 TTS 生成特色音色语音，通过飞书 API 发送语音消息的完整流程技能。

## 📁 文件结构

```
feishu-voice-reply-clean/
├── SKILL.md                      # 技能说明
├── README.md                     # 本文件
├── package.json                  # 包配置
├── scripts/
│   └── feishu-voice-reply.sh     # 自动化脚本
└── config/
    └── feishu-voice-config.json  # 配置模板
```

## 🚀 快速开始

### 1. 配置环境变量

```bash
# 编辑 ~/.openclaw/.env 文件
nano ~/.openclaw/.env

# 添加以下内容（替换为你的实际配置）
export VOLC_API_KEY="你的火山引擎 API Key"
export VOLC_RESOURCE_ID="volc.service_type.10029"
export FEISHU_APP_ID="你的飞书 App ID"
export FEISHU_APP_SECRET="你的飞书 App Secret"
export FEISHU_DEFAULT_USER_ID="你的 Open ID（可选）"

# 使配置生效
source ~/.openclaw/.env
```

### 2. 测试技能

```bash
# 进入技能目录
cd ~/.openclaw/workspace/skills/feishu-voice-reply-clean

# 运行测试
bash scripts/feishu-voice-reply.sh "你好呀，这是测试语音"
```

### 3. 使用技能

```bash
# 基本用法
bash scripts/feishu-voice-reply.sh "你好呀，这是测试语音"

# 指定音色
bash scripts/feishu-voice-reply.sh "你好" "ICL_zh_female_tiaopigongzhu_tob"

# 指定音色和接收者
bash scripts/feishu-voice-reply.sh "你好" "ICL_zh_female_tiaopigongzhu_tob" "ou_xxxxxx"
```

## 🎵 可用音色

### 已测试音色

| 音色 ID | 名称 | 风格 | 性别 |
|--------|------|------|------|
| `ICL_zh_female_tiaopigongzhu_tob` | 调皮公主 | 活泼可爱 | 女 |
| `zh_male_beijingxiaoye_emo_v2_mars_bigtts` | 北京小爷 | emo 北京腔 | 男 |

### 更多音色

访问 [火山引擎音色列表](https://www.volcengine.com/docs/6561/1257544?lang=zh) 查看完整列表。

## 🔧 配置说明

### 必需配置

| 配置项 | 环境变量 | 获取方式 |
|--------|----------|----------|
| 火山引擎 API Key | `VOLC_API_KEY` | 火山引擎控制台 |
| 火山引擎资源 ID | `VOLC_RESOURCE_ID` | 火山引擎控制台 |
| 飞书 App ID | `FEISHU_APP_ID` | 飞书开放平台 |
| 飞书 App Secret | `FEISHU_APP_SECRET` | 飞书开放平台 |

### 可选配置

| 配置项 | 环境变量 | 默认值 |
|--------|----------|--------|
| 默认接收者 | `FEISHU_DEFAULT_USER_ID` | 当前会话用户 |

## ⚠️ 错误处理

| 错误信息 | 原因 | 解决方案 |
|---------|------|----------|
| `resource ID is mismatched` | 音色不在资源包中 | 更换可用音色 |
| `99991661` | 缺少 access token | 检查飞书应用配置 |
| `ffmpeg not found` | 未安装 ffmpeg | `sudo apt install ffmpeg` |
| `VOLC_API_KEY not set` | 未配置环境变量 | 设置环境变量 |

## 📖 使用示例

### 示例 1：发送测试语音

```bash
bash scripts/feishu-voice-reply.sh "你好，这是测试语音"
```

### 示例 2：使用不同音色

```bash
# 调皮公主（女声）
bash scripts/feishu-voice-reply.sh "你好呀" "ICL_zh_female_tiaopigongzhu_tob"

# 北京小爷（男声）
bash scripts/feishu-voice-reply.sh "你好" "zh_male_beijingxiaoye_emo_v2_mars_bigtts"
```

### 示例 3：发送给指定用户

```bash
bash scripts/feishu-voice-reply.sh "你好" "ICL_zh_female_tiaopigongzhu_tob" "ou_xxxxxx"
```

## 🔐 安全提示

- ⚠️ **不要将 API Key 和 App Secret 提交到代码仓库**
- ⚠️ **使用环境变量存储敏感信息**
- ✅ 配置模板已提供，实际配置需自行创建
- ✅ 生产环境使用独立的密钥管理

## 📚 相关文档

- [火山引擎 TTS 文档](https://www.volcengine.com/docs/6561/195562)
- [火山引擎音色列表](https://www.volcengine.com/docs/6561/1257544?lang=zh)
- [飞书开放平台](https://open.feishu.cn/document/home)
- [飞书消息类型](https://open.feishu.cn/document/ukTMukTMukTM/uEjNwUjLxYDM14SM2ATN)

## 🤝 贡献

欢迎提交 Issue 和 Pull Request！

## 📄 许可证

MIT License

---

*最后更新：2026-03-13 | 作者：沉寂 (chenji)*


path: scripts/feishu-voice-reply.sh
content: #!/bin/bash
#
# 飞书语音回复自动化脚本
# 使用火山引擎 TTS 生成特色音色语音，通过飞书 API 发送语音消息
#
# 用法：./feishu-voice-reply.sh "要转换的文本" [音色] [用户 ID]
# 示例：./feishu-voice-reply.sh "你好呀" "ICL_zh_female_tiaopigongzhu_tob" "ou_xxxxxx"
#

set -e

# 参数
TEXT="${1:-你好呀，我是语音助手}"

# 音色配置：复制火山引擎音色列表中的音色 ID 到此处
# 可用音色示例:
#   ICL_zh_female_tiaopigongzhu_tob        - 调皮公主 (女，活泼可爱) ✅已测试
#   zh_male_beijingxiaoye_emo_v2_mars_bigtts - 北京小爷 emo (男) ✅已测试
#   zh_female_wanwanxiao_mars_bigtts       - 弯弯笑 (女，甜美)
#   zh_female_jingjing_mars_bigtts         - 晶晶 (女，清新)
#   zh_female_qingwan_mars_bigtts          - 轻婉 (女，温柔)
#   zh_male_beijingxiaoye_mars_bigtts      - 北京小爷 (男，北京腔)
# 完整音色列表：https://www.volcengine.com/docs/6561/1257544?lang=zh
SPEAKER="${2:-ICL_zh_female_tiaopigongzhu_tob}"
USER_ID="${3:-${FEISHU_DEFAULT_USER_ID:-}}"

# 配置文件（从环境变量读取）
# 火山引擎 API 配置
if [ -z "$VOLC_API_KEY" ]; then
    echo "❌ 错误：VOLC_API_KEY 环境变量未设置"
    echo "请在 ~/.openclaw/.env 或系统环境变量中设置 VOLC_API_KEY"
    exit 1
fi

if [ -z "$VOLC_RESOURCE_ID" ]; then
    echo "❌ 错误：VOLC_RESOURCE_ID 环境变量未设置"
    echo "请在 ~/.openclaw/.env 或系统环境变量中设置 VOLC_RESOURCE_ID"
    exit 1
fi

# 飞书应用配置
if [ -z "$FEISHU_APP_ID" ]; then
    echo "❌ 错误：FEISHU_APP_ID 环境变量未设置"
    echo "请在 ~/.openclaw/.env 或系统环境变量中设置 FEISHU_APP_ID"
    exit 1
fi

if [ -z "$FEISHU_APP_SECRET" ]; then
    echo "❌ 错误：FEISHU_APP_SECRET 环境变量未设置"
    echo "请在 ~/.openclaw/.env 或系统环境变量中设置 FEISHU_APP_SECRET"
    exit 1
fi

# 临时文件
TMP_MP3="/tmp/voice-tts-$.mp3"
TMP_OPUS="/tmp/voice-tts-$.opus"

# 清理函数
cleanup() {
    rm -f "$TMP_MP3" "$TMP_OPUS" 2>/dev/null
}
trap cleanup EXIT

echo "🎤 飞书语音回复"
echo "================"
echo "📝 文本：$TEXT"
echo "🎵 音色：$SPEAKER"
echo "👤 用户：${USER_ID:-当前会话用户}"
echo ""

# 步骤 1：生成 TTS 音频
echo "⏳ 步骤 1/5: 生成火山引擎 TTS 音频..."
RESPONSE=$(curl -sL -X POST 'https://openspeech.bytedance.com/api/v3/tts/unidirectional' \
  -H "x-[REDACTED_SECRET]" \
  -H "X-Api-Resource-Id: $VOLC_RESOURCE_ID" \
  -H 'Content-Type: application/json' \
  -d "{
      \"req_params\": {
          \"text\": \"$TEXT\",
          \"speaker\": \"$SPEAKER\",
          \"additions\": \"{\\\"disable_markdown_filter\\\":true,\\\"enable_language_detector\\\":true}\",
          \"audio_params\": {
              \"format\": \"mp3\",
              \"sample_rate\": 24000
          }
      }
  }")

CODE=$(echo "$RESPONSE" | jq -r '.code // empty')
if [ "$CODE" != "0" ]; then
    echo "❌ TTS 生成失败：$(echo "$RESPONSE" | jq -r '.message')"
    exit 1
fi

echo "$RESPONSE" | jq -r '.data' | base64 -d > "$TMP_MP3"

if [ ! -f "$TMP_MP3" ] || [ ! -s "$TMP_MP3" ]; then
    echo "❌ TTS 音频文件生成失败"
    exit 1
fi

echo "✅ TTS 生成成功"

# 步骤 2：转换为 Opus 格式
echo "⏳ 步骤 2/5: 转换为 Opus 格式..."
ffmpeg -i "$TMP_MP3" -c:a libopus -b:a 32k "$TMP_OPUS" -y 2>/dev/null

if [ ! -f "$TMP_OPUS" ] || [ ! -s "$TMP_OPUS" ]; then
    echo "❌ Opus 格式转换失败"
    exit 1
fi

echo "✅ Opus 转换成功 ($(ls -lh "$TMP_OPUS" | awk '{print $5}'))"

# 步骤 3：获取飞书 Tenant Access Token
echo "⏳ 步骤 3/5: 获取飞书 Access Token..."
TOKEN_RESPONSE=$(curl -sL -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\"
  }")

[REDACTED_SECRET] "$TOKEN_RESPONSE" | jq -r '.tenant_access_token')
TOKEN_CODE=$(echo "$TOKEN_RESPONSE" | jq -r '.code // 0')

if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ] || [ "$TOKEN_CODE" != "0" ]; then
    echo "❌ 获取飞书 token 失败：$(echo "$TOKEN_RESPONSE" | jq -r '.msg')"
    exit 1
fi

echo "✅ Access Token 获取成功"

# 步骤 4：上传 Opus 文件获取 file_key
echo "⏳ 步骤 4/5: 上传音频文件到飞书..."
UPLOAD_RESPONSE=$(curl -sL -X POST 'https://open.feishu.cn/open-apis/im/v1/files' \
  -H "Authorization: Bearer $TOKEN" \
  -F 'file_type=opus' \
  -F 'file_name=voice.opus' \
  -F 'duration=6000' \
  -F "file=@$TMP_OPUS")

FILE_KEY=$(echo "$UPLOAD_RESPONSE" | jq -r '.data.file_key')
UPLOAD_CODE=$(echo "$UPLOAD_RESPONSE" | jq -r '.code // 999')

if [ -z "$FILE_KEY" ] || [ "$FILE_KEY" = "null" ] || [ "$UPLOAD_CODE" != "0" ]; then
    echo "❌ 上传文件失败：$(echo "$UPLOAD_RESPONSE" | jq -r '.msg')"
    exit 1
fi

echo "✅ 文件上传成功 (file_key: $FILE_KEY)"

# 步骤 5：发送语音消息
echo "⏳ 步骤 5/5: 发送语音消息..."

# 如果没有指定 USER_ID，提示用户
if [ -z "$USER_ID" ]; then
    echo "⚠️  未指定接收者 USER_ID"
    echo "请设置 FEISHU_DEFAULT_USER_ID 环境变量或在命令中指定用户 ID"
    echo ""
    echo "用法示例:"
    echo "  $0 \"$TEXT\" \"$SPEAKER\" \"ou_xxxxxx\""
    exit 1
fi

SEND_RESPONSE=$(curl -sL -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\": \"$USER_ID\",
    \"msg_type\": \"audio\",
    \"content\": \"{\\\"file_key\\\":\\\"$FILE_KEY\\\"}\"
  }")

SEND_CODE=$(echo "$SEND_RESPONSE" | jq -r '.code // 999')

if [ "$SEND_CODE" != "0" ]; then
    echo "❌ 发送语音消息失败：$(echo "$SEND_RESPONSE" | jq -r '.msg')"
    exit 1
fi

MESSAGE_ID=$(echo "$SEND_RESPONSE" | jq -r '.data.message_id')
echo "✅ 语音消息发送成功！"
echo ""
echo "================"
echo "📬 消息 ID: $MESSAGE_ID"
echo "🎵 音色：$SPEAKER"
echo "👤 接收者：$USER_ID"
echo "================"
echo ""

exit 0


path: config/feishu-voice-config.json
content: {
  "description": "飞书语音回复技能配置模板",
  "note": "复制此文件为 feishu-voice-config.local.json 并填入实际配置",
  "volcengine": {
    "api_key": "请从环境变量 VOLC_API_KEY 读取",
    "resource_id": "volc.service_type.10029",
    "default_speaker": "ICL_zh_female_tiaopigongzhu_tob",
    "doc_url": "https://www.volcengine.com/docs/6561/1257544?lang=zh",
    "available_speakers": [
      {
        "id": "ICL_zh_female_tiaopigongzhu_tob",
        "name": "调皮公主",
        "style": "活泼可爱",
        "gender": "female",
        "tested": true
      },
      {
        "id": "zh_male_beijingxiaoye_emo_v2_mars_bigtts",
        "name": "北京小爷",
        "style": "emo 北京腔",
        "gender": "male",
        "tested": true
      }
    ]
  },
  "feishu": {
    "app_id": "请从环境变量 FEISHU_APP_ID 读取",
    "app_secret": "请从环境变量 FEISHU_APP_SECRET 读取",
    "default_user_id": "请从环境变量 FEISHU_DEFAULT_USER_ID 读取"
  },
  "audio": {
    "output_format": "opus",
    "bitrate": "32k",
    "sample_rate": 24000,
    "temp_dir": "/tmp"
  },
  "environment_variables": {
    "required": [
      "VOLC_API_KEY",
      "VOLC_RESOURCE_ID",
      "FEISHU_APP_ID",
      "FEISHU_APP_SECRET"
    ],
    "optional": [
      "FEISHU_DEFAULT_USER_ID"
    ],
    "setup_guide": "在 ~/.openclaw/.env 文件中添加上述环境变量"
  }
}


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)