2

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
  • 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, 2017 at 16:23

1 Answer 1

4
+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", "[email protected]")
                        .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

4
  • 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, 2017 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, 2017 at 5:14
  • @Federico Please check this link. There are some inputs from Salesforce support salesforce.stackexchange.com/questions/24966/…
    – Saroj Bera
    Jul 28, 2017 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, 2017 at 11:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .