sales-reporting

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Source of truth

权威参考来源

hubspot <command> --help
is authoritative. Build on
bulk-operations/SKILL.md
— JSONL shape, batch-read rules, and pagination live there. Reshape patterns:
bulk-operations/resources/json-patterns.md
.
search
/
list
cap at 100 rows per call; a result of exactly 100 is almost always truncated — paginate via
bulk-operations/SKILL.md
before aggregating.
hubspot <command> --help
是权威参考依据。基于
bulk-operations/SKILL.md
进行开发——JSONL格式、批量读取规则和分页逻辑均记录于此。格式调整参考:
bulk-operations/resources/json-patterns.md
search
/
list
接口每次调用最多返回100行结果;若结果恰好为100行,几乎可以确定数据被截断——在聚合数据前,请按照
bulk-operations/SKILL.md
中的说明进行分页处理。

Property and output shape notes

属性与输出格式说明

  • All CRM property values come back as strings in JSONL — booleans included.
    hs_is_closed_won
    is returned as
    "true"
    /
    "false"
    (string);
    amount
    is a numeric string. Use
    tonumber
    for arithmetic; compare booleans as strings (
    == "true"
    ) when filtering client-side.
  • In
    --filter
    expressions,
    hs_is_closed_won=true
    and
    hs_is_closed!=true
    work — the API parses the value.
  • --properties
    returns the standard nested shape:
    {"id":"123","properties":{"amount":"5000","dealname":"..."}}
    . Reference fields as
    .properties.amount
    in jq.
  • Stage IDs in
    dealstage
    are portal-specific. Map them with
    hubspot pipelines stages --type deals --pipeline <id>
    .
  • hubspot_owner_id
    is a numeric string. Resolve to a name with
    hubspot owners list
    (fields:
    id
    ,
    firstName
    ,
    lastName
    ,
    email
    ).
  • 所有CRM属性值在JSONL中均以字符串形式返回,包括布尔值。
    hs_is_closed_won
    会返回为
    "true"
    /
    "false"
    (字符串类型);
    amount
    是数值型字符串。进行算术运算时请使用
    tonumber
    ;在客户端过滤时,需将布尔值作为字符串进行比较(如
    == "true"
    )。
  • --filter
    表达式中,
    hs_is_closed_won=true
    hs_is_closed!=true
    均可正常工作——API会自动解析对应值。
  • --properties
    返回标准的嵌套格式:
    {"id":"123","properties":{"amount":"5000","dealname":"..."}}
    。在jq中引用字段时需使用
    .properties.amount
    格式。
  • dealstage
    中的阶段ID是特定于门户的。可通过
    hubspot pipelines stages --type deals --pipeline <id>
    命令映射阶段ID与对应名称。
  • hubspot_owner_id
    是数值型字符串。可通过
    hubspot owners list
    命令将其解析为负责人姓名(返回字段包括:
    id
    firstName
    lastName
    email
    )。

1. Daily briefing

1. 每日简报

Date windows differ between macOS and GNU
date
:
bash
undefined
macOS与GNU
date
命令的日期窗口语法有所不同:
bash
undefined

macOS

macOS

TODAY=$(date +%Y-%m-%d); NEXT_7=$(date -v+7d +%Y-%m-%d); YESTERDAY=$(date -v-1d +%Y-%m-%d)
TODAY=$(date +%Y-%m-%d); NEXT_7=$(date -v+7d +%Y-%m-%d); YESTERDAY=$(date -v-1d +%Y-%m-%d)

Linux

Linux

TODAY=$(date +%Y-%m-%d); NEXT_7=$(date -d '7 days' +%Y-%m-%d); YESTERDAY=$(date -d '1 day ago' +%Y-%m-%d)

**Deals closing in the next 7 days:**
```bash
hubspot objects search --type deals \
  --filter "closedate>$TODAY AND closedate<$NEXT_7 AND hs_is_closed!=true" \
  --properties dealname,amount,closedate,hubspot_owner_id
Deals updated in the last 24h:
bash
hubspot objects search --type deals \
  --filter "hs_lastmodifieddate>$YESTERDAY AND hs_is_closed!=true" \
  --properties dealname,amount,dealstage,hs_lastmodifieddate
Open-pipeline summary line:
bash
hubspot objects search --type deals --filter "hs_is_closed!=true" --properties amount \
| jq -rs '{count: length, value: ([.[].properties.amount | select(. != null) | tonumber] | add // 0 | round)}
          | "Open pipeline: \(.count) deals, $\(.value)"'
TODAY=$(date +%Y-%m-%d); NEXT_7=$(date -d '7 days' +%Y-%m-%d); YESTERDAY=$(date -d '1 day ago' +%Y-%m-%d)

**未来7天内即将关闭的交易:**
```bash
hubspot objects search --type deals \
  --filter "closedate>$TODAY AND closedate<$NEXT_7 AND hs_is_closed!=true" \
  --properties dealname,amount,closedate,hubspot_owner_id
