API生成
- 作者仓库星标 0
- 作者更新于 实时读取
- 作者仓库 rdb2wedoc
- 领域
- 通用
- 兼容 Agent
-
- Claude Code
- Cursor
- Cline
- Codex
- Windsurf
- Gemini CLI
- +20
- 信任分
- 88 / 100 · 社区维护
- 作者 / 版本 / 许可
- @nagucc · 未声明 license
- Token 消耗评级
- 低消耗
- 接入复杂程度
- 需简单配置
- 是否需要外部 API Key
- 需要 · Vendor-specific
- 兼容的系统
- 未声明(默认跨平台)
- 底层运行要求
- 无特殊要求
- 文件与系统权限
-
- 只读
- 允许写入 / 修改
- 网络行为
- 允许外网请求
- 安装命令数
- 26 条
档案由构建时根据 SKILL.md 与安装命令自动衍生,可能与作者实际意图存在差异。
需要注意: 未限定 allowed-tools,默认拥有全部工具权限。
---
name: wecom-smartsheet-add-records
description: 提供企业微信智能表格添加记录的正确操作方法,包括不同数据类型的处理格式。当需要与企业微信智能表格进行数据同步时调用。 本skill提供了企业微信智能表格添加记录的正确操作方法,确保不同数据类型…
category: 通用
runtime: 无特殊运行时
---
# wecom-smartsheet-add-records 输出预览
## PART A: 任务判断
- 适用问题:通用任务拆解、检查和交付。
- 输入要求:目标材料、限制条件、期望输出和验收方式。
- 证据边界:围绕“概述 / 适用场景 / 核心代码实现”读取原文规则,不把推断写成作者承诺。
## PART B: 执行结果
- **01** 任务判断:确认你的需求是否属于通用任务拆解、检查和交付,并标出输入、限制和预期结果。
- **02** 执行计划:优先按“概述 / 适用场景 / 核心代码实现”拆成步骤,说明每一步会读取什么、修改什么、产出什么。
- **03** 交付结果:给出可复制的命令、文件改动、检查清单或内容草稿,并说明如何继续迭代。
- **04** 风险边界:结合 读取文件、写入/修改文件、会按任务需要访问外部网络、需要准备 Vendor-specific API Key 给出执行前确认项。
## Running Rules
- 读取文件、写入/修改文件;会按任务需要访问外部网络;需要准备 Vendor-specific API Key。
- 先小样例验证,再放大到真实任务。
- 交付时同时给结果、检查口径和下一步迭代建议。 原文没有稳定的斜杠命令要求。安装验证后通常全局生效,直接在对话里点名这个 Skill 并描述任务即可。
告诉 Agent 目标文件或材料、期望结果、不可改范围、是否允许联网或执行命令。本 Skill 的权限画像是:读取文件、写入/修改文件。
先用一个小任务确认它会围绕“概述 / 适用场景 / 核心代码实现”工作;涉及文件或命令时,先看 diff、日志、预览或测试结果。
检查最终产物是否包含明确结果、必要证据和下一步动作;如果输出泛泛而谈,就补充输入、边界和验收标准后重跑。
---
name: wecom-smartsheet-add-records
description: 提供企业微信智能表格添加记录的正确操作方法,包括不同数据类型的处理格式。当需要与企业微信智能表格进行数据同步时调用。 本skill提供了企业微信智能表格添加记录的正确操作方法,确保不同数据类型…
category: 通用
source: nagucc/rdb2wedoc
---
# wecom-smartsheet-add-records
## 什么时候使用
- 提供企业微信智能表格添加记录的正确操作方法,包括不同数据类型的处理格式 适合处理通用任务拆解、检查、交付和复盘,核心价值是把输入、判断、执行、验证和交付边界固定下来,避免 Agent 泛泛回答。 把任务拆成可执行、可检查、可继续迭代的步…
- 面向通用任务拆解、检查和交付,优先处理能明确输入、步骤和验收标准的工作。
## 需要提供什么
- 目标材料、目录范围、期望结果和不可改动内容。
- 是否允许联网、执行命令、读写文件或调用外部服务。
## 执行规则
- 围绕「概述 / 适用场景 / 核心代码实现」组织步骤,不把推断写成作者事实。
- 读取文件、写入/修改文件;会按任务需要访问外部网络;需要准备 Vendor-specific API Key。
- 先跑小样例,确认结果可检查后再扩大任务范围。
## 输出要求
- 给出最终产物、关键证据、验证方式和下一步动作。
- 信息不足时标记 unknown,不编造命令、平台或依赖。 作者原文负责流程事实;仓库文件负责来源和命令;流狐只补充适用场景、限制和质量判断。
skill "wecom-smartsheet-add-records" {
输入层 -> 用户目标 + 目标文件 + 禁止范围 + 验收标准
上下文层 -> 概述 / 适用场景 / 核心代码实现
规则层 -> SKILL.md 触发条件 / 执行顺序 / 输出格式
运行层 -> 无特殊运行时 | 读取文件、写入/修改文件 | 会按任务需要访问外部网络
安全层 -> 需要准备 Vendor-specific API Key + 小任务验证 + diff / 日志复核
输出层 -> 可复制结果 + 检查清单 + 下一步迭代
} 企业微信智能表格添加记录操作指南
概述
本skill提供了企业微信智能表格添加记录的正确操作方法,确保不同数据类型(数字、日期、文本等)都能按照企业微信API的要求正确处理。
适用场景
- 当需要向企业微信智能表格添加新记录时
- 当需要处理不同数据类型的字段同步时
- 当需要确保数据格式符合企业微信API要求时
核心代码实现
企业微信文档服务类
import axios, { AxiosInstance } from 'axios';
import { WeComDocument, DocumentSheet, DocumentField, WeComAccount } from '@/types';
import { getWeComAccountById } from '@/lib/config/storage';
import { Logger } from '../utils/helpers';
export class WeComDocumentService {
private client: AxiosInstance;
constructor() {
this.client = axios.create({
baseURL: 'https://qyapi.weixin.qq.com',
timeout: 60000,
headers: {
'Content-Type': 'application/json'
}
});
}
async getAccessToken(corpid: string, corpsecret: string): Promise<string> {
try {
const response = await this.client.get('/cgi-bin/gettoken', {
params: {
corpid,
corpsecret
}
});
if (response.data.errcode !== 0) {
throw new Error(`获取access_token失败: ${response.data.errmsg}`);
}
return response.data.access_token;
} catch (error) {
Logger.error('获取企业微信access_token失败', { error: (error as Error).message });
throw error;
}
}
async writeSheetData(
accessToken: string,
documentId: string,
sheetId: string,
data: any[],
fieldTypeMap?: Map<string, string>
): Promise<boolean> {
try {
const records = data.map(row => {
const values: any = {};
Object.keys(row).forEach(key => {
const value = row[key];
if (value !== null && value !== undefined) {
// 根据目标字段类型设置正确的数据类型
const fieldType = fieldTypeMap?.get(key);
if (fieldType === 'number' || fieldType === 'currency' || fieldType === 'percentage') {
// 数字类型直接使用数值
values[key] = Number(value);
} else if (fieldType === 'boolean') {
// 布尔类型直接使用布尔值
values[key] = Boolean(value);
} else if (fieldType === 'datetime') {
// 日期类型使用毫秒时间戳
values[key] = new Date(value).getTime().toString();
} else if (fieldType === 'text' || fieldType === 'url' || fieldType === 'phone' || fieldType === 'email' || fieldType === 'select' || fieldType === 'multi_select' || fieldType === 'user' || fieldType === 'group' || fieldType === 'location' || fieldType === 'formula' || fieldType === 'reference' || fieldType === 'barcode') {
// 文本类型使用对象数组形式
values[key] = [{
type: 'text',
text: String(value)
}];
} else {
// 其他类型默认使用文本形式
values[key] = [{
type: 'text',
text: String(value)
}];
}
}
});
return { values };
});
const response = await this.client.post('/cgi-bin/wedoc/smartsheet/add_records', {
docid: documentId,
sheet_id: sheetId,
key_type: 'CELL_VALUE_KEY_TYPE_FIELD_TITLE',
records: records
}, {
params: {
access_token: accessToken
}
});
if (response.data.errcode !== 0) {
throw new Error(`写入Sheet数据失败: ${response.data.errmsg}`);
}
return true;
} catch (error) {
Logger.error('写入Sheet数据失败', { error: (error as Error).message });
throw error;
}
}
async appendSheetData(
accessToken: string,
documentId: string,
sheetId: string,
data: any[],
fieldTypeMap?: Map<string, string>
): Promise<boolean> {
try {
const records = data.map(row => {
const values: any = {};
Object.keys(row).forEach(key => {
const value = row[key];
if (value !== null && value !== undefined) {
// 根据目标字段类型设置正确的数据类型
const fieldType = fieldTypeMap?.get(key);
if (fieldType === 'number' || fieldType === 'currency' || fieldType === 'percentage') {
// 数字类型直接使用数值
values[key] = Number(value);
} else if (fieldType === 'boolean') {
// 布尔类型直接使用布尔值
values[key] = Boolean(value);
} else if (fieldType === 'datetime') {
// 日期类型使用毫秒时间戳
values[key] = new Date(value).getTime().toString();
} else if (fieldType === 'text' || fieldType === 'url' || fieldType === 'phone' || fieldType === 'email' || fieldType === 'select' || fieldType === 'multi_select' || fieldType === 'user' || fieldType === 'group' || fieldType === 'location' || fieldType === 'formula' || fieldType === 'reference' || fieldType === 'barcode') {
// 文本类型使用对象数组形式
values[key] = [{
type: 'text',
text: String(value)
}];
} else {
// 其他类型默认使用文本形式
values[key] = [{
type: 'text',
text: String(value)
}];
}
}
});
return { values };
});
const response = await this.client.post('/cgi-bin/wedoc/smartsheet/add_records', {
docid: documentId,
sheet_id: sheetId,
key_type: 'CELL_VALUE_KEY_TYPE_FIELD_TITLE',
records: records
}, {
params: {
access_token: accessToken
}
});
if (response.data.errcode !== 0) {
throw new Error(`追加Sheet数据失败: ${response.data.errmsg}`);
}
return true;
} catch (error) {
Logger.error('追加Sheet数据失败', { error: (error as Error).message });
throw error;
}
}
// 其他方法...
}
// 单例模式
export const weComDocumentService = new WeComDocumentService();
字段类型映射
private mapFieldType(fieldType: string): string {
const typeMap: Record<string, string> = {
'FIELD_TYPE_TEXT': 'text',
'FIELD_TYPE_NUMBER': 'number',
'FIELD_TYPE_CHECKBOX': 'boolean',
'FIELD_TYPE_DATE_TIME': 'datetime',
'FIELD_TYPE_IMAGE': 'image',
'FIELD_TYPE_ATTACHMENT': 'file',
'FIELD_TYPE_USER': 'user',
'FIELD_TYPE_URL': 'url',
'FIELD_TYPE_SELECT': 'multi_select',
'FIELD_TYPE_CREATED_USER': 'user',
'FIELD_TYPE_MODIFIED_USER': 'user',
'FIELD_TYPE_CREATED_TIME': 'datetime',
'FIELD_TYPE_MODIFIED_TIME': 'datetime',
'FIELD_TYPE_PROGRESS': 'number',
'FIELD_TYPE_PHONE_NUMBER': 'phone',
'FIELD_TYPE_EMAIL': 'email',
'FIELD_TYPE_SINGLE_SELECT': 'select',
'FIELD_TYPE_REFERENCE': 'reference',
'FIELD_TYPE_LOCATION': 'location',
'FIELD_TYPE_FORMULA': 'formula',
'FIELD_TYPE_CURRENCY': 'currency',
'FIELD_TYPE_WWGROUP': 'group',
'FIELD_TYPE_AUTONUMBER': 'number',
'FIELD_TYPE_PERCENTAGE': 'number',
'FIELD_TYPE_BARCODE': 'text'
};
return typeMap[fieldType] || 'text';
}
数据类型处理规则
| 字段类型 | 处理方式 | 示例 |
|---|---|---|
| number, currency, percentage | 直接使用数值 | 123.45 |
| boolean | 直接使用布尔值 | true |
| datetime | 使用毫秒时间戳字符串 | 1674835200000 |
| text, url, phone, email, select, multi_select, user, group, location, formula, reference, barcode | 使用对象数组形式 | [{ type: 'text', text: 'Hello' }] |
| 其他类型 | 默认使用文本形式 | [{ type: 'text', text: 'Other' }] |
使用示例
基本用法
import { weComDocumentService } from '@/lib/services/wecom-document.service';
// 获取access token
const accessToken = await weComDocumentService.getAccessToken(corpId, corpSecret);
// 准备数据
const data = [
{
'姓名': '张三',
'年龄': 25,
'入职日期': '2023-01-01',
'是否在职': true,
'邮箱': 'zhangsan@example.com'
},
{
'姓名': '李四',
'年龄': 30,
'入职日期': '2022-06-01',
'是否在职': true,
'邮箱': 'lisi@example.com'
}
];
// 准备字段类型映射
const fieldTypeMap = new Map<string, string>();
fieldTypeMap.set('姓名', 'text');
fieldTypeMap.set('年龄', 'number');
fieldTypeMap.set('入职日期', 'datetime');
fieldTypeMap.set('是否在职', 'boolean');
fieldTypeMap.set('邮箱', 'email');
// 写入数据
await weComDocumentService.writeSheetData(
accessToken,
documentId,
sheetId,
data,
fieldTypeMap
);
从同步服务中调用
private async overwriteToDocument(document: WeComDocument, sheetId: string, data: any[], fieldTypeMap?: Map<string, string>): Promise<void> {
const account = getWeComAccountById(document.accountId);
if (!account) {
throw new Error(`关联的企业微信账号不存在,accountId: ${document.accountId}`);
}
const accessToken = await weComDocumentService.getAccessToken(account.corpId, account.corpSecret);
if (!accessToken) {
throw new Error(`获取企业微信access token失败, corpId: ${account.corpId}`);
}
await weComDocumentService.clearSheetData(accessToken, document.id, sheetId);
await weComDocumentService.writeSheetData(accessToken, document.id, sheetId, data, fieldTypeMap);
}
private async appendToDocument(document: WeComDocument, sheetId: string, data: any[], fieldTypeMap?: Map<string, string>): Promise<void> {
const account = getWeComAccountById(document.accountId);
if (!account) {
throw new Error(`关联的企业微信账号不存在,accountId: ${document.accountId}`);
}
const accessToken = await weComDocumentService.getAccessToken(account.corpId, account.corpSecret);
if (!accessToken) {
throw new Error(`获取企业微信access token失败, corpId: ${account.corpId}`);
}
await weComDocumentService.appendSheetData(accessToken, document.id, sheetId, data, fieldTypeMap);
}
注意事项
字段类型映射:确保正确获取目标表格的字段类型,并使用
fieldTypeMap传递给写入方法。空值处理:代码会自动跳过
null和undefined值,避免向智能表格写入空值。日期处理:日期类型需要转换为毫秒时间戳字符串,确保企业微信能正确识别。
文本类型:文本类型必须使用对象数组形式
[{ type: 'text', text: 'value' }],这是企业微信API的要求。数字类型:数字类型直接使用数值,不需要转换为字符串。
布尔类型:布尔类型直接使用布尔值,不需要转换。
API参数:使用
add_records接口时,需要设置key_type: 'CELL_VALUE_KEY_TYPE_FIELD_TITLE',表示使用字段标题作为键。错误处理:添加适当的错误处理,捕获并记录API调用失败的情况。
故障排查
常见问题
文本字段同步失败:检查是否使用了正确的对象数组形式。
日期字段显示不正确:确保日期值已转换为毫秒时间戳字符串。
数字字段不显示:检查是否直接使用了数值,而不是字符串。
API调用失败:检查access token是否有效,文档和表格ID是否正确。
调试建议
- 打印请求数据,确保数据格式符合要求。
- 检查API响应,了解具体的错误信息。
- 验证字段类型映射是否正确。
- 测试单个字段的同步,定位问题所在。
参考文档
最佳实践
预获取字段类型:在同步前先获取目标表格的字段类型,确保数据类型处理正确。
批量操作:对于大量数据,使用批量添加接口,减少API调用次数。
错误重试:添加错误重试机制,提高同步的可靠性。
日志记录:记录同步过程中的关键信息和错误,便于排查问题。
数据验证:在同步前验证数据格式,确保数据符合目标字段的要求。
类型转换:根据目标字段类型自动转换数据格式,提高同步的准确性。
边界情况处理:处理空值、特殊字符等边界情况,确保同步过程稳定。
性能优化:对于大数据量的同步,考虑分批处理,避免超时或内存溢出。
先判断是否适合
作者设计意图
作者的方法与取舍
边界和复核