How to get session id in @future methods, Batch Apex jobs, or scheduled Apex jobs.

As you know you can not get session id in future method by calling UserInfo.getSessionId() method, if you call this you will get null value, so there are two ways by which you can get the session id in future method.
  1. You can pass the session id in future method when you call it, so here what can you do, you can get the session id by calling UserInfo.getSessionId() in any class from where you are going to call the future method and you can pass this session id as a parameter in future method. Here is an example
public with sharing class ExampleOne {
 public static void method1(){
  String sessionId = UserInfo.getSessionId();
  ExampleOne.myFutureMethod(sessionId);
 }
 
 @future
 public static void myFutureMethod(String sessionId){
  // your code here
 }
}

But in some cases the above approach is not possible, for example if you want to call future method from trigger you can not use UserInfo.getSessionId() method, in that situation you can use the second approach.


  1. In this approach you can get the session id in the future method itself. For that you have to create a class like below: 
public with sharing class ExplicitLogin {

    private static final String NS_SOAP = 'http://schemas.xmlsoap.org/soap/envelope/';
    private static final String NS_SF = 'urn:partner.soap.sforce.com';
    private static final String POST_METHOD = 'POST';
    private static String EndPointUrl = null;
    
    public static String login(){
        try{
            
            //string username ;//='your username';
            //string password ;//= 'password + security token';
            EndPointUrl = 'https://login.salesforce.com/services/Soap/u/29.0';
            
            HttpRequest req = new HttpRequest();
            req.setMethod(POST_METHOD);   
            req.setTimeout(60000);
            req.setEndpoint(EndPointUrl);
            req.setHeader('Content-Type', 'text/xml;charset=UTF-8');        
            req.setHeader('SOAPAction', '""');
            req.setBody('<envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"><header><body><login xmlns="urn:partner.soap.sforce.com"><username>' +username+ '</username><password>' + password + '</password></login></body></header></envelope>');        
               
            HttpResponse res =  new Http().send(req);                
                          
            Dom.Document responseDocument = res.getBodyDocument();
            // soapenv:Envelope
            Dom.Xmlnode rootElm = responseDocument.getRootElement(); 
            // soapenv:Body
            Dom.Xmlnode bodyElm = rootElm.getChildElement('Body', NS_SOAP); 
            // loginResponse 
            Dom.Xmlnode loginResponseElm = bodyElm.getChildElement('loginResponse', NS_SF); 
            // result
            Dom.Xmlnode resultElm = loginResponseElm.getChildElement('result', NS_SF);
            // sessionId 
            Dom.Xmlnode sessionIdElm = resultElm.getChildElement('sessionId', NS_SF);
            return sessionIdElm.getText();           
        }
        catch(exception e){
            system.debug('***'+e.getMessage()+'**'+e.getLineNumber());
            return null ;
        }
    }
}


Basically this is a SOAP HTTP call to Salesforce itself to login and get the session id from the login result.
Now you can call this class from the future method itself and it will return the session id.
public with sharing class ExampleOne {
 public static void method1(){
  ExampleOne.myFutureMethod();
 }
 
 @future
 public static void myFutureMethod(){
  // call the method to get the session id
  String sessionId = ExplicitLogin.login();
 }
}
This way you can get the sessionId in any async operation like future method, Batch Apex and Scheduled Apex.

Related Posts

Post a Comment

Subscribe Our Newsletter