[SalesForce] Live Chat error message “Session required but was invalid or not found”

I'm trying to develop an apex function to connect my Org with live agent based on Salesforce official guide.
Apex function connect with live agent got 2 main step as following:

  1. Create a Live Agent Session:

refer to https://developer.salesforce.com/docs/atlas.en-us.live_agent_rest.meta/live_agent_rest/live_agent_rest_SessionId.htm

  1. Chat visitor init:

refer to https://developer.salesforce.com/docs/atlas.en-us.live_agent_rest.meta/live_agent_rest/live_agent_rest_create_visitor_session.htm

  1. connect successful

Develop process

a. my apex function already successful achieve the step 1:
I get the session ID and
in my debug log show "CALLOUT_RESPONSE [218]|System.HttpResponse[Status=OK, StatusCode=200]"

b. but I fail to Chat visitor init
error message was "Session required but was invalid or not found"
debug log show "CALLOUT_RESPONSE [268]|System.HttpResponse[Status=Forbidden, StatusCode=403]"

I feel confuse because session ID what I put into the apex code to request Chat visitor init was obtain from the step a. Session ID I sure is correct and no problem becasue I already test and debug many time to comfirm the result.

can anyone tell me the reason and help me solve the problem. this is urgent thing.
My apex code show as following;

Part 1: Create a Live Agent Session

HttpRequest req = new HttpRequest();   
req = new HttpRequest();
Http h = new Http();  
h = new Http(); 
String bodyRes = '';     
req.SetEndPoint('https://d.la10.salesforceliveagent.com/chat/rest/System/SessionId'); 
req.setMethod('GET');
req.setHeader('X-LIVEAGENT-API-VERSION','36');
req.setHeader('X-LIVEAGENT-AFFINITY', '');

try {
    HttpResponse res = h.send(req);
    bodyRes = res.getBody();
    System.debug('[Client] Get Session id=============' + bodyRes);
} catch(System.CalloutException e) {
    System.debug('Callout error: '+ e);
    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, e.getMessage()));
}

String id = '';
String key = '';
JSONParser parser = JSON.createParser(bodyRes);
System.debug('parser=============' + parser);

while (parser.nextToken() != null) {
    if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) && (parser.getText() == 'id')) {
        parser.nextToken();
        id = parser.getText();System.debug('id=============' + id);
    }
    else if((parser.getCurrentToken() == JSONToken.FIELD_NAME) && (parser.getText() == 'key')){
        parser.nextToken();
        key = parser.getText();System.debug('key=============' + key);
    }
}

Part 2: Chat visitor init

req.SetEndPoint('https://d.la10.salesforceliveagent.com/chat/rest/Chasitor/ChasitorInit'); 
req.setMethod('POST');
req.setHeader('X-LIVEAGENT-API-VERSION','36');
req.setHeader('X-LIVEAGENT-SESSION-KEY', key);System.debug('req=============' + req);

JSONGenerator gen = JSON.createGenerator(true);

gen.writeStartObject();
gen.writeStringField('organizationId', 'xxxxxxxxxx');
gen.writeStringField('deploymentId', 'xxxxxxxxxxxxxxx');
gen.writeStringField('buttonId', 'xxxxxxxxxxxxxxx');
gen.writeStringField('sessionId', id);
gen.writeStringField('userAgent', '');
gen.writeStringField('language', 'en-US');
gen.writeStringField('screenResolution', '1366x768');
gen.writeStringField('visitorName', 'Jen');
//gen.writeFieldName('prechatDetails');gen.writeStartObject();gen.writeEndObject();
//gen.writeFieldName('prechatEntities');gen.writeStartObject();gen.writeEndObject();
gen.writeBooleanField('receiveQueueUpdates', true);
gen.writeBooleanField('isPost', true);
gen.writeEndObject();

