📙 HubSpot CRM/MA ゼロから学ぶ実践教科書
Chapter 7

CMS ↔ CRM 完全連携ガイド
エンジニアが知るべき統合設計

HubSpotをただ「使う」のではなく、CMSとCRMをひとつの統合システムとして設計するための技術知識を徹底解説します。トラッキングコードの仕組み・スマートコンテンツ実装・HubSpot API・Webhook設計・外部CMS連携まで、コードレベルで理解できる唯一の章です。

🎯 対象レベル:中級〜上級(エンジニア向け)
⏱ 読了目安:90〜120分
💻 必要スキル:HTML/CSS/JS 基礎 + HubL 基礎

この章の内容

  1. トラッキングコードの仕組み — Cookie・訪問者識別・既知コンタクト化の完全フロー
  2. スマートコンテンツの実装 — ライフサイクル・デバイス・地域での出し分け
  3. パーソナライズトークンの CMS 実装 — HubL での動的コンテンツ
  4. HubSpot Forms の外部 CMS 埋め込み(WordPress・React/Next.js)
  5. HubSpot API の基礎 — Contacts / Forms / Properties API
  6. Webhook の設計 — HubSpot から外部システムへのリアルタイム通知
  7. 外部サービス連携パターン(Zapier / Make / Native Integration / API直接)
Section 7-1

トラッキングコードの仕組み — Cookie・訪問者識別・既知コンタクト化の完全フロー

HubSpotがサイト訪問者を「匿名の誰か」から「特定のコンタクト」へと変換する仕組みは、 JavaScriptトラッキングコード + Cookie + フォーム送信の3つの組み合わせです。 この仕組みを完全に理解することが、CMS↔CRM連携設計の出発点です。

訪問者識別の完全フロー

🌐
① 匿名訪問者がサイトにアクセス

CookieがないブラウザでHubSpotトラッキングコードが設置されたページを訪問。この時点ではCRMにデータは登録されない。

📋
③ フォームを送信 — hubspotutk がメールアドレスと紐付く

フォーム送信データに hubspotutk が自動付与されてHubSpotサーバーへ送信。HubSpotはメールアドレスで既存コンタクトを照合し、新規なら作成・既存なら更新する。

POST: フォームデータ + hutk=e0e4e8f2... → コンタクト作成/更新
④ 訪問者が「既知コンタクト」になる

フォーム送信以降、この訪問者がサイトを訪問するたびにCRMの「ページビュー」アクティビティが自動で記録される。コンタクト詳細でリアルタイムにどのページを閲覧しているか確認できる。

コンタクト詳細 → アクティビティ → 「ページビュー」でフィルタリング
📊
⑤ 以後の行動がすべてCRMに蓄積される

ページビュー・フォーム再送信・メールのリンクのクリック・スコア加算・ワークフロートリガーが連鎖的に機能する。「このコンタクトが今日料金ページを3回見た」等の情報が営業に通知できる。

ワークフロートリガー:「価格ページを閲覧した」→ 担当営業に通知

HubSpot CMS での自動設置 vs 外部 CMS での手動設置

HubSpot CMS外部CMS(WordPress等)
トラッキングコードの設置 {{ standard_header_includes }} タグで自動挿入。追加作業不要。 手動で </body> 直前にJSコードを貼り付けるか、GTMで管理する。
Cookieの管理 自動。GDPR設定をONにするとCookie同意バナーも自動表示。 別途CookieプラグインとHubSpotのGDPR設定を合わせて管理が必要。
既知コンタクトの判定 自動。{{ request.contact_id }} でHubLから参照可能。 不可(サーバーサイドでの判定はAPI経由のみ)。
HubSpot CMS — テンプレートのベース構造(トラッキング自動設置)
<!-- base_template.html — すべてのページテンプレートが継承するベース -->
<html>
<head>
  <!-- ▼ トラッキングコード・CSSを自動挿入(HubSpot管理)-->
  {{ standard_header_includes }}
