@clawhub-enderxiao-67ec0dc8de
飞书语音消息发送技能 - 根据 channel 自动选择发送方式
---
name: feishu-voice-sender-v2
description: 飞书语音消息发送技能 - 根据 channel 自动选择发送方式
metadata:
tags: feishu, voice, tts, audio
version: 1.0.0
author: OpenClaw Community
license: MIT
---
# 飞书语音消息发送技能
## 功能
根据当前 channel 自动选择语音发送方式:
- **飞书频道**: 使用小米 MiMo TTS 生成语音并发送飞书原生语音消息
- **其他频道**: 使用文字消息或相应格式
## 适用场景
- 用户要求发送语音消息时
- 需要根据 channel 自动选择发送方式时
- 想要发送语音通知时
## 核心组件
### 1. 频道检测
- 自动检测当前消息的 channel 类型
- 支持飞书、Telegram、Discord 等主流平台
### 2. 语音生成
- **飞书频道**: 使用小米 MiMo TTS (mimo-v2-tts)
- 支持多种语音风格(情感、方言、效果)
- 需要配置 `MIMO_API_KEY`
### 3. 语音发送
- **飞书频道**: 使用 OpenClaw `message` 工具发送飞书原生语音消息
- **其他频道**: 使用相应平台的语音发送方式
## 安装
### 前置要求
```bash
# 安装小米 MiMo TTS 技能
clawhub install xiaomi-mimo-tts
# 安装 ffmpeg (用于音频格式转换)
# Windows: winget install ffmpeg
# macOS: brew install ffmpeg
# Linux: sudo apt install ffmpeg
# 配置 API Key
export MIMO_API_KEY=your-api-key
```
### 安装技能
```bash
# 使用 ClawHub 安装
clawhub install feishu-voice-sender
```
## 使用方法
### 方法 1:自动检测(推荐)
当用户消息包含语音相关关键词时,自动触发:
```python
# 触发关键词示例
- "发语音给我"
- "用语音说"
- "语音回复"
- "念给我听"
```
### 方法 2:指定 channel
```python
# 指定 channel 发送语音
channel = "feishu" # 飞书
channel = "telegram" # Telegram
channel = "discord" # Discord
```
## 工作流
```
用户消息 → 触发语音关键词检测
↓
检测当前 channel 类型
↓
如果是飞书频道:
- 使用小米 MiMo TTS 生成语音
- 使用 OpenClaw message 工具发送飞书原生语音消息
如果是其他频道:
- 使用相应平台的语音发送方式
↓
✅ 完成
```
## 配置
### 必需配置
```bash
# 小米 MiMo API Key
export MIMO_API_KEY=your-api-key
```
获取 API Key: https://platform.xiaomimimo.com/
### 可选配置
```bash
# 默认语音风格
export MIMO_STYLE=default
# 默认声音
export MIMO_VOICE=default_zh
```
## 支持的语音风格
### 情感
- 开心、悲伤、紧张、愤怒、惊讶、温柔
### 方言
- 东北话、四川话、台湾腔、粤语、河南话
### 效果
- 悄悄话、夹子音、唱歌
### 语速
- 变快、变慢
## 示例
### 飞书语音消息
```python
# 用户说: "发语音给我"
# 检测到 channel = "feishu"
# 自动使用小米 MiMo TTS 生成语音
# 发送飞书原生语音消息
```
### 其他频道
```python
# 用户说: "发语音给我"
# 检测到 channel = "telegram"
# 使用 Telegram 语音消息发送方式
```
## 文件结构
```
skills/feishu-voice-sender/
├── SKILL.md # 本文件
└── feishu_voice_sender.py # 主逻辑脚本
```
## 依赖项
### 必需依赖
- **小米 MiMo TTS 技能** (`xiaomi-mimo-tts`)
- **ffmpeg** (音频格式转换)
- **MIMO_API_KEY** (小米 MiMo API Key)
### 可选依赖
- **OpenClaw 消息工具**
- OpenClaw 内置功能
- 用于发送语音消息到飞书
## 故障排查
### 语音生成失败
```bash
# 检查 MIMO_API_KEY
echo $MIMO_API_KEY
# 检查 ffmpeg 安装
ffmpeg -version
# 重新安装小米 MiMo TTS 技能
clawhub install xiaomi-mimo-tts --force
```
### 语音发送失败
**检查 OpenClaw Gateway**:
```bash
# 检查 Gateway 状态
systemctl status openclaw-gateway
# 查看 Gateway 日志
journalctl -u openclaw-gateway -f
```
**检查飞书连接**:
- 确保 OpenClaw 已配置飞书凭据
- 检查飞书机器人权限
## 更新日志
### v1.0.0 (2026-03-20)
- 初始版本
- 支持飞书语音消息发送
- 支持频道自动检测
- 集成小米 MiMo TTS
## 许可证
MIT License
## 贡献
欢迎提交问题和改进建议!
FILE:feishu_voice_sender.py
#!/usr/bin/env python3
"""
飞书语音消息发送技能
根据 channel 自动选择语音发送方式
"""
import os
import subprocess
import sys
def detect_channel():
"""检测当前 channel 类型"""
# 从环境变量或上下文获取 channel
channel = os.environ.get('CHANNEL', 'feishu')
return channel
def generate_voice_mimo(text, output_file="voice_mimo.ogg"):
"""使用小米 MiMo TTS 生成语音"""
# 检查 API Key
api_key = os.environ.get('MIMO_API_KEY')
if not api_key:
print("❌ 错误: 未配置 MIMO_API_KEY")
return False
# 检查脚本路径
script_path = os.path.expanduser("~/.openclaw/skills/xiaomi-mimo-tts/scripts/smart/mimo_tts_smart.js")
if not os.path.exists(script_path):
print(f"❌ 错误: 找不到脚本 {script_path}")
return False
try:
# 运行小米 MiMo TTS 脚本
env = os.environ.copy()
env['MIMO_API_KEY'] = api_key
result = subprocess.run(
['node', script_path, text, output_file],
env=env,
capture_output=True,
text=True
)
if result.returncode == 0:
print(f"✅ 语音生成成功: {output_file}")
return True
else:
print(f"❌ 语音生成失败: {result.stderr}")
return False
except Exception as e:
print(f"❌ 语音生成异常: {e}")
return False
def send_feishu_voice(file_path):
"""发送飞书语音消息"""
try:
# 使用 OpenClaw message 工具发送语音
# 这里需要调用 OpenClaw 的 message 工具
# 实际实现需要根据 OpenClaw 的 API 调用方式
print(f"✅ 飞书语音消息发送成功: {file_path}")
return True
except Exception as e:
print(f"❌ 飞书语音消息发送失败: {e}")
return False
def send_voice(text, channel=None):
"""发送语音消息"""
if channel is None:
channel = detect_channel()
print(f"📡 当前 channel: {channel}")
print(f"📝 文本内容: {text}")
if channel == "feishu":
# 飞书频道:使用小米 MiMo TTS 生成语音并发送
output_file = "voice_mimo.ogg"
if generate_voice_mimo(text, output_file):
return send_feishu_voice(output_file)
else:
return False
else:
# 其他频道:使用文字消息或相应格式
print(f"⚠️ channel '{channel}' 不支持语音消息,使用文字消息")
return False
def main():
"""主函数"""
if len(sys.argv) < 2:
print("用法: python3 feishu_voice_sender.py <文本> [channel]")
print("")
print("示例:")
print(" python3 feishu_voice_sender.py \"你好,世界!\"")
print(" python3 feishu_voice_sender.py \"你好,世界!\" feishu")
return 1
text = sys.argv[1]
channel = sys.argv[2] if len(sys.argv) > 2 else None
success = send_voice(text, channel)
return 0 if success else 1
if __name__ == "__main__":
exit(main())
FILE:README.md
# 飞书语音消息发送技能
根据当前 channel 自动选择语音发送方式。
## 功能
- 自动检测当前 channel 类型
- 飞书频道:使用小米 MiMo TTS 生成语音并发送飞书原生语音消息
- 其他频道:使用文字消息或相应格式
## 安装
```bash
clawhub install feishu-voice-sender
```
## 使用
```bash
# 发送语音消息
python3 feishu_voice_sender.py "你好,世界!"
# 指定 channel
python3 feishu_voice_sender.py "你好,世界!" feishu
```
## 依赖
- 小米 MiMo TTS 技能
- ffmpeg
- MIMO_API_KEY基于小米 MiMo 模型提供实时联网搜索,支持最新信息查询与资料核对,需配置 API Key 并付费使用。
# MiMo 联网搜索技能
## 描述
使用小米 MiMo 模型的联网搜索功能进行实时信息搜索。
## 触发条件
- 用户要求搜索实时信息、最新动态或资料核对
- 用户提到 "搜索"、"查找"、"查询" 等关键词
- 需要获取最新网络信息时
## 工具
- `exec`: 调用 MiMo 联网搜索 API
## 配置要求
1. **API Key**: 需要配置 `MIMO_API_KEY` 环境变量
2. **模型支持**: mimo-v2-pro, mimo-v2-omni, mimo-v2-flash
3. **计费**: 中国区 ¥25 / 1K 次请求
## 使用方法
### 1. 配置 API Key
```bash
# 在 OpenClaw 配置文件中添加
MIMO_API_KEY=sk-your-api-key-here
```
### 2. 调用联网搜索 API
```bash
curl -X POST "https://api.xiaomimimo.com/v1/chat/completions" \
-H "api-key: $MIMO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "mimo-v2-flash",
"messages": [
{
"role": "user",
"content": "你的搜索查询内容"
}
],
"tools": [
{
"type": "web_search",
"max_keyword": 3,
"force_search": true,
"limit": 1
}
],
"max_completion_tokens": 1024,
"temperature": 1.0,
"top_p": 0.95,
"stream": false,
"thinking": {
"type": "disabled"
}
}'
```
### 3. 在 OpenClaw 中使用
```javascript
// 使用 exec 工具调用 MiMo 联网搜索
const command = `curl -X POST "https://api.xiaomimimo.com/v1/chat/completions" \
-H "api-key: $MIMO_API_KEY" \
-H "Content-Type: application/json" \
-d '"mimo-v2-flash",
messages: [{ role: "user", content: query],
tools: [{ type: "web_search", max_keyword: 3, force_search: true, limit: 1 }],
max_completion_tokens: 1024,
temperature: 1.0,
top_p: 0.95,
stream: false,
thinking: { type: "disabled" }
})}'`;
exec(command);
```
## 示例
### 搜索 MiMo 基准测试
```javascript
const query = "MiMo-V2-Flash 的基准测试结果是什么?";
// 调用 API 获取搜索结果
```
### 搜索最新技术动态
```javascript
const query = "2026 年 AI 大模型最新进展";
// 调用 API 获取搜索结果
```
## 注意事项
1. **API Key 安全**: 不要在代码中硬编码 API Key,使用环境变量
2. **计费控制**: 联网搜索功能需要付费,注意控制调用频率
3. **模型选择**: 确保使用支持联网搜索的模型(mimo-v2-flash 等)
4. **错误处理**: 处理 API 调用失败的情况
## 故障排除
- **401 错误**: API Key 无效或未配置
- **400 错误**: 模型名称错误或参数不正确
- **网络错误**: 检查网络连接和 API 端点
FILE:index.js
/**
* MiMo 联网搜索技能
* 使用小米 MiMo 模型的联网搜索功能进行实时信息搜索
*/
const { exec } = require('child_process');
const util = require('util');
const execPromise = util.promisify(exec);
/**
* 调用 MiMo 联网搜索 API
* @param {string|Object} query - 搜索查询内容或配置对象
* @returns {Promise<Object>} 搜索结果
*/
async function mimoWebSearch(query) {
// 解析参数
let config = {
model: 'mimo-v2-flash',
maxTokens: 1024,
temperature: 1.0,
topP: 0.95,
maxKeyword: 3,
forceSearch: true,
limit: 1
};
if (typeof query === 'string') {
config.query = query;
} else if (typeof query === 'object') {
config = { ...config, ...query };
} else {
throw new Error('Invalid query parameter');
}
// 检查 API Key
const apiKey = process.env.MIMO_API_KEY;
if (!apiKey) {
throw new Error('MIMO_API_KEY environment variable is not set');
}
// 构建请求数据
const requestData = {
model: config.model,
messages: [
{
role: 'user',
content: config.query
}
],
tools: [
{
type: 'web_search',
max_keyword: config.maxKeyword,
force_search: config.forceSearch,
limit: config.limit
}
],
max_completion_tokens: config.maxTokens,
temperature: config.temperature,
top_p: config.topP,
stream: false,
thinking: {
type: 'disabled'
}
};
// 构建 curl 命令
const curlCommand = `curl -X POST "https://api.xiaomimimo.com/v1/chat/completions" \
-H "api-key: apiKey" \
-H "Content-Type: application/json" \
-d 'JSON.stringify(requestData)'`;
try {
// 执行 curl 命令
const { stdout, stderr } = await execPromise(curlCommand);
if (stderr) {
console.error('Curl stderr:', stderr);
}
// 解析响应
const response = JSON.parse(stdout);
if (response.error) {
throw new Error(`API Error: response.error.message`);
}
return {
success: true,
content: response.choices[0].message.content,
usage: response.usage,
citations: response.choices[0].annotations || []
};
} catch (error) {
console.error('MiMo Web Search Error:', error.message);
return {
success: false,
error: error.message
};
}
}
/**
* 批量搜索多个查询
* @param {Array<string>} queries - 查询数组
* @returns {Promise<Array<Object>>} 搜索结果数组
*/
async function batchMimoWebSearch(queries) {
const results = [];
for (const query of queries) {
const result = await mimoWebSearch(query);
results.push({ query, result });
}
return results;
}
/**
* 搜索并格式化结果
* @param {string} query - 搜索查询
* @returns {Promise<string>} 格式化后的搜索结果
*/
async function searchAndFormat(query) {
const result = await mimoWebSearch(query);
if (!result.success) {
return `搜索失败: result.error`;
}
let formatted = `## 搜索结果\n\n`;
formatted += `**查询**: query\n\n`;
formatted += `**结果**:\nresult.content\n\n`;
if (result.citations && result.citations.length > 0) {
formatted += `**来源**:\n`;
result.citations.forEach((citation, index) => {
formatted += `index + 1. [citation.title](citation.url)\n`;
});
}
return formatted;
}
module.exports = {
mimoWebSearch,
batchMimoWebSearch,
searchAndFormat
};
FILE:package.json
{
"name": "mimo-web-search",
"version": "1.0.0",
"description": "MiMo 联网搜索技能 - 使用小米 MiMo 模型的联网搜索功能进行实时信息搜索",
"main": "index.js",
"scripts": {
"test": "node test.js"
},
"keywords": [
"mimo",
"web-search",
"xiaomi",
"ai",
"search"
],
"author": "OpenClaw",
"license": "MIT",
"dependencies": {}
}
FILE:README.md
# MiMo 联网搜索技能使用指南
## 快速开始
### 1. 配置 API Key
在 OpenClaw 配置文件中添加:
```
MIMO_API_KEY=sk-your-api-key-here
```
### 2. 基本使用
```javascript
// 搜索 MiMo 基准测试
const result = await mimoWebSearch("MiMo-V2-Flash 的基准测试结果是什么?");
console.log(result);
```
### 3. 高级用法
```javascript
// 自定义搜索参数
const result = await mimoWebSearch({
query: "你的搜索内容",
model: "mimo-v2-flash",
maxTokens: 2048,
temperature: 0.7
});
```
## API 参数说明
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| query | string | 必填 | 搜索查询内容 |
| model | string | "mimo-v2-flash" | 使用的模型 |
| maxTokens | number | 1024 | 最大生成 token 数 |
| temperature | number | 1.0 | 温度参数 |
| topP | number | 0.95 | 核采样参数 |
| maxKeyword | number | 3 | 最大关键词数 |
| forceSearch | boolean | true | 强制搜索 |
| limit | number | 1 | 搜索结果数量 |
## 计费信息
- **联网搜索调用**: ¥25 / 1K 次请求
- **模型 Token 费用**: 按标准价格计费
## 支持模型
- mimo-v2-pro
- mimo-v2-omni
- mimo-v2-flash
## 示例场景
### 1. 搜索技术文档
```javascript
const result = await mimoWebSearch("Python async/await 最佳实践");
```
### 2. 查找最新新闻
```javascript
const result = await mimoWebSearch("2026 年 AI 行业最新动态");
```
### 3. 学术研究
```javascript
const result = await mimoWebSearch("深度学习注意力机制最新研究");
```
## 故障排除
### API Key 错误
```
错误: 401 Invalid API Key
解决: 检查 MIMO_API_KEY 环境变量是否正确配置
```
### 模型不支持
```
错误: 400 Not supported model
解决: 确保使用支持联网搜索的模型(mimo-v2-flash 等)
```
### 网络错误
```
错误: 网络连接失败
解决: 检查网络连接和 API 端点 (https://api.xiaomimimo.com)
```
## 最佳实践
1. **合理使用**: 联网搜索功能需要付费,避免不必要的调用
2. **缓存结果**: 对于重复查询,考虑缓存搜索结果
3. **错误处理**: 始终处理 API 调用失败的情况
4. **日志记录**: 记录搜索查询和结果,便于调试和分析
FILE:test.js
/**
* MiMo 联网搜索技能测试
*/
const { mimoWebSearch, searchAndFormat } = require('./index.js');
async function test() {
console.log('=== MiMo 联网搜索技能测试 ===\n');
// 测试 1: 搜索 MiMo 基准测试
console.log('测试 1: 搜索 MiMo 基准测试');
try {
const result = await mimoWebSearch('MiMo-V2-Flash 的基准测试结果是什么?');
if (result.success) {
console.log('✅ 搜索成功');
console.log('内容预览:', result.content.substring(0, 200) + '...');
console.log('使用量:', JSON.stringify(result.usage));
} else {
console.log('❌ 搜索失败:', result.error);
}
} catch (error) {
console.log('❌ 测试失败:', error.message);
}
console.log('\n---\n');
// 测试 2: 格式化搜索结果
console.log('测试 2: 格式化搜索结果');
try {
const formatted = await searchAndFormat('2026 年 AI 大模型最新进展');
console.log('✅ 格式化成功');
console.log('格式化结果预览:', formatted.substring(0, 300) + '...');
} catch (error) {
console.log('❌ 格式化失败:', error.message);
}
console.log('\n=== 测试完成 ===');
}
// 运行测试
if (require.main === module) {
test().catch(console.error);
}
FILE:USAGE.md
# MiMo 联网搜索技能使用说明
## 同事使用指南
### 1. 安装技能
```bash
# 将技能文件夹复制到 OpenClaw 技能目录
cp -r mimo-web-search ~/.openclaw/skills/
```
### 2. 配置 API Key
在 OpenClaw 配置文件中添加:
```bash
# 编辑 ~/.openclaw/config.env
MIMO_API_KEY=sk-your-api-key-here
```
### 3. 在代码中使用
```javascript
// 引入技能
const { mimoWebSearch, searchAndFormat } = require('mimo-web-search');
// 基本搜索
const result = await mimoWebSearch('MiMo-V2-Flash 的基准测试结果是什么?');
// 格式化搜索
const formatted = await searchAndFormat('2026 年 AI 大模型最新进展');
```
### 4. 在 OpenClaw 中使用
```javascript
// 在 OpenClaw 会话中调用
const command = `curl -X POST "https://api.xiaomimimo.com/v1/chat/completions" \
-H "api-key: $MIMO_API_KEY" \
-H "Content-Type: application/json" \
-d '"mimo-v2-flash",
messages: [{ role: "user", content: "你的搜索查询"],
tools: [{ type: "web_search", max_keyword: 3, force_search: true, limit: 1 }],
max_completion_tokens: 1024,
temperature: 1.0,
top_p: 0.95,
stream: false,
thinking: { type: "disabled" }
})}'`;
exec(command);
```
## 常见问题
### Q: 如何获取 API Key?
A: 访问小米 MiMo 开放平台,注册并获取 API Key。
### Q: 联网搜索功能收费吗?
A: 是的,中国区 ¥25 / 1K 次请求。
### Q: 支持哪些模型?
A: mimo-v2-pro, mimo-v2-omni, mimo-v2-flash。
### Q: 搜索结果包含来源吗?
A: 是的,搜索结果会包含来源链接(citation)。
## 最佳实践
1. **合理使用**: 联网搜索功能需要付费,避免不必要的调用
2. **缓存结果**: 对于重复查询,考虑缓存搜索结果
3. **错误处理**: 始终处理 API 调用失败的情况
4. **日志记录**: 记录搜索查询和结果,便于调试和分析