Skip to content

Releases: Crim/pardot-java-client

v4.0.0 Bugfix Release

03 Jun 00:04
4e91605
Compare
Choose a tag to compare

4.0.0 (06/03/2021)

NOTE: Breaking Change

Out of an abundance of caution, denoting this release as being a breaking change.
The zip field on Account was changed from an Integer type to a String type. If you have
code that references this field, you will need to update your code to reflect this change.

  • PR-78 Account 'zip' property changed from being an Integer type to a String to support worldwide zipcodes. Thanks @daniel-exceed!

v3.3.0 Feature Release

02 May 00:48
0ed368f
Compare
Choose a tag to compare

3.3.0 (05/02/2021)

  • PR-75 Added support for querying and reading Visits. Thanks @dai-00!

Internal Dependency Updates

  • Upgraded Jackson from version 2.11.2 to 2.11.4.

v3.2.0 Feature Release

09 Feb 07:38
0dbf134
Compare
Choose a tag to compare

3.2.0 (02/09/2021)

  • ISSUE-68 Add authentication method for grant_type=authorization_code using previously retrieved refresh_token. See ConfigurationBuilder.withSsoRefreshTokenLogin()
  • ISSUE-70 Adds ability to override the OAuth authentication endpoint when doing SSO authentication. See optional parameter AuthorizationServer on the ConfigurationBuilder.withSsoRefreshTokenLogin() and ConfigurationBuilder.withSsoLogin() methods.

v3.1.0 Feature Release

23 Oct 00:56
8f456a7
Compare
Choose a tag to compare

3.1.0 (10/23/2020)

  • ISSUE-65 Adds missing Query options to ProspectQuerytRequest for withUpdatedAfter() and withUpdatedBefore().

v3.0.0 Feature Release - Adds support for SSO Authentication

21 Sep 01:59
94ea0f1
Compare
Choose a tag to compare

3.0.0 (09/21/2020)

Breaking Changes

This release has several breaking changes. See 3.0.0 Migration Notes for details on breaking changes and how to upgrade.

  • ISSUE-58 Add support for Salesforce SSO authentication.
  • PR-60 Alters return values from PardotClient.readXYZ() and PardotClient.deleteXYZ() to allow for better error handling.

Internal Dependency Updates

  • Upgraded Jackson from version 2.11.1 to 2.11.2.

Pardot Java API Client 2.x.x to 3.0.0 Migration Guide

Breaking Change : Authentication & Configuration

In order to properly support the transition of the Pardot API from authenticating using Pardot username, password, and user keys, to
Salesforce Single Signon, several breaking changes were made to how you configure the Pardot API Client.

Configuration class replaced with ConfigurationBuilder.

Where before you created a Configuration object, that class has now been replaced by ConfigurationBuilder.

Code that may have looked like this previously

final Configuration configuration = new Configuration("YourPardotUserNameHere", "PardotPassword", "UserKey");
final PardotClient client = new PardotClient(configuration);

Should now look like this

final ConfigurationBuilder configuration = Configuration.newBuilder()
    // NOTE: Authenticating using this method will cease to function after ~ Feb. 1 2021.
    //       See section below about migrating to SSO authentication.
    .withUsernameAndPasswordLogin(
        "YourPardotUsername",
        "YourPardotPassword",
        "YourPardotUserKey"
    );

// Call other methods on configuration instance as needed to complete configuration.
final PardotClient client = new PardotClient(configuration);

Pardot Username and Password Authentication Scheme deprecated in favor of Salesforce SSO Authentication.

From February 1, 2021 Pardot is removing the now legacy Pardot Username and Password authentication scheme (Salesforce EOL Notice).

You should switch to configuring authentication using the following method:

final ConfigurationBuilder configuration = Configuration.newBuilder()
    .withSsoLogin(
        "YourSalesforceUsername",
        "YourSalesforcePassword",
        "YourConnectedAppClientId",
        "YourConnectedAppClientSecret",
        "YourPardotBusinessUnitId"
    );
final PardotClient client = new PardotClient(configuration);

See Offical Pardot Developer Documentation and Salesforce OAuth Setup for details on how to obtain the above required properties.

Breaking Change : Read request methods now return Optionals

Previously methods on PardotClient for reading objects (such as PardotClient.readProspect(), PardotClient.readCampaign(), etc...)
either returned the object you wished to retrieve, or threw an InvalidRequestException if the API returned a response stating that the record
could not be found.

This often led to code like:

// Try to lookup prospect by Email.
Prospect myProspect = null;
try {
    myProspect = client.prospectRead(new ProspectReadRequest()
        .selectByEmail("test@prospect.com")
    );
} catch (final InvalidRequestException exception) {
    // Prospect could not be found. Swallow exception.  
}

// Handle prospect if found
if (myProspect != null) {
    ...
}

These methods now return Optional<T>,which means you no longer need to catch and handle InvalidRequestException
when an object is unable to be found in the API. The above example code can be simplified to:

// Check if the Optional is present
final Optional<Prospect> prospectResponse = client.prospectRead(new ProspectReadRequest()
    .selectByEmail("test@prospect.com")
);
if (prospectResponse.isPresent()) {
    final Prospect myProspect = prospectResponse.get()
}

// Or even better by using the methods available on Optional
client.prospectRead(new ProspectReadRequest()
    .selectByEmail('test@prospect.com')
).ifPresent((prospect) -> {
    // Make use of prospect if found
    logger.info("Found prospect: {}", prospect.getEmail());
});

Breaking Change : Delete request methods no longer return boolean