</head>
<body>
  {% block body %}{% endblock %}

  <!-- ▼ HubSpotトラッキングコード本体を自動挿入 -->
  {{ standard_footer_includes }}
</body>
</html>
外部CMS(WordPress等)— GTM 経由でのトラッキングコード設置
// Google Tag Manager に HubSpot トラッキングコードを追加する方法
// タグ:カスタムHTMLタグ / トリガー:全ページ

// 設置コード(HubSpot管理画面 → ⚙️設定 → トラッキングとアナリティクス → トラッキングコード からコピー)
<script type="text/javascript" id="hs-script-loader"
  async defer
  src="//js.hs-scripts.com/YOUR_HUB_ID.js">
</script>

// ▼ フォーム送信時に hubspotutk を取得して外部フォームに渡す方法
function getHubspotCookie() {
  const cookies = document.cookie.split(';');
  for (const c of cookies) {
    const [key, val] = c.trim().split('=');
    if (key === 'hubspotutk') return val;
  }
  return '';
}
// → フォームの hidden フィールド hutk にこの値をセットして送信

Section 7-2

スマートコンテンツの実装 — ライフサイクル・デバイス・地域での出し分け

スマートコンテンツとは、訪問者の属性に応じてページのコンテンツを動的に切り替える機能です。 「まだ購入していない人にはCTAを表示、既存顧客にはサポートリンクを表示」といった パーソナライズが、コードなしで(またはHubLで)実現できます。

スマートコンテンツの出し分け条件

👤 ライフサイクルステージ

  • Subscriber → ブログ購読者向けコンテンツ
  • Lead → リード向けオファーCTA
  • MQL → デモ申込CTAを強調
  • Customer → 「製品をもっと活用しよう」

📋 コンタクトリスト

  • 特定リストに入っている訪問者に別CTAを表示
  • 「既にダウンロード済みの人」への表示制御
  • VIPリスト向けの特別コンテンツ表示

🌍 国・地域

  • 日本語 vs 英語のコンテンツ切り替え
  • 地域ごとの問い合わせ先電話番号の切り替え
  • 地域別価格・通貨の表示

📱 デバイスタイプ

  • モバイル向けに簡略化したCTAを表示
  • スマホでは電話CTAを、PCではフォームを表示
  • デバイス別のレイアウト最適化

🔗 参照元(リファラー)

  • Google広告経由の訪問者に専用LPを表示
  • SNS流入者向けのメッセージ変更
  • 特定ドメインからの訪問者への特別対応

⚙️ クエリパラメータ

  • URLパラメータ(?plan=pro等)で表示を切り替え
  • メール内のリンクから来た訪問者への出し分け
  • A/Bテストと組み合わせた表示制御

HubL によるスマートコンテンツ実装

