1

Good day everyone. I am trying to create a pdf from a newly created record. I search in the internet and I find this link : https://jungleeforce.wordpress.com/2014/06/11/generate-a-pdf-and-attach-it-to-record-from-a-trigger-in-salesforce-restful/ . What it did is that it create a trigger that will call a future class and the future class call rest webservice. I follow everything instructed in the link but maybe because it's now outdated, I encounter an error saying callout loop not allowed. This error occur on the pdf.getContent(); inside my rest webservice. Can you please tell me what are the things needed for this ? Or does anyone have a good article we can follow to fix this problem ? Below is my code. Thank you

Trigger:

trigger triggerOne on Subscription__c (after insert) {
    for(Subscription__c sub : Trigger.New) {
        allSubsIdforPDF.add(sub.Id);
    }
        pdfTriggerController.addPDFAttach(userInfo.getSessionId(), allSubsIdforPDF);
}

pdfTriggerController:

global class pdfTriggerController{

    @Future(callout=true)
    public static void addPDFAttach(string sessionId, list<id> IdList){
       HttpRequest req = new HttpRequest();
       req.setEndpoint('https://'+URL.getSalesforceBaseUrl().getHost()+'/services/apexrest/addPDFtoSubscription/');
       req.setMethod('POST');
       req.setBody('{"subsIdList":'+JSON.serialize(IdList)+'}');
       req.setHeader('Authorization', 'Bearer '+ sessionId);
       req.setHeader('Content-Type', 'application/json');
       Http http = new Http();
       if(!test.isRunningTest()){
           HTTPResponse res = http.send(req);
       }
    }
}

REST Webservice:

@RestResource(urlMapping='/addPDFtoSubscription/*')
global class theaddPDFtoSubscription{

  @HttpPost
    global static void doPost(list<Id> subsIdList) {
        System.debug('subsIdList :' + subsIdList);
       list<attachment> insertAttachment = new list<attachment>();
        for(Id subsId: subsIdList){

            //create a pageReference instance of the VF page.
            pageReference pdf = Page.Membership_Certificate_PDF;
            //pass the Account Id parameter to the class.
            pdf.getParameters().put('id',subsId);
            Attachment attach = new Attachment();
            Blob body;
            if(!test.isRunningTest()){
                body = pdf.getContent();
            }else{
                body=blob.valueOf('TestString');
            }
            attach.Body = body;
            attach.Name = 'pdfName'+subsId+'.pdf';
            attach.IsPrivate = false;
            attach.ParentId = subsId;//This is the record to which the pdf will be attached
            insertAttachment.add(attach);

         }
         //insert the list
         insert insertAttachment;
    }
}

VF:

<apex:page standardController="Subscription__c" renderAs="pdf">

Hey, this is a sample

</apex:page>
3

Yep, your trouble here is because that article is a bit outdated.

getContentAsPDF() has been treated as a callout since API v34.0 (Summer '15).

So, with that in mind, the error Salesforce is giving you makes sense.

  • You have a trigger
  • Which is calling an @future method
  • Which makes a callout to the REST API of (ostensibly) the same org you're already in (callout 1)
  • Which calls getContentAsPDF() (callout 2)

Making the callout from your custom REST endpoint is the issue here. It wasn't an issue in the article you were working from because it was written in 2014 when getContentAsPDF() was treated as a normal method call.

Thankfully, the solution is simple. Just cut out the REST API call (honestly, I'd do this anyway. The REST API call here serves no purpose other than consuming more resources). Put another way, the doPost() method of your theaddPDFtoSubscription class should basically be copy/pasted to your addPDFAttach() method in pdfTriggerController (completely overwriting the existing code).

One thing to keep in mind is that you're calling getContentAsPDF() inside a loop. As we can only make 100 callouts in a transaction (sync or async), you should add some code to check the size of your incoming List<Id> before processing it.

| improve this answer | |
  • Thank you so much mate. I follow this and now it's working. Just a few question, what is the good salesforce function I can use to count the callouts and check the limit for this ? – Hope Feb 13 '18 at 3:25
  • @Hope The Limits class is what you're looking for. Limits.getLimitCallouts() gives you the total number you're allowed to make (100 for now, but Salesforce may change that in the future), and Limits.getCallouts() tells you how many you've used (in the current transaction). – Derek F Feb 13 '18 at 3:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.