{/* Trang này được tạo tự động từ SKILL.md của kỹ năng bởi website/scripts/generate-skill-docs.py. Chỉnh sửa nguồn SKILL.md, không phải trang này. */}
Máy bay
API REST có thể điều chỉnh được thông qua cuộn tròn. Ghi lại CRUD, bộ lọc, nâng cấp.
Siêu dữ liệu kỹ năng
| Nguồn | Đi kèm (được cài đặt theo mặc định) |
| Đường dẫn |
skills/productivity/airtable ` | | Phiên bản |
1.1.0 ` | | Tác giả | cộng đồng | | Giấy phép | MIT | | Nền tảng | Linux, macOS, Windows | | Thẻ |
Airtable
, `Productivity
, `Database
,
API |
Tham khảo: đầy đủ SKILL.md
Sau đây là định nghĩa kỹ năng đầy đủ mà Hermes tải khi kỹ năng này được kích hoạt. Đây là những gì tác nhân coi là hướng dẫn khi kỹ năng được kích hoạt.
Airtable — Căn cứ, Bàn & Bản ghi
Làm việc trực tiếp với API REST của Airtable thông qua
curl bằng công cụ
`terminal
. Không có máy chủ MCP, không có luồng OAuth, không có SDK Python - chỉ
curl và mã thông báo truy cập cá nhân.
Điều kiện tiên quyết
- Tạo Mã thông báo truy cập cá nhân (PAT) tại https://airtable.com/create/tokens (mã thông báo bắt đầu bằng `pat...
). 2. Cấp các phạm vi này (tối thiểu):
`data.records:read
-
đọc hàng
`data.records:write
-
tạo / cập nhật / xóa hàng
`schema.bases:read
- liệt kê các cơ sở và bảng
- Quan trọng: trong cùng một giao diện người dùng mã thông báo, hãy thêm từng cơ sở bạn muốn truy cập vào danh sách Truy cập của mã thông báo. PAT được xác định phạm vi trên mỗi cơ sở - mã thông báo hợp lệ trên cơ sở sai sẽ trả về `403
. 4. Lưu trữ mã thông báo trong
~/.Hermes/.env
(hoặc qua Hermes setup
):
` AIRTABLE_API_KEY=pat_your_token_here
``> Lưu ý: Khóa API
key... cũ không còn được dùng nữa từ tháng 2 năm 2024. Hiện tại, chỉ PAT và mã thông báo OAuth mới hoạt động.
API cơ bản
-
Điểm cuối: `https://API.airtable.com/v0
-
Tiêu đề xác thực: `Authorization: Bearer $AIRTABLE_API_KEY
-
Tất cả các yêu cầu sử dụng JSON (
Content-Type: application/JSONcho mọi nội dung POST/PATCH/PUT). -
ID đối tượng: cơ sở `app...
, bảng `tbl...
, bản ghi `rec...
, trường `fld...
. ID không bao giờ thay đổi; tên có thể. Ưu tiên ID trong tự động hóa.
- Giới hạn tốc độ: 5 yêu cầu/giây/cơ sở.
429→ lùi lại. Burst trên một cơ sở duy nhất sẽ được điều tiết.
Kiểu uốn cong cơ bản:
`
curl -s "https://API.airtable.com/v0/$BASE_ID/$TABLE?maxRecords=5" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | Python3 -m JSON.tool
`
-s
` ngăn chặn thanh tiến trình của cuộn tròn — hãy đặt thanh này cho mọi lệnh gọi để đầu ra của công cụ luôn sạch sẽ cho Hermes. Chuyển qua
`Python3 -m JSON.tool
` (luôn hiện diện) hoặc
`jq
` (nếu được cài đặt) để có JSON có thể đọc được.
## Loại trường (yêu cầu hình dạng nội dung)
| Loại trường | Viết hình |
|---|---|
| Văn bản một dòng |
"Name": "hello"
` |
| Văn bản dài |
"Notes": "multi\nline"
` |
| Số |
"Score": 42
` |
| Hộp kiểm |
"Done": true
` |
| Chọn đơn |
"Status": "Todo"
` (tên phải tồn tại trừ khi
`typecast: true
) |
| Chọn nhiều |
"Tags": ["urgent", "bug"]
` |
| Ngày |
"Due": "2026-04-01"
` |
| Ngày Giờ (UTC) |
"At": "2026-04-01T14:30:00.000Z"
` |
| URL / Email / Điện thoại |
"Link": "https://…"
` |
| Tệp đính kèm |
"Files": [\{"url": "https://…"}]
` (Tìm nạp Airtable + lưu trữ lại) |
| Bản ghi được liên kết |
"Owner": ["recXXXXXXXXXXXXXX"]
` (mảng ID bản ghi) |
| Người dùng |
"AssignedTo": \{"id": "usrXXXXXXXXXXXXXX"}
` |
Chuyển
"typecast": true
` ở cấp cao nhất của nội dung tạo/cập nhật để cho phép Airtable tự động ép buộc các giá trị (ví dụ: tạo nhanh tùy chọn chọn mới, chuyển đổi
"42"
` →
`42
).
## Truy vấn phổ biến
### Liệt kê các cơ sở mà token có thể nhìn thấy
`
``` bash
curl -s "https://API.airtable.com/v0/meta/bases" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | Python3 -m JSON.tool
`
### Liệt kê các bảng + lược đồ cho cơ sở
`
``` bash
curl -s "https://API.airtable.com/v0/meta/bases/$BASE_ID/tables" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | Python3 -m JSON.tool
`
Sử dụng điều này TRƯỚC KHI thay đổi - xác nhận tên và ID trường chính xác, hiển thị
`options.choices
` cho các trường được chọn và hiển thị tên trường chính.
### Liệt kê các bản ghi (10 bản ghi đầu tiên)
`
``` bash
curl -s "https://API.airtable.com/v0/$BASE_ID/$TABLE?maxRecords=10" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | Python3 -m JSON.tool
`
### Nhận một bản ghi duy nhất
`
``` bash
curl -s "https://API.airtable.com/v0/$BASE_ID/$TABLE/$RECORD_ID" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | Python3 -m JSON.tool
`
### Lọc bản ghi (filterByFormula)
Công thức airtable phải được mã hóa URL. Hãy để Python stdlib làm điều đó - không bao giờ mã hóa bằng tay:
`
``` bash
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
`
``Các mẫu công thức hữu ích:
- Trùng khớp chính xác:
\{Email}='user@example.com'
- Chứa:
`FIND('bug', LOWER(\{Title}))
- Nhiều điều kiện:
`AND(\{Status}='Todo', \{Priority}='High')
- Hoặc:
`OR(\{Owner}='alice', \{Owner}='bob')
- Không trống:
`NOT(\{Assignee}='')
- Ngày so sánh:
`IS_AFTER(\{Due}, TODAY())
### Sắp xếp + chọn các trường cụ thể
`
``` bash
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
`
Dấu ngoặc vuông trong tham số truy vấn PHẢI được mã hóa URL (
%5B
` /
%5D
).
### Sử dụng chế độ xem được đặt tên
`
``` bash
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
`
Chế độ xem áp dụng bộ lọc đã lưu + sắp xếp phía máy chủ.
## Đột biến phổ biến
### Tạo bản ghi
`
``` bash
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
`
### Tạo tối đa 10 bản ghi trong một cuộc gọi
`
``` bash
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
`
Điểm cuối của lô được giới hạn ở mức **10 bản ghi cho mỗi yêu cầu**. Đối với các phần chèn lớn hơn, hãy lặp theo lô 10 phần với thời gian ngủ ngắn để tôn trọng 5 req/giây/cơ sở.
### Cập nhật bản ghi (PATCH - hợp nhất, giữ nguyên các trường không thay đổi)
`
``` bash
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 bằng trường hợp nhất (không cần ID)
`
``` bash
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
` tạo các bản ghi có giá trị trường hợp nhất là mới, vá các bản ghi có giá trị trường hợp nhất đã tồn tại. Tuyệt vời cho đồng bộ bình thường.
### Xóa bản ghi
`
``` bash
curl -s -X DELETE "https://API.airtable.com/v0/$BASE_ID/$TABLE/$RECORD_ID" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | Python3 -m JSON.tool
`
### Xóa tối đa 10 bản ghi trong một cuộc gọi
`
``` bash
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
`
## Phân trang
Điểm cuối của danh sách trả về tối đa **100 bản ghi trên mỗi trang**. Nếu phản hồi bao gồm
"offset": "..."
, hãy chuyển lại phản hồi đó trong cuộc gọi tiếp theo. Lặp lại cho đến khi trường vắng mặt:
``` bash
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
`
## Quy trình làm việc điển hình của Hermes
1. **Xác nhận xác thực.**
`curl -s -o /dev/null -w "%\{http_code}\n" https://API.airtable.com/v0/meta/bases -H "Authorization: Bearer $AIRTABLE_API_KEY"
` — mong đợi
`200
.
2. **Tìm cơ sở.** Liệt kê cơ sở (bước ở trên) HOẶC yêu cầu người dùng cung cấp ID
`app...
` trực tiếp nếu mã thông báo thiếu
`schema.bases:read
.
3. **Kiểm tra lược đồ.**
`GET /v0/meta/bases/$BASE_ID/tables
` — lưu trữ tên trường chính xác và tên trường chính cục bộ trong phiên trước khi thay đổi bất kỳ thứ gì.
4. **Đọc trước khi viết.** Đối với "cập nhật X ở đâu Y",
`filterByFormula
` trước tiên phải phân giải ID
`rec...
, sau đó là
`PATCH /v0/$BASE_ID/$TABLE/$RECORD_ID
. Không bao giờ đoán ID hồ sơ.
5. **Ghi hàng loạt.** Kết hợp các tác vụ tạo có liên quan thành một POST gồm 10 bản ghi để duy trì ngân sách dưới 5 yêu cầu/giây.
6. **Các hoạt động mang tính hủy diệt.** Không thể hoàn tác việc xóa thông qua API. Nếu người dùng nói "xóa tất cả X", hãy lặp lại bộ lọc + số lượng bản ghi và xác nhận trước khi kích hoạt.
## cạm bẫy
- **
`filterByFormula
` PHẢI được mã hóa URL.** Tên trường có dấu cách hoặc không phải ASCII cũng cần mã hóa (
\{My Field}
` →
%7BMy%20Field%7D
). Sử dụng Python stdlib (mẫu ở trên) - không bao giờ thoát tay.
- **Các trường trống bị bỏ qua trong các phản hồi.** Khóa
"Assignee"
` bị thiếu không có nghĩa là trường đó không tồn tại — mà có nghĩa là giá trị của bản ghi này trống. Kiểm tra lược đồ (bước 3) trước khi kết luận trường bị thiếu.
- **PATCH vs PUT.**
`PATCH
` hợp nhất các trường được cung cấp vào bản ghi.
`PUT
` thay thế hoàn toàn bản ghi và xóa bất kỳ trường nào bạn không đưa vào. Mặc định là
`PATCH
.
- **Các tùy chọn chọn một lần phải tồn tại.** Viết
"Status": "Shipping"
` khi
`Shipping
` không có trong danh sách tùy chọn của trường lỗi với
`INVALID_MULTIPLE_CHOICE_OPTIONS
` trừ khi bạn vượt qua
"typecast": true
` (tự động tạo tùy chọn).
- **Phạm vi mã thông báo trên mỗi cơ sở.**
`403
` trên một cơ sở trong khi cơ sở khác hoạt động có nghĩa là danh sách Truy cập của mã thông báo không bao gồm cơ sở đó — không phải là vấn đề về phạm vi hoặc xác thực. Gửi người dùng tới https://airtable.com/create/tokens để cấp nó.
- **Giới hạn tốc độ trên mỗi cơ sở, không phải trên mỗi mã thông báo.** 5 req/giây trên
`baseA
` và 5 req/giây trên
`baseB
` là ổn; Chỉ riêng 6 req/giây trên
`baseA
` sẽ tăng tốc. Giám sát tiêu đề
`Retry-After
` trên
`429
.
## Những lưu ý quan trọng dành cho Hermes
- **Luôn sử dụng công cụ
`terminal
` với
`curl
.** KHÔNG sử dụng
`web_extract
` (nó không thể gửi tiêu đề xác thực) hoặc
`browser_navigate
` (cần xác thực giao diện người dùng và tốc độ chậm).
- **
`AIRTABLE_API_KEY
` tự động chuyển từ
~/.Hermes/.env
` vào quy trình con** khi kỹ năng này được tải - không cần xuất lại trước mỗi lệnh gọi
`curl
.
- ** Cẩn thận thoát khỏi dấu ngoặc nhọn trong công thức. ** Trong phần nội dung heredoc,
\{Status}
` có nghĩa đen. Trong đối số shell,
\{Status}
` an toàn bên ngoài ngữ cảnh mở rộng dấu ngoặc
\{...}
` — nhưng chuyển các chuỗi động thông qua
`Python3 urllib.parse.quote
` trước khi ghép vào một URL.
- **In đẹp với
`Python3 -m JSON.tool
** (luôn hiện diện) thay vì
`jq
` (tùy chọn). Chỉ sử dụng
`jq
` khi bạn cần lọc/chiếu.
- **Phân trang trên mỗi trang, không phải toàn cầu.** Giới hạn 100 bản ghi của Airtable là giới hạn cứng; không có cách nào để va chạm nó. Lặp lại với
`offset
` cho đến khi không còn trường này.
- **Đọc mảng
`errors
** trên các phản hồi không phải 2xx — Airtable trả về các mã lỗi có cấu trúc như
`AUTHENTICATION_REQUIRED
,
`INVALID_PERMISSIONS
,
`MODEL_ID_NOT_FOUND
,
`INVALID_MULTIPLE_CHOICE_OPTIONS
` để cho bạn biết chính xác điều gì sai.