Reach and engage your users directly through Countly’s interaction tools. Use Journeys to guide them with various personalized contents, Feedback Widgets to capture insights in real time, and Push Notifications to re-engage them with timely updates and offers. Together, these features help you create meaningful, targeted user experiences that drive engagement and retention.
The Journeys and Feedback Widgets features are available in Countly Enterprise and as an add-on in Flex.
Journeys
To understand how you can leverage Journeys in your dashboard check here.
To enable the Journeys feature:
Countly.q.push(() => { Countly.content.enterContentZone(); });
// or
Countly.q.push(['content.enterContentZone']);Countly.content.enterContentZone();Countly.sharedInstance().contents().enterContentZone()
[Countly.sharedInstance.content enterContentZone];
Countly.sharedInstance().content().enterContentZone();
Countly.instance.content.enterContentZone()Countly.content.enterContentZone()
Not supported.
Not supported.
curl --request POST \
--url 'https://YOUR_SERVER/o/sdk/content' \
--header 'Accept: application/json' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'app_key=APP_KEY' \
--data 'device_id=DEVICE_ID' \
--data 'sdk_name=SDK_NAME' \
--data 'sdk_version=SDK_VERSION' \
--data 'av=APP_VERSION' \
--data 'timestamp=TIMESTAMP' \
--data 'hour=HOUR' \
--data 'dow=DAYOFTHEWEEK' \
--data 'tz=TIMEZONE' \
--data 'resolution={"l":{"w":WIDTH_DP,"h":HEIGHT_DP},"p":{"w":WIDTH_DP,"h":HEIGHT_DP}}' \ # "l": landscape, "p": portrait
--data 'la=ISO_LANGUAGE_CODE' \
--data 'dt=DEVICE_TYPE' #[console, mobile, tablet, smarttv, wearable, embedded, desktop]
You should expect the responses to be:
# 200
{
"html": "CONTENT_URL_TO_BE_SHOWN_WITH_WEBVIEW",
"geo": {
"l": { // Landscape layout in DP
"x": LANDSCAPE_X_DP,
"y": LANDSCAPE_Y_DP,
"w": LANDSCAPE_WIDTH_DP,
"h": LANDSCAPE_HEIGHT_DP
},
"p": { // Portrait layout in DP
"x": PORTRAIT_X_DP,
"y": PORTRAIT_Y_DP,
"w": PORTRAIT_WIDTH_DP,
"h": PORTRAIT_HEIGHT_DP
}
}
}
# 200 - No content
{
"result": "No content block found!"
}
Feedback Widgets
To understand how you can leverage Feedback Widgets in your dashboard check here.
To show a Feedback Widget according to its name, tag, ID or just the type (with no param):
// default no param use to show first available widget
Countly.q.push(() => { Countly.feedback.showNPS(); });
Countly.q.push(() => { Countly.feedback.showSurvey(); });
Countly.q.push(() => { Countly.feedback.showRating(); });
// or
Countly.q.push(() => { Countly.feedback.showNPS("nameTagOrID"); });
Countly.q.push(() => { Countly.feedback.showSurvey("nameTagOrID"); });
Countly.q.push(() => { Countly.feedback.showRating("nameTagOrID"); });
// or
Countly.q.push(["feedback.showNPS", "nameTagOrID"]);
Countly.q.push(["feedback.showSurvey", "nameTagOrID"]);
Countly.q.push(["feedback.showRating", "nameTagOrID"]);// default no param use to show first available widget
Countly.feedback.showNPS();
Countly.feedback.showSurvey();
Countly.feedback.showRating();
// or
Countly.feedback.showNPS("nameTagOrID");
Countly.feedback.showSurvey("nameTagOrID");
Countly.feedback.showRating("nameTagOrID");// easiest way to show first available widget Countly.sharedInstance().feedback().presentNPS(Context context) Countly.sharedInstance().feedback().presentRating(Context context) Countly.sharedInstance().feedback().presentSurvey(Context context) // or Countly.sharedInstance().feedback().presentNPS(Context context, String nameIDorTag) Countly.sharedInstance().feedback().presentRating(Context context, String nameIDorTag) Countly.sharedInstance().feedback().presentSurvey(Context context, String nameIDorTag)
// easiest way to show first available widget [Countly.sharedInstance.feedback presentNPS]; [Countly.sharedInstance.feedback presentSurvey]; [Countly.sharedInstance.feedback presentRating]; // or [Countly.sharedInstance.feedback presentNPS:@"nameIDorTag"]; [Countly.sharedInstance.feedback presentSurvey:@"nameIDorTag"]; [Countly.sharedInstance.feedback presentRating:@"nameIDorTag"];
// easiest way to show first available widget
Countly.sharedInstance().feedback().presentNPS()
Countly.sharedInstance().feedback().presentSurvey()
Countly.sharedInstance().feedback().presentRating()
// or
Countly.sharedInstance().feedback().presentNPS("nameIDorTag")
Countly.sharedInstance().feedback().presentSurvey("nameIDorTag")
Countly.sharedInstance().feedback().presentRating("nameIDorTag")Countly.instance.feedback.presentNPS([String? nameIDorTag, FeedbackCallback? feedbackCallback]) Countly.instance.feedback.presentRating([String? nameIDorTag, FeedbackCallback? feedbackCallback]) Countly.instance.feedback.presentSurvey([String? nameIDorTag, FeedbackCallback? feedbackCallback])
// easiest way to show first available widget
Countly.feedback.presentNPS();
Countly.feedback.presentSurvey();
Countly.feedback.presentRating();
// or
Countly.feedback.presentNPS("nameTagOrID", () => {
console.log("Widget shown");
}, () => {
console.log("Widget closed");
});
Countly.feedback.presentSurvey("nameTagOrID");
Countly.feedback.presentRating("nameTagOrID");Not supported.
The Java SDK does not provide a built-in presentation mechanism. Instead, it returns a generated URL, which you can display using a WebView implementation.
Countly.instance().feedback().constructFeedbackWidgetUrl(chosenWidget, (constructedUrl, error) - {
// handle error and the constructed url
});
curl --request POST \ --url 'https://YOUR_SERVER/o/sdk' \ --header 'Accept: application/json' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data 'app_key=APP_KEY' \ --data 'device_id=DEVICE_ID' \ --data 'method=feedback' \ --data 'sdk_name=SDK_NAME' \ --data 'sdk_version=SDK_VERSION' \ --data 'av=APP_VERSION' \ --data 'timestamp=TIMESTAMP' \ --data 'hour=HOUR' \ --data 'dow=DAYOFTHEWEEK'
You should expect the responses to be:
# 200
{
"result": [
{
"_id": "WIDGET_ID",
"type": "WIDGET_TYPE", # [rating, nps, survey]
"name": "WIDGET_NAME",
"wv": "WIDGET_VERSION",
"tg": ["TAGS"],
...
},
...
]
}
# 200 - No widget
{
"result": []
}
This call fetches all available feedback widgets from the server. The widget to be presented can be filtered from the result array.
To present a feedback widget, you can generate a URL and display it inside a WebView.
https://YOUR_SERVER/feedback/{WIDGET_TYPE}?widget_id={WIDGET_ID}&device_id={DEVICE_ID}&app_key={APP_KEY}&sdk_version={SDK_VERSION}&sdk_name={SDK_NAME}&platform={PLATFORM}&custom={"tc":1,"rw":1,"xb":1} #platform: [android, ios, web, desktop]
More information about feedback widgets can be found here.
Push Notifications
To understand how you can leverage Push Notifications in your dashboard check here.
Not supported.
Countly SDK supports FCM and Huawei Push Kit as push notification service providers.
CountlyConfigPush countlyConfigPush = new CountlyConfigPush(this).setProvider(Countly.CountlyMessagingProvider.FCM); // or HMS CountlyPush.init(countlyConfigPush);
For Push Notification setup you should check here.
#import "Countly.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Start Countly with CLYPushNotifications feature as follows
CountlyConfig* config = CountlyConfig.new;
config.appKey = @"APP_KEY";
config.host = @"https://SERVER_URL";
config.features = @[CLYPushNotifications];
//config.pushTestMode = CLYPushTestModeDevelopment;
[Countly.sharedInstance startWithConfig:config];
//Ask for user's permission for Push Notifications (not necessarily here)
//You can do this later at any point in the app after starting Countly
[Countly.sharedInstance askForNotificationPermission];
// your code
return YES;
}func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
//Start Countly with CLYPushNotifications feature as follows
let config: CountlyConfig = CountlyConfig()
config.appKey = "APP_KEY"
config.host = "https://SERVER_URL"
config.features = [CLYPushNotifications]
//config.pushTestMode = CLYPushTestModeDevelopment
Countly.sharedInstance().start(with: config)
//Ask for user's permission for Push Notifications (not necessarily here)
//You can do this later at any point in the app after starting Countly
Countly.sharedInstance().askForNotificationPermission()
// your code
return true
}For Push Notification setup you should check here.
// Set messaging mode to your need before init
Countly.pushTokenType(Countly.messagingMode["TEST"]);
// This method will ask for permission, enables push notification and send push token to countly server
Countly.askForNotificationPermission();
// for handling received notification
Countly.onNotification((String notification) {
// ...
});
For Push Notification setup you should check here.
// set messaging mode to your need before init
countlyConfig.setPushTokenType(Countly.messagingMode.DEVELOPMENT);
// after init to ask for permission and enable the feature
Countly.askForNotificationPermission();
For Push Notification setup you should check here.
// set messaging mode for your need before init
.SetNotificationMode(TestMode.AndroidTestToken);
For Push Notification setup you should check here.
Not supported.
Push notifications are platform-specific, and not all platforms support them. Currently, only iOS and Android are supported. To use this feature, a platform-specific token must be reported to the server:
curl --request GET \
--url 'https://YOUR_SERVER/i?token_session=1&{android_token=ANDROID_PUSH_TOKEN or ios_token=IOS_PUSH_TOKEN}&app_key=APP_KEY&device_id=DEVICE_ID&sdk_name=SDK_NAME&sdk_version=SDK_VERSION&av=APP_VERSION×tamp=TIMESTAMP&hour=HOUR&dow=DAYOFTHEWEEK&tz=TIMEZONE' \
--header 'Accept: application/json'
You should expect the responses to be:
# 200
{
"result": "Success"
}
More information about the request calls can be found here and the feature can be found here.