-
Notifications
You must be signed in to change notification settings - Fork 0
Digital Feedback Scripting
Context object is the main object that contains all trigger functions.
var ctx = sdk()If a scenario template is used, the Context Object will be initialized automatically and can be accessed by
ctx
ctx.downloadSurvey(surveyID: string): Context// Example
ctx.downloadSurvey("<Survey ID: eg. p123456>");
// - Operation can be chained
ctx.downloadSurvey("<Survey ID: eg. p123456>")
.downloadSurvey("<Survey ID: eg. p123456>");// SDK only supports primitive types for values in JSObject
// - Start Web Survey
ctx.startWebSurvey(surveyID: string, data: JSObject = {})
// - Start Native Survey
ctx.startSurvey(surveyID: string, data: JSObject = {})// Example
ctx.startWebSurvey("<Survey ID: eg. p123456>");
ctx.startWebSurvey("<Survey ID: eg. p123456>", { "MyCustomDataKey": "MyCustomDataValue" });
ctx.startSurvey("<Survey ID: eg. p123456>", { "MyCustomDataKey": "MyCustomDataValue" });This is custom action and the app will be notified by callback onAppFeedback().
// - SDK only supports primitive types for values in JSObject
ctx.appFeedback(data: JSObject = {})// Example
ctx.appFeedback({ "MyCustomDataKey": "MyCustomDataValue" });// - SDK only supports primitive types for values in JSObject
ctx.events.on(eventName: string, callback: (data: JSObject) => void)// Example
ctx.events.on("<My Event Name>", function(data) {
// This callback will be called when app notifies matched event
// TriggerSDK.notifyEvent()
// Process data / conditions
var passedDataFromApp = data["MyCustomDataKey"];
...
// Process any actions
ctx.startSurvey("<Survey ID: eg. p123456>");
})Available: 3.2.0+
This event will be triggered after all scenarios are loaded in the system.
ctx.onStart(callback: () => void)// Example
ctx.onStart(function () {
// Some initilaization items
ctx.shared.myCount = 10;
});EventName.AppForeground
EventName.AppFeedback
// Available: 3.3.0+
EventName.BeaconEnter
EventName.BeaconExit// Example
ctx.events.on(EventName.AppForeground, function(data) {
...
})Available: 3.9.0+
Journey Tracking provides a way to track user journeys with the app. This information can be logged to a SmartHub Custom Data Table and can also be used to trigger a survey.
// Example
var hubId = 124;
var journeyName = "BookingJourney";
var customTableName = "BookingJourneyLog";
ctx.journey.start(hubId, journeyName, customTableName)
.add("BookingStarted")
.add("Schedule")
.add("BookingEnd")
.build();This function is called for every app call of TriggerSDK.addJourneyLog(data) and provides an opportunity to adjust incoming event data.
// Example
ctx.events.onJourneyLog(function(data) {
var userId = data["userId"];
var eventName = data["eventName"];
// edit and adjust incoming event data
...
// record this journey event
ctx.journey.record(userId, eventName, data);
});A journey ends when the postJourneyEventName is received.
Check isDropOff() to determine if journey was completed or abandoned.
// Example
ctx.events.onJourneyEnd(function(journey, postJourneyEventName) {
// should match columns from CustomTable Scheme
var serverRecord = {
rowId: journey.rowId,
completed: journey.completed,
userId: journey.userId,
journeyStartEvent: journey.getStart().name,
journeyLastEvent: journey.getLast().name,
postJourneyEvent: postJourneyEventName,
journeyDuration: journey.getDuration(),
journeyDropOff: journey.isDropOff(),
platform: ctx.getDeviceInfo().platform,
osVersion: ctx.getDeviceInfo().os
// additional custom data can also be stored as defined within SmartHub custom data table...
};
// send completed journey to Hub customdata table
// note: this doesn't send directly to server but queues within SDK storage for optimized transport
ctx.journey.send(journey.customTableName, serverRecord);
}// Journey Properties
interface Journey {
name: string;
events: JouneyEvent[];
rowId: string;
userId: string;
completed: Date;
getStart(): JourneyEvent; // get first event
getLast(): JourneyEvent; // get last event as part of the journey
getDuration(): number; // sum of all the events in seconds
isDropOff(): boolean; // was the journey abandoned
}
interface JourneyEvent {
name: string;
triggered: Date;
data: JSObject;
sincePreviousEvent(): number; // In-seconds
}Contact Frequency Rules provide a way to limit the frequency of prompting a specific individual user (contact) for a survey.
It also provides a way to check this limit across both web and mobile app channels so that if a user is on web and a mobile app,
it is possible to ensure that they are only requested feedback on one channel and not both, thus reducing the chance of a user feeling that "you already asked me about this in the app..."
Available: 3.4.0+
Within Digital Feedback scenario:
// Checking rule
ctx.checkCFR(surveyID: string, contactID: string, data: JSObject = {})
// Result
ResultStatus = "allow" | "deny" | "unknown" | "error"
ResultObject = {
status: ResultStatus,
eventId: string,
error: string
}
/*
Checking Contact Frequency Rule communicates with server to receive the latest status.
For this reason, as separate receiver event is required to obtain the result and allow an action to be taken.
(this is a very light and quick request but the timing can vary due to unknown mobile device connection)
*/
// Event to receive the result of the `checkCFR()` request
ctx.onCFR(surveyID: string, callback: (result: ResultObject, data: JSObject = {}) => void)// Example
ctx.events.on("<My Event Name>", function(data) {
// in most cases, the app would pass the currently logged in user from your app via data parameter
// the contact Id, can be an email, or simply an internal userId that only your system would know
var contactId = data["contactIdFromApp"];
ctx.checkCFR(surveyId, contactId, data)
});
ctx.onCFR(surveyId, function(result, data) {
if (result.status !== 'deny' && result.eventId === "<My Event Name>") {
// When CFR passed / is successful, this usually means that for this user/contact and for this event, they meet the frequency rules, therefor show a survey
ctx.startSurvey(surveyId, data)
}
if (result.error !== "") {
// If there is error -> eg) Network failure
}
});Program Variables are stored locally on device and are shared between scenarios. If a value doesn't exist for the key, the functions will return null.
ctx.set(key: string, value: any)
ctx.getInt(key: string, defaultValue: number?): number | null
ctx.getString(key: string, defaultValue: string?): string | null
ctx.getDate(key: string, defaultValue: Date?): Date | null
ctx.getNumber(key: string, defaultValue: number?): number | null
// Available: 3.12.0+
ctx.getAll(): { [key: string] : string }
ctx.getBool(key: string, defaultValue: boolean?): boolean | nullWith default value
// Example
var variableKey = "currentCount";
ctx.events.on("<My Event Name>", function(data) {
var currentCount = ctx.getInt(variableKey, 0);
if(currentCount > 10) {
ctx.startSurvey("<Survey ID>");
ctx.set("currentCount", 0);
} else {
ctx.set("currentCount", currentCount + 1);
}
})Without default value but check for null
// Example
var variableKey = "currentCount";
ctx.events.on("<My Event Name>", function(data) {
var currentCount = ctx.getInt(variableKey);
if (currentCount == null) {
ctx.set(variableKey, 0);
}
if(currentCount > 10) {
ctx.startSurvey("<Survey ID>");
ctx.set("currentCount", 0);
} else {
ctx.set("currentCount", currentCount + 1);
}
})Program counters are updated when programDownload is called so are evaluated immediately and may not reflect the latest count available at the time of the event.
ctx.getCounters(surveyID: string): { completesTotal: number, completesCurrentHour: number, completesCurrentDay: number, completesCurrentWeek: number }// Example
var variableKey = "currentCount";
ctx.events.on("<My Event Name>", function(data) {
var counters = ctx.getCounters("<Survey ID");
counters.completesTotal;
counters.completesCurrentHour;
counters.completesCurrentDay;
counters.completesCurrentWeek;
...
})Available: 3.2.0+
To share values / functions between scenarios, you can utilize shared variable in ctx.
// Set value
ctx.shared.mySharedValue = 1;
// Get value
var myValue = ctx.shared.mySharedValue; // Result: 1
// Set Function / Call Function
ctx.shared.addNumber = function(value1, value2) {
return value1 + value2;
}
var addedResult = ctx.shared.addNumber(1, 2); // Result: 3Available: 3.1.0+
ctx.getSDKInfo(): {
hostAppVersion: string
sdkVersion: string
}Available: 3.1.0+
ctx.getDeviceInfo(): {
os: string // - OS version
uniqueID: string // - Value provided from UniqueID provider in app
platform: string // - iOS | Android
model: string
}Available: 3.3.0+
BeaconObject = { uuid: string, major: number | null, minor: number | null }var beaconInfo = data['beaconInfo'];
data['uuid'] = beaconInfo.uuid;
data['major'] = beaconInfo.major;
data['minor'] = beaconInfo.minor;Copyright © 2026 Forsta. All rights reserved.
- Initializing the SDK
- Download a Program
- Sending App Events
- Sending Journey Log
- Survey Triggering
- Displaying a Survey
- Forsta Plus Server
- Program Lifecycle Monitoring
- Starting and Updating a Program
- Advanced Trigger Control