Customer Retention

hubspot/agent-cli-skills/customer-retention

作者 hubspota8eea0880838无许可证27 个星标收录于 2026年10月8日更新于 2026年10月8日仓库7天前更新

Identify inactive/at-risk customers via CRM filters and create follow-up tasks at scale. Builds on `bulk-operations`; defers activity-creation specifics to `sales-execution`.

仅含说明Marketing & Sales
AI 生成的概览

在 HubSpot 中找出不活跃或有流失风险的客户,并批量创建关联的跟进任务。

功能
通过 HubSpot CLI 过滤器定位近期没有外联或销售活动记录的客户,并标记逾期订阅。随后生成跟进任务或回访记录,并将其与对应联系人关联,支持对整个客户群批量创建。还引用一个配套资源文件,内含流失信号过滤表达式。
适用场景
适用于销售或客户成功团队需要识别流失风险、不活跃账户或需要续约外联的客户时。适合按客户群批量创建跟进任务,而非单条记录编辑。
运行要求
需要已认证的 HubSpot CLI,以及 jq 和标准 shell 日期工具。部分订阅读取需要具备 subscriptions-read 权限的私有应用令牌。该技能不含脚本,只有说明文档和一个参考文件,并依赖 bulk-operations 与 sales-execution 技能。

Resources

FileWhen to use
resources/customer-health-signals.mdFilter cookbook of churn signals — --filter expressions for notes_last_contacted, hs_last_sales_activity_date, hs_email_optout, stale tickets, subscription status.

Prereqs

Read bulk-operations/SKILL.md first — every read/write below uses its JSONL pipe, pagination, and dry-run/digest patterns. Activity-property tables and association rules live in sales-execution/SKILL.md.

Schema is portal-specific. Verify each property before filtering — e.g. hubspot properties get --type contacts notes_last_contacted, ... hs_last_sales_activity_date, ... --type subscriptions hs_subscription_status. If subscriptions returns 403, your token lacks subscriptions-read — use a private-app token with that scope.

1 — Find inactive customers

bash
CUTOFF=$(date -v-60d +%Y-%m-%d 2>/dev/null || date -d '60 days ago' +%Y-%m-%d)
# No outreach in 60d (calls/notes/meetings update notes_last_contacted)hubspot objects search --type contacts \  --filter "lifecyclestage=customer AND notes_last_contacted<$CUTOFF" \  --properties email,firstname,notes_last_contacted,hubspot_owner_id
# No sales activity in 60d (broader — also catches emails/tasks)hubspot objects search --type contacts \  --filter "lifecyclestage=customer AND hs_last_sales_activity_date<$CUTOFF" \  --properties email,firstname,hs_last_sales_activity_date
# Never contactedhubspot objects search --type contacts \  --filter "lifecyclestage=customer AND !notes_last_contacted" \  --properties email,firstname

For more signals (email opt-out, stale tickets, no open deals) see resources/customer-health-signals.md. For >100 hits, use the pagination loop from bulk-operations.

To audit why a customer churned or moved stage — which workflow, integration, import, or UI edit last changed lifecyclestage — use hubspot objects history --type contacts --properties lifecyclestage [--id <recordId>] [--include-ui]. It flattens each property's source history into one row per change.

2 — Flag at-risk subscriptions

subscriptions is a standard object (hubspot objects types confirms). Enum values for hs_subscription_status are portal-specific — verify before filtering, then plug the exact value in:

bash
hubspot properties options-list --type subscriptions hs_subscription_status   # allowed values
# Past-due — revenue at immediate risk (substitute your verified value)hubspot objects search --type subscriptions \  --filter "hs_subscription_status=past_due" \  --properties hs_recurring_billing_total,hs_subscription_status
# Map an at-risk subscription to its contact for outreachhubspot associations list --from subscriptions:<sub_id> --to contacts --format jsonl

3 — Create a follow-up task or check-in note

Activity creation lives in sales-execution (full property tables, note + meeting flows). One anchor example — unassociated tasks are invisible in the CRM UI, so always associate:

bash
task_id=$(hubspot objects create --type tasks \  --property hs_task_subject="Q1 retention check-in" \  --property hs_task_priority=HIGH --property hs_task_status=NOT_STARTED \  --property hs_task_type=CALL --property hs_timestamp=$(date +%s)000 \  --format json | jq -r '.id')hubspot associations create --from tasks:$task_id --to contacts:<contact_id>

4 — Bulk task creation for a cohort

Pipe a search through jq into one objects create call, then associate. objects create is Additive — never digest-gated — so --dry-run is a plain preview and you execute by dropping it (no digest/confirm). The digest flow only applies to the irreversible writes in bulk-operations/SKILL.md.

bash
DUE_MS=$(( ($(date +%s) + 2*86400) * 1000 ))   # due in 2 days
# 1. Capture the cohort (same file feeds both create + associate)hubspot objects search --type contacts \  --filter "lifecyclestage=customer AND notes_last_contacted<$CUTOFF" \  --properties firstname > /tmp/inactive.jsonl
# 2. Build task payloads — one per contactjq -c --arg due "$DUE_MS" '{  contact_id: .id,  properties: {    hs_task_subject: ("Re-engage: " + (.properties.firstname // "customer")),    hs_task_priority: "HIGH", hs_task_status: "NOT_STARTED",    hs_task_type: "CALL", hs_timestamp: $due  }}' /tmp/inactive.jsonl > /tmp/task_payloads.jsonl
# 3. Dry-run, then create (drop contact_id before piping)jq -c '{properties}' /tmp/task_payloads.jsonl | hubspot objects create --type tasks --dry-run | headjq -c '{properties}' /tmp/task_payloads.jsonl | hubspot objects create --type tasks > /tmp/created.jsonl
# 4. Associate each new task to its contact — one piped call (associations create batches 100 pairs/API call; paste preserves order)paste <(jq -r '.id' /tmp/created.jsonl) <(jq -r '.contact_id' /tmp/task_payloads.jsonl) \  | jq -cR 'split("\t") | {from:("tasks:" + .[0]), to:("contacts:" + .[1])}' \  | hubspot associations create

One CLI call for the search, one for the create, and one for all associations — no xargs -I{} per record. The output-order guarantee of objects create (one result per stdin line, in order — see bulk-operations "Output shape") is what makes the paste correct.

Known gaps

  • No native churn-score / health-score property — track via a custom property.
  • hubspot segments provides CRM lists for re-engagement cohorts — segments members-list pulls a list's members, and segments create / update-filters save an at-risk audience as a reusable list. Re-engagement enrollment can be built as a workflow via hubspot workflows create / update (see workflow-automation/SKILL.md).
  • hubspot sequences reads Sales Hub sequences (read-only): use sequences enrollments <contact_id> to see whether an at-risk customer was ever engaged through a sales sequence. Sequences are a product API (Sales Hub Professional+, automation.sequences.read scope), not a CRM object type — the CLI cannot create sequences or enroll contacts. This list grows over time; recheck hubspot --help / CHANGELOG.md rather than assuming an API is absent.
  • hubspot associations create batches stdin JSONL (up to 100 pairs per API call) — pipe the pairs in one call instead of looping.

来源与署名

来源:hubspot/agent-cli-skills位于customer-retention提交a8eea08

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架