0

I am trying to get a token in apex code so that I can save this in a custom object -- This token once retrieved will be further used to access Pardot from Salesforce via apex code.

While running the below class code, I am getting the following error.

I am also attaching Named Credentials and Auth. Provider in screenshot.

I am in a developer sandbox, and trying to get token through the URL specified in the named credential.

ERROR:

caused by: System.UnexpectedException: You don't have permission to view this data. Ask your administrator to set up authentication for the external data source.

enter image description here

enter image description here

enter image description here

CLASS CODE

public class Sf2PardotAuth implements Queueable,Database.AllowsCallouts{
public void execute(QueueableContext context) {


    //Metadata to hold key info.
    PardotAuthFocus__c  creds = [SELECT ConsumerKey__c, ConsumerSecret__c, GrantType__c, Password__c,
                                 Username__c FROM PardotAuthFocus__c];

    SYSTEM.debug('CREDENTIAL LIST::::' + creds);

    String request_body = 'grant_type=' + creds.GrantType__c + '&client_id=' + creds.ConsumerKey__c 
                        + '&client_secret=' + creds.ConsumerSecret__c + '&username=' + creds.Username__c
                        +   '&password=' + creds.Password__c;

    System.debug('REQUEST BODY:::::' +request_body );

    //Declare the Instantiation request variable to send as Http request
    HttpRequest request = new HttpRequest();

    //Formation of HTTP initial request
    request.setBody(request_body);
    request.setMethod('POST');
    request.setHeader('Content-Type', 'application/x-www-form-urlencoded');
    request.setEndpoint('callout:SF2Pardot');

    //Send http request 
    Http http_var = new Http();

    Httpresponse response_rec = http_var.send(request);

    //Check for Successful response
    if(response_rec.getStatusCode() == 200){
        System.debug(response_rec.getBody());
    }


}

}

identigral
  • 7,543
  • 29
  • 32
  • 42
  • You're mixing two different approaches for getting the token: the out of the box no-code approach with Auth Provider versus the Apex-based solution. Choose one. See this Q&A for an almost complete example. – identigral Jan 20 '23 at 20:48
  • @identigral would you able to help me with apex code? And why are we getting stuck? I need to store that token in a custom field so that it can be added to other APIs that will require this token. – user127159 Jan 21 '23 at 21:31
  • Named Credentials with auth provider will store the token for you. This type of question (getting a token from a 3rd party) is frequently asked and answered on here + you have an almost-working example linked in our comment above. – identigral Jan 22 '23 at 17:18
  • @identigral i resolved the issue by not using Named Credential, using the endpoint directly, and it returned a token which I am now able to save without any extra steps. The endpoint did not need to have a callout: Named Credential as I would eventually have to supply username, password and client keys in the HTTP request body anyway. – user127159 Jan 23 '23 at 06:04
  • No, you don't have to supply username or password. That is only true for Client Creds flow which is insecure for a reason. – identigral Jan 23 '23 at 06:06

2 Answers2

0

Based on your screenshots, the Named Credential URL should be https://pi.demo.pardot.com for the URL (using https://pi.pardot.com for Production).

Your class code can effectively be thrown away. We have a github project that demonstrates how you can call the Pardot API here: https://github.com/sercante-llc/pardot-publisher-sfdx

HttpRequest req = new HttpRequest();
req.setHeader('Content-Type', 'application/json');
req.setHeader('Pardot-Business-Unit-Id', '0Uvxxxxxxxxxxx');

req.setEndpoint('callout:'+NAMED_CREDENTIAL+'/v5/objects/prospects/do/upsertLatestByEmail'); req.setMethod('POST'); req.setBody(jsonString);

If it helps, I've written a blog post that goes through all details for setting up the scenario that you are describing here: https://thespotforpardot.com/2021/02/02/pardot-api-and-getting-ready-with-salesforce-sso-users-part-3a-connecting-to-pardot-api-from-apex/ (note that this blog post walks you through the JWT Token OAuth flow, though as I've learned more since the Client Credentials flow MIGHT be a better approach)

Adam Erstelle
  • 423
  • 1
  • 5
  • 14
0

I resolved the issue by not using Named Credential, using the endpoint directly, and it returned a token which I am now able to save without any extra steps. The endpoint did not need to have a callout: Named Credential as I would eventually have to supply username, password and client keys in the HTTP request body anyway.

  • The point of named credentials is to remove username, pwd, keys from APEX code and (potentially) insecure configuration. Though yes, choosing to do it entirely manually is certainly a way to make it function, it is not necessary and against best practices. – Adam Erstelle Jan 25 '23 at 01:40