> ## Documentation Index
> Fetch the complete documentation index at: https://help.teable.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# AI 脚本

> 使用 JavaScript 代码自动化处理数据，实现复杂的业务逻辑和数据操作

<Note>云端版本所有方案可用；私有部署版本需要商业版及以上方案。</Note>

编码提示：本文档为 AI 脚本功能提供了编码指南和示例。为了获得最佳的编码效果，建议使用 claude-sonnet-4 模型来编写和优化脚本。

## 基础概念

Teable 脚本功能让您可以通过 JavaScript 代码自动化处理数据，实现复杂的业务逻辑和数据操作。

## 执行环境

* **语言**: JavaScript (ES6+)
* **环境**: 安全沙箱环境
* **模块系统**: CommonJS (`require()`)
* **支持**: 顶级 await、现代 JavaScript 特性

## 获取输入数据

脚本通过 `input` 对象获取前面工作流步骤的输出。每个前序步骤的输出以其 actionId 作为键名：

```javascript theme={null}
// 查看所有可用的action ID
console.log("可用的action节点:", Object.keys(input));

// 获取第一个action的数据（最常见的情况）
const actionIds = Object.keys(input);
const firstAction = input[actionIds[0]];

// 获取用户信息
const user = firstAction.user;
console.log("用户名:", user.name);

// 获取记录信息
const record = firstAction.record;
console.log("记录名称:", record.name);
console.log("记录ID:", record.id);

// 获取字段值（使用字段ID）
const fields = record.fields;
console.log("所有字段:", Object.keys(fields));

// 示例：获取具体字段值
const taskName = fields.fldUzGUph7OcCoBs8Ax; // 任务名称
const priority = fields.fldLutlmzOfk0XCWStS; // 优先级
const status = fields.fldOvtZuB4WTac5LSNx; // 状态
```

## 设置输出结果（推荐方式）

**使用 `output.set()` 是最佳方式**，因为它能保留对象的完整格式：

```javascript theme={null}
// 推荐：使用 output.set() 设置输出
const actionIds = Object.keys(input);
const record = input[actionIds[0]].record;

// 设置单个值
output.set("taskName", record.name);
output.set("priority", record.fields.fldLutlmzOfk0XCWStS);

// 设置对象（推荐）
output.set("taskInfo", {
  id: record.id,
  name: record.name,
  priority: record.fields.fldLutlmzOfk0XCWStS,
  status: record.fields.fldOvtZuB4WTac5LSNx,
  url: record.url,
});

// 设置数组
output.set("fieldList", Object.keys(record.fields));

// 设置处理结果
output.set("processed", true);
output.set("message", "任务处理完成");
```

## 依赖管理

如果使用外部 npm 包，必须在依赖配置中声明：

```javascript theme={null}
// 代码中使用lodash
const _ = require("lodash");

// 如果需要使用指定版本，则必须在 dependencies 中配置，否则沙箱会自动解析最新的包
[{ name: "lodash", version: "4.17.21" }];
```

**建议：优先使用 JavaScript 内置功能，避免额外依赖**

## HTTP 请求

使用内置的 `fetch()` 函数：

```javascript theme={null}
// GET 请求
const response = await fetch("https://api.example.com/data");
const data = await response.json();
output.set("apiData", data);

// POST 请求
const response = await fetch("https://api.example.com/create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer your-token",
  },
  body: JSON.stringify({ name: "test", value: 123 }),
});

const result = await response.json();
output.set("createResult", result);
```

## 调试技巧

### 1. 查看输入数据结构

```javascript theme={null}
// 查看完整输入结构
console.log("完整输入:", JSON.stringify(input, null, 2));

// 查看第一个action的数据
const firstActionId = Object.keys(input)[0];
const firstAction = input[firstActionId];
console.log("第一个action:", firstAction);

// 查看字段信息
if (firstAction.record && firstAction.record.fields) {
  console.log("可用字段:", Object.keys(firstAction.record.fields));
  for (const fieldId in firstAction.record.fields) {
    console.log(`${fieldId}: ${firstAction.record.fields[fieldId]}`);
  }
}

// 临时输出调试信息
output.set("debug", {
  actionIds: Object.keys(input),
  firstAction: firstAction,
  fields: firstAction.record ? Object.keys(firstAction.record.fields) : [],
});
```

### 2. 错误处理

```javascript theme={null}
try {
  // 你的主要代码
  const actionIds = Object.keys(input);
  const record = input[actionIds[0]].record;

  output.set("result", "处理成功");
  output.set("data", record.name);
} catch (error) {
  console.error("处理出错:", error.message);
  output.set("error", true);
  output.set("message", error.message);
}
```

## 快速上手步骤

1. **先调试输入** - 使用 `console.log(JSON.stringify(input, null, 2))` 查看数据结构
2. **提取需要的数据** - 通过 `input[actionId].record.fields[fieldId]` 获取字段值
3. **处理数据** - 使用 JavaScript 进行计算、转换、过滤等操作
4. **设置输出** - 用 `output.set(key, value)` 设置结果
5. **测试验证** - 运行脚本检查输出是否符合预期

## 实际应用示例

### 基础数据处理

```javascript theme={null}
// 处理输入数据
const inputData = input.dataNode.records;
const processedRecords = inputData.map((record) => ({
  id: record.id,
  title: record.title,
  content: `标题: ${record.title}\n内容: ${record.content}`,
  updatedAt: new Date().toISOString(),
}));

// 输出结果
output.set("processedRecords", processedRecords);
output.set("totalCount", processedRecords.length);
output.set("status", "success");
```

### API 调用示例

```javascript theme={null}
try {
  const response = await fetch("https://api.example.com/data");
  const data = await response.json();

  output.set("apiData", data);
  output.set("success", true);
} catch (error) {
  output.set("success", false);
  output.set("error", error.message);
}
```

### Teable API 操作

```javascript theme={null}
// 基本配置
const baseUrl = "https://app.teable.cn/api";
const token = process.env.AUTOMATION_TOKEN; // 内置token

// 创建记录
async function createRecord(tableId, recordData) {
  const response = await fetch(`${baseUrl}/table/${tableId}/record`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      records: [{ fields: recordData }],
    }),
  });

  return response.json();
}

// 使用示例
const newRecord = await createRecord("tbl123", {
  姓名: "张三",
  邮箱: "zhangsan@example.com",
});

output.set("createdRecord", newRecord);
```

## 注意事项

### 认证和安全

* 使用内置的 `process.env.AUTOMATION_TOKEN`
* 避免在脚本中硬编码敏感信息
* 确保脚本只访问必要的表格和字段

### 数据处理

* 建议开启 `typecast: true` 进行自动类型转换
* 处理前验证输入数据的完整性和格式
* 使用有意义的字段名

### 性能优化

* 优先使用批量操作而非循环单条操作
* 大量数据时使用分页查询
* 只获取需要的字段

### 错误处理

* 所有 API 调用都要用 try/catch 包装
* 记录详细的错误信息便于调试
* 实现优雅降级，部分失败时不影响整体流程

## 常用 Teable API 端点

```javascript theme={null}
// 查询记录
GET / table / { tableId } / record;

// 创建记录
POST / table / { tableId } / record;

// 更新记录
PATCH / table / { tableId } / record;

// 删除记录
DELETE / table / { tableId } / record;

// 获取表格信息
GET / table / { tableId };

// 获取字段列表
GET / table / { tableId } / field;
```

## 获取帮助

如果您有具体的脚本需求或遇到问题，请在脚本编辑器中详细描述您的需求，AI 会为您生成相应的代码示例和解决方案。
