📦 Tally — 表单管理

v1.0.2

通过托管 OAuth 调用 Tally API,集中管理表单、提交、工作区与 Webhook,一键集成 Maton 网关,无需额外 OAuth 配置。

3· 3.5k·0 当前·0 累计
byungkyu 头像by @byungkyu·MIT-0
下载技能包
License
MIT-0
最后更新
2026/2/26
0
安全扫描
VirusTotal
无害
查看报告
OpenClaw
安全
high confidence
该技能内部一致:通过 Maton 代理 Tally API 调用,仅请求单个 MATON_API_KEY 环境变量,与描述的网关设计相符。
评估建议
本技能通过 Maton 代理 Tally 调用并需 MATON_API_KEY;仅在你信任 Maton(gateway.maton.ai / ctrl.maton.ai)代持 OAuth 连接时安装。将 MATON_API_KEY 视为机密,勿粘贴至不受信任处;建议查阅 Maton 隐私/安全文档,若不再使用可撤销密钥或 OAuth 连接。
详细分析 ▾
用途与能力
名称/描述(通过托管 OAuth 调用 Tally API)与运行时指令及端点(gateway.maton.ai、ctrl.maton.ai)匹配。所请求的 MATON_API_KEY 适合注入 OAuth 令牌的网关服务。
指令范围
SKILL.md 仅指示向 Maton 端点发起 HTTP 请求并使用 MATON_API_KEY 环境变量,未要求读取无关文件、系统凭据或将数据发送至意外第三方端点。
安装机制
纯指令技能,无安装规范,无代码文件写入磁盘,安装风险最低。
凭证需求
仅需要并使用 MATON_API_KEY,所请求密钥与描述的网关认证方式成比例,未请求无关机密或配置路径。
持久化与权限
always:false 且 user-invocable:true;disable-model-invocation 为 false(智能体可自主调用),属平台默认且此处无其他风险标志。
安全有层次,运行前请审查代码。

License

MIT-0

可自由使用、修改和再分发,无需署名。

运行时依赖

无特殊依赖

版本

latestv1.0.22026/2/9

- 新增元数据以指示所需环境变量(`MATON_API_KEY`)并为技能添加表情符号标记。 - 无代码变更;仅文档与元数据更新。

无害

安装命令

点击复制
官方npx clawhub@latest install tally-api
镜像加速npx clawhub@latest install tally-api --registry https://cn.longxiaskill.com

技能文档

快速开始

# 列出你的表单
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/tally/forms')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('User-Agent', 'Maton/1.0')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

基础 URL

https://gateway.maton.ai/tally/{native-api-path}

{native-api-path} 替换为实际的 Tally API 端点路径。网关会把请求代理到 api.tally.so 并自动注入你的 OAuth token。

认证

所有请求都需要在 Authorization 头中携带 Maton API key,并设置 User-Agent 头:

Authorization: Bearer $MATON_API_KEY
User-Agent: Maton/1.0

环境变量: 将 API key 设置为 MATON_API_KEY

export MATON_API_KEY="YOUR_API_KEY"

获取 API Key

连接管理

https://ctrl.maton.ai 管理你的 Tally OAuth 连接。

列出连接

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=tally&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

创建连接

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'tally'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

获取连接

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

响应:

{
  "connection": {
    "connection_id": "cd54e2b0-f1d0-435e-a97d-f2d6a5c474bf",
    "status": "ACTIVE",
    "creation_time": "2026-02-07T21:00:31.222600Z",
    "last_updated_time": "2026-02-07T21:00:37.821240Z",
    "url": "https://connect.maton.ai/?session_token=...",
    "app": "tally",
    "metadata": {}
  }
}

在浏览器中打开返回的 url 完成 OAuth 授权。

删除连接

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

指定连接

如果你有多个 Tally 连接,用 Maton-Connection 头指定使用哪一个:

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/tally/forms')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', 'cd54e2b0-f1d0-435e-a97d-f2d6a5c474bf')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

如果省略,网关将使用默认(最早创建的)活跃连接。

API 参考

用户

获取当前用户

GET /tally/users/me

响应:

{
  "id": "w2lBkb",
  "firstName": "John",
  "lastName": "Doe",
  "email": "john@example.com",
  "organizationId": "n0Ze8Q",
  "subscriptionPlan": "FREE",
  "createdAt": "2026-02-07T20:58:54.000Z",
  "updatedAt": "2026-02-07T22:50:35.000Z"
}

表单

列出表单

GET /tally/forms

查询参数:

  • page - 页码(默认:1)
  • limit - 每页条数(默认:50)

响应:

{
  "items": [
    {
      "id": "GxdRaQ",
      "name": "Contact Form",
      "workspaceId": "3jW9Q1",
      "organizationId": "n0Ze8Q",
      "status": "PUBLISHED",
      "hasDraftBlocks": false,
      "numberOfSubmissions": 42,
      "createdAt": "2026-02-09T08:36:00.000Z",
      "updatedAt": "2026-02-09T08:36:17.000Z",
      "isClosed": false
    }
  ],
  "page": 1,
  "limit": 50,
  "total": 1,
  "hasMore": false
}