String sendMsg = gen.getAsString();
System.debug('sendMsg in json==============' + sendMsg);
req.setBody(sendMsg);
try {
    HttpResponse res = h.send(req);
    bodyRes = res.getBody();System.debug('bodyRes==============' + bodyRes);            
} catch (System.CalloutException e) {
    System.debug('Callout error: '+ e);
    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, e.getMessage()));
}

I already test on my postman based on your guide, and finally my request can pop up my live agent. But when I try to implement in my apex code I got error message "Session required but was invalid or not found" again even I already hard code "X-LIVEAGENT-SESSION-KEY" and "sessionId" value.

enter image description here

Can you help me verify my code as following? Thank you very very much.

New updated at 30-4-2016

    HttpRequest req = new HttpRequest();   
    Http h = new Http();  
    String bodyRes = '';

    req.SetEndPoint('https://d.la10.salesforceliveagent.com/chat/rest/Chasitor/ChasitorInit'); 
    req.setMethod('POST');

    req.setHeader('X-LIVEAGENT-API-VERSION','36');
    req.setHeader('X-LIVEAGENT-SESSION-KEY', '18c52adc-0bfc-4843-bc14-6b3ff98cebc5!c9ce3e32-684a-4359-b6f1-edb43141d2a7');
    req.setHeader('X-LIVEAGENT-AFFINITY', 'null');        
    req.setHeader('X-LIVEAGENT-SEQUENCE', '1');

    JSONGenerator gen = JSON.createGenerator(true);

    gen.writeStartObject();
    gen.writeStringField('organizationId', '00D2xxxxxxxxxxx');
    gen.writeStringField('deploymentId', '572xxxxxxxxxxxx');
    gen.writeStringField('buttonId', '573xxxxxxxxxxxx');
    gen.writeStringField('sessionId', '18c52adc-0bfc-4843-bc14-6b3ff98cebc5');
    gen.writeStringField('userAgent', '');
    gen.writeStringField('language', 'en-US');
    gen.writeStringField('screenResolution', '1366x768');
    gen.writeStringField('visitorName', 'Jen');
    gen.writeFieldName('prechatDetails');
        gen.writeStartArray();
        gen.writeEndArray();
    gen.writeFieldName('prechatEntities');
        gen.writeStartArray();
        gen.writeEndArray();
    gen.writeBooleanField('receiveQueueUpdates', true);
    gen.writeBooleanField('isPost', true);
    gen.writeEndObject();

    String sendMsg = gen.getAsString();
    req.setBody(sendMsg);
    try {
        HttpResponse res = h.send(req);
        bodyRes = res.getBody();    
    } catch (System.CalloutException e) {
        System.debug('Callout error: '+ e);
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, e.getMessage()));
    }

Best Answer

You haven't include header for ChasitorInit request:

X-LIVEAGENT-AFFINITY

Where X-LIVEAGENT-AFFINITY is the system-generated ID used to identify the Live Agent session on the Live Agent servers. This affinity token is included in the response body of the SessionId request. That's why you have http 403

When you are using Rest tools e.g. PostMan, token could be omitted, but when you are trying to use SF, ChasitorInit denies access.

Modify Get:

req.setHeader('X-LIVEAGENT-AFFINITY', 'null');
//..
else if((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
    (parser.getText() == 'affinityToken')){
    parser.nextToken();
    affinityToken = parser.getText();
}

Post:

req.setHeader('X-LIVEAGENT-AFFINITY', affinityToken);

Minimum request message looks like:

{
"organizationId": "00Dxxxxxxxxxxxx",
"deploymentId": "572xxxxxxxxxxxx",
"buttonId": "573xxxxxxxxxxxx",
"sessionId": "0b333f76-90c7-4cc0-8653-de2885857236",
"userAgent": "",
"language": "en-US",
"screenResolution": "1900x1080",
"visitorName": "Ilya",
"prechatDetails": [],
"prechatEntities": [],
"receiveQueueUpdates": true,
"isPost": true
}

It's very close to your original message, but prechatDetails,prechatEntities are required.

Related Topic