This guide will go into the reporting of feedback widgets (nps and surveys) manually. It will give more context into how the widget data should be intepreted and how the response should be structured when reporting back to the SDK. Not all SDK's contain the functionality to do manual feedback widget reporting.
The SDK should provide 2 calls to perform this. One to retrieve the widget data describing the widget and another to report the result.
When receiving the data, it would be packaged in a JSON type object. Their structure would slightly differ depending for which type of widget it is reported.
In case of a survey, it would looks something like this:
{
"_id":"601345cf5e313f747656c241",
"app_id":"5e3356e07b96b63120334842",
"name":"Survey name",
"questions":[
{
"type":"multi",
"question":"Multi answer question",
"required":true,
"choices":[
{
"key":"ch1611875792-0",
"value":"Choice A"
},
{
"key":"ch1611875792-1",
"value":"Choice B"
},
{
"key":"ch1611875792-2",
"value":"Choice C"
},
{
"key":"ch1611875792-3",
"value":"Choice D"
}
],
"randomize":false,
"id":"1611875792-0"
},
{
"type":"radio",
"question":"Radio button question",
"required":false,
"choices":[
{
"key":"ch1611875792-0",
"value":"First"
},
{
"key":"ch1611875792-1",
"value":"Second"
},
{
"key":"ch1611875792-2",
"value":"Third"
},
{
"key":"ch1611875792-3",
"value":"Fourth"
}
],
"randomize":false,
"id":"1611875792-1"
},
{
"type":"text",
"question":"Text input question",
"required":true,
"id":"1611875792-2"
},
{
"type":"dropdown",
"question":"Question with a dropdown",
"required":false,
"choices":[
{
"key":"ch1611875792-0",
"value":"Value 1"
},
{
"key":"ch1611875792-1",
"value":"Value 2"
},
{
"key":"ch1611875792-2",
"value":"Value 3"
}
],
"randomize":false,
"id":"1611875792-3"
},
{
"type":"rating",
"question":"Rating type question",
"required":false,
"id":"1611875792-4"
}
],
"msg":{
"thanks":"Thanks for your feedback!"
},
"appearance":{
"show":"uClose",
"position":"bLeft",
"color":"#2eb52b"
},
"type":"survey"
}
In case of a NPS widget, the JSON internally would look something like this:
{ "_id":"60186d8b3687037dbb058d80", "app_id":"5e3356e07b96b63120334842", "name":"test3", "msg":{ "mainQuestion":"How likely are you to recommend this product to a friend?", "followUpAll":"", "followUpPromoter":"We're glad you like us. What do you like the most about our product?", "followUpPassive":"Thank you for your feedback. How can we improve your experience?", "followUpDetractor":"We're sorry to hear it. What would you like us to improve on?", "thanks":"Thanks for your feedback!" }, "followUpType":"score", "appearance":{ "show":"uSubmit", "color":"#027aff", "style":"full" }, "type":"nps" }
Both of these describe all server side configured information that would be used to visualize a widget manually. Starting from some style and color related fields and finally all questions and their potential answers. In the case of surveys, it also shows the required id's to report survey results.
When reporting the widgets results manually, the filled out response is reported through the segmentation field.
Reporting NPS widgets manually
To report the results of a NPS widget manually, no information from the widgets data JSON is needed. These widgets can report only two pieces of information - an integer rating from 1 to 10 and a String comment.
Therefore when reporting these results, you need to set two segmentation values, one with the key of "rating" and an int value and the other with the "comment" key and a String value.
Android sample code
The following sample code would report the result of a NPS widget:
Countly.sharedInstance().feedback().getFeedbackWidgetData(chosenWidget, new RetrieveFeedbackWidgetData() {
@Override public void onFinished(JSONObject retrievedWidgetData, String error) {
Map<String, Object> segm = new HashMap<>();
segm.put("rating", 3);//value from 1 to 10
segm.put("comment", "Filled out comment");
Countly.sharedInstance().feedback().reportFeedbackWidgetManually(widgetToReport, retrievedWidgetData, segm);
}
});
Reporting Survey widgets manually
To report survey widgets manually, investigation of the data JSON is needed. Each question has a question type and depending on the question type, the answer needs to be reported in a different way. Each questions also has it's own ID which needs to be used as part of the segmentation key when reporting the result.
The questions id can be seen in the "id" field. For example, in the above posted survey JSON the first question has the ID of "1611875792-0". When trying to report the result for a question, you would append "answ-" to the start of an ID and then use that as segmentation key. For example, for the first survey questions you would have the result segmentation key of "answ-1611875792-0".
The specific value would depend on the question type. Here is a description of how to report results for different question types:
Multiple answer question
It has the type "multi". In the question description there is a field "choices" which describes all valid options and their keys.
Users can select any combination of all answers.
You would prepare the segmentation value by concatinating the keys of the chosen options and using a comma as the delimiter.
For example, the above survey has 4 options in it's first question. If a user would choose the first, third and fourth option as the result, the resulting value for the answer would be: "ch1611875792-0,ch1611875792-2,ch1611875792-3".
Radio buttons
It has the type "radio". In the question description there is a field "choices" which describes all valid options and their keys.
Only one option can be selected.
You would use the chosen options key value as the value for your result segementation.
Dropdown value selector
It has the type "dropdown". In the question description there is a field "choices" which describes all valid options and their keys.
Only one option can be selected.
You would use the chosen options key value as the value for your result segementation.
Text input field
It has the type "text".
You would provide any string you want as the answer.
Rating picker
It has the type "rating"
You would provide any int value from 1 to 10 as the answer.
Android sample code
The following sample code would go through all of the received Survey widgets questions and choose a random answer to every question. It the reports the results:
Countly.sharedInstance().feedback().getFeedbackWidgetData(chosenWidget, new RetrieveFeedbackWidgetData() {
@Override public void onFinished(JSONObject retrievedWidgetData, String error) {
JSONArray questions = retrievedWidgetData.optJSONArray("questions");
Map<String, Object> segm = new HashMap<>();
Random rnd = new Random();
//iterate over all questions and set random answers
for (int a = 0; a < questions.length(); a++) {
JSONObject question = null;
try {
question = questions.getJSONObject(a);
} catch (JSONException e) {
e.printStackTrace();
}
String wType = question.optString("type");
String questionId = question.optString("id");
String answerKey = "answ-" + questionId;
JSONArray choices = question.optJSONArray("choices");
switch (wType) {
//multiple answer question
case "multi":
StringBuilder sb = new StringBuilder();
for (int b = 0; b < choices.length(); b++) {
if (b % 2 == 0) {//pick every other choice
if (b != 0) {
sb.append(",");
}
sb.append(choices.optJSONObject(b).optString("key"));
}
}
segm.put(answerKey, sb.toString());
break;
//radio buttons
case "radio":
//dropdown value selector
case "dropdown":
int pick = rnd.nextInt(choices.length());
segm.put(answerKey, choices.optJSONObject(pick).optString("key"));//pick the key of random choice
break;
//text input field
case "text":
segm.put(answerKey, "Some random text");
break;
//rating picker
case "rating":
segm.put(answerKey, rnd.nextInt(11));//put a random rating
break;
}
}
Countly.sharedInstance().feedback().reportFeedbackWidgetManually(widgetToReport, retrievedWidgetData, segm);
}
});