Skip to content

Commit

Permalink
Added a method for feedback widget segmentation (#438)
Browse files Browse the repository at this point in the history
* added feedback widget segmentation

* lint

* changes

* Update CHANGELOG.md

* send a custom object instead of segmentation

* changelog improvement

* more succint example

* changelog

* jsdoc for optionals

* optional

---------

Co-authored-by: Artūrs Kadiķis <kadikis.arturs@gmail.com>
  • Loading branch information
turtledreams and ArtursKadikis committed Nov 9, 2023
1 parent 23b1855 commit 8fca557
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 50 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 23.6.3
- You can now add segmentation while presenting a widget with 'present_feedback_widget'

## 23.6.2
- Adding app version information to every request

Expand Down
84 changes: 37 additions & 47 deletions examples/examples_feedback_widgets.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,27 @@
}

// Decide which which widget to show. Here the first rating widget is selected.
var i = countlyPresentableFeedback.length - 1;
var countlyFeedbackWidget = countlyPresentableFeedback[0];
while (i--) {
// You can change 'rating' to 'nps' or 'survey'. Or you can create your own logic here.
if (countlyPresentableFeedback[i].type === 'rating') {
countlyFeedbackWidget = countlyPresentableFeedback[i];
break;
}
const widgetType = "rating";
const countlyFeedbackWidget = countlyPresentableFeedback.find(widget => widget.type === widgetType);
if (!countlyFeedbackWidget) {
console.error(`[Countly] No ${widgetType} widget found`);
return;
}

// Define the element ID and the class name (optional)
var selectorId = "";
var selectorClass = "";
const selectorId = "";
const selectorClass = "";

// Define the segmentation (optional)
const segmentation = { page: "home_page" };

// Display the feedback widget to the end user
Countly.present_feedback_widget(countlyFeedbackWidget, selectorId, selectorClass);
Countly.present_feedback_widget(countlyFeedbackWidget, selectorId, selectorClass, segmentation);
}


//=================================================
// Fetching and reporting feedback widgets manually
//=================================================
var CountlyFeedbackWidget;
var CountlyWidgetData;
// an example of getting the widget list, using it to get widget data and then recording data for it manually. widgetType can be 'nps', 'survey' or 'rating'
function getFeedbackWidgetListAndDoThings(widgetType) {
// get the widget list
Expand All @@ -66,43 +63,36 @@
}

