You need to sign in to do that
Don't have an account?

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)
{
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;
}
}
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);
}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;
}
}
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.
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