engagement-suppression-workflow — скилл для Claude Code
Скилл создаёт в HubSpot двухэтапный сценарий для реактивации неактивных контактов и их отписки. Помогает защитить доставляемость рассылок без потери базы.
npx skills add TomGranot/hubspot-admin-skills --skill engagement-suppression-workflow -a claude-codeЧто делает engagement-suppression-workflow
Скилл разворачивает в HubSpot двухэтапную схему отсева неактивных контактов. На первом этапе контакт, не открывавший письма в течение окна затухания (по умолчанию 180 дней), попадает в цепочку реактивации. На втором этапе, если за окно ожидания (по умолчанию 30 дней) реакции не последовало, статус контакта меняется на «немаркетинговый».
Внутри работают три Python-скрипта через утилиту uv. Скрипт scripts/before.py проверяет уже созданные воркфлоу на совпадение имён. Основной scripts/execute.py добавляет кастомное свойство engagement_flag и создаёт через API два линейных сценария. Завершающий scripts/after.py сверяет статус созданных цепочек. Все новые сценарии формируются отключёнными (isEnabled: false), поэтому их нужно активировать вручную в интерфейсе HubSpot.
Для запуска понадобятся Python 3.10+ с менеджером uv, а также токен HUBSPOT_ACCESS_TOKEN в файле .env со скоупом automation. Без тарифа HubSpot Marketing Professional или Enterprise автоматизация работать не будет: доступ к API рабочих процессов на младших планах закрыт.
Какие задачи решает
- защитить доставляемость рассылок в HubSpot от влияния неактивной базы
- создать двухэтапный сценарий реактивации и отписки через Automation API
- промаркировать спящие контакты отдельным свойством
engagement_flag - перевести неответивших подписчиков в статус non-marketing
Примеры запросов агенту
- Настрой двухэтапный сценарий отсева неактивных контактов в HubSpot
- Проверь текущие воркфлоу через
scripts/before.pyи подготовь запуск сценария затухания базы - Создай через API цепочку реактивации для контактов без открытий за последние 180 дней
Как установить engagement-suppression-workflow
1Через Skills CLI (Vercel)
npx skills add TomGranot/hubspot-admin-skills --skill engagement-suppression-workflow -a claude-code2Вручную: положить файлы
~/.claude/skills/engagement-suppression-workflow/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/engagement-suppression-workflow/
1Через Skills CLI (Vercel)
npx skills add TomGranot/hubspot-admin-skills --skill engagement-suppression-workflow -a codex2Вручную: положить файлы
.agents/skills/engagement-suppression-workflow/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add TomGranot/hubspot-admin-skills --skill engagement-suppression-workflow -a cursor2Вручную: положить файлы
.cursor/skills/engagement-suppression-workflow/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install TomGranot/hubspot-admin-skills engagement-suppression-workflow2Вручную: положить файлы
.github/skills/engagement-suppression-workflow/SKILL.md1Через Skills CLI (Vercel)
npx skills add TomGranot/hubspot-admin-skills --skill engagement-suppression-workflow -a gemini-cli2Командой платформы
gemini skills install https://github.com/TomGranot/hubspot-admin-skills --path skills/engagement-suppression-workflowВручную: положить файлы
.devin/skills/engagement-suppression-workflow/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add TomGranot/hubspot-admin-skills --skill engagement-suppression-workflow -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Вопросы о engagement-suppression-workflow
Как установить engagement-suppression-workflow в Claude Code?
Выполните команду npx skills add TomGranot/hubspot-admin-skills --skill engagement-suppression-workflow -a claude-code. Файлы скилла будут размещены по пути ~/.claude/skills/engagement-suppression-workflow/SKILL.md.
Что делает engagement-suppression-workflow?
Скилл создаёт два связанных сценария в HubSpot. Сначала контакты без активности отправляются в реактивационную рассылку, а если они не реагируют в течение контрольного срока, переводятся в статус неотправляемых.
Что требуется для запуска скриптов скилла?
Нужен тариф HubSpot Marketing Professional или Enterprise, Python 3.10+ с утилитой uv, а также переменная HUBSPOT_ACCESS_TOKEN в файле .env со скоупом automation. Дополнительно потребуется заранее подготовленная рассылка для реактивации.
Исходный текст
SKILL.md · MIT
---
name: engagement-suppression-workflow
description: "Build a two-tier sunset workflow that re-engages dormant contacts before suppressing them. Tier 1 triggers a re-engagement campaign after a configurable inactivity window. Tier 2 suppresses contacts that fail to re-engage within a configurable re-engagement window."
license: MIT
metadata:
author: tomgranot
version: "1.1"
category: automation-workflows
---
# Engagement-Based Suppression Workflow
Build a two-tier sunset system that protects email deliverability while giving disengaged contacts a fair chance to re-engage before suppression.
## Why Two Tiers Matter
Suppressing contacts immediately after inactivity is aggressive and loses potential re-activations. A two-tier approach:
- **Tier 1** (inactive for your sunset window — typically 120-270 days): Triggers a re-engagement campaign — a last chance to interact.
- **Tier 2** (your re-engagement window after Tier 1 — typically 21-45 days — with still no engagement): Suppresses the contact from marketing emails.
This preserves deliverability scores while maximizing the recoverable audience.
## Prerequisites
- HubSpot Marketing Professional or Enterprise plan
- A HubSpot service key (`HUBSPOT_ACCESS_TOKEN` in `.env`; an existing legacy private app token also works) with the `automation` scope (for the API path)
- Python 3.10+ with [`uv`](https://github.com/astral-sh/uv)
- A re-engagement email campaign or sequence ready to send
- A custom dropdown property to track suppression status (default: `engagement_flag` — the execute script creates it if missing)
## Scripts
Script paths are relative to this skill's directory. Run them from your project directory so `.env`, `data/`, and `reports/` resolve there: prefix each path with wherever this skill is installed (`skills/engagement-suppression-workflow/` in a clone of the repo).
| Stage | Script | Run with |
|-------|--------|----------|
| Before | [`scripts/before.py`](./scripts/before.py) | `uv run scripts/before.py` |
| Execute | [`scripts/execute.py`](./scripts/execute.py) | `uv run scripts/execute.py` |
| After | [`scripts/after.py`](./scripts/after.py) | `uv run scripts/after.py` |
`before.py` inventories existing workflows and checks for name collisions. `execute.py` creates the `engagement_flag` property (if missing) and both sunset workflows via `POST /automation/v4/flows` — **always disabled, for review in the UI before enabling**. `after.py` verifies they exist and reports enabled state.
## Workflow Design
```
TRIGGER: Last engagement date > [sunset window] ago
AND email is known
AND not globally unsubscribed
AND [suppression status property] is unknown
│
▼
┌────────────────────┐
│ Set [status prop] │
│ = "re-engagement │
│ sent" │
└────────┬───────────┘
│
▼
┌────────────────────┐
│ Enroll in │
│ re-engagement │
│ campaign/sequence │
└────────┬───────────┘
│
▼
┌────────────────────┐
│ Delay: [re-engage │
│ window] days │
└────────┬───────────┘
│
▼
┌────────────────────┐
│ IF/THEN BRANCH: │
│ Any engagement in │
│ re-engage window? │
├──────────┬─────────┘
│ YES │ NO
│ │
▼ ▼
Clear Set [status prop]
status = "suppressed"
prop + set non-marketing
```
## Building the Workflow: Two Options
### Option A: Create via the v4 Automation API (primary)
**API status:** HubSpot documents the Workflows API as **beta** and subject to change. Its current reference is the date-based beta path `/automation/v4/2027-03-beta/flows`; this skill's scripts still call the unversioned `/automation/v4/flows` path, which v4's end of support on March 30, 2027 also covers. Creating workflows disabled and reviewing them in the UI is what makes a beta API acceptable here. If a script's create call starts failing, the manual UI build below is the fallback.
The v4 Automation API supports creating workflows programmatically. Instead of one workflow with an if/then branch, the script decomposes the design into **two linear workflows** — which the API expresses cleanly and which are easier to reason about:
1. **Tier 1 — Flag for Re-engagement**: enrollment = last open older than the sunset window (or never) AND email known AND not globally unsubscribed AND flag unknown. Action: set `engagement_flag` = "re-engagement sent".
2. **Tier 2 — Suppress Non-responders**: enrollment = flag = "re-engagement sent" AND still no open/click after sunset + re-engagement windows. Actions: set flag = "suppressed", set marketing contact status to non-marketing.
Run the scripts (configure `SUNSET_DAYS`, `REENGAGE_DAYS`, `FLAG_PROPERTY` in `execute.py` first):
```bash
uv run scripts/before.py
uv run scripts/execute.py
```
**Safety model:** both workflows are created with `isEnabled: false`. Review them in Automation > Workflows, then:
- Add the "enroll in re-engagement sequence/email" action to Tier 1 (email/sequence IDs are portal-specific).
- If the script reported it could not include the set-marketing-status action, add "Set marketing contact status" to Tier 2 in the UI (one click).
- Turn both on, choosing whether to enroll existing contacts.
**Payload notes:** the scripts use documented v4 action types (`0-5` set property; `0-31` set marketing contact status, with automatic fallback if your portal rejects its undocumented field shape). If a filter shape is rejected, HubSpot's own recommendation applies: build the workflow once in the UI, `GET /automation/v4/flows/{flowId}`, and adapt the script to the exact shapes your portal returns.
### Option B: Manual UI Build (single workflow with branch)
Follow the step-by-step instructions in Stage 3 below. This builds the original single-workflow design with the if/then re-engagement branch, and works on portals where the Automation API is unavailable.
**Alternatives:** HubSpot Breeze AI can scaffold a similar workflow from a prompt, but it creates event-based (OR) triggers instead of filter-based (AND) triggers and cannot configure re-enrollment or "is unknown" conditions — every Breeze-built trigger needs manual verification. The Claude Chrome extension can drive the workflow builder UI directly. Both are secondary to Options A and B.
## Step-by-Step Build Instructions
### Stage 1: Plan
1. Choose your **sunset window** (typically 120-270 days; default 180) and **re-engagement window** (21-45 days; default 30).
2. **Define "engagement"** for the Tier 2 check. Recommended: email open OR email click within the re-engagement window.
3. **Create or identify a re-engagement email/sequence.** A simple 1-2 email series asking "Still interested?" with a clear CTA works well.
### Stage 2: Before
Run `uv run scripts/before.py` — it inventories all workflows, flags name collisions with the two planned SUNSET workflows, and writes the inventory CSV baseline.
If building manually, also create your suppression status property (dropdown: "re-engagement sent", "suppressed") if it does not exist — the API path creates it automatically.
### Stage 3: Execute
**Option A:** run `uv run scripts/execute.py`, then complete the UI review steps listed above.
**Option B — manual UI build:**
1. **Set enrollment trigger:**
- `hs_email_last_open_date` is more than your sunset window (typically 120-270 days) ago OR is unknown
- AND `email` is known
- AND `hs_email_optout` is not true
- AND your suppression status property is unknown
2. **Action: Set contact property**
- Your suppression status property = "re-engagement sent"
3. **Action: Enroll in re-engagement sequence** (or send re-engagement email)
4. **Delay: your re-engagement window (typically 21-45 days)**
5. **If/then branch:**
- Condition: `hs_email_last_open_date` is less than [re-engagement window] days ago OR `hs_email_last_click_date` is less than [re-engagement window] days ago
- **YES (re-engaged):** Set your suppression status property to blank/unknown (clears flag, contact returns to normal)
- **NO (still disengaged):** Set your suppression status property = "suppressed" and set `hs_marketable_status` to non-marketing contact via the "Set marketing contact status" workflow action. (The property itself is read-only via direct API writes — a workflow action is the mechanism, whether the workflow is built in the UI or created via the v4 API.)
6. **Settings:**
- Re-enrollment: OFF
- Goal: Contact opens or clicks any email (optional — exits workflow early)
7. **Turn on the workflow.**
### Stage 4: After
1. Run `uv run scripts/after.py` (API path) to confirm both workflows exist and report their enabled state.
2. Spot-check 10-20 contacts that entered the workflow. Confirm:
- Re-engagement email was sent
- After the re-engagement window, disengaged contacts were suppressed
- Re-engaged contacts had their suppression status property cleared (Option B) or never entered Tier 2 (Option A)
3. Monitor deliverability metrics weekly for the first month.
4. Track how many contacts re-engage vs. get suppressed — adjust the sunset window if needed.
## Rollback
1. Turn off the workflow.
2. To reverse suppressions: filter contacts where your suppression status property = "suppressed" and manually set them back to marketing contacts in the UI.
3. Clear the suppression status property values in bulk if needed.
## Tuning
- **Shorten the sunset window** (e.g., 90-120 days) for aggressive deliverability improvement.
- **Lengthen the re-engagement window** (e.g., 45-60 days) if your email cadence is low.
- **Exclude recent customers** — add a filter to skip contacts with lifecycle stage = Customer or with a closed-won deal in the last 12 months.
© tomgranot · MIT · TomGranot/hubspot-admin-skills