Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

Enconding $session.params.[parameter] on Dialog Flow CX ERROR: ByteString is not valid UTF8

I am having a problem to display a message of type $session.params.[parameter] on DialogFlow CX

I am reading a json file from Google Bucket and when the Json is with no special characters it works fine example Convencao.

But when I put some special character example Convenção it not working giving me the error below:

   "FunctionExecution": {
    "Webhook": {
      "URL": "example.com",
      "Status": {
        "ErrorCode": "INTERNAL",
        "ErrorMessage": "Response body [<ByteString@40a8d64c size=182 contents=\"{\\n  \\\"session_info\\\": {\\n    \\\"parameters\\\": {\\n     ...\">] is not valid UTF8."
      },
      "DisplayName": "example",
      "Latency": "170 ms",
      "ID": "a8660475-f28b-440e-ad4c-4e8506cb6795"
    },
    "Responses": [
      {
        "responseType": "ENTRY_PROMPT",
        "text": {
          "text": [
            "Escolha o evento:\n1. $session.params.evento1\n2. $session.params.evento2\n3. $session.params.evento3\n4. Outros Eventos"
          ],
          "redactedText": [
            "Escolha o evento:\n1. $session.params.evento1\n2. $session.params.evento2\n3. $session.params.evento3\n4. Outros Eventos"
          ]
        },
        "source": "VIRTUAL_AGENT"
      }
    ]
  }
}

},

This is the .json that work

{
   "eventname1":{
      "eventname":"Test Diamond Summit",
      "eventdate":"07 até 12 de Fevereiro",
      "eventlocation":"Kenya",
      "eventsite":"example.com"
   },
   "eventname2":{
      "eventname":"Test de Incentivo 2023",
      "eventdate":"08 até 12 de Março",
      "eventlocation":"Ilha de Comandatuba",
      "eventsite":"example.com"
   },
   "eventname3":{
      "eventname":"Convencao Florescer 2023",
      "eventdate":"Sessões complementares: 17 de maio de 2023 - Convenção: 18, 19 e 20 de maio 2023",
      "eventlocation":"Rio de Janeiro / RJ",
      "eventsite":"example.com"
   },
   "edicao":{
      "edicaoname":"Motivação",
      "duracao":"1° de Dezembro à 28 de Fevereiro",
      "link":"example.com"
   },
   "businesshourPT":{
      "intervalName":"MONDAY-FRIDAY-08:59-20:01"
   },
   "businesshourES":{
      "intervalName":"MONDAY-FRIDAY-08:59-20:01"
   }
}

This is the .json that not work

{
   "eventname1":{
      "eventname":"Test Diamond Summit",
      "eventdate":"07 até 12 de Fevereiro",
      "eventlocation":"Kenya",
      "eventsite":"example.com"
   },
   "eventname2":{
      "eventname":"Test de Incentivo 2023",
      "eventdate":"08 até 12 de Março",
      "eventlocation":"Ilha de Comandatuba",
      "eventsite":"example.com"
   },
   "eventname3":{
      "eventname":"Convenção Florescer 2023",
      "eventdate":"Sessões complementares: 17 de maio de 2023 - Convenção: 18, 19 e 20 de maio 2023",
      "eventlocation":"Rio de Janeiro / RJ",
      "eventsite":"example.com"
   },
   "edicao":{
      "edicaoname":"Motivação",
      "duracao":"1° de Dezembro à 28 de Fevereiro",
      "link":"example.com"
   },
   "businesshourPT":{
      "intervalName":"MONDAY-FRIDAY-08:59-20:01"
   },
   "businesshourES":{
      "intervalName":"MONDAY-FRIDAY-08:59-20:01"
   }
}

This is my java code

//Used to collecting bucket data (all parameterized data)
public JSONObject readBucket() throws IOException {
    Storage storage = StorageOptions.getDefaultInstance().getService(); 
    BlobId blobId = BlobId.of("test", "test_properties.json");
    byte[] content = storage.readAllBytes(blobId);
    String contentString = new String(content,  StandardCharsets.UTF_8);

    JSONObject jsonObj = new JSONObject(contentString.toString());
    return jsonObj;
}


//Used to build webhookResponse for Dialog Flow CX
public JsonObject setSessionParameter(JsonObject parameterObject){
    // Constructs the webhook response object
    JsonObject parameterSessionObject = new JsonObject();
    parameterSessionObject.add("parameters", parameterObject); 
    JsonObject webhookResponse = new JsonObject();
    webhookResponse.add("session_info", parameterSessionObject);   
    return webhookResponse;
}




