SalesforceからHubSpot APIをコールしてみた

2022.09.07

はじめに

SalesforceとHubSpotのデータ連携の検証として、HubSpot APIをコールするApexクラスを作成してSalesforceからHubSpotのレコードを作成、参照してみました。

HubSpotの設定

HubSpot APIにアクセスする為には非公開アプリを作成してアクセストークンを発行する必要があります。

アクセストークンの発行

設定 > アカウントのセットアップ > 連携から非公開アプリを表示します。 非公開アプリの画面 非公開アプリを作成をクリックして基本情報を入力します。 非公開アプリ登録の基本情報の画面 スコープではHubSpotのオブジェクトに対する権限を設定します。
今回はコンタクトの作成と参照がしたいのでcrm.objects.contactsに対する読み取りと書き込みにチェックをつけ、アプリを作成をクリックします。
スコープの設定 アクセストークンが発行されるので、トークンを表示しコピーしておきます。
アクセストークンの表示 このアクセストークンが外部に漏れるとHubSpotアカウントに対するAPIアクセスが可能になってしまいます。取り扱いには十分に注意してください。

Salesforceの設定

Apexから外部サイトを呼び出すにはリモートサイトの設定にサイトを登録しておく必要があります。

リモートサイトの設定

設定 > セキュリティ > リモートサイトの設定から新規リモートサイトを作成します。
リモートサイト名に任意の名前を、リモートサイトのURLにhttps://api.hubapi.comを入力し保存します。 リモートサイトの登録

Apexクラスの作成

HubSpotのAPIをコールするApexクラスを作成します。

コンタクトの作成

HttpRequestクラスを使い、メソッドにPOSTを、エンドポイントにhttps://api.hubapi.com/crm/v3/objects/contactsを指定します。
エンドポイントに指定する値はHubSpot APIドキュメントを参照してください。
認証はAutorizationヘッダーにBearer アクセストークンの形式で、先ほどコピーしたHubSpotの非公開アプリのアクセストークンを指定します。
ボディにはJSON形式で各プロパティの値を指定します。

public static void createContact(){

    HttpRequest req = new HttpRequest();
    req.setMethod('POST');
    req.setEndpoint('https://api.hubapi.com/crm/v3/objects/contacts');

    String accessToken = 'pat-na1-11284**-****-****-****-************';
    String authorizationHeader = 'Bearer ' + accessToken;
    req.setHeader('Authorization', authorizationHeader);
    req.setHeader('content-type', 'application/json');

    JSONGenerator gen = JSON.createGenerator(true);
    gen.writeStartObject();
    gen.writeFieldName('properties');
    gen.writeStartObject();
    gen.writeStringField('company', 'クラスメソッド株式会社');
    gen.writeStringField('email', 'yamada.tarou@example.com');
    gen.writeStringField('firstname', '山田');
    gen.writeStringField('lastname', '太郎');
    gen.writeEndObject();
    gen.writeEndObject();
    req.setBody(gen.getAsString());

    Http http = new Http();
    HTTPResponse res = http.send(req);
    System.debug(res.getBody());
}

実行してレコードの作成に成功すると、作成されたレコードの内容がレスポンスとして返ってきます。

{
  "id": "251",
  "properties": {
    "company": "クラスメソッド株式会社",
    "createdate": "2022-09-06T23:36:28.047Z",
    "email": "yamada.tarou@example.com",
    "firstname": "太郎",
    "hs_all_contact_vids": "251",
    "hs_email_domain": "example.com",
    "hs_is_contact": "true",
    "hs_is_unworked": "true",
    "hs_object_id": "251",
    "hs_pipeline": "contacts-lifecycle-pipeline",
    "lastmodifieddate": "2022-09-06T23:36:28.047Z",
    "lastname": "山田"
  },
  "createdAt": "2022-09-06T23:36:28.047Z",
  "updatedAt": "2022-09-06T23:36:28.047Z",
  "archived": false
}

コンタクトの参照

GETメソッドを使い、コンタクトを参照します。
認証はコンタクト作成時と同様に指定します。
作成したコンタクトのIDをエンドポイントの末尾に追加して参照するレコードを指定します。

public static void readContact(){

    HttpRequest req = new HttpRequest();
    req.setMethod('GET');

    String contactId = '251';
    req.setEndpoint('https://api.hubapi.com/crm/v3/objects/contacts' + '/' + contactId);

    String accessToken = 'pat-na1-11284**-****-****-****-************';
    String authorizationHeader = 'Bearer ' + accessToken;
    req.setHeader('Authorization', authorizationHeader);

    Http http = new Http();
    HTTPResponse res = http.send(req);
    System.debug(res.getBody());
}

実行するとレコードの内容がレスポンスとして返ってきます。

{
  "id": "251",
  "properties":{
    "createdate": "2022-09-06T23:36:28.047Z",
    "email": "yamada.tarou@example.com",
    "firstname": "太郎",
    "hs_object_id": "251",
    "lastmodifieddate": "2022-09-06T23:39:52.638Z",
    "lastname": "山田"
  },
  "createdAt": "2022-09-06T23:36:28.047Z",
  "updatedAt": "2022-09-06T23:39:52.638Z",
  "archived": false
}

最後に

HubSpotにあるSalesforceアプリを使うことによって、HubSpotとSalesforceのデータの同期は可能ですが、例えばSalesforceの商談フェーズが受注になった時だけHubSpotの取引を更新したいといった細かい制御を行いたい場合は、ApexトリガーからHubSpot APIをコールするなどの方法でデータ連携を行うのが良さそうかなと思いました。

参考

Salesforce リモートサイトの設定
HubSpot APIドキュメント