跳到主要內容

Airtable

通過 curl 使用 Airtable REST API。支持記錄的 CRUD、過濾和 upsert(更新或插入)。

技能元數據

來源Bundled(默認安裝)
路徑skills/productivity/airtable
版本1.1.0
作者community
許可證MIT
平臺linux, macos, windows
標籤Airtable, Productivity, Database, API

參考:完整 SKILL.md

信息

以下是 Hermes 在觸發此技能時加載的完整技能定義。這是技能激活時代理看到的指令。

Airtable — Base、表與記錄

通過 terminal 工具直接使用 curl 操作 Airtable 的 REST API。無需 MCP 服務器,無需 OAuth 流程,無需 Python SDK — 只需 curl 和個人訪問令牌。

前提條件

  1. https://airtable.com/create/tokens 創建個人訪問令牌 (PAT)(令牌以 pat... 開頭)。
  2. 授予以下作用域(最低要求):
    • data.records:read — 讀取行
    • data.records:write — 創建/更新/刪除行
    • schema.bases:read — 列出 base 和表
  3. 重要: 在同一令牌界面中,將每個要訪問的 base 添加到令牌的訪問 (Access) 列表中。PAT 是按 base 限定作用域的 — 在錯誤的 base 上使用有效令牌將返回 403
  4. 將令牌存儲在 ~/.hermes/.env 中(或通過 hermes setup):
   AIRTABLE_API_KEY=pat_your_token_here

注意:舊版 key... API 密鑰已於 2024 年 2 月棄用。現在僅支持 PAT 和 OAuth 令牌。

API 基礎

  • 端點: https://api.airtable.com/v0
  • 認證頭: Authorization: Bearer $AIRTABLE_API_KEY
  • 所有請求均使用 JSON(任何 POST/PATCH/PUT 正文的 Content-Type: application/json)。
  • 對象 ID: base 為 app...,表為 tbl...,記錄為 rec...,字段為 fld...。ID 永不更改;名稱可能會變。在自動化中優先使用 ID。
  • 速率限制: 每個 base 每秒 5 個請求。遇到 429 時需退避。單個 base 上的突發請求將被限流。

基本 curl 模式:

curl -s "https://api.airtable.com/v0/$BASE_ID/$TABLE?maxRecords=5" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.tool

-s 抑制 curl 的進度條 — 每次調用都保持設置此項,以便工具輸出對 Hermes 保持乾淨。通過 python3 -m json.tool(始終存在)或 jq(如果已安裝)管道傳輸以獲得可讀的 JSON。

字段類型(請求正文形狀)

字段類型寫入形狀
單行文本"Name": "hello"
長文本"Notes": "multi\nline"
數字"Score": 42
複選框"Done": true
單選"Status": "Todo"(除非 typecast: true,否則名稱必須已存在)
多選"Tags": ["urgent", "bug"]
日期"Due": "2026-04-01"
日期時間 (UTC)"At": "2026-04-01T14:30:00.000Z"
URL / 電子郵件 / 電話"Link": "https://…"
附件"Files": [{"url": "https://…"}](Airtable 獲取並重新託管)
關聯記錄"Owner": ["recXXXXXXXXXXXXXX"](記錄 ID 數組)
用戶"AssignedTo": {"id": "usrXXXXXXXXXXXXXX"}

在創建/更新正文的頂層傳遞 "typecast": true,以讓 Airtable 自動強制轉換值(例如,動態創建新的選項值,將 "42" 轉換為 42)。

常見查詢

列出令牌可見的 base

curl -s "https://api.airtable.com/v0/meta/bases" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.tool

列出 base 的表 + 架構

curl -s "https://api.airtable.com/v0/meta/bases/$BASE_ID/tables" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.tool

在修改之前使用此命令 — 確認確切的字段名稱和 ID,顯示單選字段的 options.choices,並顯示主字段名稱。

列出記錄(前 10 條)

curl -s "https://api.airtable.com/v0/$BASE_ID/$TABLE?maxRecords=10" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.tool