@Override
  public void service(HttpRequest request, HttpResponse response) throws Exception {    
    //Create DialogFlow Objects
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    Map<String, Object> requestBody = gson.fromJson(request.getReader(), Map.class);
    Map<String, Object> sessionInfo = (Map<String, Object>) requestBody.get("sessionInfo");
    Map<String, Object> parameters = (Map<String, Object>) sessionInfo.get("parameters");
    Map<String, Object> fulfillmentInfo = (Map<String, Object>) requestBody.get("fulfillmentInfo");
    
    System.out.println("parameters: "+parameters);

    //Extracting Values of DialogFlow
    String ani = (String) parameters.get("ani");
    System.out.println("ani: "+ani);
    String tag = (String) fulfillmentInfo.get("tag");
    System.out.println("tag: "+tag);
    
    JSONObject con;
    String status;
    JsonObject parameterObject;
    String jsonResponseObject;
    BufferedWriter writer;
    String intervalName;
    JSONObject properties;
    String eventname;
    String eventname1value;
    String eventname2value;
    String eventname3value;
    String eventdate;
    String eventlocation;
    String eventsite;
    JSONObject edicao;
    String edicaoduracao;
    String edicaonome;
    String edicaolink;
    JSONObject eventname1;
    JSONObject eventname2;
    JSONObject eventname3;
    JSONObject eventnamedtmf;
    JSONObject bhour;
    String iaeventmenudtmf = null;
    String intervalNameFormat;
    

    //Checking Routes
    try {
        switch(tag) {
        case "11040":
            properties = readBucket();

            //Writing values on Objects that will became Parameters
        eventname1 = properties.getJSONObject("eventname1");
        eventname1value = eventname1.getString("eventname");
        eventname2 = properties.getJSONObject("eventname2");
        eventname2value = eventname2.getString("eventname");
        eventname3 = properties.getJSONObject("eventname3");
        eventname3value = eventname3.getString("eventname");
    
            //Creating Response Objects
            parameterObject  = new JsonObject();
            parameterObject .addProperty("evento1", eventname1value.toString());    
            parameterObject .addProperty("evento2", eventname2value.toString());    
            parameterObject .addProperty("evento3", eventname3value.toString());
            jsonResponseObject = gson.toJson(setSessionParameter(parameterObject));
            System.out.println("jsonResponseObject: "+jsonResponseObject.toString());
            
            //Sends the responseObject
            writer = response.getWriter();
            writer.write(jsonResponseObject.toString());
            break;
    
        case "11100":
            //Get user option to concat file bucket file
            iaeventmenudtmf = (String) parameters.get("iaeventmenu");
            System.out.println("iaeventmenudtmf: "+iaeventmenudtmf);
              
            properties = readBucket();

            //Writing values on Objects that will became Parameters
            eventnamedtmf = properties.getJSONObject("eventname"+iaeventmenudtmf);
        eventname = eventnamedtmf.getString("eventname");
        eventdate = eventnamedtmf.getString("eventdate");
        eventlocation = eventnamedtmf.getString("eventlocation");
        eventsite = eventnamedtmf.getString("eventsite");
            
        //Creating Response Objects
            parameterObject  = new JsonObject();
            parameterObject .addProperty("evento", eventname.toString());   
            parameterObject .addProperty("eventoData", eventdate.toString());   
            parameterObject .addProperty("eventoLocal", eventlocation.toString());      
            parameterObject .addProperty("eventoSite", eventsite.toString());
            jsonResponseObject = gson.toJson(setSessionParameter(parameterObject));
            System.out.println("jsonResponseObject: "+jsonResponseObject.toString());
            
            //Sends the responseObject
            writer = response.getWriter();
            writer.write(jsonResponseObject.toString());
            break;
              
        case "12040":
            properties = readBucket(); 
    
            //Writing values on Objects that will became Parameters
            edicao = properties.getJSONObject("edicao");
            edicaonome = edicao.getString("edicaoname");
            edicaoduracao = edicao.getString("duracao");
            edicaolink = edicao.getString("link");
             
            //Creating Response Objects
            parameterObject  = new JsonObject();
            parameterObject .addProperty("edicao", edicaonome.toString());      
            parameterObject .addProperty("duracao", edicaoduracao.toString());      
            parameterObject .addProperty("link", edicaolink.toString());
            jsonResponseObject = gson.toJson(setSessionParameter(parameterObject));
            System.out.println("jsonResponseObject: "+jsonResponseObject.toString());
            
            //Sends the responseObject
            writer = response.getWriter();
            writer.write(jsonResponseObject.toString());
            break;
                
        default:
            break;
            
        }
    }catch(Exception e) {
        parameterObject  = new JsonObject();
        parameterObject .addProperty("error", "999 Error on request - Class:  " + getClass().getName() + ": Message" + e.getMessage()+ " Cause: "+e.getCause() + " Stack: " +Arrays.toString(e.getStackTrace()));       
        jsonResponseObject = gson.toJson(setSessionParameter(parameterObject));
        System.out.println("jsonResponseObject: "+jsonResponseObject.toString());
          
        //Sends the responseObject
        writer = response.getWriter();
        writer.write(jsonResponseObject.toString());
    }
  }
}

