Adding the Mobile SDK to a Unity game

Last updated: 9 October 2026 · 8 min read

The Unity package is a C# bridge to the native Android and iOS SDKs, and the screens are native screens. In the Editor and on other platforms the calls do nothing: the SDK works only in Android and iOS builds.

Steps

  1. 1

    Requirements

    • Unity 2021.3 or newer, Unity 6 works too.
    • Android: Minimum API Level 23, compileSdk 35 or newer. iOS: Target minimum iOS Version 15.0, Xcode 15.
    • External Dependency Manager for Unity (EDM4U): it brings the native SDKs.
    • The App ID and both API keys (android_…, ios_…).
    • Voice messages (from SDK 1.0.2) need RECORD_AUDIO declared in the Android app's manifest, otherwise the microphone button does not show. The camera needs no permission.
  2. 2

    Install

    1. Install EDM4U.
    2. Window › Package Manager › + › Add package from git URL (“Install package from git URL” in Unity 6) and enter:
    https://github.com/clomni/clomni-mobile-sdk.git?path=unity#unity-1.0.5
    1. Android: Project Settings › Player › Android › Minimum API Level 23 or higher. EDM4U › Android Resolver › Settings: “Use Gradle” and “Patch mainTemplate.gradle” on (EDM4U 1.2.183 or newer).
    2. iOS: Project Settings › Player › iOS › Target minimum iOS Version 15.0. After the build, open the .xcworkspace, not the .xcodeproj. If Xcode asks for a Swift version, set SWIFT_VERSION = 5.0 on the UnityFramework target.

    EDM4U writes pod 'ClomniMessenger', '1.0.4' into the iOS build's Podfile. That form looks for the pod on CocoaPods trunk, where the SDK is not published. After every iOS build, change that line in the build folder's Podfile and run pod install there:

    pod 'ClomniMessenger', :git => 'https://github.com/clomni/clomni-mobile-sdk.git', :tag => '1.0.4'

    To try it quickly: Package Manager › Clomni Messenger › Samples › Basic › Import. Add ClomniBasicSample to an empty GameObject, enter the App ID and keys in the Inspector, and build to a device.

  3. 3

    Start the SDK

    using ClomniMessenger;
    using UnityEngine;
    
    public static class ClomniSetup
    {
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        private static void Initialize()
        {
            var apiKey = Application.platform == RuntimePlatform.IPhonePlayer ? "ios_…" : "android_…";
            Clomni.Initialize("app_…", apiKey);
            if (Debug.isDebugBuild) Clomni.SetLogLevel(ClomniLogLevel.Debug);
        }
    }

    Call Clomni from Unity's main thread; events arrive there too.

  4. 4

    User and Messenger

    Clomni.LoginUser(new ClomniUser { UserId = "12345", Email = "[email protected]", Name = "Aysel" }, hashFromYourServer);
    Clomni.UpdateUser(language: "az", customAttributes: new Dictionary<string, object> { ["plan"] = "premium" });
    
    // Together with the game's own logout:
    Clomni.Logout();

    The hash comes from your game's server. Never put the Identity Secret in the game: not in C# code, not in assets, not in PlayerPrefs.

    using ClomniMessenger;
    using UnityEngine;
    using UnityEngine.UI;
    
    public sealed class SupportButton : MonoBehaviour
    {
        [SerializeField] private Button button;
        [SerializeField] private Text badge;
    
        private void OnEnable()
        {
            button.onClick.AddListener(Open);
            Clomni.UnreadCountChanged += ShowUnread;
        }
    
        private void OnDisable()
        {
            button.onClick.RemoveListener(Open);
            Clomni.UnreadCountChanged -= ShowUnread;
        }
    
        private void Open() => Clomni.Present("settings_support");
    
        private void ShowUnread(int count) => badge.text = count > 0 ? count.ToString() : "";
    }

    Other calls: PresentNewConversation(source), PresentConversation(id), Dismiss(), SetLauncherVisible(true), SetBottomPadding(72), StartFlow(...). Events: MessengerOpened, MessengerClosed, ConversationStarted, FlowCompleted, OnLink.

    Call Clomni.LoginUser on every app start while the user is signed in, as if they had just signed in. For the same user the SDK reuses its stored session.

  5. 5

    Push: Android

    Upload the keys to the dashboard first (“Mobile SDK push keys”). Use the Firebase Unity SDK (Firebase Messaging) and put google-services.json in Assets/. The package's “Push (Firebase)” sample passes the token and the messages to Clomni:

    using ClomniMessenger;
    using Firebase.Messaging;
    using UnityEngine;
    
    public sealed class ClomniFirebaseBridge : MonoBehaviour
    {
        private void Start()
        {
            FirebaseMessaging.TokenReceived += OnTokenReceived;
            FirebaseMessaging.MessageReceived += OnMessageReceived;
        }
    
        private void OnDestroy()
        {
            FirebaseMessaging.TokenReceived -= OnTokenReceived;
            FirebaseMessaging.MessageReceived -= OnMessageReceived;
        }
    
        private void OnTokenReceived(object sender, TokenReceivedEventArgs e)
        {
            if (Application.platform == RuntimePlatform.Android) Clomni.SetDeviceToken(e.Token);
        }
    
        private void OnMessageReceived(object sender, MessageReceivedEventArgs e)
        {
            if (Application.platform != RuntimePlatform.Android) return;
            if (Clomni.HandlePush(e.Message.Data)) return;
            // the game's own push
        }
    }
    • Android 13+: UnityEngine.Android.Permission.RequestUserPermission("android.permission.POST_NOTIFICATIONS").
    • The notification icon is a drawable in an .androidlib folder, for example Assets/Plugins/Android/ClomniRes.androidlib/res/drawable/ic_notification.png, named with Clomni.SetNotificationIcon("ic_notification").

    Firebase Unity delivers a message to C# only while the game runs. For a notification to show while the game is closed too, hand the message to the SDK in Java before Unity starts:

    // Assets/Plugins/Android/ClomniListenerService.java
    package com.example.game;
    
    import ai.clomni.messenger.ClomniPush;
    import com.google.firebase.messaging.RemoteMessage;
    import com.google.firebase.messaging.cpp.ListenerService;
    
    public class ClomniListenerService extends ListenerService {
        @Override
        public void onMessageReceived(RemoteMessage message) {
            if (ClomniPush.handle(this, message.getData())) return;
            super.onMessageReceived(message);
        }
    }
    <!-- Assets/Plugins/Android/AndroidManifest.xml, inside <application>.
         The <manifest> element needs xmlns:tools="http://schemas.android.com/tools". -->
    <service android:name="com.google.firebase.messaging.cpp.ListenerService" tools:node="remove" />
    <service android:name="com.example.game.ClomniListenerService" android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    Check in the build's merged manifest that only ClomniListenerService receives MESSAGING_EVENT.

  6. 6

    Push: iOS

    Clomni expects the APNs device token in hex, not an FCM token. Use Unity's Mobile Notifications package (com.unity.mobile.notifications). In Project Settings › Mobile Notifications › iOS, turn on “Enable Push Notifications”; it adds the capability to the Xcode project.

    using System.Collections;
    using ClomniMessenger;
    using UnityEngine;
    #if UNITY_IOS
    using Unity.Notifications.iOS;
    #endif
    
    public sealed class ClomniIosPush : MonoBehaviour
    {
    #if UNITY_IOS
        private string handled;
    
        private IEnumerator Start()
        {
            var options = AuthorizationOption.Alert | AuthorizationOption.Badge | AuthorizationOption.Sound;
            using (var request = new AuthorizationRequest(options, true))
            {
                while (!request.IsFinished) yield return null;
                if (request.Granted && !string.IsNullOrEmpty(request.DeviceToken))
                {
                    Clomni.SetDeviceToken(request.DeviceToken);
                }
            }
        }
    
        // A tap brings the game to the front: a Clomni push opens its conversation.
        private void OnApplicationFocus(bool focused)
        {
            if (!focused) return;
            var tapped = iOSNotificationCenter.GetLastRespondedNotification();
            if (tapped == null || tapped.Identifier == handled) return;
            handled = tapped.Identifier;
            Clomni.HandlePush(tapped.UserInfo);
        }
    #endif
    }

    Clomni.ShouldShowForeground(data) says whether a push that arrives while the game is open should be shown: false for a Clomni push while the Messenger is open.

  7. 7

    Problems

    • Nothing happens in the Editor: expected, test on a device.
    • The Android build cannot find ai.clomni:messenger: Assets › External Dependency Manager › Android Resolver › Force Resolve, with “Use Gradle” on.
    • pod install cannot find ClomniMessenger: change the line in the build folder's Podfile to the :git form.
    • Xcode cannot find the ClomniMessenger module: open the .xcworkspace.
    • On Android, notifications arrive only while the game is open: the Java service above.
  8. 8

    Full guide

    • PDF: Clomni Mobile SDK guide, in English, Azerbaijani and Russian.
    • Online: Unity.
    • In the dashboard: “Guide” in the channel's settings column.

Document