2026年7月30日

2026年7月30日

Gravity FormsとHubSpot・SalesforceをZapierなしで直接連携する方法(公式アドオンとAPI実装の選び方)

Gravity Forms の送信内容を HubSpot や Salesforce に渡す方法は、Zapier のような中継サービスを使わなくても2通りあります。公式または定評のあるアドオンで設定する方法と、gform_after_submission フックから各サービスの API へ直接送る方法です。この記事では、どちらを選ぶべきかの判断基準を示したうえで、コードで直接送る場合の HubSpot・Salesforce それぞれの実装例と、送信失敗に備えた作りを説明します。

まず選ぶ:アドオンか、自前の実装か

中継サービスを外したい理由が「月額の費用を減らしたい」「データを第三者のサーバーに通したくない」「遅延をなくしたい」のいずれであっても、最初に検討すべきは既存のアドオンです。

HubSpot については、Gravity Forms の開発元が HubSpot 用の公式アドオンを提供しています。利用できるライセンスの種類は時期によって変わるため、手持ちのライセンスで使えるかは Gravity Forms の公式サイトで確認してください(2026年10月現在)。フォームの項目と HubSpot のコンタクトのプロパティを画面上で対応付けでき、条件付きの送信なども設定できます。Salesforce については、Gravity Forms の公式アドオンの一覧に含まれているかを確認し、無い場合は第三者が提供する連携アドオンを、更新頻度やサポート体制を見て選ぶことになります。

自前の実装が向いているのは、次のような場合です。

  • 送信前に値を加工したい(電話番号の整形、複数項目の結合、社内コードへの変換など)
  • 送信先や送信条件が複雑で、アドオンの設定画面では表現しきれない
  • 使いたい API の機能(特定のオブジェクトへの書き込みなど)にアドオンが対応していない

自前で作る場合は、API の仕様変更への追随、エラー時の再送、認証情報の管理を自分たちで引き受けることになります。この負担を見積もったうえで選んでください。

実装の土台:送信後フックと認証情報の置き場所

Gravity Forms は、エントリー(送信データ)を保存した後に gform_after_submission アクションを呼びます。特定のフォームだけに処理を付けたい場合は、末尾にフォームIDを付けた gform_after_submission_5 のようなフック名を使えます。

認証情報(HubSpot のアクセストークンなど)は、コードやデータベースの公開されうる場所ではなく、wp-config.php の定数か、Web からアクセスできない場所に置いた環境変数から読みます。

<?php
// wp-config.php(値はダミー。実際のトークンはリポジトリに含めない)
define( 'MYSITE_HUBSPOT_PORTAL_ID', 'your-portal-id' );
define( 'MYSITE_HUBSPOT_FORM_GUID', 'your-form-guid' );

もう一つ大切なのが、送信処理をフォームの送信と切り離すことです。gform_after_submission の中で外部 API を呼ぶと、相手の応答が遅いときに訪問者の画面が待たされ、相手が落ちていればデータが渡らないまま終わります。そこで、フックではエントリーIDを WP-Cron の単発イベントに積むだけにし、実際の送信は別のリクエストで行います。

<?php
// フォームID 5 の送信後に、CRM 送信をバックグラウンドに回す
add_action( 'gform_after_submission_5', function ( $entry, $form ) {
	if ( 'spam' === rgar( $entry, 'status' ) ) {
		return; // スパム判定されたエントリーは送らない
	}
	wp_schedule_single_event( time() + 10, 'mysite_send_entry_to_crm', array( (int) $entry['id'] ) );
}, 10, 2 );

WP-Cron はサイトへのアクセスをきっかけに動くため、アクセスが少ないサイトではサーバーの cron から wp-cron.php を定期的に呼ぶ設定にしておくと、送信の遅れを抑えられます。

HubSpotへ送る:フォーム送信APIを使う

HubSpot にコンタクトを作る方法はいくつかありますが、問い合わせフォームの連携では、HubSpot 側にも「フォーム」を作り、そのフォームへの送信として API を呼ぶ方法が扱いやすいです。メールアドレスによる既存コンタクトとの照合や、フォーム送信としての記録(どのページから送られたか)が HubSpot 側で処理されるためです。

