Setup: Pardot (3rd Party services I'm using) requires you to request an API_Key by submitting your email, password, and user_key so that you can then use the api_key with the user_key to do any API calls. At the moment I have a Pardot class like this.
public class Pardot {
public static void createProspectsByLead (Lead[] leads){
String api_key = getAPIKey();
// More HttpGetRequest using pardot api endpoint (https://pi.pardot.com/api/) with user_key + api_key body parameters
}
public static String getAPIKey (){
/* Found out my credentials were correct but I needed to urlEncode them */
String Connector_Email = EncodingUtil.urlEncode(Globals.get('Pardot Connector Email', 'Value__c'), 'UTF-8');
String Connector_Password = EncodingUtil.urlEncode(Globals.get('Pardot Connector Password', 'Value__c'), 'UTF-8');
String Connector_User_Key = EncodingUtil.urlEncode(Globals.get('Pardot User Key', 'Value__c'), 'UTF-8');
String body = 'email='+Connector_Email
+'&password='+Connector_Password
+'&user_key='+Connector_User_Key;
String url = 'https://pi.pardot.com/api/login/version/3?'+body;
System.debug(body);
/* Request API Key */
String api_response = HttpGetRequest(url, body);
/* Generate the HTTP response as an XML stream */
XmlStreamReader reader = api_response.getXmlStreamReader(); // Need to figure this out next
// return String API_Key;
}
/* HERE COMES THE PROBLEM */
@future (callout=true) // future method needed to run callouts from Triggers
static void HttpGetRequest(String url, String body){
/* Instantiate a new http object */
Http h = new Http();
/* Instantiate a new HTTP request, specify the method (GET) as well as the endpoint */
HttpRequest req = new HttpRequest();
req.setEndpoint(url);
req.setMethod('POST');
req.setBody(body);
req.setCompressed(true);
/* Try to send the request */
try {
HttpResponse res = h.send(req);
System.debug(res.getBody());
// I want to now return 'res' but I can't
} catch(System.CalloutException e) {
System.debug('ERROR: '+ e);
}
}
}
The Problems
- @future can only return void: As you can see from the code above, I expected with each API call to request the API_Key and then return that key to my method so that I could use it as necessary. But since httpRequest need to be made with @future and it can only return void there is no way to pass api_key directly. I imagine from here I would attempt to store this in my Global__c object in a text field but then I also need to add a timestamp since Pardot only allows that API key for 1 hour.
Handling the Response: I was able to get a response in the debug output but I'm not sure how to handle the response to parse out the API key specifically. Here is the response:
<?xml version="1.0" encoding="UTF-8"?> <rsp stat="ok" version="1.0"> <api_key>6d800bfaab63274b1b908dacd8544936</api_key> </rsp>
This is all part of my first APEX project and has become quite the task to get to this point including other questions I've already posted:
- HttpResponse StatusCode=200, but 3rd party request (Pardot) not made
- Creating a Custom Object Handler Class
Really appreciate even some resource that outline the exact process of what I'm attempting because I would think its a common process using 3rd party web services, but up till now I'm having trouble finding any simple working examples. Also I'm completely open to suggestion for better approaches to something like this. Thank you so much in advance for any help you can provide.
Follow Up Question posted here: Verify getChildElement() is not null
Global__c
object that I queried from a Globals class at the time. The most secure option (of 3) I believe was to store that detail in a Custom Setting of a managed package, but at the time this was secure enough I believe. Could store in a custom setting within your Org as well, just not the "best/secure" option ;) Also you can review the code I used at that time here: github.com/Xtremefaith/Pardot-API-Example/tree/master/src/…