webview
AuthTokenRequest
class
class AuthTokenRequest(val chatId: String, val reason: AuthTokenRequest.Reason)Member | Declaration | Description |
|---|---|---|
AuthTokenRequest | constructor(chatId: String, reason: AuthTokenRequest.Reason) | |
chatId | val chatId: String | |
reason | val reason: AuthTokenRequest.Reason | |
AuthTokenRequest.Reason
enum
enum Reason : Enum<AuthTokenRequest.Reason>Member | Declaration | Description |
|---|---|---|
INITIAL_CONNECT | INITIAL_CONNECT | |
EXPIRED | EXPIRED | |
entries | val entries: EnumEntries<AuthTokenRequest.Reason> | Returns a representation of an immutable list of all enum entries, in the order they're declared. This method may be used to iterate over the enum entries. |
valueOf | fun valueOf(value: String): AuthTokenRequest.Reason | Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.) Throws - kotlin.IllegalArgumentException: if this enum type has no constant with the specified name |
values | fun values(): Array<AuthTokenRequest.Reason> | Returns an array containing the constants of this enum type, in the order they're declared. This method may be used to iterate over the constants. |
ChatKindlyWebViewSDK
class
class ChatKindlyWebViewSDKThe Kindly web view SDK. Call its companion (KindlyWebViewSDK); instances are created by EntryPoint.start only (pattern of the native ChatKindlySDK).
ChatKindlyWebViewSDK.Companion
object
object Companion : EntryPointMember | Declaration | Description |
|---|---|---|
currentState | open override val currentState: KindlyEventState | The current state, without subscribing. |
enableCrashReporting | open override var enableCrashReporting: Boolean | Whether the SDK sends crash reports to Kindly. Defaults to true; applied at start. |
events | open override val events: Flow<KindlyEvent> | Every event: load, message, buttonclick, ui, globalicon and state. A hot stream with no replay: a subscriber sees the events emitted after it subscribed. Available before start. |
interface | open override var interface: KindlyWebViewInteraction? | Optional delegate for link interception. Kept across start and kill. |
state | open override val state: Flow<KindlyEventState> | The SDK state. A StateFlow underneath: a new subscriber gets the current value first. |
verboseLogging | open override var verboseLogging: Boolean | Whether the SDK logs at debug level. Defaults to false. Logs never contain chat content. |
authenticate | open override fun authenticate(): Deferred<Unit> | Re-authenticates the chat with the configured provider, for example after the user signs in. |
clearNewContext | open override fun clearNewContext() | Clears context set with setNewContext. |
close | open override fun close() | Dismisses the chat screen without ending the conversation. |
deauthenticate | open override fun deauthenticate(): Deferred<Unit> | Signs the user out of the chat without ending it; the chat continues anonymously. |
displayChat | open override fun displayChat(context: Context) | Shows the chat. Kept for compatibility; the same as launchChat without arguments. |
endChat | open override fun endChat(): Deferred<Unit> | Ends the conversation: the next display starts a new one. When the chat was never shown in this session the server is not notified; the stored session simply expires there. |
isSupported | open override fun isSupported(context: Context): Boolean | Whether this device's WebView can run the chat. When false, the chat shows an update screen. |
kill | open override fun kill(): Deferred<Unit> | Ends the conversation and stops the SDK. Call start again before anything else. |
launchChat | open override fun launchChat(context: Context, triggerDialogueId: String? = null, languageCode: String? = null) | Shows the chat. The first display creates the chat page; later ones show the same live chat instantly. Parameters - context: Context used to start the chat screen. - triggerDialogueId: Optional dialogue to trigger as the chat opens. - languageCode: Optional language for this display. A language different from the live chat's renders the chat again in that language. |
sendMessage | open override fun sendMessage(message: String, newContext: Map<String, String>? = null): Deferred<Unit> | Sends a message on behalf of the user. The chat must have been displayed (it can be hidden since); otherwise it fails with KindlyWebViewException.ChatNotReady. Parameters - message: The text; whitespace is trimmed and it must not be empty. - newContext: Optional context attached to this message only. |
setNewContext | open override fun setNewContext(context: Map<String, String>) | Context attached to the next message or button click. |
start | open override fun start(application: Application, botKey: String, languageCode: String = "en", market: String, authTokenProvider: KindlyAuthTokenProvider? = null, authCredentialsProvider: KindlyAuthCredentialsProvider? = null) | Initializes the SDK. The chat page is created on the first display, but the usage metrics start here, and the error reports unless enableCrashReporting is off, so an app that asks for the user's consent calls start after it. Whitespace around botKey, market and languageCode is trimmed. Calling it again with the same botKey and market keeps the live chat and only replaces the auth providers and the language, which applies to the next chat page (a launchChat with a languageCode switches the live chat now). Another bot or market closes the chat and starts over (the old conversation stays stored for that bot). Parameters - application: The application. - botKey: The bot key from the Kindly platform. - languageCode: The chat language (default en). - market: Required market slug, as configured for the bot (Settings → General → Details & markets). There is no fallback to another market. - authTokenProvider: Optional provider of a JWT for authenticated chat, called with the chat id whenever the chat needs a token, bounded at 15 s. - authCredentialsProvider: Optional provider of full KindlyAuthCredentials. Wins over authTokenProvider when both are set. |
triggerDialogue | open override fun triggerDialogue(id: String) | Triggers a dialogue in the live chat (opening the chat only if it is displayed). |
EntryPoint
interface
interface EntryPointThe Kindly web view SDK: Kindly's web chat widget in a native screen, with the same API as the native Kindly SDK. Use it through KindlyWebViewSDK (the companion of ChatKindlyWebViewSDK).
Every function can be called from any thread; the SDK hops to the main thread itself. The Deferred results fail with KindlyWebViewException.
Member | Declaration | Description |
|---|---|---|
currentState | abstract val currentState: KindlyEventState | The current state, without subscribing. |
enableCrashReporting | abstract var enableCrashReporting: Boolean | Whether the SDK sends crash reports to Kindly. Defaults to true; applied at start. |
events | abstract val events: Flow<KindlyEvent> | Every event: load, message, buttonclick, ui, globalicon and state. A hot stream with no replay: a subscriber sees the events emitted after it subscribed. Available before start. |
interface | abstract var interface: KindlyWebViewInteraction? | Optional delegate for link interception. Kept across start and kill. |
state | abstract val state: Flow<KindlyEventState> | The SDK state. A StateFlow underneath: a new subscriber gets the current value first. |
verboseLogging | abstract var verboseLogging: Boolean | Whether the SDK logs at debug level. Defaults to false. Logs never contain chat content. |
authenticate | abstract fun authenticate(): Deferred<Unit> | Re-authenticates the chat with the configured provider, for example after the user signs in. |
clearNewContext | abstract fun clearNewContext() | Clears context set with setNewContext. |
close | abstract fun close() | Dismisses the chat screen without ending the conversation. |
deauthenticate | abstract fun deauthenticate(): Deferred<Unit> | Signs the user out of the chat without ending it; the chat continues anonymously. |
displayChat | abstract fun displayChat(context: Context) | Shows the chat. Kept for compatibility; the same as launchChat without arguments. |
endChat | abstract fun endChat(): Deferred<Unit> | Ends the conversation: the next display starts a new one. When the chat was never shown in this session the server is not notified; the stored session simply expires there. |
isSupported | abstract fun isSupported(context: Context): Boolean | Whether this device's WebView can run the chat. When false, the chat shows an update screen. |
kill | abstract fun kill(): Deferred<Unit> | Ends the conversation and stops the SDK. Call start again before anything else. |
launchChat | abstract fun launchChat(context: Context, triggerDialogueId: String? = null, languageCode: String? = null) | Shows the chat. The first display creates the chat page; later ones show the same live chat instantly. Parameters - context: Context used to start the chat screen. - triggerDialogueId: Optional dialogue to trigger as the chat opens. - languageCode: Optional language for this display. A language different from the live chat's renders the chat again in that language. |
sendMessage | abstract fun sendMessage(message: String, newContext: Map<String, String>? = null): Deferred<Unit> | Sends a message on behalf of the user. The chat must have been displayed (it can be hidden since); otherwise it fails with KindlyWebViewException.ChatNotReady. Parameters - message: The text; whitespace is trimmed and it must not be empty. - newContext: Optional context attached to this message only. |
setNewContext | abstract fun setNewContext(context: Map<String, String>) | Context attached to the next message or button click. |
start | abstract fun start(application: Application, botKey: String, languageCode: String = "en", market: String, authTokenProvider: KindlyAuthTokenProvider? = null, authCredentialsProvider: KindlyAuthCredentialsProvider? = null) | Initializes the SDK. The chat page is created on the first display, but the usage metrics start here, and the error reports unless enableCrashReporting is off, so an app that asks for the user's consent calls start after it. Whitespace around botKey, market and languageCode is trimmed. Calling it again with the same botKey and market keeps the live chat and only replaces the auth providers and the language, which applies to the next chat page (a launchChat with a languageCode switches the live chat now). Another bot or market closes the chat and starts over (the old conversation stays stored for that bot). Parameters - application: The application. - botKey: The bot key from the Kindly platform. - languageCode: The chat language (default en). - market: Required market slug, as configured for the bot (Settings → General → Details & markets). There is no fallback to another market. - authTokenProvider: Optional provider of a JWT for authenticated chat, called with the chat id whenever the chat needs a token, bounded at 15 s. - authCredentialsProvider: Optional provider of full KindlyAuthCredentials. Wins over authTokenProvider when both are set. |
triggerDialogue | abstract fun triggerDialogue(id: String) | Triggers a dialogue in the live chat (opening the chat only if it is displayed). |
KindlyAuthCredentials
data class
data class KindlyAuthCredentials(val idToken: String? = null, val accessToken: String? = null, val issuer: String? = null, val expiresAt: Long? = null)The credentials the host app hands the SDK to authenticate a chat.
The Kindly platform verifies an authenticated chat in one of three ways, and this single type covers all of them — which is why nothing here is named after any one of them:
- Kindly JWT — a JWT your own backend signs. Only idToken is read; accessToken is ignored by this strategy.
- Identity provider (JWKS) — a JWT minted by your identity provider. Set accessToken as well when the provider hands you a separate access token; the backend then verifies the pair together and forwards the access token to your webhooks rather than the id token.
- Introspection — an opaque bearer token. Put it in idToken and set issuer so the backend knows which provider to introspect it against.
Every field is optional, but at least one of idToken / accessToken must be set - whichever is present becomes the Authorization: Bearer (see bearerToken). A single-JWT integration can keep returning a plain String from KindlyAuthTokenProvider and never touch this type at all.
Member | Declaration | Description |
|---|---|---|
KindlyAuthCredentials | constructor(idToken: String? = null, accessToken: String? = null, issuer: String? = null, expiresAt: Long? = null) | |
accessToken | val accessToken: String? | |
bearerToken | val bearerToken: String? | The token actually sent as Authorization: Bearer, or null when neither field was set. Authorization is mandatory on the backend's auth route, so whichever token the host has goes there — idToken first, falling back to accessToken. A provider that returns only an access token is a normal, supported case: the backend verifies it by whichever strategy the bot is configured for, exactly as it did before dual-token support existed. |
companionAccessToken | val companionAccessToken: String? | The access token in its companion role — the value that will be sent as X-Access-Token, or null when no companion header will be sent. Exposed so a host can see what the SDK will actually do rather than re-deriving the rule. It is null in two cases that are easy to get wrong: when the access token is itself the bearer (no id token was supplied), and when it merely duplicates the id token. The backend verifies the companion against the id token's at_hash and rejects a mismatched pair outright, so sending a duplicate would fail an auth that would otherwise have succeeded. |
expiresAt | val expiresAt: Long? | |
hasToken | val hasToken: Boolean | true when these credentials carry something usable. |
idToken | val idToken: String? | |
issuer | val issuer: String? | |
KindlyAuthCredentialsProvider
fun interface
fun interface KindlyAuthCredentialsProviderSupplies full authentication credentials to the SDK.
Use this instead of KindlyAuthTokenProvider when your identity provider issues more than a single JWT — a companion access token, an issuer the backend has to verify against, or an opaque token whose expiry only you know.
Same contract as KindlyAuthTokenProvider otherwise: the SDK calls it from its own coroutine and bounds the call at 15 seconds. KindlyAuthCredentials.expiresAt is Unix seconds; a value above 1e12 is read as milliseconds. Throw to signal failure.
Member | Declaration | Description |
|---|---|---|
fetchCredentials | abstract suspend fun fetchCredentials(request: AuthTokenRequest): KindlyAuthCredentials | |
KindlyAuthTokenProvider
fun interface
fun interface KindlyAuthTokenProviderMember | Declaration | Description |
|---|---|---|
fetchToken | abstract suspend fun fetchToken(request: AuthTokenRequest): String | |
KindlyWebViewException
sealed class
sealed class KindlyWebViewException : ExceptionThe failures the SDK's kotlinx.coroutines.Deferred results complete with. The same cases as the iOS KindlyWebViewError.
KindlyWebViewException.ChatNotReady
class
class ChatNotReady : KindlyWebViewExceptionThe call needs a chat page, and none is loaded. Display the chat first.
Member | Declaration | Description |
|---|---|---|
ChatNotReady | constructor() | |
KindlyWebViewException.InvalidArgument
class
class InvalidArgument(val argument: String) : KindlyWebViewExceptionAn argument failed validation. argument names it; the value is never included.
Member | Declaration | Description |
|---|---|---|
InvalidArgument | constructor(argument: String) | |
argument | val argument: String | |
KindlyWebViewException.NoAuthProvider
class
class NoAuthProvider : KindlyWebViewExceptionThe call needs an auth provider and EntryPoint.start received none.
Member | Declaration | Description |
|---|---|---|
NoAuthProvider | constructor() | |
KindlyWebViewException.NotStarted
class
class NotStarted : KindlyWebViewExceptionEntryPoint.start has not been called, or EntryPoint.kill ran since.
Member | Declaration | Description |
|---|---|---|
NotStarted | constructor() | |
KindlyWebViewException.Timeout
class
class Timeout : KindlyWebViewExceptionThe chat did not answer in time.
Member | Declaration | Description |
|---|---|---|
Timeout | constructor() | |
KindlyWebViewException.Unsupported
class
class Unsupported : KindlyWebViewExceptionThis device's WebView cannot run the chat. See EntryPoint.isSupported.
Member | Declaration | Description |
|---|---|---|
Unsupported | constructor() | |
KindlyWebViewException.WidgetError
class
class WidgetError(val code: String) : KindlyWebViewExceptionThe chat widget refused or failed the call. code is unknown_command, widget_error or unknown, the same values as on iOS, never text from the page.
Member | Declaration | Description |
|---|---|---|
WidgetError | constructor(code: String) | |
code | val code: String | |
KindlyWebViewInteraction
interface
interface KindlyWebViewInteractionOptional delegate for the Kindly web view SDK. Set it with KindlyWebViewSDK.interface; the SDK keeps it across EntryPoint.start and EntryPoint.kill.
Adapted from the native SDK's KindlySDKInteraction, keeping only shouldHandleLink.
Member | Declaration | Description |
|---|---|---|
shouldHandleLink | open suspend fun shouldHandleLink(url: String): Boolean | Called when the chat is about to open a link outside the app: an http, https, mailto, tel or sms link the user tapped in the chat. Links never open inside the chat itself. Return true to let the SDK open it (the system browser or the app registered for the scheme), or false to handle it yourself. The SDK asks off the main thread's navigation callback and waits at most 5 seconds; no answer, or an exception, counts as true. Parameters - url: The absolute URL the user tapped. |
KindlyWebViewSDK
typealias
typealias KindlyWebViewSDK = ChatKindlyWebViewSDKThe SDK entry point: KindlyWebViewSDK.start(...), KindlyWebViewSDK.launchChat(...), ...