獲取單條記錄

curl -s "https://api.airtable.com/v0/$BASE_ID/$TABLE/$RECORD_ID" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.tool

過濾記錄 (filterByFormula)

Airtable 公式必須進行 URL 編碼。讓 Python 標準庫處理 — 切勿手動編碼:

FORMULA="{Status}='Todo'"
ENC=$(python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$FORMULA")
curl -s "https://api.airtable.com/v0/$BASE_ID/$TABLE?filterByFormula=$ENC&maxRecords=20" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.tool

有用的公式模式:

  • 精確匹配:{Email}='user@example.com'
  • 包含:FIND('bug', LOWER({Title}))
  • 多條件:AND({Status}='Todo', {Priority}='High')
  • 或:OR({Owner}='alice', {Owner}='bob')
  • 非空:NOT({Assignee}='')
  • 日期比較:IS_AFTER({Due}, TODAY())

排序 + 選擇特定字段

curl -s "https://api.airtable.com/v0/$BASE_ID/$TABLE?sort%5B0%5D%5Bfield%5D=Priority&sort%5B0%5D%5Bdirection%5D=asc&fields%5B%5D=Name&fields%5B%5D=Status" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.tool

查詢參數中的方括號必須進行 URL 編碼(%5B / %5D)。

使用命名視圖

curl -s "https://api.airtable.com/v0/$BASE_ID/$TABLE?view=Grid%20view&maxRecords=50" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.tool

視圖在服務器端應用其保存的過濾器 + 排序。

常見變更操作

創建記錄

curl -s -X POST "https://api.airtable.com/v0/$BASE_ID/$TABLE" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"fields":{"Name":"New task","Status":"Todo","Priority":"High"}}' | python3 -m json.tool

在一次調用中創建最多 10 條記錄

curl -s -X POST "https://api.airtable.com/v0/$BASE_ID/$TABLE" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"typecast": true,
"records": [
{"fields": {"Name": "Task A", "Status": "Todo"}},
{"fields": {"Name": "Task B", "Status": "In progress"}}
]
}' | python3 -m json.tool

批量端點限制為每個請求最多 10 條記錄。對於更大的插入操作,請以 10 條為一批循環,並短暫休眠以遵守每個 base 每秒 5 個請求的限制。

更新記錄(PATCH — 合併,保留未更改的字段)

curl -s -X PATCH "https://api.airtable.com/v0/$BASE_ID/$TABLE/$RECORD_ID" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"fields":{"Status":"Done"}}' | python3 -m json.tool

通過合併字段 Upsert(無需 ID)

curl -s -X PATCH "https://api.airtable.com/v0/$BASE_ID/$TABLE" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"performUpsert": {"fieldsToMergeOn": ["Email"]},
"records": [
{"fields": {"Email": "user@example.com", "Status": "Active"}}
]
}' | python3 -m json.tool

performUpsert 創建合併字段值為新的記錄,修補合併字段值已存在的記錄。非常適合冪等同步。

刪除記錄

curl -s -X DELETE "https://api.airtable.com/v0/$BASE_ID/$TABLE/$RECORD_ID" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.tool

在一次調用中刪除最多 10 條記錄

curl -s -X DELETE "https://api.airtable.com/v0/$BASE_ID/$TABLE?records%5B%5D=rec1&records%5B%5D=rec2" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.tool

分頁

列表端點每頁最多返回 100 條記錄。如果響應包含 "offset": "...",請在下一次調用中傳回它。循環直到該字段不存在:

OFFSET=""
while :; do
URL="https://api.airtable.com/v0/$BASE_ID/$TABLE?pageSize=100"
[ -n "$OFFSET" ] && URL="$URL&offset=$OFFSET"
RESP=$(curl -s "$URL" -H "Authorization: Bearer $AIRTABLE_API_KEY")
echo "$RESP" | python3 -c 'import json,sys; d=json.load(sys.stdin); [print(r["id"], r["fields"].get("Name","")) for r in d["records"]]'
OFFSET=$(echo "$RESP" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(d.get("offset",""))')
[ -z "$OFFSET" ] && break
done

典型 Hermes 工作流

  1. 確認身份驗證。 curl -s -o /dev/null -w "%{http_code}\n" https://api.airtable.com/v0/meta/bases -H "Authorization: Bearer $AIRTABLE_API_KEY" — 預期返回 200
  2. 查找 Base。 列出 bases(上一步)或者如果令牌缺少 schema.bases:read 權限,則直接向用戶詢問 app... ID。
  3. 檢查架構。 GET /v0/meta/bases/$BASE_ID/tables — 在進行任何變更操作之前,先在本地會話中緩存確切的字段名稱和主字段名稱。
  4. 先讀後寫。 對於“更新滿足條件 Y 的 X”,首先使用 filterByFormula 解析出 rec... ID,然後執行 PATCH /v0/$BASE_ID/$TABLE/$RECORD_ID。切勿猜測記錄 ID。
  5. 批量寫入。 將相關的創建操作合併為一個包含 10 條記錄的 POST 請求,以保持在每秒 5 次請求的限制預算內。
  6. 破壞性操作。 刪除操作無法通過 API 撤銷。如果用戶說“刪除所有 X”,請回顯過濾器 + 記錄數量並在執行前確認。

常見陷阱

  • filterByFormula 必須進行 URL 編碼。 包含空格或非 ASCII 字符的字段名也需要編碼({My Field}%7BMy%20Field%7D)。使用 Python 標準庫(上述模式)— 切勿手動轉義。
  • 空字段在響應中被省略。 缺少 "Assignee" 鍵並不意味著該字段不存在 — 它意味著此記錄中的值為空。在得出字段缺失的結論之前,請檢查架構(步驟 3)。
  • PATCH 與 PUT。 PATCH 將提供的字段合併到記錄中。PUT 完全替換記錄並清除任何未包含的字段。默認使用 PATCH
  • 單選選項必須存在。Shipping 不在字段的選項列表中時,寫入 "Status": "Shipping" 會報錯 INVALID_MULTIPLE_CHOICE_OPTIONS,除非你傳遞 "typecast": true(這將自動創建該選項)。
  • 每個 Base 的令牌作用域。 如果一個 Base 返回 403 而另一個正常,這意味著令牌的訪問列表未包含該 Base — 這不是作用域或身份驗證問題。引導用戶前往 https://airtable.com/create/tokens 授予權限。
  • 速率限制是按 Base 而非按令牌計算的。 baseA 每秒 5 次請求且 baseB 每秒 5 次請求是可以的;僅 baseA 每秒 6 次請求將會被限流。監控 429 響應中的 Retry-After 頭。

Hermes 重要注意事項

  • 始終使用帶有 curlterminal 工具。 不要使用 web_extract(它無法發送身份驗證頭)或 browser_navigate(需要 UI 身份驗證且速度較慢)。
  • 加載此技能時,AIRTABLE_API_KEY 會自動從 ~/.hermes/.env 流入子進程 — 無需在每次 curl 調用前重新導出它。
  • 仔細轉義公式中的花括號。 在 heredoc 主體中,{Status} 是字面量。在 shell 參數中,{Status}{...} 花括號擴展上下文之外是安全的 — 但在拼接到 URL 之前,請通過 python3 urllib.parse.quote 傳遞動態字符串。
  • 使用 python3 -m json.tool(始終存在)進行美化打印,而不是 jq(可選)。僅在需要過濾/投影時才使用 jq
  • 分頁是按頁進行的,而非全局的。 Airtable 的 100 條記錄上限是硬性限制;無法提高它。循環使用 offset 直到該字段 absent。
  • 讀取非 2xx 響應中的 errors 數組 — Airtable 返回結構化錯誤代碼,如 AUTHENTICATION_REQUIREDINVALID_PERMISSIONSMODEL_ID_NOT_FOUNDINVALID_MULTIPLE_CHOICE_OPTIONS,這些代碼會準確告知你哪裡出錯了。