Releases: Crim/pardot-java-client
v4.0.0 Bugfix Release
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 aString
to support worldwide zipcodes. Thanks @daniel-exceed!
v3.3.0 Feature Release
v3.2.0 Feature Release
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 theConfigurationBuilder.withSsoRefreshTokenLogin()
andConfigurationBuilder.withSsoLogin()
methods.
v3.1.0 Feature Release
3.1.0 (10/23/2020)
- ISSUE-65 Adds missing Query options to
ProspectQuerytRequest
forwithUpdatedAfter()
andwithUpdatedBefore()
.
v3.0.0 Feature Release - Adds support for SSO Authentication
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()
andPardotClient.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
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
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
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
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
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);