获取表单

GET /tally/forms/{formId}

响应:

{
  "id": "GxdRaQ",
  "name": "Contact Form",
  "workspaceId": "3jW9Q1",
  "status": "PUBLISHED",
  "blocks": [
    {
      "uuid": "11111111-1111-1111-1111-111111111111",
      "type": "FORM_TITLE",
      "groupUuid": "22222222-2222-2222-2222-222222222222",
      "groupType": "FORM_TITLE",
      "payload": {}
    },
    {
      "uuid": "33333333-3333-3333-3333-333333333333",
      "type": "INPUT_TEXT",
      "groupUuid": "44444444-4444-4444-4444-444444444444",
      "groupType": "INPUT_TEXT",
      "payload": {}
    }
  ],
  "settings": null
}

创建表单

POST /tally/forms
Content-Type: application/json
{
  "status": "DRAFT",
  "workspaceId": "3jW9Q1",
  "blocks": [
    {
      "type": "FORM_TITLE",
      "uuid": "11111111-1111-1111-1111-111111111111",
      "groupUuid": "22222222-2222-2222-2222-222222222222",
      "groupType": "FORM_TITLE",
      "title": "My Form",
      "payload": {}
    },
    {
      "type": "INPUT_TEXT",
      "uuid": "33333333-3333-3333-3333-333333333333",
      "groupUuid": "44444444-4444-4444-4444-444444444444",
      "groupType": "INPUT_TEXT",
      "title": "Your name",
      "payload": {}
    }
  ]
}

Block Types:

  • FORM_TITLE - 表单标题块
  • INPUT_TEXT - 单行文本输入
  • INPUT_EMAIL - 邮箱输入
  • INPUT_NUMBER - 数字输入
  • INPUT_PHONE_NUMBER - 手机号输入
  • INPUT_DATE - 日期选择器
  • INPUT_TIME - 时间选择器
  • INPUT_LINK - 链接输入
  • TEXTAREA - 多行文本输入
  • MULTIPLE_CHOICE - 单选按钮
  • CHECKBOXES - 多选框组
  • DROPDOWN - 下拉选择
  • LINEAR_SCALE - 线性评分
  • RATING - 星级评分
  • FILE_UPLOAD - 文件上传
  • SIGNATURE - 签名字段
  • PAYMENT - 支付字段
  • HIDDEN_FIELDS - 隐藏字段

注意: Block 的 uuidgroupUuid 必须是有效的 UUID(GUID)。

更新表单

PATCH /tally/forms/{formId}
Content-Type: application/json
{
  "name": "Updated Form Name",
  "status": "PUBLISHED"
}

状态值:

  • DRAFT - 草稿
  • PUBLISHED - 已发布

删除表单

DELETE /tally/forms/{formId}

将表单移至回收站。

表单问题

列出问题

GET /tally/forms/{formId}/questions

响应:

{
  "questions": [
    {
      "uuid": "33333333-3333-3333-3333-333333333333",
      "type": "INPUT_TEXT",
      "title": "Your name"
    }
  ],
  "hasResponses": true
}

表单提交

列出提交记录

GET /tally/forms/{formId}/submissions

查询参数:

  • page - 页码(默认:1)
  • limit - 每页条数(默认:50)
  • startDate - 起始日期过滤(ISO 8601)
  • endDate - 结束日期过滤(ISO 8601)
  • afterId - 游标分页,获取此 ID 之后的提交

响应:

{
  "page": 1,
  "limit": 50,
  "hasMore": false,
  "totalNumberOfSubmissionsPerFilter": {
    "all": 42,
    "completed": 40,
    "partial": 2
  },
  "questions": [
    {
      "uuid": "33333333-3333-3333-3333-333333333333",
      "type": "INPUT_TEXT",
      "title": "Your name"
    }
  ],
  "submissions": [
    {
      "id": "sub123",
      "respondentId": "resp456",
      "formId": "GxdRaQ",
      "createdAt": "2026-02-09T10:00:00.000Z",
      "isCompleted": true,
      "responses": [
        {
          "questionId": "33333333-3333-3333-3333-333333333333",
          "value": "John Doe"
        }
      ]
    }
  ]
}

获取提交

GET /tally/forms/{formId}/submissions/{submissionId}

删除提交

DELETE /tally/forms/{formId}/submissions/{submissionId}

工作区

列出工作区

GET /tally/workspaces

响应:

{
  "items": [
    {
      "id": "3jW9Q1",
      "name": "My Workspace",
      "createdByUserId": "w2lBkb",
      "createdAt": "2026-02-09T08:35:53.000Z",
      "updatedAt": "2026-02-09T08:35:53.000Z"
    }
  ],
  "page": 1,
  "limit": 50,
  "total": 1,
  "hasMore": false
}

获取工作区

GET /tally/workspaces/{workspaceId}

响应:

{
  "id": "3jW9Q1",
  "name": "My Workspace",
  "createdByUserId": "w2lBkb",
  "createdAt": "2026-02-09T08:35:53.000Z",
  "members": [
    {
      "id": "w2lBkb",
      "firstName": "John",
      "lastName": "Doe",
      "email": "john@example.com"
    }
  ]
}

