Android Installation

If you are only targeting Android the dependency is:

dependencies {
    [...]
+   implementation("ai.botstacks:chat-sdk-android:{version}")
    [...]
}
To setup android click here

Compose Multiplatform Installation

Add ai.botstacks:chat-sdk:{version} to your dependencies

val commonMain by getting {
    dependencies {
        [...]
+       implementation("ai.botstacks:chat-sdk:{version}")
        [...]
    }
}

To setup Compose Multiplatform click here

Initialization Compose Multiplatform

In order to display any of the UI components and access chat data, you must first initialize the SDK and log in as a chat user.

Step 1. Initialization

In your Application class, call BotStacksChat.shared.setup with your API key. You can obtain your API key from the Botstacks Dashboard. If you don’t yet have one, you can create one for FREE!

If you don’t have an Application class, create one.

class App : Application() {

    override fun onCreate() {
        super.onCreate()
+       BotStacksChat.shared.setup(
+           context = this,
+           apiKey = "your-api-key"
+       )
    }
}

Note, you can optionally delay load and later call BotStacksChat.shared.load to load BotStacks in whatever load sequence you wish.

If you’d like Giphy support in your chats, send your Giphy API key during setup.

BotStacksChat.shared.setup(
    context = this,
    apiKey = "your_botstacks_api_key",
    giphyApiKey = "your_giphy_api_key"
)

Step 2. Logging in

Nearly all functionality is within the context of a chat user. That said, you must first be logged in as a chat user in order to appropriately display the UI components.

To log in, call the login function prior to displaying any UI components. Below is an example of how to accomplish this.

val composeScope = rememberCoroutineScope()
composeScope.launch {
    BotStacksChat.shared.login(
        "user-identifier",
        "username"
    ) // optionally pass displayName and picture
    if (BotStacksChat.shared.isUserLoggedIn) {
        // handle logged in state change
    }
}

Step 3. Render the UI

The BotStacks UI Kit uses Jetpack Compose. You can add it to any NavHost by rendering inside an BotStacksThemeEngine and adding the BotStacksChatController. Customization controls for the Theme Engine are described below.

BotStacksThemeEngine {
    NavHost(navController = navController, startDestination = "splash") {
        val openChat = {
            navController.navigate("chats")
        }
        composable("splash") {
            Splash(openChat = openChat, openLogin = {
                navController.navigate("login")
            })
        }
        composable("login") {
            Login(openChat)
        }

        composable("chats") {
           BotStacksChatController(onLogout = { navController.navigate("login") })
        }
    }
}

Step 4. Push Notifications (Firebase Cloud Messaging)

For push notifications via FCM, just pass your push token to BotStacks.

BotStacksChat.registerFCMToken(token)

Compose Multiplatform Environment Setup

Our Chat SDK uses Moko Resources to include the internal assets in the SDK for iOS.

Since iOS doesn’t bundle resources for static frameworks, we have to add the Moko resource plugin and setup the environment properly for inclusion.

Step 1: Update Gradle

build.gradle.kts

buildscript {
    dependencies {
        // required for now to include resources from Chat SDK
+       classpath(libs.moko.resources.generator)
    }
}
shared/build.gradle.kts

plugins {
    // required for now to include resources from Chat SDK
+   id("dev.icerock.mobile.multiplatform-resources")
}

kotlin {
    [...]
    sourceSets {
        [...]
+       val iosX64Main by getting
+       val iosArm64Main by getting
+       val iosSimulatorArm64Main by getting

        iosMain {
+           dependsOn(commonMain.get())
+           iosX64Main.dependsOn(this)
+           iosArm64Main.dependsOn(this)
+           iosSimulatorArm64Main.dependsOn(this)
            dependencies {
                // required for now to include resources from Chat SDK
+               implementation(libs.moko.resources)
            }
        }
    }
}

Step 2: Add Build Phase to XCode

Per the documentation from Moko here, we need to add a Run Script Build Phase with the following script:

cd "$SRCROOT/.."

./gradlew :shared:copyFrameworkResourcesToApp \
    -Pmoko.resources.BUILT_PRODUCTS_DIR="$BUILT_PRODUCTS_DIR" \
    -Pmoko.resources.CONTENTS_FOLDER_PATH="$CONTENTS_FOLDER_PATH" \
    -Pkotlin.native.cocoapods.platform="$PLATFORM_NAME" \
    -Pkotlin.native.cocoapods.archs="$ARCHS" \
    -Pkotlin.native.cocoapods.configuration="$CONFIGURATION"

Be sure to update shared with the name of your shared module. The Multiplatform Wizard usually uses shared or composeApp.