<?php
add_action( 'mysite_send_entry_to_crm', function ( $entry_id ) {
	$entry = GFAPI::get_entry( $entry_id );
	if ( is_wp_error( $entry ) ) {
		return;
	}

	// フィールドIDはフォームごとに異なる。管理画面のフォーム編集画面で確認する
	$fields = array(
		array( 'name' => 'email',     'value' => sanitize_email( rgar( $entry, '2' ) ) ),
		array( 'name' => 'lastname',  'value' => sanitize_text_field( rgar( $entry, '1.6' ) ) ),
		array( 'name' => 'firstname', 'value' => sanitize_text_field( rgar( $entry, '1.3' ) ) ),
		array( 'name' => 'company',   'value' => sanitize_text_field( rgar( $entry, '3' ) ) ),
	);

	$url = sprintf(
		'https://api.hsforms.com/submissions/v3/integration/submit/%s/%s',
		rawurlencode( MYSITE_HUBSPOT_PORTAL_ID ),
		rawurlencode( MYSITE_HUBSPOT_FORM_GUID )
	);

	$response = wp_remote_post( $url, array(
		'timeout' => 15,
		'headers' => array( 'Content-Type' => 'application/json' ),
		'body'    => wp_json_encode( array(
			'fields'  => $fields,
			'context' => array(
				'pageUri'  => esc_url_raw( rgar( $entry, 'source_url' ) ),
				'pageName' => get_bloginfo( 'name' ),
			),
		) ),
	) );

	$code = wp_remote_retrieve_response_code( $response );
	if ( is_wp_error( $response ) || $code < 200 || $code >= 300 ) {
		gform_update_meta( $entry_id, 'mysite_crm_status', 'failed:' . ( is_wp_error( $response ) ? $response->get_error_code() : $code ) );
		return;
	}
	gform_update_meta( $entry_id, 'mysite_crm_status', 'sent' );
} );

name に指定するのは HubSpot のプロパティの内部名で、画面上のラベルとは異なる場合があります。HubSpot の設定画面でプロパティの内部名を確認してから書いてください。氏名のような複合フィールドは 1.3(名)、1.6(姓)のように「フィールドID.入力欄の番号」で値を取ります。

HubSpot ではプライバシー同意の扱いをフォーム側で設定でき、同意情報を API で一緒に送る仕組みも用意されています。マーケティングメールの配信に使う場合は、Gravity Forms 側に同意チェックボックスを置き、その値を送るように拡張してください。認証付きのエンドポイントや CRM の API を使う場合のトークンの種類や名称は HubSpot 側で変更が続いているため、HubSpot の開発者向けドキュメントで現行の方式を確認します。

Salesforceへ送る:Web-to-LeadかREST APIか

Salesforce にリードを作る方法は、大きく2つです。

1つ目は Web-to-Lead です。Salesforce の設定画面で生成されるフォームの送信先と組織ID(oid)を使い、サーバー側から同じ形式で POST します。認証の仕組みが不要で始めやすい反面、1日あたりの受付件数に上限があり、送信に失敗しても詳しいエラーが返らないなど、細かい制御には向きません。上限の値は Salesforce の公式ヘルプで確認してください。

2つ目は REST API です。Salesforce 側に接続用のアプリケーション(外部クライアントアプリや接続アプリケーション。名称は時期により異なります)を作り、OAuth 2.0 でアクセストークンを取得してから、リードなどのオブジェクトに書き込みます。重複チェックや任意の項目への書き込み、エラー内容の取得ができる一方、トークンの取得と更新を実装する必要があります。サーバー同士の連携では、利用者のログイン操作を伴わない認可フロー(クライアントクレデンシャルや JWT ベアラー)が使われるのが一般的です。どのフローが自社の組織で許可されているかは、Salesforce の管理者と相談して決めてください。

どちらの方式でも、上の HubSpot の例と同じく、送信処理はバックグラウンドに回し、結果をエントリーのメタに記録する作りが使えます。送信先の関数を差し替えるだけで済むよう、「エントリーからCRM向けの配列を作る関数」と「配列をCRMに送る関数」を分けておくと、両方に送る場合も見通しがよくなります。

失敗に備える:記録・再送・個人情報

連携は「動いているように見えて、実は一部が届いていない」状態が最も厄介です。次の3つを用意しておくと、問題に早く気づけます。

  • 送信結果をエントリーに残す:上の例では gform_update_meta() で sent / failed:コード を記録しています。Gravity Forms の画面で状態を確認したい場合は、エントリーにノートを追加する API を使う方法もあります。
  • 再送の手段を用意する:失敗したエントリーだけを抽出して再度イベントを積む管理用の処理(WP-CLI コマンドや管理画面のボタン)を作っておくと、相手側の障害の後に復旧できます。管理画面に作る場合は nonce と権限チェックを入れます。
  • ログに個人情報を書かない:デバッグのためにリクエスト本文をそのままログに出すと、氏名やメールアドレスがサーバーのログに残ります。記録するのはエントリーIDとステータスコード程度にとどめます。

また、問い合わせ内容を外部の CRM に送ることは、個人データを第三者のサービスに提供することにあたります。プライバシーポリシーに送信先と目的を記載し、フォームの近くにも案内を置いてください。

まとめ

  • 中継サービスを外すなら、まず公式・定評のあるアドオンで要件を満たせるかを確認し、満たせない部分だけを自前で実装する。
  • 自前の実装では gform_after_submission(フォーム別なら _フォームID 付き)から WP-Cron に処理を回し、訪問者の送信を外部 API の応答から切り離す。
  • HubSpot はフォーム送信 API、Salesforce は手軽さなら Web-to-Lead、制御が必要なら OAuth 付きの REST API を選ぶ。
  • 認証情報は wp-config.php の定数や環境変数に置き、送信結果をエントリーに記録して再送できるようにする。
  • 個人データの送信先はプライバシーポリシーに明記し、ログに個人情報を残さない。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