sales-execution について
sales-executionは、HubSpot CLIで営業アクティビティやタスクを作成・管理するスキルです。アクティビティとCRMレコードの関連付けを重視し、タスク検索や一括フォローアップ作成の方法を示します。
主な機能
- 01営業アクティビティの作成と関連付け
- 02コンタクトに紐づくタスクの取得
- 03ステータスと担当者によるタスク検索
- 04特定ステージの取引に一括フォローアップ作成
- 05アクティビティ属性と列挙値の参照
活用シーン
- 01通話をコンタクトや取引に記録
- 02コンタクトの未完了タスクを検索
- 03特定ステージの取引にフォローアップタスクを一括作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ hubspot/ agent-cli-skills --skill sales-executionインストール後、Claude Code で/sales-executionを入力して読み込まれたか確認します。
同梱ファイルresources/activity-properties-reference.md
詳細
リソース
| ファイル | 使用するタイミング |
|---|---|
resources/activity-properties-reference.md | 通話/メモ/会議/タスクのプロパティ名と列挙値。objects create を書いている間は開いたままにしてください — 実際の列挙値については hubspot properties options-list --type calls <property> を実行し、通話の結果については hubspot activities calls dispositions list を実行します。リファレンスは近道です。 |
まず bulk-operations/SKILL.md を読んでください — このスキルはそのバッチ処理、パイプ、ドライランのパターンを前提としています。
2 つの自明でないルール
1. アクティビティは関連付けられるまで見えません。 hubspot objects create --type calls ... だけでは、CRM UI で誰にも見えないレコードが生成されます。必ず hubspot associations create --from calls:<id> --to contacts:<id>(関連する場合はディールも)を続けてから終了してください。
2. タイムスタンプは書き込みと読み取りで異なります。
| パス | フィールド | 形式 |
|---|---|---|
objects create --property hs_timestamp=... | hs_timestamp | Unix ms(13 桁) |
objects get --type calls <id> が返す | properties.hs_timestamp | Unix ms(文字列) |
activities list --contact <id> が返す | timestamp(フラット、トップレベル) | ISO 8601(例: 2024-01-15T10:00:00Z) |
現在の Unix ms: $(date +%s)000(macOS)または $(date +%s%3N)(Linux)。activities list の行は {"id","type","timestamp","lastModified","title","body","status","owner_id"} です — クロスタイプのタイムライン読み取り形状で、生のプロパティ名はありません。
タイプ別の作成 + 関連付け
# CALL
call_id=$(hubspot objects create --type calls \
--property hs_call_title="Discovery call" \
--property hs_call_body="Confirmed $50K budget, Q2 timeline." \
--property hs_call_direction=OUTBOUND \
--property hs_call_status=COMPLETED \
--property hs_call_duration=1800000 \
--property hs_timestamp=$(date +%s)000 \
--format json | jq -r '.id')
hubspot associations create --from calls:$call_id --to contacts:149
hubspot associations create --from calls:$call_id --to deals:456
# NOTE
note_id=$(hubspot objects create --type notes \
--property hs_note_body="Sent proposal. Follow-up Friday." \
--property hs_timestamp=$(date +%s)000 \
--format json | jq -r '.id')
hubspot associations create --from notes:$note_id --to deals:456
# MEETING — start/end in Unix ms; reuse start as hs_timestamp
start=$(date +%s)000; end=$(( ${start%000} + 3600 ))000
meeting_id=$(hubspot objects create --type meetings \
--property hs_meeting_title="Demo — Acme" --property hs_meeting_outcome=COMPLETED \
--property hs_meeting_start_time=$start --property hs_meeting_end_time=$end \
--property hs_timestamp=$start --format json | jq -r '.id')
hubspot associations create --from meetings:$meeting_id --to contacts:149
# TASK — hs_timestamp is the DUE DATE, not creation time
due=$(( $(date -v+7d +%s) * 1000 )) # macOS; Linux: date -d '7 days' +%s
task_id=$(hubspot objects create --type tasks \
--property hs_task_subject="Confirm proposal received" \
--property hs_task_priority=HIGH \
--property hs_task_status=NOT_STARTED \
--property hs_task_type=CALL \
--property hs_timestamp=$due \
--format json | jq -r '.id')
hubspot associations create --from tasks:$task_id --to deals:456
連絡先の未完了タスク — 2 つの CLI 呼び出し、xargs なし
associations list は行ごとに {"id": …} を出力します(加えて label/associationType フィールド)。objects get は 1 回のバッチ呼び出しで標準入力から読み取ります(bulk-operations/SKILL.md の「バッチで読み取る」を参照)。
hubspot associations list --from contacts:149 --to tasks \
| hubspot objects get --type tasks \
--properties hs_task_subject,hs_task_status,hs_task_priority,hs_timestamp \
| jq -c 'select(.properties.hs_task_status != "COMPLETED")'
ポータル全体の未完了タスク — @!= でサーバー側でステータスを除外する
@!= は NOT_IN です。除外リスト全体に対して 1 つの条件で済みます。除外するステータスごとに --filter フラグを 1 つずつ使ってはいけません — 検索 API は 1 リクエストあたりフィルタグループ 5 個、グループあたり条件 6 個、条件合計 18 個が上限です。
@!= はそのプロパティを持つレコードにのみ一致するため、実際の HubSpot タスクビューの「ステータスが次のいずれでもない…または空である」を再現するには 2 つのグループ(OR 結合)が必要で、共有条件をそれぞれで繰り返します:
hubspot objects search --type tasks \
--filter "hubspot_owner_id=123 AND hs_task_status@!=COMPLETED,DEFERRED" \
--filter "hubspot_owner_id=123 AND !hs_task_status" \
--properties hs_task_subject,hs_task_status,hs_task_priority,hs_timestamp
逆(これらのステータスのみ)は @=(IN)です: --filter "hs_task_status@=NOT_STARTED,IN_PROGRESS,WAITING"。
一括: ステージ内のディールごとのフォローアップタスク
ディール ID とタスク ID は一緒に移動する必要があります。ディールのペイロードをファイルに永続化し、タスクを作成し(出力順は入力順と一致します — bulk-operations を参照)、次に 2 つの ID リストを行ごとに対にして、1 回の呼び出しで関連付けペアをストリームします。
due=$(( $(date -v+7d +%s) * 1000 ))
# 1. Per-deal payload, deal_id retained alongside the create payload.
hubspot objects search --type deals --filter "dealstage=appointmentscheduled" \
--properties dealname \
| jq -c --argjson due "$due" '{deal_id: .id, payload: {properties: {
hs_task_subject: ("Follow up: " + .properties.dealname),
hs_task_priority: "HIGH", hs_task_status: "NOT_STARTED", hs_task_type: "CALL",
hs_timestamp: ($due|tostring)
}}}' > /tmp/deal_tasks.jsonl
# 2. Create tasks; one CLI call for the whole batch.
jq -c '.payload' /tmp/deal_tasks.jsonl \
| hubspot objects create --type tasks > /tmp/created_tasks.jsonl
# 3. Zip and stream association pairs through stdin.
paste \
<(jq -r '.deal_id' /tmp/deal_tasks.jsonl) \
<(jq -r '.id' /tmp/created_tasks.jsonl) \
| jq -Rc 'split("\t") | {from:("tasks:"+.[1]), to:("deals:"+.[0])}' \
| hubspot associations create
これらは objects create 呼び出し(Additive)です — 作成は決してダイジェストで制限されないため、--dry-run は単なるプレビューであり、それを外すことで実行します(ダイジェスト/確認は不要)。ダイジェストフローは bulk-operations/SKILL.md の不可逆な書き込み(update/upsert/delete/merge)にのみ適用されます。
既知の制約
アクティビティはすぐに関連付けなければ、CRM UI では見えません。アクティビティプロパティの列挙オプション値については、hubspot properties options-list --type calls <property> を実行してください(通話の結果については、hubspot activities calls dispositions list を実行してください)。リファレンスは近道です。Sales Hub のシーケンスは CLI では読み取り専用です(hubspot sequences list / get / enrollments、automation.sequences.read スコープ) — CLI は連絡先をシーケンスに登録できないため、上記のタスク/アクティビティを介してアウトリーチを進めてください。このサーフェスは拡大しています。API が存在しないと決めつける前に、hubspot --help / CHANGELOG.md を再確認してください。