Ваш Capacitor застосунок зберігає власний вебекран, а транспорт розмови й відображення віджета залишаються нативними.
Установіть і синхронізуйте опубліковані Capacitor-пакети
Для нового хоста один раз ініціалізуйте Capacitor, установіть узгоджені пакети платформ Capacitor, а також Capacitor-обгортку DobroDesk і спільний пакет протоколу в одній версії релізу. Додайте кожну нативну платформу один раз, потім синхронізуйте проєкти.
# Run once for a new host.
npx cap init "Your app" com.example.app --web-dir=www
npm install @capacitor/core@8.5.3 @capacitor/cli@8.5.3 @capacitor/ios@8.5.3 @capacitor/android@8.5.3 @dobrodesk/capacitor-sdk@0.2.0 @dobrodesk/mobile-protocol@0.2.0
npx cap add ios --packagemanager CocoaPods
npx cap add android
npx cap syncЗареєструйте bundled Android-репозиторій
Додайте локальний Maven-шлях Capacitor-обгортки в налаштуваннях Android-хоста. Обгортка застосовує org.jetbrains.kotlin.android без версії, тому оголосіть Kotlin та Android plugins перед згенерованими include-рядками. Мінімальний перевірений хост Capacitor 6.2.1 використовує Android Gradle Plugin 8.13.2, Kotlin Gradle Plugin 2.2.0, Gradle 8.14.3 і JDK 17. Поточний згенерований хост Capacitor 8.5.3 використовує AGP 8.13.0, Kotlin 2.2.20 і JDK 21. Зберігайте версії, згенеровані встановленою версією Capacitor. PREFER_SETTINGS зберігає сумісність із репозиторієм офіційного Capacitor Android-модуля, а артефакти DobroDesk знаходяться в установленому пакеті.
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id 'com.android.application' version '8.13.0' apply false
id 'com.android.library' version '8.13.0' apply false
id 'org.jetbrains.kotlin.android' version '2.2.20' apply false
}
import org.gradle.api.initialization.resolve.RepositoriesMode
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
google()
mavenCentral()
maven { url = uri("$rootDir/../node_modules/@dobrodesk/capacitor-sdk/native/maven") }
}
}
// Keep the generated include and apply-from lines below this block.Установіть вимоги нативних платформ
Опублікована обгортка потребує iOS 15.1 або новішої та Android API 26 або новішої. Обидва перевірені Android-профілі використовують compile SDK 36 і minSdk 26. Мінімальний профіль Capacitor 6.2.1 використовує JDK 17. Для цього профілю задайте distributionUrl у android/gradle/wrapper/gradle-wrapper.properties як https://services.gradle.org/distributions/gradle-8.14.3-all.zip. Актуальні хости Capacitor 8.5.3 використовують JDK 21 із сумісними згенерованими wrapper і набором версій. Перед pod install установіть target iOS і підніміть згенерований Android minSdkVersion з 24 до 26.
# ios/App/Podfile
platform :ios, "15.1"
# android/variables.gradle
minSdkVersion = 26
compileSdkVersion = 36
# android/gradle/wrapper/gradle-wrapper.properties for Capacitor 6.2.1
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zipНалаштуйте й відкрийте нативну обгортку
Обгортка підтримує Capacitor від 6 до 8. Після встановлення пакетів, синхронізації нативних проєктів і налаштування репозиторію надайте credentialProvider зі свого застосунку хоста.
Вебекран хоста залишається звичайним Capacitor WebView, але віджет DobroDesk і транспорт є нативними. Не завантажуйте вебрендерер віджета у WebView як заміну цій інтеграції.
import { DobroDeskCapacitorClient } from "@dobrodesk/capacitor-sdk";
import type { DobroDeskSdkConfig } from "@dobrodesk/mobile-protocol";
const config: DobroDeskSdkConfig = {
apiOrigin: "https://dobrodesk.com",
integrationId: "wgt_0123456789abcdef0123456789abcdef",
accountScope: currentCustomer.id,
credentialProvider: async () => ({
authorizationToken: await loadDobroDeskToken(),
}),
};
const client = new DobroDeskCapacitorClient(config);
await client.presentWidget();Монтуйте inline або використовуйте власний тригер
mountWidget підключає нативний віджет до з'єднаного HTMLElement у Capacitor host. Перед монтуванням задайте контейнеру явні розміри, щоб WebView layout не стрибав.
Власна кнопка може викликати setVisible на єдиному handle. Передавайте типізований onError callback, якщо хосту потрібне власне повідомлення про відновлення. Під час dispose приклад прибирає listener кнопки й звільняє inline-власника без скидання сесії чи чернетки.
mountWidget входить до опублікованого пакета Mobile SDK 0.2.0. Використовуйте його для обмеженої нативної поверхні й викликайте await handle.dispose(), коли хост прибирає контейнер.
import type {
DobroDeskCapacitorClient,
DobroDeskEmbeddedWidget,
} from "@dobrodesk/capacitor-sdk";
type SupportPanelOptions = Readonly<{
onError?: (error: unknown) => void;
}>;
export async function mountSupportPanel(
client: DobroDeskCapacitorClient,
{ onError }: SupportPanelOptions = {},
) {
const supportSlot = document.querySelector<HTMLElement>("#support-slot");
const helpButton = document.querySelector<HTMLButtonElement>("#help-button");
if (
!supportSlot ||
!helpButton ||
!supportSlot.isConnected ||
!helpButton.isConnected
) {
throw new Error("Connect #support-slot and #help-button before mounting");
}
Object.assign(supportSlot.style, { width: "100%", height: "560px" });
helpButton.setAttribute("aria-controls", "support-slot");
let visible = true;
let mountedHandle: DobroDeskEmbeddedWidget | undefined;
const toggle = () => {
visible = !visible;
mountedHandle?.setVisible(visible);
helpButton.setAttribute("aria-expanded", String(visible));
};
const onClose = () => {
visible = false;
helpButton.setAttribute("aria-expanded", "false");
};
helpButton.addEventListener("click", toggle);
try {
mountedHandle = await client.mountWidget(
supportSlot,
{ locale: "en", view: "home" },
{ onClose, onError },
);
mountedHandle.setVisible(true);
helpButton.setAttribute("aria-expanded", "true");
} catch (error) {
helpButton.removeEventListener("click", toggle);
onError?.(error);
throw error;
}
if (!mountedHandle) throw new Error("Support widget did not mount");
const handle = mountedHandle;
return {
handle,
dispose: async () => {
helpButton.removeEventListener("click", toggle);
await handle.dispose();
},
};
}Розділяйте hybrid- і нативні життєві цикли
Наданий хостом credentialProvider має викликати бекенд endpoint, який повертає короткоживучий customer identity JWT. Він не повинен розкривати support API token або signing secret у веббандлі. Викликайте closeWidget після знищення маршруту хоста, resetSession після відкидання розмови та logout перед зміною акаунта.
Нативний presenter поважає системне reduced motion, якщо override не заданий. Тримайте переходи сторінки хоста окремо, щоб зміна маршруту WebView не створила другий нативний віджет.
Керуйте завантаженням, від'єднанням і доступністю
Нативна поверхня показує завантаження повідомлень, очікування помічника та повтори. Використовуйте onError для стану host і не дублюйте spinner у WebView.
setVisible(false) приховує віджет на час зміни маршруту, а setVisible(true) повертає його після підключення контейнера. dispose не скидає сесію. Нативна поверхня враховує системний reduced motion, а host керує focus order та клавіатурою.
- Створюйте один handle на client і блокуйте mountWidget, коли embedded handle уже активний.
- Використовуйте setVisible(false) для тимчасового від'єднання та setVisible(true) після повернення.
- Викликайте dispose і logout лише після завершення екрана або акаунта.
Перевірте Capacitor-флоу
- Після npx cap sync виконайте npx cap doctor, потім відкрийте віджет із вебекрана. Перевірте, що презентація нативна й не з'явився другий iframe вебвіджета.
- Перевірте start, resume, send зі стабільним idempotency key, refresh і flushOutbox під час перемикання доступності мережі.
- Викликайте logout перед зміною підписаного клієнта й перевірте, що наступний клієнт не успадкував попередню нативну сесію.