SuperAPI AI Directory

dingtalk-tb-ai-skill

General & other

View repository

Updated 10-16 08:44

About this skill

Applicable Scenarios

✅ Suitable for using this skill:

  • Query my to-do tasks, tasks due today/this week, overdue tasks
  • Create, update, archive tasks
  • Update task status, priority, assignee, notes
  • Manage task progress, comments (supports @mentions), activities
  • Upload files to tasks
  • Query project list, project details
  • Query enterprise members
  • Manage sprints (create/start/complete)

❌ Not applicable scenarios:

  • Operate non-Teambition platforms (Jira, Asana, etc.)
  • Git operations or code management → directly use git
  • Manage Teambition organization/administrator settings not covered by the scripts

Environment Preparation

Get User Token:Teambition Open Platform

# 方式 1:环境变量
export TB_USER_TOKEN="your_token"

# 方式 2:在 dingtalk-tb-ai-skill/ 目录下创建 user-token.json
# {"userToken": "your_token"}

cd dingtalk-tb-ai-skill && uv sync

Core Rules

  1. me(): To query "my" tasks/projects in TQL, you must use executorId = me(), hardcoding user IDs is prohibited

  2. Time Zone:create_task.py / update_task.py / manage_sprint.py has built-in UTC+8→UTC conversion, just pass local time directly; do not manually pass UTC time (it will be converted again causing deviation). Conversion logic reference:

    from datetime import datetime, timedelta
    user_date = "2026-03-15"
    dt = datetime.strptime(user_date, "%Y-%m-%d") - timedelta(hours=8)
    iso_date = dt.strftime("%Y-%m-%dT%H:%M:%S.000Z")
    # 结果:2026-03-14T16:00:00.000Z
    
  3. ID→Name: Various ID fields returned by the API are raw ID strings,they must be converted to readable names before displaying to users, directly displaying raw IDs is prohibited。

    • Common ID fields that need conversion:
      Field Meaning Conversion Method
      executorId Assignee query_members.py --user-ids <ID> batch query
      creatorId Creator query_members.py --user-ids <ID> batch query
      involveMembers Participant list query_members.py --user-ids <ID1,ID2,...> batch query
      sprintId Sprint query_project_detail.py <projectId> get sprint list then match
      stageId Task column Task details usually include stageName, otherwise need to query project workflow
      projectId Project Project name is usually already in context, or use query_project_detail.py to query
      parentTaskId Parent task query_task_detail.py <parentTaskId> get parent task title
    • Necessary steps when displaying task list/details:
      1. Collect all kinds of IDs appearing in all tasks (deduplicate)
      2. Batch query the corresponding names (use query_members.pyfor people, use respective query scripts for projects/sprints/tasks)
      3. Replace IDs with names before displaying to users
    • If the name corresponding to an ID cannot be determined, it can be displayed as "Unknown" or the field can be kept hidden, do not directly display the raw ID
    # 按姓名搜索成员,获取 userId
    uv run scripts/query_members.py --keyword "张三"
    # 返回结果中匹配 userId,确认后用于展示或操作
    
    # 批量按用户ID查询成员(推荐用于ID转换)
    uv run scripts/query_members.py --user-ids "id1,id2,id3"
    
  4. Priority: numeric meanings are 0=紧急 1=高 2=中 3=低, butenterprises usually customize priority names, the script output priorityLabel is only the system default value, and does not represent the enterprise's actual configuration.

    • Before displaying priority names, you must first query the enterprise configuration, query chain:
      1. Get from task details projectId
      2. uv run scripts/query_project_detail.py <projectId> --extra-fields organizationId get organizationId
      3. uv run scripts/get_priority_list.py <organizationId> get the enterprise's actual priority list
    • Each priority in the returned result contains priority(numeric value) and name(enterprise-defined name), which override the default label before display
    • Before updating a priority, you also need to query first, match the priority name described by the user with the enterprise configuration, then use the corresponding priority numeric value to call the update interface
  5. Archive vs Delete: Archiving a task moves it to the recycle bin and it no longer appears in the normal list; it can be restored via --restore restore; archiving is not the same as deletion

  6. Activity vs Progress: Activity is the operation history automatically recorded by the system (status changes, field modifications, etc.); progress (trace) is the stage-based status update manually filled in by the user

  7. Iteration operation order: First use --action create --project-id <id> --name <名> to create an iteration and obtain the sprint-id, then use --action start --project-id <id> --sprint-id <id> to start it, and after completion use --action complete --project-id <id> --sprint-id <id>; both start/complete require passing both --project-id and --sprint-id

  8. Status query priority: When updating a task status, prioritize using get_task_statuses.py <taskId> to directly query the workflow status list of that task, without needing to first obtain the projectId; only use it when creating a task and an initial status is needed get_taskflow_statuses.py

  9. Read documentation on demand: TQL syntax → references/tql.md; progress/comments/activity/archive → references/task-ops.md; error handling → references/error-handling.md

  10. File upload process: First use upload_file.py to upload the file and obtain fileToken, then use create_comment.py --file-tokens <token> to attach the file to the comment; both steps go through scripts, no need to call the API directly

  11. ID link rendering: When a reply involves a task ID or project ID, it must be rendered as a clickable link in the following format:

    • Task link:https://www.teambition.com/task/{taskId}
    • Project link:https://www.teambition.com/project/{projectId}
  12. Task content = title: The content field returned by the API is the task'stitle, and when displaying it to the user, uniformly use "title" rather than "content" to avoid confusion;create_task.py use --title,update_task.py use --content, the two have the same semantics

  13. Hide empty fields: When displaying task or project information,fields whose values are empty, null, 0, false, or an empty array should be hidden and not shown to the user, and only fields with actual values should be displayed. For example:

    • Progress is 0 → do not display progress
    • Due date is null → do not display due date
    • Notes is an empty string → do not display notes
    • Iteration is null → do not display iteration
    • Tags is an empty array → do not display tags
    • This rule applies to all optional fields, keeping information display concise
  14. Custom field update format: When using --customfields to update task custom fields, different types have different formats:

    # 日期类型(date):value 是数组,包含带 title 的对象,日期格式为 ISO 8601
    uv run scripts/update_task.py --task-id 'xxx' \
      --customfields '[{"customfieldId": "字段ID", "value": [{"title": "2026-03-16T00:00:00.000Z"}]}]'
    
    # 文本类型(text):value 是数组,包含带 title 的对象
    uv run scripts/update_task.py --task-id 'xxx' \
      --customfields '[{"customfieldId": "字段ID", "value": [{"title": "文本内容"}]}]'
    
    # 单选类型(select):value 是数组,包含带 id 的选项对象
    uv run scripts/update_task.py --task-id 'xxx' \
      --customfields '[{"customfieldId": "字段ID", "value": [{"id": "选项ID"}]}]'
    

    Note: When querying, the field ID is cfId, and when updating, the field ID is customfieldId(different!)

  15. Custom field file type display: In custom fields, the type is workfields of (file attachment); when displaying, the file name must be rendered as a clickable download link, using the value of the field in downloadUrl field as the link address, in the following format:

    • Display format:[文件名](downloadUrl)
    • Example:[面圣材料.md](https://tb-oss-test.oss-cn-shanghai.aliyuncs.com/...)
    • If a field contains multiple files, render each file as a separate link
    • It is forbidden to display only the file name without an accompanying link

Script quick reference

Script Purpose Key parameters
query_tasks.py Query task list (TQL); by default returns: title, status, priority, assignee ID, due date, notes, sprint, task column, start time, progress, parent task ID --tql <TQL> --page-size N --page-token T --no-details --extra-fields f1,f2
query_task_detail.py <id1,id2> Query task details (batch supported) --detail-level simple|detailed --extra-fields f1,f2
create_task.py Create task --title <标题>(required)--project-id --executor-id --due-date --priority
update_task.py Update task (multiple fields in parallel) --task-id <id>(required)--content --executor-id --due-date --note --priority --taskflowstatus-id
update_task_priority.py Update priority separately (before updating, first use get_priority_list.py to query enterprise configuration) --task-id <id> --priority <0-3>
create_comment.py Create comment --task-id <id> --content <内容> --mention <姓名> --mention-id <userId> --file-tokens <token>
query_projects.py Query project list (TQL) --tql <TQL> --page-size N --page-token T --no-details --include-template
query_project_detail.py <id> Query project details (batch supported) --detail-level simple|detailed --extra-fields f1,f2
query_members.py Search members (batch ID query supported) --keyword <姓名> --user-ids <ID1,ID2,...>
get_task_statuses.py <taskId> Query task workflow status list (recommended) --q <关键词>
get_taskflow_statuses.py <projectId> Get project workflow status (used when creating tasks) --only-start --q <关键词>
get_custom_fields.py <projectId> Get project custom field configuration --cf-ids <IDs> --sfc-id <ID>
get_scenario_types.py <projectId> Get project task type list --q <关键词> --sfc-ids <IDs>
get_priority_list.py <organizationId> Get enterprise priority configuration —
get_current_user.py Get current logged-in user information (userId, name, email, etc.) —
create_trace.py Add task progress --task-id <id> --title <标题> --status <1-3>
upload_file.py Upload file, returns fileToken --file-path <路径> --scope task:<id> --category attachment
archive_task.py Archive/restore task --task-id <id> [--restore]
query_task_activity.py Query task activity --task-id <id> --actions comment
manage_sprint.py Sprint management --action list|create|start|complete --project-id <id> --sprint-id <id> --name <名>

query_task_detail.py parameter description

Parameter Type Required Description
任务ID String Yes Task ID; comma-separated for batch
--detail-level String No simple(default) or detailed
--extra-fields String No Additional fields included in simple mode, comma-separated

simple (default) includes fields:

Field Description
id Task ID
content Task title
isDone Whether completed
executorId Assignee ID
projectId Project ID
dueDate Due date
priority Priority (0=urgent, 1=high, 2=medium, 3=low)
created Creation time
updated Update time
note Notes

detailed additionally includes:sprintId(sprint ID)stageId(task column ID)startDate(start time)progress(progress)parentTaskId(parent task ID) and custom fields, etc., 30+ fields

query_project_detail.py parameter description

Parameter Type Required Description
项目ID String Yes Project ID; comma-separated for batch
--detail-level String No simple(default) or detailed
--extra-fields String No Additional fields included in simple mode, comma-separated

simple (default) Included fields:

Field Description
id Project ID
name Project name
description Project description
visibility Visibility (public/private)
isTemplate Whether it is a template project
creatorId Creator ID
isArchived Whether it is in the recycle bin
isSuspended Whether it is archived
created Creation time
updated Update time

detailed Additionally includes:logo(project LOGO)organizationId(enterprise ID)uniqueIdPrefix(task ID prefix)startDate(start time)endDate(end time), etc. 20+ fields


TQL Quick Reference

Common Task TQL Scenarios

Scenario TQL
My to-do tasks executorId = me() AND isDone = false
My overdue tasks executorId = me() AND isDone = false AND dueDate < startOf(d)
Tasks due today executorId = me() AND dueDate >= startOf(d) AND dueDate <= endOf(d)
Tasks due this week executorId = me() AND dueDate >= startOf(w) AND dueDate <= endOf(w)
Due soon (next 3 days) executorId = me() AND isDone = false AND dueDate >= startOf(d) AND dueDate <= endOf(d, 3d)
Tasks updated in the past 7 days executorId = me() AND updated >= startOf(d, -7d)
High priority incomplete priority = 0 AND isDone = false
Title fuzzy search title ~ '关键词'
Full-text search (title + notes) text ~ '关键词'
Tasks in a specified project projectId = 'xxx'

Full TQL syntax (fields, operators, time functions) → references/tql.md

Common Project TQL Scenarios

Scenario TQL
Projects I participate in involveMembers = me()
Projects I created creatorId = me()
Search by name nameText ~ '关键词'
Archived projects isSuspended = true
Projects updated today updated >= startOf(d) AND updated <= endOf(d)
Projects created today created >= startOf(d) AND created <= endOf(d)
Projects created this week created >= startOf(w) AND created <= endOf(w)
Projects created this month created >= startOf(M) AND created <= endOf(M)
Projects created in the past 7 days created >= startOf(d, -7d)
Created within a specified date range created >= '2026-03-01T00:00:00.000Z' AND created <= '2026-03-31T23:59:59.999Z'

⚠️ Projects do not have a due date (dueDate) field, only created and updated。

Full project TQL → references/project-tql.md


Common Command Examples

Query tasks

# 我的待办任务
uv run scripts/query_tasks.py --tql "executorId = me() AND isDone = false"
# 注意:返回的 executorId 是原始 ID,需批量调用 query_members.py --user-ids 转换为姓名后展示

# 我的逾期任务,按截止时间升序
uv run scripts/query_tasks.py --tql "executorId = me() AND isDone = false AND dueDate < startOf(d) ORDER BY dueDate ASC"
# 返回的 executorId 需批量转换为姓名:uv run scripts/query_members.py --user-ids "<id1,id2,...>"

# 本周截止的任务
uv run scripts/query_tasks.py --tql "executorId = me() AND dueDate >= startOf(w) AND dueDate <= endOf(w)"

# 标题搜索
uv run scripts/query_tasks.py --tql "title ~ '需求'"

# 查询任务详情(simple 默认,含 note)
uv run scripts/query_task_detail.py <taskId>

# 查询详细信息(含自定义字段等)
uv run scripts/query_task_detail.py <taskId> --detail-level detailed

# 批量查询多个任务
uv run scripts/query_task_detail.py id1,id2,id3

Create task

# 基本创建
uv run scripts/create_task.py --project-id 'xxx' --title '完成需求文档'

# 完整参数创建
uv run scripts/create_task.py \
  --project-id 'xxx' \
  --title '实现登录模块' \
  --executor-id 'uid' \
  --due-date '2026-04-01' \
  --priority 1 \
  --note '参考设计稿'

Update task

# 更新标题和优先级(多字段并行执行)
uv run scripts/update_task.py --task-id 'xxx' --content '新标题' --priority 0

# 更新截止日期和执行人
uv run scripts/update_task.py --task-id 'xxx' --due-date '2026-04-01' --executor-id 'uid'

# 更新任务状态(先查询状态 ID)
uv run scripts/get_task_statuses.py <taskId>
uv run scripts/update_task.py --task-id 'xxx' --taskflowstatus-id '状态ID'

# 单独更新优先级
uv run scripts/update_task_priority.py --task-id 'xxx' --priority 0

Query projects

# 我参与的项目
uv run scripts/query_projects.py --tql "involveMembers = me()"

# 按名称搜索
uv run scripts/query_projects.py --tql "nameText ~ '产品开发'"

# 查询项目详情
uv run scripts/query_project_detail.py <projectId>

# 获取 organizationId(用于查询优先级配置)
uv run scripts/query_project_detail.py <projectId> --extra-fields organizationId

Query members and current user

# 按姓名搜索成员
uv run scripts/query_members.py --keyword '张三'

# 批量按用户ID查询成员(推荐用于ID转换)
uv run scripts/query_members.py --user-ids "id1,id2,id3"

# 获取当前登录用户信息(userId、name、email 等)
uv run scripts/get_current_user.py

Create comment (with @mention)

# 创建评论并 @张三(--mention 接受姓名,脚本自动查询 userId)
uv run scripts/create_comment.py \
  --task-id 'xxx' \
  --content '请张三确认一下' \
  --mention '张三'

# @多人(逗号分隔)
uv run scripts/create_comment.py \
  --task-id 'xxx' \
  --content '请张三和李四评审' \
  --mention '张三,李四'

# 已知 userId 时可直接用 --mention-id
uv run scripts/create_comment.py \
  --task-id 'xxx' \
  --content '已更新' \
  --mention-id '61cad8021deea2ac89a4cbf3'

File upload

# 第一步:上传文件,获取 fileToken
uv run scripts/upload_file.py \
  --file-path '/path/to/doc.pdf' \
  --scope 'task:<taskId>' \
  --category attachment

# 第二步:将 fileToken 附加到评论
uv run scripts/create_comment.py \
  --task-id 'xxx' \
  --content '附件已上传,请查收' \
  --file-tokens 'token1'

Paginated query

query_tasks.py and query_projects.py both support pagination:

Parameter Description
--page-size <N> Number of records per page (default determined by the API)
--page-token <T> Pass in the nextPageToken returned last time to get the next page
# 第一页
uv run scripts/query_tasks.py --tql "executorId = me()" --page-size 20

# 下一页(使用上次输出中的 nextPageToken)
uv run scripts/query_tasks.py --tql "executorId = me()" --page-size 20 --page-token "上次返回的TOKEN"