创建工作区

POST /tally/workspaces
Content-Type: application/json
{
  "name": "New Workspace"
}

注意: 创建工作区需要 Pro 订阅。

更新工作区

PATCH /tally/workspaces/{workspaceId}
Content-Type: application/json
{
  "name": "Updated Workspace Name"
}

删除工作区

DELETE /tally/workspaces/{workspaceId}

将工作区及其所有表单移至回收站。

组织用户

列出用户

GET /tally/organizations/{organizationId}/users

响应:

[
  {
    "id": "w2lBkb",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john@example.com",
    "createdAt": "2026-02-07T20:58:54.000Z"
  }
]

移除用户

DELETE /tally/organizations/{organizationId}/users/{userId}

组织邀请

列出邀请

GET /tally/organizations/{organizationId}/invites

创建邀请

POST /tally/organizations/{organizationId}/invites
Content-Type: application/json
{
  "email": "newuser@example.com",
  "workspaceIds": ["3jW9Q1"]
}

取消邀请

DELETE /tally/organizations/{organizationId}/invites/{inviteId}

Webhooks

列出 Webhooks

GET /tally/webhooks

注意: 列出 webhooks 可能需要特定权限。

创建 Webhook

POST /tally/webhooks
Content-Type: application/json
{
  "formId": "GxdRaQ",
  "url": "https://your-endpoint.com/webhook",
  "eventTypes": ["FORM_RESPONSE"]
}

Webhook 事件类型:

  • FORM_RESPONSE - 新表单提交时触发

更新 Webhook

PATCH /tally/webhooks/{webhookId}
Content-Type: application/json
{
  "url": "https://new-endpoint.com/webhook"
}

删除 Webhook

DELETE /tally/webhooks/{webhookId}

列出 Webhook 事件

GET /tally/webhooks/{webhookId}/events

重试 Webhook 事件

POST /tally/webhooks/{webhookId}/events/{eventId}

分页

Tally 使用基于页码的分页:

GET /tally/forms?page=1&limit=50

响应包含分页信息:

{
  "items": [...],
  "page": 1,
  "limit": 50,
  "total": 100,
  "hasMore": true
}

对于提交记录,也可以使用基于游标的分页,通过 afterId 参数。

代码示例

JavaScript

const response = await fetch(
  'https://gateway.maton.ai/tally/forms',
  {
    headers: {
      'Authorization': Bearer ${process.env.MATON_API_KEY},
      'User-Agent': 'Maton/1.0'
    }
  }
);
const data = await response.json();
console.log(data.items);

Python

import os
import requests

response = requests.get( 'https://gateway.maton.ai/tally/forms', headers={ 'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}', 'User-Agent': 'Maton/1.0' } ) data = response.json() print(data['items'])

创建表单并获取提交记录

import os
import requests
import uuid

headers = { 'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}', 'User-Agent': 'Maton/1.0' }

# 创建一个简单表单 form_data = { 'status': 'DRAFT', 'blocks': [ { 'type': 'FORM_TITLE', 'uuid': str(uuid.uuid4()), 'groupUuid': str(uuid.uuid4()), 'groupType': 'FORM_TITLE', 'title': 'Contact Form', 'payload': {} }, { 'type': 'INPUT_EMAIL', 'uuid': str(uuid.uuid4()), 'groupUuid': str(uuid.uuid4()), 'groupType': 'INPUT_EMAIL', 'title': 'Your email', 'payload': {} } ] }

response = requests.post( 'https://gateway.maton.ai/tally/forms', headers=headers, json=form_data ) form = response.json() print(f"Created form: {form['id']}")

# 获取表单提交记录 response = requests.get( f'https://gateway.maton.ai/tally/forms/{form["id"]}/submissions', headers=headers ) submissions = response.json() print(f"Total submissions: {submissions['totalNumberOfSubmissionsPerFilter']['all']}")

注意事项

  • 表单和工作区 ID 为短字母数字串(如 GxdRaQ
  • Block 的 uuidgroupUuid 字段必须是有效的 UUID(GUID)
  • 创建工作区需要 Pro 订阅
  • API 处于公开 beta 阶段,可能会变动
  • 速率限制:每分钟 100 次请求
  • 如需实时通知,请使用 webhook 而非轮询
  • 重要:在部分 shell 环境中,将 curl 输出通过管道传给 jq 等命令时,环境变量如 $MATON_API_KEY 可能无法正确展开

错误处理

状态码含义
400Tally 连接缺失或校验错误
401Maton API key 无效或缺失
403权限不足
404资源未找到
429触发速率限制(100 req/min)
4xx/5xxTally API 透传错误

故障排查:API Key 问题

  • 检查是否已设置 MATON_API_KEY 环境变量:
echo $MATON_API_KEY
  • 通过列出连接验证 API key 是否有效:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

故障排查:无效应用名

  • 确保 URL 路径以 tally 开头。例如:
- 正确:https://gateway.maton.ai/tally/forms - 错误:https://gateway.maton.ai/forms

资源

数据来源ClawHub ↗ · 中文优化:龙虾技能库