关于 team-ownership
team-ownership 是面向 HubSpot CRM 操作的技能,指导按负责人查找、重新分配联系人、公司、交易和工单。它还说明如何在客户端按负责人汇总记录,并要求批量变更先预览和确认。
主要功能
- 01按邮箱查找负责人 ID
- 02跨四类对象搜索负责人记录
- 03安全批量重新分配记录
- 04按负责人汇总团队视图
适用场景
- 01员工离职时转交 CRM 记录
- 02查看各负责人的交易数量
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ hubspot/ agent-cli-skills --skill team-ownership安装后在 Claude Code 中输入/team-ownership确认已加载。
详细介绍
前置要求:先阅读 bulk-operations/SKILL.md。JSONL 管道、分页、dry-run/digest/confirm,以及 hubspot history 恢复方法均见该文档。数据重塑模式见 bulk-operations/resources/json-patterns.md。
hubspot_owner_id 是 contacts、companies、deals 和 tickets 上的字符串字段。所有者是 CRM 用户,可通过 hubspot owners list 获取;不存在 teams 对象,因此团队级视图是客户端按 hubspot_owner_id 分组生成的。
1. 将邮箱解析为所有者 ID
切勿对 ID 进行硬编码——它们因门户而异。先解析,再缓存:
FROM_ID=$(hubspot owners list | jq -r 'select(.email=="[email protected]") | .id')
TO_ID=$(hubspot owners list | jq -r 'select(.email=="[email protected]") | .id')
2. 查找某个所有者的记录
四种对象类型使用相同的筛选条件。添加特定对象的 --properties 以获取上下文。无所有者的记录使用 !property 形式。
hubspot objects search --type contacts --filter "hubspot_owner_id=$FROM_ID" --properties email,firstname,lifecyclestage
hubspot objects search --type companies --filter "hubspot_owner_id=$FROM_ID" --properties name,domain
hubspot objects search --type deals --filter "hubspot_owner_id=$FROM_ID" --properties dealname,dealstage,amount
hubspot objects search --type tickets --filter "hubspot_owner_id=$FROM_ID" --properties subject,hs_pipeline_stage
# Records with no owner at all
hubspot objects search --type deals --filter "!hubspot_owner_id" --properties dealname,amount
超过 100 条结果时,使用 bulk-operations 中的 --after 循环进行分页。仅计数时:通过管道传给 wc -l。
3. 批量重新分配——搜索 → 更新
将每条搜索结果重塑为 {id, properties:{hubspot_owner_id}},并通过管道传给 objects update。objects update 不可撤销,因此先执行 dry-run:无论记录数量多少,dry-run 都会输出摘要和 apply_command_hint(单条记录的 confirm 值为记录 ID,批量操作的值为行数)。然后使用 --digest/--confirm 重新运行(参见 bulk-operations/SKILL.md §“安全的破坏性操作工作流”)。
# Dry-run
hubspot objects search --type contacts --filter "hubspot_owner_id=$FROM_ID" \
| jq -c --arg to "$TO_ID" '{id, properties:{hubspot_owner_id:$to}}' \
| hubspot objects update --type contacts --dry-run \
| tee /tmp/reassign.preview.jsonl
# Execute — lift the digest + confirm from the preview line (required at every size)
digest=$(jq -r 'select(.digest != null) | .digest' /tmp/reassign.preview.jsonl)
confirm=$(jq -r 'select(.digest != null) | .target.id' /tmp/reassign.preview.jsonl) # single: record ID; batch: row count
hubspot objects search --type contacts --filter "hubspot_owner_id=$FROM_ID" \
| jq -c --arg to "$TO_ID" '{id, properties:{hubspot_owner_id:$to}}' \
| hubspot objects update --type contacts --digest "$digest" --confirm "$confirm"
单条记录分配——无需 stdin,也无需 jq。此操作仍不可撤销,因此先执行 dry-run(confirm 值为记录 ID):
hubspot objects update --type contacts 12345 --property hubspot_owner_id=$TO_ID --dry-run
hubspot objects update --type contacts 12345 --property hubspot_owner_id=$TO_ID --digest <hash> --confirm 12345
4. 离职销售代表的工作流
遍历该销售代表涉及的四种对象类型:
FROM_ID=$(hubspot owners list | jq -r 'select(.email=="[email protected]") | .id')
TO_ID=$(hubspot owners list | jq -r 'select(.email=="[email protected]") | .id')
for type in contacts companies deals tickets; do
echo "── $type ──"
hubspot objects search --type "$type" --filter "hubspot_owner_id=$FROM_ID" \
| jq -c --arg to "$TO_ID" '{id, properties:{hubspot_owner_id:$to}}' \
| hubspot objects update --type "$type" --dry-run
done
检查每一行摘要,然后针对每种类型重新运行,并从该类型的预览行中复制 --digest/--confirm(无论数量多少都必需;批量操作的 confirm 值为行数,单条记录的值为记录 ID)。重新分配错误?hubspot history --since 1h 会列出受影响的 ID。
5. 团队级视图(客户端分组)
按 hubspot_owner_id 对记录分组,并与 owners list 的结果联接,以获取便于阅读的邮箱:
hubspot objects search --type deals --filter "dealstage!=closedwon AND dealstage!=closedlost" \
--properties hubspot_owner_id --format json \
| jq '.data | group_by(.properties.hubspot_owner_id)
| map({owner_id: .[0].properties.hubspot_owner_id, count: length})' \
> /tmp/by-owner.json
hubspot owners list \
| jq --slurpfile by /tmp/by-owner.json -r \
'. as $o | $by[0][] | select(.owner_id==$o.id) | "\($o.email)\t\(.count)"'