🟢HubSpot 開発者向け実践教科書 — 2026年版 Developer Edition
Chapter 7  ·  Workflow Extensions & Custom Code Actions

ワークフロー拡張 &
カスタムコードアクション

Custom Code Action(Node.js)・Serverless Functions・Run Agent ステップを活用し、HubSpot ワークフローの自動化をコードで拡張する実践的な実装パターンを学ぶ。

Operations Hub Professional+
Node.js 18 ランタイム
所要時間:約90分
7-1 ワークフロー拡張の全体像

HubSpot ワークフローをコードで拡張する3つの手段を整理する。

機能実行環境主な用途必要プラン
Custom Code Action Node.js(HubSpot 内) 外部 API 呼び出し・データ変換・条件分岐 Ops Hub Pro+
Serverless Functions Node.js(HubSpot 内) HTTP エンドポイント・Webhook 受信・フォーム後処理 CMS Hub Pro+
Run Agent(Breeze) Breeze AI エージェント AI によるデータ分類・要約・スコアリング Ops Hub Pro+
7-2 Custom Code Action の基礎

ワークフロー内で Node.js コードを直接実行し、外部サービスや HubSpot API と連携する。

⚡ Custom Code Action の仕様

ランタイム:Node.js 18.x(npm パッケージは @hubspot/api-client など一部プリインストール済み)
タイムアウト:20秒(超過するとワークフローはエラー扱い)
入力:ワークフローのコンタクト・プロパティ値を event.inputFields で受け取る
出力:callback() でプロパティ値を返し、後続ステップに渡せる