Step 3: Setup Cocoapods

Add a podfile with GoogleMaps and Giphy:

target 'iosApp' do
#   use_frameworks!
  platform :ios, '15.0'

+ pod 'GoogleMaps', '8.4.0'
+ pod 'Giphy', '2.2.8'
end

Setup cocoapods in gradle:

plugins {
+   kotlin("native.cocoapods")
}
kotlin {
    [...]
    cocoapods {
        name = "shared"
        version = "1.0"
        homepage = "https://botstacks.ai"
        summary = "Some cool story"
        ios.deploymentTarget = "15.0"

        podfile = file("../iosApp/Podfile")

        framework {
            baseName = "shared"
            isStatic = true
        }

        pod("Giphy") {
            moduleName = "GiphyUISDK"
            version = "2.2.8"
            extraOpts += listOf("-compiler-option", "-fmodules")
        }

        pod("GoogleMaps") {
            version = "8.4.0"
            extraOpts += listOf("-compiler-option", "-fmodules")
        }
    }
}

Android Initialization

Step 1: Initialize the SDK

In each platform (Android/iOS), call BotStacksChat.shared.setup with your API key. You can obtain your API key from the Botstacks Dashboard. If you don’t yet have one, you can create one for FREE!

Android

main.android.kt

@Composable
fun MainView() {
    BotStacksChat.shared.setup(
        context = LocalContext.current,
        apiKey = stringResource(R.string.botstacks_api_key),
    )

    App()
}

iOS

main.ios.kt

fun MainViewController() = ComposeUIViewController(
    configure = {
        onFocusBehavior = OnFocusBehavior.DoNothing
    }
) {
    val apiKey = readPlist<String>("AppSecrets", "BOTSTACKS_API_KEY") ?: throw IllegalArgumentException("BotStacks API Key not provided")

    BotStacksChat.shared.setup(
        apiKey = apiKey,
    )

    App()
}
App.kt

@Composable
fun App() {
    BotStacksThemeEngine {
        AppNavigation()
    }
}

Note, you can optionally delay load and later call BotStacksChat.shared.load to load BotStacks in whatever load sequence you wish.

If you’d like Giphy support in your chats, send your Giphy API key during setup.

Step 2: Logging in

Nearly all functionality is within the context of a chat user. That said, you must first be logged in as a chat user in order to appropriately display the UI components.

To log in, call the login function prior to displaying any UI components. Below is an example of How to accomplish this.

val composeScope = rememberCoroutineScope()
composeScope.launch {
    BotStacksChat.shared.login(
        "user-identifier",
        "username"
    ) // optionally pass displayName and picture
    if (BotStacksChat.shared.isUserLoggedIn) {
        // handle logged in state change
    }
}

Step 3: Render the UI

The BotStacks UI Kit uses Jetpack Compose (Multiplatform). There is a plethora of navigation protocols for Compose Multiplatform, so pick whatever one works best for your app.

Our Sample uses Voyager. To implement the controller screen, we create a common approach that provides platform-specific bottom sheet implementations for both iOS and Android. This ensures that our apps remain consistent with the respective platforms they run on.

data class ChatScreen: Screen {
    override val key = uniqueScreenKey

    @Composable
    override fun Content() {
        val navigator = LocalPlatformNavigator.current
 +      BotStacksChatController { navigator.replaceAll(LoginScreen) }
    }
}

Step 4: Theming

You can theme your BotStacks UI kit by modifying the defaults of the BotStacksThemeEngine. The theme supports fonts, colors, assets, and dimensions. Configure it like this:

BotStacksThemeEngine(
    // true or false to force theming one way (default follows system)
    useDarkTheme = isSystemInDarkTheme(),
    // color scheme for light mode
    lightColorScheme = lightBotStacksColors(
        primary = Purple40,
        onPrimary = Color.White,
    ),
    // color scheme for dark mode
    darkColorScheme = darkBotStacksColors(
        primary = Purple80,
        onPrimary = Color.Black
    ),
    // fonts to utilize for Text within components
    fonts = with(Typography.bodyLarge) {
        botstacksFonts(
            body1 = FontStyle(
                size = fontSize,
            )
        )
    },
    // assets for empty state and logo (in header)
    assets = Assets(
        logo = R.drawable.inappchat_icon,
        emptyChat = EmptyScreenConfig.Messages(
            caption = "No messages yet."
        )
    ),
    // shape definitions for components
    shapes = ShapeDefinitions(
        small = 4.dp,
        medium = 10.dp,
        large = 16.dp
    )
) {
    // content code here (components, Controller)
}