跳转到主要内容

Documentation Index

Fetch the complete documentation index at: https://docs.kontext.so/llms.txt

Use this file to discover all available pages before exploring further.

这是 5 分钟接入的完整流程。开始之前,请确认你已经完成 安装

1. 创建会话

入口是 KontextAds.createSession(context, options),它返回一个 Session——后续整个对话生命周期都通过它来操作。
import so.kontext.ads.KontextAds
import so.kontext.ads.model.Character
import so.kontext.ads.model.SessionOptions

val session = KontextAds.createSession(
    context = applicationContext,
    options = SessionOptions(
        publisherToken = "<your-publisher-token>",
        userId = "user-1234",
        conversationId = "conv-5678",
        character = Character(
            id = "character-1234",
            name = "John Doe",
            avatarUrl = "https://example.com/avatar.png",
            greeting = "Hello, how can I help you today?",
        ),
        onEvent = { event ->
            // 处理广告生命周期事件
            android.util.Log.d("kontext", "${event.name} $event")
        },
    ),
)
会话在其生命周期内会固定 publisherTokenuserIdconversationId。当这些值变化时(例如用户开始新对话),请重建会话。
请传入 context.applicationContext 而不是 Activity 上下文——Session 的生命周期通常长于任意单个 Activity,SDK 会内部管理 WebView 资源。

2. 喂入对话消息

每条消息出现时都要 add 到会话中。用户消息会在后台触发一次防抖后的预加载;助手消息让 SDK 把匹配到的广告绑定到对应的广告位上。
import so.kontext.ads.model.Message
import so.kontext.ads.model.Role

session.addMessage(
    Message(id = "msg-1", role = Role.USER, content = "Hello, how are you?"),
)

session.addMessage(
    Message(id = "msg-2", role = Role.ASSISTANT, content = "I am good, thank you!"),
)
addMessage(...) 是同步返回的——它不是 suspend 函数。预加载的结果会稍后通过 onEvent 回调送达(FilledNoFillError ……)——不会通过返回值返回。

3. 渲染广告

推荐使用 InlineAd composable。传入助手消息的 messageIdSession 即可,剩下的它都会处理:
import androidx.compose.runtime.Composable
import so.kontext.ads.ui.InlineAd

@Composable
fun ChatRow(message: ChatMessage, session: Session) {
    MessageBubble(message)

    if (message.role == Role.ASSISTANT) {
        InlineAd(messageId = message.id, session = session)
    }
}
InlineAd 在重组之间是幂等的——它内部调用 session.createAd(messageId),对同一个 (messageId, code, theme) 已存在的 Ad 直接复用。把广告滚出可视区再滚回来不会重建 iframe。 如果你的应用没有使用 Compose,请改用 InlineAdView——见 实践指南 → View 互操作

4. 释放资源

对话结束或页面关闭时调用 session.destroy()。该方法是幂等的,且是取消待处理网络请求、释放 WebView 资源的必要操作。 在 Compose 中:
DisposableEffect(session) {
    onDispose { session.close() } // 等价于 session.destroy()
}

订阅事件

AdEvent 既可以通过 SessionOptions 里的 onEvent 回调拿到,也可以通过 Session.events Flow 拿到——任选其一。两者会在主线程上送达相同的事件。

onEvent 回调

val session = KontextAds.createSession(
    context = applicationContext,
    options = SessionOptions(
        publisherToken = "...",
        userId = "...",
        conversationId = "...",
        onEvent = { event ->
            when (event) {
                is AdEvent.Filled -> println("ad filled: ${event.bidId} revenue=${event.revenue}")
                is AdEvent.Clicked -> println("clicked: ${event.url}")
                else -> Unit
            }
        },
    ),
)

Flow

import kotlinx.coroutines.flow.collect

lifecycleScope.launch {
    session.events.collect { event ->
        println("event: ${event.name}")
    }
}
完整事件列表见 API 参考