Custom Code Action — 基本構造
// HubSpot の Custom Code Action 実行環境 // event オブジェクトにコンタクト情報が入っている const hubspot = require('@hubspot/api-client'); exports.main = async (event, callback) => { // ── 入力値の取得 ──────────────────── const { email, firstname, hs_object_id: contactId, } = event.inputFields; // ── HubSpot クライアント(シークレット経由) ── const client = new hubspot.Client({ accessToken: process.env.HUBSPOT_ACCESS_TOKEN, }); try { // ── 外部 API 呼び出し例 ───────────── const response = await fetch( `https://api.external-service.com/user?email=${email}`, { headers: { 'Authorization': `Bearer ${process.env.EXTERNAL_API_KEY}` } } ); const data = await response.json(); // ── 出力値を callback で返す ────────── callback({ outputFields: { external_score: String(data.score), external_status: data.status, sync_timestamp: new Date().toISOString(), }, }); } catch (err) { // エラー時は outputFields を空で返す(ワークフローはエラーとして記録) console.error('Custom code error:', err.message); callback({ outputFields: {} }); } };
Custom Code Action — 実践例:Slack に通知する
const https = require('https'); exports.main = async (event, callback) => { const { firstname, lastname, email, dealname, amount } = event.inputFields; const message = { blocks: [ { type: 'section', text: { type: 'mrkdwn', text: `🎉 *新規成約:${dealname}*\n担当者:${firstname} ${lastname} (${email})\n金額:¥${Number(amount).toLocaleString()}`, }, }, ], }; await fetch(process.env.SLACK_WEBHOOK_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(message), }); callback({ outputFields: { slack_notified: 'true' } }); };
Custom Code Action — 実践例:AI でリードスコアリング
exports.main = async (event, callback) => { const { jobtitle, company, num_employees, hs_analytics_source, recent_conversion_event_name } = event.inputFields; // Anthropic Claude API でスコアリング const res = await fetch('https://api.anthropic.com/v1/messages', { method: 'POST', headers: { 'x-api-key': process.env.ANTHROPIC_API_KEY, 'anthropic-version': '2023-06-01', 'content-type': 'application/json', }, body: JSON.stringify({ model: 'claude-haiku-4-5-20251001', max_tokens: 256, messages: [{ role: 'user', content: `以下のリード情報から0〜100のスコアと理由を JSON で返してください。 職種: ${jobtitle}, 会社: ${company}, 従業員数: ${num_employees}, 流入元: ${hs_analytics_source}, コンバージョン: ${recent_conversion_event_name} 形式: {"score": 数値, "reason": "理由"}`, }], }), }); const data = await res.json(); const parsed = JSON.parse(data.content[0].text); callback({ outputFields: { ai_lead_score: String(parsed.score), ai_score_reason: parsed.reason, }, }); };
⚠ シークレット管理: API キーなどの機密情報は、HubSpot の「設定 → プライベートアプリ → シークレット」に登録し、 process.env.SECRET_NAME で参照します。コードに直書きしないでください。
7-3 Serverless Functions

HubSpot ホスト上で動く HTTP エンドポイント。フォーム後処理・Webhook 受信・外部連携に使う。

🌐 Serverless Functions の仕様

エンドポイント:https://your-portal.hs-sites.com/_hcms/api/function-name
ランタイム:Node.js 18.x
タイムアウト:10秒(レスポンスを返す必要がある)
認証:HubSpot Cookie(ログインユーザー)または API キーで保護可能
ファイル:テーマ内の serverless/ フォルダに配置

serverless/contact-lookup.js
const hubspot = require('@hubspot/api-client'); exports.main = async (context, sendResponse) => { const { email } = context.params; if (!email) { return sendResponse({ statusCode: 400, body: { error: 'email is required' }, }); } const client = new hubspot.Client({ accessToken: process.env.HUBSPOT_ACCESS_TOKEN, }); const result = await client.crm.contacts.searchApi.doSearch({ filterGroups: [{ filters: [{ propertyName: 'email', operator: 'EQ', value: email }], }], properties: ['firstname', 'lastname', 'email', 'lifecyclestage'], limit: 1, }); if (result.results.length === 0) { return sendResponse({ statusCode: 404, body: { found: false } }); } sendResponse({ statusCode: 200, body: { found: true, contact: result.results[0].properties }, }); };
serverless.json — 関数の設定ファイル
{ "runtime": "nodejs18.x", "version": "1.0", "secrets": ["HUBSPOT_ACCESS_TOKEN"], "endpoints": { "contact-lookup": { "method": "GET", "file": "contact-lookup.js" }, "form-handler": { "method": "POST", "file": "form-handler.js" } } }
7-4 Run Agent ステップ(Breeze AI 連携)

ワークフロー内で Breeze AI エージェントを呼び出し、コンタクトデータを AI で処理する。

🤖 Run Agent ステップでできること

ワークフローの「Run Agent」ステップでは、Breeze AI エージェントを指定し、コンタクトのプロパティを入力として渡すことができます。 メール文面の自動生成・問い合わせ内容の分類・スコアリング・翻訳・要約などの AI 処理を、ノーコードのワークフローステップとして組み込めます。 処理結果はコンタクトプロパティに書き戻すことも可能です。

💡 Run Agent の典型的なユースケース

リード分類:問い合わせ内容から「製品に興味あり」「サポート案件」「採用問い合わせ」を自動分類
パーソナライズ:コンタクトの属性を元に、営業メールの文面を AI が自動生成
センチメント分析:サポートチケットの感情スコアを算出し、優先度を自動設定
翻訳:多言語の問い合わせを日本語に自動翻訳してプロパティに保存

Custom Code Action との使い分け: Run Agent は設定画面でプロンプトを書くだけで使えるノーコードの AI ステップです。 一方 Custom Code Action は Node.js でロジックを自由に書けます。 シンプルな AI 処理は Run Agent、複雑なロジックや外部 API 組み合わせは Custom Code Action を選択してください。
7-5 この章のまとめ

✅ Chapter 7 チェックリスト

  • Custom Code Action・Serverless Functions・Run Agent の違いと使い分けを理解した
  • Custom Code Action の event.inputFieldscallback(outputFields) の使い方を習得した
  • 外部 API 呼び出し・Slack 通知・AI スコアリングを Custom Code Action で実装できる
  • シークレットを process.env 経由で安全に管理できる
  • Serverless Functions で HTTP エンドポイントを実装できる
  • Run Agent ステップを使った AI 処理の設計ができる
次章(Chapter 8)について:Webhook とイベント駆動設計を学びます。Webhook の署名検証・外部システム連携パターン・べき等処理について解説します。