VIH Messenger Mobile SDK

Integration Guide

Add VIH Messenger to your app

Drop the VIH Messenger SDK into your Android or iOS app to give users authenticated, bidirectional chat with enterprises on your channel β€” installed with one dependency and launched with a single call.

🧭 Overview

The SDK ships the full messaging experience β€” sign-in, the list of enterprises on your channel, and real-time two-way chat β€” as a self-contained module. You supply two things from the VIH team (a channel hashcode and an API base URL), wire one entry point, and the SDK renders and manages the rest.

Android and iOS use the same hashcode for a given channel, so a user is reachable identically on both platforms.

🧩

Customizing the SDK? See the Customization guide (tabs, brand colors) and the Custom Discover Integration guide (list enterprises in your own app).

πŸ“‹ Requirements

Android

Min SDK
24 (Android 7.0)
Target SDK
35
Gradle
7+ (AGP 8+)
Language
Kotlin / Java
Distribution
Maven (AAR)

iOS

Deployment
iOS 15.0+
Xcode
15+
Language
Swift 5.9+
UI
UIKit host
Distribution
Swift Package

πŸ”‘ What you'll need

Before you integrate, get these from the VIH team for your channel:

  • Channel hashcode β€” a per-tenant identifier (e.g. 046c8dd…07e43) that scopes the app to your channel. Identical on Android and iOS.
  • API base URL β€” the backend host for your environment. On iOS you pass it at runtime (apiBaseURL); on Android it is baked into the artifact you choose (see the dependency step). The active host is https://api.platform.vihresearchlabs.ai/.
  • Firebase config β€” google-services.json (Android) and GoogleService-Info.plist (iOS) for push notifications, provided out-of-band.
πŸ’‘

Version numbers below are examples. Always use the exact SDK version and package URL the VIH team gives you, and pin to it.

Android Integration

Four steps: point Gradle at the repositories, add the dependency, declare permissions, then launch the SDK from your app.

1

πŸ› οΈ Configure repositories

In your root settings.gradle.kts, make sure both blocks include Google, Maven Central, the Gradle Plugin Portal, and JitPack.

kotlinsettings.gradle.kts
pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
        maven { url = uri("https://jitpack.io") }
    }
}
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://jitpack.io") }
    }
}
2

πŸ“¦ Add the dependency

The Android SDK is distributed via JitPack, built from the ViH_SDK repository. Add it to your module-level build.gradle (the JitPack repository is configured in step 1):

groovyapp/build.gradle
dependencies {
    // Targets https://api.platform.vihresearchlabs.ai/ (active backend)
    implementation "com.github.ViH-Metaverse.ViH_SDK:vih-sdk:1.2.1"
}

Kotlin DSL:

kotlinapp/build.gradle.kts
dependencies {
    implementation("com.github.ViH-Metaverse.ViH_SDK:vih-sdk:1.2.1")
}
⚠️

