Dynamic messages
Choose automation messages according to website conditions, such as different greetings for new and returning visitors.
Main section: Initialization Parameters.
Settings Based on Website Conditions
The resolveRuntime(context) function in init selects the greeting and appearance based on the visitor and website page. Conditions are defined in website code, while channel settings specify which messages can be selected.
Different Messages for First and Repeat Conversations
In this example, a visitor with no dialogs sees one message, and a visitor with dialogs sees another. The automations can differ. First allow both automation and step pairs in greeting settings, then substitute their actual IDs:
const firstContact = {
mode: "automation_message",
automation_id: "FIRST_AUTOMATION_ID",
node_id: "FIRST_MESSAGE_STEP_UUID",
};
const returningContact = {
mode: "automation_message",
automation_id: "RETURNING_AUTOMATION_ID",
node_id: "RETURNING_MESSAGE_STEP_UUID",
};
SenlerWidget.init({
channel_id: "YOUR_CHANNEL_ID",
resolveRuntime(context) {
return {
welcome: context.dialogs.count === 0 ? firstContact : returningContact,
};
},
});
The branch for a visitor with dialogs selects the greeting for their next new chat, rather than greeting them again in the open conversation. Recognizing the same account across devices requires a signed user identity; anonymous history belongs to a browser session.
Page Conditions and Website Data
You can use the URL, the user's status in your service, and other data available to the website. For example, show a plan-selection message to a pricing-page visitor with no dialogs, while other visitors keep the base greeting:
SenlerWidget.init({
channel_id: "YOUR_CHANNEL_ID",
resolveRuntime(context) {
if (location.pathname === "/pricing" && context.dialogs.count === 0) {
return {
welcome: {
mode: "automation_message",
automation_id: "AUTOMATION_ID",
node_id: "MESSAGE_STEP_UUID",
},
};
}
return {};
},
});
// After navigation within the website without a page reload:
SenlerWidget.refreshRuntime();
First allow the message in greeting settings. Prepare your service's data before evaluation; context does not contain subscription or purchase status from your website. Call refreshRuntime() after these data change. Selection in website code does not grant visitors additional permissions.
Visitor Data and Application Order
context contains only facts about the current visitor in this channel:
channelId: the channel ID;visitor.isNew: the visitor record was created during this initialization, not an indication that they have no dialogs;visitor.identityVerified: the server has verified the visitor's identity;dialogs.count: their total dialog count in the channel, regardless of search or the current list page;currentDialog:{ id }of the selected real dialog, ornullin a new chat before communication starts and when nothing is selected, even if other dialogs exist.
The function runs after initialization, before the greeting is shown, and again when these facts change. Navigating between website pages does not itself change them: call refreshRuntime() for navigation and other website conditions.
The context is read-only. dialogs.count === 0 becomes true again after every dialog is deleted. visitor.isNew refers to a widget record created during the current initialization, not the first visit to the website itself.
Only welcome, lang, theme_mode, border_radius, and shell can be returned. Each result replaces this function's previous override; omitted fields inherit the current base settings, including init and updateRuntime. An empty object {} restores base settings, while welcome: null explicitly selects the greeting from channel settings.
Precedence: channel settings → init → updateRuntime → resolveRuntime result. Nested shell fields inherit individually.
This setting requires both the loader and widget app to support resolveRuntime. SDK integrations also need the refreshRuntime method and the SenlerWidgetRuntimeContext, SenlerWidgetResolvedRuntimeConfig, and SenlerWidgetRuntimeResolver types: updateRuntime support alone is not enough. In React, keep config stable, read changing conditions through a ref, and call api.refreshRuntime() after updating them.
The function must run synchronously and return an object, not a Promise. Prepare website data beforehand. If it throws, returns an invalid result, or does not respond, the widget uses base settings and logs a console warning. Without resolveRuntime and in button_only mode, refreshRuntime() changes nothing. This function is not for sending messages or switching dialogs: call those commands separately through the Public API.