This is my return on Google Cloud Function Log

jsonResponseObject: {   "session_info": {
    "parameters": {
      "evento1": "Blue Diamond Summit",
      "evento2": "Viagem de Incentivo 2023",
      "evento3": "Convenção Florescer 2023"
    }   } }

When it passes Convenção I receive the error above when it is Convencao it displays the message with success.

I tried some enconding UTF-8 ways without suceess

I tried some solutions below

            byte[] jsonResponseObjectb = jsonResponseObject.getBytes(StandardCharsets.UTF_8);
        String jsonResponseObjects = new String(jsonResponseObjectb, StandardCharsets.UTF_8);

            //Sends the responseObject
            writer = response.getWriter();
            writer.write(jsonResponseObjects);


        //handle encoding error on Dialog Flow CX
        CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder().onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE);

        byte[] eventname1valueb = eventname1value.getBytes(StandardCharsets.UTF_8);
        String eventname1values = decoder.decode(ByteBuffer.wrap(eventname1valueb)).toString();
            
        byte[] eventname2valueb = eventname2value.getBytes(StandardCharsets.UTF_8);
        String eventname2values = decoder.decode(ByteBuffer.wrap(eventname2valueb)).toString();

        byte[] eventname3valueb = eventname3value.getBytes(StandardCharsets.UTF_8);
        String eventname3values = decoder.decode(ByteBuffer.wrap(eventname3valueb)).toString(); 
            
            
                //Creating Response Objects
        JsonObject parameterObject  = new JsonObject();
            parameterObject .addProperty("evento1", eventname1value.toString());    
            parameterObject .addProperty("evento2", eventname2value.toString());    
            parameterObject .addProperty("evento3", eventname3value.toString());
            String jsonResponseObject = gson.toJson(setSessionParameter(parameterObject));
            
                //Sends the responseObject
            writer = response.getWriter();
            writer.write(jsonResponseObjects);


            byte[] jsonResponseObjectb = jsonResponseObject.getBytes(StandardCharsets.UTF_8);
        String jsonResponseObjects = new String(jsonResponseObjectb, StandardCharsets.UTF_8);
            String encodedString = URLEncoder.encode(jsonResponseObjects, "UTF-8");

            //Sends the responseObject
            writer = response.getWriter();
            writer.write(encodedString);


            CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder().onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE);
byte[] 
                jsonResponseObjectb = jsonResponseObject.getBytes(StandardCharsets.UTF_8);
        String jsonResponseObjects = decoder.decode(ByteBuffer.wrap(eventname3valueb)).toString();

            //Sends the responseObject
            writer = response.getWriter();
            writer.write(jsonResponseObjects);

My return must be

Choose the event:

  1. Test Diamond Summit
  2. Test de Incentivo 2023
  3. Convenção Test 2023
  4. Other Events

but in it is Convenção I received

Choose the event:

  1. $session.params.evento1
  2. $session.params.evento2
  3. $session.params.evento3
  4. Other Events

but in it is Convencao I received

Choose the event:

  1. Test Diamond Summit
  2. Test de Incentivo 2023
  3. Convencao Test 2023
  4. Other Events

No one of them worked

I do not know more what I could try to do to solve this error

Could you help me please?

Tried to use some enconding methods that I know

0 1 916
1 REPLY 1

I would suggest that you try to force the encoding of the JSON file to UTF-8 by adding the following header to your JSON file: {'Content-Type' : 'application/json; charset=UTF-8'}

This SO post might be helpful.