tyoshikawa1106のブログ

- Force.com Developer Blog -

SFDC:Apex開発とPardot API - Part 1

Apex開発とPardot APIについてです。

f:id:tyoshikawa1106:20200628121242p:plain

Overview - Pardot API Documentation

Pardot APIの基本的な使い方

Apexでの開発どうこうの前に、Pardot APIへの認証方法からデータの取得まで基本的な使い方がわからなかったのでどうしたものかなと悩んでいたところ、次のブログ記事を見つけて問題が解決しました。


InsomniaというツールをつかってPardot APIによる認証からデータの取得→更新まで開発に必要なAPI処理の使い方について解説がされていました。自分の環境で試してみてPardot API自体が正しく実行できることの動作確認ができました。

Pardot APIを使った機能の再開発の流れ

最終的なゴールはAPIをつかったデータの更新処理でしたが、基本もわからず手探りでそのゴールを目指すのはシンドかったので下記の手順で対処しました。

  1. InsomniaをつかってPardot APIの基本操作を確認
  2. ApexとPardot APIによるデータ取得 ★今回の記事でも使うサンプル機能
  3. ApexとPardot APIによるデータ更新 ★最終的なゴール

サンプルコード

今回の記事で使うサンプルコードです。(classとpageのフォルダにサンプルコードが入っています。)


Pardot APIでPardotキャンペーンの情報を取得してリスト表示するVisualforceページとなります。
f:id:tyoshikawa1106:20200628123511p:plain

はじめに

開発前に下記の2つを用意します。

カスタム設定の用意

認証情報をApexに直接埋め込むとメンテナンス性を下げてしまいます。こうした情報はカスタム設定で管理するべきなので今回もそのように準備します。

f:id:tyoshikawa1106:20200628124429p:plain


登録する認証情報はこんな感じ。カスタム設定の値登録をプロファイルに紐付けて登録しているのを見かけることがありますが、プロファイルごとに登録内容を分ける必要がなければ、組織に紐付けて登録しておく方が利用用途が広がった際に一部のユーザだと動かないというトラブルを回避できて便利だと思います。

f:id:tyoshikawa1106:20200628124643p:plain

リモートサイトの用意

Salesforce内から外部システムのAPIを実行する場合はリモートサイトへの登録が必要となります。
f:id:tyoshikawa1106:20200628124841p:plain


これが登録されてないと次のようなエラーになります。
f:id:tyoshikawa1106:20200628124913p:plain

Apex処理の流れ

PardotAPIによる認証処理とPardotキャンペーンの情報を取得する処理をApexで行うと下記の流れとなります。

  1. カスタム設定からPardot認証情報取得
  2. カスタム設定取得結果でエラー判定★
  3. Pardot認証処理を実行
    • 認証に成功するとAPIキーを取得できます。
    • APIキーの利用期限は1時間です。
  4. API実行時のステータスコードでエラー判定★
  5. API実行結果の値の受け取り。(APIキー取得処理)
    • 結果はXML形式で返ってきます。
    • 値の受け取りはDom.Document型変数などを利用します。
  6. APIキーの値の有無でエラー判定★
  7. Pardotキャンペーンの取得
    1. 認証処理で取得したAPIキーがあればデータの取得処理を実行できます。
  8. API実行時のステータスコードでエラー判定★
  9. API実行結果の値の受け取り。(Pardotキャンペーン取得処理)
    • 結果はXML形式で返ってきます。
    • 値の受け取りはDom.Document型変数などを利用します。


処理としては上記のとおりです。ざっくりまとめると認証→データ取得になりますが実際に開発するときに意識すると結構細かい処理の実装が必要になるはずです。


★のついているのがエラー判定処理です。外部システムとのAPI連携の場合、様々な理由で連携処理が適切に動作しなくなる可能性があるので細かくエラーチェックをしていくのが良いと思います。

Pardot APIの連携失敗で考えられるケース

  1. カスタム設定に保持した認証情報を誤った情報に更新してしまった。
  2. Pardot側に用意された認証用アカウントの情報を別の値に更新してしまった。
    • パスワード変更など
  3. Pardot側の権限周りの設定に変更が発生した。
    • IPアドレスの制限追加など
  4. Salesforce側の権限周りの設定に変更が発生した。
  5. Pardot APIの仕様が変更されて今までの実装方式が使えなくなった。
  6. Apexの仕様が変更されて今までの実装方式が使えなくなった。


ざっくり想定しただけでも上記のケースが考えられます。細かくエラーチェックをすることでトラブル発生時に原因の調査をスムーズに進められるはずです。

Apexでの実装コード

カスタム設定からPardot認証情報取得

カスタム設定の情報はApexの機能として用意されているものをそのまま使って取得できます。
f:id:tyoshikawa1106:20200628133003p:plain


エラーチェックはこんな感じ。
f:id:tyoshikawa1106:20200628133217p:plain