Previously methods on PardotClient for deleting objects (such as PardotClient.deleteProspect(), PardotClient.deleteCampaign(), etc...)
always returned a value of true regardless if the delete request was successful or not. Version 3.0.0 changes the return type for these methods
to a type of Result<Boolean>. The Result object
allows for returning a successful response (value of boolean true) as well as an ErrorResponse
instance if the request was not successful.

The quick way to simply migrate your code:

// Code that looked like the following:
final boolean result = client.userDelete(deleteRequest);
// or
if (client.userDelete(deleteRequest)) {

// Now should look like:
final boolean result = client.userDelete(deleteRequest).isSuccess();
// or
if (client.userDelete(deleteRequest.isSuccess())) {

But this new return type also gives you additional flexibility to handle errors more gracefully:

// Handle success conditions:
client
    .userDelete(deleteRequest)
    .ifSuccess((success) -> logger.info("Successfully deleted user!"));

// Handle error conditions:
client
    .userDelete(deleteRequest)
    .ifError((error -> logger.info("Failed to delete user: {}", error.getMessage())));

// Or handle both cases:
client
    .userDelete(deleteRequest)
    .handle(
        (success) -> {
            logger.info("Successfully deleted user!");
            return true;
        },
        (error) -> {
            logger.info("Error deleting user: {}", error.getMessage());
            return false;
        });

v2.1.0 Feature Release

30 Jul 01:55
4f9b5d7
Compare
Choose a tag to compare

2.1.0 (07/30/2020)

  • ISSUE-56 Adds support for Dynamic Content.

Internal Dependency Updates

  • Upgraded Jackson from version 2.10.2 to 2.11.1.
  • Upgraded HttpComponents Client from version 4.5.11 to 4.5.12.

v2.0.0 Bugfix update - Improve support for Record Multiple Fields

05 Apr 01:19
d8a6495
Compare
Choose a tag to compare

2.0.0 (03/05/2020)

  • ISSUE-50 Improve support for record multiple fields.

Breaking Change

In order to better support record multiple value custom fields, the accessor on Prospect for getCustomFields() has been changed FROM
public Map<String, String> getCustomFields() TO public Map<String, ProspectCustomFieldValue> getCustomFields()

For custom fields which are NOT record multiple value custom fields the accessor public String getCustomField(final String customFieldName) method will continue to return the stored value for the custom field.

For custom fields which ARE record multiple value custom fields the accessor public String getCustomField(final String customFieldName) method will only return the first stored value. You can use the new accessor
public List<String> getCustomFieldValues(final String customFieldName) to get all stored values for record multiple value custom fields.

v1.1.2 Bugfix Release

20 Feb 08:23
73929e5
Compare
Choose a tag to compare

1.1.2 (02/20/2020)

Bugfixes

  • ISSUE-45 Fixed bug preventing the library from auto-renewing a session when it expires.

Internal Dependency Updates

  • Upgraded Jackson from version 2.10.1 to 2.10.2.
  • Upgraded HttpComponents Client from version 4.5.10 to 4.5.11.
  • Upgraded SLF4J from version 1.7.29 to 1.7.30.

v1.1.1 Bugfix Release

06 Jan 22:13
8cba394
Compare
Choose a tag to compare

1.1.1 (01/07/2020)

  • Fixed bug in User create endpoint where setting a new user's role could only be set via a RoleId. Now you can set the role by name or id.

1.1.0

17 Dec 03:27
d665999
Compare
Choose a tag to compare

1.1.0 (12/17/2019)

  • Removed org.apache.logging.log4j dependency, instead relying on the org.slf4j logging interface/facade dependency explicitly.

    • If your project was depending on this transitive dependency you may need to add it to your own project:
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.12.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.12.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.12.1</version>
    </dependency>
    
  • Adds support for additional user end points.

  • Adds RequestInterceptor interface to allow for end-user manipulation of requests prior to being sent over the wire.

  • Adds UserDefinedRequest interface to allow for customizing/defining your own API requests.

    /**
     * Example of defining a Custom API endpoint request.  The methods required to be implemented are
     * defined below with examples.
     *
     * You can make use of the methods defined on the parent 'BaseRequest' class to set request parameter
     * as needed.
     */
    public class MyTestRequest extends UserDefinedRequest<MyTestRequest, MyCustomReturnObject> {
        /**
         * Given the API's response String, this method should parse it into a more easily consumed object.
         * Alternatively, it could just return the API's response string.
         *
         * @return An object that represents the parsed API response.
         */
        @Override
        public ResponseParser<MyCustomReturnObject> getResponseParser() {
            return (apiResponseStringapiResponseString) -> {
                // Your own custom parsing Logic.
                return new MyCustomReturnObject(apiResponseString);
            };
        }

        /**
         * The API endpoint URL string.
         *
         * @return The API endpoint URL string.
         */
        @Override
        public String getApiEndpoint() {
            return "/prospect/query";
        }
       
        /**
         * Set the Id property.
         */ 
        public MyTestRequest withId(final long id) {
            return setParam("id", id);
        } 

        /**
         * Set other property.
         */ 
        public MyTestRequest withOtherProperty(final String value) {
            return setParam("other", value);
        }
    } 
    /**
     * Example usage of the above class:
     */
    PardotClient apiClient = new PardotClient(new Configuration("username", "password", "api-key"));

    // Construct custom request class instance
    MyTestRequest myCustomRequest = new MyTestRequest()
        .withId(123L)
        .withOtherProperty("SomeValue");

    // Execute the request and get the parsed response returned
    MyCustomReturnObject parsedApiResponse = apiClient.userDefinedRequest(myCustomRequest);