主页以及文档: https://autable.github.io/
最近我在尝试把一些公司内部的流程迁移到钉钉 AI 表格, 然而发现并不顺利
[ol]
[/ol]
我也调研了一下开源方案, 一个问题就是 OIDC 登录基本都是付费功能, 商业版 self-host 普遍定价比钉钉/飞书的最高级别的订阅还贵
最终, 我搓了一个符合我需求的 AI 表格
[ol]
[/ol]
目前刚跑通一个使用案例, 可以使用自动化同步钉钉 AI 表格的数据, 已经可以渐进式迁移, 并且可以借助这个打通钉钉内部所有数据的同步
下面是一个周期性同步钉钉 AI 表格的 workflow.js 例子
function instances(info) {
return {
timer: "time.schedule",
dingTable: "dingtalk.notable.records.list",
fields: "table.field.create",
rows: "table.row.upsert"
};
}
function trigger(info) {
return {
instance: "timer",
params: {
interval_ms: 5 * 60 * 1000
}
};
}
function run(info) {
const table = "同步表";
let nextToken = "";
while (true) {
const page = info.instance("dingTable").exec({
max_results: 100,
...(nextToken ? { next_token: nextToken } : {})
});
const records = page.records || [];
info.instance("fields").exec({
table,
fields: fieldsOf(records)
});
for (const record of records) {
info.instance("rows").exec({
table,
match_field: "dingtalk_record_id",
values: valuesOf(record)
});
}
nextToken = page.next_token || "";
if (!page.has_more || !nextToken) break;
}
return { ok: true, table };
}
function fieldsOf(records) {
const fields = {
dingtalk_record_id: "string"
};
for (const record of records) {
for (const name of Object.keys(record.fields || {})) {
fields[name] = "string";
}
}
return fields;
}
function valuesOf(record) {
return {
dingtalk_record_id: String(record.id || ""),
...Object.fromEntries(
Object.entries(record.fields || {}).map(([name, value]) => [
name,
stableStringify(value)
])
)
};
}

