function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
jd_06jd_06 

REST Webservice can't get access token

Hi All - I have a business requirement to attach a pdf document (visualforce rendered as pdf) to Notes and Attachments on a record when that record gets updated.  Since we can't use getContentAsPDF() in the context of a trigger, I am attempting to create a Web Service that will run asyncronously to perform this task.  Thanks go to jungleeforce for this post (http://jungleeforce.wordpress.com/2014/06/11/generate-a-pdf-and-attach-it-to-record-from-a-trigger-in-salesforce-restful/).  With some minor customization tweaks I got this working for a single record update.  However when I perform a bulk load, I am getting the following errror from the FutureHandler Operation (as seen in the Debug Log).  I am calling out from the same org that I am calling into.

10:02:35.245 (245356383)|CALLOUT_RESPONSE|[48]|System.HttpResponse[Status=Unauthorized, StatusCode=401]

I know why I am getting this, but I don't know how to resolve.  I am getting this issue because I am passing userInfo.getSessionId() to the asyncronous @future method.  Since asyncronous processes don't run in a user context I am not getting a session id....hence Status=Unauthorized.

I have tried creating a connected app and using the Consumer Key and Consumer Secret.  I'm not certain if this the correct approach and if so I need to know how to correctly use this Key and Secret.

Here is the trigger and two classes that I'm using to perform this task.

Please advise on how I can get my access code for this asyncronous process.

Thank you very much.

Trigger
trigger pdfAttachTrigger on DealerPlanning__c (after update)
{
list<id>dealerPlanIdList = new list<id>();
map<id,id> dealerPlanAcctMap = new map<id,id>();

for(DealerPlanning__c dealPlan: trigger.new)
{
  dealerPlanIdList.add(dealPlan.id);
  dealerPlanAcctMap.put(dealPlan.id,dealPlan.account__c);
}

DealerPlanTriggerController.addPDFAttach(userInfo.getSessionId(), dealerPlanIdList, dealerPlanAcctMap);
}

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

Class with @RestResource
@RestResource(urlMapping='/addPDFtoRecord/*')
global with sharing class AddPDFtoRecordREST
{  
  @HttpPost
    global static void doPost(map<String,String> dealerPlanAcctMap, list<String> dealerPlanIdList) {

       list<attachment> insertAttachment = new list<attachment>();
     
        for(String dpId: dealerPlanIdList)
        {
            //create a pageReference instance of the VF page.
            pageReference pdf = Page.PI_Certificate;
            //pass the Account Id parameter to the class.
            pdf.getParameters().put('accountID', dealerPlanAcctMap.get(dpId));
                    
            Attachment attach = new Attachment();
            Blob body;
            if(!test.isRunningTest()){
                body = pdf.getContent();
            }else{
                body=blob.valueOf('TestString');
            }
           
            attach.Body = body;
            attach.Name = 'pdfName'+dpId+'.pdf';
            attach.IsPrivate = false;
            attach.ParentId = dpId;//This is the record to which the pdf will be attached
            insertAttachment.add(attach);
         }
        
         //insert the list
         insert insertAttachment;
    }
}

Justin JulicherJustin Julicher
Hi jd_06

Not sure about this but a solution provided at http://ttps://developer.salesforce.com/forums?id=906F000000099zbIAA

suggests using:

req.setHeader('Authorization', 'OAuth '+UserInfo.getSessionId());

where you have 

req.setHeader('Authorization', 'Bearer '+ sessionId);

So change 'Bearer' to 'OAuth' and give that a go.

jd_06jd_06
Hi Justin - Thanks for taking the time to respond to my question.  Unfortunately this too does not work.  The issue is when I run asyncrously (which is what I have to do in order to generate the pdf from a trigger) Salesforce does not run in the context of a user.  So when we call teh UserInfo.getSessionId(); method we get a null value....hence no authorization.

However, I believe that I may have found a solution using SOAP.  I'm not too crazy about it because it requires that i hard code my username, login+security token in Apex.  I am continuing to test....but so far so good.  Once I come up with a solution I'll be sure to post.

Again, thanks for your response.

Jason