1

I am accessing Salesforce Live Agent through REST API version 40.

I am able to create session, do chasitorInit and get Messages successfully.

When I send Chat Message which user types to agent via ChatMessage call,

I get this error,

Out of sync Ack. Expected 4. Actual 1

The documentation doesn't say to send ack param along with url for /Chasitor/ChatMessage like how we do for /System/Messages call

Below is my code,

`public void sendUserChatMessage(LiveAgentData liveAgentData, String text) {
    LOGGER.entry(liveAgentData,text);
    LiveAgentSessionBean liveAgentSessionBean = liveAgentData.getLiveAgentSessionBean();
    Map<String,String> headers = new HashMap<String,String>();
            headers.put("X-LIVEAGENT-AFFINITY",liveAgentSessionBean.getAffinityToken());
            headers.put("X-LIVEAGENT-API-VERSION","40");
            headers.put("X-LIVEAGENT-SESSION-KEY",liveAgentSessionBean.getKey());
            LOGGER.debug("CHAT_MESSAGE::: SEQUENCE_ID: "+liveAgentSessionBean.getSequenceId());
            headers.put("X-LIVEAGENT-SEQUENCE",liveAgentSessionBean.getSequenceId());
    String jsonBody = "{\"text\": \""+text+"\"}";
    String response = null;
    try {
        response = HttpUtils.performPostRequest("https://hostname/chat/rest/Chasitor/ChatMessage",jsonBody,headers);
        if("OK".equalsIgnoreCase(response)){
            LOGGER.debug("Success sending message")
        } else{
            throw new Exception("Could not send user chat message: "+response);
        }
    }  catch (Exception e) {
        e.printStackTrace();
    } 
}`

Can someone help me with this.?

  • 1
    I'm having the same issue, I can send messages as long as I don't do a Messages call, after asking for messages, all subsequent calls to ChatMessage fails. – Federico Jul 16 '17 at 16:23
2
+50

I tried to access Salesforce Live Agent REST API(version 40) through a standalone Java class and was able to call all methods successfully. Please see the below code and check if you have missed anything. Hope this helps.

Java Class

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonReader;

public class LiveChat {
    private final String USER_AGENT = "Mozilla/5.0";
    private final String LIVE_AGENT_URL = "https://d.la1-c2-iad.salesforceliveagent.com";
    private final String API_VERSION = "40";

    public static void main(String[] args) throws Exception {
        LiveChat liveCh = new LiveChat();
        // 1 - Get Session Details
        JsonObject objSession = liveCh.getSessionDetails();

        // 2 - Send Chat Request to Server
        liveCh.sendChatRequest(objSession);

        //Wait till agent accept the chat request 
        System.out.println("\n\nPlease Accept the Chat Request in Service Console.");
        System.out.println("Then Press \"ENTER\" to continue...");
        Scanner console = new Scanner(System.in);
        console.nextLine();

        // 3 - Read Chat Details
        liveCh.ReadChatDetails(objSession);

        // 4 - Send Chat Message
        liveCh.SendChatMessage(objSession); 

        //Wait till agent accept the chat request 
        System.out.println("\n\nPlease Accept the Chat Request in Service Console.");
        System.out.println("Then Press \"ENTER\" to continue...");
        console = new Scanner(System.in);
        console.nextLine(); 

        liveCh.syncChatSession(objSession);

        // 5 - Read Chat Message Again
        liveCh.ReadChatDetails(objSession);

        // 4 - Send Chat Message Again
        liveCh.SendChatMessage(objSession);


    }
    private void SendChatMessage(JsonObject objSession) throws Exception{
        Scanner console = new Scanner (System.in);
        System.out.print("\n\nPlease enter chat message:");  
        String chatMsg = console.nextLine(); // Get what the user types.    

        URL endpoint = new URL(LIVE_AGENT_URL + "/chat/rest/Chasitor/ChatMessage");
        HttpURLConnection con = (HttpURLConnection) endpoint.openConnection();

        // add request header
        con.setRequestProperty("User-Agent", USER_AGENT);
        con.setRequestProperty("X-LIVEAGENT-API-VERSION", "40");
        con.setRequestProperty("X-LIVEAGENT-AFFINITY", objSession.getString("affinityToken"));
        con.setRequestProperty("X-LIVEAGENT-SESSION-KEY", objSession.getString("key"));

        con.setRequestMethod("POST");

        // Send post request
        String jsonPost = Json.createObjectBuilder().add("text", chatMsg).add("isPost", true).build().toString();
        //System.out.println("jsonPost:"+jsonPost);//Uncomment this line to check the JSON request body
        con.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.writeBytes(jsonPost);
        wr.flush();
        wr.close();     

        System.out.println("Send Message Response Code : " + con.getResponseCode());        
    }
    private void ReadChatDetails(JsonObject objSession) throws Exception{
        URL endpoint = new URL(LIVE_AGENT_URL + "/chat/rest/System/Messages");
        HttpURLConnection con = (HttpURLConnection) endpoint.openConnection();
        con.setRequestMethod("GET");

        // add request header
        con.setRequestProperty("User-Agent", USER_AGENT);
        con.setRequestProperty("X-LIVEAGENT-API-VERSION", "40");
        con.setRequestProperty("X-LIVEAGENT-AFFINITY", objSession.getString("affinityToken"));
        con.setRequestProperty("X-LIVEAGENT-SESSION-KEY", objSession.getString("key"));

        System.out.println("\n\nRead Message Response Code : " + con.getResponseCode());

        //Parse this JSON to get all the messages
        JsonReader reader = Json.createReader(con.getInputStream());
        JsonObject mresObj = reader.readObject();
        reader.close();
        System.out.println("\n\nMessage Details : " + mresObj.toString());      
    }
    private void sendChatRequest(JsonObject objSession) throws Exception{
        URL endpoint = new URL(LIVE_AGENT_URL + "/chat/rest/Chasitor/ChasitorInit");
        HttpURLConnection con = (HttpURLConnection) endpoint.openConnection();
        // add request header
        con.setRequestProperty("User-Agent", USER_AGENT);
        con.setRequestProperty("X-LIVEAGENT-API-VERSION", "40");
        con.setRequestProperty("X-LIVEAGENT-AFFINITY", objSession.getString("affinityToken"));
        con.setRequestProperty("X-LIVEAGENT-SESSION-KEY", objSession.getString("key"));
        con.setRequestProperty("X-LIVEAGENT-SEQUENCE", "1");
        con.setRequestMethod("POST");
        // Send post request
        JsonArray array = Json.createArrayBuilder().build();
        String jsonPost = Json.createObjectBuilder().add("organizationId", "XXXXXXXXXXXX")
                .add("deploymentId", "572i00000006rlJ").add("buttonId", "573i00000006vIn")
                .add("sessionId", objSession.getString("id")).add("userAgent", USER_AGENT).add("language", "en-US")
                .add("screenResolution", "1900x1080")
                .add("prechatDetails", Json.createArrayBuilder().add(Json.createObjectBuilder()
                        .add("label", "E-mail Address").add("value", "jon@example.com")
                        .add("entityMaps", Json.createArrayBuilder()
                                .add(Json.createObjectBuilder().add("entityName", "Contact").add("fieldName", "Email")
                                        .add("isFastFillable", false).add("isAutoQueryable", true)
                                        .add("isExactMatchable", true).build())
                                .build())
                        .add("transcriptFields", Json.createArrayBuilder().add("c__EmailAddress").build())
                        .add("displayToAgent", true).build()).build())
                .add("prechatEntities", array).add("receiveQueueUpdates", true).add("isPost", true).build().toString();
        /*Uncomment the below line to check the JSON request body*/
        // System.out.println("jsonPost:"+jsonPost); 
        con.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.writeBytes(jsonPost);
        wr.flush();
        wr.close();

        System.out.println("\n\nChat Request Call Response Code : " + con.getResponseCode());
    }