The groupId ends in .ViH_SDK β€” JitPack appends the repo name for multi-module builds. The API base URL is compiled into the artifact (https://api.platform.vihresearchlabs.ai/); there is no runtime override. Use the vih-sdk artifact. Both published artifacts β€” vih-sdk (prod flavor) and vih-sdk-staging (staging flavor) β€” are compiled against https://api.platform.vihresearchlabs.ai/, so they are interchangeable; vih-sdk is simply the one we support for production.

🚫

Do not use the legacy Maven Central artifacts io.github.vihmessenger:vih-sdk-staging:1.0.0 or io.github.vihmessenger:vih-sdk:1.0.9 (and earlier) β€” they were built against retired hosts (stagingnlp.vihmessenger.com / vihapi.plugseal.com) that do not host current channels, and return 404 {"message":"channel not found","error_code":"EC_CHANNEL_4040"} even when your hashcode is valid.

πŸ”„

Click Sync Now in Android Studio after editing Gradle files. The first sync fetches Firebase and other transitive dependencies and can take a minute.

3

πŸ” Declare permissions

The SDK's own manifest already merges what it needs. If your app manifest is strict, these are the permissions the SDK uses:

xmlAndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
βœ…

The SDK does not read phone state, phone numbers, or call logs β€” no READ_PHONE_STATE / READ_CALL_LOG is requested, so it clears Google Play's sensitive-permission review on those.

4

πŸš€ Launch the SDK

Start the messaging flow with FloatingButtonView.startSdk(), passing the user's phone number and your channel hashcode. Call it from any click listener:

kotlinMainActivity.kt
import com.vihmessenger.vihchatbot.utils.FloatingButtonView

launchButton.setOnClickListener {
    FloatingButtonView.startSdk(
        context  = this,
        phone    = "919876543210",
        hashcode = "your-channel-hashcode"
    )
}

Optional parameters let you pre-fill the signed-in user's identity so they skip straight into chat:

kotlinMainActivity.kt
FloatingButtonView.startSdk(
    context        = this,
    phone          = "919876543210",
    hashcode       = "your-channel-hashcode",
    name           = "Priya Sharma",           // optional
    userProfileUrl = "https://…/avatar.jpg"     // optional
)

Optional: a persistent floating button

To show an always-on chat launcher, drop FloatingButtonView into any layout and set your hashcode via app:extraValue. Tapping it opens the SDK.

xmlactivity_main.xml
<com.vihmessenger.vihchatbot.utils.FloatingButtonView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    app:extraValue="your-channel-hashcode" />

Widget behavior

The floating button is a full launcher widget you can place anywhere β€” for example, centered on your app's bottom navigation bar.

  • Custom image: set the artwork with app:centerImage (XML) or setCenterImageResource(...); set imageOnly = true to draw the image full-bleed with no background circle (for a logo/PNG).
  • Pops on new message: the widget animates up-and-back whenever the SDK receives a message (it auto-listens to the SDK's in-app message broadcast). Toggle with popOnMessageEnabled; trigger manually with popUp().
  • Unread badge: a red count badge at the top-right via unreadCount β€” auto-increments on each incoming message, clears when tapped. Drive it from your own source (e.g. your server's unread total) by setting unreadCount with countUnreadOnMessage = false; hide it with unreadBadgeEnabled = false.
  • Tap handling: by default a tap opens the SDK. Set launchesSdkOnClick = false plus your own setOnClickListener to handle it yourself (e.g. call startSdk(...)).
kotlinMainActivity.kt
val widget = FloatingButtonView(context).apply {
    setCenterImageResource(R.drawable.ic_vih_widget) // your widget artwork
    imageOnly = true            // full-bleed image, no background circle
    launchesSdkOnClick = false  // we handle the tap ourselves
    setOnClickListener {
        FloatingButtonView.startSdk(context, "919876543210", "your-channel-hashcode")
    }
}
// The widget pops + increments its unread badge automatically as messages arrive.
// Or drive the badge yourself:  widget.unreadCount = serverUnreadTotal

iOS Integration

The SDK ships as a Swift Package. Add it, wire Firebase for push, configure once at launch, then present the SDK's UI.

1

πŸ“¦ Add the Swift Package

In Xcode: File β–Έ Add Package Dependencies…, paste the package URL, set the rule to Up to Next Major from 1.2.1, and add the VihChatBotSDK product to your app target.

textPackage URL
https://github.com/ViH-Metaverse/ViH_SDK.git

Or, if your app is itself a Swift Package:

swiftPackage.swift
dependencies: [
    .package(
        url: "https://github.com/ViH-Metaverse/ViH_SDK.git",
        from: "1.2.1"
    ),
],
targets: [
    .target(
        name: "YourApp",
        dependencies: [
            .product(name: "VihChatBotSDK", package: "ViH_SDK"),
        ]
    ),
]
⏳

The first package resolve pulls in the Firebase iOS SDK and can take several minutes to download and cache. Subsequent builds are fast.

2

πŸ”₯ Add Firebase (push)

Add your GoogleService-Info.plist to the app bundle and configure Firebase before the SDK. Enable the Push Notifications and Background Modes β–Έ Remote notifications capabilities on your target.

3

βš™οΈ Configure the SDK

Configure the SDK once at launch with a VihSDKConfig β€” before presenting any SDK screen.

swiftAppDelegate.swift
import VihChatBotSDK

VihChatBotSDK.shared.configure(
    VihSDKConfig(
        apiBaseURL: URL(string: "https://api.platform.vihresearchlabs.ai/")!,
        hashcode:   "your-channel-hashcode",
        sdkVersion: "1.0.0",
        isDebug:    true
    )
)

Fields: apiBaseURL and hashcode are required; bugfenderKey and certificatePins are optional. Use the same hashcode as Android.

4

πŸš€ Launch the SDK

Configure Firebase and the SDK in didFinishLaunchingWithOptions, then set the SDK's splash screen as your root β€” it checks for a stored session and routes to sign-in or chat.

swiftAppDelegate.swift
import UIKit
import VihChatBotSDK
import FirebaseCore

@main
final class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(_ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions:
            [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {

        FirebaseApp.configure()                     // 1. push

        VihChatBotSDK.shared.configure(             // 2. SDK
            VihSDKConfig(
                apiBaseURL: URL(string: "https://api.platform.vihresearchlabs.ai/")!,
                hashcode:   "your-channel-hashcode",
                sdkVersion: "1.0.0",
                isDebug:    false
            )
        )

        // 3. present the SDK's splash as root
        let window = UIWindow(frame: UIScreen.main.bounds)
        let nav = UINavigationController(rootViewController: SplashViewController())
        nav.isNavigationBarHidden = true
        window.rootViewController = nav
        window.makeKeyAndVisible()
        self.window = window
        return true
    }
}
βœ…

That's it β€” build and run (⌘R). SplashViewController loads the saved theme and routes the user into the correct flow automatically.

πŸŒ— Theming & dark mode

The SDK automatically follows the device's system Light/Dark setting β€” screen backgrounds and body text adapt for legibility. Your channel's brand / accent colors (primary color, headers, highlights from the channel config) are preserved in both modes; only backgrounds and text flip. No integration work is required β€” it just works.

Android

Built on a DayNight theme that follows the system. Nothing to enable.

To pin the SDK to one appearance, force it from your host app:

kotlin
AppCompatDelegate.setDefaultNightMode(
    AppCompatDelegate.MODE_NIGHT_NO   // or MODE_NIGHT_YES
)

iOS

Uses UIKit semantic colors, which adapt automatically. Nothing to enable.

To pin the SDK to one appearance, set it on your window:

swift
window.overrideUserInterfaceStyle = .light  // or .dark
πŸ’‘

If your host app already forces a night mode (setDefaultNightMode / overrideUserInterfaceStyle), that setting wins and the SDK follows it β€” so the SDK matches the rest of your app.

πŸ”” Notification tones

Push notifications can play a different sound per message type, so users recognize an OTP versus a promotional or transactional message by ear. The tone is chosen from the message's CPaaS template_type in the FCM data payload.

template_typeCategoryTone
1OTPOTP tone
2PromotionalPromo tone
3TransactionalPromo tone
4 / otherNormal chatSystem default

Android Automatic

Handled inside the SDK β€” no integration work. Each category maps to its own notification channel with its bundled tone (Android locks a channel's sound at creation, so each tone needs its own channel). Just ensure the FCM data payload includes template_type.

iOS One-time setup

iOS decides a remote push's sound from the APNs payload, so it needs either a Notification Service Extension (the app ships one, VihNotificationService, mapping template_type β†’ tone) with "mutable-content": 1 in the payload, or the backend setting aps.sound per template. iOS sounds must be .caf/.aiff/.wav (not mp3). See notification-tones.md.

πŸ’‘

The backend must send template_type in the push data (Android) and "mutable-content": 1 in the APNs payload (iOS) for per-template tones to apply.

πŸ“Œ Home-screen shortcut Android

The SDK can pin a shortcut on the device home screen (using your channel's logo + name) that opens the chat directly, so users skip your app to reach messages. It's offered automatically on first sign-in, and users can add it anytime from an "Add to Home Screen" row in the SDK's Settings. No integration work.

βœ…

The pinned shortcut launches straight into the SDK for the signed-in user (Android only β€” it can request a pinned shortcut but can't remove one, so it's add-only).

πŸ“š Support

Stuck on integration, need your channel hashcode, or want the latest SDK version? Reach the VIH team at developers@vihmessenger.com. Include your platform, SDK version, and any Gradle/Xcode error output so we can help fast.