HubL — ライフサイクルステージによるCTAの出し分け
{# ライフサイクルステージによってCTAを切り替える実装例 #}

{% set lc_stage = contact.lifecyclestage %}

{% if lc_stage == "customer" %}
  <!-- 既存顧客には「サポートページへ」を表示 -->
  <div class="cta cta--support">
    <p>いつもご利用いただきありがとうございます。</p>
    <a href="/support" class="btn btn--green">サポートページへ</a>
  </div>

{% elif lc_stage == "marketingqualifiedlead"
        or lc_stage == "salesqualifiedlead" %}
  <!-- MQL/SQLには「デモを申し込む」を強調表示 -->
  <div class="cta cta--demo cta--prominent">
    <p>製品についてご興味をお持ちの方へ</p>
    <a href="/demo" class="btn btn--orange">無料デモを申し込む</a>
  </div>

{% elif lc_stage == "lead" %}
  <!-- Leadには「資料ダウンロード」を表示 -->
  <div class="cta cta--download">
    <a href="/resources/guide" class="btn btn--blue">導入ガイドをダウンロード</a>
  </div>

{% else %}
  <!-- 未知の訪問者・Subscriberには汎用CTAを表示 -->
  <div class="cta cta--default">
    <a href="/contact" class="btn btn--primary">まずは相談してみる</a>
  </div>
{% endif %}
HubL — デバイスタイプと国コードの複合条件
{# デバイスと国でコンテンツを切り替える実装例 #}

{% set is_mobile = request.is_mobile %}
{% set country   = request.geoip_country_code %}

{# モバイル訪問者向け:電話CTAを最優先 #}
{% if is_mobile %}
  <a href="tel:0120-XXX-XXX" class="btn btn--tel">
    📞 今すぐ電話で相談する(無料)
  </a>

{# 日本以外からの訪問者:英語CTAを表示 #}
{% elif country != "JP" %}
  <a href="/en/contact" class="btn btn--en">
    Contact us in English
  </a>

{% else %}
  {# 日本・PCのデフォルト #}
  <a href="/contact" class="btn btn--default">
    お問い合わせ
  </a>
{% endif %}

Section 7-3

パーソナライズトークンの CMS 実装 — HubL での動的コンテンツ

第4章ではメール内でのパーソナライズトークンを学びましたが、 HubSpot CMS のページテンプレートでも同様の動的コンテンツを実装できます。 ログインしている既知コンタクト専用のパーソナライズされたページが作れます。

HubL — コンタクトプロパティを使ったページのパーソナライズ
{# ========================================================
   コンタクトが判明している場合のパーソナライズ実装
   request.contact_id が空でなければ既知コンタクト
   ======================================================== #}

{% if request.contact_id %}

  {# コンタクトのプロパティを取得 #}
  {% set fname   = contact.firstname     | default("ゲスト") %}
  {% set company = contact.company       | default("貴社") %}
  {% set stage   = contact.lifecyclestage | default("subscriber") %}
  {% set score   = contact.hubspotscore   | default(0) %}

  <!-- パーソナライズされたヘッダー -->
  <section class="hero hero--personalized">
    <h1>{{ fname }}様、おかえりなさい</h1>
    <p>{{ company }}向けの最新コンテンツをご用意しました。</p>
  </section>

  {# リードスコアに基づくコンテンツ推薦 #}
  {% if score >= 50 %}
    <div class="recommendation recommendation--hot">
      <p>⚡ {{ fname }}様は現在ホットリードです</p>
      <a href="/demo-booking">今すぐ専門担当者と話す</a>
    </div>
  {% endif %}

{% else %}
  <!-- 未識別の匿名訪問者向けデフォルト表示 -->
  <section class="hero hero--default">
    <h1>業務効率を劇的に改善するCRMツール</h1>
    <a href="/contact">無料で試してみる</a>
  </section>
{% endif %}
✅ HubL で参照できる主要な request / contact 変数

コンタクト情報:contact.firstname / contact.lastname / contact.company / contact.lifecyclestage / contact.hubspotscore / contact.email

リクエスト情報:request.contact_id(既知コンタクトか判定)/ request.is_mobile / request.geoip_country_code / request.path / request.query_dict.xxx(クエリパラメータ取得)


Section 7-4

HubSpot Forms の外部 CMS 埋め込み(WordPress・React/Next.js)

HubSpot CMS 以外で構築したサイト(WordPress・Next.js・Nuxt.js等)にも、 HubSpot フォームを埋め込んでCRMにデータを送ることができます。 埋め込み方法は用途に応じて3パターンあります。

パターン① 標準 JS 埋め込み(最もシンプル)

HTML/WordPress — hbspt.forms.create() による標準埋め込み
<!-- 1. フォームを表示したい場所にターゲット要素を設置 -->
<div id="hubspot-form-container"></div>

<!-- 2. HubSpot Forms JS ライブラリを読み込む -->
<script charset="utf-8"
  type="text/javascript"
  src="//js.hsforms.net/forms/embed/v2.js">
</script>

<!-- 3. フォームを生成 -->
<script>
  hbspt.forms.create({
    // ポータルID:HubSpot管理画面のURLから確認(例: app.hubspot.com/contacts/XXXXX)
    portalId  : "YOUR_PORTAL_ID",
    // フォームID:フォームエディターのURLから確認
    formId    : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    // フォームをレンダリングするDOM要素のセレクタ
    target    : "#hubspot-form-container",
    // ▼ 主要コールバック
    onFormReady: function($form) {
      // フォームがDOMに挿入された後に実行
      // hidden フィールドへのUTM値の注入はここで行う
      const params = new URLSearchParams(window.location.search);
      ['utm_source','utm_medium','utm_campaign'].forEach(key => {
        if (params.get(key))
          $form.find(`input[name="${key}"]`).val(params.get(key));
      });
    },
    onFormSubmit: function($form) {
      // 送信ボタンが押された直後(送信完了前)に実行
      console.log('フォームが送信されました');
    },
    onFormSubmitted: function($form, data) {
      // 送信完了後に実行 → GA4 / Google広告のコンバージョンタグをここで発火
      if (typeof gtag !== 'undefined') {
        gtag('event', 'conversion', { send_to: 'AW-XXXXXXXX/YYYYYYYY' });
      }
      // サンクスページへリダイレクト(フォーム設定のリダイレクトより優先)
      window.location.href = '/thanks';
    }
  });
</script>

パターン② React / Next.js への組み込み

React — HubSpotForm カスタムコンポーネント
// components/HubSpotForm.tsx
import { useEffect, useRef } from 'react';

interface Props {
  portalId : string;
  formId   : string;
  onSubmitted?: () => void;
}

declare global {
  interface Window { hbspt: any; }
}

export default function HubSpotForm({ portalId, formId, onSubmitted }: Props) {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    // HubSpot Forms JS の動的読み込み
    const script = document.createElement('script');
    script.src  = 'https://js.hsforms.net/forms/embed/v2.js';
    script.async = true;
    script.onload = () => {
      if (window.hbspt && ref.current) {
        window.hbspt.forms.create({
          portalId,
          formId,
          target : `#hs-form-${formId}`,
          onFormSubmitted: () => onSubmitted?.()
        });
      }
    };
    document.head.appendChild(script);
    // クリーンアップ:コンポーネントアンマウント時にスクリプトを削除
    return () => { document.head.removeChild(script); };
  }, [portalId, formId]);

  return <div ref={ref} id={`hs-form-${formId}`} />;
}

// 使い方
// <HubSpotForm
//   portalId="12345"
//   formId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
//   onSubmitted={() => router.push('/thanks')}
// />

Section 7-5

HubSpot API の基礎 — Contacts / Forms / Properties API

HubSpot API を使うと、外部システムから直接CRMのデータを読み書きできます。 バックエンドでのデータ同期・カスタム連携・CI/CDパイプラインでの自動化に不可欠です。

認証:Private App Token(推奨)

⚠️ 旧APIキー方式は廃止済み — Private App Token を使う

2022年11月以降、従来のHubSpot APIキー(hapikey)は廃止されました。 現在は「プライベートアプリトークン(Private App Access Token)」を使います。
発行場所:⚙️設定 → インテグレーション → プライベートアプリ → 「プライベートアプリを作成」
スコープ(権限)を必要最小限に設定してから発行し、トークンは環境変数で管理してください。

主要 API エンドポイント

GET /crm/v3/objects/contacts?limit=10&properties=email,firstname,lifecyclestage コンタクト一覧の取得
GET /crm/v3/objects/contacts/{contactId} 特定コンタクトの取得
POST /crm/v3/objects/contacts コンタクトの新規作成
PATCH /crm/v3/objects/contacts/{contactId} コンタクトプロパティの更新
POST /crm/v3/objects/contacts/search 条件によるコンタクト検索(メールアドレス等)
POST /submissions/v3/submissions/forms/{formGuid} フォーム送信データをAPIで直接送信
GET /crm/v3/properties/contacts コンタクトの全プロパティ定義を取得
POST /crm/v3/objects/deals 取引(Deal)の新規作成

実装例:Node.js でのコンタクト作成・更新

Node.js (TypeScript) — コンタクトの upsert(作成 or 更新)
// hubspot-client.ts
// npm install @hubspot/api-client
import { Client } from '@hubspot/api-client';

const hubspotClient = new Client({
  accessToken: process.env.HUBSPOT_PRIVATE_TOKEN!
});

/**
 * メールアドレスでコンタクトを検索し、存在すれば更新、なければ作成する
 * (Upsert パターン)
 */
export async function upsertContact(data: {
  email     : string;
  firstname?: string;
  lastname? : string;
  company?  : string;
  [key: string]: string | undefined;
}) {
  // ① メールアドレスで既存コンタクトを検索
  const searchRes = await hubspotClient.crm.contacts.searchApi.doSearch({
    filterGroups: [{
      filters: [{
        propertyName: 'email',
        operator    : 'EQ',
        value       : data.email
      }]
    }],
    properties: ['email', 'firstname', 'lifecyclestage'],
    limit     : 1
  });

  const properties = Object.fromEntries(
    Object.entries(data).filter(([_, v]) => v !== undefined)
  ) as Record<string, string>;

  if (searchRes.total > 0) {
    // ② 既存コンタクトがいれば更新(PATCH)
    const contactId = searchRes.results[0].id;
    return hubspotClient.crm.contacts.basicApi.update(contactId, { properties });
  } else {
    // ③ 存在しなければ新規作成(POST)
    return hubspotClient.crm.contacts.basicApi.create({ properties });
  }
}

// 使い方例
await upsertContact({
  email    : 'yamada@abc-corp.co.jp',
  firstname: '太郎',
  lastname : '山田',
  company  : '株式会社ABC',
  hs_lead_status: 'NEW'   // カスタムプロパティも渡せる
});

Section 7-6

Webhook の設計 — HubSpot から外部システムへのリアルタイム通知

Webhook とは「HubSpot内でイベントが発生した瞬間に、 指定したURLにPOSTリクエストを自動送信する」仕組みです。 ポーリング(定期的なAPI呼び出し)なしでリアルタイム連携が実現できます。

Webhook のデータフロー

🟠
HubSpot
CRM内でイベントが発生
トリガーイベント
コンタクト作成・プロパティ変更・取引ステージ変更等
📡
HTTPS POST
JSON ペイロードを登録URLに即時送信
🖥️
外部サーバー
Node.js / Python / Cloudflare Workers 等
🔧
自動アクション
Slack通知 / DB更新 / 外部API呼び出し

Webhook 受信サーバーの実装例

Node.js (Express) — HubSpot Webhook の受信と署名検証
// webhook-server.ts
// npm install express crypto
import express from 'express';
import crypto  from 'crypto';

const app = express();
app.use(express.json());

/**
 * HubSpot Webhook の署名を検証する(セキュリティ必須)
 * 設定場所:HubSpot → ⚙️設定 → インテグレーション → プライベートアプリ → Webhook
 */
function verifyHubSpotSignature(
  req: express.Request,
  clientSecret: string
): boolean {
  const signature  = req.headers['x-hubspot-signature-v3'] as string;
  const timestamp  = req.headers['x-hubspot-request-timestamp'] as string;
  const bodyStr    = JSON.stringify(req.body);
  const sourceStr  = `POST${req.protocol}://${req.hostname}${req.path}${bodyStr}${timestamp}`;
  const expected   = crypto
    .createHmac('sha256', clientSecret)
    .update(sourceStr)
    .digest('base64');
  return crypto.timingSafeEqual(
    Buffer.from(signature), Buffer.from(expected)
  );
}

// ▼ Webhook 受信エンドポイント
app.post('/webhooks/hubspot', (req, res) => {

  // 1. 署名検証(改ざん防止)
  if (!verifyHubSpotSignature(req, process.env.HS_CLIENT_SECRET!)) {
    return res.status(401).send('Invalid signature');
  }

  // 2. ペイロードを処理(配列でイベントが届く)
  const events: any[] = req.body;

  for (const event of events) {
    console.log(`イベント: ${event.subscriptionType}`);

    switch (event.subscriptionType) {

      case 'contact.creation':
        // 新規コンタクト作成 → Slack通知
        notifySlack(`新規リード: contactId=${event.objectId}`);
        break;

      case 'contact.propertyChange':
        if (event.propertyName === 'lifecyclestage'
            && event.propertyValue === 'customer') {
          // 成約 → 社内DBのステータスを即時更新
          updateInternalDB(event.objectId, 'customer');
        }
        break;

      case 'deal.propertyChange':
        if (event.propertyName === 'dealstage'
            && event.propertyValue === 'closedwon') {
          // 成約 → 請求システムに自動連携
          triggerBillingSystem(event.objectId);
        }
        break;
    }
  }

  // 3. 必ず 200 を返す(HubSpotが再送しないよう)
  res.sendStatus(200);
});
購読できる主要イベント説明
contact.creation新規コンタクトが作成された時
contact.deletionコンタクトが削除された時
contact.propertyChangeコンタクトのプロパティが変更された時(どのプロパティかも指定可)
deal.creation新規取引が作成された時
deal.propertyChange取引のプロパティが変更された時(ステージ変更の検知に使う)
company.propertyChange会社プロパティが変更された時

Section 7-7

外部サービス連携パターン — Zapier / Make / Native / API 直接

HubSpotを外部サービスと連携する方法は4つのパターンがあります。 開発工数・リアルタイム性・柔軟性のトレードオフを理解して最適な方法を選びます。

⚡ Zapier(ノーコード)

GUIでHubSpotと他サービスをつなぐ最もシンプルな方法。6,000以上のアプリと接続できる。

向いているケース:開発リソースがない / 急ぎで繋ぎたい / 比較的シンプルなデータ連携
代表的な使い方:HubSpotフォーム送信 → Googleスプレッドシートに追記 / HubSpot成約 → Slackに通知 / 名刺スキャンアプリ → HubSpotコンタクト作成

🔧 Make(旧Integromat)

Zapierより高度な条件分岐・ループ・データ変換が可能なノーコード/ローコード連携ツール。

向いているケース:複雑な条件分岐がある / Zapierより安くしたい / JSON変換が必要
代表的な使い方:Shopify注文 → HubSpot取引自動作成 / Typeform回答 → HubSpotプロパティ更新 / HubSpot → Airtableの双方向同期

🟢 ネイティブインテグレーション

HubSpotが公式に提供している専用の連携機能。設定が最も簡単で安定している。

主要な対応サービス:Slack / Gmail / Outlook / Google広告 / Facebook広告 / Salesforce / Zoom / Stripe / Shopify / WordPress
確認場所:⚙️設定 → インテグレーション → App Marketplace

🔵 API 直接実装

HubSpot API を直接呼び出すカスタム実装。最も柔軟で、Zapier/Makeでは難しい複雑な処理が可能。

向いているケース:リアルタイム性が必要 / 独自のビジネスロジックがある / 大量データの同期
代表的な使い方:自社基幹システム ↔ HubSpot 双方向同期 / Webhook受信で即時処理 / バッチ処理での一括インポート

連携方法の選択フローチャート

連携方法の選択基準
Q1: 接続したいサービスはHubSpotの公式インテグレーションにあるか?
YES → ネイティブインテグレーションを使う(最もシンプル・安定)

Q2: 開発リソースがなく、できるだけすぐ繋ぎたいか?
YES → Zapier または Make(ノーコード)
       データ変換が不要でシンプル → Zapier
       条件分岐・ループが必要    → Make

Q3: リアルタイム性(数秒以内の反応)が必要か?
YES → Webhook + 自前サーバー(API直接実装)
       ※ ZapierやMakeは数分〜数十分の遅延が発生することがある

Q4: 独自のビジネスロジック・大量データ処理が必要か?
YES → API直接実装(@hubspot/api-client 使用推奨)
       バッチ処理 → 定期実行のCronジョブ
       イベント駆動 → Webhook受信サーバー

Q5: コストを最小限にしたいか?
YES → Zapierは有料プランが高い → Make(より安価)またはAPI直接実装

代表的な連携パターン × 推奨方法

連携したいこと推奨方法実装難易度
HubSpot成約 → Slackに通知 ネイティブ連携(Slack公式) or Zapier ⭐(設定5分)
Shopify注文 → HubSpot取引作成 ネイティブ連携(Shopify公式) ⭐⭐(設定30分)
Typeformアンケート → HubSpotプロパティ更新 Zapier / Make ⭐⭐(設定1時間)
自社基幹システム ↔ HubSpot 双方向同期 API直接実装 + Webhook ⭐⭐⭐⭐(開発2〜5日)
Next.js サイトのフォーム → HubSpot CRM Forms API または Forms JS SDK ⭐⭐(開発2〜4時間)
HubSpot成約 → 請求書自動発行(freee / MF等) Webhook + API直接実装 ⭐⭐⭐(開発1〜3日)
✅ CMS↔CRM 連携実装チェックリスト

□ HubSpot トラッキングコードがすべてのページに設置されているか
□ フォームの hidden フィールドに hubspotutk が渡されているか(外部CMSの場合)
□ スマートコンテンツでライフサイクルステージ別の表示が設計されているか
□ パーソナライズトークンにすべてデフォルト値が設定されているか
□ API認証は Private App Token で行い、環境変数で管理しているか(APIキーは廃止済み)
□ Webhook受信サーバーで署名検証(x-hubspot-signature-v3)を実装しているか
□ Webhook受信後に必ず 200 を返しているか(返さないとHubSpotが再送し続ける)
□ 外部連携で障害が起きた場合のリトライ・エラーログの仕組みがあるか


Section 7-8

第7章まとめ

📌 この章で押さえるべきポイント

hubspotutk が「匿名→既知」の鍵

トラッキングコードがCookieを発行し、フォーム送信時にメールと紐付く。HubSpot CMSでは自動設置、外部CMSでは手動設置が必要。フォームに hutk を渡す実装を忘れない。

スマートコンテンツで CVR を底上げする

ライフサイクルステージ / リスト / デバイス / 国 / 参照元の5条件でコンテンツを出し分けられる。HubLの {% if contact.lifecyclestage == "customer" %} パターンを使い回す。

React/Next.js には HubSpotForm コンポーネントを作る

hbspt.forms.create() を useEffect でラップした再利用可能なコンポーネントを作成する。onFormSubmitted コールバックで GA4 のコンバージョンタグも同時発火させる。

API認証は必ず Private App Token

旧来のAPIキー(hapikey)は2022年廃止。Private App Tokenをスコープ最小限で発行し、環境変数(.env)で管理する。コードに直書きは絶対NG。

Webhook は署名検証が必須

x-hubspot-signature-v3 ヘッダーをHMAC-SHA256で検証しないと、第三者からの偽リクエストを処理してしまう。受信後は必ず 200 を返す(返さないと無限再送が発生する)。

連携方法はコストと複雑さで使い分ける

公式連携あり→ネイティブ。開発リソースなし→Zapier/Make。リアルタイム必須→Webhook+API直接。独自ロジック→API直接実装。無闇にZapierを使わず、まず公式連携を確認する。

お疲れさまでした!

章一覧に戻る
← 章一覧へ