Как подключить мобильный SDK к приложению React Native или Expo
Обновлено: 9 октября 2026 · 10 мин чтения
Пакет @clomni/react-native работает поверх нативных SDK для Android и iOS, экраны нативные.
Шаги
-
1
Требования
- React Native 0.75 или новее (0.76 для New Architecture). Expo SDK 52 или новее, с development build.
- iOS 15, Android 6.0 (API 23).
- App ID и оба ключа API (
android_…,ios_…). - Голосовым сообщениям (с SDK 1.0.2) нужно
RECORD_AUDIOв манифесте Android-приложения, иначе кнопка микрофона не показывается. Камере разрешение не нужно.
-
2
Установка
npm install @clomni/react-native cd ios && pod install
Остальное делает autolinking. На Android модуль берёт
ai.clomni:messengerиз Maven Central. На iOSpod installдобавляет SDK как Swift package (spm_dependencyиз React Native), Xcode скачивает его при первой сборке.На React Native старше 0.75
pod installостанавливается с «@clomni/react-native needs React Native 0.75 or later». Обновите React Native или добавьте в Podfile строку ниже. Ту же строку добавьте, если линковка падает на символахClomniMessengerили если push подключается в нативном коде:# ios/Podfile, in your app's target pod 'ClomniMessenger', :git => 'https://github.com/clomni/clomni-mobile-sdk.git', :tag => '1.0.4'
-
3
Expo
Expo Go не загружает нативные модули. Используйте development build:
npx expo prebuild,npx expo run:iosилиrun:android, либо сборку EAS. Config plugin пакета записывает в нативные проекты всё нужное:// app.config.ts export default { // ... plugins: [ ['@clomni/react-native', { photoLibraryPermission: 'To send photos to support', // iOS cameraPermission: 'To take a photo and send it to support', // iOS push: true, // the default notificationIcon: './assets/notification-icon.png', // Android, white silhouette PNG }], ], };push: trueдобавляет на iOS entitlementaps-environmentи background moderemote-notification, на Android разрешениеPOST_NOTIFICATIONS. Иконка становится drawable с именемclomni_notification_icon. В обычном приложении без Expo добавьте два текста разрешений для фото вInfo.plistсами:NSPhotoLibraryUsageDescriptionиNSCameraUsageDescription. -
4
Запустите SDK
Один раз, вне компонентов.
index.jsподходит лучше всего, потому что push может запустить приложение без экрана.// index.js import { AppRegistry, Platform } from 'react-native'; import Clomni from '@clomni/react-native'; import App from './App'; import { name as appName } from './app.json'; Clomni.initialize('app_…', Platform.OS === 'ios' ? 'ios_…' : 'android_…'); if (__DEV__) Clomni.setLogLevel('debug'); AppRegistry.registerComponent(appName, () => App);Третий параметр
initializeназываетсяregion, по умолчанию'eu'. Сейчас есть только'eu', передавать его не нужно: любое другое значение SDK пишет в лог и использует'eu'. -
5
Пользователь и Messenger
Clomni.loginUser({ userId: '12345', email: '[email protected]', name: 'Aysel' }, hashFromYourServer); Clomni.updateUser({ language: 'az', customAttributes: { plan: 'premium' } }); // Together with your app's own logout: Clomni.logout();import { useEffect, useState } from 'react'; import { Pressable, Text } from 'react-native'; import Clomni from '@clomni/react-native'; export function SupportRow() { const [unread, setUnread] = useState(0); useEffect(() => { // The current count at once, then every change. const subscription = Clomni.addEventListener('unreadCountChanged', setUnread); return () => subscription.remove(); }, []); return ( <Pressable onPress={() => Clomni.present('profile_support')}> <Text>Support{unread > 0 ? ` (${unread})` : ''}</Text> </Pressable> ); }Другие вызовы:
presentNewConversation(source),presentConversation(id),dismiss(),setLauncherVisible(true),setBottomPadding(72). События черезaddEventListener:messengerOpened,messengerClosed,conversationStarted,flowCompleted. Колбэки нативного SDK модуль забирает сам, не назначайте их отдельно в нативном коде.Пока пользователь вошёл в приложение, вызывайте
loginUserпри каждом запуске, как будто он только что вошёл. Для того же пользователя SDK использует сохранённую сессию.Для пользователя, который не вошёл, ничего вызывать не нужно: Messenger сам создаёт анонимного посетителя при открытии.
Clomni.loginUnidentifiedUser()делает это заранее. Посетитель остаётся тем же на этом устройстве доlogout, а при вызовеloginUserего диалоги переходят к пользователю. -
6
Flow, события, ссылки и внешний вид
Запуск flow из приложения и события Messenger:
Clomni.startFlow('ride_problem', { ride_id: 'R-1923' }, { openMessenger: true, source: 'ride_screen' }); const subscriptions = [ Clomni.addEventListener('messengerOpened', (source) => console.log('opened from', source)), Clomni.addEventListener('messengerClosed', () => console.log('closed')), Clomni.addEventListener('conversationStarted', (id) => console.log('conversation', id)), Clomni.addEventListener('flowCompleted', (flowId) => console.log('flow', flowId)), ]; // later: subscriptions.forEach((s) => s.remove());В панели нужен flow с триггером «App event» и тем же именем, и он должен быть опубликован. Данные должны быть JSON. Модуль сам управляет событиями нативного SDK: не задавайте их ещё и в нативном коде приложения.
Ссылки, язык, звуки и собственный цвет приложения:
import { Linking } from 'react-native'; Clomni.onLink((url) => Linking.openURL(url)); // or your own router; null: the system opens links Clomni.setLanguage('en'); // 'az', 'en', 'ru'; null follows the phone Clomni.setSoundsEnabled(false); Clomni.setTheme({ primaryColor: '#0A66C2', typeface: 'Montserrat', mode: 'dark' });Шрифт задаётся именем семейства, которое Вы используете в стилях
fontFamily. На iOS шрифт должен быть в приложении и указан подUIAppFonts, на Android React Native ищет его вandroid/app/src/main/assets/fontsилиres/font. Только шрифт:Clomni.setTypeface('Montserrat'). Значение из панели действует, только если приложение не задало своё. -
7
Push: Android
Сначала загрузите ключи в панель (статья «Ключи push для мобильного SDK»). Настройте Firebase с
google-services.jsonи плагином Google services для Gradle, как описано в документации React Native Firebase. Затем:// index.js, next to initialize import messaging from '@react-native-firebase/messaging'; // Clomni data messages while the app is in the background or closed: the SDK shows the notification. messaging().setBackgroundMessageHandler(async (message) => { Clomni.handlePush(message.data ?? {}); });// App.tsx import { useEffect } from 'react'; import { PermissionsAndroid, Platform } from 'react-native'; import messaging from '@react-native-firebase/messaging'; import Clomni from '@clomni/react-native'; useEffect(() => { if (Platform.OS !== 'android') return; PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS); // Android 13+ messaging().getToken().then((token) => Clomni.setDeviceToken(token)); const unsubscribeToken = messaging().onTokenRefresh((token) => Clomni.setDeviceToken(token)); // Messages while the app is open. const unsubscribeMessage = messaging().onMessage(async (message) => { if (!Clomni.handlePush(message.data ?? {})) { // your app's own push } }); Clomni.setNotificationIcon('clomni_notification_icon'); // the config plugin's notificationIcon return () => { unsubscribeToken(); unsubscribeMessage(); }; }, []);В обычном приложении объявите
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />вAndroidManifest.xml, положите белую иконку вandroid/app/src/main/res/drawable/и передайте её имя вsetNotificationIcon. -
8
Push: iOS
Clomni отправляет push на iOS напрямую в APNs, не через Firebase. Библиотека Firebase сообщает только о сообщениях FCM и не видит нажатия на уведомление Clomni. Поэтому ловите нажатие в нативном коде:
- Добавьте в Xcode capability Push Notifications.
- Добавьте строку
pod 'ClomniMessenger'выше вios/Podfileи выполнитеpod install. - Добавьте этот файл в цель приложения:
// ios/<YourApp>/ClomniNotifications.swift import ClomniMessenger import UserNotifications /// Clomni pushes: hidden while the Messenger is open, and a tap opens the conversation. @objc(ClomniNotifications) final class ClomniNotifications: NSObject, UNUserNotificationCenterDelegate { @objc static let shared = ClomniNotifications() func userNotificationCenter( _ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void ) { let show = Clomni.shouldShowForeground(notification.request.content.userInfo) completionHandler(show ? [.banner, .list, .sound] : []) } func userNotificationCenter( _ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void ) { _ = Clomni.handlePush(response.notification.request.content.userInfo) completionHandler() } }- Сделайте его делегатом в
application(_:didFinishLaunchingWithOptions:), до возврата из метода:
// AppDelegate.swift UNUserNotificationCenter.current().delegate = ClomniNotifications.shared
// AppDelegate.mm, when the app delegate is Objective-C #import "YourApp-Swift.h" #import <UserNotifications/UserNotifications.h> [UNUserNotificationCenter currentNotificationCenter].delegate = ClomniNotifications.shared;
React Native Firebase затем берёт делегат на себя и передаёт этому делегату каждый чужой для него push, так что Ваши push через FCM продолжают работать.
- Передайте токен APNs из JavaScript:
if (Platform.OS === 'ios') { await messaging().requestPermission(); const apnsToken = await messaging().getAPNSToken(); // hex if (apnsToken) Clomni.setDeviceToken(apnsToken); }Если на iOS нет Firebase, передайте токен в нативном коде:
Clomni.setDeviceToken(deviceToken)вdidRegisterForRemoteNotificationsWithDeviceToken. В Expo папкуiosсоздаётprebuild: держите шаги 3 и 4 в своём небольшом config plugin (withAppDelegate,withXcodeProject) или храните папкуiosв репозитории. -
9
Проблемы
- «The package doesn't seem to be linked» или нативный модуль не найден: пересоберите приложение; в Expo используйте development build.
- Ошибки линковки на символах
ClomniMessengerна iOS: строкаpod 'ClomniMessenger'в Podfile иpod install. - На Android уведомления не приходят, когда приложение закрыто:
setBackgroundMessageHandlerдолжен быть вindex.js, вне компонентов. - На iOS нажатие на уведомление Clomni только открывает приложение: нативного делегата (шаги 3 и 4) нет или он назначен слишком поздно.
- Плавающая кнопка не появляется при холодном запуске приложения. Причина: ошибка SDK 1.0.1, исправлено в 1.0.2. До этого открывайте Messenger своей кнопкой.
- Android: открытый Messenger пропадает, когда приложение снова открывают по иконке. Причина:
MainActivityсsingleTask. Исправлено в SDK 1.0.2.
-
10
Полное руководство
- PDF: руководство Clomni Mobile SDK, на русском языке.
- Онлайн: React Native (на английском).
- В панели: раздел «Guide» в колонке настроек канала.