※エラー発生した場合はerrorMessage変数に格納すると画面にメッセージが表示される処理となっています。(これ以降にも共通の挙動となる部分です。)

APIキーの取得

PardotAPiをつかった認証処理です。
f:id:tyoshikawa1106:20200628133316p:plain

f:id:tyoshikawa1106:20200628133441p:plain


認証処理のPOSTは「multipart/form-data」形式で行えば良いことが最初にリンクを貼ったブログ記事で把握することができました。問題はApexクラスでPOSTする際の書き方がわからなかったことですが、これについては過去に別の問題で調査が必要だったときに人に教わっていたのでなんとかなりました。

APIキーの取得結果の格納(ステータスコード)

まずはAPI実行自体がうまく行ったかをステータスコードからチェックします。Apexでは「getStatus」などの処理が用意されているのでそれで取得できます。

f:id:tyoshikawa1106:20200628134147p:plain


ステータスコードのチェック処理は別メソッドに分けておくとテストクラスの開発時に引数を渡してテストできるようになって開発が楽になると思います。

f:id:tyoshikawa1106:20200628134303p:plain

APIキーの取得結果の格納(APIキー)

APIの実行結果はXML形式で返ってきます。ここがやり方がわからなかったところで、手探りの試行錯誤でアレコレ試して動く方法を見つけたという感じの場所です。

f:id:tyoshikawa1106:20200628134813p:plain

f:id:tyoshikawa1106:20200628134915p:plain



手探りといっても流石に開発者ガイドはチェックしながら調査しました。「salesforce apex xml」という感じにそれっぽいキーワードで検索すると対象のページがヒットします。
f:id:tyoshikawa1106:20200628135052p:plain

Pardotキャンペーン取得

取得したAPIキーを使ってPardotのデータを取得する処理を実行できます。取得対象はなんでもよかったのですが、とりあえずの動作確認用であればキャンペーンデータへのアクセスぐらいがちょうど良いかなと選択しました。

f:id:tyoshikawa1106:20200628135311p:plain

f:id:tyoshikawa1106:20200628135350p:plain

Pardotキャンペーンの取得結果判定

認証処理と同じでステータスコードなどのチェックを行います。チェック処理は認証処理の際に使ったものをそのまま適用できると思います。

f:id:tyoshikawa1106:20200628135617p:plain

Pardotキャンペーンの取得結果を変数にセット

APIキーの取得処理ではシンプルなXML結果で取得できましたが、キャンペーンなど複数データの取得はXMLの形式も入れ子になっていたりして複雑になっています。

f:id:tyoshikawa1106:20200628135830p:plain


このXMLの中から対象のリスト情報を取得する部分がさっぱりわからず時間を持っていかれたのですが、最終的に海外のブログ記事で参考になる記事が見つかり下記の処理で値の取得に成功しました。

f:id:tyoshikawa1106:20200628140215p:plain


参考になった海外のブログ

Infallible Techie: Simple REST API for XML response in Salesforce


以上の処理でPardot APIからキャンペーンリストを取得するところまで動作するはずです。

Apexテストクラスの作成

Pardot APIの基本操作を確認するこのサンプル機能の開発ではもう一つチェックしておくべき箇所があります。テストクラスの作成についてです。Apexクラスの開発だけやってテストクラスはやっつけ対応するケースを見かけることがありますが、それをやってしまうと後続の追加開発時に支障が発生します。そういった不要なトラブル回避のため、テストクラスが正しく実装できるかも調査をしました。


Pardot APIの実行といったコールアウト処理を実装する場合のテストクラスですが、「implements HttpCalloutMock」で呼び出すモック処理を用意する必要があります。ただ、今回のように複数のエンドポイントを対象に処理を用意する場合のテスト処理はどう書くのがキレイかなと調べたところ、StackExchangeに良いやり方が紹介されていました。

f:id:tyoshikawa1106:20200628142544p:plain

apex - How to create mock class for multiple Callouts in single class - Salesforce Stack Exchange


意味としては下記のとおり。

  1. テストクラス内のインナークラスとしてHttpCalloutMockクラスを用意する。
  2. Endpointの値をチェックしてif文判定で戻り値を切り替える。


これを参考に実装した結果がこちらです。このやり方でスムーズにテストクラスを実装できました。
f:id:tyoshikawa1106:20200628142835p:plain


また、コールアウトモック処理で返す結果はBodyにセットする形で返すことができます。PardotAPIの処理はXML形式となっているため、テストデータでもXMLの形式にしておく必要があります。このときに普通のString文字列として頑張って用意するケースを見かけることがありますが、Apexに用意されているXmlStreamWriter関数を利用することでメンテナンス性を下げずにXML形式の文字列を用意することが可能です。

f:id:tyoshikawa1106:20200628143250p:plain


以上がApex開発とPardot APIについてです。この方法でApexでのPardot API処理の実装を行えると思います。