过去24小时内更新的交易:
bash
hubspot objects search --type deals \
  --filter "hs_lastmodifieddate>$YESTERDAY AND hs_is_closed!=true" \
  --properties dealname,amount,dealstage,hs_lastmodifieddate
未结管道汇总信息:
bash
hubspot objects search --type deals --filter "hs_is_closed!=true" --properties amount \
| jq -rs '{count: length, value: ([.[].properties.amount | select(. != null) | tonumber] | add // 0 | round)}
          | "Open pipeline: \(.count) deals, $\(.value)"'

2. Pipeline snapshot

2. 销售管道快照

By stage — count and amount per
dealstage
:
bash
hubspot objects search --type deals --filter "hs_is_closed!=true" \
  --properties dealstage,amount \
| jq -rs '
    group_by(.properties.dealstage)
    | map({stage: .[0].properties.dealstage, count: length,
           total: ([.[].properties.amount | select(. != null) | tonumber] | add // 0 | round)})
    | sort_by(-.total) | .[] | "\(.stage)\tcount: \(.count)\tvalue: $\(.total)"' \
| column -t -s$'\t'
By owner:
bash
hubspot objects search --type deals --filter "hs_is_closed!=true" \
  --properties amount,hubspot_owner_id \
| jq -rs '
    group_by(.properties.hubspot_owner_id)
    | map({owner: .[0].properties.hubspot_owner_id, count: length,
           total: ([.[].properties.amount | select(. != null) | tonumber] | add // 0 | round)})
    | sort_by(-.total) | .[] | "owner \(.owner)\tdeals: \(.count)\tvalue: $\(.total)"' \
| column -t -s$'\t'
To label owner IDs with names, dump the owners file once and join:
bash
hubspot owners list | jq -r '"\(.id)\t\(.firstName) \(.lastName) <\(.email)>"' > /tmp/owners.tsv
按阶段划分——每个
dealstage
的交易数量与金额:
bash
hubspot objects search --type deals --filter "hs_is_closed!=true" \
  --properties dealstage,amount \
| jq -rs '
    group_by(.properties.dealstage)
    | map({stage: .[0].properties.dealstage, count: length,
           total: ([.[].properties.amount | select(. != null) | tonumber] | add // 0 | round)})
    | sort_by(-.total) | .[] | "\(.stage)\tcount: \(.count)\tvalue: $\(.total)"' \
| column -t -s$'\t'
按负责人划分:
bash
hubspot objects search --type deals --filter "hs_is_closed!=true" \
  --properties amount,hubspot_owner_id \
| jq -rs '
    group_by(.properties.hubspot_owner_id)
    | map({owner: .[0].properties.hubspot_owner_id, count: length,
           total: ([.[].properties.amount | select(. != null) | tonumber] | add // 0 | round)})
    | sort_by(-.total) | .[] | "owner \(.owner)\tdeals: \(.count)\tvalue: $\(.total)"' \
| column -t -s$'\t'
若要将负责人ID替换为姓名,可先导出负责人信息文件,再进行关联:
bash
hubspot owners list | jq -r '"\(.id)\t\(.firstName) \(.lastName) <\(.email)>"' > /tmp/owners.tsv

3. Win/loss analysis

3. 输赢分析

Filter on
hs_is_closed_won=true
for won;
hs_is_closed=true AND hs_is_closed_won!=true
for lost. Scope with
closedate>=YYYY-MM-DD AND closedate<YYYY-MM-DD
.
Closed won / lost in a period:
bash
hubspot objects search --type deals \
  --filter "hs_is_closed_won=true AND closedate>=2026-04-01 AND closedate<2026-07-01" \
  --properties dealname,amount,closedate,hubspot_owner_id

hubspot objects search --type deals \
  --filter "hs_is_closed=true AND hs_is_closed_won!=true AND closedate>=2026-04-01 AND closedate<2026-07-01" \
  --properties dealname,amount,closedate,hubspot_owner_id
Win rate by rep — pull all closed deals in the period, group, divide. Note:
hs_is_closed_won
lands as a string, so compare
== "true"
.
bash
hubspot objects search --type deals \
  --filter "hs_is_closed=true AND closedate>=2026-01-01" \
  --properties hubspot_owner_id,hs_is_closed_won,amount \
| jq -rs '
    group_by(.properties.hubspot_owner_id)
    | map({owner: .[0].properties.hubspot_owner_id,
           total: length,
           won: ([.[] | select(.properties.hs_is_closed_won == "true")] | length),
           won_value: ([.[] | select(.properties.hs_is_closed_won == "true")
                       | .properties.amount | select(. != null) | tonumber] | add // 0 | round)})
    | map(. + {win_rate: ((.won / .total * 100) | round)})
    | sort_by(-.won_value)
    | .[] | "owner \(.owner)\twon: \(.won)/\(.total)\trate: \(.win_rate)%\twon: $\(.won_value)"' \
| column -t -s$'\t'
Revenue by close month (won deals):
bash
hubspot objects search --type deals \
  --filter "hs_is_closed_won=true AND closedate>=2026-01-01" \
  --properties amount,closedate \
| jq -rs '
    group_by(.properties.closedate[0:7])
    | map({month: .[0].properties.closedate[0:7], count: length,
           revenue: ([.[].properties.amount | select(. != null) | tonumber] | add // 0 | round)})
    | sort_by(.month) | .[] | "\(.month)\tdeals: \(.count)\trevenue: $\(.revenue)"' \
| column -t -s$'\t'
筛选成交交易时使用
hs_is_closed_won=true
;筛选未成交交易时使用
hs_is_closed=true AND hs_is_closed_won!=true
。可通过
closedate>=YYYY-MM-DD AND closedate<YYYY-MM-DD
指定时间范围。
某时间段内的成交/未成交交易:
bash
hubspot objects search --type deals \
  --filter "hs_is_closed_won=true AND closedate>=2026-04-01 AND closedate<2026-07-01" \
  --properties dealname,amount,closedate,hubspot_owner_id

hubspot objects search --type deals \
  --filter "hs_is_closed=true AND hs_is_closed_won!=true AND closedate>=2026-04-01 AND closedate<2026-07-01" \
  --properties dealname,amount,closedate,hubspot_owner_id
按销售代表划分的赢单率——提取某时间段内所有已关闭交易,分组后计算赢单率。注意:
hs_is_closed_won
以字符串形式返回,因此需使用
== "true"
进行比较。
bash
hubspot objects search --type deals \
  --filter "hs_is_closed=true AND closedate>=2026-01-01" \
  --properties hubspot_owner_id,hs_is_closed_won,amount \
| jq -rs '
    group_by(.properties.hubspot_owner_id)
    | map({owner: .[0].properties.hubspot_owner_id,
           total: length,
           won: ([.[] | select(.properties.hs_is_closed_won == "true")] | length),
           won_value: ([.[] | select(.properties.hs_is_closed_won == "true")
                       | .properties.amount | select(. != null) | tonumber] | add // 0 | round)})
    | map(. + {win_rate: ((.won / .total * 100) | round)})
    | sort_by(-.won_value)
    | .[] | "owner \(.owner)\twon: \(.won)/\(.total)\trate: \(.win_rate)%\twon: $\(.won_value)"' \
| column -t -s$'\t'
按成交月份划分的营收(仅统计成交交易):
bash
hubspot objects search --type deals \
  --filter "hs_is_closed_won=true AND closedate>=2026-01-01" \
  --properties amount,closedate \
| jq -rs '
    group_by(.properties.closedate[0:7])
    | map({month: .[0].properties.closedate[0:7], count: length,
           revenue: ([.[].properties.amount | select(. != null) | tonumber] | add // 0 | round)})
    | sort_by(.month) | .[] | "\(.month)\tdeals: \(.count)\trevenue: $\(.revenue)"' \
| column -t -s$'\t'

Known limitations

已知限制

  • hubspot pipelines stages
    does not expose stage probability — won/lost stages can't be auto-identified from the stages list. Use
    hs_is_closed_won
    on deals instead.
  • No team object — group by
    hubspot_owner_id
    and resolve names from
    hubspot owners list
    client-side.
  • hubspot pipelines stages
    命令不会暴露阶段概率——无法通过阶段列表自动识别成交/未成交阶段。请改用交易的
    hs_is_closed_won
    属性进行判断。
  • 无团队对象——需通过
    hubspot_owner_id
    分组,并在客户端通过
    hubspot owners list
    命令解析负责人姓名。