// find the widget object with the given widget type. This or a similar implementation can be used while using fetchAndDisplayWidget() as well
var i = feedbackList.length - 1;
while (i--) {
if (feedbackList[i].type === widgetType) {
CountlyFeedbackWidget = feedbackList[i];
break;
}
const countlyFeedbackWidget = feedbackList.find(widget => widget.type === widgetType);
if (!countlyFeedbackWidget) {
console.error(`[Countly] No ${widgetType} widget found`);
return;
}

// if the widget object is found
if (CountlyFeedbackWidget) {
// Get data with the widget object
Countly.getFeedbackWidgetData(CountlyFeedbackWidget,
// callback function, 1st param is the feedback widget data
function (feedbackData, err) {
if (err) { // error handling
console.log(err);
return;
}

CountlyWidgetData = feedbackData;
// record data according to the widget type
if (CountlyWidgetData.type === 'nps') {
Countly.reportFeedbackWidgetManually(CountlyFeedbackWidget, CountlyWidgetData, { rating: 3, comment: "comment" });
} else if (CountlyWidgetData.type === 'survey') {
var widgetResponse = {};
// form the key/value pairs according to data
widgetResponse["answ-" + CountlyWidgetData.questions[0].id] = CountlyWidgetData.questions[0].type === "rating" ? 3 : "answer";
Countly.reportFeedbackWidgetManually(CountlyFeedbackWidget, CountlyWidgetData, widgetResponse);
} else if (CountlyWidgetData.type === 'rating') {
Countly.reportFeedbackWidgetManually(CountlyFeedbackWidget, CountlyWidgetData, { rating: 3, comment: "comment", email: "email", contactMe: true });
}
// Get data with the widget object
Countly.getFeedbackWidgetData(CountlyFeedbackWidget,
// callback function, 1st param is the feedback widget data
function (feedbackData, err) {
if (err) { // error handling
console.error(err);
return;
}

);
} else {
console.error("The widget type you are looking for does not exist")
}
const CountlyWidgetData = feedbackData;
// record data according to the widget type
if (CountlyWidgetData.type === 'nps') {
Countly.reportFeedbackWidgetManually(CountlyFeedbackWidget, CountlyWidgetData, { rating: 3, comment: "comment" });
} else if (CountlyWidgetData.type === 'survey') {
var widgetResponse = {};
// form the key/value pairs according to data
widgetResponse["answ-" + CountlyWidgetData.questions[0].id] = CountlyWidgetData.questions[0].type === "rating" ? 3 : "answer";
Countly.reportFeedbackWidgetManually(CountlyFeedbackWidget, CountlyWidgetData, widgetResponse);
} else if (CountlyWidgetData.type === 'rating') {
Countly.reportFeedbackWidgetManually(CountlyFeedbackWidget, CountlyWidgetData, { rating: 3, comment: "comment", email: "email", contactMe: true });
}
}

);
})
}
</script>
Expand Down
20 changes: 17 additions & 3 deletions lib/countly.js
Original file line number Diff line number Diff line change
Expand Up @@ -3064,11 +3064,14 @@
/**
* Present the feedback widget in webview
* @param {Object} presentableFeedback - Current presentable feedback
* @param {String} id - DOM id to append the feedback widget
* @param {String} className - Class name to append the feedback widget
* @param {String} [id] - DOM id to append the feedback widget (optional, in case not used pass undefined)
* @param {String} [className] - Class name to append the feedback widget (optional, in case not used pass undefined)
* @param {Object} [feedbackWidgetSegmentation] - Segmentation object to be passed to the feedback widget (optional)
* */
this.present_feedback_widget = function(presentableFeedback, id, className) {
this.present_feedback_widget = function(presentableFeedback, id, className, feedbackWidgetSegmentation) {
// TODO: feedbackWidgetSegmentation implementation only assumes we want to send segmentation data. Change it if we add more data to the custom object.
log(logLevelEnums.INFO, "present_feedback_widget, Presenting the feedback widget by appending to the element with ID: [ " + id + " ] and className: [ " + className + " ]");

if (!this.check_consent(featureEnums.FEEDBACK)) {
return;
}
Expand All @@ -3081,6 +3084,12 @@
return;
}

log(logLevelEnums.INFO, "present_feedback_widget, Adding segmentation to feedback widgets:[" + JSON.stringify(feedbackWidgetSegmentation) + "]");
if (!feedbackWidgetSegmentation || typeof feedbackWidgetSegmentation !== "object" || Object.keys(feedbackWidgetSegmentation).length === 0) {
log(logLevelEnums.DEBUG, "present_feedback_widget, Segmentation is not an object or empty");
feedbackWidgetSegmentation = null;
}

try {
var url = this.url;

Expand Down Expand Up @@ -3125,6 +3134,11 @@
url += "&platform=" + this.platform;
url += "&app_version=" + this.app_version;
url += "&sdk_version=" + SDK_VERSION;
if (feedbackWidgetSegmentation) {
var customObjectToSendWithTheWidget = {};
customObjectToSendWithTheWidget.sg = feedbackWidgetSegmentation;
url += "&custom=" + JSON.stringify(customObjectToSendWithTheWidget);
}
// Origin is passed to the popup so that it passes it back in the postMessage event
// Only web SDK passes origin and web
url += "&origin=" + passedOrigin;
Expand Down

0 comments on commit 8fca557

Please sign in to comment.