audience-targeting — скилл для Claude Code: что делает
Фильтрует контакты в HubSpot по стадии сделки, активности или должности и выгружает сегмент в JSONL. Пригодится при сборке баз для рассылок и кампаний.
npx skills add HubSpot/agent-cli-skills --skill audience-targeting -a claude-codeЧто делает audience-targeting
Скилл учит агента работать с CLI-командами HubSpot для точной выборки аудитории. Поиск строится через вызов hubspot objects search с параметрами --filter. Результаты направляются в поток JSONL. Их можно передавать в другие утилиты или сохранять на диск для повторных выгрузок.
Ограничения накладывает поисковый интерфейс CRM: не больше пяти флагов --filter, до шести условий на флаг и не больше 18 условий суммарно. Оператор ~ ищет только целые токены, а не подстроки. Если нужен сложный поиск по тексту, придётся фильтровать вывод через jq.
Фирмографические атрибуты вроде отрасли и штата сотрудников хранятся у компаний, а не у контактов. Поэтому для фильтрации людей по свойствам бизнеса скилл сначала ищет организации, читает связи через hubspot associations list и только потом запрашивает пачку контактов.
Какие задачи решает
- выгрузить контакты лидов без назначенного владельца в JSONL
- найти лиц, принимающих решения, по вхождению слов в должность
- собрать сегмент контактов из компаний конкретной отрасли
- отсеять отписавшихся адресатов перед передачей базы в рассылку
Примеры запросов агенту
- Собери в JSONL всех лидов из США, которые открывали письма в этом месяце и не отписались от рассылки.
- Найди контакты директоров и вице-президентов через фильтр должностей и сохрани их в
segments/decision_makers.jsonl. - Выгрузи контакты сотрудников из компаний сферы SOFTWARE со штатом от 100 человек.
Как установить audience-targeting
1Через Skills CLI (Vercel)
npx skills add HubSpot/agent-cli-skills --skill audience-targeting -a claude-code2Вручную: положить файлы
~/.claude/skills/audience-targeting/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/audience-targeting/
1Через Skills CLI (Vercel)
npx skills add HubSpot/agent-cli-skills --skill audience-targeting -a codex2Вручную: положить файлы
.agents/skills/audience-targeting/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add HubSpot/agent-cli-skills --skill audience-targeting -a cursor2Вручную: положить файлы
.cursor/skills/audience-targeting/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install HubSpot/agent-cli-skills audience-targeting2Вручную: положить файлы
.github/skills/audience-targeting/SKILL.md1Через Skills CLI (Vercel)
npx skills add HubSpot/agent-cli-skills --skill audience-targeting -a gemini-cli2Командой платформы
gemini skills install https://github.com/HubSpot/agent-cli-skills --path audience-targetingВручную: положить файлы
.devin/skills/audience-targeting/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add HubSpot/agent-cli-skills --skill audience-targeting -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Вопросы о audience-targeting
Как установить audience-targeting в Claude Code?
Выполните команду npx skills add HubSpot/agent-cli-skills --skill audience-targeting -a claude-code.
Что делает скилл audience-targeting?
Он помогает формировать выборки контактов в HubSpot по этапам сделки и активности в письмах с выгрузкой в JSONL.
Как искать контакты по отрасли компании?
Поле industry хранится в объекте компании, поэтому агент сначала находит нужные организации через hubspot objects search --type companies, извлекает связанные идентификаторы через hubspot associations list и пакетно запрашивает контакты.
Исходный текст
SKILL.md · Apache-2.0
---
name: audience-targeting
description: Build a targeted contact segment by filtering on lifecycle, engagement, jobtitle, geography, or firmographics — then export it as JSONL for a campaign or downstream tool.
triggers:
- "segment contacts"
- "target audience"
- "find prospects"
- "build audience"
- "contact segmentation"
- "contacts in industry"
- "decision makers"
- "engaged contacts"
---
## Foundation
Read `bulk-operations/SKILL.md` first — pagination, JSONL piping, destructive-op safety. Reshape recipes in `bulk-operations/resources/json-patterns.md`. Resource: `resources/contact-segmentation-filters.md` is the filter-expression cookbook (lifecycle, lead status, email engagement, activity, deals, owner).
## Filter syntax cheat sheet
Source of truth: `hubspot objects search --help`.
- One `--filter` flag = one AND group: `--filter "lifecyclestage=lead AND !hubspot_owner_id"`.
- Multiple `--filter` flags are OR'd. Use for enum-OR-enum.
- Operators: `=`, `!=`, `>`, `>=`, `<`, `<=`, `~` (CONTAINS_TOKEN — whole-word, NOT substring), `@=` (IN), `@!=` (NOT_IN).
- HAS_PROPERTY: bare `name` or `name?`. NOT_HAS_PROPERTY: `!name`. Dates: `YYYY-MM-DD`.
- **Limits (CRM search API):** max 5 `--filter` flags, max 6 conditions per flag, max 18 conditions total. Prefer `@=` / `@!=` for enum lists — `lifecyclestage@=lead,customer` is **one** condition, `--filter "lifecyclestage=lead" --filter "lifecyclestage=customer"` is two groups.
- **"None of these, or empty" needs two groups** — `@!=` skips records where the property is unset, so OR in a `!name` group and repeat the shared conditions in both:
`--filter "hubspot_owner_id=123 AND lifecyclestage@!=customer,evangelist" --filter "hubspot_owner_id=123 AND !lifecyclestage"`
`~` gotcha: `jobtitle~director` matches the token "director", not arbitrary substrings. No regex operator — search broadly, post-filter with `jq`.
## Properties this skill turns on
Full live list: `hubspot properties list --type contacts`. Enum options: `hubspot properties options-list --type contacts <name> | jq -r '.value'`. As a fallback (e.g. to see which values are actually in use), read live records: `hubspot objects list --type contacts --properties <name> --limit 100 --format json | jq -r '.data[].properties.<name> // empty' | sort -u`.
Core fields used here: `lifecyclestage`, `hubspot_owner_id` (bare/`!` for owned/unowned; `hubspot owners list` for IDs), `hs_email_optout` (`!=true` excludes opted-out), `hs_email_last_open_date` / `notes_last_contacted` (recency), `jobtitle` / `country` / `city` (string `=` or `~`), `num_associated_deals` (0 net-new, `>=1` has-pipeline).
Firmographics (`industry`, `numberofemployees`, `annualrevenue`) live on **companies** — see cross-object section.
## Common segments
```bash
# Recent leads (this quarter, not yet owned)
hubspot objects search --type contacts \
--filter "lifecyclestage=lead AND createdate>2026-01-01 AND !hubspot_owner_id" \
--properties email,firstname,lastname,createdate
# Decision-makers by jobtitle (OR across tokens)
hubspot objects search --type contacts \
--filter "jobtitle~director" --filter "jobtitle~vp" --filter "jobtitle~chief" \
--properties email,jobtitle,company
# Engaged but not yet MQL (opened recently, still lead, opted in)
hubspot objects search --type contacts \
--filter "lifecyclestage=lead AND hs_email_last_open_date>2026-04-01 AND hs_email_optout!=true" \
--properties email,firstname,hs_email_last_open_date
# Geographic — US contacts opted in
hubspot objects search --type contacts \
--filter "country=United States AND hs_email_optout!=true" \
--properties email,state,city
```
More patterns (lead status, deals, owners, combined AND/OR) in `resources/contact-segmentation-filters.md`.
## Cross-object: companies-in-industry → their contacts
`industry`/`numberofemployees`/`annualrevenue` live on the company. Build the company set, then traverse — never `xargs -I{} hubspot objects get` per company. `associations list` emits `{"id":"...","labels":[...],"associationTypes":[...]}` — `{id}` feeds directly into a single batched `objects get`.
```bash
# Step 1: target companies. Industry options are portal-specific — discover with:
# hubspot objects list --type companies --properties industry --limit 100 --format json \
# | jq -r '.data[].properties.industry // empty' | sort -u
hubspot objects search --type companies \
--filter "industry=SOFTWARE AND numberofemployees>=100" \
--properties name,industry,numberofemployees \
> target_companies.jsonl
# Step 2: gather association IDs (associations list has no batch --from), then ONE batched
# objects get for all contacts. Page each company with --limit/--after — a company with >100
# associated contacts truncates silently on a single call.
while read -r cid; do
after=""
while :; do
page=$(hubspot associations list --from "companies:$cid" --to contacts --limit 100 ${after:+--after "$after"} --format json)
echo "$page" | jq -c '.data[]?'
after=$(echo "$page" | jq -r '.meta.next // empty')
[ -z "$after" ] && break
done
done \
< <(jq -r '.id' target_companies.jsonl) \
| jq -c '{id}' | sort -u \
| hubspot objects get --type contacts --properties email,firstname,jobtitle,hs_email_optout \
> target_contacts.jsonl
# Optional: drop opted-out
jq -c 'select(.properties.hs_email_optout != "true")' target_contacts.jsonl > campaign_audience.jsonl
```
## Saving and reusing a segment
A segment is a JSONL file. Re-use for updates, exports, or re-fetches:
```bash
# Save
hubspot objects search --type contacts \
--filter "lifecyclestage=lead AND hs_email_optout!=true" \
--properties email,firstname,lastname,jobtitle \
> segments/opted_in_leads.jsonl
# Assign owner (dry-run first per bulk-operations/SKILL.md)
jq -c '{id, properties:{hubspot_owner_id:"12345"}}' segments/opted_in_leads.jsonl \
| hubspot objects update --type contacts --dry-run
# Re-fetch with different properties later
jq -c '{id}' segments/opted_in_leads.jsonl \
| hubspot objects get --type contacts --properties email,lifecyclestage,hs_lead_status
```
Destructive ops on a saved segment follow the dry-run → digest → confirm flow in `bulk-operations/SKILL.md`.
## Save as a HubSpot list or view
A JSONL segment is portable, but you can also persist an audience in HubSpot:
- **List** — `hubspot segments create` saves a list; `segments get` / `list` inspect it; `segments members-list` reads members; `segments members-add` / `members-remove` manage membership. Use `segments update-filters` to set a dynamic list's filter criteria.
- **View** — `hubspot views create --type <t> --name "..." --columns a,b [--filters-file filters.json] [--sort prop:asc]` saves a filter set as a reusable object view; `views list` / `get` / `update` / `replace-field` / `delete` manage it.
- **Size it first** — `hubspot objects count --type contacts --filter "..."` returns `{"object_type":"contacts","total":N}` without paging, so you can size an audience before saving or exporting it.
## Related read-only signals (context for targeting)
- `hubspot buyer-intent` — visiting-company intent signals (read-only). **Requires OAuth login (`hubspot auth login`); service keys are NOT supported.**
- `hubspot analytics traffic sources` — where sessions/contacts came from, for source-based segmentation.
- `hubspot marketing forms list` — form definitions, to segment by which form a contact converted on.
Run each command's `--help` for the full surface.
## Known limits
- `~` is token-match, not substring. No regex operator.
- Enum options: `hubspot properties options-list --type contacts <name>` (fallback: read live records via `objects list` + `jq`).
- `associations list` has no batch `--from`, and returns one page (default 100) per call. Loop to gather IDs and page each call with `--limit`/`--after` until `.meta.next` is null, then batch the downstream `objects get` — otherwise a company with >100 associated contacts truncates silently.
- For >100 results, use the pagination loop in `bulk-operations/SKILL.md`.
© HubSpot · Apache-2.0 · HubSpot/agent-cli-skills