    private JsonObject getSessionDetails() throws Exception {
        JsonObject resObj = null;
        URL endpoint = new URL(LIVE_AGENT_URL + "/chat/rest/System/SessionId");
        HttpURLConnection con = (HttpURLConnection) endpoint.openConnection();
        con.setRequestMethod("GET");

        // add request header
        con.setRequestProperty("User-Agent", USER_AGENT);
        con.setRequestProperty("X-LIVEAGENT-API-VERSION", API_VERSION);
        con.setRequestProperty("X-LIVEAGENT-AFFINITY", "null");

        System.out.println("\n\nSession Call Response Code : " + con.getResponseCode());

        // Get the Session details
        JsonReader reader = Json.createReader(con.getInputStream());
        resObj = reader.readObject();
        reader.close();
        System.out.println("\n\nkey: " + resObj.getString("key"));
        System.out.println("id: " + resObj.getString("id"));
        System.out.println("clientPollTimeout: " + resObj.getInt("clientPollTimeout"));
        System.out.println("affinityToken: " + resObj.getString("affinityToken"));
        return resObj;
    }
    private void syncChatSession(JsonObject objSession) throws Exception {
        JsonObject resObj = null;
        URL endpoint = new URL(LIVE_AGENT_URL + "/chat/rest/System/ResyncSession");
        HttpURLConnection con = (HttpURLConnection) endpoint.openConnection();
        con.setRequestMethod("GET");

        // add request header
        con.setRequestProperty("User-Agent", USER_AGENT);
        con.setRequestProperty("X-LIVEAGENT-API-VERSION", "40");
        con.setRequestProperty("X-LIVEAGENT-AFFINITY", objSession.getString("affinityToken"));
        con.setRequestProperty("X-LIVEAGENT-SESSION-KEY", objSession.getString("key"));

        System.out.println("\n\nSync Session Call Response Code : " + con.getResponseCode());
    }   
}

Console Screenshots:

enter image description here

Java Console Output: enter image description here

  • 1
    It did work for me, the issue seems to be the X-LIVEAGENT-SEQUENCE that I was including on each request and incrementing on each call. I removed that and it works. Also I think that the requestSync in not actually needed unless you get a 503, is that right? – Federico Jul 25 '17 at 22:14
  • @Federico Glad, I could help. During multiple calls, sometimes I got 503 that's why I used ResyncSession. – Saroj Bera Jul 26 '17 at 5:14
  • @Federico Please check this link. There are some inputs from Salesforce support salesforce.stackexchange.com/questions/24966/… – Saroj Bera Jul 28 '17 at 9:31
  • thanks, I've already faced that issue. It seems that there is also some things missing for the documentation of other headers. – Federico Jul 29 '17 at 11:59

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.