This is the full developer documentation for capgo # Selamat datang di Capgo > Capgo는 Capacitor와 모바일 개발팀을 위한 오픈 소스 실시간 업데이트 플랫폼으로, 사용자에게 수일이 아닌 수분 만에 실시간 업데이트를 제공할 수 있게 해줍니다 Die Kraft des Live-Updates Liefern Sie nahtlos Live-App-Updates, kritische Fehlerbehebungen, Inhaltsänderungen, Beta-Funktionen und mehr, um Ihren Nutzern das bestmögliche Erlebnis zu bieten Einfach zu integrieren Das Plugin benötigt 3 Schritte zur Integration in Ihren Codebase und ermöglicht es Ihnen, Updates in Minuten statt Tagen an Ihre Nutzer zu senden! Installation Führen Sie `npx @capgo/cli@latest init [APIKEY]` aus, um zu beginnen Umfangreiche Dokumentation Lernen Sie in der [Dokumentation](/docs/getting-started/quickstart/), wie Sie das Plugin in 5 Minuten mit unserem Einführungsvideo meistern # Befehle > Capgo CLI-Dokumentation ### Verwendung Alle Befehle sollten in Ihrem App-Ordner mit ordnungsgemäß initialisiertem Capacitor-Projekt ausgeführt werden [Capacitor plattformübergreifende native Laufzeit für Web-Apps ](https://capacitorjs.com/docs/getting-started/) ### **Init** `npx @capgo/cli@latest init [apikey]` Diese Methode führt Sie Schritt für Schritt durch den Onboarding-Prozess Sie fügt Ihre App zu Capgo hinzu Sie fügt den Code zur Validierung des Updates in Ihre App ein Ebenso wird sie Ihre App erstellen Außerdem wird sie Ihre App zu Capgo hochladen Und sie hilft Ihnen zu überprüfen, ob das Update funktioniert ### **Login** `npx @capgo/cli login [apikey]` Diese Methode speichert den `apikey` für Sie Note verwenden Sie `--apikey=********` in jedem Befehl, um ihn zu überschreiben **Optional können Sie angeben:** `--local` Dies speichert Ihren **apikey** im lokalen Repository und ignoriert ihn in Git ## **Doctor** `npx @capgo/cli doctor` Befehl zur Überprüfung, ob Sie mit den Capgo-Paketen auf dem neuesten Stand sind Dieser Befehl ist auch für Fehlerberichte nützlich ## App ### **Add** `npx @capgo/cli app add [appId]` `[appId]` Ihre App-ID, das Format `comtestapp` wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt > 💡 Alle Optionen werden aus Ihrer Konfiguration erraten, wenn nicht angegeben Optional können Sie angeben: * `--icon [/path/to/my/icon]` für ein benutzerdefiniertes Icon in der Capgo Web-App * `--name [test]` für einen benutzerdefinierten Namen in der Liste * `--apikey [key]` API-Schlüssel zur Verknüpfung mit Ihrem Konto * `--retention [retention]` Aufbewahrungszeitraum des App-Bundles in Tagen, 0 standardmäßig = unendlich Beispiel einer `capacitorconfigjson` für appId und AppName, das Icon wird im resources-Ordner gesucht ```json { "appId": "eeforgrcapacitor_go", "appName": "Capgo", "webDir": "dist" } ``` ### **Set** `npx @capgo/cli app set [appId]` `[appId]` ist Ihre App-ID, das Format wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt Optional können Sie angeben: * `--icon [/path/to/my/icon]` für ein benutzerdefiniertes Icon in der Capgo Web-App * `--name [test]` für einen benutzerdefinierten Namen in der Liste * `--retention [retention]` Aufbewahrungszeitraum des App-Bundles in Tagen, 0 standardmäßig = unendlich * `--apikey [key]` API-Schlüssel zur Verknüpfung mit Ihrem Konto ### **List** `npx @capgo/cli app list [appId]` `[appId]` Ihre App-ID, das Format `comtestapp` wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt Optional können Sie angeben: * `--apikey [key]` API-Schlüssel zur Verknüpfung mit Ihrem Konto ### **Delete** `npx @capgo/cli app delete [appId]` `[appId]` Ihre App-ID, das Format `comtestapp` wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt Optional können Sie angeben: * `--apikey [key]` API-Schlüssel zur Verknüpfung mit Ihrem Konto * `--bundle` mit der Versionsnummer löscht nur diese Version ### Debug `npx @capgo/cli app debug [appId]` `[appId]` Ihre App-ID, das Format `comtestapp` wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt Optional können Sie angeben: * `--apikey [key]` API-Schlüssel zur Verknüpfung mit Ihrem Konto * `--device` mit dem spezifischen Gerät, das Sie debuggen möchten ### Setting `npx @capgo/cli app setting [path]` Bearbeiten der Capacitor-Konfiguration `[path]` - Pfad der Einstellung, die Sie ändern möchten Zum Beispiel, um die `appId` zu ändern, geben Sie `appId` an Wenn Sie das automatische Update in `capacitor-updater` deaktivieren möchten, geben Sie `pluginsCapacitorUpdaterautoUpdate` an Sie MÜSSEN entweder `--string` oder `--bool` angeben! Optionen: * `--string ` - setzt die Einstellung auf einen String * `--bool ` - setzt die Einstellung auf einen Boolean ## Bundle ### Upload `npx @capgo/cli bundle upload [appId]` `[appId]` ist Ihre App-ID, das Format wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt Optional können Sie angeben: * `--apikey ` API-Schlüssel zur Verknüpfung mit Ihrem Konto * `--path ` Pfad des hochzuladenden Ordners * `--channel ` Zu verknüpfender Kanal * `--external ` Link zu externer URL anstelle des Uploads zur Capgo Cloud * `--iv-session-key ` IV und Sitzungsschlüssel für externe Bundle-URL festlegen * `--s3-endpoint ` URL des S3-Endpunkts Funktioniert nicht mit partiellem Upload oder externer Option * `--s3-region ` Region für Ihren S3-Bucket * `--s3-apikey ` API-Schlüssel für Ihren S3-Endpunkt * `--s3-apisecret ` API-Geheimnis für Ihren S3-Endpunkt * `--s3-bucket-name ` Name für Ihren AWS S3-Bucket * `--s3-port ` Port für Ihren S3-Endpunkt * `--no-s3-ssl` SSL für S3-Upload deaktivieren * `--key ` Benutzerdefinierter Pfad für öffentlichen Signierungsschlüssel (v1-System) * `--key-data ` Öffentlicher Signierungsschlüssel (v1-System) * `--key-v2 ` Benutzerdefinierter Pfad für privaten Signierungsschlüssel (v2-System) * `--key-data-v2 ` Privater Signierungsschlüssel (v2-System) * `--bundle-url` Gibt Bundle-URL in stdout aus * `--no-key` Signierungsschlüssel ignorieren und klares Update senden * `--no-code-check` Überprüfung ignorieren, ob notifyAppReady() im Quellcode aufgerufen wird und Index im Stammverzeichnis vorhanden ist * `--display-iv-session` IV und Sitzungsschlüssel in der Konsole anzeigen, die zur Verschlüsselung des Updates verwendet werden * `--bundle ` Bundleversion der hochzuladenden Version * `--min-update-version ` Minimale Version, die für ein Update auf diese Version erforderlich ist Wird nur verwendet, wenn auto update auf metadata im Kanal gesetzt ist * `--auto-min-update-version` Minimale Update-Version basierend auf nativen Paketen festlegen * `--ignore-metadata-check` Ignoriert die Metadaten-Prüfung (node\_modules) beim Hochladen * `--ignore-checksum-check` Ignoriert die Prüfsummen-Prüfung beim Hochladen * `--timeout ` Timeout für den Upload-Prozess in Sekunden * `--partial` Lädt keine partiellen Dateien zur Capgo-Cloud hoch * `--tus` Lädt das Bundle mit dem tus-Protokoll hoch * `--multipart` Verwendet das Multipart-Protokoll zum Hochladen von Daten zu S3, Veraltet, verwenden Sie stattdessen TUS * `--encrypted-checksum ` Eine verschlüsselte Prüfsumme (Signatur) Wird nur beim Hochladen eines externen Bundles verwendet * `--package-json ` Ein Pfad zu packagejson Nützlich für Monorepos * `--auto-set-bundle` Bundle in capacitorconfigjson setzen * `--node-modules ` Eine Liste von Pfaden zu node\_modules Nützlich für Monorepos (kommagetrennt z.B.: //node\_modules,/node\_modules) > ⭐️ Die externe Option hilft zwei Fälle zu lösen: Unternehmen mit Datenschutzbedenken, die keinen Code an Dritte senden möchten und Apps größer als 200 MB Mit dieser Einstellung speichert Capgo nur den Link zur ZIP-Datei und sendet den Link an alle Apps > 👀 Capgo Cloud schaut nie, was sich im Link (für externe Option) oder im Code befindet, wenn gespeichert > 🔑 Sie können eine zweite Sicherheitsebene durch Verschlüsselung hinzufügen, dann kann Capgo nichts einsehen oder modifizieren, es wird “vertrauenslos” Beispiel einer `packagejson` für Version ```json { "version": "102" } ``` > ⛔ Version sollte größer als “000” sein > 💡 Vergessen Sie nicht, die Versionsnummer bei jedem Senden zu aktualisieren, Versionsnummern können aus Sicherheitsgründen nicht überschrieben oder nach dem Löschen wiederverwendet werden ### **List** `npx @capgo/cli bundle list [appId]` `[appId]` Ihre App-ID, das Format `comtestapp` wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt Optional können Sie angeben: * `--apikey [key]` API-Schlüssel zur Verknüpfung mit Ihrem Konto ### **Delete** `npx @capgo/cli bundle delete [appId]` `[appId]` Ihre App-ID, das Format `comtestapp` wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt Optional können Sie angeben: * `--apikey [key]` API-Schlüssel zur Verknüpfung mit Ihrem Konto * `--bundle` mit der Versionsnummer löscht nur diese Version ### Cleanup in einem SemVer-Bereich für eine Hauptversion in der Cloud `npx @capgo/cli bundle cleanup [appId] --bundle=[majorVersion] --keep=[numberToKeep]` `[appId]` Ihre App-ID, das Format `comtestapp` wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt Optional können Sie angeben: * `--apikey [key]` API-Schlüssel zur Verknüpfung mit Ihrem Konto * `--bundle [majorVersion]` eine Version, für die Sie vorherige Pakete entfernen möchten, es wird die letzte Version + `numberToKeep` behalten\* `--keep [numberToKeep]` die Anzahl der Pakete, die Sie behalten möchten (Standard 4) Zum Beispiel: Wenn Sie 10 Versionen von 1001 bis 10011 haben und Sie `npx @capgo/cli cleanup [appId] --bundle=1000` verwenden, werden 1001 bis 1006 entfernt, 1007 bis 10011 werden behalten Wenn Sie insgesamt 20 Versionen haben und keine Bundlenummer angeben, wie hier: `npx @capgo/cli cleanup [appId] --keep=2`, werden 18 Versionen entfernt und die letzten 2 behalten > Dieser Befehl wird um Bestätigung bitten und zeigt eine Tabelle mit den zu behaltenden und zu entfernenden Versionen Note Dieser Befehl ignoriert Bundles, die derzeit in einem Kanal verwendet werden ### **Encrypt** > **Warnung**: Dieser Befehl ist veraltet und wird in der nächsten Hauptversion entfernt. Bitte verwenden Sie das neue Verschlüsselungssystem `npx @capgo/cli bundle encrypt [path/to/zip]` Dieser Befehl wird verwendet, wenn Sie externe Quellen zum Speichern Ihres Codes verwenden oder zu Testzwecken Optional können Sie angeben: `--key [/path/to/my/private_key]` der Pfad zu Ihrem privaten Schlüssel `--key-data [privateKey]` die privaten Schlüsseldaten, wenn Sie sie inline verwenden möchten Der Befehl gibt Ihren `ivSessionKey` aus und generiert eine verschlüsselte ZIP-Datei zur Verwendung mit dem Upload- oder Decrypt-Befehl ### **Encrypt V2** `npx @capgo/cli bundle encryptV2 [path/to/zip] [checksum]` Dieser Befehl wird verwendet, wenn Sie externe Quellen zum Speichern Ihres Codes verwenden oder zu Testzwecken Die Prüfsumme ist der SHA256-Hash des Bundles (generiert durch —key-v2) und wird verwendet, um die Integrität der Datei nach der Entschlüsselung zu überprüfen Sie wird mit dem privaten Schlüssel verschlüsselt und zusammen mit dem Bundle gesendet In Verschlüsselung v2 wird die Prüfsumme zu einer “Signatur” des Bundles aufgewertet Optional können Sie angeben: `--key [/path/to/my/private_key]` der Pfad zu Ihrem privaten Schlüssel `--key-data [privateKey]` die privaten Schlüsseldaten, wenn Sie sie inline verwenden möchten `--json` um Informationen als JSON auszugeben Der Befehl gibt Ihren `ivSessionKey` aus und generiert eine verschlüsselte ZIP-Datei zur Verwendung mit dem Upload- oder Decrypt-Befehl ### **Decrypt** `npx @capgo/cli bundle decrypt [path/to/zip] [ivSessionKey]` Optional können Sie angeben: `--key [/path/to/my/private_key]` der Pfad zu Ihrem privaten Schlüssel `--key-data [privateKey]` die privaten Schlüsseldaten, wenn Sie sie inline verwenden möchten Dieser Befehl wird hauptsächlich zu Testzwecken verwendet, er entschlüsselt die ZIP-Datei und gibt den base64-decodierten Sitzungsschlüssel in der Konsole aus ### **Decrypt V2** `npx @capgo/cli bundle decryptV2 [path/to/zip] [ivSessionKey]` Optional können Sie angeben: `--key [/path/to/my/private_key]` der Pfad zu Ihrem privaten Schlüssel `--key-data [privateKey]` die privaten Schlüsseldaten, wenn Sie sie inline verwenden möchten Dieser Befehl wird hauptsächlich zu Testzwecken verwendet, er entschlüsselt die ZIP-Datei und gibt den base64-decodierten Sitzungsschlüssel in der Konsole aus `--checksum [checksum]` die Prüfsumme der Datei, sie wird nach der Entschlüsselung überprüft ### **Zip** `npx @capgo/cli bundle zip [appId]` `[appId]` ist Ihre App-ID, das Format wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt Optional können Sie angeben: * `--path [/path/to/my/bundle]` um einen bestimmten Ordner hochzuladen * `--bundle [100]` um die Bundle-Versionsnummer des Dateinamens festzulegen * `--name [myapp]` um den Dateinamen zu überschreiben * `--json` um Informationen als JSON auszugeben * `--no-code-check` um die Code-Prüfung zu ignorieren und das Bundle trotzdem zu senden * `--key-v2` um das neue Verschlüsselungssystem zu verwenden Dies ist erforderlich, da das neue Verschlüsselungssystem bessere Prüfsummen zur Überprüfung der Dateiintegrität verwendet ### **Compatibility** `npx @capgo/cli bundle compatibility [appId] -c [channelId]` `[appId]` ist Ihre App-ID, das Format wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt `[channelId]` der Name Ihres neuen Kanals Optional können Sie angeben: * `--apikey [key]` API-Schlüssel zur Verknüpfung mit Ihrem Konto * `--text` Text statt Emojis in der Tabelle verwenden * `--channel [channel]` der Kanal, dessen Kompatibilität überprüft werden soll * `--package-json ` Ein Pfad zur package.json Nützlich für Monorepos * `--node-modules ` Eine Liste von Pfaden zu node\_modules Nützlich für Monorepos (kommagetrennt z.B.: //node\_modules,/node\_modules) ## Channel ### **Add** `npx @capgo/cli channel add [channelId] [appId]` `[channelId]` der Name Ihres neuen Kanals `[appId]` Ihre App-ID, das Format `comtestapp` wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt ### **Delete** `npx @capgo/cli channel delete [channelId] [appId]` `[channelId]` der Name des Kanals, den Sie löschen möchten `[appId]` Ihre App-ID, das Format `comtestapp` wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt ### **List** `npx @capgo/cli channel list [appId]` `[appId]` Ihre App-ID, das Format `comtestapp` wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt Optional können Sie angeben: * `--apikey [key]` API-Schlüssel zur Verknüpfung mit Ihrem Konto ### **Set** `npx @capgo/cli channel set [channelId] [appId]` `[appId]` ist Ihre App-ID, das Format wird [hier](https://capacitorjs.com/docs/cli/commands/init/) erklärt Optional können Sie angeben: * `--bundle [123]` Ihr bereits in die Cloud gesendetes App-Bundle, um es mit einem Kanal zu verknüpfen * `--latest` holt die Bundle-Version aus `packagejson:version`, kann nicht mit `--bundle` verwendet werden * `--state [ normal | default ]` setzt den Kanalstatus, kann `normal` oder `default` sein Ein Kanal muss `default` sein * `--downgrade` erlaubt dem Kanal, Downgrade-Versionen an Geräte zu senden * `--no-downgrade` verbietet dem Kanal, Downgrade-Versionen an Geräte zu senden * `--upgrade` erlaubt dem Kanal, Upgrade (Major) Versionen an Geräte zu senden * `--no-upgrade` verbietet dem Kanal, Upgrade (Major) Versionen an Geräte zu senden * `--ios` erlaubt dem Kanal, Versionen an iOS-Geräte zu senden * `--no-ios` verbietet dem Kanal, Versionen an iOS-Geräte zu senden * `--android` erlaubt dem Kanal, Versionen an Android-Geräte zu senden * `--no-android` verbietet dem Kanal, Versionen an Android-Geräte zu senden * `--self-assign` erlaubt Geräten, sich selbst diesem Kanal zuzuweisen * `--no-self-assign` verbietet Geräten, sich selbst diesem Kanal zuzuweisen * `--disable-auto-update STRATEGY` Deaktiviert die Auto-Update-Strategie für diesen Kanal Die möglichen Optionen sind: major, minor, metadata, none * `--apikey [key]` API-Schlüssel zur Verknüpfung mit Ihrem Konto ## Deaktivieren der Update-Strategien Es gibt mehrere Möglichkeiten, Updates für zu alte Versionen zu deaktivieren\ Capgo kann nativen Code nicht aktualisieren, daher sollte ein Update von einer Version mit altem nativen Code auf eine Version mit aktualisiertem nativen Code nicht möglich sein Es gibt mehrere Möglichkeiten, dies zu erreichen Erstens die `major` Strategie Sie verhindert ein Update von `000` -> `100` Die Hauptversion ist die hervorgehobene Nummer (**1**00 und **0**00)\ Zweitens die `minor` Strategie Sie verhindert ein Update von `000` -> `110` oder ein Update von `110` auf `120` **ACHTUNG** diese Strategie verhindert nicht ein Update von `010` -> `110` Drittens die `patch` Strategie Sie wurde als sehr strenger Modus in Capgo eingeführt Es wird nicht empfohlen, sie zu verwenden, es sei denn, Sie verstehen vollständig, wie sie funktioniert Damit ein Update akzeptiert wird, müssen folgende Bedingungen erfüllt sein: * Die Hauptversion ist zwischen der neuen und alten Version gleich * Die Nebenversion ist zwischen der neuen und alten Version gleich * Die Patch-Version der neuen Version ist größer als die Patch-Version der alten Version Hier ein Beispiel, welche Szenarien für Updates erlaubt oder abgelehnt werden: * 00311 -> 00314 ✅ * 000 -> 00314 ✅ * 00316 -> 00314 ❌ * 01312 -> 00314 ❌ * 10312 -> 00314 ❌ Zuletzt die komplizierteste Strategie Die `metadata` Strategie\ Zuerst müssen Sie wissen, dass die Updates anfangs **FEHLSCHLAGEN** werden, da dem Kanal die erforderlichen Metadaten fehlen\ Wenn dem Kanal Metadaten fehlen, sehen Sie eine Nachricht wie diese: ![Cannot find metadata](/fail-metadata.webp) Wenn Sie so etwas sehen, wissen Sie, dass Sie zum aktuellen Bundle für den fehlschlagenden Kanal gehen und die Metadaten setzen müssen\ Ermitteln Sie zunächst, welcher Kanal fehlschlägt Sie können das in der Spalte `misconfigured` sehen ![Misconfigured table](/misconfigured-table.webp) Gehen Sie dann zum fehlerhaften Kanal und klicken Sie auf `Bundle number`. Dies sollte Sie zur Bundle-Seite führen. ![Locate failing channel](/fail-channel-show.webp) Füllen Sie dort das Feld `Minimal update version` aus. Dies sollte ein [semver](https://devhints.io/semver/) sein.\ Wenn der eingegebene Wert kein semver ist, erhalten Sie eine Fehlermeldung. Bei korrekter Eingabe sollten Sie etwa Folgendes sehen: ![Set min version](/set-min-update-version.webp) Sie möchten diese Daten wahrscheinlich nicht bei jedem Update manuell festlegen. Glücklicherweise verhindert die CLI das Senden eines Updates ohne diese Metadaten. ![CLI fail no metadata](/cli-fail-no-metadata.webp) Um ein Bundle mit der Option `metadata` korrekt hochzuladen, müssen Sie `--min-update-version` mit einem gültigen semver übergeben. Etwa so: ![CLI upload with metadata](/cli-upload-with-metadata.webp) Die `--min-update-version` ist nicht der EINZIGE Weg für Kompatibilität. Es gibt auch `--auto-min-update-version`. So funktioniert es: 1. Es prüft die aktuell im Kanal hochgeladene Version und überprüft die Kompatibilität wie der Befehl `bundle compatibility`. 2. Wenn die neue Version 100% kompatibel ist, wird die `min_update_version` der neuesten Version im Kanal wiederverwendet. Wenn nicht, wird die `min_update_version` auf die Bundle-Nummer der neu hochgeladenen Version gesetzt. Sie erhalten bei Verwendung dieser Option immer eine Information über die `min_update_version`. Es wird etwa so aussehen: ![Min update version](/min_update_version_info.webp) Wenn die neue Version nicht kompatibel ist, sollte es etwa so aussehen: ![Min update version not compatible](/min_update_version_not_compatible.webp) ## Ende-zu-Ende-Verschlüsselung (Trustless) Capgo unterstützt Ende-zu-Ende-Verschlüsselung, das bedeutet, dass Ihr Bundle (Code) vor dem Senden in die Cloud verschlüsselt und auf dem Gerät entschlüsselt wird. Dafür müssen Sie ein RSA-Schlüsselpaar generieren, Sie können den folgenden Befehl verwenden, um es zu generieren. Das Verschlüsselungssystem ist eine Kombination aus RSA und AES, der RSA-Schlüssel wird verwendet, um den AES-Schlüssel zu verschlüsseln, und der AES-Schlüssel wird verwendet, um die Datei zu verschlüsseln. Weitere Informationen zum Verschlüsselungssystem finden Sie unten ![How crypto works](/crypto_explained.webp) Verschlüsselungsschema ### Schlüssel für Ihre App erstellen `npx @capgo/cli key create` Optional können Sie `--force` verwenden, um den vorhandenen Schlüssel zu überschreiben. Dieser Befehl erstellt ein Schlüsselpaar in Ihrer App und fordert Sie auf, den privaten Schlüssel an einem sicheren Ort zu speichern. Es wird empfohlen, den privaten Schlüssel nicht in Git zu committen und mit niemandem zu teilen. > Nach Ihrem lokalen Test entfernen Sie den Schlüssel aus der Konfigurationsdatei und fügen Sie ihn im CI-Schritt mit `key save` hinzu. ### Schlüssel in Ihrer App-Konfiguration speichern `npx @capgo/cli key save` Optional können Sie angeben: `--key [/path/to/my/private_key]` der Pfad zu Ihrem privaten Schlüssel `--key-data [privateKey]` die privaten Schlüsseldaten, wenn Sie sie inline verwenden möchten. Dieser Befehl ist nützlich, wenn Sie der Empfehlung gefolgt sind und den Schlüssel nicht in Ihrer App und in der Konfiguration committet haben. ## CI-Integration Um Ihre Arbeit zu automatisieren, empfehle ich Ihnen, GitHub Actions die Aufgabe des Pushens zu unserem Server zu überlassen. [GitHub Action Tutorial](https://capgo.app/blog/automatic-build-and-release-with-github-actions/) ## Unsere Demo-App [GitHub - Cap-go/demo-app](https://github.com/Cap-go/demo-app/) Vergessen Sie nicht, die CI-Umgebungsvariable mit Ihrem API-Schlüssel zu konfigurieren. # CLI de 0.x a 1.x > Upgrade-Anleitung von 0.x auf 1.x Es gibt keine wesentlichen Änderungen in der CLI Die wichtigste Änderung ist die Umbenennung des Arguments `--version` zu `--bundle`, um Konflikte zu vermeiden und der neuen Namensgebung überall zu folgen # Verschlüsselung > So verschlüsseln Sie Ihre Daten mit neuer Verschlüsselung Diese Dokumentation erklärt, wie Sie Ihre Daten mit dem neuen Verschlüsselungssystem verschlüsseln und das alte entfernen können Erfahren Sie mehr über das neue Verschlüsselungssystem im [Blog-Beitrag](/blog/introducing-end-to-end-security-to-capacitor-updater-with-code-signing) *** Erstellen Sie zunächst ein neues Schlüsselpaar mit folgendem Befehl: ```bash npx @capgo/cli key create ``` Dieser Befehl erstellt ein neues Schlüsselpaar in Ihrer App; es ist zwingend erforderlich, den privaten Schlüssel an einem sicheren Ort aufzubewahren. Der private Schlüssel darf niemals in die Versionskontrolle übernommen oder mit nicht vertrauenswürdigen Parteien geteilt werden Dieser Befehl entfernt auch den alten Schlüssel aus Ihrer Capacitor-Konfiguration, entfernt jedoch nicht die alten Schlüsseldateien. Die CLI behält diese bei, damit Sie weiterhin Live-Updates für Apps senden können, die noch kein App-Store-Update erhalten haben und das alte Plugin verwenden. Dies erleichtert die Migration Wenn Sie bei der Migration gefragt werden: “Möchten Sie die Verschlüsselung mit dem neuen Kanal einrichten, um alte Apps zu unterstützen und die Migration zu erleichtern?”, stimmen Sie bitte zu. Dies fügt eine neue “defaultChannel”-Option zu Ihrer Capacitor-Konfiguration hinzu. Dadurch verwendet Ihre App den Kanal “encryption\_v2”. Dies stellt sicher, dass die neue Verschlüsselung nur von Apps verwendet wird, die sie unterstützen. Apps, die noch kein App-Store-Update erhalten haben, verwenden weiterhin den vorherigen Standardkanal *** Nun müssen Sie Ihr JS-Bundle erstellen und es in den neuen Kanal hochladen. Führen Sie dazu folgenden Befehl aus: ```bash npx @capgo/cli bundle upload --channel encryption_v2 ``` *** Führen Sie dann diesen Befehl aus, um Apps zu erlauben, sich selbst dem Kanal “encryption\_v2” zuzuweisen: Caution Dies ist notwendig, damit die neue “defaultChannel”-Option funktioniert ```bash npx @capgo/cli channel set encryption_v2 --self-assign ``` *** Sie können die App jetzt ausführen; sie wird das neue Verschlüsselungssystem verwenden Um das neue JS-Bundle in den alten Kanal hochzuladen, müssen Sie nur folgenden Befehl ausführen: ```bash npx @capgo/cli bundle upload --channel production ``` *** Sie müssen sich keine Sorgen um die Capacitor-Konfiguration machen, sie wird nie zu Capgo hochgeladen Wenn alle Benutzer ihre Apps aktualisiert haben (dies kann bis zu 3/4 Monate dauern), können Sie “defaultChannel” aus Ihrer Capacitor-Konfiguration entfernen Dann können Sie den alten Kanal mit folgendem Befehl entfernen: ```bash npx @capgo/cli channel delete encryption_v2 ``` *** Nach dem Löschen des “encryption\_v2”-Kanals werden alle Apps, die ihn als Standard verwenden, beginnen, den “production”-Kanal zu verwenden # Übersicht Nutzen Sie Capgos Live-Updates-Funktion, um die JavaScript-Bundles Ihrer App aus der Ferne in Echtzeit zu aktualisieren. Senden Sie JS-Updates direkt an Ihre Nutzer, ohne den App-Store-Überprüfungsprozess zu durchlaufen, um sofort Fehler zu beheben und neue Funktionen bereitzustellen. Note Live-Updates sind auf JavaScript-Bundle-Änderungen beschränkt. Wenn Sie nativen Code aktualisieren müssen, wie das Hinzufügen oder Entfernen eines Plugins oder das Ändern der nativen Projektkonfiguration, müssen Sie einen neuen nativen Binary-Build an die App Stores übermitteln. ## Wie Live-Updates funktionieren Das Live-Update-System von Capgo hat zwei Schlüsselkomponenten: 1. Das Capgo SDK, das Sie in Ihrer App installieren. Das SDK prüft auf verfügbare Updates und lädt sie im Hintergrund herunter. 2. Kanäle, mit denen Sie Updates für bestimmte Benutzergruppen bereitstellen können. Sie können Kanäle verwenden, um verschiedene Release-Tracks wie `Production`, `Staging` und `Dev` zu verwalten. Wenn Sie ein neues JS-Bundle auf Capgo hochladen und einem Kanal zuweisen, erkennt das Capgo SDK in Apps, die für diesen Kanal konfiguriert sind, das Update und lädt es herunter. Beim nächsten Neustart der App wird das neue Bundle geladen. ## Erste Schritte Folgen Sie diesen Schritten, um mit Live-Updates zu beginnen: 1. Schließen Sie den [Capgo Quickstart](/docs/getting-started/quickstart) ab, um Ihre App in Capgo einzurichten und das Capgo SDK zu installieren. 2. Rufen Sie in Ihrem App-Code `CapacitorUpdaternotifyAppReady()` auf, nachdem Ihre App initialisiert wurde. Dies teilt dem Capgo SDK mit, dass Ihre App bereit ist, Updates zu empfangen. 3. Erstellen Sie Ihr JS-Bundle und laden Sie es auf Capgo hoch: ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. Öffnen Sie Ihre App und warten Sie, bis das Update heruntergeladen ist. Sie können den Status überprüfen mit: ```shell npx @capgo/cli@latest app debug ``` 5. Sobald das Update heruntergeladen ist, schließen und öffnen Sie Ihre App erneut, um das neue Bundle zu laden. Weitere Details finden Sie im [Leitfaden für Live-Updates-Bereitstellung](/docs/getting-started/deploy). ## Die Capgo CLI Die Capgo CLI ist ein leistungsstarkes Tool, das Entwicklern ermöglicht, mit Capgos Diensten aus ihren eigenen CI/CD-Pipelines zu interagieren. Mit der CLI haben Sie detaillierte Kontrolle darüber, wann Builds erstellt und bereitgestellt werden, sodass Sie Capgo in Ihre bestehenden Enterprise-Workflows integrieren können. ### Wofür ist die Capgo CLI gedacht? Die Capgo CLI ist für Entwickler und Teams konzipiert, die mehr Kontrolle und Flexibilität in ihren Live-Update-Workflows benötigen. Durch die Verwendung der CLI in Ihren CI/CD-Pipelines können Sie: * Genau festlegen, wann Updates erstellt und bereitgestellt werden sollen, anstatt sich auf Capgos integrierte Automatisierung zu verlassen * Eigene Prozesse wie Code-Signierung, QA-Tests oder Manager-Genehmigungen zwischen den Build- und Bereitstellungsschritten einfügen * Capgo in Ihre bestehenden DevOps-Tools und -Workflows integrieren ### Authentifizierung Um die Capgo CLI zu nutzen, müssen Sie sich mit Ihrem API-Schlüssel authentifizieren. Sie können einen API-Schlüssel in Ihren Capgo-Kontoeinstellungen generieren. Um sich anzumelden und Ihren API-Schlüssel sicher zu speichern, führen Sie aus: ```shell npx @capgo/cli@latest login [API_KEY] ``` Dieser Befehl wird dann für zukünftige Verwendungen gespeichert. Nach der Anmeldung müssen Sie Ihren API-Schlüssel nicht bei jedem Befehl erneut angeben. ### Wichtige Unterschiede zu anderen CLI-Tools Wenn Sie mit anderen Live-Update-CLI-Tools vertraut sind, gibt es einige wichtige Besonderheiten der Capgo CLI zu beachten: * Capgo verwendet eine einzige CLI sowohl für Entwicklungs- als auch für CI/CD-Anwendungsfälle, da Capgo sich ausschließlich auf Live-Update-Funktionen konzentriert * Die Capgo CLI erfordert keinen separaten Installationsschritt. Sie ist im `@capgo/cli`-Paket enthalten und kann direkt mit `npx` ausgeführt werden * Die Capgo CLI ist speziell für den Live-Update-Workflow konzipiert und enthält möglicherweise nicht alle Funktionen oder Befehle, die in allgemeineren CLI-Tools zu finden sind ## Nächste Schritte [ Kanäle](/docs/live-updates/channels/) [Erfahren Sie, wie Sie Kanäle verwenden, um verschiedene Release-Tracks zu verwalten und Updates für bestimmte Benutzer bereitzustellen](/docs/live-updates/channels/) [ Rollbacks](/docs/live-updates/rollbacks/) [Entdecken Sie, wie Sie zu einer vorherigen JS-Bundle-Version zurückkehren können, wenn ein Update Probleme verursacht](/docs/live-updates/rollbacks/) [ Update-Verhalten](/docs/live-updates/update-behavior/) [Passen Sie an, wie und wann Updates in Ihrer App heruntergeladen und angewendet werden](/docs/live-updates/update-behavior/) [ Schnelle Updates](/docs/live-updates/differentials/) [Erfahren Sie, wie Sie schnelle Updates verwenden können, um den Update-Prozess zu beschleunigen](/docs/live-updates/differentials/) # Übersicht > Detaillierte Dokumentation für Capgo CLI-Befehle Die Capgo CLI stellt eine Reihe von Befehlen zur Verwaltung Ihrer Capgo-Apps und Deployments bereit. Diese Referenz bietet detaillierte Informationen zu jedem verfügbaren Befehl, einschließlich seiner Optionen und Anwendungsbeispiele. ## Befehle [ init](/docs/cli/reference/init/) [Eine neue Capgo-App initialisieren](/docs/cli/reference/init/) [ login](./login/) [Mit dem Capgo-Service authentifizieren](./login/) [ doctor](/docs/cli/reference/doctor/) [Überprüfen Sie Ihre Capgo-Einrichtung auf mögliche Probleme](/docs/cli/reference/doctor/) [ app](./app/) [Verwalten Sie Ihre Capgo-Apps](./app/) [ bundle](/docs/cli/reference/bundle/) [Verwalten Sie Ihre App-Bundles](/docs/cli/reference/bundle/) [ channel](/docs/cli/reference/channel/) [Verwalten Sie Ihre Release-Kanäle](/docs/cli/reference/channel/) [ key](/docs/cli/reference/key/) [Verwalten Sie Ihre App-Signierungsschlüssel](/docs/cli/reference/key/) ## CI-Integration Um Ihre Arbeit zu automatisieren, empfehlen wir die Verwendung von GitHub Actions, um Ihre Updates an Capgo zu übertragen. Weitere Informationen finden Sie in unserem [GitHub Actions Tutorial](https://capgo.app/blog/automatic-build-and-release-with-github-actions/) Vergessen Sie nicht, Ihre CI-Umgebungsvariablen mit Ihrem Capgo API-Schlüssel zu konfigurieren. ## Demo-App Ein vollständiges Beispiel einer Capgo-App mit CI-Integration finden Sie in unserer [Demo-App auf GitHub](https://github.com/Cap-go/demo-app/) # Konto Der `account`-Befehl ermöglicht die Verwaltung Ihres Capgo-Kontos ### id `npx @capgo/cli account id` Ruft Ihre Konto-ID ab Optionen: * `-a, --apikey `: API-Schlüssel zur Verknüpfung mit Ihrem Konto # App Der `app`-Befehl ermöglicht die Verwaltung Ihrer Capgo-Apps ### add `npx @capgo/cli app add [appId]` Fügt eine neue App zu Ihrem Capgo-Konto hinzu `[appId]` ist Ihre App-ID im Format `com.example.app`. Weitere Informationen finden Sie in der [Capacitor-Dokumentation](https://capacitorjs.com/docs/cli/commands/init/) > 💡 Alle Optionen werden aus Ihrer `capacitor.config.json` ermittelt, wenn sie nicht angegeben werden Optionen: * `--icon [path]`: Pfad zu einem benutzerdefinierten Symbol, das in der Capgo-Webanwendung angezeigt wird * `--name [name]`: Benutzerdefinierter Name, der in der App-Liste angezeigt wird * `--apikey [key]`: API-Schlüssel zur Verknüpfung mit Ihrem Konto * `--retention [days]`: Aufbewahrungszeitraum für App-Bundles in Tagen (Standard: 0 = unbegrenzt) ### set `npx @capgo/cli app set [appId]` Aktualisiert eine bestehende App in Ihrem Capgo-Konto Optionen: * `--icon [path]`: Pfad zu einem benutzerdefinierten Symbol, das in der Capgo-Webanwendung angezeigt wird * `--name [name]`: Benutzerdefinierter Name, der in der App-Liste angezeigt wird * `--retention [days]`: Aufbewahrungszeitraum für App-Bundles in Tagen (Standard: 0 = unbegrenzt) * `--apikey [key]`: API-Schlüssel zur Verknüpfung mit Ihrem Konto ### list `npx @capgo/cli app list [appId]` Listet alle Apps in Ihrem Capgo-Konto auf Optionen: * `--apikey [key]`: API-Schlüssel zur Verknüpfung mit Ihrem Konto ### delete `npx @capgo/cli app delete [appId]` Löscht eine App aus Ihrem Capgo-Konto Optionen: * `--apikey [key]`: API-Schlüssel zur Verknüpfung mit Ihrem Konto * `--bundle`: Löscht nur eine bestimmte Bundle-Version ### debug `npx @capgo/cli app debug [appId]` Zeigt Debug-Informationen für eine App an Optionen: * `--apikey [key]`: API-Schlüssel zur Verknüpfung mit Ihrem Konto * `--device`: Debug eines bestimmten Geräts ### setting `npx @capgo/cli app setting [path]` Bearbeitet die Capacitor-Konfiguration für eine App `[path]` ist der Pfad zur Einstellung, die Sie ändern möchten (z.B. `appId` oder `plugins.CapacitorUpdater.autoUpdate`) Sie müssen entweder `--string` oder `--bool` angeben: * `--string `: Setzt die Einstellung auf einen String-Wert * `--bool `: Setzt die Einstellung auf einen Boolean-Wert # Bündel Der `bundle`-Befehl ermöglicht die Verwaltung Ihrer App-Bundles ### upload `npx @capgo/cli bundle upload [appId]` Lädt ein neues Bundle für eine App hoch Optionen: * `-a, --apikey `: API-Schlüssel zur Verknüpfung mit Ihrem Konto * `-p, --path `: Pfad zum hochzuladenden Ordner (standardmäßig das `webDir` in `capacitorconfig`) * `-c, --channel `: Channel, mit dem das Bundle verknüpft werden soll * `-e, --external `: Link zu einer externen URL statt Upload zu Capgo Cloud * `--iv-session-key `: IV und Session-Schlüssel für externe Bundle-URL festlegen * `--s3-region `: Region für Ihren S3-Bucket * `--s3-apikey `: API-Schlüssel für Ihren S3-Endpunkt * `--s3-apisecret `: API-Secret für Ihren S3-Endpunkt * `--s3-endpoint `: URL des S3-Endpunkts * `--s3-bucket-name `: Name Ihres S3-Buckets * `--s3-port `: Port für Ihren S3-Endpunkt * `--no-s3-ssl`: SSL für S3-Uploads deaktivieren * `--key `: Benutzerdefinierter Pfad für den öffentlichen Signaturschlüssel (v1-System) * `--key-data `: Öffentliche Signaturschlüsseldaten (v1-System) * `--key-v2 `: Benutzerdefinierter Pfad für den privaten Signaturschlüssel (v2-System) * `--key-data-v2 `: Private Signaturschlüsseldaten (v2-System) * `--bundle-url`: Bundle-URL in stdout ausgeben * `--no-key`: Signaturschlüssel ignorieren und unsigniertes Update senden * `--no-code-check`: Überprüfung auf `notifyAppReady()` im Quellcode und `indexhtml` im Root-Verzeichnis überspringen * `--display-iv-session`: IV und Session-Schlüssel zur Verschlüsselung des Updates anzeigen * `-b, --bundle `: Hochzuladende Bundle-Versionsnummer * `--min-update-version `: Mindestversion der App für dieses Update (nur verwendet wenn Auto-Update über Metadaten deaktiviert ist) * `--auto-min-update-version`: Automatische Festlegung der Mindest-Update-Version basierend auf nativen Paketversionen * `--ignore-metadata-check`: Metadaten-Prüfung (node\_modules) beim Hochladen ignorieren * `--ignore-checksum-check`: Prüfsummen-Prüfung beim Hochladen ignorieren * `--timeout `: Timeout für den Upload-Prozess in Sekunden * `--multipart`: Multipart-Protokoll für S3-Upload verwenden (veraltet, nutzen Sie stattdessen `--tus`) * `--tus`: Bundle mit dem tus-Protokoll hochladen * `--tus-chunk-size `: Chunk-Größe für den tus-Upload * `--partial`: Nur geänderte Dateien zu Capgo Cloud hochladen * `--partial-only`: Nur partielle Dateien zu Capgo Cloud hochladen, ZIP-Datei überspringen (nützlich für große Bundles) * `--encrypted-checksum `: Verschlüsselte Prüfsumme (Signatur) für externes Bundle * `--auto-set-bundle`: Bundle-Version automatisch in `capacitorconfigjson` setzen * `--dry-upload`: Testlauf des Upload-Prozesses ohne tatsächlichen Upload (nützlich zum Testen) * `--package-json `: Kommagetrennte Liste von Pfaden zu `packagejson`-Dateien (nützlich für Monorepos) * `--node-modules `: Kommagetrennte Liste von Pfaden zu `node_modules`-Verzeichnissen (nützlich für Monorepos) * `--encrypt-partial`: Partielle Update-Dateien verschlüsseln * `--delete-linked-bundle-on-upload`: Aktuell verknüpftes Bundle im Ziel-Channel vor dem Upload löschen ### compatibility `npx @capgo/cli bundle compatibility [appId]` Prüft die Kompatibilität eines Bundles mit einem bestimmten Channel Optionen: * `-a, --apikey `: API-Schlüssel zur Verknüpfung mit Ihrem Konto * `-c, --channel `: Zu prüfender Channel * `--text`: Ergebnisse als Text statt Emoji ausgeben * `--package-json `: Kommagetrennte Liste von Pfaden zu `packagejson`-Dateien (nützlich für Monorepos) * `--node-modules `: Kommagetrennte Liste von Pfaden zu `node_modules`-Verzeichnissen (nützlich für Monorepos) ### delete `npx @capgo/cli bundle delete [bundleId] [appId]` Löscht ein Bundle aus einer App Optionen: * `-a, --apikey `: API-Schlüssel zur Verknüpfung mit Ihrem Konto ### list `npx @capgo/cli bundle list [appId]` Listet alle Bundles einer App auf Optionen: * `-a, --apikey `: API-Schlüssel zur Verknüpfung mit Ihrem Konto ### cleanup `npx @capgo/cli bundle cleanup [appId]` Bereinigt alte Bundles einer Hauptversion und behält die angegebene Anzahl der neuesten Bundles Optionen: * `-b, --bundle `: Zu bereinigende Hauptversionsnummer * `-a, --apikey `: API-Schlüssel zur Verknüpfung mit Ihrem Konto * `-k, --keep `: Anzahl der zu behaltenden Bundles (Standard: 4) * `-f, --force`: Erzwungenes Entfernen ohne Bestätigung ### decrypt `npx @capgo/cli bundle decrypt [zipPath] [sessionKey]` Entschlüsselt ein signiertes ZIP-Bundle Optionen: * `--key `: Benutzerdefinierter Pfad für den privaten Signaturschlüssel * `--key-data `: Private Signaturschlüsseldaten ### encrypt `npx @capgo/cli bundle encrypt [zipPath]` Verschlüsselt ein ZIP-Bundle Optionen: * `--key `: Benutzerdefinierter Pfad für den privaten Signaturschlüssel * `--key-data `: Private Signaturschlüsseldaten ### encryptV2 `npx @capgo/cli bundle encryptV2 [zipPath] [checksum]` Verschlüsselt ein ZIP-Bundle mit der neuen Verschlüsselungsmethode Optionen: * `--key `: Benutzerdefinierter Pfad für den privaten Signaturschlüssel * `--key-data `: Private Signaturschlüsseldaten * `-j, --json`: Ergebnisse als JSON ausgeben ### decryptV2 `npx @capgo/cli bundle decryptV2 [zipPath] [checksum]` Entschlüsselt ein ZIP-Bundle mit der neuen Verschlüsselungsmethode Optionen: * `--key `: Benutzerdefinierter Pfad für den privaten Signaturschlüssel * `--key-data `: Private Signaturschlüsseldaten * `--checksum `: Prüfsumme des Bundles zur Integritätsprüfung ### zip `npx @capgo/cli bundle zip [appId]` Erstellt eine ZIP-Datei für ein Bundle Optionen: * `-p, --path `: Pfad zum zu zippenden Ordner (standardmäßig das `webDir` in `capacitorconfig`) * `-b, --bundle `: Bundle-Versionsnummer für den Dateinamen * `-n, --name `: Benutzerdefinierter Dateiname für die ZIP-Datei * `-j, --json`: Ergebnisse als JSON ausgeben * `--no-code-check`: Überprüfung auf `notifyAppReady()` im Quellcode und `indexhtml` im Root-Verzeichnis überspringen * `--key-v2`: Neue Verschlüsselungsmethode (v2) verwenden * `--package-json `: Kommagetrennte Liste von Pfaden zu `packagejson`-Dateien (nützlich für Monorepos) # Kanal Der `channel`-Befehl ermöglicht die Verwaltung Ihrer Release-Kanäle ### add `npx @capgo/cli channel add [channelId] [appId]` Erstellt einen neuen Kanal für eine App Optionen: * `-d, --default`: Setzt den neuen Kanal als Standardkanal * `-a, --apikey `: API-Schlüssel zur Verknüpfung mit Ihrem Konto ### delete `npx @capgo/cli channel delete [channelId] [appId]` Löscht einen Kanal aus einer App Optionen: * `-a, --apikey `: API-Schlüssel zur Verknüpfung mit Ihrem Konto * `--delete-bundle`: Löscht das mit dem Kanal verbundene Bundle ### list `npx @capgo/cli channel list [appId]` Listet alle Kanäle einer App auf Optionen: * `-a, --apikey `: API-Schlüssel zur Verknüpfung mit Ihrem Konto ### currentBundle `npx @capgo/cli channel currentBundle [channel] [appId]` Ruft das aktuelle Bundle für einen bestimmten Kanal ab Optionen: * `-c, --channel `: Kanal, von dem das aktuelle Bundle abgerufen werden soll * `-a, --apikey `: API-Schlüssel zur Verknüpfung mit Ihrem Konto * `--quiet`: Gibt nur die Bundle-Version aus ### set `npx @capgo/cli channel set [channelId] [appId]` Legt die Eigenschaften eines Kanals fest Optionen: * `-a, --apikey `: API-Schlüssel zur Verknüpfung mit Ihrem Konto * `-b, --bundle `: Bundle-Versionsnummer für den Kanal festlegen * `-s, --state `: Setzt den Status des Kanals (`default` oder `normal`) * `--latest`: Verwendet die neueste Version aus `packagejson` als Bundle-Version * `--downgrade`: Erlaubt Downgrades auf Versionen unter der nativen Version * `--no-downgrade`: Deaktiviert Downgrades auf Versionen unter der nativen Version * `--upgrade`: Erlaubt Upgrades auf Versionen über der nativen Version * `--no-upgrade`: Deaktiviert Upgrades auf Versionen über der nativen Version * `--ios`: Erlaubt das Senden von Updates an iOS-Geräte * `--no-ios`: Deaktiviert das Senden von Updates an iOS-Geräte * `--android`: Erlaubt das Senden von Updates an Android-Geräte * `--no-android`: Deaktiviert das Senden von Updates an Android-Geräte * `--self-assign`: Erlaubt Geräten die Selbstzuweisung zu diesem Kanal * `--no-self-assign`: Deaktiviert die Selbstzuweisung von Geräten zu diesem Kanal * `--disable-auto-update `: Deaktiviert die Auto-Update-Strategie für diesen Kanal (Optionen: `major`, `minor`, `metadata`, `patch`, `none`) * `--dev`: Erlaubt das Senden von Updates an Entwicklungsgeräte * `--no-dev`: Deaktiviert das Senden von Updates an Entwicklungsgeräte * `--emulator`: Erlaubt das Senden von Updates an Emulator-Geräte * `--no-emulator`: Deaktiviert das Senden von Updates an Emulator-Geräte * `--package-json `: Kommagetrennte Liste von Pfaden zu `packagejson`-Dateien (nützlich für Monorepos) # Arzt `npx @capgo/cli doctor` Dieser Befehl überprüft, ob Sie die neueste Version der Capgo-Pakete verwenden Er ist auch nützlich für die Meldung von Fehlern # initialisieren `npx @capgo/cli@latest init [apikey]` Dieser Befehl führt Sie Schritt für Schritt durch: * Hinzufügen Ihrer App zu Capgo * Hinzufügen des Codes zu Ihrer App zur Validierung des Updates * Erstellen Ihrer App * Hochladen Ihrer App zu Capgo * Hilft Ihnen zu überprüfen, ob das Update funktioniert # Schlüssel Mit dem Befehl `key` können Sie Ihre App-Signierungsschlüssel verwalten ### save `npx @capgo/cli key save` Speichert einen Base64-codierten Verschlüsselungsschlüssel in der Capacitor-Konfiguration (nützlich für CI) Options: * `-f, --force`: Erzwingt die Generierung eines neuen Schlüssels * `--key`: Pfad zur Schlüsseldatei, die in der Capacitor-Konfiguration gespeichert werden soll * `--key-data`: Schlüsseldaten, die direkt in der Capacitor-Konfiguration gespeichert werden sollen ### create `npx @capgo/cli key create` Erstellt einen neuen Verschlüsselungsschlüssel Options: * `-f, --force`: Erzwingt die Generierung eines neuen Schlüssels ### delete\_old `npx @capgo/cli key delete_old` Löscht den alten Verschlüsselungsschlüssel # Login `npx @capgo/cli login [apikey]` Dieser Befehl speichert Ihren Capgo API-Schlüssel für die zukünftige Verwendung Note Sie können den gespeicherten API-Schlüssel überschreiben, indem Sie `--apikey=` zu einem beliebigen Befehl hinzufügen Optionen: * `--local`: Speichert den API-Schlüssel im lokalen Repository und fügt ihn zur `gitignore` hinzu # Häufig gestellte Fragen > Häufig gestellte Fragen zu Capgo Wenn Sie hier nicht beantwortete Fragen haben, fragen Sie bitte! Sowohl das Erstellen eines Issues als auch das Fragen auf [Discord](https://discordcom/invite/VnYRvBfgA6) funktionieren. ### Was ist “Code Push”? Code Push, auch bekannt als “Over the Air Updates” (OTA), ist ein Cloud-Service, der es Capacitor-Entwicklern ermöglicht, Updates für ihre Apps in der Produktion bereitzustellen. Capgo funktioniert derzeit auf Android und iOS und wird letztendlich überall dort funktionieren, wo Capacitor funktioniert. “Code Push” ist eine Referenz auf den Namen einer Deploy-Funktion, die von der React Native Community von [Microsoft](https://appcenterms/) und [Expo](https://expodev/) verwendet wird, die beide Capacitor nicht unterstützen. ### Was ist der Unterschied zwischen einem Bundle und einem Release? Wir verwenden den Begriff “Release” für die Vorbereitung einer Binärdatei für die App Stores. Um später ein Bundle generieren zu können, muss Capgo die exakte Binärdatei kennen, die an die App Stores gesendet wurde. Wir verwenden den Begriff “Bundle” für ein Patch, das auf ein Release angewendet werden kann, um es mit neuem Code zu aktualisieren. Der Befehl `npx @capgo/cli app update` wird verwendet, um aus Ihrem neuen lokalen Code ein Bundle zu generieren, das dann an Ihre Nutzer ausgeliefert wird. ### Wie sieht die Roadmap aus? Unsere Projekt-Boards sind öffentlich und zu finden unter: [https://github.com/orgs/Cap-go/projects](https://github.com/orgs/Cap-go/projects/) Unser Team arbeitet auch öffentlich, sodass Sie jederzeit sehen können, woran wir arbeiten. Wir beantworten gerne Ihre Fragen zu unserer Roadmap oder Prioritäten über Github Issues oder [Discord](https://discordcom/invite/VnYRvBfgA6). ### Kann ich Capgo mit meinem Team nutzen? Ja! Alle Pläne unterstützen unbegrenzte Entwickler. Wir beschränken nur App-Metriken (MAU, Speicher und Bandbreite) für jede Organisation. Weitere Informationen finden Sie unter [Teams](https://capgo.app/pricing/). ### Speichert Capgo meinen Quellcode? Nein. Capgo-Server sehen niemals Ihren Quellcode. Wenn Sie `npx @capgo/cli app update` ausführen, lädt das `npx @capgo/cli`-Tool nur den kompilierten Code hoch, den Sie auch an die App Stores senden. Wenn Sie zusätzliche Sicherheit wünschen, können Sie Ende-zu-Ende-Verschlüsselung verwenden, um Ihr Bundle vor dem Upload auf Capgo-Server zu verschlüsseln. Siehe auch unsere Datenschutzrichtlinie: [https://capgo.app/privacy](https://capgo.app/privacy/) ### Kann ich Capgo von meinem CI-System aus nutzen? Ja. Capgo ist für die Verwendung in CI-Systemen gedacht. Wir haben eine Anleitung für [Android und Github Actions](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) und [IOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) sowie für [Gitlab](https://capgo.app/blog/setup-ci-and-cd-gitlab/) veröffentlicht, andere CI-Systeme sollten ähnlich sein. Zögern Sie nicht, sich bei Problemen über GitHub Issues oder Discord zu melden. ### Wie verhält sich das zu Firebase Remote Config oder Launch Darkly? Code Push ermöglicht das Hinzufügen neuen Codes/Ersetzen von Code auf dem Gerät. Firebase Remote Config und Launch Darkly sind beides Konfigurationssysteme. Sie ermöglichen es Ihnen, die Konfiguration Ihrer App zu ändern, ohne eine neue Version ausliefern zu müssen. Sie sind nicht dafür gedacht, Code zu ersetzen. ### Wie groß ist der Dependency-Footprint? Ich habe es kürzlich nicht gemessen, aber ich erwarte, dass die Code-Push-Bibliothek weniger als ein Megabyte zu Capacitor-Apps hinzufügt. Wir kennen Möglichkeiten, dies kleiner zu machen, wenn es Priorität wird. Wenn die Größe ein Blocker für Sie ist, lassen Sie es uns wissen! ### Funktioniert Code Push mit großen Anwendungen? Ja. Es gibt keine Begrenzung für die Größe der Anwendung, die mit Code Push aktualisiert werden kann. Wie [unten](https://capgo.app/docs/faq/#what-types-of-changes-does-capgo-code-push-support) erwähnt, kann Capgo jeden JS-Code in Ihrer Anwendung ändern, unabhängig von der Größe. Zu beachten: Eine größere Größe erschwert es Benutzern, Updates herunterzuladen. Wir empfehlen, Ihre App so klein wie möglich zu halten. ### Wofür kann ich Capgo Code Push verwenden? Wir haben verschiedene Anwendungsfälle gesehen, darunter: * Notfall-Fixes für Produktions-Apps * Auslieferung von Fehlerbehebungen an Benutzer älterer Versionen Ihrer App * Kontinuierliche Auslieferung (z.B. stündlich) Beachten Sie, dass die meisten App Stores das Ausliefern von Code verbieten, der das Verhalten der App wesentlich ändert. Weitere Informationen finden Sie [unten](https://capgo.app/docs/faq/#how-does-this-relate-to-the-appplay-store-review-process-or-policies). ### Was zählt als “MAU” für Capgo? Ein MAU ist ein “Monthly Active User”. Wir zählen einen MAU als jedes Gerät, das in den letzten 30 Tagen unsere Server kontaktiert hat. Wir zählen keine Geräte, die unsere Server in den letzten 30 Tagen nicht kontaktiert haben. Jedes Mal, wenn ein Gerät Ihre App neu installiert, wird ein neuer MAU gezählt, dies geschieht aufgrund von Apple Store-Einschränkungen bezüglich der Privatsphäre. Wir können dasselbe Gerät nicht verfolgen, wenn der Benutzer die App neu installiert. Während der Entwicklung wird bei jeder Neuinstallation der App ein neuer MAU gezählt. Dasselbe gilt für Testflight-Downloads oder Kanalwechsel in Android. Das Aktualisieren der App erstellt keine neue Geräte-ID. > Wir empfehlen nach dem ersten Setup, Entwicklungsgeräte und Emulatoren zu deaktivieren, um die Anzahl doppelter Geräte zu reduzieren. ### Wofür können wir Capgo Code Push nicht verwenden? Wie oben erwähnt, sollte Capgo nicht verwendet werden, um gegen App Store-Richtlinien zu verstoßen. Weitere Informationen finden Sie [unten](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines). Außerdem unterstützt Capgo keine Änderungen am nativen Code (z.B. Java/Kotlin auf Android oder Objective-C/Swift auf iOS). Das Tool warnt Sie während eines Aktualisierungsversuchs, wenn Sie nativen Code geändert haben. ### Reicht Capgo die Apps für mich bei den Stores ein? Capgo unterstützt derzeit nicht das Einreichen bei den App Stores in Ihrem Namen. Wir planen, dies in Zukunft hinzuzufügen, aber vorerst müssen Sie weiterhin Ihre bestehenden Prozesse für die Einreichung bei den App Stores verwenden. Sie können unseren [CI-Leitfaden für Android](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) und [CI-Leitfaden für iOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) verwenden, um diesen Prozess zu automatisieren. ### Was speichert Capgo auf der Festplatte und wo? Der Capgo-Updater (der in Ihrer Anwendung enthalten ist, wenn Sie Ihre App erstellen) speichert das zuletzt heruntergeladene Bundle im einzigen Verzeichnis, das Capacitor zum Laden von Code erlaubt. Auf Android befindet sich dies in `/data/user/0/comexampleapp/code_cache/capgo_updater`, wobei der Basispfad vom Android-System bereitgestellt wird und sich zur Laufzeit dynamisch ändern kann. Auf iOS-Geräten werden Daten unter `Library/Application Support/capgo` gespeichert. Die Capgo-Kommandozeilentools (z.B.`npx @capgo/cli app update`) werden auf der Festplatte in npm-Caches installiert, Ihre Anmeldedaten werden in Ihrem Home-Verzeichnis in `~/capgo` gespeichert ### Wie verhält sich das zum Capacitor Hot Reload? Capacitor Hot Reload ist ein Feature ausschließlich für die Entwicklungszeit. Code Push ist für die Produktion. Hot Reload ist eine Funktion von Capacitor, die es ermöglicht, Code während der Entwicklung auf dem Gerät zu ändern. Dies erfordert das Erstellen der Capacitor-App mit einem Proxy zur Verbindung mit Ihrem lokalen Rechner. Code Push ist eine Funktion, die es ermöglicht, Code auf dem Gerät in der Produktion zu ändern. Wir verwenden verschiedene Techniken, um dies je nach Plattform zu ermöglichen. ### Welche Arten von Änderungen unterstützt Capgo Code Push? Capgo kann jeden JS-Code in Ihrer Anwendung ändern. Dies umfasst App-Code und generierten Code. Sie können auch Abhängigkeiten in `package.json` aktualisieren, solange diese keine nativen Code-Änderungen erfordern. Wir haben nicht vor, Änderungen am nativen Code zu unterstützen (z.B. Java/Kotlin auf Android oder Objective-C/Swift auf iOS), und das Tool wird Sie warnen, wenn es erkennt, dass Sie nativen Code geändert haben, da dieser nicht im Bundle enthalten sein wird. ### Unterstützt dies Web? Code Push wird für Web nicht benötigt, da Web bereits so funktioniert. Wenn ein Benutzer eine Web-App öffnet, lädt sie bei Bedarf die neueste Version vom Server herunter. Wenn Sie einen Anwendungsfall für Code Push mit Web haben, würden wir das gerne wissen! ### Wird dies auf iOS, Android, Mac, Windows, Linux usw. funktionieren? Ja. Bisher haben wir uns auf die Android- und iOS-Unterstützung konzentriert, aber Code Push wird letztendlich überall funktionieren, wo Capacitor funktioniert. Wir stellen sicher, dass wir zuerst die gesamte Infrastruktur aufbauen, die benötigt wird, um Code Push zuverlässig und sicher bereitzustellen, bevor wir auf weitere Plattformen expandieren. ### Welche Betriebssystemversionen unterstützt Capgo? Capgo unterstützt die gleichen Android-Versionen, die auch Capacitor unterstützt. Capacitor unterstützt derzeit Android API Level 22+ und iOS 13.0+: [https://capacitorjs.com/docs/main/reference/support-policy](https://capacitorjs.com/docs/main/reference/support-policy/) ### Welche Versionen von Capacitor unterstützt Capgo? Capgo unterstützt derzeit nur aktuelle stabile Versionen von Capacitor. Wir könnten auch ältere Versionen von Capacitor unterstützen, haben aber noch nicht die nötige Infrastruktur aufgebaut, um diese über die Zeit zu pflegen. Wir beabsichtigen, in Zukunft mehr Versionen von Capacitor zu unterstützen, einschließlich jeder Version für unsere Enterprise-Kunden [https://github.com/Cap-go/capgo/issues/1100](https://github.com/Cap-go/capgo/issues/1100/) Capgo verfolgt die stabilen Versionen und aktualisiert in der Regel innerhalb weniger Stunden nach einer stabilen Veröffentlichung. Unser System für diese Aktualisierungen ist automatisiert und benötigt nur wenige Minuten. Danach führen wir einen zusätzlichen manuellen Verifizierungsschritt durch, bevor wir auf unsere Server veröffentlichen. ### Wie verhält sich dies zum App/Play Store Überprüfungsprozess oder deren Richtlinien? Entwickler sind an ihre Vereinbarungen mit Store-Anbietern gebunden, wenn sie diese Stores nutzen. Code Push ist so konzipiert, dass Entwickler ihre Apps aktualisieren und dabei die Store-Richtlinien auf iOS und Android einhalten können. Ähnlich wie bei den verschiedenen kommerziellen Produkten, die für React Native verfügbar sind (z.B. [Microsoft](https://appcenter.ms/), [Expo](https://expo.dev/)) Microsoft veröffentlicht auch einen Leitfaden darüber, wie ihre Lösung die App Store-Richtlinien erfüllt: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) Code Push ist eine weit verbreitete Technik in den App Stores. Alle großen Apps, die ich kenne, verwenden Code Push. Die wichtigste Richtlinie ist, das Verhalten der App nicht wesentlich zu ändern. Weitere Informationen finden Sie [unten](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines). ### Erfüllt Capgo die Play Store-Richtlinien? Ja. Der Play Store bietet zwei Einschränkungen in Bezug auf Update-Tools: 1. Updates müssen einen Interpreter oder eine virtuelle Maschine verwenden (Capgo verwendet die Dart Virtual Machine) [https://support.google.com/googleplay/android-developer/answer/9888379?hl=en](https://support.google.com/googleplay/android-developer/answer/9888379/?hl=en) ```plaintext Eine über Google Play verteilte App darf sich nicht selbst modifizieren, ersetzen oder aktualisieren
mit anderen Methoden als dem Update-Mechanismus von Google Play. Ebenso darf eine App
keinen ausführbaren Code (wie dex-, JAR-, .so-Dateien) von einer
anderen Quelle als Google Play herunterladen. *Diese Einschränkung gilt nicht für Code,
der in einer virtuellen Maschine oder einem Interpreter läuft*, wo entweder
indirekten Zugriff auf Android-APIs bietet (wie JavaScript in einer WebView oder
Browser)

Apps oder Drittanbieter-Code, wie SDKs, mit interpretierten Sprachen (JavaScript,
Python, Lua, etc.), die zur Laufzeit geladen werden (zum Beispiel nicht mit der
App gebündelt), dürfen keine potenziellen Verstöße gegen Google Play-Richtlinien ermöglichen
``` 2. Änderungen an der App dürfen nicht täuschend sein (z.B. Ändern des Zwecks der App durch ein Update) [https://support.google.com/googleplay/android-developer/answer/9888077](https://support.google.com/googleplay/android-developer/answer/9888077/) Bitte seien Sie transparent gegenüber Ihren Benutzern bezüglich dessen, was Sie mit Ihrer Anwendung bereitstellen, und verletzen Sie nicht ihre Erwartungen durch wesentliche Verhaltensänderungen durch die Verwendung von Capgo. Capgo ist so konzipiert, dass es mit den Play Store-Richtlinien kompatibel ist. Allerdings ist Capgo ein Werkzeug und kann wie jedes Werkzeug missbraucht werden. Die absichtliche missbräuchliche Verwendung von Capgo zur Verletzung der Play Store-Richtlinien verstößt gegen die Capgo [Nutzungsbedingungen](https://capgo.app/tos/) und kann zur Kündigung Ihres Kontos führen. Schließlich werden Code Push-Dienste in der Branche weit verbreitet eingesetzt (alle großen Apps, die ich kenne, verwenden sie) und es gibt mehrere andere öffentlich verfügbare Code Push-Dienste (z.B. expo.dev & appcenter.ms). Dies ist ein gut ausgetretener Pfad. Microsoft veröffentlicht auch einen Leitfaden darüber, wie ihre React Native “codepush”-Bibliothek die App Store-Richtlinien erfüllt: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### Erfüllt Capgo die App Store-Richtlinien? Ja. Ähnlich wie der Play Store bietet der App Store sowohl technische als auch Richtlinien-Einschränkungen. ```plaintext 3.2.2
interpretierter Code kann in eine Anwendung heruntergeladen werden, jedoch nur solange
dieser Code:
(a) den primären Zweck der Anwendung nicht durch Bereitstellung von
Funktionen oder Funktionalität ändert, die nicht mit dem beabsichtigten und
beworbenen Zweck der Anwendung, wie sie im App Store eingereicht wurde, übereinstimmen,
(b) keinen Store oder Storefront für anderen Code oder Anwendungen erstellt, und
(c) keine Signierung, Sandbox oder andere Sicherheitsfunktionen des Betriebssystems umgeht
Capgo verwendet einen benutzerdefinierten Dart-Interpreter, um die Interpreter-Only-Beschränkung für Updates auf iOS einzuhalten. Solange Ihre Anwendung kein täuschendes Verhalten durch Updates zeigt (z.B. Änderung des App-Zwecks durch Update), ist das Aktualisieren über Capgo (oder eine andere Code-Push-Lösung) gängige Branchenpraxis und entspricht den App Store-Richtlinien. Der absichtliche Missbrauch von Capgo zur Verletzung der App Store-Richtlinien verstößt gegen die [Nutzungsbedingungen](https://capgo.app/tos/) von Capgo und kann zur Kündigung Ihres Kontos führen. Microsoft veröffentlicht auch einen Leitfaden, wie ihre React Native "CodePush"-Bibliothek die App Store-Richtlinien einhält: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### Kann ich Capgo in meinem Land nutzen?[](https://capgo.app/docs/faq/#can-i-use-capgo-in-my-country "Direct link to Can I use Capgo in my country?") Wir haben den Zugriff auf Capgo aus keinem Land eingeschränkt. Wir erkennen an, dass einige Länder Einschränkungen haben, welche URLs innerhalb des Landes aufgerufen werden können. Capgo verwendet derzeit Cloudflare Cloud für das Hosting, einschließlich R2 Storage und Cloudflare Workers. Folgende URLs werden von Capgo verwendet: - [https://apicapgo.app](https://apicapgo.app/) -- verwendet von den `npx @capgo/cli` Command Line Tools für die Interaktion mit den Capgo-Servern sowie vom Capgo-Updater auf den Geräten der Benutzer zur Überprüfung von Updates - [https://*r2cloudflarestoragecom](https://*r2cloudflarestoragecom/) -- verwendet vom `npx @capgo/cli` Command Line Tool zum Hoch- und Herunterladen von Bundles Wenn all diese URLs aus Ihrem Land erreichbar sind, sollte Capgo funktionieren. Wenn Ihre Region den Zugriff auf eine dieser URLs blockieren muss, lassen Sie es uns wissen und wir können mit Ihnen an einer Lösung arbeiten. Proxy-Server sind eine Option. ### Kann ich Capgo selbst hosten?[](https://capgo.app/docs/faq/#can-i-self-host-capgo "Direct link to Can I self-host Capgo?") Ja, Sie können Capgo selbst hosten. Die Anleitung ist noch nicht geschrieben, aber der Code ist Open Source und verfügbar unter [https://github.com/cap-go/capgo](https://github.com/cap-go/capgo/) ### Benötigt Code Push Internet zum Funktionieren?[](https://capgo.app/docs/faq/#does-code-push-require-the-internet-to-work "Direct link to Does code push require the internet to work?") Ja. Man könnte sich vorstellen, einen Server zu betreiben, um die Updates getrennt vom allgemeinen Internet zu verteilen, aber irgendeine Form von Netzwerkverbindung ist erforderlich, um Updates auf die Geräte zu übertragen. ### Wie wird Capgo von fehlender Netzwerkverbindung beeinflusst?[](https://capgo.app/docs/faq/#how-is-capgo-affected-by-lack-of-network-connectivity "Direct link to How is Capgo affected by lack of network connectivity?") Der Capgo-Updater (der in Ihrer Anwendung enthalten ist, wenn Sie Ihre App mit Capgo erstellen) ist darauf ausgelegt, resistent gegen Netzwerkverbindungsprobleme zu sein. Im Standard-Update-Verhalten benachrichtigt die Anwendung beim Start den Capgo-Updater, der einen separaten Thread startet, um eine Netzwerkanfrage an die Capgo-Server zu stellen und nach einem Update zu fragen. Wir verwenden absichtlich einen separaten Thread, um andere Aktivitäten der Anwendung nicht zu blockieren. Wenn die Netzwerkanfrage fehlschlägt oder eine Zeitüberschreitung auftritt, wird der Updater beim nächsten Start der Anwendung erneut prüfen. Capgo Command Line Tools (z.B. `npx @capgo/cli app update`) benötigen eine Netzwerkverbindung zum Funktionieren. Wenn Sie Capgo zur Verteilung Ihrer App verwenden, sollten Sie sicherstellen, dass Ihr CI-System eine Netzwerkverbindung hat. ### Was passiert, wenn ein Benutzer lange Zeit nicht aktualisiert und ein Update verpasst?[](https://capgo.app/docs/faq/#what-happens-if-a-user-doesnt-update-for-a-long-time-and-misses-an-update "Direct link to What happens if a user doesn't update for a long time and misses an update?") Unsere Implementierung sendet immer ein speziell auf das anfragende Gerät zugeschnittenes Update, das den Anfrager immer auf die neueste verfügbare Version aktualisiert. Wenn ein Benutzer also eine Weile nicht aktualisiert, wird er Zwischenupdates "verpassen". Der Update-Server könnte geändert werden, um je nach Bedarf Ihrer Anwendung entweder die nächste inkrementelle Version oder die neueste Version zu unterstützen. Bitte lassen Sie uns wissen, wenn alternative Update-Verhaltensweisen für Sie wichtig sind. ### Wie verhält sich Capgo zu Capacitor?[](https://capgo.app/docs/faq/#how-does-capgo-relate-to-capacitor "Direct link to How does Capgo relate to Capacitor?") Capgo ist ein Plugin für Capacitor, das Code Push hinzufügt. Capgo ist kein Ersatz für Capacitor. Sie können weiterhin die Capacitor-Tools verwenden, die Sie bereits kennen und schätzen. Wir verfolgen die neueste stabile Version von Capacitor und aktualisieren unser Code Push Plugin entsprechend. ### Wann finden Updates statt?[](https://capgo.app/docs/faq/#when-do-updates-happen "Direct link to When do updates happen?") Standardmäßig prüft der Capgo-Updater beim App-Start auf Updates. Er läuft in einem Hintergrund-Thread und blockiert nicht den UI-Thread. Updates werden installiert, während der Benutzer die App verwendet, und beim nächsten Neustart der App angewendet. Es ist auch möglich, den Capgo-Updater manuell mit [package:capgo_code_push](https://pubdev/packages/capgo_code_push/) auszuführen, wodurch Updates jederzeit ausgelöst werden können, auch über Push-Benachrichtigungen. Der Capgo-Updater ist so konzipiert, dass die App normal weiterläuft, wenn das Netzwerk nicht verfügbar ist oder der Server nicht erreichbar ist. Sollten Sie sich jemals entscheiden, ein Update von unseren Servern zu löschen, werden alle Ihre Clients normal weiterlaufen. Wir haben die Möglichkeit hinzugefügt, Patches zurückzurollen. Am einfachsten ist es, einfach ein vorheriges Bundle an Ihren Kanal anzuhängen, um dies rückgängig zu machen. ### Muss ich meine app_id geheim halten?[](https://capgo.app/docs/faq/#do-i-need-to-keep-my-app_id-secret "Direct link to Do I need to keep my app_id secret?") Nein. Die `app_id` ist in Ihrer App enthalten und kann öffentlich sein. Sie können sie in die Versionskontrolle einchecken (auch öffentlich) und müssen sich keine Sorgen machen, dass jemand anderes darauf zugreift. Jemand mit Ihrer `app_id` kann die neueste Version Ihrer App von Capgo-Servern abrufen, kann aber keine Updates für Ihre App pushen oder auf andere Aspekte Ihres Capgo-Kontos zugreifen. ### Welche Informationen werden an Capgo-Server gesendet?[](https://capgo.app/docs/faq/#what-information-is-sent-to-capgo-servers "Direct link to What information is sent to Capgo servers?") Obwohl Capgo sich mit dem Netzwerk verbindet, werden keine personenbezogenen Daten gesendet. Das Einbinden von Capgo sollte Ihre Erklärungen für den Play Store oder App Store nicht beeinflussen. Anfragen, die von der App an Capgo-Server gesendet werden, enthalten: - app_id (angegeben in `capacitorconfigjson`) - channel (optional in `capacitorconfigjson`) - release_version (versionName aus AndroidManifestxml oder CFBundleShortVersionString aus Infoplist oder `capacitorconfigjson` wenn in [`CapacitorUpdaterversion`](/docs/plugin/settings/#version) gesetzt) - version_number (generiert als Teil von `npx @capgo/cli app update`) - os_version (z.B. '1121') - platform (z.B. 'android', notwendig um den richtigen Patch zu senden) Das wars. Der Code dafür ist in `updater/library/src/networkrs` - device_id (beim ersten Start auf dem Gerät generiert, wird verwendet um Geräte-spezifische Installationen zu deduplizieren und ermöglicht uns die Abrechnung basierend auf installierten Benutzern)monatlich aktive Nutzer), anstatt der Gesamtanzahl der Patches oder Patch-Installationen) - custom_id (optional, zur Laufzeit vom Entwickler festgelegt, um ein Gerät mit einem Benutzer in Ihrem System zu verknüpfen) ### Welche Plattformen unterstützt Capgo?[](https://capgo.app/docs/faq/#what-platforms-does-capgo-support "Direct link to What platforms does Capgo support?") Derzeit unterstützt Capgo iOS und Android. Beide sind produktionsreif. Die Nutzung von Capgo für iOS oder Android kann unabhängig voneinander entschieden werden. Sie können in Ihrem Kanal festlegen, ob Sie an Android oder eine in den App Store gebaute IPA ausliefern möchten oder umgekehrt. Capgo kann (relativ einfach) für Desktop- oder Embedded-Ziele erweitert werden. Wenn diese für Sie wichtig sind, lassen Sie es uns bitte wissen. ### Wie interagiert Capgo mit Play Testing Tracks oder Apple TestFlight?[](https://capgo.app/docs/faq/#how-does-capgo-interact-with-play-testing-tracks-or-apple-testflight "Direct link to How does Capgo interact with Play Testing Tracks or Apple TestFlight?") Jeder App Store hat eigene Mechanismen zur Verteilung von Apps an begrenzte Benutzergruppen (z.B. "internes Testen", "geschlossene Beta" usw.). Dies sind alles Mechanismen zur Segmentierung Ihrer Benutzer in Gruppen und zur Verteilung spezifischer App-Versionen. Leider erlauben nicht alle diese Mechanismen Drittanbietern zu erkennen, wenn Apps in einem bestimmten Test Track oder über TestFlight installiert sind. Daher haben wir keine zuverlässige Einsicht in die Zusammensetzung dieser Gruppen und können den Zugriff auf Capgo-Patches nicht zuverlässig auf Basis dieser Gruppen steuern. [https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play](https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play/) [https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i](https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i/) Wenn Sie die Verfügbarkeit von Capgo-Bundles segmentieren möchten, gibt es 4 mögliche Optionen: 1. Verwenden Sie separate Kanäle für jede Gruppe. Dies ist der einfachste Ansatz, erfordert aber die Verwaltung mehrerer Kanäle. Möglicherweise haben Sie bereits Dev-Kanäle und Prod-Kanäle mit unterschiedlicher Verfügbarkeit. Sie können also Ihre Dev-Kanäle aktualisieren, überprüfen und dann separat Ihre Prod-Kanäle aktualisieren. Wir empfehlen die Verwendung von Branches/Tags in Ihrer Versionskontrolle, um den Überblick über die Quellen der einzelnen Releases zu behalten. 2. Verfolgen Sie Ihre eigene Liste von Opt-in-Benutzern, deaktivieren Sie automatische Updates und lösen Sie Updates nur für bestimmte Benutzer über package:capgo_code_push aus. Dies funktioniert heute, erfordert aber die Verwaltung Ihrer eigenen Opt-in-Liste. 3. Capgo ermöglicht einen eigenen Opt-in-Mechanismus auf Geräteebene (ähnlich wie Test Tracks oder TestFlight, nur plattformunabhängig). Dies ermöglicht Ihrem QA-Team, sich für Bundles anzumelden, bevor sie der Öffentlichkeit zur Verfügung gestellt werden. 4. Capgo hat prozentbasierte Rollouts. Dies lässt Sie zwar nicht auswählen, an welche Geräte gesendet wird, kann aber helfen, inkrementell auszurollen und bei Problemen zurückzurollen. ## Abrechnung[](https://capgo.app/docs/faq/#billing "Direct link to Billing") ### Wie kann ich meinen Plan upgraden oder downgraden?[](https://capgo.app/docs/faq/#how-do-i-upgrade-or-downgrade-my-plan "Direct link to How do I upgrade or downgrade my plan?") Sie können Ihren Plan jederzeit in Ihrem Dashboard upgraden oder downgraden: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Wann wird meine Abrechnungsperiode zurückgesetzt?[](https://capgo.app/docs/faq/#when-does-my-billing-period-reset "Direct link to When does my billing period reset?") Abrechnungsperioden werden automatisch jeden Monat am Tag Ihrer ersten Capgo-Anmeldung zurückgesetzt. Wenn Sie sich zum Beispiel am 15. des Monats angemeldet haben, wird Ihre Abrechnungsperiode am 15. jedes Monats zurückgesetzt. ### Wie kann ich mein Abonnement kündigen?[](https://capgo.app/docs/faq/#how-do-i-cancel-my-subscription "Direct link to How do I cancel my subscription?") Sie können Ihr Abonnement jederzeit in Ihrem Dashboard kündigen: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Kann ich für ein Jahr im Voraus bezahlen?[](https://capgo.app/docs/faq/#can-i-pay-for-a-year-in-advance "Direct link to Can I pay for a year in advance?") Ja, Sie können jederzeit in Ihrem Dashboard für ein Jahr im Voraus bezahlen: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Statistiken und Analysen[](https://capgo.app/docs/faq/#stats-and-analytics "Direct link to Stats and analytics") Die Statistiken in Ihrem Dashboard werden jeden Tag um Mitternacht UTC aktualisiert. Die Statistiken basieren auf der Anzahl der [MAU](https://capgo.app/docs/faq/#what-is-the-difference-between-a-bundle-and-a-release "Direct link to What is the difference between a bundle and a release?"), die auf Ihren Geräten installiert wurden. # Wie wird die Geräte-ID generiert[](https://capgo.app/docs/faq/#how-device-id-is-generated "Direct link to How device ID is generated") Die Geräte-ID wird beim ersten Start auf dem Gerät generiert und wird verwendet, um Installationen pro Gerät zu deduplizieren und uns zu ermöglichen, basierend auf installierten Benutzern (z.B. monatlich aktive Nutzer) abzurechnen, anstatt der Gesamtanzahl der Patches oder Patch-Installationen. MAU ist eine bessere Lösung als die Anzahl der Installationen für die Preisgestaltung von Capgo, da es genauer ist und die tatsächlichen Kosten von Capgo pro Gerät widerspiegelt. Aus Datenschutzgründen können wir dasselbe Gerät nicht verfolgen, wenn der Benutzer die App neu installiert. Die Datenschutzregeln werden von Apple und Google durchgesetzt und nicht von Capgo. Geräte-IDs werden erst in Ihrer Geräteliste angezeigt, wenn sie ihren ersten Patch installiert haben. # Warum unterscheidet sich meine Geräteanzahl von meinen MAU?[](https://capgo.app/docs/faq/#why-my-device-number-is-different-than-my-mau "Direct link to Why my device number is different than my MAU?") Derzeit wird die Geräteliste nicht so häufig aktualisiert wie die MAU. Die Geräteliste wird nur aktualisiert, wenn ein Gerät ein Update installiert. Die MAU wird bei jedem App-Start aktualisiert. Dies ist eine aktuelle Einschränkung der Plattform. Unsere Analyseplattform unterstützt keine Raw-Updates, daher verwenden wir konventionelle Datenbanken für die Geräteliste. Um die Anzahl der Datenbankabfragen zu begrenzen, aktualisieren wir Zeilen nur bei App-Updates. Diese Einschränkung wird in Zukunft behoben. # Wie kann ich verschiedene Updates pro Plattform haben?[](https://capgo.app/docs/faq/#how-to-have-different-update-by-platform "Direct link to How to have different update by platform?") Sie können einen Kanal für jede Plattform erstellen und plattformspezifische Updates in jedem Kanal deaktivieren. Im iOS-Kanal Android-Updates deaktivieren und im Android-Kanal iOS-Updates deaktivieren. Dann laden Sie ein Bundle in jeden Kanal hoch, um verschiedene Updates für jede Plattform zu haben. Wenn Sie dasselbe Update für beide Plattformen benötigen, können Sie ein Bundle mit mehreren Kanälen verknüpfen. Das Bundle muss nicht dupliziert werden. ``` # Tech Support für Capgo > So erhalten Sie Hilfe für Capgo ## Support über Discord Capgo hat einen offiziellen [Discord Server](https://discordcom/invite/VnYRvBfgA6). Dort technischen Support zu erhalten ist wahrscheinlich einer der schnellsten Wege, eine Antwort zu bekommen. Hier ist eine Kurzanleitung: 1. Gehe zum `questions` Kanal ![Ask on discord](/discord-questions.webp) 2. Erstelle deinen Thread ![Create a question on discord](/discord-newquestion.webp) 3. Beschreibe dein Problem und wähle die relevanten Tags aus ![Create a post on discord](/discord-new-post.webp) 4. Teile deine sichere Konto-ID (optional) Dies ermöglicht es dem Capgo-Team, einen Blick auf dein Konto zu werfen. Das Teilen dieser ID ist sicher, da sie dafür entwickelt wurde, öffentlich geteilt zu werden. Um dies zu teilen, gehe bitte zu den [Capgo-Einstellungen](https://web.capgo.app/dashboard/settings/account/). Klicke dort bitte auf `copy account id`. ![Share your id without leaking your info](/share-secure-id.webp) Dies kopiert die sichere Konto-ID in die Zwischenablage. Bitte füge diese in deinen Discord-Beitrag ein. ## Support per E-Mail Dies ist der langsamste Weg, Support zu erhalten. Bitte nutze zuerst den Discord-Server. Wenn du uns per E-Mail kontaktieren musst, sende bitte eine E-Mail an # App hinzufügen > Fügen Sie eine App zu Ihrem Capgo-Account hinzu und installieren Sie das Plugin in Ihrer App ## Einführung in Capgo [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## Live-Updates sind 3 Schritte entfernt ### Geführtes Setup 1. Erstellen Sie Ihr Konto unter ![signup screenshot](/signup.webp "signup screenshot") 2. Verwenden Sie die Init-Befehle, um zu beginnen ```bash npx @capgo/cli@latest init [APIKEY] ``` Es werden Ihnen eine Reihe von Fragen gestellt. Beantworten Sie diese, um das automatische Setup abzuschließen Tip Wenn Sie diese Schritte befolgen, sind Sie in kürzester Zeit einsatzbereit. Falls Sie während des Prozesses weitere Unterstützung benötigen, ist unser Support-Team [hier um zu helfen](https://support.capgo.app). Viel Spaß beim Onboarding! 3. Deployment eines Live-Updates [Deploy a live update ](/docs/getting-started/deploy/)Erfahren Sie, wie Sie ein Live-Update für Ihre App bereitstellen ### Manuelles Setup Falls der Init-Befehl für Sie nicht funktioniert, können Sie eine App manuell hinzufügen 1. Verbinden Sie die CLI mit Ihrem Konto: ```bash npx @capgo/cli@latest login [APIKEY] ``` 2. Fügen Sie die App mit diesem Befehl zu Ihrem Konto hinzu: ```bash npx @capgo/cli@latest app add [APP_NAME] ``` 3. Installieren Sie das Plugin in Ihrer App: ```json { "plugins": { CapacitorUpdater: { "appId": "Your appID", "autoUpdate": true, "version": "1.0.0" } } } ``` 4. Rufen Sie die Init-Methode so früh wie möglich in Ihrer App auf: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; CapacitorUpdater.notifyAppReady(); ``` 5. Deployment eines Live-Updates [Deploy a live update ](/docs/getting-started/deploy/)Erfahren Sie, wie Sie ein Live-Update für Ihre App bereitstellen # CI/CD-Integration Die Integration von Capgo in Ihre CI/CD-Pipeline ermöglicht es Ihnen, den Prozess des Erstellens und Bereitstellens von Updates für Ihre App vollständig zu automatisieren. Durch die Nutzung der Capgo CLI und semantic-release können Sie konsistente, zuverlässige Bereitstellungen sicherstellen und schnelle Iterationen ermöglichen. ## Vorteile der CI/CD-Integration * **Automatisierung**: Keine manuellen Schritte mehr oder Raum für menschliche Fehler. Ihr gesamter Build-, Test- und Bereitstellungsprozess kann von Anfang bis Ende automatisiert werden. * **Konsistenz**: Jede Bereitstellung folgt den gleichen Schritten und gewährleistet einen vorhersehbaren und wiederholbaren Prozess. Dies ist besonders wertvoll, wenn mehrere Teammitglieder Code beisteuern. * **Schnellere Iterationen**: Mit automatisierten Bereitstellungen können Sie Updates häufiger und mit Zuversicht ausliefern. Kein Warten mehr auf manuelle QA oder Freigabegenehmigungen. ## Capgo CLI Die Capgo CLI ist der Schlüssel zur Integration von Capgo in Ihren CI/CD-Workflow. Sie bietet Befehle zum Pushen neuer Bundle-Versionen, Verwalten von Kanälen und mehr. Der wichtigste Befehl für die CI/CD-Integration ist `upload`: ```shell npx @capgo/cli@latest bundle upload --channel=Production --apikey YOUR_API_KEY ``` Dieser Befehl lädt den aktuellen Web-Build in den angegebenen Kanal hoch. Sie führen dies typischerweise als letzten Schritt in Ihrer CI/CD-Pipeline aus, nachdem Ihr Web-Build erfolgreich abgeschlossen wurde. ## Einrichtung von Capgo in Ihrer CI/CD-Pipeline Während die genauen Schritte je nach CI/CD-Tool variieren, sieht der allgemeine Prozess für die Integration von Capgo wie folgt aus: 1. **API-Schlüssel generieren**: Melden Sie sich beim Capgo-Dashboard an und erstellen Sie einen neuen API-Schlüssel. Dieser Schlüssel wird zur Authentifizierung der CLI in Ihrer CI/CD-Umgebung verwendet. Halten Sie ihn geheim und committen Sie ihn niemals in Ihr Repository! 2. **Konfigurieren Sie den `upload`-Befehl**: Fügen Sie Ihrer CI/CD-Konfiguration einen Schritt hinzu, der den `upload`-Befehl mit den entsprechenden Argumenten ausführt: upload.yml ```yaml - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secrets.CAPGO_API_KEY }} ``` \n Ersetzen Sie `Production` mit dem Kanal, in den Sie deployen möchten, und `${{ secrets.CAPGO_API_KEY }}` mit der Umgebungsvariable, die Ihren API-Schlüssel enthält. 3. **Fügen Sie den `upload`-Schritt nach Ihrem Web-Build hinzu**: Stellen Sie sicher, dass der `upload`-Schritt nach erfolgreichem Abschluss Ihres Web-Builds erfolgt. Dies stellt sicher, dass Sie immer Ihren neuesten Code bereitstellen.\n Hier ist ein Beispiel für die Konfiguration für GitHub Actions:\n upload.yml ```yaml name: Deploy to Capgo on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v4 with: node-version: 18 - run: npm ci - run: npm run build - run: npm install -g @capgo/cli - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secrets.CAPGO_API_KEY }} ``` ## Semantic-release Integration Semantic-release ist ein leistungsstarkes Tool zur Automatisierung der Versionsverwaltung und Generierung von Release Notes. Durch die Integration von semantic-release mit Capgo können Sie automatisch Ihre App-Version inkrementieren und Changelogs mit jeder Bereitstellung generieren. Hier ist eine Beispiel-`releaserc`-Konfigurationsdatei für semantic-release: ```json { "branches": [ "main", { "name": "beta", "prerelease": true } ], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", [ "@semantic-release/exec", { "publishCmd": "npx @capgo/cli@latest bundle upload --channel=${nextRelease.channel} --apikey YOUR_API_KEY --partial" } ], [ "@semantic-release/git", { "assets": ["CHANGELOG.md", "package.json"], "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" } ] ] } ``` Diese Konfiguration führt Folgendes aus: 1. Analysiert Commit-Nachrichten, um die nächste Versionsnummer nach der Conventional Commits-Spezifikation zu bestimmen 2. Generiert Release Notes basierend auf den Commits seit dem letzten Release 3. Aktualisiert die `CHANGELOG.md`-Datei mit den neuen Release Notes 4. Führt den Capgo CLI `upload`-Befehl aus und übergibt die neue Versionsnummer mit dem `--partial`-Flag für differentielle Updates 5. Committet die aktualisierte `CHANGELOG.md`, `package.json` und alle anderen geänderten Dateien zurück ins Repository Um semantic-release mit Capgo zu verwenden, fügen Sie einfach einen Schritt zu Ihrer CI/CD-Konfiguration hinzu, der `npx semantic-release` ausführt. Stellen Sie sicher, dass dieser Schritt nach Ihrem Web-Build und vor dem Capgo `upload`-Schritt erfolgt. ## Fehlerbehebung Wenn Sie Probleme mit Ihrer Capgo CI/CD-Integration haben, hier einige Dinge, die Sie überprüfen sollten: * **API-Schlüssel**: Stellen Sie sicher, dass Ihr API-Schlüssel gültig ist und die erforderlichen Berechtigungen hat. Wenn Sie eine Umgebungsvariable verwenden, überprüfen Sie, ob sie korrekt gesetzt ist. * **CLI-Version**: Stellen Sie sicher, dass Sie die neueste Version der Capgo CLI verwenden. Ältere Versionen können Kompatibilitätsprobleme haben oder bestimmte Funktionen fehlen. * **Build-Artefakte**: Bestätigen Sie, dass Ihr Web-Build die erwarteten Ausgabedateien generiert. Die Capgo CLI benötigt einen gültigen Web-Build, um ein Bundle zu erstellen. * **Netzwerkverbindung**: Überprüfen Sie, ob Ihre CI/CD-Umgebung Netzwerkzugriff auf die Capgo-Server hat. Firewall- oder Proxy-Probleme können manchmal den `upload`-Befehl stören. Wenn Sie immer noch Probleme haben, wenden Sie sich an den Capgo-Support. Sie können bei der Fehlerbehebung für Ihre spezifische Einrichtung helfen. ## Fazit Die Integration von Capgo in Ihre CI/CD-Pipeline und die Nutzung von semantic-release für die Versionsverwaltung kann Ihren Entwicklungsworkflow erheblich vereinfachen. Durch die Automatisierung Ihrer Bereitstellungen und Versionierung können Sie Updates schneller und mit mehr Zuversicht ausliefern. Die Capgo CLI und semantic-release bieten eine leistungsstarke Kombination für vollständig automatisierte End-to-End-Releases. Mit etwas Konfiguration können Sie einen robusten und zuverlässigen Bereitstellungsprozess haben, der es Ihnen ermöglicht, sich auf das Entwickeln großartiger Funktionen zu konzentrieren, anstatt sich über manuelle Release-Schritte Gedanken zu machen. Weitere Details zu den Capgo CLI-Befehlen und Optionen finden Sie in der [CLI-Referenz](/docs/cli/overview). Und für einen tieferen Einblick in die semantic-release-Konfiguration, siehe die [semantic-release Dokumentation](https://github.com/semantic-release/semantic-release). Viel Spaß beim Bereitstellen! # Live Update bereitstellen Nutzen Sie die Live-Updates-Funktion von Capgo, um die Benutzeroberfläche und Geschäftslogik Ihrer App aus der Ferne in Echtzeit zu aktualisieren. Übertragen Sie JS-Bundle-Updates direkt an Ihre Nutzer, ohne den App Store zu durchlaufen, um sofort Fehler zu beheben und neue Funktionen bereitzustellen. Diese Anleitung setzt voraus, dass Sie den [Capgo Quickstart](/docs/getting-started/quickstart) abgeschlossen haben und bereits: 1. Das `@capgo/capacitor-updater` SDK in Ihrer Capacitor-App installiert haben 2. Ihre App-ID und den Update-Kanal in `capacitor.config.ts` konfiguriert haben 3. Die `CapacitorUpdater.notifyAppReady()` Methode in Ihren Code eingefügt haben Wenn Sie diese Schritte noch nicht ausgeführt haben, gehen Sie bitte zurück und schließen Sie zuerst den Quickstart ab [App hinzufügen ](/docs/getting-started/add-an-app/)Fügen Sie eine App zu Ihrem Capgo-Konto hinzu und installieren Sie das Plugin in Ihrer App ## Bundle hochladen Mit dem installierten und konfigurierten Capgo SDK können Sie Ihr erstes Live-Update-Bundle hochladen: 1. Web-Assets erstellen: ```shell npm run build ``` 2. Bundle zu Capgo hochladen: * Console ```shell npx @capgo/cli@latest bundle upload --channel=Production ``` * Github Actions github/workflows/build\_and\_deploy.yml ```yml name: Build source code and send to Capgo concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true on: push: branches: - main jobs: deploy_to_capgo: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v5 - uses: actions/setup-node@v4 with: node-version: 18 - name: Install dependencies run: npm install - name: Build run: npm run build - name: Deploy to Capgo run: bunx @capgo/cli@latest bundle upload -a ${{ secrets.CAPGO_TOKEN }} --channel ${{ env.CHANNEL }} env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} ``` * Gitlab gitlab-ci.yml ```yml stages: - build build: stage: build image: node:18 cache: - key: files: - package-lock.json paths: - node_modules/ script: - npm install - npm run build - npx @capgo/cli@latest bundle upload -a $CAPGO_TOKEN --channel $CAPGO_CHANNEL artifacts: paths: - node_modules/ - dist/ only: - master ``` Dies lädt eine neue Bundle-Version in den im Befehl angegebenen Kanal hoch ### Fehlerbehebung beim Hochladen Wenn das Hochladen fehlschlägt, überprüfen Sie: * Ihre App-ID in `capacitor.config.ts` stimmt mit Ihrer App im Capgo-Dashboard überein * Sie führen den Upload-Befehl vom Root-Verzeichnis Ihres Capacitor-Projekts aus * Ihre Web-Assets sind erstellt und aktuell Wenn Sie immer noch Probleme haben, gehen Sie zum Abschnitt [Fehlerbehebung](/docs/getting-started/troubleshooting/) ## Update auf einem Gerät empfangen Sobald Ihr Bundle hochgeladen ist, können Sie das Live-Update auf einem Gerät testen: 1. Synchronisieren Sie Ihre App mit dem Gerät: ```shell npx cap sync ios ``` 2. Öffnen Sie ein weiteres Terminal und führen Sie den folgenden Befehl aus, um den Update-Status zu überprüfen: ```shell npx @capgo/cli@latest app debug ``` 3. Führen Sie Ihre App lokal aus: ```shell npx cap run ios ``` Oder öffnen Sie das iOS/Android-Projekt in Xcode/Android Studio und führen Sie einen nativen Start durch 4. Lassen Sie die App etwa 30 Sekunden geöffnet, damit das Update im Hintergrund heruntergeladen werden kann 5. Die Logs brauchen einige Sekunden, um sich zu aktualisieren und den Update-Status anzuzeigen 6. Schließen und öffnen Sie die App erneut. Sie sollten Ihr Live-Update angewendet sehen! Schauen Sie im [Capgo Quickstart](/docs/getting-started/quickstart#receiving-a-live-update-on-a-device) nach, um weitere Details zum Testen von Live-Updates zu erhalten ## Nächste Schritte Herzlichen Glückwunsch zum Bereitstellen Ihres ersten Live-Updates mit Capgo! 🎉 Um mehr zu erfahren, lesen Sie den Rest der [Capgo Live-Updates-Dokumentation](/docs/live-updates). Einige wichtige Themen, die Sie als Nächstes überprüfen sollten: * [Updates mit Kanälen zielgerichtet einsetzen](/docs/live-updates/channels) * [Update-Verhalten anpassen](/docs/live-updates/update-behavior) * [Live-Update-Rollbacks](/docs/live-updates/rollbacks) # Überblick Das Quickstart-Tutorial führt Sie durch die wichtigsten Konzepte von Capgo! Zu den behandelten Konzepten gehören: 1. Hinzufügen einer App zu Ihrem Capgo-Konto 2. Integration von Capgo in Ihre CI/CD 3. Auslösen des Bundle-Uploads auf Capgo durch Pushen von Commits 4. Konfiguration und Anpassung der Capgo Bundle-Veröffentlichung 5. Einrichten Ihrer App für Live-Updates über Capgo 6. Bereitstellung von Live-Updates für Ihre App von Capgo aus Folgen Sie einfach der Anleitung Schritt für Schritt oder navigieren Sie direkt zur Dokumentation der Komponente, die Sie interessiert [ Tutorial starten](/docs/getting-started/add-an-app/) [Folgen Sie dem Quickstart-Tutorial und nutzen Sie Capgo in kürzester Zeit!](/docs/getting-started/add-an-app/) [ Einfach zu integrieren](/docs/getting-started/deploy/) [Integrieren Sie Capgo in Ihre CI/CD und lösen Sie Bundle-Uploads auf Capgo durch Pushen von Commits aus](/docs/getting-started/deploy/) [ Live Update Dokumentation](/docs/live-updates/) [Aktualisieren Sie Ihre App aus der Ferne in Echtzeit ohne App Store Verzögerungen](/docs/live-updates/) [ Fehlerbehebung](/docs/getting-started/troubleshooting) [Häufige Probleme und deren Lösungen](/docs/getting-started/troubleshooting) Tip Die Over-the-Air (OTA) Update-Funktion gilt nur für Änderungen an HTML-, CSS- und JavaScript-Dateien Wenn Sie Änderungen am nativen Code vornehmen, wie z.B. Updates von Capacitor-Plugins, müssen Sie die Anwendung erneut zur Genehmigung im App Store einreichen ## Discord Community beitreten [Treten Sie dem Capacitor-updater Discord Server bei!](https://discordcom/invite/VnYRvBfgA6) ## Wartung | Plugin-Version | Capacitor-Kompatibilität | Gewartet | | -------------- | ------------------------ | ------------------------------------------------------------------------- | | v6\*\* | v6\*\* | ✅ | | v5\*\* | v5\*\* | Nur kritische Fehler | | v4\*\* | v4\*\* | ⚠️ Veraltet | | v3\*\* | v3\*\* | ⚠️ Veraltet | | > 7 | v4\*\* | ⚠️ Veraltet, unsere CI ist durchgedreht und hat zu viele Versionen erhöht | ## Einhaltung der Store-Richtlinien Der Android Google Play und der iOS App Store haben entsprechende Richtlinien mit Regeln, die Sie kennen sollten, bevor Sie die Capacitor-updater-Lösung in Ihre Anwendung integrieren ### Google Play Der dritte Absatz zum Thema [Geräte- und Netzwerkmissbrauch](https://supportgooglecom/googleplay/android-developer/answer/9888379/?hl=en) beschreibt, dass die Aktualisierung von Quellcode durch andere Methoden als den Update-Mechanismus von Google Play eingeschränkt ist. Diese Einschränkung gilt jedoch nicht für die Aktualisierung von JavaScript-Bundles > Diese Einschränkung gilt nicht für Code, der in einer virtuellen Maschine ausgeführt wird und eingeschränkten Zugriff auf Android-APIs hat (wie JavaScript in einer Webview oder einem Browser) Das erlaubt Capacitor-updater vollständig, da es nur die JS-Bundles aktualisiert und keinen nativen Code ändert ### App Store Absatz **332** des [Apple Developer Program License Agreement](https://developer.apple.com/programs/ios/information/) erlaubt seit 2015 vollständig Over-the-Air-Updates von JavaScript und Assets - und in der neuesten Version (20170605) [hier herunterladbar](https://developer.apple.com/terms/) ist diese Regelung sogar noch umfassender: > Interpretierter Code kann in eine Anwendung heruntergeladen werden, solange dieser Code: (a) den primären Zweck der Anwendung nicht durch Funktionen oder Funktionalitäten ändert, die mit dem beabsichtigten und beworbenen Zweck der Anwendung, wie sie im App Store eingereicht wurde, nicht übereinstimmen, (b) keinen Store oder Storefront für anderen Code oder Anwendungen erstellt, und (c) keine Signierung, Sandbox oder andere Sicherheitsfunktionen des Betriebssystems umgeht Capacitor-updater ermöglicht es Ihnen, diese Regeln vollständig einzuhalten, solange das Update, das Sie pushen, nicht wesentlich von der ursprünglichen, vom App Store genehmigten Absicht Ihres Produkts abweicht Um weiterhin die Apple-Richtlinien einzuhalten, empfehlen wir, dass im App Store vertriebene Apps das Szenario ‘Erzwungenes Update’ nicht aktivieren, da in den [App Store Review Guidelines](https://developer.apple.com/app-store/review/guidelines/) steht: > Apps dürfen Benutzer nicht zwingen, die App zu bewerten, die App zu überprüfen, andere Apps herunterzuladen oder ähnliche Aktionen durchzuführen, um auf Funktionen, Inhalte oder die Nutzung der App zugreifen zu können Dies ist kein Problem für das Standardverhalten des Hintergrund-Updates, da es den Benutzer nicht zwingt, die neue Version anzuwenden, bis er die App das nächste Mal schließt, aber Sie sollten sich dieser Rolle bewusst sein, wenn Sie sich entscheiden, sie anzuzeigen ## Open Source Das Plugin steht unter der LGPL-3.0 Lizenz und das Backend unter der AGPL-3.0 Lizenz > 💡 LGPL-3.0 bedeutet, wenn jemand den Code des Plugins modifiziert, ist es verpflichtend, ihn als Open Source mit der gleichen Lizenzierung zu veröffentlichen. Wenn Sie den Code ohne Modifikation verwenden, betrifft Sie das nicht. Weitere Details finden Sie im Issue unten, siehe Link 👇 [Lizenzierung? ](https://github.com/Cap-go/capacitor-updater/issues/7) [Probieren Sie GPTS Capgo aus, um Hilfe zu erhalten, anstatt die Dokumentation zu lesen ](https://chatopenaicom/g/g-3dMwHbF2w-capgo-doc-gpt) > Sie können es ohne Bedenken in Ihre App einbinden ## Abschließende Bemerkungen Wenn Sie selbst hosten und dieses Tool nützlich finden, erwägen Sie bitte, meine Arbeit zu unterstützen, indem Sie [GitHub Sponsor](https://github.com/sponsors/riderx/) werden Ich habe mich entschieden, den gesamten Code, den ich hier entwickelt habe, als Open Source zur Verfügung zu stellen, anstatt ihn hinter einer Bezahlschranke zu verstecken. Ich glaube, dass wir durch Öffnung statt Kampf und Verstecken die Welt zu einem besseren Ort machen können Um dies zu ermöglichen, müssen wir alle unseren Teil beitragen, auch Sie 🥹 Wenn Capgo Cloud Ihre Bedürfnisse nicht erfüllt, können Sie einen bootstrapped Maker [hier](https://github.com/sponsors/riderx/) zu Ihren eigenen Bedingungen unterstützen ## Einfache Rechnung Der Preis des Basic-Plans: 14€\*12 = 168€ pro Jahr Während durchschnittliche Entwicklerkosten/Stunde = 60€ Das bedeutet, dass 3 verschwendete Entwicklerstunden beim Self-Hosting es Ihnen ermöglichen, ein ganzes Jahr zu bezahlen. Wenn Sie mehr als 3 Stunden aufwenden, verlieren Sie Geld ^^ # Fehlerbehebung Hier sind einige häufige Probleme, auf die Sie bei der Verwendung von Capgo stoßen könnten, und wie Sie diese lösen können 🚀 Benötigen Sie Experten-Hilfe? Stecken Sie bei einem komplexen Problem fest? Unser Expertenteam ist hier, um zu helfen! Erhalten Sie persönlichen Support, Code-Reviews und maßgeschneiderte Lösungen für Ihre spezifischen Bedürfnisse. [Professionellen Support erhalten](/de/consulting/) ### Upload-Fehler Wenn Ihr Bundle-Upload fehlschlägt, überprüfen Sie: * Ihre App-ID in `capacitorconfigts` stimmt mit Ihrer App im Capgo Dashboard überein * Sie führen den Upload-Befehl vom Root-Verzeichnis Ihres Capacitor-Projekts aus * Ihre Web-Assets sind gebaut und aktuell #### Erweiterte Upload-Optionen Die Capgo CLI bietet einige zusätzliche Flags zur Lösung häufiger Upload-Probleme: * `--tus`: Verwendet das [tus resumable upload protocol](https://tusio/) für zuverlässigere Uploads von großen Bundles oder bei schlechten Netzwerkverbindungen. Wenn Ihr Bundle über 10MB groß ist oder Sie eine instabile Verbindung haben, erwägen Sie die Verwendung von `--tus`: ```shell npx @capgo/cli@latest bundle upload --tus ``` * `--package-json` und `--node-modules`: Teilt Capgo mit, wo Ihre root `packagejson` und `node_modules` zu finden sind, wenn Ihre App eine nicht-standardmäßige Struktur wie ein Monorepo oder npm Workspace verwendet. Übergeben Sie den Pfad zur root `packagejson` und den `--node-modules` Pfad: ```shell npx @capgo/cli@latest bundle upload --package-json=path/to/packagejson --node-modules=path/to/node_modules ``` Capgo benötigt diese Informationen, um die Abhängigkeiten Ihrer App korrekt zu bündeln Sie können diese Flags mit anderen Optionen wie `--channel` nach Bedarf kombinieren. Siehe die [Capgo CLI Dokumentation](/docs/cli/overview/) für vollständige Details zu den verfügbaren Upload-Optionen Wenn Sie immer noch Probleme mit Uploads haben, wenden Sie sich an den [Capgo Support](https://support.capgo.app) für weitere Unterstützung ### Updates debuggen Wenn Sie Probleme mit Live-Updates haben, ist der Capgo Debug-Befehl ein hilfreiches Tool zur Fehlerbehebung. So verwenden Sie es: 1. Führen Sie den folgenden Befehl in Ihrem Projektverzeichnis aus: ```shell npx @capgo/cli@latest app debug ``` 2. Starten Sie Ihre App auf einem Gerät oder Emulator und führen Sie die Aktion aus, die ein Update auslösen sollte (z.B. die App nach dem Hochladen eines neuen Bundles neu öffnen) 3. Beobachten Sie die Ausgabe des Debug-Befehls. Er protokolliert Informationen über den Update-Prozess, einschließlich: * Wann die App nach einem Update sucht * Ob ein Update gefunden wurde und welche Version es ist * Download- und Installationsfortschritt für das Update * Alle Fehler, die während des Update-Prozesses auftreten 4. Verwenden Sie die Debug-Logs, um zu identifizieren, wo das Problem auftritt. Zum Beispiel: * Wenn kein Update gefunden wird, überprüfen Sie, ob Ihr Bundle erfolgreich hochgeladen wurde und die App für den richtigen Kanal konfiguriert ist * Wenn das Update heruntergeladen, aber nicht installiert wird, stellen Sie sicher, dass Sie `CapacitorUpdater.notifyAppReady()` aufgerufen haben und die App vollständig geschlossen und neu geöffnet wurde * Wenn Sie eine Fehlermeldung sehen, suchen Sie nach diesem spezifischen Fehler in der Capgo-Dokumentation oder wenden Sie sich an den Support Der Debug-Befehl ist besonders nützlich, um Probleme mit dem Update-Download und Installationsprozess zu identifizieren. Wenn die Logs zeigen, dass die erwartete Update-Version gefunden, aber nicht letztendlich angewendet wurde, konzentrieren Sie Ihre Fehlerbehebung auf die Schritte nach dem Download ### Debugging mit nativen Logs Zusätzlich zum Capgo Debug-Befehl können die nativen Logs auf Android und iOS wertvolle Fehlerbehebungsinformationen liefern, besonders für Probleme auf der nativen Seite des Update-Prozesses #### Android Logs So greifen Sie auf die Android-Logs zu: 1. Verbinden Sie Ihr Gerät oder starten Sie Ihren Emulator 2. Öffnen Sie Android Studio und wählen Sie “View > Tool Windows > Logcat” 3. Im Logcat-Fenster filtern Sie die Logs auf den Prozess Ihrer App, indem Sie ihn aus dem Dropdown-Menü oben auswählen 4. Suchen Sie nach Zeilen, die `Capgo` enthalten, um die SDK-Logs zu finden Alternativ können Sie den `adb logcat` Befehl verwenden und nach `Capgo` grep’en, um die Logs zu filtern Das Capgo SDK protokolliert wichtige Ereignisse während des Update-Prozesses, wie zum Beispiel: * Wann eine Update-Prüfung initiiert wird * Ob ein Update gefunden wurde und welche Version es ist * Wann der Update-Download startet und abgeschlossen ist * Wann die Update-Installation ausgelöst wird * Alle Fehler, die während der nativen Update-Schritte auftreten Häufige Android-spezifische Probleme, die Sie in den Logs sehen könnten, sind: * Netzwerkverbindungsprobleme, die den Update-Download verhindern * Dateiberechtigungsfehler beim Speichern oder Lesen des Update-Bundles * Nicht genügend Speicherplatz für das Update-Bundle * Fehler beim Neustart der App nach der Update-Installation #### iOS Logs So greifen Sie auf die iOS-Logs zu: 1. Verbinden Sie Ihr Gerät oder starten Sie Ihren Simulator 2. Öffnen Sie Xcode und gehen Sie zu “Window > Devices and Simulators” 3. Wählen Sie Ihr Gerät und klicken Sie auf “Open Console” 4. Suchen Sie in der Konsolenausgabe nach Zeilen, die `Capgo` enthalten, um die SDK-Logs zu finden Sie können auch den `log stream` Befehl im Terminal verwenden und nach `Capgo` grep’en, um die Logs zu filtern Ähnlich wie bei Android protokolliert das Capgo SDK wichtige iOS-seitige Ereignisse: * Update-Prüfung Initiierung und Ergebnis * Download-Start, Fortschritt und Abschluss * Installations-Trigger und Ergebnis * Alle Fehler während des nativen Update-Prozesses iOS-spezifische Probleme, die Sie in den Logs identifizieren könnten, sind: * SSL-Zertifikatsprobleme beim Herunterladen des Updates * App Transport Security blockiert den Update-Download * Unzureichender Speicherplatz für das Update-Bundle * Fehler beim korrekten Extrahieren oder Anwenden des Update-Bundles Auf beiden Plattformen bieten die nativen Logs einen tieferen Einblick in den Update-Prozess mit mehr Details zur nativen Implementierung. Sie sind besonders nützlich für die Identifizierung von Problemen, die außerhalb der Capgo JavaScript-Schicht auftreten Bei der Fehlerbehebung eines kniffligen Live-Update-Problems ist es eine gute Idee, sowohl die Capgo Debug-Logs als auch die nativen Logs für ein umfassendes Bild der Situation zu erfassen. Die beiden Logs zusammen geben Ihnen die beste Chance, das Problem zu identifizieren und zu lösen ### Updates werden nicht angewendet Wenn Sie ein Bundle hochgeladen haben, aber die Änderungen auf Ihrem Gerät nicht sehen: * Stellen Sie sicher, dass Sie `CapacitorUpdater.notifyAppReady()` in Ihrem App-Code aufgerufen haben, wie im [Quickstart](/docs/getting-started/quickstart) gezeigt * Prüfen Sie, ob Ihr Gerät mit dem Internet verbunden ist und die Capgo Debug-Logs zeigen, dass das Update heruntergeladen wurde * Versuchen Sie, die App vollständig zu schließen und neu zu öffnen, da Updates nur bei einem Neustart angewendet werden * Suchen Sie in den nativen Logs nach Fehlern, die auf ein Problem beim Anwenden des Updates hinweisen könnten Weitere Details zum Update-Prozess finden Sie im [Live-Updates Deployment Guide](/docs/getting-started/deploy). Wenn Sie immer noch Probleme haben, verwenden Sie den `npx @capgo/cli@latest app debug` Befehl und native Logs, um mehr Einblick in das Geschehen zu bekommen ## SDK-Installation Wenn Sie Probleme bei der Installation des Capgo SDK haben, stellen Sie sicher: * Ihre App verwendet eine unterstützte Version von Capacitor (4.0 oder neuer) * Sie sind den [Quickstart](/docs/getting-started/quickstart) Schritten in der richtigen Reihenfolge gefolgt, einschließlich der Synchronisierung Ihrer App nach der Installation des SDK ## CI/CD-Integration Bei Problemen mit dem Auslösen von Capgo-Uploads aus Ihrer CI/CD-Pipeline: * Überprüfen Sie, ob Ihr Capgo-Authentifizierungstoken korrekt eingerichtet ist * Stellen Sie sicher, dass Sie den Upload-Befehl nach dem Build Ihrer Web-Assets ausführen * Prüfen Sie, ob der Upload-Befehl den richtigen Kanalnamen für Ihre Zielumgebung verwendet Weitere Fehlerbehebungstipps finden Sie in der [CI/CD-Integration](/docs/getting-started/cicd-integration) Dokumentation. Sie können auch den `npx @capgo/cli@latest app debug` Befehl verwenden, um zu bestätigen, ob Ihre CI/CD-ausgelösten Updates von der App empfangen werden # So geht's > So verwenden Sie Capgo, Tutorials, Tipps und Tricks [Wie Versionierung in Capgo funktioniert ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [Wie man Major Versionen in Capgo veröffentlicht ](https://capgo.app/blog/how-to-release-major-version-in-capgo/)capgo.app [Wie man spezifische Updates an einen Benutzer oder eine Gruppe sendet ](https://capgo.app/blog/how-to-send-specific-version-to-users/)capgo.app ## CI / CD [Automatischer Build und Release mit GitHub Actions ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [Verwaltung von Entwicklungs- und Produktionsbuilds mit GitHub Actions ](https://capgo.app/blog/automatic-build-and-release-with-github-actions/)capgo.app ## Mitwirken [Beitragen zu Capgo Open Source ](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTINGmd)githubcom # Übersicht Nutzen Sie Capgos Live Updates-Funktion, um die JavaScript-Bundles Ihrer App remote in Echtzeit zu aktualisieren. Pushen Sie JS-Updates direkt an Ihre Nutzer, ohne den App Store-Überprüfungsprozess zu durchlaufen, um sofort Fehler zu beheben und neue Funktionen bereitzustellen. Note Live Updates sind auf JavaScript-Bundle-Änderungen beschränkt. Wenn Sie nativen Code aktualisieren müssen, wie das Hinzufügen oder Entfernen eines Plugins oder das Ändern der nativen Projektkonfiguration, müssen Sie einen neuen nativen Binary-Build an die App Stores übermitteln. ## Wie Live Updates funktionieren Das Live Update-System von Capgo hat zwei Schlüsselkomponenten: 1. Das Capgo SDK, das Sie in Ihrer App installieren. Das SDK prüft auf verfügbare Updates und lädt diese im Hintergrund herunter. 2. Kanäle, mit denen Sie Updates an bestimmte Benutzergruppen richten können. Sie können Kanäle verwenden, um verschiedene Release-Tracks wie `Production`, `Staging` und `Dev` zu verwalten. Wenn Sie ein neues JS-Bundle zu Capgo hochladen und es einem Kanal zuweisen, erkennt das Capgo SDK in Apps, die für diesen Kanal konfiguriert sind, das Update und lädt es herunter. Beim nächsten Neustart der App wird das neue Bundle geladen. ## Erste Schritte Folgen Sie diesen Schritten, um Live Updates zu verwenden: 1. Schließen Sie den [Capgo Quickstart](/docs/getting-started/quickstart) ab, um Ihre App in Capgo einzurichten und das Capgo SDK zu installieren. 2. Rufen Sie in Ihrem App-Code `CapacitorUpdaternotifyAppReady()` auf, nachdem Ihre App initialisiert wurde. Dies teilt dem Capgo SDK mit, dass Ihre App bereit ist, Updates zu empfangen. 3. Erstellen Sie Ihr JS-Bundle und laden Sie es zu Capgo hoch: ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. Öffnen Sie Ihre App und warten Sie, bis das Update heruntergeladen ist. Sie können den Status überprüfen mit: ```shell npx @capgo/cli@latest app debug ``` 5. Sobald das Update heruntergeladen wurde, schließen und öffnen Sie die App erneut, um das neue Bundle zu laden. Weitere Details finden Sie im [Leitfaden zum Bereitstellen von Live Updates](/docs/getting-started/deploy). ## Nächste Schritte [ Kanäle](/docs/live-updates/channels/) [Erfahren Sie, wie Sie Kanäle verwenden, um verschiedene Release-Tracks zu verwalten und Updates an bestimmte Benutzer zu richten](/docs/live-updates/channels/) [ Rollbacks](/docs/live-updates/rollbacks/) [Entdecken Sie, wie Sie zu einer vorherigen JS-Bundle-Version zurückkehren können, wenn ein Update Probleme verursacht](/docs/live-updates/rollbacks/) [ Update-Verhalten](/docs/live-updates/update-behavior/) [Passen Sie an, wie und wann Updates in Ihrer App heruntergeladen und angewendet werden](/docs/live-updates/update-behavior/) [ Schnelle Updates](/docs/live-updates/differentials/) [Erfahren Sie, wie Sie schnelle Updates verwenden können, um den Update-Prozess zu beschleunigen](/docs/live-updates/differentials/) # Kanäle Ein Live-Update-Kanal verweist auf einen bestimmten JS-Bundle-Build Ihrer App, der mit allen Geräten geteilt wird, die für Updates auf diesen Kanal eingestellt sind. Wenn Sie das [Capgo Live Updates SDK](/docs/getting-started/quickstart/) in Ihrer App installieren, prüft jede native Binary, die für diesen Kanal konfiguriert ist, beim App-Start auf verfügbare Updates. Sie können den Build, auf den ein Kanal verweist, jederzeit ändern und bei Bedarf auch auf vorherige Builds zurücksetzen. ## Einrichten eines Kanals Jede App wird mit einem Standardkanal namens “Production” ausgeliefert, der nicht gelöscht werden kann. So fügen Sie neue Kanäle hinzu: 1. Gehen Sie zum Bereich “Channels” im Capgo Dashboard 2. Klicken Sie auf den Button “New Channel” 3. Geben Sie einen Namen für den Kanal ein und klicken Sie auf “Create” Kanalnamen können frei gewählt werden. Eine gängige Strategie ist es, Kanäle Ihren Entwicklungsphasen zuzuordnen, zum Beispiel: * `Development` - zum Testen von Live-Updates auf lokalen Geräten oder Emulatoren * `QA` - für Ihr QA-Team zur Überprüfung von Updates vor der breiten Veröffentlichung * `Staging` - für finale Tests in einer produktionsähnlichen Umgebung * `Production` - für die Version Ihrer App, die Endbenutzer aus den App Stores erhalten ## Konfigurieren des Kanals in Ihrer App Nachdem Sie Ihre Kanäle erstellt haben, müssen Sie Ihre App so konfigurieren, dass sie auf den entsprechenden Kanal hört. In diesem Beispiel verwenden wir den `Development`-Kanal. Öffnen Sie Ihre `capacitor.config.ts` (oder `capacitor.config.json`) Datei. Setzen Sie unter dem `plugins`-Abschnitt die `channel`-Eigenschaft des `CapacitorUpdater`-Plugins auf den Namen Ihres gewünschten Kanals: ```ts import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { defaultChannel: 'Development', }, }, }; ``` Bauen Sie anschließend Ihre Web-App und führen Sie `npx cap sync` aus, um die aktualisierte Konfigurationsdatei in Ihre iOS- und Android-Projekte zu kopieren. Wenn Sie diesen Sync-Schritt überspringen, verwenden Ihre nativen Projekte weiterhin den Kanal, für den sie zuvor konfiguriert waren. Caution Die `defaultChannel`-Eigenschaft überschreibt immer den Cloud-Standardkanal. Sie können jedoch die deviceId weiterhin in der Cloud einem Kanal zuweisen. ## Zuweisen eines Bundles zu einem Kanal Um ein Live-Update bereitzustellen, müssen Sie einen neuen JS-Bundle-Build hochladen und einem Kanal zuweisen. Sie können dies in einem Schritt mit der Capgo CLI tun: ```shell npx @capgo/cli@latest bundle upload --channel=Development ``` Dies lädt Ihre gebauten Web-Assets hoch und setzt den neuen Bundle als aktiven Build für den `Development`-Kanal. Alle Apps, die für diesen Kanal konfiguriert sind, erhalten das Update beim nächsten Überprüfen. Sie können Builds auch über den “Bundles”-Bereich des Capgo Dashboards Kanälen zuweisen. Klicken Sie auf das Menü-Symbol neben einem Build und wählen Sie “Assign to Channel”, um den Kanal für diesen Build auszuwählen. ## Bundle-Versionierung und Kanäle Es ist wichtig zu beachten, dass Bundles in Capgo global für Ihre App sind und nicht spezifisch für einzelne Kanäle. Dasselbe Bundle kann mehreren Kanälen zugewiesen werden. Bei der Versionierung Ihrer Bundles empfehlen wir die Verwendung von Semantic Versioning [semver](https://semver.org/) mit Pre-Release-Kennungen für kanalspezifische Builds. Ein Beta-Release könnte beispielsweise als `1.2.3-beta.1` versioniert sein. Dieser Ansatz hat mehrere Vorteile: * Er kommuniziert die Beziehung zwischen Builds klar: `1.2.3-beta.1` ist offensichtlich eine Vorabversion von `1.2.3` * Er ermöglicht die Wiederverwendung von Versionsnummern über Kanäle hinweg und reduziert Verwirrung * Er ermöglicht klare Rollback-Pfade. Wenn Sie von `1.2.3` zurückrollen müssen, wissen Sie, dass `1.2.2` die vorherige stabile Version ist Hier ist ein Beispiel, wie Sie Ihre Bundle-Versionen mit einem typischen Kanal-Setup abstimmen könnten: * `Development`-Kanal: `1.2.3-dev.1`, `1.2.3-dev.2`, etc. * `QA`-Kanal: `1.2.3-qa.1`, `1.2.3-qa.2`, etc. * `Staging`-Kanal: `1.2.3-rc.1`, `1.2.3-rc.2`, etc. * `Production`-Kanal: `1.2.3`, `1.2.4`, etc. ## Zurücksetzen eines Live-Updates Wenn Sie ein Live-Update bereitstellen, das einen Fehler einführt oder aus anderen Gründen zurückgesetzt werden muss, können Sie einfach zu einem vorherigen Build zurückkehren. Vom “Channels”-Bereich des Dashboards aus: 1. Klicken Sie auf den Namen des Kanals, den Sie zurücksetzen möchten 2. Finden Sie den Build, zu dem Sie zurückkehren möchten, und klicken Sie auf das Kronen-Symbol ![Rollback build](/select_bundle.webp) 3. Bestätigen Sie die Aktion Der ausgewählte Build wird sofort wieder zum aktiven Build für diesen Kanal. Apps erhalten die zurückgesetzte Version beim nächsten Update-Check. ## Automatisierung von Deployments Für fortgeschrittenere Workflows können Sie Ihre Live-Update-Deployments als Teil Ihrer CI/CD-Pipeline automatisieren. Durch die Integration von Capgo in Ihren Build-Prozess können Sie automatisch neue Bundles hochladen und Kanälen zuweisen, wenn Sie zu bestimmten Branches pushen oder neue Releases erstellen. Schauen Sie sich die [CI/CD Integration](/docs/getting-started/cicd-integration/) Dokumentation an, um mehr über die Automatisierung von Capgo Live-Updates zu erfahren. ## Bereitstellung auf einem Gerät Nachdem Sie die Kanäle verstanden haben, können Sie mit der Bereitstellung von Live-Updates auf echten Geräten beginnen. Der grundlegende Prozess ist: 1. Installieren Sie das Capgo SDK in Ihrer App 2. Konfigurieren Sie die App, um auf Ihren gewünschten Kanal zu hören 3. Laden Sie einen Build hoch und weisen Sie ihn diesem Kanal zu 4. Starten Sie die App und warten Sie auf das Update! Eine detailliertere Anleitung finden Sie im [Deploying Live Updates](/docs/getting-started/deploy/) Guide. Viel Spaß beim Aktualisieren! # Schnelle Aktualisierungen Capgos Live-Update-System kann Updates schneller und effizienter bereitstellen, indem nur die geänderten Dateien und nicht das gesamte JS-Bundle gesendet werden Dies ist besonders vorteilhaft für Benutzer mit langsameren oder getakteten Netzwerkverbindungen, da die Menge der herunterzuladenden Daten minimiert wird Ein zweiter Vorteil ist, wenn die App große Assets enthält, die sich selten ändern, wie Bilder oder Videos - im Vergleich zu gezippten JS-Dateien werden diese nur einmal heruntergeladen ## Wie Differenzielle Updates funktionieren Differenzielle Updates in Capgo werden durch das in Ihrer App installierte Capgo-Plugin verarbeitet. Wenn Sie eine neue Version Ihrer App mit der Flag `--partial` hochladen, führt Capgo Folgendes aus: 1. Jede Datei in Ihrem Build wird einzeln hochgeladen 2. Für jede Datei werden Prüfsummen generiert 3. Ein neues JSON-Manifest wird erstellt, das alle Dateien und ihre Prüfsummen auflistet 4. Dieses Manifest wird in die Capgo-Datenbank hochgeladen Wenn ein Gerät, auf dem Ihre App läuft, nach Updates sucht, erhält das Capgo-Plugin das neue Manifest vom Server. Es vergleicht dieses Manifest mit dem aktuellen und identifiziert anhand der Prüfsummen und Dateipfade, welche Dateien sich geändert haben Das Plugin lädt dann nur die geänderten Dateien herunter, anstatt das gesamte JS-Bundle. Es rekonstruiert die neue Version der App, indem es diese heruntergeladenen Dateien mit den unveränderten Dateien kombiniert Manifest Bei differenziellen Updates speichert das Gerät alle heruntergeladenen Dateien in einem gemeinsamen Cache. Capgo wird diesen nie bereinigen, aber das Betriebssystem kann dies jederzeit tun ## Aktivierung von Differenziellen Updates Um differenzielle Updates für Ihre Capgo-App zu aktivieren, verwenden Sie einfach die Flag `--partial` beim Hochladen einer neuen Version: ## Erzwingen von Differenziellen Updates Wenn Sie sicherstellen möchten, dass alle Uploads differenzielle Updates sind und versehentliche vollständige Bundle-Uploads verhindert werden, können Sie die Flag `--partial-only` verwenden: ```shell npx @capgo/cli@latest bundle upload --partial-only ``` Wenn `--partial-only` verwendet wird, lädt Capgo nur einzelne Dateien hoch und generiert ein Manifest. Geräte, die keine partiellen Updates unterstützen, können das Update nicht herunterladen Sie möchten `--partial-only` möglicherweise verwenden, wenn: * Sie immer differenzielle Updates verwenden und nie vollständige Bundle-Uploads zulassen möchten * Sie eine CI/CD-Pipeline einrichten und sicherstellen möchten, dass alle automatisierten Uploads differenziell sind * Ihre App groß ist und die Bandbreite begrenzt ist, sodass Sie Upload-/Download-Größen minimieren müssen Wenn Sie einen vollständigen Bundle-Upload durchführen müssen, während `--partial-only` gesetzt ist, führen Sie den Upload-Befehl einfach ohne `--partial-only` aus. Dies überschreibt die Einstellung für diesen einzelnen Upload und ermöglicht es Ihnen, ein vollständiges Bundle zu pushen, wenn nötig ## Fehlerbehebung Wenn differenzielle Updates nicht zu funktionieren scheinen (d.h. Geräte laden immer das vollständige JS-Bundle herunter, auch bei kleinen Änderungen), überprüfen Sie Folgendes: * Sie verwenden die Flag `--partial` bei jedem Upload einer neuen Version * Bei Verwendung von `--partial-only` stellen Sie sicher, dass Sie die Flag `--partial` nicht versehentlich weggelassen haben * Ihr Gerät läuft mit der neuesten Version des Capgo-Plugins * Ihr Gerät hat eine stabile Netzwerkverbindung und kann die Capgo-Server erreichen Sie können auch die Capgo-Webapp verwenden, um die Details Ihres letzten Uploads zu überprüfen: 1. Gehen Sie zur [Webapp](https://app.capgo.io) 2. Klicken Sie auf Ihre App 3. Klicken Sie auf die Bundles-Nummer in der Statistikleiste 4. Wählen Sie das letzte Bundle 5. Überprüfen Sie das `Partial`-Feld ![bundle type](/bundle_type.webp) Wenn Sie weiterhin Probleme haben, wenden Sie sich bitte an den Capgo-Support für weitere Unterstützung. Sie können die Server-Logs überprüfen, um zu bestätigen, dass Ihre partiellen Uploads korrekt verarbeitet werden und die Geräte die aktualisierten Manifeste erhalten Das war’s! Die Flag `--partial` weist Capgo an, die einzelnen Datei-Uploads und Manifest-Generierung durchzuführen, die für differenzielle Updates benötigt werden Beachten Sie, dass Sie `--partial` jedes Mal verwenden müssen, wenn Sie eine neue Version hochladen, die als differenzielles Update bereitgestellt werden soll. Wenn Sie die Flag weglassen, lädt Capgo das gesamte JS-Bundle als einzelne Datei hoch, und Geräte werden das gesamte Bundle herunterladen, auch wenn sich nur ein kleiner Teil geändert hat # Rollbacks Während die Live-Updates von Capgo es Ihnen ermöglichen, schnell Verbesserungen und Fehlerbehebungen an Ihre Nutzer zu liefern, kann es Situationen geben, in denen Sie zu einer vorherigen Version Ihrer App zurückkehren müssen. Vielleicht hat ein neues Update ein unerwartetes kritisches Problem eingeführt, oder Sie möchten eine bestimmte Änderung rückgängig machen, während Sie an einer Lösung arbeiten. Capgo bietet verschiedene Möglichkeiten, die Builds eines Kanals zu verwalten und die Version Ihrer App zu kontrollieren, die Benutzer erhalten. ## Zurücksetzen auf ein vorheriges Bundle Jedes Mal, wenn Sie einen neuen Build hochladen und einem Kanal zuweisen, behält Capgo einen Verlauf dieser Builds bei. Wenn Sie ein bestimmtes Update rückgängig machen müssen, können Sie einen dieser vorherigen Builds auswählen, um ihn erneut im Kanal bereitzustellen. Um zu einem vorherigen Build zurückzukehren: 1. Melden Sie sich beim [Capgo Dashboard](https://app.capgo.io) an 2. Navigieren Sie zum Bereich “Channels” 3. Klicken Sie auf den Namen des Kanals, den Sie zurücksetzen möchten 4. Suchen Sie den Build, zu dem Sie zurückkehren möchten, in der Build-Historie des Kanals 5. Klicken Sie auf das Kronen-Symbol neben diesem Build, um ihn zum aktiven Build für den Kanal zu machen ![Kanal-Verwaltungsoptionen](/select_bundle.webp) 6. Bestätigen Sie, dass Sie zu diesem Build zurückkehren möchten Note Das Zurücksetzen auf einen vorherigen Build betrifft nur den ausgewählten Kanal. Wenn Sie mehrere Kanäle haben (z.B. Produktion, Staging, etc.), müssen Sie den Rollback-Prozess für jeden betroffenen Kanal wiederholen. Nach dem Zurücksetzen erhalten Geräte, die für den aktualisierten Kanal konfiguriert sind, beim nächsten Update-Check den vorherigen Build. Der zurückgesetzte Build wird als neues Update behandelt, sodass der übliche Update-Ablauf und die Bedingungen gelten. ## Trennen eines Kanals Wenn Sie Updates auf einem Kanal vorübergehend anhalten möchten, während Sie ein Problem untersuchen, können Sie den Kanal von seinem aktuellen Build trennen. Um einen Kanal zu trennen: 1. Navigieren Sie zum Kanal im Capgo Dashboard 2. Klicken Sie auf die Schaltfläche “Unlink” neben dem aktuellen Build 3. Bestätigen Sie, dass Sie den Kanal trennen möchten Sobald ein Kanal getrennt ist, werden keine neuen Updates mehr verteilt. Geräte, die für diesen Kanal konfiguriert sind, bleiben bei ihrem aktuellen Build, bis der Kanal wieder mit einem Build verknüpft wird. Dies ist nützlich, wenn Sie ein Problem mit einem Update identifiziert haben, aber noch nicht sicher sind, zu welchem Build Sie zurückkehren möchten. Das Trennen des Kanals gibt Ihnen Zeit zur Untersuchung, ohne weitere Updates zu verteilen. ## Erzwingen des eingebauten Bundles In schwerwiegenderen Situationen möchten Sie möglicherweise alle Geräte eines Kanals auf den Web-Build zurücksetzen, der ursprünglich mit dem nativen Binary Ihrer App gepackt wurde. Dies ist als “eingebautes Bundle” bekannt. Um das eingebaute Bundle auf einem Kanal zu erzwingen: 1. Navigieren Sie zum Kanal im Capgo Dashboard 2. Klicken Sie auf die Schaltfläche “Built-in Bundle” 3. Bestätigen Sie, dass Sie das eingebaute Bundle erzwingen möchten Wenn Sie das eingebaute Bundle erzwingen, kehren alle Geräte, die für diesen Kanal konfiguriert sind, bei ihrer nächsten Update-Prüfung zum ursprünglich gepackten Web-Build zurück. Dies geschieht unabhängig davon, welchen Build sie derzeit verwenden. Dies ist eine aggressivere Rollback-Option als das Zurücksetzen auf einen bestimmten vorherigen Build, da es alle Live-Updates verwirft, die seit der letzten Veröffentlichung der App in den App Stores freigegeben wurden. Caution Seien Sie vorsichtig beim Erzwingen des eingebauten Bundles, da es alle Geräte im Kanal betrifft. Stellen Sie sicher, dass Sie die Auswirkungen bedacht und einen Plan für das weitere Vorgehen haben, bevor Sie diese Aktion durchführen. ## Überwachung und Reaktion auf Probleme Um Probleme schnell zu erkennen und die Auswirkungen problematischer Updates zu minimieren, ist es wichtig, einen Plan für die Überwachung Ihrer Releases und die Reaktion auf Probleme zu haben. Einige Strategien umfassen: * Überwachung von Absturzberichten und Benutzer-Feedback unmittelbar nach der Veröffentlichung eines Updates * Verwendung von stufenweisen Rollouts oder einem mehrstufigen Kanalsystem, um Updates an einer kleineren Gruppe zu testen, bevor sie breit veröffentlicht werden * Einen klaren Entscheidungsprozess haben, wann zurückgesetzt, getrennt oder das eingebaute Bundle erzwungen werden soll, und wer dazu berechtigt ist * Gegebenenfalls Kommunikation mit den Benutzern über das Problem und die Lösung Durch die Kombination sorgfältiger Überwachung mit der Möglichkeit, problematische Updates schnell zu verwalten, können Sie eine kontinuierlich verbesserte App-Erfahrung bieten und gleichzeitig Störungen für Ihre Benutzer minimieren. # Aktualisierungsverhalten Wenn Sie ein Update für Ihre Capgo-App veröffentlichen, möchten Sie wahrscheinlich, dass Ihre Nutzer dieses Update so schnell wie möglich erhalten. Allerdings möchten Sie deren Nutzungserfahrung nicht stören, indem Sie sie zwingen, mitten in einer Sitzung auf einen Download zu warten oder die App neu zu starten. Das Update-Verhalten von Capgo wurde entwickelt, um eine Balance zwischen schneller Update-Bereitstellung und minimaler Störung der Nutzer zu finden. ## Standard Update-Ablauf Standardmäßig behandelt Capgo App-Updates wie folgt: 1. Beim App-Start prüft das Capgo-Plugin, ob ein neues Update verfügbar ist 2. Wenn ein Update gefunden wird, wird es im Hintergrund heruntergeladen, während der Nutzer die aktuelle Version der App weiter verwendet 3. Sobald der Download abgeschlossen ist, wartet Capgo darauf, dass der Nutzer die App entweder in den Hintergrund verschiebt oder vollständig beendet 4. Wenn der Nutzer die App das nächste Mal startet, wird die aktualisierte Version ausgeführt Dieser Ablauf stellt sicher, dass Nutzer immer die neueste Version Ihrer App verwenden, ohne jemals durch Update-Benachrichtigungen unterbrochen oder zum Warten auf Downloads gezwungen zu werden. Tip Capgo prüft auch auf Updates, wenn die App aus dem Hintergrund fortgesetzt wird. So erhalten Nutzer Updates auch dann, wenn sie die App nicht vollständig beenden. ## Warum dieser Ansatz? Das Anwenden von Updates bei Hintergrund- oder Beendigungsereignissen hat einige wichtige Vorteile für die Benutzererfahrung: * Nutzer werden nicht durch Update-Aufforderungen unterbrochen oder müssen mitten in einer Sitzung auf Downloads warten * Updates werden nahtlos zwischen den Sitzungen angewendet, sodass das Starten der App immer ein frisches Erlebnis ist * Sie können häufig Updates bereitstellen, ohne sich Sorgen machen zu müssen, aktive Nutzer zu stören Der Hauptnachteil ist, dass wenn ein Nutzer die App in den Hintergrund verschiebt und schnell wieder aufruft, könnte nicht gespeicherter Status verloren gehen, da das Update zwischen diesen Aktionen angewendet wurde. Um dies zu vermeiden, empfehlen wir: * Status häufig zu speichern und ihn beim Fortsetzen der App korrekt wiederherzustellen * Sehr häufige Updates zu vermeiden, die große Teile des App-Status verändern * Die Anpassung des Update-Verhaltens für sensible Abläufe in Erwägung zu ziehen (siehe unten) ## Anpassen wann Updates angewendet werden In manchen Fällen möchten Sie möglicherweise mehr Kontrolle darüber haben, wann genau ein Update angewendet wird. Zum Beispiel möchten Sie vielleicht sicherstellen, dass ein Nutzer einen laufenden Prozess abschließt, bevor das Update installiert wird, oder ein App-Update mit einer serverseitigen Änderung koordinieren. Capgo bietet eine `setDelay`-Funktion, mit der Sie Bedingungen festlegen können, die erfüllt sein müssen, bevor ein Update installiert wird: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; await CapacitorUpdater.setMultiDelay({ delayConditions: [ { kind: 'date', value: '2023-06-01T00:00:00.000Z', }, { kind: 'background', value: '60000', }, ], }); ``` Dieses Beispiel würde die Installation eines Updates verzögern, bis nach dem 1. Juni 2023 UND die App mindestens 60 Sekunden im Hintergrund war. Die verfügbaren Verzögerungsbedingungen sind: * `date`: Warten bis nach einem bestimmten Datum/Uhrzeit, um das Update anzuwenden * `background`: Nach einer Mindestdauer warten, nachdem die App in den Hintergrund verschoben wurde * `nativeVersion`: Warten auf die Installation einer nativen Binary mit einer Mindestversion * `kill`: Warten bis zum nächsten App-Beendigungsereignis Sie können diese Bedingungen kombinieren, um präzise zu steuern, wann ein Update installiert wird. Danger Beachten Sie, dass die `kill`-Bedingung das Update derzeit nach dem ersten Beendigungsereignis auslöst, nicht nach dem nächsten Hintergrundereignis wie die anderen Bedingungen. Diese Inkonsistenz wird in einer zukünftigen Version behoben. ## Sofortiges Anwenden von Updates Für kritische Updates oder Apps mit sehr einfachem Status möchten Sie möglicherweise ein Update sofort nach dem Download anwenden, ohne auf ein Hintergrund- oder Beendigungsereignis zu warten. Capgo unterstützt dies über die `directUpdate`-Konfigurationsoption. `directUpdate` wird in Ihrer `capacitor.config.ts`-Datei gesetzt, nicht im JavaScript-Code: ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: true, keepUrlPathAfterReload: true, }, }, }; export default config; ``` Mit aktiviertem `directUpdate` wird Capgo ein Update sofort anwenden, sobald der Download abgeschlossen ist, auch wenn der Nutzer die App aktiv verwendet. Beachten Sie, dass `directUpdate` als native Konfiguration zusätzliche Behandlung in Ihrem JavaScript-Code erfordert. Bei Verwendung von `directUpdate` müssen Sie auf das `appReady`-Event hören und den Splash-Screen Ihrer App entsprechend ausblenden: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater'; import { SplashScreen } from '@capacitor/splash-screen'; CapacitorUpdater.addListener('appReady', () => { // Splash Screen ausblenden SplashScreen.hide(); }); CapacitorUpdater.notifyAppReady(); ``` Das `appReady`-Event wird ausgelöst, sobald die App die Initialisierung abgeschlossen und alle ausstehenden Updates angewendet hat. Ab diesem Zeitpunkt ist es sicher, die Benutzeroberfläche Ihrer App anzuzeigen, da sichergestellt ist, dass der Nutzer die neueste Version sieht. Zusätzlich zur Behandlung des `appReady`-Events empfehlen wir, die Konfigurationsoption `keepUrlPathAfterReload` auf `true` zu setzen, wenn Sie `directUpdate` verwenden. Dies bewahrt den aktuellen URL-Pfad, wenn die App aufgrund eines Updates neu geladen wird, und hilft dabei, den Standort des Nutzers in der App beizubehalten und Desorientierung zu reduzieren. Wenn Sie das `appReady`-Event nicht behandeln und `keepUrlPathAfterReload` nicht setzen, wenn Sie `directUpdate` verwenden, könnte der Nutzer kurzzeitig eine veraltete Version der App sehen, zur Ausgangsroute zurückgeführt werden oder ein Flackern sehen, während das Update angewendet wird. Die Verwendung von `directUpdate` kann nützlich sein, um kritische Fehlerbehebungen oder Sicherheitspatches bereitzustellen, bringt aber einige Kompromisse mit sich: * Der Nutzer könnte ein kurzes Flackern oder einen Ladezustand sehen, während das Update angewendet wird, wenn Sie das `appReady`-Event nicht richtig behandeln * Wenn das Update den App-Status oder die Benutzeroberfläche ändert, könnte der Nutzer eine störende Änderung mitten in einer Sitzung sehen * Der Standort des Nutzers in der App könnte verloren gehen, wenn `keepUrlPathAfterReload` nicht gesetzt ist, was möglicherweise desorientierend wirkt * Sie müssen sorgfältig das Speichern und Wiederherstellen des Status handhaben, um einen reibungslosen Übergang zu gewährleisten Wenn Sie `directUpdate` aktivieren, empfehlen wir: * Behandlung des `appReady`-Events zur Kontrolle, wann die Benutzeroberfläche Ihrer App angezeigt wird * Setzen von `keepUrlPathAfterReload` auf `true`, um den Standort des Nutzers in der App zu bewahren * Speichern und Wiederherstellen des App-Status nach Bedarf, um Nutzerffortschritt nicht zu verlieren * Gründliches Testen des Update-Verhaltens Ihrer App, um sicherzustellen, dass es keine störenden Übergänge, verlorenen Status oder desorientierenden Standortänderungen gibt In den meisten Fällen bietet das Standard-Update-Verhalten die beste Balance zwischen schneller Update-Bereitstellung und minimaler Störung. Aber für Apps mit spezifischen Anforderungen bietet Capgo die Flexibilität, anzupassen, wann und wie Updates angewendet werden. # Funktionen und Einstellungen > Alle verfügbaren Methoden und Einstellungen des Plugins # Updater Plugin Konfiguration Siehe Github [Readme](https://github.com/Cap-go/capacitor-updater) für weitere Informationen CapacitorUpdater kann mit diesen Optionen konfiguriert werden: | Eigenschaft | Typ | Beschreibung | Standard | Seit | | ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | ------- | | **`appReadyTimeout`** | `number` | Konfiguriert die Anzahl der Millisekunden, die das native Plugin warten soll, bevor ein Update als ‘fehlgeschlagen’ gilt. Nur verfügbar für Android und iOS | `10000 // (10 Sekunden)` | | | **`responseTimeout`** | `number` | Konfiguriert die Anzahl der Millisekunden, die das native Plugin warten soll, bevor API-Timeout eintritt. Nur verfügbar für Android und iOS | `20 // (20 Sekunden)` | | | **`autoDeleteFailed`** | `boolean` | Konfiguriert, ob das Plugin fehlgeschlagene Bundles automatisch löschen soll. Nur verfügbar für Android und iOS | `true` | | | **`autoDeletePrevious`** | `boolean` | Konfiguriert, ob das Plugin vorherige Bundles nach einem erfolgreichen Update automatisch löschen soll. Nur verfügbar für Android und iOS | `true` | | | **`autoUpdate`** | `boolean` | Konfiguriert, ob das Plugin Auto-Update über einen Update-Server verwenden soll. Nur verfügbar für Android und iOS | `true` | | | **`resetWhenUpdate`** | `boolean` | Löscht automatisch zuvor heruntergeladene Bundles, wenn ein neueres natives App-Bundle auf dem Gerät installiert wird. Nur verfügbar für Android und iOS | `true` | | | **`updateUrl`** | `string` | Konfiguriert die URL / den Endpunkt, an den Update-Prüfungen gesendet werden. Nur verfügbar für Android und iOS | `https://plugin.capgo.app/updates` | | | **`channelUrl`** | `string` | Konfiguriert die URL / den Endpunkt für Kanal-Operationen. Nur verfügbar für Android und iOS | `https://plugin.capgo.app/channel_self` | | | **`statsUrl`** | `string` | Konfiguriert die URL / den Endpunkt, an den Update-Statistiken gesendet werden. Nur verfügbar für Android und iOS. Auf "" setzen, um Statistik-Reporting zu deaktivieren | `https://plugin.capgo.app/stats` | | | **`privateKey`** | `string` | Konfiguriert den privaten Schlüssel für Ende-zu-Ende Live-Update-Verschlüsselung. Nur verfügbar für Android und iOS. Veraltet in Version 6.2.0, wird in Version 7.0.0 entfernt | `undefined` | | | **`publicKey`** | `string` | Konfiguriert den öffentlichen Schlüssel für Ende-zu-Ende Live-Update-Verschlüsselung Version 2. Nur verfügbar für Android und iOS | `undefined` | 6.2.0 | | **`version`** | `string` | Konfiguriert die aktuelle Version der App. Wird für die erste Update-Anfrage verwendet. Wenn nicht gesetzt, holt das Plugin die Version aus dem nativen Code. Nur verfügbar für Android und iOS | `undefined` | 4.17.48 | | **`directUpdate`** | `boolean` | Lässt das Plugin Updates direkt installieren, wenn die App gerade aktualisiert/installiert wurde. Nur für autoUpdate-Modus. Nur verfügbar für Android und iOS | `undefined` | 5.1.0 | | **`periodCheckDelay`** | `number` | Konfiguriert die Verzögerungsperiode für periodische Update-Prüfungen in Sekunden. Nur verfügbar für Android und iOS. Kann nicht weniger als 600 Sekunden (10 Minuten) sein | `600 // (10 Minuten)` | | | **`localS3`** | `boolean` | Konfiguriert die CLI zur Verwendung eines lokalen Servers für Tests oder selbst-gehosteten Update-Server | `undefined` | 4.17.48 | | **`localHost`** | `string` | Konfiguriert die CLI zur Verwendung eines lokalen Servers für Tests oder selbst-gehosteten Update-Server | `undefined` | 4.17.48 | | **`localWebHost`** | `string` | Konfiguriert die CLI zur Verwendung eines lokalen Servers für Tests oder selbst-gehosteten Update-Server | `undefined` | 4.17.48 | | **`localSupa`** | `string` | Konfiguriert die CLI zur Verwendung eines lokalen Servers für Tests oder selbst-gehosteten Update-Server | `undefined` | 4.17.48 | | **`localSupaAnon`** | `string` | Konfiguriert die CLI zur Verwendung eines lokalen Servers für Tests | `undefined` | 4.17.48 | | **`localApi`** | `string` | Konfiguriert die CLI zur Verwendung einer lokalen API für Tests | `undefined` | 6.3.3 | | **`localApiFiles`** | `string` | Konfiguriert die CLI zur Verwendung einer lokalen Datei-API für Tests | `undefined` | 6.3.3 | | **`allowModifyUrl`** | `boolean` | Erlaubt dem Plugin, updateUrl, statsUrl und channelUrl dynamisch von der JavaScript-Seite zu ändern | `false` | 5.4.0 | | **`defaultChannel`** | `string` | Setzt den Standard-Kanal für die App in der Konfiguration | `undefined` | 4.17.48 | | **`appId`** | `string` | App-ID in der Konfiguration für die App konfigurieren | `undefined` | 600 | | **`keepUrlPathAfterReload`** | `boolean` | Plugin so konfigurieren, dass der URL-Pfad nach einem Reload erhalten bleibt WARNUNG: Wenn ein Reload ausgelöst wird, wird ‘windowhistory’ gelöscht | `false` | 680 | ## Beispiele In `capacitorconfigjson`: ```json { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 // (1 Sekunde), "responseTimeout": 10 // (10 Sekunden), "autoDeleteFailed": false, "autoDeletePrevious": false, "autoUpdate": false, "resetWhenUpdate": false, "updateUrl": https://examplecom/api/auto_update, "channelUrl": https://examplecom/api/channel, "statsUrl": https://examplecom/api/stats, "privateKey": undefined, "publicKey": undefined, "version": undefined, "directUpdate": undefined, "periodCheckDelay": undefined, "localS3": undefined, "localHost": undefined, "localWebHost": undefined, "localSupa": undefined, "localSupaAnon": undefined, "localApi": undefined, "localApiFiles": undefined, "allowModifyUrl": undefined, "defaultChannel": undefined, "appId": undefined, "keepUrlPathAfterReload": undefined } } } ``` In `capacitorconfigts`: ```ts /// import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { appReadyTimeout: 1000 // (1 Sekunde), responseTimeout: 10 // (10 Sekunden), autoDeleteFailed: false, autoDeletePrevious: false, autoUpdate: false, resetWhenUpdate: false, updateUrl: https://examplecom/api/auto_update, channelUrl: https://examplecom/api/channel, statsUrl: https://examplecom/api/stats, privateKey: undefined, publicKey: undefined, version: undefined, directUpdate: undefined, periodCheckDelay: undefined, localS3: undefined, localHost: undefined, localWebHost: undefined, localSupa: undefined, localSupaAnon: undefined, localApi: undefined, localApiFiles: undefined, allowModifyUrl: undefined, defaultChannel: undefined, appId: undefined, keepUrlPathAfterReload: undefined, }, }, }; export default config; ``` * [`notifyAppReady()`](#notifyappready) * [`setUpdateUrl()`](#setupdateurl) * [`setStatsUrl()`](#setstatsurl) * [`setChannelUrl()`](#setchannelurl) * [`download()`](#download) * [`next()`](#next) * [`set()`](#set) * [`delete()`](#delete) * [`list()`](#list) * [`reset()`](#reset) * [`current()`](#current) * [`reload()`](#reload) * [`setMultiDelay()`](#setmultidelay) * [`cancelDelay()`](#canceldelay) * [`getLatest()`](#getlatest) * [`setChannel()`](#setchannel) * [`unsetChannel()`](#unsetchannel) * [`getChannel()`](#getchannel) * [`setCustomId()`](#setcustomid) * [`getBuiltinVersion()`](#getbuiltinversion) * [`getDeviceId()`](#getdeviceid) * [`getPluginVersion()`](#getpluginversion) * [`isAutoUpdateEnabled()`](#isautoupdateenabled) * [`removeAllListeners()`](#removealllisteners) * [`addListener('download', )`](#addlistenerdownload-) * [`addListener('noNeedUpdate', )`](#addlistenernoneedupdate-) * [`addListener('updateAvailable', )`](#addlistenerupdateavailable-) * [`addListener('downloadComplete', )`](#addlistenerdownloadcomplete-) * [`addListener('majorAvailable', )`](#addlistenermajoravailable-) * [`addListener('updateFailed', )`](#addlistenerupdatefailed-) * [`addListener('downloadFailed', )`](#addlistenerdownloadfailed-) * [`addListener('appReloaded', )`](#addlistenerappreloaded-) * [`addListener('appReady', )`](#addlistenerappready-) * [`isAutoUpdateAvailable()`](#isautoupdateavailable) * [`getNextBundle()`](#getnextbundle) * [Schnittstellen](#interfaces) * [Typalias](#type-aliases) # Methoden ## notifyAppReady() ```typescript notifyAppReady() => Promise ``` Benachrichtigt Capacitor Updater, dass das aktuelle Bundle funktioniert (ein Rollback erfolgt, wenn diese Methode nicht bei jedem App-Start aufgerufen wird) Standardmäßig sollte diese Methode innerhalb der ersten 10 Sekunden nach dem App-Start aufgerufen werden, andernfalls erfolgt ein Rollback Dieses Verhalten kann mit {@link appReadyTimeout} geändert werden **Returns:** `Promise` *** ## setUpdateUrl() ```typescript setUpdateUrl(options: UpdateUrl) => Promise ``` Legt die updateUrl für die App fest, diese wird zum Prüfen auf Updates verwendet | Param | Type | Description | | ------------- | ----------- | ------------------------------------------------------ | | **`options`** | `UpdateUrl` | enthält die URL, die für Update-Prüfungen genutzt wird | **Seit:** 540 *** ## setStatsUrl() ```typescript setStatsUrl(options: StatsUrl) => Promise ``` Legt die statsUrl für die App fest, diese wird zum Senden von Statistiken verwendet. Wenn ein leerer String übergeben wird, wird die Erfassung von Statistiken deaktiviert | Param | Type | Description | | ------------- | ---------- | ------------------------------------------------------------------ | | **`options`** | `StatsUrl` | enthält die URL, die für das Senden von Statistiken verwendet wird | **Seit:** 540 *** ## setChannelUrl() ```typescript setChannelUrl(options: ChannelUrl) => Promise ``` Legt die channelUrl für die App fest, diese wird zum Setzen des Kanals verwendet | Param | Type | Description | | ------------- | ------------ | ------------------------------------------------------------- | | **`options`** | `ChannelUrl` | enthält die URL, die für das Setzen des Kanals verwendet wird | **Seit:** 540 *** ## download() ```typescript download(options: DownloadOptions) => Promise ``` Lädt ein neues Bundle von der angegebenen URL herunter, es sollte eine ZIP-Datei sein, mit Dateien innerhalb oder mit einer eindeutigen ID innerhalb mit all Ihren Dateien | Param | Type | Description | | ------------- | ----------------- | --------------------------------------------------------------------------------------------- | | **`options`** | `DownloadOptions` | Die {@link [DownloadOptions](#downloadoptions)} für das Herunterladen eines neuen Bundle-ZIPs | **Returns:** `Promise` *** ## next() ```typescript next(options: BundleId) => Promise ``` Legt das nächste Bundle fest, das verwendet werden soll, wenn die App neu geladen wird| Param | Type | Beschreibung | | ------------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | Enthält die ID des nächsten Bundles, das beim nächsten App-Start gesetzt wird {@link [BundleInfoid](#bundleinfo)} | **Returns:** `Promise` *** ## set() ```typescript set(options: BundleId) => Promise ``` Setzt das aktuelle Bundle und lädt die App sofort neu | Param | Type | Beschreibung | | ------------- | ---------- | ------------------------------------------------------------------------ | | **`options`** | `BundleId` | Ein {@link [BundleId](#bundleid)} Objekt, das die neue Bundle-ID enthält | *** ## delete() ```typescript delete(options: BundleId) => Promise ``` Löscht das angegebene Bundle aus dem nativen App-Speicher. Verwenden Sie {@link list} um die gespeicherten Bundle-IDs zu erhalten | Param | Type | Beschreibung | | ------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | **`options`** | `BundleId` | Ein {@link [BundleId](#bundleid)} Objekt, das die ID des zu löschenden Bundles enthält (Hinweis: dies ist die Bundle-ID, NICHT der Versionsname) | *** ## list() ```typescript list(options?: ListOptions | undefined) => Promise ``` Alle lokal heruntergeladenen Bundles in Ihrer App abrufen | Param | Type | Beschreibung | | ------------- | ------------- | --------------------------------------------------------------------- | | **`options`** | `ListOptions` | Die {@link [ListOptions](#listoptions)} für das Auflisten von Bundles | **Returns:** `Promise` *** ## reset() ```typescript reset(options?: ResetOptions | undefined) => Promise ``` Setzt die App auf das ‘builtin’ Bundle (das an den Apple App Store / Google Play Store gesendet wurde) oder das zuletzt erfolgreich geladene Bundle zurück | Param | Type | Beschreibung | | ------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **`options`** | `ResetOptions` | Enthält {@link [ResetOptionstoLastSuccessful](#resetoptions)}, `true` setzt auf das builtin Bundle zurück und `false` setzt auf das zuletzt erfolgreich geladene Bundle zurück | *** ## current() ```typescript current() => Promise ``` Ruft das aktuelle Bundle ab, wenn keines gesetzt ist, wird ‘builtin’ zurückgegeben. currentNative ist das ursprünglich auf dem Gerät installierte Bundle **Returns:** `Promise` *** ## reload() ```typescript reload() => Promise ``` Die Ansicht neu laden *** ## setMultiDelay() ```typescript setMultiDelay(options: MultiDelayConditions) => Promise ``` Setzt ein {@link [DelayCondition](#delaycondition)} Array mit Bedingungen, die das Plugin verwendet, um das Update zu verzögern Nachdem alle Bedingungen erfüllt sind, wird der Update-Prozess wie gewohnt neu gestartet, sodass das Update nach dem Hintergrundsetzen oder Beenden der App installiert wird Für die Art ‘date’ sollte der Wert ein iso8601-Datums-String sein Für die Art ‘background’ sollte der Wert eine Zahl in Millisekunden sein Für die Art ‘nativeVersion’ sollte der Wert die Versionsnummer sein Für die Art ‘kill’ wird der Wert nicht verwendet Die Funktion hat inkonsistentes Verhalten: Die Option kill löst das Update nach dem ersten Beenden aus und nicht nach dem nächsten Hintergrundsetzen wie andere Optionen. Dies wird in einem zukünftigen Major Release behoben | Param | Type | Beschreibung | | ------------- | ---------------------- | --------------------------------------------------------------------------------------- | | **`options`** | `MultiDelayConditions` | Enthält das {@link [MultiDelayConditions](#multidelayconditions)} Array von Bedingungen | **Seit:** 430 *** ## cancelDelay() ```typescript cancelDelay() => Promise ``` Bricht eine {@link [DelayCondition](#delaycondition)} ab, um ein Update sofort zu verarbeiten **Seit:** 400 *** ## getLatest() ```typescript getLatest(options?: GetLatestOptions | undefined) => Promise ``` Neuestes verfügbares Bundle von der Update-URL abrufen | Param | Type | | ------------- | ------------------ | | **`options`** | `GetLatestOptions` | **Returns:** `Promise` **Seit:** 400 *** ## setChannel() ```typescript setChannel(options: SetChannelOptions) => Promise ``` Setzt den Kanal für dieses Gerät. Der Kanal muss Selbstzuweisung erlauben, damit dies funktioniert Verwenden Sie diese Methode nicht, um den Kanal beim Start zu setzen, wenn `autoUpdate` in der {@link PluginsConfig} aktiviert ist Diese Methode dient dazu, den Kanal zu setzen, nachdem die App bereit ist Diese Methode sendet eine Anfrage an den Capgo-Backend, um die Geräte-ID mit dem Kanal zu verknüpfen. Capgo kann dies je nach den Einstellungen Ihres Kanals akzeptieren oder ablehnen | Param | Type | Beschreibung | | ------------- | ------------------- | ----------------------------------------------------------------------- | | **`options`** | `SetChannelOptions` | Ist die {@link [SetChannelOptions](#setchanneloptions)} Kanal zu setzen | **Returns:** `Promise` **Seit:** 470 *** ## unsetChannel() ```typescript unsetChannel(options: UnsetChannelOptions) => Promise ``` Hebt die Einstellung des Kanals für dieses Gerät aufDas Gerät kehrt dann zum Standardkanal zurück | Param | Type | | ------------- | --------------------- | | **`options`** | `UnsetChannelOptions` | **Seit:** 470 *** ## getChannel() ```typescript getChannel() => Promise ``` Rufe den Kanal für dieses Gerät ab **Returns:** `Promise` **Seit:** 480 *** ## setCustomId() ```typescript setCustomId(options: SetCustomIdOptions) => Promise ``` Lege eine benutzerdefinierte ID für dieses Gerät fest | Param | Type | Description | | ------------- | -------------------- | ----------------------------------------------------------------------------- | | **`options`** | `SetCustomIdOptions` | ist die {@link [SetCustomIdOptions](#setcustomidoptions)} customId zum Setzen | **Seit:** 490 *** ## getBuiltinVersion() ```typescript getBuiltinVersion() => Promise ``` Rufe die native App-Version oder die in der Konfiguration festgelegte Builtin-Version ab **Returns:** `Promise` **Seit:** 520 *** ## getDeviceId() ```typescript getDeviceId() => Promise ``` Rufe eindeutige ID ab, die zur Identifizierung des Geräts verwendet wird (wird an den Auto-Update-Server gesendet) **Returns:** `Promise` *** ## getPluginVersion() ```typescript getPluginVersion() => Promise ``` Rufe die native Capacitor Updater Plugin-Version ab (wird an den Auto-Update-Server gesendet) **Returns:** `Promise` *** ## isAutoUpdateEnabled() ```typescript isAutoUpdateEnabled() => Promise ``` Rufe den Status der Auto-Update-Konfiguration ab **Returns:** `Promise` *** ## removeAllListeners() ```typescript removeAllListeners() => Promise ``` Entferne alle Listener für dieses Plugin **Seit:** 100 *** ## addListener(‘download’, ) ```typescript addListener(eventName: 'download', listenerFunc: (state: DownloadEvent) => void) => Promise ``` Höre auf Bundle-Download-Events in der App. Wird ausgelöst, wenn ein Download startet, während des Downloads und wenn er abgeschlossen ist | Param | Type | | ------------------ | -------------------------------- | | **`eventName`** | `’download’` | | **`listenerFunc`** | `(state: DownloadEvent) => void` | **Returns:** `Promise` **Seit:** 2011 *** ## addListener(‘noNeedUpdate’, ) ```typescript addListener(eventName: 'noNeedUpdate', listenerFunc: (state: NoNeedEvent) => void) => Promise ``` Höre auf Events, wenn kein Update benötigt wird. Nützlich, wenn bei jedem App-Start eine Überprüfung erzwungen werden soll | Param | Type | | ------------------ | ------------------------------ | | **`eventName`** | `’noNeedUpdate’` | | **`listenerFunc`** | `(state: NoNeedEvent) => void` | **Returns:** `Promise` **Seit:** 400 *** ## addListener(‘updateAvailable’, ) ```typescript addListener(eventName: 'updateAvailable', listenerFunc: (state: UpdateAvailableEvent) => void) => Promise ``` Höre auf verfügbare Update-Events. Nützlich, wenn bei jedem App-Start eine Überprüfung erzwungen werden soll | Param | Type | | ------------------ | --------------------------------------- | | **`eventName`** | `’updateAvailable’` | | **`listenerFunc`** | `(state: UpdateAvailableEvent) => void` | **Returns:** `Promise` **Seit:** 400 *** ## addListener(‘downloadComplete’, ) ```typescript addListener(eventName: 'downloadComplete', listenerFunc: (state: DownloadCompleteEvent) => void) => Promise ``` Höre auf downloadComplete Events | Param | Type | | ------------------ | ---------------------------------------- | | **`eventName`** | `’downloadComplete’` | | **`listenerFunc`** | `(state: DownloadCompleteEvent) => void` | **Returns:** `Promise` **Seit:** 400 *** ## addListener(‘majorAvailable’, ) ```typescript addListener(eventName: 'majorAvailable', listenerFunc: (state: MajorAvailableEvent) => void) => Promise ``` Höre auf Major-Update-Events in der App. Informiert dich, wenn ein Major-Update durch die Einstellung disableAutoUpdateBreaking blockiert wird | Param | Type | | ------------------ | -------------------------------------- | | **`eventName`** | `’majorAvailable’` | | **`listenerFunc`** | `(state: MajorAvailableEvent) => void` | **Returns:** `Promise` **Seit:** 230 *** ## addListener(‘updateFailed’, ) ```typescript addListener(eventName: 'updateFailed', listenerFunc: (state: UpdateFailedEvent) => void) => Promise ``` Höre auf Update-Fehlschlag-Events in der App. Informiert dich, wenn ein Update beim nächsten App-Start nicht installiert werden konnte | Param | Type | | ------------------ | ------------------------------------ | | **`eventName`** | `’updateFailed’` | | **`listenerFunc`** | `(state: UpdateFailedEvent) => void` | **Returns:** `Promise` **Seit:** 230 *** ## addListener(‘downloadFailed’,\`\`\`typescript addListener(eventName: ‘downloadFailed’, listenerFunc: (state: DownloadFailedEvent) => void) => Promise ````plaintext Lauschen Sie auf das Download-Fehlerereignis in der App, das Sie darüber informiert, wenn ein Bundle-Download fehlgeschlagen ist | Param | Typ | |--------------|----------------------------------------------------------------------------------------| | **`eventName`** | 'downloadFailed' | | **`listenerFunc`** | (state: DownloadFailedEvent) => void | **Gibt zurück:** Promise<PluginListenerHandle> **Seit:** 400 -------------------- ## addListener('appReloaded', ) ```typescript addListener(eventName: 'appReloaded', listenerFunc: () => void) => Promise ```` Lauschen Sie auf das Neuladen-Ereignis in der App, das Sie darüber informiert, wenn ein Neuladen stattgefunden hat | Param | Typ | | ------------------ | --------------- | | **`eventName`** | `’appReloaded’` | | **`listenerFunc`** | `() => void` | **Gibt zurück:** `Promise` **Seit:** 430 *** ## addListener(‘appReady’, ) ```typescript addListener(eventName: 'appReady', listenerFunc: (state: AppReadyEvent) => void) => Promise ``` Lauschen Sie auf das App-Bereit-Ereignis in der App, das Sie darüber informiert, wenn die App einsatzbereit ist | Param | Typ | | ------------------ | -------------------------------- | | **`eventName`** | `’appReady’` | | **`listenerFunc`** | `(state: AppReadyEvent) => void` | **Gibt zurück:** `Promise` **Seit:** 510 *** ## isAutoUpdateAvailable() ```typescript isAutoUpdateAvailable() => Promise ``` Prüfen Sie, ob automatische Aktualisierung verfügbar ist (nicht durch serverUrl deaktiviert) **Gibt zurück:** `Promise` *** ## getNextBundle() ```typescript getNextBundle() => Promise ``` Ruft das nächste Bundle ab, das beim Neuladen der App verwendet wird Gibt null zurück, wenn kein nächstes Bundle festgelegt ist **Gibt zurück:** `Promise` **Seit:** 680 *** ## Interfaces ### AppReadyResult | Eigenschaft | Typ | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | ### BundleInfo | Eigenschaft | Typ | | ---------------- | -------------- | | **`id`** | `string` | | **`version`** | `string` | | **`downloaded`** | `string` | | **`checksum`** | `string` | | **`status`** | `BundleStatus` | ### UpdateUrl | Eigenschaft | Typ | | ----------- | -------- | | **`url`** | `string` | ### StatsUrl | Eigenschaft | Typ | | ----------- | -------- | | **`url`** | `string` | ### ChannelUrl | Eigenschaft | Typ | | ----------- | -------- | | **`url`** | `string` | ### DownloadOptions | Eigenschaft | Typ | Beschreibung | Standard | Seit | | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ---- | | **`url`** | `string` | Die URL der Bundle-ZIP-Datei (z.B. distzip), die heruntergeladen werden soll (Dies kann eine beliebige URL sein, z.B. Amazon S3, ein GitHub-Tag oder ein anderer Ort, an dem Sie Ihr Bundle gehostet haben) | | | | **`version`** | `string` | Der Versions-Code/Name dieses Bundles/dieser Version | | | | **`sessionKey`** | `string` | Der Sitzungsschlüssel für das Update | `undefined` | 400 | | **`checksum`** | `string` | Die Prüfsumme für das Update | `undefined` | 400 | ### BundleId | Eigenschaft | Typ | | ----------- | -------- | | **`id`** | `string` | ### BundleListResult | Eigenschaft | Typ | | ------------- | -------------- | | **`bundles`** | `BundleInfo[]` | ### ListOptions | Eigenschaft | Typ | Beschreibung | Standard | Seit | | ----------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ---- | | **`raw`** | `boolean` | Ob die rohe Bundle-Liste oder das Manifest zurückgegeben werden soll. Wenn true, wird versucht, die interne Datenbank anstelle von Dateien auf der Festplatte zu lesen | `false` | 6140 | ### ResetOptions | Eigenschaft | Typ | | ---------------------- | --------- | | **`toLastSuccessful`** | `boolean` | ### CurrentBundleResult | Eigenschaft | Typ | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | | **`native`** | `string` | ### MultiDelayConditions | Eigenschaft | Typ | | --------------------- | ------------------ | | **`delayConditions`** | `DelayCondition[]` | ### DelayCondition | Eigenschaft | Typ | Beschreibung | | ----------- | ---------------- | --------------------------------------------------- | | **`kind`** | `DelayUntilNext` | Verzögerungsbedingungen in setMultiDelay einrichten | | **`value`** | `string` | | ### LatestVersion | Eigenschaft | Typ | Beschreibung | Seit | | ---------------- | ----------------- | ------------------------------ | ---- | | **`version`** | `string` | Ergebnis der getLatest-Methode | 400 | | **`checksum`** | `string` | | 6 | | **`major`** | `boolean` | | | | **`message`** | `string` | | | | **`sessionKey`** | `string` | | | | **`error`** | `string` | | | | **`old`** | `string` | | | | **`url`** | `string` | | | | **`manifest`** | `ManifestEntry[]` | | 61 | ### ManifestEntry | Eigenschaft | Typ | | ------------------ | ---------------- | | **`file_name`** | `string \| null` | | **`file_hash`** | `string \| null` | | **`download_url`** | `string \| null` | ### GetLatestOptions | Eigenschaft | Typ | Beschreibung | Standard | Seit | | ------------- | -------- | --------------------------------------------------------------------------------------------------------------------------- | ----------- | ---- | | **`channel`** | `string` | Der Kanal, für den die neueste Version abgerufen werden soll. Der Kanal muss ‘self\_assign’ für die Funktionalität erlauben | `undefined` | 680 | ### ChannelRes | Eigenschaft | Typ | Beschreibung | Seit | | ------------- | -------- | --------------------------- | ---- | | **`status`** | `string` | Aktueller Status des Kanals | 470 | | **`error`** | `string` | | | | **`message`** | `string` | | | ### SetChannelOptions | Eigenschaft | Typ | | ----------------------- | --------- | | **`channel`** | `string` | | **`triggerAutoUpdate`** | `boolean` | ### UnsetChannelOptions | Eigenschaft | Typ | | ----------------------- | --------- | | **`triggerAutoUpdate`** | `boolean` | ### GetChannelRes | Eigenschaft | Typ | Beschreibung | Seit | | -------------- | --------- | --------------------------- | ---- | | **`channel`** | `string` | Aktueller Status des Kanals | 480 | | **`error`** | `string` | | | | **`message`** | `string` | | | | **`status`** | `string` | | | | **`allowSet`** | `boolean` | | | ### SetCustomIdOptions | Eigenschaft | Typ | | -------------- | -------- | | **`customId`** | `string` | ### BuiltinVersion | Eigenschaft | Typ | | ------------- | -------- | | **`version`** | `string` | ### DeviceId | Eigenschaft | Typ | | -------------- | -------- | | **`deviceId`** | `string` | ### PluginVersion | Eigenschaft | Typ | | ------------- | -------- | | **`version`** | `string` | ### AutoUpdateEnabled | Eigenschaft | Typ | | ------------- | --------- | | **`enabled`** | `boolean` | ### PluginListenerHandle | Eigenschaft | Typ | | ------------ | --------------------- | | **`remove`** | `() => Promise` | ### DownloadEvent | Eigenschaft | Typ | Beschreibung | Seit | | ------------- | ------------ | --------------------------------------------- | ---- | | **`percent`** | `number` | Aktueller Download-Status, zwischen 0 und 100 | 400 | | **`bundle`** | `BundleInfo` | | | ### NoNeedEvent | Eigenschaft | Typ | Beschreibung | Seit | | ------------ | ------------ | --------------------------------------------- | ---- | | **`bundle`** | `BundleInfo` | Aktueller Download-Status, zwischen 0 und 100 | 400 | ### UpdateAvailableEvent | Eigenschaft | Typ | Beschreibung | Seit | | ------------ | ------------ | --------------------------------------------- | ---- | | **`bundle`** | `BundleInfo` | Aktueller Download-Status, zwischen 0 und 100 | 400 | ### DownloadCompleteEvent | Eigenschaft | Typ | Beschreibung | Seit | | ------------ | ------------ | --------------------------------------------- | ---- | | **`bundle`** | `BundleInfo` | Wird ausgelöst, wenn ein Update verfügbar ist | 400 | ### MajorAvailableEvent | Eigenschaft | Typ | Beschreibung | Seit | | ------------- | -------- | --------------------------------------------------- | ---- | | **`version`** | `string` | Wird ausgelöst, wenn ein Major-Update verfügbar ist | 400 | ### UpdateFailedEvent | Eigenschaft | Typ | Beschreibung | Seit | | ------------ | ------------ | -------------------------------------------------- | ---- | | **`bundle`** | `BundleInfo` | Wird ausgelöst, wenn ein Update fehlgeschlagen ist | 400 | ### DownloadFailedEvent | Eigenschaft | Typ | Beschreibung | Seit | | ------------- | -------- | --------------------------------------------- | ---- | | **`version`** | `string` | Wird ausgelöst, wenn ein Download fehlschlägt | 400 | ### AppReadyEvent | Eigenschaft | Typ | Beschreibung | Seit | | ------------ | ------------ | --------------------------------------- | ---- | | **`bundle`** | `BundleInfo` | Wird ausgelöst, wenn die App bereit ist | 520 | | **`status`** | `string` | | | ### AutoUpdateAvailable | Eigenschaft | Typ | | --------------- | --------- | | **`available`** | `boolean` | ## Type Aliases ### BundleStatus `‘success’ | ‘error’ | ‘pending’ | ‘downloading’` ### DelayUntilNext `‘background’ | ‘kill’ | ‘nativeVersion’ | ‘date’` # Auto actualización > So verwenden Sie die automatische Aktualisierung mit capacitor-updater Here’s the German translation: Dieser Modus ermöglicht Entwicklern die Verwendung von capacitor-updater im Auto-Update-Modus und das Pushen von Updates über Capgo-Kanäle oder Äquivalente. ### Voraussetzungen Stellen Sie sicher, dass Ihre App-Version verwendet, bevor Sie Capgo Auto-Update nutzen. Dies ist die Konvention, die verwendet wird, um Versionen in Capgo zu verwalten. Es gibt zwei Möglichkeiten, die Version in Ihrer App festzulegen: Neue Methode: Verwenden Sie das `version`-Feld in Ihrer `capacitorconfigjson`-Datei ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true, // Auto-Update aktivieren, standardmäßig true "appId": "comexampleapp", // Wird zur Identifizierung der App auf dem Server verwendet "version": "100" // Wird zur Überprüfung auf Updates verwendet } } } ``` Diese Optionen werden vom Plugin zur Überprüfung auf Updates und von der CLI zum Hochladen der Version verwendet. Alte Methode: In 3 Dateien in Ihrem Projekt: * `packagejson` in **version** * `android/app/buildgradle` in **versionName** * `ios/App/Appxcodeproj/projectpbxproj` in **CURRENT\_PROJECT\_VERSION** ### Tutorials Richten Sie Ihre App in 5 Minuten ein [Aktualisieren Sie Ihre Capacitor-Apps nahtlos mit Capacitor Updater](https://capgo.app/blog/update-your-capacitor-apps-seamlessly-using-capacitor-updater) Richten Sie Ihre CI in 5 Minuten ein [Automatischer Build und Release mit GitHub Actions](https://capgo.app/blog/automatic-build-and-release-with-github-actions) ### Installation ```bash npm install @capgo/capacitor-updater npx cap sync ``` ### Einführung Klicken Sie auf [Registrieren](https://capgo.app), um Ihr Konto zu erstellen Der Server ermöglicht es Ihnen, Kanäle und Versionen und vieles mehr zu verwalten `autoUpdate` verwendet Daten aus `capacitorconfig`, um den Capgo-Server zu identifizieren Note Sie können Capgo Cloud weiterhin nutzen, ohne Ihren Code an unseren Server zu senden, falls dies von Ihrem Unternehmen nicht erlaubt ist #### Version validieren Wenn Auto-Update eingerichtet ist, müssen Sie von JavaScript aus mitteilen, dass Ihre App aktiv und bereit ist Dies kann durch den Aufruf von `notifyAppReady` in Ihrer App erfolgen Tun Sie dies so früh wie möglich ```ts import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdaternotifyAppReady() ``` #### Benutzer-Ablauf * Benutzer öffnet die App, die App ruft den Server ab, um nach Updates zu suchen, wenn Updates gefunden werden, werden sie im Hintergrund heruntergeladen * Benutzer verlässt die App, die neue Version wird als aktiv gesetzt * Benutzer öffnet die App erneut, wir laden die neue aktive Version und setzen sie als Standard * Wenn `notifyAppReady()` aufgerufen wird, wird die vorherige Version gelöscht, wenn der Benutzer die App verlässt * Benutzer setzt den normalen App-Ablauf fort bis zum nächsten Update-Zyklus Danger ⚠️ Wenn Sie `notifyAppReady()` nicht in Ihrer App aufrufen, wird die aktuelle Version als ungültig markiert und auf das vorherige gültige Bundle oder die Standardversion zurückgesetzt #### Entwickler-Ablauf Wenn Sie neue Funktionen entwickeln, stellen Sie sicher, dass Sie `autoUpdate` blockieren, da Capgo sonst ständig Ihre Arbeit mit dem neuesten Update-Bundle überschreibt Setzen Sie `autoUpdate` in Ihrer Konfiguration auf false Falls Sie aus irgendeinem Grund bei einem Update festhängen, können Sie die App löschen und neu installieren Stellen Sie sicher, dass Sie `autoUpdate` in Ihrer Konfiguration auf false setzen, bevor Sie dies tun Und bauen Sie sie dann erneut mit Xcode oder Android Studio Um die Version bei jedem Commit hochzuladen, richten Sie CI/CD mit dieser Anleitung ein [Automatischer Build und Release mit GitHub Actions](https://capgo.app/blog/automatic-build-and-release-with-github-actions) #### Major Available Event Wenn `disableAutoUpdateBreaking` auf true gesetzt ist, können Sie auf das Event hören, um zu erfahren, wann die App sich weigert, ein Major Breaking Update durchzuführen ```jsx import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdateraddListener('majorAvailable', (info: any) => { consolelog('majorAvailable wurde ausgelöst', infoversion) }) ``` # Kanalsystem > Wie man das Kanal-System mit capacitor-updater verwendet Capgo und capacitor-updater verfügen über ein leistungsstarkes Kanalsystem ## Was Sie mit Kanälen machen können: * Geräte einem Kanal für Entwicklung und Beta-Tests zuordnen * Einen Kanal pro Entwicklungszweig verwenden und Ihr Team sich selbst vom Telefon aus zuweisen lassen ## Geräte einem Kanal zuweisen: * Den Kanal als Standard festlegen, jedes Mal wenn ein neues Gerät Capgo nach einem Update fragt, wird dieser Kanal antworten * Die **deviceId** (mit der [**getDeviceId**](/docs/plugin/api#getdeviceid) Methode) an Ihr Backend senden und sie über die Capgo Public API zuweisen * Den Kanal selbst zuweisbar machen (mit der [**setChannel**](/docs/plugin/api#setchannel) Methode) und das Gerät den Kanal abonnieren lassen (mit oder ohne Benutzerinteraktion) mit der `setChannel` Methode des Plugins * Die Option `defaultChannel` in der [Konfiguration](/docs/plugin/settings#defaultchannel) verwenden, um den Standardkanal für alle Geräte mit dieser Plugin-Konfiguration festzulegen Note Sie können ein Gerät auch direkt einem Bundle zuweisen ## Kanal-Optionen ![](/channel_setting_1.webp) Details zu jeder Option: | Option | Beschreibung | | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | | **Automatisches Downgrade unter Native deaktivieren** | Kein Update senden, wenn die native Version der App größer ist als die Kanalversion | | **Automatisches Upgrade über Major deaktivieren** | Kein Update senden, wenn die native Version der App niedriger ist als ein Major (**1**23) der Kanalversion | | **Automatisches Upgrade über Minor deaktivieren** | Kein Update senden, wenn die native Version der App niedriger ist als ein Minor (1**2**3) der Kanalversion | | **Gerät darf sich selbst zuweisen** | Ein Gerät darf die `setChannel` Methode für diesen Kanal verwenden | | **iOS** | iOS-Geräten erlauben, Updates von diesem Kanal herunterzuladen | | **Android** | Android-Geräten erlauben, Updates von diesem Kanal herunterzuladen | | **Emulator erlauben** | Emulatoren erlauben, Updates von diesem Kanal zu empfangen | | **Entwicklungs-Build erlauben** | Entwicklungs-Builds erlauben, Updates von diesem Kanal zu empfangen | Note Capgo führt automatisch einige Filterungen für Sie durch. Wenn Sie eine CI/CD konfiguriert haben, die Ihre Version an Google Play sendet, wird Google Play Ihre App jedes Mal auf über 20 echten Geräten ausführen. Während der ersten 4 Stunden eines neuen Bundles blockieren wir Google-Datencenter-IPs, um zu verhindern, dass diese in Ihren Statistiken gezählt werden Note Capgo zählt Emulatoren und Entwicklungs-Builds **nicht** in Ihrer Nutzung, aber beachten Sie, dass Sie nicht mehr als 3% davon haben können, sonst wird Ihr Konto gesperrt, bis Sie dies beheben # Erste Schritte > Installiere das Plugin in deiner App ## Einführung in Capgo [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## Live-Updates sind 3 Schritte entfernt ### Konto erstellen Besuchen Sie unsere Registrierungsseite unter ![onboarding screenshot](/onboard.webp "onboarding screenshot") ### Installieren Sie Capgo mit der CLI Verwenden Sie die magischen Befehle, um loszulegen ```bash npx @capgo/cli@latest init [APIKEY] ``` Dieser Befehl führt Sie durch den Einrichtungsprozess ### Folgen Sie einfach den Anweisungen In der CLI werden Ihnen eine Reihe von Fragen gestellt. Beantworten Sie die notwendigen Fragen, um die automatische Einrichtung abzuschließen Tip Wenn Sie diese Schritte befolgen, sind Sie im Handumdrehen einsatzbereit. Falls Sie während des Prozesses weitere Unterstützung benötigen, steht Ihnen unser Support-Team zur Verfügung. Viel Spaß beim Onboarding! ### Genießen Sie die Magie von Capgo! Testen Sie Ihre App und lernen Sie später, wie Sie die Power-Features von Capgo nutzen können # Mise à jour hybride > Update-Methoden für automatische Updates Beim Pushen von Updates an Ihre Benutzer haben Sie mehrere Möglichkeiten, den Update-Zyklus nach Ihren Vorstellungen zu handhaben, bevor Sie sie anwenden * Stilles Update * Auf `updateAvailable` Event hören * Modalfenster anzeigen oder Updates verzögern ## Stilles Update Sie können einen Update-Zyklus bei jedem App-Start erzwingen, indem Sie `directUpdate` auf `true` setzen. Dies löst den Update-Zyklus wie gewohnt ohne Benutzerinteraktion aus ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "directUpdate": true, }, "SplashScreen": { "launchAutoHide": false, } } } ``` In Ihrer App sollten Sie dann den Splash Screen ausblenden, wenn Sie das Event `appReady` empfangen: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' CapacitorUpdateraddListener('appReady', () => { // Hide splash SplashScreenhide() }) CapacitorUpdaternotifyAppReady() ``` ## Erzwungenes Update Fügen Sie einen Listener für das Event `updateAvailable` hinzu und zeigen Sie dann eine Benachrichtigung an, um den Benutzer über das Update zu informieren: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { Dialog } from '@capacitor/dialog' CapacitorUpdateraddListener('updateAvailable', async (res) => { try { await Dialogalert({ title: 'Update verfügbar', message: `Version ${resbundleversion} ist verfügbar. Die App wird jetzt aktualisiert`, }) CapacitorUpdaterset(resbundle) } catch (error) { consolelog(error) } }) CapacitorUpdaternotifyAppReady() ``` ## Modal Update Sie können den Benutzer auch entscheiden lassen, indem Sie einen Dialog anzeigen, der nach dem Update fragt: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { Dialog } from '@capacitor/dialog' CapacitorUpdateraddListener('updateAvailable', async (res) => { try { const { value } = await Dialogconfirm({ title: 'Update verfügbar', message: `Version ${resbundleversion} ist verfügbar. Möchten Sie jetzt aktualisieren?`, }) if (value) CapacitorUpdaterset(resbundle) } catch (error) { consolelog(error) } }) CapacitorUpdaternotifyAppReady() ``` # 手動更新 > Wie Sie ein Update selbst durchführen Wenn Sie selbst steuern möchten, wann Updates angewendet werden, verwenden Sie den manuellen Modus mit Capgo Cloud Hier ist, was Sie tun müssen: Richten Sie Ihr Konto ein, wie in Erste Schritte erklärt [Erste Schritte ](/docs/getting-started/quickstart/) #### Konfiguration Deaktivieren Sie das automatische Update in Ihrer `capacitor.config.json` ```tsx // capacitor.config.json { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` Fügen Sie dann die Logik hinzu, um Updates selbst zu verwalten\ Hier ist ein Beispiel, wie Sie das machen können: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater' import type { BundleInfo } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' CapacitorUpdater.notifyAppReady() let data: BundleInfo | null = null App.addListener('appStateChange', async (state: any) => { console.log('appStateChange', state) if (state.isActive) { console.log('getLatest') // Führen Sie den Download durch, während die App aktiv genutzt wird, um fehlgeschlagene Downloads zu vermeiden const latest = await CapacitorUpdater.getLatest() console.log('latest', latest) if (latest.url) { data = await CapacitorUpdater.download(latest) console.log('download', data) } } if (!state.isActive && data) { console.log('set') // Führen Sie den Wechsel durch, wenn der Benutzer die App verlässt oder wenn Sie es möchten SplashScreen.show() try { await CapacitorUpdater.set({ id: data.id }) } catch (err) { console.log(err) SplashScreen.hide() // falls das Setzen fehlschlägt, andernfalls muss die neue App es ausblenden } } }) ``` Dokumentation aller verfügbaren APIs im Plugin: [Methoden ](/docs/plugin/api/) Es gibt einige Anwendungsfälle, bei denen Sie Benutzern erlauben können, Kanäle zu abonnieren und verschiedene Versionen zu testen:\ # Cordova > Wird capacitor-updater auf Cordova verfügbar sein? Sie haben sich gefragt, ob dieses Plugin jemals für Cordova verfügbar sein wird Ich habe ein F\&E-Repository dafür begonnen, aber es ist eine enorme Arbeitsmenge ## Probleme Ich weiß, dass ich es kann, aber dafür muss ich den gesamten Code der Cordova-Codebasis lesen, wie ich es für Capacitor getan habe, um zu verstehen, wie ich es zum Laufen bringe Die Android-Version ist einfacher zu erstellen, da beide Java verwenden, aber iOS benötigt eine komplette Neuschreibung, da Swift in Cordova noch nicht gut unterstützt wird ## Lösung In der Zwischenzeit können Sie Folgendes tun: * [Unterstützen Sie mich](https://github.com/sponsors/riderx) auf GitHub und ich kann das priorisieren. Dies wird mindestens 1 Monat Arbeit benötigen * Engagieren Sie mich als Berater, ich habe früher großen Unternehmen bei der Migration zu Capacitor geholfen, es dauert normalerweise \~10-20 Tage und der [Nutzen](https://ionicio/resources/articles/capacitor-vs-cordova-modern-hybrid-app-development) ist enorm für das Team # Debugging > So debuggen Sie Ihre App ## Cloud-Logs verstehen: ### Vom Backend gesendet | Code | Beschreibung | | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **InvalidIp** | Der Benutzer befindet sich in einem Google-Rechenzentrum und das Update ist weniger als 4 Stunden alt. Dies verhindert, dass Google-Bot-Geräte als Geräte in Ihrem Konto gezählt werden | | **needPlanUpgrade** (früher **needUpgrade**) | Zeigt an, dass Sie das Limit Ihres Plans erreicht haben und das Gerät keine Updates erhält, bis Sie upgraden oder bis zum nächsten Monat | | **noNew** | Das Gerät hat die neueste verfügbare Version | | **disablePlatformIos** | Das Gerät läuft auf der iOS-Plattform, aber diese ist in den Kanaleinstellungen deaktiviert | | **disablePlatformAndroid** | Das Gerät läuft auf der Android-Plattform, aber diese ist in den Kanaleinstellungen deaktiviert | | **disableAutoUpdate** | ”major" | | **disableAutoUpdateUnderNative** | Das Gerät hat Version (`123`), und der Kanal hat ein Update (`122`) unter der Geräteversion zum Senden, aber dies ist in den Kanaleinstellungen deaktiviert | | **disableDevBuild** | Das Gerät hat einen Dev-Build, aber dies ist in den Kanaleinstellungen deaktiviert | | **disableEmulator** | Das Gerät ist ein Emulator, aber dies ist in den Kanaleinstellungen deaktiviert | ### Vom Gerät gesendet | Code | Beschreibung | | ------------------------- | ------------------------------------------------------------------------------------------- | | **get** | Informationen zum Herunterladen der neuen Version wurden an das Gerät gesendet | | **delete** | Ein Bundle wurde auf dem Gerät gelöscht | | **set** | Ein Bundle wurde auf dem Gerät eingerichtet | | **set\_fail** | Das Bundle konnte nicht eingerichtet werden | | **reset** | Das Gerät wurde auf das `builtin`-Bundle zurückgesetzt | | **download\_XX** | Ein neues Bundle wurde heruntergeladen - Fortschritt angezeigt durch XX% (in 10%-Schritten) | | **download\_complete** | Das neue Bundle wurde vollständig heruntergeladen | | **download\_fail** | Das neue Bundle konnte nicht heruntergeladen werden | | **update\_fail** | Das neue Bundle wurde installiert, konnte aber `notifyAppReady` nicht aufrufen | | **checksum\_fail** | Das neue Bundle konnte die Prüfsumme nicht validieren | | **windows\_path\_fail** | Die ZIP-Datei enthält unzulässige Windows-Pfade | | **canonical\_path\_fail** | Der Pfad der Dateien ist nicht kanonisch | | **directory\_path\_fail** | Es gibt einen Fehler im Pfad der ZIP-Dateien | | **unzip\_fail** | Entpacken fehlgeschlagen | | **low\_mem\_fail** | Download aufgrund von niedrigem Gerätespeicher fehlgeschlagen | ### Bundle-Status * `SUCCESS`: Bundle-Installation abgeschlossen * `ERROR`: Installation oder Download fehlgeschlagen * `PENDING`: Download abgeschlossen, wartet auf Freigabe * `DELETED`: Bundle gelöscht, wird noch für Statistiken angezeigt * `DOWNLOADING`: Bundle wird gerade heruntergeladen ## Geräte-Logs verstehen: ### Debug-Befehl: Es gibt einen Debug-Befehl für Capgo Cloud-Benutzer ```bash npx @capgo/cli@latest app debug ``` Damit können Sie alle Ereignisse in der App überprüfen und eine Lösung finden, wenn Updates nicht funktionieren ### iOS So finden Sie Ihre Logs in Xcode [Getting the Device Log in Xcode ](https://intercomhelp/deploygate/en/articles/4682692-getting-the-device-log-in-xcode) ### Android: So finden Sie Ihre Logs in Android Studio [View logs with Logcat ](https://developerandroidcom/studio/debug/am-logcat) ### Erklärungen zu den Logs * `Failed to download from` **=>** gleich wie **download\_fail** * `notifyAppReady was not called, roll back current bundle` => gleich wie **update\_fail** ## Heruntergeladenes Bundle auf Ihrem Gerät finden ### iOS Zum Debuggen unter iOS müssen Sie die App auf Ihren Computer exportieren. Das geht so: Xcode hat eine eingebaute Funktion zur Überprüfung des Dateisystems von Entwickler-installierten Apps auf einem iOS-Gerät So gehen Sie vor: 1. Verbinden Sie Ihr Gerät mit dem Mac und wählen Sie Fenster > Geräte in der Xcode-Menüleiste 2. Wählen Sie Ihr Gerät im linken Bereich unter Geräte aus 3. Dies zeigt eine Liste der entwicklerinstallierten Apps für dieses Gerät 4. Wählen Sie die App aus, die Sie überprüfen möchten, und klicken Sie auf das Zahnrad-Symbol unten im Bildschirm 5. Hier können Sie das aktuelle Dateisystem durch Auswahl von Container anzeigen oder einen Snapshot davon herunterladen Wenn Sie Container herunterladen wählen, wird ein Snapshot des Dateisystems als xcappdata-Datei heruntergeladen, die Sie durchsuchen können Klicken Sie mit der rechten Maustaste auf diese Datei und wählen Sie Paketinhalt anzeigen, um den Ordner zu öffnen Öffnen Sie den App Data-Ordner, und Sie sollten nun einige Ordner wie Documents, Library, tmp usw. sehen ![image](/ios_debug_update_1.webp) Dann finden Sie eine Version in 2 Ordnern: `library/NoCloud/ionic_built_snapshots` wird nach dem App-Neustart benötigt und `documents/versions` für Hot Reload ### Android Zum Debuggen unter Android müssen Sie über Android Studio auf das Gerät zugreifen: 1. Klicken Sie auf Ansicht > Werkzeugfenster > Gerätedatei-Explorer oder klicken Sie auf die Schaltfläche Gerätedatei-Explorer in der Werkzeugleiste 2. Wählen Sie ein Gerät aus der Dropdown-Liste 3. Öffnen Sie den Pfad **data/data/APP\_NAME/** wobei **APP\_NAME Ihre App-ID ist** ![image](/android_debug_update.webp) Dann finden Sie den Ordner `versions`, um alle Versionen zu sehen Wussten Sie? Unter Android werden alle Versionen in einem Ordner gespeichert, anders als bei iOS, wo sie an zwei Stellen dupliziert werden müssen ## iOS Produktions-Absturzprotokolle verstehen [How to review your app's crash logs ](https://developer.apple.com/news/?id=nra79npr) # Nuxt 2 > So installierst du das Plugin in Nuxt 2 # Installation in Nuxt 2 Erstelle eine Plugin-Datei `capacitor-updaterjs` im `plugins` Verzeichnis ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' export default ({ app }) => { if (processclient) { windowonNuxtReady(() => { CapacitorUpdaternotifyAppReady() }) } } ``` Dies lädt das Plugin auf der Client-Seite und benachrichtigt die App, dass sie bereit ist, Updates zu empfangen # Bekannte Probleme > Bekannte Probleme mit Capacitor und CapGo ## Ionic Live-Reload * Wenn Sie während der Entwicklung die Ionic Live-Reload-Funktion der CLI verwenden, überschreibt diese das Plugin, sodass Sie Ihre Aktualisierungen nicht sehen werden ## Quasar Live-Reload * Es verwendet intern das gleiche System wie Ionic, daher werden Sie Ihre Aktualisierungen nicht sehen ## Fehlgeschlagene Updates * Dies passiert üblicherweise bei großen Updates (> 20MB), ein großer Prozentsatz der Nutzer erhält dann nicht die letzte Version\ Früher mussten Nutzer die App geöffnet halten, bis der Download abgeschlossen war. Jetzt verwenden wir Hintergrund-Downloads, aber diese sind immer noch auf wenige Sekunden begrenzt ## Android ### Download nicht möglich Wir haben einige Probleme mit Geräten in Indien festgestellt und konnten mit Nutzern telefonisch verschiedene DNS-Server testen, was das Problem löste Wenn Sie also Probleme haben, versuchen Sie einen anderen DNS-Server wie Cloudflare oder Google DNS zu verwenden Cloudflare: 1111 und 1001 Google DNS: 8888 und 8844 oder dnsgoogle [How to setup a preferred DNS server on Android? ](https://wwwandroidpolicecom/use-preferred-dns-server-android-tutorial/) ### Self Hosted Wenn Sie ein selbst gehostetes Update bereitstellen, beachten Sie, dass Sie keinen “HTTP”-Endpunkt verwenden können, da dies gegen die Sicherheitsrichtlinien von Android-Apps verstößt. Wenn Sie es trotzdem tun möchten, folgen Sie dieser Anleitung: [How to allow all Network connection types HTTP and HTTPS in Android (9) Pie? ](https://stackoverflow.com/a/51902630/5511370) ### Unzip Unzip-Problem: DEFLATED-Einträge können EXT-Deskriptor haben Wenn Sie Ihr Bundle mit etwas anderem als der CLI gepackt haben, könnte das Format Ihrer ZIP-Datei falsch sein. Bitte verwenden Sie den CLI-Befehl `npx @capgo/cli zip BUNDLE_FOLDER` Dies ist ein bekanntes Problem von Java: [Unzip issue: DEFLATED entries can have EXT descriptor ](https://bugsopenjdkorg/browse/JDK-8143613) ### Cleartext-Problem * Wenn Sie Probleme mit usesCleartextTraffic haben, liegt das daran, dass das Plugin den von Sonar Cloud empfohlenen Best Practices folgt. In 90% der Fälle funktioniert dies einwandfrei, aber bei einigen Plugins kann es zu Problemen führen Um dies zu beheben, fügen Sie in `android/app/src/main/AndroidManifestxml` im ``-Schlüssel folgendes hinzu: ```xml tools:replace="android:usesCleartextTraffic" xmlns:tools="http://schemasandroidcom/tools" ``` ## iOS ### Privacy Manifest Fügen Sie den Dictionary-Schlüssel `NSPrivacyAccessedAPICategoryUserDefaults` zu Ihrem [Privacy Manifest](https://capacitorjs.com/docs/ios/privacy-manifest) hinzu (normalerweise `ios/App/PrivacyInfoxcprivacy`): ```xml NSPrivacyAccessedAPITypes NSPrivacyAccessedAPIType NSPrivacyAccessedAPICategoryUserDefaults NSPrivacyAccessedAPITypeReasons CA921 ``` Wir empfehlen, [`CA921`](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278401) als Grund für den Zugriff auf die [`UserDefaults`](https://developer.apple.com/documentation/foundation/userdefaults) API anzugeben ### Netzwerkberechtigungen Bei der Verwendung eines lokalen Servers zum Testen von Updates wird die App nach Netzwerkberechtigungen fragen. Dies ist ein normales Verhalten und tritt nicht auf, wenn Sie einen Remote-Server verwenden ## Beide Betriebssysteme Bei manuellen Update-Modi sind einige Events nicht einfach abzufangen. Zum Beispiel wird der Update-Fehler kurz bevor Ihr JS-Code neu geladen wird ausgelöst, sodass Sie ihn nicht abfangen können Eine Alternative ist es, die Bundles aufzulisten und die Fehlerstatistiken zu überprüfen, um zu erfahren, ob das Update fehlgeschlagen ist Wir müssen in Zukunft einen besseren Weg finden, dies zu handhaben, aber es hat keine Priorität, da der Auto-Modus die empfohlene Update-Methode ist PRs zur Verbesserung sind willkommen ## CLI Wenn Ihre CLI Probleme bei der Ausführung hat, Prüfen Sie, ob **appId** und **appName** in Ihrer **capacitorconfigts** vorhanden sind Folgen Sie der Anleitung der offiziellen Dokumentation: [Capacitor Configuration ](https://capacitorjs.com/docs/config) # Übersicht > Erläuterung der beiden unterschiedlichen Ansätze ### Cloud Mode (Empfohlen) Der Cloud-Modus ist unsere empfohlene Wahl für eine problemlose Update-Verwaltung. Das Backend von Capgo übernimmt die gesamte Update-Logik und trifft Entscheidungen über Updates serverseitig für bessere Sicherheit und Kontrolle. Dieser Modus steht für Benutzerfreundlichkeit: Einmal eingerichtet, läuft er reibungslos von selbst und bietet erweiterte Funktionen wie Statistiken und Kanäle. Er kann auch in einem manuellen Modus eingerichtet werden, der Ihnen mehr Kontrolle gibt und es Ihnen ermöglicht, mit Ihrem JavaScript-Code zu entscheiden, wann aktualisiert werden soll. Das Backend verwaltet weiterhin, was aktualisiert wird. Dieser Modus teilt viele Vorteile mit dem Auto-Modus, insbesondere bei Sicherheit und erweiterten Funktionen, fügt aber die Flexibilität hinzu, Updates selbst zu terminieren. ### Self Hosted Mode Der Self-Hosted Auto-Modus ist für diejenigen gedacht, die die gesamte Update-Logik auf ihrem Server verwalten möchten. Er bietet vollständige Autonomie, erfordert aber einen separaten Server und mehr Aufwand bei der Verwaltung von Updates und Serveranforderungen. Der Self-Hosted Manual-Modus verbindet Kontrolle und Autonomie. Sie entscheiden über JavaScript, wann aktualisiert wird, aber Ihr Server verwaltet, was aktualisiert wird. Es ist etwas komplex, da Sie Update-Code in die Updates einbinden. Note Wenn Sie sich für das Self-Hosting entscheiden, entgehen Ihnen alle großartigen Funktionen, die Capgo Cloud zu bieten hat, wie z.B.: automatische Rücksetzungen, E-Mail-Benachrichtigungen, Kanäle, Statistiken, Verschlüsselung und mehr. Danger Wenn Sie ein fehlerhaftes Update an Ihre Benutzer senden, können und werden Sie deren App beschädigen. # Pembaruan Otomatis > So verwenden Sie das automatische Update-Plugin im selbst gehosteten Modus Diese Dokumentation erklärt, wie Sie Ihren Auto-Update-Server ausführen können ## Bundle bereitstellen Stellen Sie sicher, dass Ihr Bundle über HTTPS bereitgestellt wird und der Server die richtigen CORS-Header hat, damit die App das Update herunterladen kann z.B. `https://myservercom/app/updates/updatesjson` Wenn Sie mit der Bereitstellung eines Bundles nicht vertraut sind, empfehlen wir Ihnen, Capgo Cloud zu verwenden oder hier ein Beispiel anzusehen: [Bundle bereitstellen ](/docs/self-hosted/auto-update/update-endpoint) ## Konfiguration Fügen Sie eine `updateUrl` zu Ihrer `capacitorconfigjson` hinzu ```json { "plugins": { "CapacitorUpdater": { "updateUrl": "https://myservercom/app/updates/updatesjson", } } } ``` Caution Wenn Sie ein selbst gehostetes Update durchführen, beachten Sie, dass Sie keinen “HTTP”-Endpunkt verwenden können, da dies gegen die Sicherheitsrichtlinien von Android-Apps verstößt. Zu Testzwecken können Sie es [erlauben](https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted) ## Update API Das Plugin führt bei jedem Öffnen der App einen POST-Aufruf an Ihre API durch, mit diesem Body: ```typescript interface AppInfos { "platform": "ios" | "android", "device_id": "UUID_of_device_unique_by_install", "app_id": "APPID_FROM_CAPACITOR_CONFIG", "custom_id": "your_custom_id_set_on_runtime", "plugin_version": "PLUGIN_VERSION", "version_build": "VERSION_NUMBER_FROM_NATIVE_CODE", "version_code": "VERSION_CODE_FROM_NATIVE_CODE", "version_name": "LAST_DOWNLOADER_VERSION" | "builtin" "version_os": "VERSION_OF_SYSYEM_OS", "is_emulator": boolean, "is_prod": boolean, } ``` Die Server-API sollte in JSON dem Capacitor-Updater-Plugin mit diesen Daten antworten, wenn ein Update erforderlich ist: ```json { "version": "123", "url": "https://myservercom/app/updates/my-new-app-200zip" } ``` Im Auto-Update-Modus sollte der Server die Versionen vergleichen und die richtige zurückgeben. Wenn der URL-Schlüssel vorhanden ist, startet das Plugin den Download-Prozess Wenn Sie die Schlüssel “message” und “error” hinzufügen, wird die Version nicht gesetzt, und die Nachricht wird stattdessen in den Logs angezeigt Der `version`-Schlüssel sollte im [`semver`](https://semverorg/)-Format sein Die ZIP-Datei sollte `indexhtml` als Datei im Stammverzeichnis haben oder nur einen Ordner im Stammverzeichnis mit `indexhtml` darin Sie können den Befehl der CLI verwenden, um Ihr Bundle zu zippen: Erstellen Sie ein Bundle mit Ihren Dateien zur Bereitstellung von Ihrem Server ```bash npx @capgo/cli bundle zip --path [/path/to/my/bundle] ``` # Contributing > Beitrag zu capgo Open-Source-Projekten ## Warum beitragen? Zunächst einmal vielen Dank, dass Sie einen Beitrag zu den Open-Source-Projekten von capgo in Erwägung ziehen! Es sind Menschen wie Sie, die capgo Open-Source-Projekte zu so großartigen Werkzeugen machen. Hier sind einige Gründe, warum Sie einen Beitrag leisten sollten: * Die Mitarbeit an capgo Open-Source-Projekten ist eine großartige Möglichkeit, Geld durch die [zahlreichen Bounties](https://console.algora.io/org/Capgo) zu verdienen, die vom capgo-Team angeboten werden * Die Mitarbeit an capgo Open-Source-Projekten ist eine großartige Möglichkeit, eine Funktion hinzuzufügen, die Sie gerne sehen würden * Die Mitarbeit an capgo Open-Source-Projekten ist eine großartige Möglichkeit, einen Bug zu beheben, auf den Sie gestoßen sind * Die [Hauptlizenz von Capgo](https://github.com/Cap-go/capgo/blob/main/LICENSE) verlangt, dass Sie alle Änderungen, die Sie daran vornehmen, als Open Source zur Verfügung stellen. Durch Ihren Codebeitrag können Sie Ihre Änderungen als Open Source behalten und anderen die Nutzung ermöglichen ## Wie man beiträgt * Zunächst müssen Sie das Repository forken, zu dem Sie beitragen möchten * Als Zweites müssen Sie Ihre Änderungen in dieses Repository übertragen und pushen * Zuletzt müssen Sie einen Pull Request erstellen * Das war’s! Jetzt müssen Sie nur noch warten, bis das capgo-Team Ihren PR überprüft ## Weitere zu lesende Dokumente * Capgos [CONTRIBUTING.MD](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTING.md) * Capgos [BOUNTY.md](https://github.com/Cap-go/capgo/blob/main/BOUNTY.md) # Verschlüsselte Bundles > So verwenden Sie das manuelle Update-Plugin im Self-Hosted-Modus ## Ende-zu-Ende-Verschlüsselung Ab Version 4150 ermöglicht das Plugin das Senden verschlüsselter Updates. Beginnen Sie mit der Erstellung eines privaten Schlüssels Create a private key ```bash npx @capgo/cli key create ``` Dann verschlüsseln Sie Ihre ZIP-Datei Encrypt bundled zip ```bash npx @capgo/cli encrypt [path/to/zip] ``` Der Befehl gibt Ihnen einen `ivSessionKey` aus, der mit Ihrem Update-Payload im Schlüssel `session_key` gesendet werden muss ```json { "version": "123", "url": "https://myservercom/app/updates/my-new-app-200zip", "session_key": "encrypted_session_key", } ``` Dann kann Ihre App den privaten Schlüssel verwenden, um den `session_key` zu entschlüsseln und den entschlüsselten `session_key` verwenden, um das Update zu entschlüsseln Erfahren Sie mehr darüber hier: [Self-hosted Live Updates ](https://capgo.app/blog/self-hosted-live-updates/) # Erste Schritte > Selbst-Update-Server ausführen Diese Dokumentation erklärt, wie Sie Ihren eigenen Auto-Update-Server betreiben können ## Einführung Wenn Sie diese Arbeit hilfreich finden, erwägen Sie bitte, meine Arbeit durch eine [Github-Sponsorschaft](https://github.com/sponsors/riderx) zu unterstützen Ich habe mich entschieden, den gesamten hier entwickelten Code Open Source zu machen, anstatt ihn hinter einer Bezahlschranke zu verstecken. Ich glaube, dass wir die Welt zu einem besseren Ort machen können, wenn wir offen sind, anstatt zu kämpfen und uns zu verstecken Darüber hinaus möchte ich mich auf Capgo-Tools konzentrieren und daraus ein offenes und transparentes Unternehmen machen Aber um dies zu ermöglichen, ist es notwendig, dass wir alle unseren Teil dazu beitragen, auch Sie 🥹 Wenn Capgo nicht zu Ihnen passt, dann zahlen Sie Ihren eigenen Preis und [unterstützen Sie einen bootstrapped Maker](https://github.com/sponsors/riderx) zu Ihren Bedingungen [Erwägen Sie einen Beitrag ](/docs/plugin/self-hosted/contributing/) ## Funktionsparität Wenn Sie sich für Ihren eigenen Server entscheiden, verlieren Sie den 5-Minuten-Einrichtungsablauf\ Sie müssen alle diese Funktionen selbst implementieren | Funktionen | Capgo | Selbst gehostet | | ---------------------------- | ----- | --------------- | | Updates | ✅ | 🚧 | | Auto-Rücksetzung | ✅ | 🚧 | | E-Mail-Warnungen bei Fehlern | ✅ | 🚧 | | Kanäle | ✅ | 🚧 | | Kanal-Überschreibungen | ✅ | 🚧 | | Geräte-Überschreibungen | ✅ | 🚧 | | Kanal-Einstellungen | ✅ | 🚧 | | Geräte-Einstellungen | ✅ | 🚧 | | Benutzerdefinierte ID | ✅ | 🚧 | | Auto-Set-Kanäle | ✅ | 🚧 | | API-Kanäle | ✅ | 🚧 | | Update-Statistiken | ✅ | 🚧 | | Download-Fehlerstatistiken | ✅ | 🚧 | | App-Nutzungsstatistiken | ✅ | 🚧 | | Update-Verschlüsselung | ✅ | 🚧 | Danger Wenn Sie ein fehlerhaftes Update an Ihre Benutzer senden, können und werden Sie deren App beschädigen > Beachten Sie, dass Sie nicht gleichzeitig die Capgo-Cloud und Ihren eigenen Server verwenden können Danger Die Over-the-Air (OTA) Update-Funktion gilt nur für Änderungen an HTML-, CSS- und JavaScript-Dateien Wenn Sie Änderungen am nativen Code vornehmen, wie z.B. Updates von Capacitor-Plugins, müssen Sie die Anwendung erneut im App Store zur Genehmigung einreichen ## Wählen Sie zwischen Auto und Manuell Im Auto-Modus wird ein Teil der Logik vom nativen Code verarbeitet, Updates werden serverseitig entschieden, dies ist sicherer und ermöglicht feinkörnige Updates, teilweise Bereitstellung auf einem Gerät oder einer Gruppe und mehr Im manuellen Modus wird die gesamte Logik von JS verarbeitet [Auto Update ](/docs/plugin/self-hosted/auto-update/) [Manuell ](/docs/plugin/self-hosted/manual-update/) ## Capacitor Updater installieren Installieren Sie den Capacitor Updater ```bash npm install @capgo/capacitor-updater npx cap sync ``` ## Bereiten Sie Ihr Bundle vor Um Updates an Ihre App zu senden, müssen Sie sie zippen Der beste Weg, um sicherzustellen, dass Ihr Zip gut ist, ist die Verwendung der Capgo CLI zum Zippen Erstellen Sie ein Bundle mit Ihren Dateien, die von Ihrem Server bereitgestellt werden sollen ```bash npx @capgo/cli@latest bundle zip ``` Sie müssen diese Zip-Datei selbst von Ihrem Server bereitstellen [Auto Update ](/docs/plugin/self-hosted/auto-update/) [Manuell ](/docs/plugin/self-hosted/manual-update/) Note Wenn Ihnen das zu viel Arbeit erscheint, probieren Sie die Capgo Cloud Testversion aus # Umgang mit Statistiken > Eigenen Statistik-Endpoint erstellen Hier ist ein Beispiel für JavaScript-Code zum Speichern der Plugin-Statistiken ```typescript interface AppInfos { version_name: string action: 'delete' | 'reset' | 'set' | 'set_fail' | 'update_fail' | 'windows_path_fail' | 'canonical_path_fail' | 'directory_path_fail' | 'unzip_fail' | 'low_mem_fail' | 'download_fail' | 'update_fail' | 'download_10' | 'download_20' | 'download_30' | 'download_40' | 'download_50' | 'download_60' | 'download_70' | 'download_80' | 'download_90' | 'download_complete' version_build: string version_code: string version_os: string plugin_version: string platform: string app_id: string device_id: string custom_id?: string is_prod?: boolean is_emulator?: boolean } export const handler: Handler = async (event) => { const body = JSONparse(eventbody || '{}') as AppInfos const { platform, app_id, action, version_code, version_os, device_id, version_name, version_build, plugin_version, } = body consolelog('update asked', platform, app_id, action, version_os, version_code, device_id, version_name, version_build, plugin_version) // Speichern Sie es in Ihrer Datenbank return { status: 'ok' } } ``` Dieser Endpunkt sollte ein JSON zurückgeben: ```json { "status": "ok" } ``` ## Aktionen: * **delete**: wenn ein Bundle lokal gelöscht wird * **reset**: wenn die App zum eingebauten Bundle zurückkehrt * **set**: wenn die App ein neues Bundle einstellt * **set\_fail**: wenn die App die ID des eingestellten Bundles nicht finden konnte * **update\_fail**: wird nach der Verzögerung gesendet und `notifyAppReady` wurde nie aufgerufen * **download\_fail**: wenn der Download nie abgeschlossen wurde * **download\_complete:** Wenn der Download abgeschlossen ist * **download\_xx:** Wird alle 10% des Downloads gesendet, z.B.: download\_20, download\_70 * **update\_fail:** wenn das Bundle `notifyAppReady` nicht im vorgegebenen Zeitrahmen ausführt # Updates handhaben > Verwendung des Auto Update Plugins im Self-Hosted Modus Hier ist ein Beispiel für JavaScript-Code zum Senden eines Updates an das Plugin ```typescript interface AppInfos { version_name: string version_build: string version_os: string custom_id?: string is_prod?: boolean is_emulator?: boolean plugin_version: string platform: string app_id: string device_id: string } export const handler: Handler = async (event) => { const body = JSONparse(eventbody || '{}') as AppInfos const { platform, app_id, version_os, device_id, version_name, version_build, plugin_version, } = body consolelog('update asked', platform, app_id, version_os, device_id, version_name, version_build, plugin_version) if (version_name === '100') { return { version: '101', url: 'https://apiurlcom/mybuild_101zip', } } else if (version_name === '101') { return { version: '102', url: 'https://apiurlcom/mybuild_102zip', } } else { return { message: 'Error version not found' version: '', url: '', } } } ``` Dieser Endpunkt sollte ein JSON zurückgeben: ```json { "version": "102", "url": "https://apiurlcom/mybuild_102zip" } ``` Und wenn kein Update oder Fehler vorliegt, fügen Sie den Schlüssel `message` und optional einen `error` hinzu ```json { "message": "Version not found", "error": "The backend crashed", "version": "102", "url": "https://apiurlcom/mybuild_102zip" } ``` # Manuelle Aktualisierung > Manuelles Update-Plugin im Self-Hosted-Modus verwenden ## Konfiguration Fügen Sie dies zu Ihrer `capacitorconfigjson` hinzu, um Auto-Update zu deaktivieren ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false, } } } ``` ## Verwendung Sie können dieses Beispiel verwenden oder die Logik in Ihrer App nachbilden Caution Wir zwingen den Benutzer dazu, die App mit einer im Code deklarierten statischen Version zu aktualisieren. Dies wird nicht empfohlen, Sie sollten eine dynamische Version von Ihrem Server verwenden Danger In diesem Beispiel führen wir keine Versionsüberprüfung, Entschlüsselung oder Prüfsummenvalidierung durch. Dies sollten Sie selbst implementieren ```tsx import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' let data = {version: ""} CapacitorUpdaternotifyAppReady() AppaddListener('appStateChange', async(state) => { if (stateisActive) { // Do the download during user active app time to prevent failed download data = await CapacitorUpdaterdownload({ version: '004', url: 'https://github.com/Cap-go/demo-app/releases/download/004/distzip', }) } if (!stateisActive && dataversion !== "") { // Do the switch when user leave app SplashScreenshow() try { await CapacitorUpdaterset(data) } catch (err) { consolelog(err) SplashScreenhide() // in case the set fail, otherwise the new app will have to hide it } } }) ``` Note Wenn Ihnen das zu viel Arbeit erscheint, erwägen Sie [Capgo trial](https://capgo.app/register/) auszuprobieren. Es wird all dies für Sie erledigen # 설정 > Alle verfügbaren Einstellungen für Capacitor Updater Um eine detailliertere Kontrolle über das Update-System zu haben, können Sie es mit diesen Einstellungen konfigurieren: ## `appReadyTimeout` > Konfigurieren Sie die Anzahl der Millisekunden, die das native Plugin warten soll, bevor ein Update als ‘fehlgeschlagen’ eingestuft wird Nur verfügbar für Android und iOS Standard: `10000` (10 Sekunden) ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 } } } ``` ## `responseTimeout` > Konfigurieren Sie die Anzahl der Millisekunden, die das native Plugin warten soll, bevor ein API-Timeout eintritt Nur verfügbar für Android und iOS Standard: `20` (20 Sekunden) ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "responseTimeout": 1000 } } } ``` ## `autoDeleteFailed` > Konfigurieren Sie, ob das Plugin fehlgeschlagene Bundles automatisch löschen soll Nur verfügbar für Android und iOS Standard: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoDeleteFailed": false } } } ``` ## `autoDeletePrevious` > Konfigurieren Sie, ob das Plugin vorherige Bundles nach einem erfolgreichen Update automatisch löschen soll Nur verfügbar für Android und iOS Standard: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoDeletePrevious": false } } } ``` ## `autoUpdate` > Konfigurieren Sie, ob das Plugin Auto-Update über einen Update-Server verwenden soll Nur verfügbar für Android und iOS Standard: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` ## `updateUrl` > Konfigurieren Sie die URL / den Endpunkt, an den Update-Überprüfungen gesendet werden Nur verfügbar für Android und iOS Standard: `https://apicapgo.app/updates` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "updateUrl": "https://examplecom/api/updates" } } } ``` ## `statsUrl` > Konfigurieren Sie die URL / den Endpunkt, an den Update-Statistiken gesendet werden Nur verfügbar für Android und iOS. Setzen Sie auf "" um die Statistikberichterstattung zu deaktivieren Standard: `https://apicapgo.app/stats` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "statsUrl": "https://examplecom/api/stats" } } } ``` ## `privateKey` > Konfigurieren Sie den privaten Schlüssel für die Ende-zu-Ende-Verschlüsselung von Live-Updates Nur verfügbar für Android und iOS Erstellen Sie den privaten Schlüssel mit dem Befehl `npx @capgo/cli key create` Standard: `undefined` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "privateKey": "YOUR_KEY" } } } ``` ## `directUpdate` > Lässt das Plugin das Update direkt installieren, wenn die App gerade aktualisiert/installiert wurde. Nur im autoUpdate-Modus anwendbar Nur verfügbar für Android und iOS Standard: `undefined` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": true } } } ``` ## `resetWhenUpdate` Note Wenn ein Store-Update erfolgt, deaktivieren Sie das erzwungene Zurücksetzen auf die native Version Es gibt noch viele weitere Einstellungen, die nur in der [Web-App](https://web.capgo.app/login) verfügbar sind Um das Plugin zu konfigurieren, verwenden Sie diese Einstellungen: ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } } ``` ## `directUpdate` Lässt das Plugin das Update direkt installieren, wenn die App gerade aktualisiert/installiert wurde. Nur im autoUpdate-Modus anwendbar Caution Diese Einstellung erfordert, dass Sie die App vor dem Benutzer verbergen, während das Update installiert wird. Andernfalls wird die App zurückgesetzt, wenn der Benutzer navigiert ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": true } } } ``` ## `defaultChannel` Legt den Standard-Kanal für die App fest. Dies überschreibt jeden anderen in Capgo eingestellten Kanal, wenn der Kanal das Überschreiben erlaubt ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "defaultChannel": "production" } } } ``` ## `appId` Legt die appId für die App fest. Dies überschreibt alle anderen Wege, die appId zu erhalten. Dies ist nützlich, wenn Sie eine andere appId in Capgo und in Ihrem nativen Code haben möchten Note Dies ist der neue Weg, die appId festzulegen. Der alte Weg wird weiterhin unterstützt ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "AppId": "comexampleapp" } } } ``` ## `version` Legt die Version für die App fest. Dies überschreibt alle anderen Wege, die Version zu erhalten. Dies ist nützlich, wenn Sie eine andere Version in Capgo und in Ihrem nativen Code haben möchten Note Dies ist der neue Weg, die Version festzulegen. Der alte Weg wird weiterhin unterstützt ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "version": "123" } } } ``` # 統計情報 API > Wie man das automatische Update-Plugin im selbstgehosteten Modus verwendet ## Statistik-API Ab Version 130 kann das Update-System Statistiken senden! Standardmäßig werden alle Statistiken an unseren Server gesendet, um die Nutzung zu verstehen und zu erforschen Note Es werden keine privaten Daten für Statistiken gesendet, nur zufällige UUID, Versions-Update, Version der nativen App, Plattform, Aktion und App-ID Wenn Sie diese Daten stattdessen an Ihren Server senden möchten, ändern Sie die Konfiguration wie folgt: ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "statsUrl": "IHRE_URL" } } } ``` Ihr Server wird Folgendes empfangen: ```tsx interface AppInfosStats { "action": "set", // kann set, delete, set_fail, reset, revert sein // Dann sind es die gleichen Informationen wie beim Update "app_id": "*******", // App-Identifikator im Store "device_id": "*******", // eindeutige ID pro App-Installation "platform": "ios", // oder android "custom_id": "user_1", // repräsentiert Ihren Benutzer "version_name": "123", // Version des Web-Builds "version_build": "120", // Version des nativen Builds "version_code": "120", // Build-Nummer des nativen Builds "version_os": "16", // OS-Version des Geräts "plugin_version": "400"// damit sich Ihre API bei verschiedenen Plugins unterschiedlich verhält "is_emulator": false, "is_prod": false, } ``` Sie können es auch vollständig deaktivieren, mit einem leeren String. Bedenken Sie, dass die Statistiken datenschutzfreundlich gestaltet sind und mir helfen zu verstehen, wie Menschen das Plugin nutzen, um Probleme zu lösen und es zu verbessern [Updates verwalten ](/docs/plugin/self-hosted/handling-updates/) # Migration von AppFlow zu Capgo > Vollständiger Leitfaden zur Migration Ihrer App von Ionic AppFlow zu Capgo ## AppFlow-Konfigurationsreferenz Notieren Sie vor der Migration Ihre aktuelle AppFlow-Konfiguration in `capacitor.config.ts`: ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { LiveUpdates: { appId: 'your-app-id', channel: 'Production', autoUpdateMethod: 'background', // oder 'always latest', 'force update' maxVersions: 2 } } }; ``` Diese Konfiguration hilft Ihnen, AppFlow-Funktionen den Capgo-Äquivalenten zuzuordnen. ## Warum zu Capgo migrieren? Mit der Ankündigung der Einstellung von Ionic AppFlow bietet die Migration zu Capgo einen nahtlosen Übergang für Ihren Mobile-App-Entwicklungsworkflow. Capgo bietet verbesserte Funktionen, bessere Leistung und erhebliche Kosteneinsparungen bei Beibehaltung aller wichtigen Funktionalitäten. ### Hauptvorteile * Schnellere Update-Bereitstellung (< 1 Minute vs. 10 Minuten) * Günstigere Preisgestaltung (14$/Monat vs. 499$/Monat) * Ende-zu-Ende-Verschlüsselung in allen Plänen enthalten * Verbesserte Kontrolle über Update-Kanäle * Umfassende CI/CD-Integrationsoptionen ## Migrationsschritte ### 1. Live-Updates Migration #### Vorherige Abhängigkeiten entfernen ```bash npm uninstall @ionic/appflow ``` #### Capgo installieren ```bash npm install @capgo/capacitor-updater npx cap sync ``` #### Konfiguration aktualisieren Fügen Sie die Capgo-Konfiguration zu Ihrer `capacitor.config.json` hinzu: ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true } } } ``` ### 2. CI/CD Migration Capgo bietet flexible CI/CD-Optionen: #### Option 1: Bestehende CI/CD verwenden Folgen Sie unseren detaillierten Tutorials zur Einrichtung von CI/CD mit beliebten Plattformen: * [iOS Build-Einrichtung](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) * [Android Build-Einrichtung](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) * [GitHub Actions Integration](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) #### Option 2: CI/CD als Service Lassen Sie uns Ihre CI/CD-Einrichtung mit unserem [verwalteten Service](https://cal.com/team/capgo/mobile-ci-cd-done-for-you) übernehmen. ### 3. Kanal-Einrichtung 1. Kanäle im Capgo-Dashboard erstellen: ```bash npx @capgo/cli channel create production npx @capgo/cli channel create staging ``` 2. Kanal-Einstellungen konfigurieren: ```bash # Produktionskanal einrichten npx @capgo/cli channel update production --no-downgrade --no-upgrade # Staging-Kanal einrichten npx @capgo/cli channel update staging ``` ### 4. Migration testen 1. **Live-Updates testen** ```bash # Test-Bundle erstellen und hochladen npx @capgo/cli bundle create --channel staging ``` 2. **Update-Empfang überprüfen** * App auf Testgerät installieren * Überprüfen, ob Updates korrekt empfangen werden * Update-Installationsprozess verifizieren * Wiederherstellungsfunktion testen ## Fehlerbehebung ### Häufige Probleme #### Updates werden nicht empfangen * Kanal-Konfiguration überprüfen * Geräte-Logs überprüfen * Netzwerkverbindung sicherstellen * Bundle-Versionsformat validieren ## Nächste Schritte 1. [Capgo-Konto erstellen](/register/) 2. [Schnellstart-Anleitung](/docs/getting-started/quickstart/) befolgen 3. [CI/CD-Integration](/docs/getting-started/cicd-integration/) einrichten 4. [Live-Updates](/docs/live-updates/) konfigurieren Für Unternehmensteams, die während der Migration dedizierten Support benötigen, [vereinbaren Sie einen Termin mit unserem Team](https://cal.com/team/capgo/capgo-enterprise-inquiry). # Von V2 auf V3 > So aktualisieren Sie von V2 auf V3 Diese Dokumentation erklärt, wie Sie auf Version 3 von auto-update aktualisieren können ## Zuerst migrieren Sie zu den aktuellsten Tools: ```bash npm remove -g capgo npm remove capacitor-updater npm i @capgo/cli npm i @capgo/capacitor-updater@3 npx cap sync ``` ## Entfernen Sie alle Ihre vorherigen Konfigurationen: ```json { CapacitorUpdater: { autoUpdateURL: "https", }, } ``` um nur dies übrig zu lassen: ```json { "CapacitorUpdater": { "autoUpdate": true } } ``` > ⚠️ Wenn Sie Ihren eigenen Server mit `autoUpdateURL` verwendet haben, werde ich diesen Leitfaden bald für Sie aktualisieren. Schauen Sie sich in der Zwischenzeit die neue Upload-Option `external` an, mit der Sie nur den Link Ihrer ZIP-Datei senden können, nicht den Code in der Capgo-Cloud. Dies wurde für Unternehmen mit strengen Datenschutzrichtlinien entwickelt. Im externen Modus wird der Code niemals auf dem Capgo-Server landen, wir speichern nur die URL und senden sie an das Gerät, das sie direkt herunterlädt. Auf die standardmäßige Art wird der Code gezippt und auf unserem Server gespeichert, aber wir werden ihn niemals öffnen oder anderweitig verwenden ## Was sich ändert Alle Konfigurationen werden serverseitig für auto-update, um Ihnen mehr Kontrolle darüber zu geben, wie Sie ein Update an Benutzer senden Dies ermöglicht uns das Zurücksetzen und sogar das Bereitstellen für nur einen Benutzer mit Kanälen! Diese Einstellungen werden der Weboberfläche hinzugefügt: * Deaktivieren der Zurücksetzung unter der nativen Version * Deaktivieren von Updates über Major-Versionen > ⚠️ Diese werden standardmäßig für alle Kanäle aktiviert Dies wird auch die Notwendigkeit häufiger Plugin-Updates beseitigen, die meisten Updates werden serverseitig durchgeführt, und Sie erhalten sie ohne Änderungen auf Ihrer Seite > ⚠️ Zurücksetzen, wenn ein Update zum Standard wird. Wenn Sie es vorziehen, nicht alle heruntergeladenen Versionen beim Update aus dem Store zu entfernen, tun Sie dies: ```json { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } ``` ## Aktualisieren Sie Ihren Code Aktualisieren Sie zuletzt alle Ihre Imports in JS von: ```plaintext import { CapacitorUpdater } from 'capacitor-updater' ``` zu ```plaintext import { CapacitorUpdater } from '@capgo/capacitor-updater' ``` Dann bauen Sie Ihren Code erneut `npm run build` und kopieren Sie die Assets noch einmal `npx cap copy` Sie sollten jetzt in der Lage sein, das neueste auto-update System zu testen Senden Sie Ihre Version mit: ```plaintext npx @capgo/cli@latest bundle upload ``` anstelle von ```plaintext npx capgo upload ``` ## Zukünftige Entwicklung Derzeit wird nur der erste öffentliche Kanal verwendet, in Zukunft wird public sich für mehrere öffentliche Kanäle ändern, wenn mehr als einer eingerichtet ist ## Häufige Probleme: * Build-Problem nach dem Upgrade: Wenn Sie den Quellcode des Plugins bereits in Android Studio oder Xcode geöffnet haben, entfernt die Synchronisierung diese manchmal nicht, das ist die Ursache des Problems. Öffnen Sie die native IDE und entfernen Sie `capacitor-updater` manuell und führen Sie `npx cap sync` aus, das sollte das Problem lösen # Von V3 zu V4 > So aktualisieren Sie von V3 auf V4 ## Warum dieses Upgrade Nach vielen Gesprächen mit Ihnen in der Discord-Community habe ich festgestellt, dass der manuelle Modus zu manuell und nicht sicher in der Anwendung war. Zum Beispiel war ein automatisches Zurücksetzen nicht möglich, sodass bei einem fehlgeschlagenen Update der Benutzer die App entfernen und neu installieren musste, was eine sehr schlechte Nutzererfahrung darstellt. In der Zwischenzeit habe ich dies als Gelegenheit genutzt, Ihnen mehr Freiheit zu geben und den gesamten schlechten Code zu entfernen. ## Installation `npm i @capgo/capacitor-updater@4` ## Auto-Update Cloud Wenn Sie das Grundbeispiel in Ihrer App verwenden, können Sie sicher auf die neue Version migrieren. Viel Spaß! ## Auto-Update Self-Hosted Für Sie ist es weiterhin einfach, die Änderungen sind: * Der Name der Einstellung von `autoUpdateUrl` zu `updateUrl` * Die Endpoint-Methode wurde von `GET` zu `POST` geändert ## Manuelle Benutzer Für Sie ist dies die bedeutendste Änderung, aber zum Besten! Sie erhalten viele Verbesserungen, lesen Sie sorgfältig. ## Änderungen * `autoUpdateUrl` wird zu `updateUrl`, da diese Einstellung jetzt auch im manuellen Modus verwendet werden kann * Löschung von `cancelDelay` und `delayUpdate` zugunsten von `setDelay` * Kein `versionName` mehr in set * Änderung des `version`-Schlüssels, der in den meisten Funktionen zum Objekt `BundleInfo` zurückgegeben wurde ```typescript interface BundleInfo { id: string; version: string; downloaded: string; status: 'success' | 'error' | 'pending' | 'downloading' } ``` * Umbenennung irreführender Namen (auch wenn die Erklärung nicht klar sein kann, ist die Verwendung der neuen Namen einfach zu verstehen): * was als `version` bezeichnet wurde, wird jetzt als `bundle` bezeichnet * `id` bezieht sich auf die alte `version`, die eine zufällige Zeichenfolge von 10 Zeichen war, diese `id` ist die einzige vertrauenswürdige und eindeutige Möglichkeit, auf Ihre Bundles zuzugreifen, Beispiel `7Dfcd2RedN` * `version` bezieht sich jetzt auf den `versionName`, den Sie für ein Bundle wählen, Beispiel `100` * `updateUrl` wechselt von `get` zu `post`, da benutzerdefinierte Header für einige von Ihnen ein Problem darstellten und post logischer ist, alle vorherigen Header gehen in den Body und das Präfix `cap_` verschwindet * `versionName`-Methode wird gelöscht, zugunsten von `getId` * list gibt jetzt eine Liste von `BundleInfo` zurück * Umbenennung von `getId` in `getDeviceId` * `autoUpdate` wird standardmäßig auf true gesetzt, wenn Sie den manuellen Modus verwenden, setzen Sie es auf false ## Neuheiten * Methode `getLatest`, diese Methode ermöglicht es Ihnen, von Ihrem mit `updateUrl` eingestellten Server die letzte verfügbare Version zu erhalten * Methode `setDelay`, die `{kind: "background" | "kill" | "nativeVersion" | "date", value?: string}` als Argument nimmt, um Verzögerungen für verschiedene Modi einzustellen * Methode `next`, um die Version beim nächsten Hintergrundprozess festzulegen, im Gegensatz zu `set`, das es sofort ausführt * Methode `isAutoUpdateEnabled`, um zu erfahren, ob Sie sich im Auto-Update-Kontext befinden * Event `downloadComplete`, wenn der Download 100% erreicht * Hinzugefügtes Pflichtfeld `version` in der Download-Methode * `notifyAppReady` wird auch im manuellen Modus obligatorisch, wenn nicht nach 10 Sekunden aufgerufen, kehrt die App zur vorherigen Version zurück ## Mitwirkende [@lincolnthree](https://github.com/lincolnthree/) Vielen Dank für den Start dieser Arbeit, es wäre unmöglich gewesen, dieses Update ohne Sie zum Laufen zu bringen # Von V4 zu V5 > So aktualisieren Sie von V4 auf V5 ## Warum dieses Upgrade Diese Major-Version folgt der Capacitor Major-Version Befolgen Sie zunächst die Migrationsanleitung von Capacitor: [https://capacitorjs.com/docs/updating/5-0](https://capacitorjs.com/docs/updating/5-0/) ## Installation `npm i @capgo/capacitor-updater@5` `Dann synchronisieren Sie den nativen Code-Update:` `npx cap sync` Das war’s! Ziemlich einfach! ## Manueller Modus Wenn Sie selbst das Update mit getLatest geholt haben, gibt es eine kleine Änderung Wenn Sie bereits auf dem neuesten Stand sind, wird es in den catch-Block gehen Jede Antwort, die sich von verfügbaren Updates unterscheidet, wird dies tun # Von V5 auf V6 > So aktualisieren Sie von V5 auf V6 ## Warum dieses Upgrade Diese Major-Version folgt der Capacitor Major-Version Befolgen Sie zunächst die Migrationsanleitung von Capacitor: [https://capacitorjs.com/docs/updating/6-0](https://capacitorjs.com/docs/updating/6-0/) ## Installation `npm i @capgo/capacitor-updater@6` `Dann synchronisieren Sie das native Code-Update:` `npx cap sync` Das war’s! Ganz einfach! # Introduzione > Einführung in die Cagpo Webapp ## Was ist das? Cagpo verfügt über eine umfangreiche Webapp zur Verwaltung Ihrer Projekte. Diese Webapp wurde mit Vuejs entwickelt und ist Open Source. Den Quellcode finden Sie auf [GitHub](https://github.com/Cap-go/capgo/tree/main/src/)\ Die Webapp ist [hier](https://web.capgo.app/) verfügbar\ Mit dieser Webapp können Sie [Kanäle verwalten](/docs/webapp/channels/), [Versionen verwalten](/docs/webapp/bundles/), [Geräte verwalten](/docs/webapp/devices/), [Protokolle einsehen](/docs/webapp/logs/), [Abrechnung verwalten](/docs/webapp/settings/) und [Ihr Konto verwalten](/docs/webapp/settings/) ## Wie benutze ich es? Zunächst müssen Sie ein Konto erstellen oder sich anmelden. Dies ist relativ einfach und kann durch Klicken auf die Schaltfläche `Anmelden` in der Bildschirmmitte erfolgen. Nach der Anmeldung werden Sie zum Dashboard weitergeleitet. Dies ist die Hauptseite der Webapp. Von hier aus können Sie zu allen anderen Seiten navigieren. ![login page](/login.webp) ## Ein Konto erstellen Sie müssen auf `Kostenloses Konto erstellen` im unteren Teil des Anmeldeformulars klicken. Von da an ist es so einfach wie das Ausfüllen eines Formulars und das Befolgen der Anweisungen. ![create account](/create-account.webp) # API-Schlüssel verwalten > API-Schlüssel verwalten ## Was kann ich mit den API-Schlüsseln tun? Ein API-Schlüssel kann neu generiert, entfernt oder ein neuer hinzugefügt werden ## Wie kann ich alle API-Schlüssel sehen? Sie müssen zur [API-Schlüssel-Seite](https://web.capgo.app/dashboard/apikeys/) gehen und dort sehen Sie alle Ihre API-Schlüssel ## Wie füge ich einen neuen API-Schlüssel hinzu? Um einen neuen API-Schlüssel hinzuzufügen, klicken Sie auf den kleinen Plus-Button ![add apikey](/apikeys-add.webp) und wählen Sie dann die Berechtigungen aus, die Sie dem neuen API-Schlüssel geben möchten. Sie können auswählen: * Lesen - der API-Schlüssel kann alle Daten lesen * Upload - der API-Schlüssel kann neue Versionen über die CLI hochladen und lesen * Alles - der API-Schlüssel kann alles tun ![select perm](/apikeys-select-perm.webp) ## Wie entferne ich einen API-Schlüssel? Um einen API-Schlüssel zu entfernen, klicken Sie auf den kleinen Papierkorb-Button ![remove apikey](/apikeys-remove.webp) Und bestätigen Sie dann das Entfernen des API-Schlüssels ## Wie generiere ich einen API-Schlüssel neu? Um einen API-Schlüssel neu zu generieren, klicken Sie auf den kleinen Aktualisieren-Button ![generate apikey](/apikeys-regenerate.webp) Und bestätigen Sie dann die Neugenerierung des API-Schlüssels # Bundle > Entdecken Sie, wie man Bundles verwaltet ## Alle Bundles anzeigen Schauen wir uns zunächst die Bundles-Seite an. Sie können darauf zugreifen, indem Sie [auf Ihre App klicken](/docs/webapp/main-page) und dann [auf den Bundles-Tab klicken](/docs/webapp/main-app-page) ![bundle list](/bundles.webp) ## Ein Bundle löschen Es gibt zwei Möglichkeiten, ein Bundle zu löschen: * Normal * Unsicher Die unsichere Möglichkeit zum Löschen eines Bundles wurde am 12. August 2024 zu Capgo hinzugefügt Der Unterschied zwischen den beiden Methoden liegt in der Möglichkeit, die Versionsnummer nach dem Löschen wiederzuverwenden Wenn Sie zum Beispiel eine Version `100` auf normale Weise löschen und später versuchen, eine Version `100` hochzuladen, wird dies fehlschlagen Wenn Sie diese Version über das unsichere Löschen entfernen, können Sie eine Version `100` hochladen Danger Das unsichere Löschen einer Version und erneutes Hochladen ist WIRKLICH gefährlich Es kann alle Arten von Fehlern und unvorhersehbarem Verhalten im Plugin verursachen Es sollte NIEMALS für Bundles verwendet werden, die in einem öffentlichen Kanal verwendet wurden Aus diesem Grund erfordert das unsichere Löschen einer Version “super\_admin”-Berechtigungen ## Ein bestimmtes Bundle verwalten Sobald Sie die Liste aller Bundles sehen, klicken Sie auf das Bundle, das Sie verwalten möchten. Danach sollten Sie etwa Folgendes sehen: ![bundle info](/bundle-info.webp) Gehen wir alle Elemente auf dieser Seite durch *** Zuerst sehen Sie einen `Channel`. Dieser zeigt Ihnen an, für welchen Kanal dieses Bundle bestimmt ist. Sie können den Kanal durch Anklicken ändern Nach dem Klicken sollten Sie etwa Folgendes sehen: ![bundle change](/bundle-change.webp) `Set bundle to channel` ermöglicht es Ihnen, dieses Bundle als Standard für jeden Kanal zu verknüpfen\ `Open channel` öffnet die Kanalseite für den Kanal, für den dieses Bundle bestimmt ist\ `Unlink bundle from channel` trennt die Verknüpfung dieses Bundles vom zugehörigen Kanal (**WARNUNG**: Wenn das Bundle mit mehr als einem Kanal verknüpft ist, haben Sie keine Auswahlmöglichkeit, welcher Kanal getrennt werden soll) *** Als Nächstes sehen Sie die `Size`. Wenn Sie darauf klicken, können Sie dieses Bundle herunterladen Es sollte etwa so aussehen: ![download bundle](/download-bundle.webp) *** Zuletzt gibt es den Bereich `Devices`. Hier können Sie alle Geräte sehen, die diese Version verwenden # 채널 > Kanäle sind eine Möglichkeit, die Updates deiner App zu verwalten. Du kannst mehrere Kanäle haben und jeder Kanal kann mehrere Versionen enthalten. Dies ermöglicht es dir, mehrere Versionen deiner App gleichzeitig in Produktion zu haben. ## Kanäle verwalten Schauen wir uns zunächst die Kanäle-Seite an. Sie können darauf zugreifen, indem Sie [auf Ihre App klicken](/docs/webapp/main-page) und dann [auf den Kanäle-Tab klicken](/docs/webapp/main-app-page) ![channel list](/channels.webp) ## Einen Kanal erstellen Wie Sie sehen können, gibt es einen Plus-Button in der unteren rechten Ecke (`1` im Bild). Wenn Sie darauf klicken, öffnet sich ein Modal, in dem Sie einen neuen Kanal erstellen können. ![new channel](/new_channel_modal.webp) Nachdem Sie auf `Hinzufügen` geklickt haben, sollte ein neuer Kanal in der Liste erscheinen. ![after channel create](/post-channel-create.webp) ## Was bedeutet fehlkonfiguriert? Manchmal ist die Konfiguration eines Kanals nicht gültig. In diesem Fall erhalten Sie eine große Warnung und die Spalte `Fehlkonfiguriert` zeigt `Ja` für einen oder mehrere Kanäle an. Mehr dazu erfahren Sie [hier](/docs/cli/commands/#disable-updates-strategy) ## Einen Kanal löschen Das Löschen eines Kanals ist unkompliziert. Klicken Sie einfach auf das Papierkorb-Symbol und bestätigen Sie die Löschung (`2` im Bild) ## Einen Kanal verwalten Wenn Sie auf den Kanalnamen klicken, öffnet sich ein Modal, in dem Sie den Kanal verwalten können (`3` im Bild). Diese Seite sollte etwa so aussehen: ![manage channel](/manage_channel_main.webp) Gehen wir die verschiedenen Abschnitte durch: Zuerst die `Bundle-Nummer` (`1` im Bild). Dies ist die aktuelle Version für diesen Kanal. Wenn nach einem Update gefragt wird, wird dieser Kanal immer versuchen, mit dieser Version zu antworten\* \[^1] Ein Klick darauf sollte Sie zur [Bundle](/docs/webapp/bundles/)-Seite führen. Zweitens die `Geteilt mit`-Seite (`2` im Bild). Ich rate davon ab, dies jemals zu verwenden. Ein neues und besseres System ist in Arbeit. Nun die erzwungenen Geräte (`3` im Bild). Dies ist eine Liste von Geräten, die immer Updates von diesem Kanal erhalten werden. Dies ist nützlich für Testzwecke. Sie können ein Gerät von der [Geräte](/docs/webapp/devices/)-Seite aus zu einem Kanal zwingen. Zuletzt die Einstellungen (`4` im Bild). Hier können Sie verwalten, wie sich die Kanäle verhalten. Nachdem Sie darauf geklickt haben, sollten Sie etwa Folgendes sehen: ![setting of channel](/channel_settings.webp) Die Liste der Einstellungen ist lang, aber ich werde mein Bestes geben, sie alle zu erklären: *** Erstens der `Standardkanal` **DIES IST WAHRSCHEINLICH DER WICHTIGSTE**\ Wenn ein Kanal als Standard markiert ist, wird er als Standardkanal für alle neuen Geräte verwendet.\ Anders ausgedrückt: Wenn Sie einen neuen Benutzer haben, wird Capgo versuchen, ihm die neueste Version dieses Standardkanals zu liefern. Nur 1 Kanal kann gleichzeitig als Standard festgelegt werden. Wenn Sie versuchen, diese Regel zu brechen, werden Sie gebeten, Ihre Aktion zu bestätigen. ![confirm make change](/confirm-make-default.webp) Nach der Bestätigung wird der alte Standardkanal nicht mehr als Standard markiert und der neue wird als Standard markiert. *** Zweitens die `iOS`-Einstellung. Dies ist relativ einfach. Wenn dies falsch ist, dürfen iOS-Geräte keine Updates von diesem Kanal herunterladen. Drittens ist die `Android`-Einstellung. Dies ist ähnlich wie `iOS`. Wenn dies falsch ist, dürfen Android-Geräte keine Updates von diesem Kanal herunterladen. Viertens ist die Einstellung `Auto-Downgrade unter Native deaktivieren`. Wenn dies wahr ist, wird es unmöglich sein, von einer nativen Version herabzustufen. Das bedeutet, wenn Sie eine Version `120` im App Store oder Play Store hochgeladen haben und versuchen, die Kanalversion auf `110` zu setzen, wird das Update (Downgrade) fehlschlagen. Fünftens ist `Auto-Update deaktivieren`. Diese Einstellung ist ziemlich komplex, und Sie können mehr darüber [hier](/docs/cli/commands/#disable-updates-strategy) erfahren. Was `Entwicklungs-Build erlauben` betrifft: Wenn dies wahr ist, dürfen Entwicklungs-Builds Updates von diesem Kanal herunterladen. Wenn nicht, wird jede Update-Anfrage, bei der `prod` auf false gesetzt ist, abgelehnt. Dies ist hauptsächlich für Testzwecke nützlich. Siebens ist `Emulatoren erlauben`. Wenn dies falsch ist, wird Capgo jede Update-Anfrage ablehnen, die von einem Emulator kommt. Dies ist hauptsächlich für Testzwecke nützlich. Achtens ist `Geräten erlauben, sich selbst zuzuordnen`. Wenn dies wahr ist, wird die [setChannel](/docs/plugin/api/#setchannel)-Methode verfügbar sein. Wenn dies auf falsch gesetzt ist und Sie versuchen, die [setChannel](/docs/plugin/api/#setchannel)-Methode mit diesem Kanal aufzurufen, wird der Aufruf fehlschlagen. # Geräte > Verwendung der Device-Seite ## Liste aller Geräte anzeigen Schauen wir uns zunächst die Geräteseite an. Sie können darauf zugreifen, indem Sie [auf Ihre App klicken](/docs/webapp/main-page) und dann [auf den Geräte-Tab klicken](/docs/webapp/main-app-page) ![devices list](/devices.webp) ## Nur Entwicklergeräte anzeigen Möglicherweise möchten Sie nur die überschriebenen Geräte anzeigen (Geräte, die einen [benutzerdefinierten Kanal](/docs/plugin/api/#setchannel) oder eine benutzerdefinierte Version haben). Klicken Sie dazu auf `Filter` und dann auf `Überschreiben`. Es sollte etwa so aussehen: ![filter devices](/overwrite-filter.webp) ## Ein Gerät konfigurieren Um ein bestimmtes Gerät zu konfigurieren, klicken Sie in der Tabelle darauf. Sie sollten dann etwa Folgendes sehen: ![show one device](/device-specific.webp) Zunächst die `Benutzerdefinierte ID`. Diese ist nicht wirklich nützlich und macht derzeit nichts. Sie können sie ignorieren. Als Nächstes die erzwungene Version. Wenn diese eingestellt ist, wird dieses Gerät **IMMER** diese Version erhalten. Sie hat Vorrang vor dem Kanal. Zuletzt der benutzerdefinierte Kanal. Wenn dieser eingestellt ist, wird dieses Gerät sich nicht um den öffentlichen (Standard-) Kanal kümmern und stattdessen diesen verwenden. # Protokolle > So lernen Sie die Protokollseite kennen ## Alle Logs anzeigen Schauen wir uns zunächst die Logs-Seite an. Sie können darauf zugreifen, indem Sie [auf Ihre App klicken](/docs/webapp/main-page) und dann [auf den Updates-Tab klicken](/docs/webapp/main-app-page) Von dort aus sollten Sie eine Seite wie diese sehen: ![show logs](/logs.webp) ## Weitere Details zu einem Log erhalten Wenn Sie auf ein Log klicken, gelangen Sie zur [Geräte-Seite](/docs/webapp/devices/) # Hauptseite der App > Was zeigt die Hauptseite an? ## Was zeigt die Hauptseite an? Schauen wir uns zunächst die Hauptseite der App an: ![Main page screeshot](/main-app-page.webp) Lass uns dies genauer betrachten Zuerst die Statistiken. Die Statistiken werden derzeit überarbeitet, daher können sie zu diesem Zeitpunkt nicht dokumentiert werden. Wir werden einen Statistik-Abschnitt hinzufügen, sobald sie vollständig funktionsfähig sind. Zweitens, schauen wir uns alle verfügbaren Menüs und ihre Funktionen an ![Multiple sections screeshot](/app-multiple-sections.webp) Die erste Schaltfläche führt Sie zur [channels](/docs/webapp/channels/) Seite. Dort können Sie die Kanäle der App erstellen/löschen/konfigurieren\ Die zweite Schaltfläche führt Sie zur [bundles](/docs/webapp/bundles/) Seite. Dort können Sie alle Versionen der App sehen Die zweite Schaltfläche führt Sie zur [device](/docs/webapp/devices/) Seite. Dort können Sie alle Geräte sehen. Sie können dort auch gerätespezifische Überschreibungen festlegen Die zweite Schaltfläche führt Sie zur [updates](/docs/webapp/logs/) Seite. Dort können Sie die detaillierten Statistiken (Logs) und Fehler sehen, die Ihre App erfährt # Page principale > Diese Seite erklärt die Hauptseite der Webanwendung ## Was zeigt die Hauptseite an? Schauen wir uns zunächst die Hauptseite an: ![Main page screeshot](/main-page.webp) Beginnen wir von vorne. Das Erste, was Sie sehen, sind die **Statistiken**. Diese enthalten app-spezifische Statistiken. Diese Aktualisierungen hängen von der Nutzung der App ab. Das Zweite, was Sie sehen, ist die Liste aller verfügbaren Apps. Diese ändert sich je nachdem, wie viele Apps Sie erstellt haben. Sie können auf jede App klicken, um weitere Details darüber zu sehen. Das Dritte, was Sie sehen, ist die Schaltfläche **API-Schlüssel**. Diese Schaltfläche führt Sie zur [API-Schlüssel](/docs/webapp/api-keys/) Seite. Als Nächstes sehen Sie die Schaltfläche **Capgo testen**. Diese Schaltfläche ändert sich je nach Ihrem Vor- und Nachnamen und führt Sie zur [Einstellungen](/docs/webapp/settings/) oder Support-Seite. Zuletzt sehen Sie eine Schaltfläche zum Hinzufügen einer weiteren App. Diese Schaltfläche führt Sie zu einer Seite, auf der Sie eine neue App zu Capgo hinzufügen können. # 二要素認証 > Verwalten Sie die Zwei-Faktor-Authentifizierung, um Ihr Capgo-Konto besser zu schützen. ## Was ist 2FA? 2FA ist eine Sicherheitsmaßnahme, die verhindert, dass ein böswilliger Akteur Ihr Capgo-Konto übernehmen kann\ Dies wird erreicht, indem ein zusätzlicher Code erforderlich ist. Dieser Code wird auf Ihrem Mobiltelefon oder einem Hardware-2FA-Schlüssel gespeichert. Er ändert sich alle 30 Sekunden, was es unmöglich macht, ihn zu erraten. ## Voraussetzungen für diese Anleitung * Ein Android- oder iOS-Telefon * Internetverbindung ## Was behandelt diese Anleitung? Diese Anleitung zeigt, wie man 2FA mit `Google Authenticator` einrichtet. Es gibt auch andere Apps für ähnliche Zwecke, aber ich kann in dieser Anleitung nicht das gesamte Thema 2FA abdecken. ## Wie richtet man 2FA ein? Laden Sie zunächst die `Google Authenticator`-App herunter. Wenn Sie Android nutzen, können Sie sie aus dem [Play Store](https://play.google.com/store/apps/details/?id=comgoogleandroidappsauthenticator2) herunterladen. Auf iOS können Sie sie aus dem [App Store](https://appsapplecom/us/app/google-authenticator/id388497605/) herunterladen. Gehen Sie als Nächstes zu den [Capgo-Kontoeinstellungen](https://web.capgo.app/dashboard/settings/account/). Dort sollten Sie einen grünen Button sehen, der so aussieht: ![Button MFA](/button-mfa.webp) Klicken Sie darauf, und es sollte ein QR-Code erscheinen. ![Enable MFA](/enable-mfa.webp) Danger ⚠️ Wichtiger Hinweis:\ Teilen Sie diesen QR-Code niemals mit anderen, sonst könnten Sie aus Ihrem Konto ausgeloggt werden Öffnen Sie als Nächstes den `Google Authenticator` auf Ihrem Telefon. Folgen Sie dann diesen Schritten: Klicken Sie auf den Plus-Button ![MFA auth plus](/mfa-auth-plus.webp) Klicken Sie danach auf den Kamera-Button ![MFA scan QR](/mfa-scan-qr.webp) Dadurch wird die Kameravorschau geöffnet. Scannen Sie den QR-Code, der auf Ihrem PC angezeigt wird. Danach sollten Sie so etwas sehen: ![MFA final code](/mfa-final-code.webp) Gehen Sie dann zurück zum PC und klicken Sie auf den Verifizieren-Button ![Verify MFA](/enable-mfa-verify.webp) Dadurch öffnet sich ein Fenster zum Eingeben des 2FA-Codes. In meinem Fall ist dieser Code `095101`, aber er wird bei Ihnen anders sein\ Nachdem Sie diesen Code eingegeben haben, klicken Sie bitte auf den `verify`-Button ![MFA verify code final](/mfa-verify-final-code.webp) Wenn Sie den richtigen Code eingegeben und auf `verify` geklickt haben, sollten Sie ein Pop-up wie dieses sehen ![MFA enabled](/mfa-enabled.webp) Glückwunsch!\ Sie haben die 2FA-Authentifizierung aktiviert 🎉 ## Wie man sich mit 2FA einloggt Beim nächsten Login in Ihr Konto sehen Sie ein Fenster wie dieses ![MFA required](/mfa-required.webp) Öffnen Sie den Authenticator und kopieren Sie Ihren Authentifizierungscode ![MFA login](/mfa-login.webp) Danger ⚠️ Wichtiger Hinweis:\ Drücken Sie `verify`, bevor sich der Code aktualisiert, sonst ändert sich der Code und der alte ist nicht mehr gültig Geben Sie dann den Code in das Login-Formular ein und drücken Sie auf `verify` ![MFA login](/mfa-final-login-verify.webp) Wenn Sie den richtigen Code eingegeben haben, sollten Sie das Capgo-Dashboard sehen ## Wie man 2FA deaktiviert Um 2FA zu deaktivieren, gehen Sie bitte zu den [Capgo-Kontoeinstellungen](https://web.capgo.app/dashboard/settings/account/). Dort sollten Sie einen roten Button sehen, der so aussieht: ![MFA disable button](/mfa-disable-button.webp) Klicken Sie darauf und Sie sollten einen Bildschirm wie diesen sehen ![MFA disabled](/mfa-disable-2.webp) Drücken Sie einfach den `disable`-Button und das war’s # Organisationssystem > Organisation in deinem Capgo Account verwalten ## Was ist das Organisationssystem? Das Organisationssystem ist ein System in Capgo, das es Ihnen ermöglicht, Ihre Apps sicher mit Mitgliedern Ihres Teams zu teilen. ### F: Wie kann ich auf die Informationen meiner Organisation zugreifen? Um auf die Informationen Ihrer Organisation zuzugreifen, gehen Sie bitte zu [Einstellungen](/docs/webapp/settings/#how-to-get-to-the-settings-page) und klicken Sie dann auf `Organisationseinstellungen` ![Org settings](/orgs-settings.webp) ### F: Wie kann ich die Organisation wechseln, die ich gerade ansehe? Um die Einstellungen einer anderen Organisation anzusehen, klicken Sie bitte auf den Organisationsauswähler neben Ihrem Namen ![Org selector](/org-selector.webp) Wenn Sie dies nicht sehen können, befinden Sie sich wahrscheinlich nicht auf der Einstellungsseite ### F: Wie kann ich die Mitglieder meiner Organisation sehen? Bitte klicken Sie auf `Mitglieder` ![Org Show members](/org-show-members.webp) ### F: Wie kann ich einen Benutzer zu einer Organisation einladen? Bitte klicken Sie auf `Mitglied hinzufügen` ![Org add member](/orgs-add-member.webp) Dann erscheint ein Popup - bitte geben Sie die E-Mail-Adresse des Benutzers ein ![Invite to org](/invite-to-org-email-enter.webp) Klicken Sie dann auf `Einladen`. Ein weiteres Popup erscheint, das Sie nach den Berechtigungen fragt, die der eingeladene Benutzer haben soll ![Select perm for org](/select-perm-orgs.webp) Hier ist eine Übersicht aller Berechtigungen: | Berechtigung | Lesen | Upload | Schreiben | Admin | Super Admin | | ---------------------------------- | ----- | ------ | --------- | ----- | ----------- | | App-Statistiken anzeigen | ✅ | ✅ | ✅ | ✅ | ✅ | | App-Kanäle anzeigen | ✅ | ✅ | ✅ | ✅ | ✅ | | Geräte anzeigen | ✅ | ✅ | ✅ | ✅ | ✅ | | Logs anzeigen | ✅ | ✅ | ✅ | ✅ | ✅ | | Bundles anzeigen | ✅ | ✅ | ✅ | ✅ | ✅ | | App löschen | ❌ | ❌ | ❌ | ❌ | ✅ | | Kanal löschen | ❌ | ❌ | ❌ | ✅ | ✅ | | Version löschen | ❌ | ❌ | ✅ | ✅ | ✅ | | Org-Einstellungen ändern | ❌ | ❌ | ❌ | ✅ | ✅ | | Org-Benutzer verwalten | ❌ | ❌ | ❌ | ✅ | ✅ | | Kanaleinstellungen ändern | ❌ | ❌ | ✅ | ✅ | ✅ | | Neue Version hochladen | ❌ | ✅ | ✅ | ✅ | ✅ | | Geräte ändern | ❌ | ❌ | ✅ | ✅ | ✅ | | Aktuelle Version des Kanals ändern | ❌ | ❌ | ✅ | ✅ | ✅ | | Neuen Kanal erstellen | ❌ | ❌ | ❌ | ✅ | ✅ | | Version ändern (Metadaten) | ❌ | ❌ | ✅ | ✅ | ✅ | | Abrechnung verwalten | ❌ | ❌ | ❌ | ❌ | ✅ | | Version unsicher löschen | ❌ | ❌ | ❌ | ❌ | ✅ | ### F: Wie funktioniert die Abrechnung innerhalb von Organisationen? Jeder mit einer **Super Admin**-Berechtigung kann die Abrechnung für eine bestimmte Organisation verwalten. Pläne sind mit einer Organisation und nicht mit Ihrem persönlichen Konto verknüpft. Danger ⚠️ Der Kauf eines Plans wirkt sich NUR auf die Organisation aus, die Sie aktuell ausgewählt haben ### F: Kann ich mehr als eine Organisation erstellen? Nein, noch nicht # Zahlungssystem > Zahlungsverwaltung in Ihrem Capgo-Konto. ## Worum geht es? Diese Seite beantwortet einige Fragen zum Zahlungssystem in capgo #### F: Wie kann ich meinen capgo-Plan upgraden? A: Sie können Ihren capgo-Plan upgraden, indem Sie zu [den Einstellungen](/docs/webapp/settings/#how-to-get-to-the-settings-page) gehen und auf die Schaltfläche **Pläne** klicken ![Choose plan](/plans-button.webp) Dann können Sie den Plan auswählen, der am besten zu Ihren Bedürfnissen passt, und auf **Abonnieren** klicken ![Subscribe to plan](/plans-subscribe.webp) Danach öffnet sich eine Stripe-Seite. Dort können Sie Ihre Zahlungsinformationen eingeben ![Stripe portal](/plans-stripe.webp) #### F: Sind die Zahlungen sicher? A: Ja, Zahlungen werden vollständig von Stripe verwaltet. Capgo erhält niemals Zugriff auf Ihre Kreditkartendaten. Stripe nimmt Sicherheit sehr ernst. [Mehr über Stripes Sicherheitsrichtlinien erfahren](https://stripecom/docs/security/) #### F: Wird capgo meinen Plan automatisch upgraden, wenn ich das Limit überschreite? A: Nein, capgo wird niemals Ihren Plan ändern #### F: Wird capgo mir eine E-Mail senden, wenn mein Plan seine Grenzen erreicht? A: Ja, capgo wird Ihnen eine E-Mail mit Informationen über die Nutzung senden #### F: Wird der von mir gekaufte Plan die Organisationen beeinflussen, zu denen ich eingeladen wurde? A: Nein, der Plan wird nur die Organisation beeinflussen, die Sie aktuell ausgewählt haben Bitte beachten Sie [die Organisations-Dokumentation](/docs/webapp/organization-system/#q-how-is-billing-done-within-orgs) #### F: Was, wenn ich einen maßgeschneiderten Plan benötige? A: [Bitte kontaktieren Sie den capgo-Support direkt](/docs/getting-help#support-by-chat) #### F: Wie sieht die Rückerstattungsrichtlinie für capgo aus? A: Eine Rückerstattungsrichtlinie finden Sie [hier](https://capgo.app/return/) # Impostazioni > So ändern Sie die Benutzereinstellungen ## So gelangen Sie zur Einstellungsseite Klicken Sie zuerst auf **VORNAME NACHNAME**. In meinem Fall ist das **test Capgo**. In Ihrem Fall wird das Ihr Vorname und dann Ihr Nachname sein. Klicken Sie dann auf **Einstellungen** ![open settings](/settings-go.webp) ## Benutzereinstellungen ändern Um Benutzereinstellungen zu ändern, füllen Sie einfach das Formular im Konto aus und klicken Sie dann auf **Aktualisieren** ![save change in account](/account-save.webp) Dann sollte eine Bestätigung erscheinen ![acount updated](/account-updated.webp) ## Passwort ändern Um das Passwort zu ändern, gehen Sie zur Einstellungsseite und klicken Sie auf **Passwort**. Füllen Sie dann das Formular aus und klicken Sie auf **Aktualisieren** ![update password](/update-passwd.webp) Wenn das Passwort nicht den Capgo-Passwort-Sicherheitsregeln entspricht, erhalten Sie eine Fehlermeldung ![wrong password](/passwd-error.webp) # Welcome to Capgo Documentation > Master Capgo Cloud for instant app updates and explore our comprehensive collection of Capacitor plugins to enhance your mobile development ## 🚀 Capgo Cloud - Live Updates Made Simple Instant Updates Deploy JavaScript, HTML, and CSS updates directly to users without app store delays. Fix bugs and ship features in minutes, not days. 3-Step Integration Get started with just `npx @capgo/cli@latest init [APIKEY]` and start pushing updates immediately with our simple integration. Advanced Features Channels for A/B testing, automatic rollbacks, update analytics, encrypted bundles, and enterprise-grade security features. Complete Guide Learn everything from [quick setup](/docs/getting-started/quickstart/) to advanced deployment strategies in our comprehensive documentation. ## 📚 What’s in This Documentation [Capgo Cloud Setup ](/docs/getting-started/quickstart/)Complete guides for integrating live updates, managing channels, CI/CD integration, and monitoring your deployments. [20+ Capacitor Plugins ](/docs/plugins/)Explore our collection of production-ready plugins for biometrics, purchases, camera, storage, and more native features. [CLI & Public API ](/docs/cli/overview/)Automate your workflow with our CLI tools and integrate Capgo into your existing systems with our REST API. [Enterprise Solutions ](/enterprise/)Dedicated support, SLAs, custom features, and advanced security options for teams that need more. ## 🎯 Quick Links * **First time?** Start with the [5-minute quickstart](/docs/getting-started/quickstart/) * **Need a plugin?** Browse our [plugin collection](/docs/plugins/) or request [custom development](/consulting/) * **Having issues?** Check the [FAQ](/docs/faq/) or join our [Discord](https://discord.capgo.app) * **Enterprise needs?** Check our [enterprise solutions](/enterprise/) or [contact us](mailto:support@capgo.app) # Commands > Capgo CLI documentation, how to use it and what is used for ### Usage All command should be run in your app folder with capacitor project ignited properly. [Capacitor Cross-platform native runtime for web apps ](https://capacitorjs.com/docs/getting-started/) ### **Init** `npx @capgo/cli@latest init [apikey]` This method is here to onboard you step by step. It will add your app to Capgo. It will add the code to your app to validate the update. Likewise, it will build your app. Furthermore, it will upload your app to Capgo. And it will help you to check if the update works. ### **Login** `npx @capgo/cli login [apikey]` This method is here to remember the `apikey` for you. Note use `--apikey=********` in any command to override it **Optionaly you can give:** `--local` This will store your **apikey** in the local repo and git ignore it. ## **Doctor** `npx @capgo/cli doctor` Command to check if you are up-to-date with Capgo packages. This command will also be useful for bug report. ## App ### **Add** `npx @capgo/cli app add [appId]` `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/commands/init/). > 💡 All option will be guessed in your config if not provided. Optionally, you can give: * `--icon [/path/to/my/icon]` to have a custom icon display in Capgo web app. * `--name [test]` to have a custom name in the list. * `--apikey [key]` API key to link to your account. * `--retention [retention]` retention period of app bundle in days, 0 by default = infinite. Example of `capacitor.config.json` for appId and AppName, the icon is guess in the resources folder ```json { "appId": "ee.forgr.capacitor_go", "appName": "Capgo", "webDir": "dist" } ``` ### **Set** `npx @capgo/cli app set [appId]` `[appId]` is your app ID, the format is explained [here](https://capacitorjs.com/docs/cli/commands/init/). Optionally, you can give: * `--icon [/path/to/my/icon]` to have a custom icon display in Capgo web app. * `--name [test]` to have a custom name in the list. * `--retention [retention]` retention period of app bundle in days, 0 by default = infinite. * `--apikey [key]` API key to link to your account. ### **List** `npx @capgo/cli app list [appId]` `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/commands/init/). Optionally, you can give: * `--apikey [key]` API key to link to your account. ### **Delete** `npx @capgo/cli app delete [appId]` `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/commands/init/). Optionally, you can give: * `--apikey [key]` API key to link to your account. * `--bundle` with the version number will only delete this version. ### Debug `npx @capgo/cli app debug [appId]` `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/commands/init/). Optionally, you can give: * `--apikey [key]` API key to link to your account. * `--device` with the specific device you want to debug ### Setting `npx @capgo/cli app setting [path]` Edit the Capacitor config. `[path]` - path of the setting that you would like to change. For example, to change the `appId`, provide `appId`. If you wish to disable auto update in the `capacitor-updater` provide `plugins.CapacitorUpdater.autoUpdate` You MUST provide either `--string` or `--bool`! Options: * `--string ` - sets the setting to a string * `--bool ` - sets the setting to a boolean ## Bundle ### Upload `npx @capgo/cli bundle upload [appId]` `[appId]` is your app ID, the format is explained [here](https://capacitorjs.com/docs/cli/commands/init/). Optionally, you can give: * `--apikey ` API key to link to your account. * `--path ` Path of the folder to upload. * `--channel ` Channel to link to. * `--external ` Link to external URL instead of uploading to Capgo Cloud. * `--iv-session-key ` Set the IV and session key for bundle URL external. * `--s3-endpoint ` URL of S3 endpoint. Do not work with Partial upload, or external option. * `--s3-region ` Region for your S3 bucket. * `--s3-apikey ` API key for your S3 endpoint. * `--s3-apisecret ` API secret for your S3 endpoint. * `--s3-bucket-name ` Name for your AWS S3 bucket. * `--s3-port ` Port for your S3 endpoint. * `--no-s3-ssl` Disable SSL for S3 upload. * `--key ` Custom path for public signing key (v1 system). * `--key-data ` Public signing key (v1 system). * `--key-v2 ` Custom path for private signing key (v2 system). * `--key-data-v2 ` Private signing key (v2 system). * `--bundle-url` Prints bundle URL into stdout. * `--no-key` Ignore signing key and send clear update. * `--no-code-check` Ignore checking if notifyAppReady() is called in source code and index present in root folder. * `--display-iv-session` Show in the console the IV and session key used to encrypt the update. * `--bundle ` Bundle version number of the bundle to upload. * `--min-update-version ` Minimal version required to update to this version. Used only if the disable auto update is set to metadata in channel. * `--auto-min-update-version` Set the min update version based on native packages. * `--ignore-metadata-check` Ignores the metadata (node\_modules) check when uploading. * `--ignore-checksum-check` Ignores the checksum check when uploading. * `--timeout ` Timeout for the upload process in seconds. * `--delta` Uploads delta files alongside the full bundle (legacy flag – identical to `--partial`). * `--tus` Upload the bundle using tus protocol. * `--multipart` Uses multipart protocol to upload data to S3, Deprecated, use TUS instead. * `--encrypted-checksum ` An encrypted checksum (signature). Used only when uploading an external bundle. * `--package-json ` A path to package.json. Usefull for monorepos. * `--auto-set-bundle` Set the bundle in capacitor.config.json. * `--node-modules ` A list of path to node\_modules. Usefull for monorepos (comma separated ex: ../../node\_modules,./node\_modules) > ⭐️ External option helps to unlock 2 cases: corporate with privacy concern, don’t send the code to a third part and app bigger than 200 MB. With this setting, Capgo store only the link to the zip and sends the link to all apps. > 👀 Capgo cloud never looks at what is in the link (for external option), or in the code when stored. > 🔑 You can add a second layer of security by using encryption, then Capgo will not be able to look or modify anything, it becomes “trustless”. Example of `package.json` for version ```json { "version": "1.0.2" } ``` > ⛔ Version should be greater than “0.0.0”. > 💡 Don’t forget to update the version number each time you send one, version number cannot be overridden, or reused after deletion for security reason. ### **List** `npx @capgo/cli bundle list [appId]` `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/commands/init/). Optionally, you can give: * `--apikey [key]` API key to link to your account. ### **Delete** `npx @capgo/cli bundle delete [appId]` `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/commands/init/). Optionally, you can give: * `--apikey [key]` API key to link to your account. * `--bundle` with the version number will only delete this version. ### Cleanup in a SemVer range for a major version to Cloud `npx @capgo/cli bundle cleanup [appId] --bundle=[majorVersion] --keep=[numberToKeep]` `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/commands/init/). Optionally, you can give: * `--apikey [key]` API key to link to your account. * `--bundle [majorVersion]` a version you wish to remove previous packages for, it will keep the last one + `numberToKeep`. * `--keep [numberToKeep]` the number of packages you wish to keep (default 4). For example: If you have 10 versions from 10.0.1 to 10.0.11, and you use `npx @capgo/cli cleanup [appId] --bundle=10.0.0` it will remove 10.0.1 to 10.0.6. 10.0.7 until 10.0.11 will be kept. If you have 20 versions in total, and you don’t provide a bundle number like this: `npx @capgo/cli cleanup [appId] --keep=2` It will remove 18 versions, and keep the last 2. > This command will ask for confirmation, it shows a table of what it will be keeping and removing. Note This command will ignore bundles which are currently in use in any channel. ### **Encrypt** > **Warning**: This command is deprecated and will be removed in the next major release. Please use the new encryption system. `npx @capgo/cli bundle encrypt [path/to/zip]` This command is used when you use external source to store your code or for test purpose. Optionally, you can give: `--key [/path/to/my/private_key]` the path of your private key. `--key-data [privateKey]` the private key data, if you want to use inline. The command will print your `ivSessionKey`y and generate an encrypted zip, to use it with the upload command or decryt command. ### **Encrypt V2** `npx @capgo/cli bundle encrypt [path/to/zip] [checksum]` This command is used when you use external source to store your code or for test purpose. The checksum is the sha256 of the bundle (generated by —key-v2), it is used to verify the integrity of the file after decryption. It will be enncrypted with the private key and sent along with the bundle. In encryption v2 the checksum is upgraded to become a “signature” of the bundle. Optionally, you can give: `--key [/path/to/my/private_key]` the path of your private key. `--key-data [privateKey]` the private key data, if you want to use inline. `--json` to output info as json. The command will print your `ivSessionKey`y and generate an encrypted zip, to use it with the upload command or decryt command. ### **Decrypt** `npx @capgo/cli bundle decrypt [path/to/zip] [ivSessionKey]` Optionally, you can give: `--key [/path/to/my/private_key]` the path of your private key. `--key-data [privateKey]` the private key data, if you want to use inline. This command is mainly used for test purpose, it will decrypt the zip and print the base64 decrypted session key in the console. ### **Decrypt V2** `npx @capgo/cli bundle decryptV2 [path/to/zip] [ivSessionKey]` Optionally, you can give: `--key [/path/to/my/private_key]` the path of your private key. `--key-data [privateKey]` the private key data, if you want to use inline. This command is mainly used for test purpose, it will decrypt the zip and print the base64 decrypted session key in the console. `--checksum [checksum]` the checksum of the file, it will verify the checksum after decryption. ### **Zip** `npx @capgo/cli bundle zip [appId]` `[appId]` is your app ID, the format is explained [here](https://capacitorjs.com/docs/cli/commands/init/). Optionally, you can give: * `--path [/path/to/my/bundle]` to upload a specific folder. * `--bundle [1.0.0]` to set the bundle version number of the filename. * `--name [myapp]` to override the filename. * `--json` to output info as json. * `--no-code-check` to ignore the code check and send the bundle anyway. * `--key-v2` to use the new encryption system. This is required as new encryption system use better checksums to verify the integrity of the file. ### **Compatibility** `npx @capgo/cli bundle compatibility [appId] -c [channelId]` `[appId]` is your app ID, the format is explained [here](https://capacitorjs.com/docs/cli/commands/init/). `[channelId]` the name of your new channel. Optionally, you can give: * `--apikey [key]` API key to link to your account. * `--text` use text instead of emojis in the table * `--channel [channel]` the channel to check the compatibility with. * `--package-json ` A path to package.json. Usefull for monorepos * `--node-modules ` A list of path to node\_modules. Usefull for monorepos (comma separated ex: ../../node\_modules,./node\_modules) ## Channel ### **Add** `npx @capgo/cli channel add [channelId] [appId]` `[channelId]` the name of your new channel. `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/commands/init/). ### **Delete** `npx @capgo/cli channel delete [channelId] [appId]` `[channelId]` the name of your channel you want to delete. `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/commands/init/). ### **List** `npx @capgo/cli channel list [appId]` `[appId]` your app ID the format `com.test.app` is explained [here](https://capacitorjs.com/docs/cli/commands/init/). Optionally, you can give: * `--apikey [key]` API key to link to your account. ### **Set** `npx @capgo/cli channel set [channelId] [appId]` `[appId]` is your app ID, the format is explained [here](https://capacitorjs.com/docs/cli/commands/init/). Optionally, you can give: * `--bundle [1.2.3]` your app bundle already sent to the cloud, to link it to a channel. * `--latest` get the bundle version from `package.json:version`, cannot be used with `--bundle`. * `--state [ normal | default ]` set the channel state, can be `normal` or `default`. One channel needs to be `default`. * `--downgrade` allows the channel to send downgrade version to devices. * `--no-downgrade` disallows the channel to send downgrade version to devices. * `--upgrade` allows the channel to send upgrade (major) version to devices. * `--no-upgrade` disallow the channel to send upgrade (major) version to devices. * `--ios` allows the channel to send version to iOS devices. * `--no-ios` disallows the channel to send version to iOS devices. * `--android` allows the channel to send version to android devices. * `--no-android` disallows the channel to send version to android devices. * `--self-assign` allows devices to self assign to this channel. * `--no-self-assign` disallows devices to self assign to this channel. * `--disable-auto-update STRATEGY` Disable auto update strategy for this channel. The possible options are: major, minor, metadata, none. * `--apikey [key]` API key to link to your account. ## Disable updates strategy There are a few ways to handle disabling updates for too old versions.\ Capgo cannot update native code thus an update from a version with the old native code to a version with the updated native code should not be possible. There are a couple of ways to achieve that. First, the `major` strategy. It prevents an update from `0.0.0` -> `1.0.0`. The major is the highlighted number (**1**.0.0 and **0**.0.0).\ Second is the `minor` strategy. It prevents an update from `0.0.0` -> `1.1.0` or an update from `1.1.0` to `1.2.0`. **BE AWARE** this strategy does not prevent an update from `0.1.0` -> `1.1.0` Third, the `patch` strategy. It was added into capgo as a very strict mode. It’s not recomended to be used unless you fully understand how it works. In order for it to accept a update the following conditions must be meet: * The major is the same between the new and the old version * The minor is the same between the new and the old version * The patch of the new version if greater then the patch of the old version Here is an example of which scenarios the update is allowed or denied * 0.0.311 -> 0.0.314 ✅ * 0.0.0 -> 0.0.314 ✅ * 0.0.316 -> 0.0.314 ❌ * 0.1.312 -> 0.0.314 ❌ * 1.0.312 -> 0.0.314 ❌ Lastly the most complicated strategy. The `metadata` strategy.\ First you need to know that initially after you enable it the updates **WILL** fail as the channel is lacking the required metadata.\ If the channel is lacking metadata you will see a message like this: ![Cannot find metadata](/fail-metadata.webp) If you see something like this you know that you have to go to the current bundle for the failing channel and set the metadata.\ First, figure out what channel is failing. You can do that by looking at the `misconfigured` column ![Misconfigured table](/misconfigured-table.webp) Then go to the failing channel and click on `Bundle number`. This should take you to the bundle page. ![Locate failing channel](/fail-channel-show.webp) Once there fill the `Minimal update version` field. This should be a [semver](https://devhints.io/semver/).\ If the value you pass is not a semver you will get an error, but if everything goes correctly you should see something like this: ![Set min version](/set-min-update-version.webp) Now, you likely do not want to set this data manually every time you update. Fortunately, the CLI will prevent you from sending an update without this metadata ![CLI fail no metadata](/cli-fail-no-metadata.webp) To properly upload a bundle when using the `metadata` option you need to pass the `--min-update-version` with the valid semver. Something like this: ![CLI upload with metadata](/cli-upload-with-metadata.webp) The `--min-update-version` is not the ONLY way to do compatibility. There also exists the `--auto-min-update-version`. Here is how it works. First, it takes a look at the version curently uploaded to the channel. It checks compatibility same as `bundle compatibility` command would. Second, if the new version is 100% compatible it reuses the `min_update_version` from the latest version in the channel. If not, then it sets the `min_update_version` to the bundle number of the newly uploaded version. You will always get an information what is the `min_update_version` when using this option. It will look something like this: ![Min update version](/min_update_version_info.webp) If the new version is not compatible it should look something like this ![Min update version not compatible](/min_update_version_not_compatible.webp) ## End-to-End encryption (Trustless) Capgo supports end-to-end encryption, this means that your bundle(code) is encrypted before sent to the cloud and decrypted on the device. For that, you need to generate an RSA key pair, you can use the following command to generate it. The encryption system is a combination of RSA and AES, the RSA key is used to encrypt the AES key, and the AES key is used to encrypt the file. See below for more information about the encryption system. ![How crypto works](/crypto_explained.webp) Ecryption schema ### Create key for your app `npx @capgo/cli key create` Optionally, you can give: `--force` to overwrite the existing key. This command will create for you a key pair in your app, and will ask you to save the private key in a safe place. It’s recommended to not git commit the private key, and to not share it with anyone. > After your local test, remove the key from the config file and add it on the CI step with `key save` ### Save key in your app config `npx @capgo/cli key save` Optionally, you can give: `--key [/path/to/my/public_key]` the path of your public key file. `--key-data [publicKey]` the public key data, if you want to use inline. This command is useful if you followed the recommendation and didn’t commit the key in your app config. ## Ci integration To automate your work, I recommend you make GitHub action do the job of pushing to our server [GitHub action tutorial](https://capgo.app/blog/automatic-build-and-release-with-github-actions/) ## Our demo app [GitHub - Cap-go/demo-app](https://github.com/Cap-go/demo-app/) Don’t forget to configure CI env variable with your API key # CLI From 0.x to 1.x > How to upgrade from 0.x to 1.x, of the updater of Capgo, learn what are the breaking changes and how to handle them There are no significant changes in the CLI. The breaking change is mainly the rename of the argument `--version` to `--bundle` to avoid conflict, and follow the new naming everywhere. # Encryption > How to encrypt your data with encryption v2, secure your app and ensure only you can update your users with your updates This documentation explains how to migrate to the encryption v2 system. Learn more about the encryption v2 system in the [blog post](/blog/introducing-end-to-end-security-to-capacitor-updater-with-code-signing). ## 1. Create Key Pair ```bash npx @capgo/cli key create ``` Store the private key securely. Never commit it to source control or share it with untrusted parties. This command: * Creates a new key pair in your app * Removes the old key from your Capacitor config * Keeps old key files for backward compatibility ## 2. Update Capacitor Config When prompted “Do you want to setup encryption with the new channel in order to support old apps and facilitate the migration?”, select yes. This adds a new `defaultChannel` option to your Capacitor config. capacitor.config.ts ```ts import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { appId: 'com.example.app', appName: 'Example App', plugins: { CapacitorUpdater: { // ... other options defaultChannel: 'encryption_v2' // New apps will use this channel } } }; export default config; ``` ## 3. Upload Bundle to New Channel ```bash npx @capgo/cli bundle upload --channel encryption_v2 ``` ## 4. Enable Self-Assignment Caution Required for the `defaultChannel` option to work ```bash npx @capgo/cli channel set encryption_v2 --self-assign ``` ## 5. Upload to Old Channel ```bash npx @capgo/cli bundle upload --channel production ``` Tip Capacitor config is never uploaded to Capgo ## 6. Cleanup (After 3-4 Months) Once all users have updated their apps: 1. Remove `defaultChannel` from your Capacitor config 2. Delete the old channel: ```bash npx @capgo/cli channel delete encryption_v2 ``` Note Apps using `encryption_v2` as default will switch to `production` channel after deletion # Overview > This document provides a comprehensive overview of the Capgo CLI, how it can be utilized to enhance your app development process by enabling seamless live updates Use Capgo’s Live Updates feature to update the JavaScript bundles of your app remotely, in real-time. Push JS updates directly to your users without going through the app store review process to instantly fix bugs and ship new features. Note Live Updates are limited to JavaScript bundle changes. If you need to update native code, such as adding or removing a plugin or changing native project configuration, you’ll need to submit a new native binary build to the app stores. ## How Live Updates Work Capgo’s Live Update system has two key components: 1. The Capgo SDK, which you install in your app. The SDK checks for available updates and downloads them in the background. 2. Channels, which let you target updates to specific groups of users. You can use channels to manage different release tracks, such as `Production`, `Staging`, and `Dev`. When you upload a new JS bundle to Capgo and assign it to a channel, the Capgo SDK in apps configured for that channel will detect the update and download it. The next time the app restarts, the new bundle will be loaded. ## Getting Started To start using Live Updates, follow these steps: 1. Complete the [Capgo Quickstart](/docs/getting-started/quickstart) to set up your app in Capgo and install the Capgo SDK. 2. In your app code, call `CapacitorUpdater.notifyAppReady()` after your app has finished initializing. This tells the Capgo SDK that your app is ready to receive updates. 3. Build your JS bundle and upload it to Capgo: ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. Open your app and wait for the update to download. You can check the status with: ```shell npx @capgo/cli@latest app debug ``` 5. Once the update is downloaded, close and reopen your app to load the new bundle. See the [Deploying Live Updates](/docs/getting-started/deploy) guide for more details. ## The Capgo CLI The Capgo CLI is a powerful tool that allows developers to interact with Capgo’s services from their own CI/CD pipelines. With the CLI, you have granular control over when builds are produced and deployed, enabling you to integrate Capgo into your existing enterprise workflows. ### What is the Capgo CLI for? The Capgo CLI is designed for developers and teams who need more control and flexibility in their live update workflows. By using the CLI in your CI/CD pipelines, you can: * Decide exactly when to build and deploy updates, rather than relying on Capgo’s built-in automation * Insert your own processes, such as code signing, QA testing, or manager approvals, between the build and deploy steps * Integrate Capgo into your existing DevOps tooling and workflows ### Authentication To use the Capgo CLI, you’ll need to authenticate with your API key. You can generate an API key in your Capgo account settings. To log in and securely store your API key, run: ```shell npx @capgo/cli@latest login [API_KEY] ``` This command will then be saved for future use. You won’t need to provide your API key with each command after logging in. ### Key Differences from Other CLI Tools If you’re familiar with other live update CLI tools, there are a few key things to note about Capgo’s CLI: * Capgo uses a single CLI for both development and CI/CD use cases, as Capgo is focused solely on the live update feature set. * The Capgo CLI doesn’t require a separate installation step. It’s bundled with the `@capgo/cli` package and can be run directly using `npx`. * Capgo’s CLI is designed specifically for the live update workflow, so it may not include some features or commands found in more general-purpose CLI tools. ## Next Steps [ Channels](/docs/live-updates/channels/) [Learn how to use channels to manage different release tracks and target updates to specific users.](/docs/live-updates/channels/) [ Rollbacks](/docs/live-updates/rollbacks/) [Discover how to roll back to a previous JS bundle version if an update causes issues.](/docs/live-updates/rollbacks/) [ Update Behavior](/docs/live-updates/update-behavior/) [Customize how and when updates are downloaded and applied in your app.](/docs/live-updates/update-behavior/) [ Fast Updates](/docs/live-updates/differentials/) [Learn how to use fast updates to speed up the update process.](/docs/live-updates/differentials/) # Overview > Detailed documentation for the Capgo CLI commands The Capgo CLI provides a set of commands for managing your Capgo apps and deployments. This reference provides detailed information about each available command, including its options and usage examples. ## Commands [ init](/docs/cli/reference/init/) [Initialize a new Capgo app](/docs/cli/reference/init/) [ bundle](/docs/cli/reference/bundle/) [Manage your app bundles](/docs/cli/reference/bundle/) [ login](./login/) [Authenticate with the Capgo service](./login/) [ doctor](/docs/cli/reference/doctor/) [Check your Capgo setup for potential issues](/docs/cli/reference/doctor/) [ app](./app/) [Manage your Capgo apps](./app/) [ channel](/docs/cli/reference/channel/) [Manage your release channels](/docs/cli/reference/channel/) [ key](/docs/cli/reference/key/) [Manage your app signing keys](/docs/cli/reference/key/) ## CI Integration To automate your work, we recommend using GitHub Actions to push your updates to Capgo. Check out our [GitHub Actions tutorial](https://capgo.app/blog/automatic-build-and-release-with-github-actions/) for more information. Don’t forget to configure your CI environment variables with your Capgo API key. ## Demo App For a complete example of a Capgo app with CI integration, check out our [demo app on GitHub](https://github.com/Cap-go/demo-app/). # 👤 account > 👤 Manage your Capgo account details and retrieve information for support or collaboration. 👤 Manage your Capgo account details and retrieve information for support or collaboration. ### []()🔹 **Id** ```bash npx @capgo/cli@latest account id ``` 🪪 Retrieve your account ID, safe to share for collaboration or support purposes in Discord or other platforms. **Example:** ```bash npx @capgo/cli@latest account id ``` **Options:** | Param | Type | Description | | ------- | -------- | ------------------------------- | | **-a,** | `string` | API key to link to your account | # 📱 app > 📱 Manage your Capgo app settings and configurations in Capgo Cloud. 📱 Manage your Capgo app settings and configurations in Capgo Cloud. ### []()➕ **Add** **Alias:** `a` ```bash npx @capgo/cli@latest app add ``` ➕ Add a new app to Capgo Cloud with a unique app ID in the format com.test.app. All options can be guessed from config if not provided. **Example:** ```bash npx @capgo/cli@latest app add com.example.app --name "My App" --icon ./icon.png ``` **Options:** | Param | Type | Description | | -------------- | -------- | ---------------------------------------------------------------- | | **-n,** | `string` | App name for display in Capgo Cloud | | **-i,** | `string` | App icon path for display in Capgo Cloud | | **-a,** | `string` | API key to link to your account | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()🗑️ **Delete** ```bash npx @capgo/cli@latest app delete ``` 🗑️ Delete an app from Capgo Cloud, optionally specifying a version to delete only that bundle. **Example:** ```bash npx @capgo/cli@latest app delete com.example.app ``` **Options:** | Param | Type | Description | | -------------- | -------- | ---------------------------------------------------------------- | | **-a,** | `string` | API key to link to your account | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()📋 **List** **Alias:** `l` ```bash npx @capgo/cli@latest app list ``` 📋 List all apps registered under your account in Capgo Cloud. **Example:** ```bash npx @capgo/cli@latest app list ``` **Options:** | Param | Type | Description | | -------------- | -------- | ---------------------------------------------------------------- | | **-a,** | `string` | API key to link to your account | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()🐞 **Debug** ```bash npx @capgo/cli@latest app debug ``` 🐞 Listen for live update events in Capgo Cloud to debug your app. Optionally target a specific device for detailed diagnostics. **Example:** ```bash npx @capgo/cli@latest app debug com.example.app --device DEVICE_ID ``` **Options:** | Param | Type | Description | | -------------- | -------- | ---------------------------------------------------------------- | | **-a,** | `string` | API key to link to your account | | **-d,** | `string` | The specific device ID to debug | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()⚙️ **Setting** ```bash npx @capgo/cli@latest app setting ``` ⚙️ Modify Capacitor configuration programmatically. Specify setting path (e.g., plugins.CapacitorUpdater.defaultChannel) with —string or —bool. **Example:** ```bash npx @capgo/cli@latest app setting plugins.CapacitorUpdater.defaultChannel --string "Production" ``` **Options:** | Param | Type | Description | | ----------- | -------- | ----------------------------------------------------------------------- | | **—bool** | `string` | A value for the setting to modify as a boolean, ex: —bool true | | **—string** | `string` | A value for the setting to modify as a string, ex: —string “Production” | ### []()⚙️ **Set** **Alias:** `s` ```bash npx @capgo/cli@latest app set ``` ⚙️ Update settings for an existing app in Capgo Cloud, such as name, icon, or retention period for bundles. Retention of 0 means infinite storage. **Example:** ```bash npx @capgo/cli@latest app set com.example.app --name "Updated App" --retention 30 ``` **Options:** | Param | Type | Description | | -------------- | -------- | ---------------------------------------------------------------- | | **-n,** | `string` | App name for display in Capgo Cloud | | **-i,** | `string` | App icon path for display in Capgo Cloud | | **-a,** | `string` | API key to link to your account | | **-r,** | `string` | Days to keep old bundles (0 = infinite, default: 0) | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | # 📦 bundle > 📦 Manage app bundles for deployment in Capgo Cloud, including upload, compatibility checks, and encryption. 📦 Manage app bundles for deployment in Capgo Cloud, including upload, compatibility checks, and encryption. ### []()⬆️ **Upload** **Alias:** `u` ```bash npx @capgo/cli@latest bundle upload ``` ⬆️ Upload a new app bundle to Capgo Cloud for distribution. Version must be > 0.0.0 and unique. Deleted versions cannot be reused for security. External option: Store only a URL link (useful for apps >200MB or privacy requirements). Capgo never inspects external content. Add encryption for trustless security. **Example:** ```bash npx @capgo/cli@latest bundle upload com.example.app --path ./dist --channel production ``` **Options:** | Param | Type | Description | | ----------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------- | | **-a,** | `string` | API key to link to your account | | **-p,** | `string` | Path of the folder to upload, if not provided it will use the webDir set in capacitor.config | | **-c,** | `string` | Channel to link to | | **-e,** | `string` | Link to external URL instead of upload to Capgo Cloud | | **—iv-session-key** | `string` | Set the IV and session key for bundle URL external | | **—s3-region** | `string` | Region for your S3 bucket | | **—s3-apikey** | `string` | API key for your S3 endpoint | | **—s3-apisecret** | `string` | API secret for your S3 endpoint | | **—s3-endpoint** | `string` | URL of S3 endpoint | | **—s3-bucket-name** | `string` | Name for your AWS S3 bucket | | **—s3-port** | `string` | Port for your S3 endpoint | | **—no-s3-ssl** | `boolean` | Disable SSL for S3 upload | | **—key-v2** | `string` | Custom path for private signing key (v2 system) | | **—key-data-v2** | `string` | Private signing key (v2 system) | | **—bundle-url** | `boolean` | Prints bundle URL into stdout | | **—no-key** | `boolean` | Ignore signing key and send clear update | | **—no-code-check** | `boolean` | Ignore checking if notifyAppReady() is called in source code and index present in root folder | | **—display-iv-session** | `boolean` | Show in the console the IV and session key used to encrypt the update | | **-b,** | `string` | Bundle version number of the bundle to upload | | **—link** | `string` | Link to external resource (e.g. GitHub release) | | **—comment** | `string` | Comment about this version, could be a release note, a commit hash, a commit message, etc. | | **—min-update-version** | `string` | Minimal version required to update to this version. Used only if the disable auto update is set to metadata in channel | | **—auto-min-update-version** | `boolean` | Set the min update version based on native packages | | **—ignore-metadata-check** | `boolean` | Ignores the metadata (node\_modules) check when uploading | | **—ignore-checksum-check** | `boolean` | Ignores the checksum check when uploading | | **—timeout** | `string` | Timeout for the upload process in seconds | | **—multipart** | `boolean` | \[DEPRECATED] Use —tus instead. Uses multipart protocol for S3 uploads | | **—zip** | `boolean` | Upload the bundle using zip to Capgo cloud (legacy) | | **—tus** | `boolean` | Upload the bundle using TUS to Capgo cloud | | **—tus-chunk-size** | `string` | Chunk size in bytes for TUS resumable uploads (default: auto) | | **—partial** | `boolean` | \[DEPRECATED] Use —delta instead. Upload incremental updates | | **—partial-only** | `boolean` | \[DEPRECATED] Use —delta-only instead. Upload only incremental updates, skip full bundle | | **—delta** | `boolean` | Upload incremental/differential updates to reduce bandwidth | | **—delta-only** | `boolean` | Upload only delta updates without full bundle (useful for large apps) | | **—encrypted-checksum** | `string` | An encrypted checksum (signature). Used only when uploading an external bundle. | | **—auto-set-bundle** | `boolean` | Set the bundle in capacitor.config.json | | **—dry-upload** | `boolean` | Dry upload the bundle process, mean it will not upload the files but add the row in database (Used by Capgo for internal testing) | | **—package-json** | `string` | Paths to package.json files for monorepos (comma-separated) | | **—node-modules** | `string` | Paths to node\_modules directories for monorepos (comma-separated) | | **—encrypt-partial** | `boolean` | Encrypt delta update files (auto-enabled for updater > 6.14.4) | | **—delete-linked-bundle-on-upload** | `boolean` | Locates the currently linked bundle in the channel you are trying to upload to, and deletes it | | **—no-brotli-patterns** | `string` | Files to exclude from Brotli compression (comma-separated globs, e.g., “*.jpg,*.png”) | | **—disable-brotli** | `boolean` | Completely disable brotli compression even if updater version supports it | | **—version-exists-ok** | `boolean` | Exit successfully if bundle version already exists, useful for CI/CD workflows with monorepos | | **—self-assign** | `boolean` | Allow devices to auto-join this channel (updates channel setting) | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()🧪 **Compatibility** ```bash npx @capgo/cli@latest bundle compatibility ``` 🧪 Check compatibility of a bundle with a specific channel in Capgo Cloud to ensure updates are safe. **Example:** ```bash npx @capgo/cli@latest bundle compatibility com.example.app --channel production ``` **Options:** | Param | Type | Description | | ----------------- | --------- | ------------------------------------------------------------------ | | **-a,** | `string` | API key to link to your account | | **-c,** | `string` | Channel to check the compatibility with | | **—text** | `boolean` | Output text instead of emojis | | **—package-json** | `string` | Paths to package.json files for monorepos (comma-separated) | | **—node-modules** | `string` | Paths to node\_modules directories for monorepos (comma-separated) | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()🗑️ **Delete** **Alias:** `d` ```bash npx @capgo/cli@latest bundle delete ``` 🗑️ Delete a specific bundle from Capgo Cloud, optionally targeting a single version. **Example:** ```bash npx @capgo/cli@latest bundle delete BUNDLE_ID com.example.app ``` **Options:** | Param | Type | Description | | -------------- | -------- | ---------------------------------------------------------------- | | **-a,** | `string` | API key to link to your account | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()📋 **List** **Alias:** `l` ```bash npx @capgo/cli@latest bundle list ``` 📋 List all bundles uploaded for an app in Capgo Cloud. **Example:** ```bash npx @capgo/cli@latest bundle list com.example.app ``` **Options:** | Param | Type | Description | | -------------- | -------- | ---------------------------------------------------------------- | | **-a,** | `string` | API key to link to your account | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()🧹 **Cleanup** **Alias:** `c` ```bash npx @capgo/cli@latest bundle cleanup ``` 🧹 Delete old bundles in Capgo Cloud, keeping specified number of recent versions. Bundles linked to channels are preserved unless —ignore-channel is used. **Example:** ```bash npx @capgo/cli@latest bundle cleanup com.example.app --bundle=1.0 --keep=3 ``` **Options:** | Param | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------- | | **-b,** | `string` | Bundle version number of the app to delete | | **-a,** | `string` | API key to link to your account | | **-k,** | `string` | Number of versions to keep | | **-f,** | `string` | Force removal | | **—ignore-channel** | `boolean` | Delete bundles even if linked to channels (WARNING: deletes channels too) | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()🔒 **Encrypt** ```bash npx @capgo/cli@latest bundle encrypt ``` 🔒 Encrypt a zip bundle for secure external storage. Returns ivSessionKey for upload/decryption. Get checksum using ‘bundle zip —json’. **Example:** ```bash npx @capgo/cli@latest bundle encrypt ./myapp.zip CHECKSUM ``` **Options:** | Param | Type | Description | | ------------- | -------- | ----------------------------------- | | **—key** | `string` | Custom path for private signing key | | **—key-data** | `string` | Private signing key | | **-j,** | `string` | Output in JSON | ### []()🔓 **Decrypt** ```bash npx @capgo/cli@latest bundle decrypt ``` 🔓 Decrypt an encrypted bundle (mainly for testing). Prints base64 session key for verification. **Example:** ```bash npx @capgo/cli@latest bundle decrypt ./myapp_encrypted.zip CHECKSUM ``` **Options:** | Param | Type | Description | | ------------- | -------- | ------------------------------------------------------------- | | **—key** | `string` | Custom path for private signing key | | **—key-data** | `string` | Private signing key | | **—checksum** | `string` | Checksum of the bundle, to verify the integrity of the bundle | ### []()🔹 **Zip** ```bash npx @capgo/cli@latest bundle zip ``` 🗜️ Create a zip file of your app bundle. Returns checksum for use with encryption. Use —json for machine-readable output. **Example:** ```bash npx @capgo/cli@latest bundle zip com.example.app --path ./dist ``` **Options:** | Param | Type | Description | | ------------------ | --------- | --------------------------------------------------------------------------------------------- | | **-p,** | `string` | Path of the folder to upload, if not provided it will use the webDir set in capacitor.config | | **-b,** | `string` | Bundle version number to name the zip file | | **-n,** | `string` | Name of the zip file | | **-j,** | `string` | Output in JSON | | **—no-code-check** | `boolean` | Ignore checking if notifyAppReady() is called in source code and index present in root folder | | **—key-v2** | `boolean` | Use encryption v2 | | **—package-json** | `string` | Paths to package.json files for monorepos (comma-separated) | # 📢 channel > 📢 Manage distribution channels for app updates in Capgo Cloud, controlling how updates are delivered to devices. 📢 Manage distribution channels for app updates in Capgo Cloud, controlling how updates are delivered to devices. ### []()➕ **Add** **Alias:** `a` ```bash npx @capgo/cli@latest channel add ``` ➕ Create a new channel for app distribution in Capgo Cloud to manage update delivery. **Example:** ```bash npx @capgo/cli@latest channel add production com.example.app --default ``` **Options:** | Param | Type | Description | | ---------------- | --------- | ---------------------------------------------------------------- | | **-d,** | `string` | Set the channel as default | | **—self-assign** | `boolean` | Allow device to self-assign to this channel | | **-a,** | `string` | API key to link to your account | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()🗑️ **Delete** **Alias:** `d` ```bash npx @capgo/cli@latest channel delete ``` 🗑️ Delete a channel from Capgo Cloud, optionally removing associated bundles to free up resources. **Example:** ```bash npx @capgo/cli@latest channel delete production com.example.app ``` **Options:** | Param | Type | Description | | ------------------------- | --------- | ---------------------------------------------------------------- | | **-a,** | `string` | API key to link to your account | | **—delete-bundle** | `boolean` | Delete the bundle associated with the channel | | **—success-if-not-found** | `boolean` | Success if the channel is not found | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()📋 **List** **Alias:** `l` ```bash npx @capgo/cli@latest channel list ``` 📋 List all channels configured for an app in Capgo Cloud to review distribution settings. **Example:** ```bash npx @capgo/cli@latest channel list com.example.app ``` **Options:** | Param | Type | Description | | -------------- | -------- | ---------------------------------------------------------------- | | **-a,** | `string` | API key to link to your account | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()📦 **CurrentBundle** ```bash npx @capgo/cli@latest channel currentBundle ``` 📦 Get the current bundle linked to a specific channel in Capgo Cloud for update tracking. **Example:** ```bash npx @capgo/cli@latest channel currentBundle production com.example.app ``` **Options:** | Param | Type | Description | | -------------- | --------- | ---------------------------------------------------------------- | | **-c,** | `string` | Channel to get the current bundle from | | **-a,** | `string` | API key to link to your account | | **—quiet** | `boolean` | Only print the bundle version | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()⚙️ **Set** **Alias:** `s` ```bash npx @capgo/cli@latest channel set ``` ⚙️ Configure settings for a channel, such as linking a bundle, setting update strategies (major, minor, metadata, patch, none), or device targeting (iOS, Android, dev, emulator). One channel must be default. **Example:** ```bash npx @capgo/cli@latest channel set production com.example.app --bundle 1.0.0 --state default ``` **Options:** | Param | Type | Description | | -------------------------- | --------- | -------------------------------------------------------------------------- | | **-a,** | `string` | API key to link to your account | | **-b,** | `string` | Bundle version number of the file to set | | **-s,** | `string` | Set the state of the channel, default or normal | | **—latest-remote** | `boolean` | Get the latest bundle uploaded in capgo cloud and set it to the channel | | **—latest** | `boolean` | Get the latest version key in the package.json to set it to the channel | | **—downgrade** | `boolean` | Allow to downgrade to version under native one | | **—no-downgrade** | `boolean` | Disable downgrade to version under native one | | **—ios** | `boolean` | Allow sending update to iOS devices | | **—no-ios** | `boolean` | Disable sending update to iOS devices | | **—android** | `boolean` | Allow sending update to Android devices | | **—no-android** | `boolean` | Disable sending update to Android devices | | **—self-assign** | `boolean` | Allow device to self-assign to this channel | | **—no-self-assign** | `boolean` | Disable devices to self-assign to this channel | | **—disable-auto-update** | `string` | Block updates by type: major, minor, metadata, patch, or none (allows all) | | **—dev** | `boolean` | Allow sending update to development devices | | **—no-dev** | `boolean` | Disable sending update to development devices | | **—emulator** | `boolean` | Allow sending update to emulator devices | | **—no-emulator** | `boolean` | Disable sending update to emulator devices | | **—package-json** | `string` | Paths to package.json files for monorepos (comma-separated) | | **—ignore-metadata-check** | `boolean` | Ignore checking node\_modules compatibility if present in the bundle | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | # 👨‍⚕️ doctor > 👨‍⚕️ Check if your Capgo app installation is up-to-date and gather information useful for bug reports. 👨‍⚕️ Check if your Capgo app installation is up-to-date and gather information useful for bug reports. ```bash npx @capgo/cli@latest doctor ``` This command helps diagnose issues with your setup. **Example:** ```bash npx @capgo/cli@latest doctor ``` ## []()Options | Param | Type | Description | | ----------------- | -------- | ----------------------------------------------------------- | | **—package-json** | `string` | Paths to package.json files for monorepos (comma-separated) | # 🚀 init > 🚀 Initialize a new app in Capgo Cloud with step-by-step guidance. 🚀 Initialize a new app in Capgo Cloud with step-by-step guidance. **Alias:** `i` ```bash npx @capgo/cli@latest init ``` This includes adding code for updates, building, uploading your app, and verifying update functionality. **Example:** ```bash npx @capgo/cli@latest init YOUR_API_KEY com.example.app ``` ## []()Options | Param | Type | Description | | -------------- | -------- | ---------------------------------------------------------------- | | **-n,** | `string` | App name for display in Capgo Cloud | | **-i,** | `string` | App icon path for display in Capgo Cloud | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | # 🔐 key > 🔐 Manage encryption keys for secure bundle distribution in Capgo Cloud, supporting end-to-end encryption with RSA and AES combination. 🔐 Manage encryption keys for secure bundle distribution in Capgo Cloud, supporting end-to-end encryption with RSA and AES combination. ### []()🔹 **Save** ```bash npx @capgo/cli@latest key save ``` 💾 Save the public key in the Capacitor config, useful for CI environments. Recommended not to commit the key for security. **Example:** ```bash npx @capgo/cli@latest key save --key ./path/to/key.pub ``` **Options:** | Param | Type | Description | | ------------- | -------- | ------------------------------------ | | **-f,** | `string` | Force generate a new one | | **—key** | `string` | Key path to save in Capacitor config | | **—key-data** | `string` | Key data to save in Capacitor config | ### []()🔨 **Create** ```bash npx @capgo/cli@latest key create ``` 🔨 Create RSA key pair for end-to-end encryption. Creates .capgo\_key\_v2 (private) and .capgo\_key\_v2.pub (public) in project root. Public key is saved to capacitor.config for mobile app decryption. NEVER commit the private key - store it securely! **Example:** ```bash npx @capgo/cli@latest key create ``` **Options:** | Param | Type | Description | | ------- | -------- | ------------------------ | | **-f,** | `string` | Force generate a new one | ### []()🗑️ **Delete\_old** ```bash npx @capgo/cli@latest key delete_old ``` 🧹 Delete the old encryption key from the Capacitor config to ensure only the current key is used. **Example:** ```bash npx @capgo/cli@latest key delete_old ``` # 🔑 login > 🔑 Save your Capgo API key to your machine or local folder for easier access to Capgo Cloud services. 🔑 Save your Capgo API key to your machine or local folder for easier access to Capgo Cloud services. **Alias:** `l` ```bash npx @capgo/cli@latest login ``` Use —apikey=\*\*\*\*\*\*\*\* in any command to override it. **Example:** ```bash npx @capgo/cli@latest login YOUR_API_KEY ``` ## []()Options | Param | Type | Description | | -------------- | --------- | ---------------------------------------------------------------- | | **—local** | `boolean` | Only save in local folder, git ignored for security. | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | # 🔹 organisation > 🏢 Manage your organizations in Capgo Cloud for team collaboration and app management. 🏢 Manage your organizations in Capgo Cloud for team collaboration and app management. ### []()📋 **List** **Alias:** `l` ```bash npx @capgo/cli@latest organisation list ``` 📋 List all organizations you have access to in Capgo Cloud. **Example:** ```bash npx @capgo/cli@latest organisation list ``` **Options:** | Param | Type | Description | | -------------- | -------- | ---------------------------------------------------------------- | | **-a,** | `string` | API key to link to your account | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()➕ **Add** **Alias:** `a` ```bash npx @capgo/cli@latest organisation add ``` ➕ Create a new organization in Capgo Cloud for team collaboration. **Example:** ```bash npx @capgo/cli@latest organisation add --name "My Company" --email admin@mycompany.com ``` **Options:** | Param | Type | Description | | -------------- | -------- | ---------------------------------------------------------------- | | **-n,** | `string` | Organization name | | **-e,** | `string` | Management email for the organization | | **-a,** | `string` | API key to link to your account | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()⚙️ **Set** **Alias:** `s` ```bash npx @capgo/cli@latest organisation set ``` ⚙️ Update organization settings such as name and management email. **Example:** ```bash npx @capgo/cli@latest organisation set ORG_ID --name "Updated Company Name" ``` **Options:** | Param | Type | Description | | -------------- | -------- | ---------------------------------------------------------------- | | **-n,** | `string` | Organization name | | **-e,** | `string` | Management email for the organization | | **-a,** | `string` | API key to link to your account | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | ### []()🗑️ **Delete** **Alias:** `d` ```bash npx @capgo/cli@latest organisation delete ``` 🗑️ Delete an organization from Capgo Cloud. This action cannot be undone. Only organization owners can delete organizations. **Example:** ```bash npx @capgo/cli@latest organisation delete ORG_ID ``` **Options:** | Param | Type | Description | | -------------- | -------- | ---------------------------------------------------------------- | | **-a,** | `string` | API key to link to your account | | **—supa-host** | `string` | Custom Supabase host URL (for self-hosting or Capgo development) | | **—supa-anon** | `string` | Custom Supabase anon key (for self-hosting) | # FAQ > Frequently asked questions about Capgo, how to solve the most common issue in Capgo or with the Updater, what is OTA and how to manage them If you have questions not answered here, please ask! Both filing an issue or asking on [Discord](https://discord.capgo.app) work. ### What is “code push”?[](https://capgo.app/docs/#what-is-code-push "Direct link to What is \"code push\"?") Code push, also referred to as “over the air updates” (OTA) is a cloud service enabling Capacitor developers to deploy updates to their apps in production. Capgo currently works on Android and iOS and will eventually work everywhere Capacitor works. “Code Push” is a reference to the name of a deploy feature used by the React Native community from [Microsoft](https://appcenter.ms/) and [Expo](https://expo.dev/), neither of which support Capacitor. ### What is the difference between a bundle and a release?[](https://capgo.app/docs/faq/#what-is-the-difference-between-a-bundle-and-a-release "Direct link to What is the difference between a bundle and a release?") We use the term “release” to mean preparing a binary for the app stores. In order to later generate a bundle Capgo needs to know the exact binary that was shipped to the app stores. We use the term “bundle” to mean a patch that can be applied to a release to update it to new code. The `npx @capgo/cli@latest bundle upload` command is used to generate a bundle from your new local code which is then shipped to your users. ### What is the roadmap?[](https://capgo.app/docs/faq/#what-is-the-roadmap "Direct link to What is the roadmap?") Our project boards are also public and found at: [https://github.com/orgs/Cap-go/projects](https://github.com/orgs/Cap-go/projects/) Our team also operates in the public, so you can see what we’re working on at any time. We’re happy to answer any questions you have about our roadmap or priorities via Github issues or [Discord](https://discord.capgo.app). ### Can I use Capgo with my team?[](https://capgo.app/docs/faq/#can-i-use-capgo-with-my-team "Direct link to Can I use Capgo with my team?") Yes! All plans support unlimited developers. We only limit app metrics (MAU, storage and bandwidth) to each organization. See [Teams](https://capgo.app/pricing/) for more information. ### Does Capgo store my source code?[](https://capgo.app/docs/faq/#does-capgo-store-my-source-code "Direct link to Does Capgo store my source code?") No. Capgo servers never see your source code. When you run `npx @capgo/cli@latest bundle upload`, Capgo stores a zip file of the minified/compiled code - the same code that a browser would receive, not your source code. For additional security, you have two options: * **End-to-End Encryption**: Encrypt your bundle before uploading, making it impossible for Capgo to read or modify the contents * **External URL Upload**: Store the bundle on your own server and only provide Capgo with the download link with the option `--external ` See also our privacy policy: [https://capgo.app/privacy](https://capgo.app/privacy/) ### Can I use Capgo from my CI system?[](https://capgo.app/docs/faq/#can-i-use-capgo-from-my-ci-system "Direct link to Can I use Capgo from my CI system?") Yes. Capgo is intended to be used from CI systems. We’ve published a guide for [Android and Github Actions](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) and [iOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/), and for [GitLab](https://capgo.app/blog/setup-ci-and-cd-gitlab/). Other CI systems should be similar. Please don’t hesitate to reach out over GitHub issues or Discord if you encounter any issues. ### How does this relate to Firebase Remote Config or Launch Darkly?[](https://capgo.app/docs/faq/#how-does-this-relate-to-firebase-remote-config-or-launch-darkly "Direct link to How does this relate to Firebase Remote Config or Launch Darkly?") Code push allows adding new code / replacing code on the device. Firebase Remote Config and Launch Darkly are both configuration systems. They allow you to change the configuration of your app without having to ship a new version. They are not intended to replace code. ### How big of a dependency footprint does this add?[](https://capgo.app/docs/faq/#how-big-of-a-dependency-footprint-does-this-add "Direct link to How big of a dependency footprint does this add?") I haven’t measured recently, but I expect the code push library to add less than one megabyte to Capacitor apps. We know of ways we can make this smaller when that becomes a priority. If size is a blocker for you, please let us know! ### Does Capgo work on the iOS 18.4 Simulator?[](https://capgo.app/docs/faq/#does-capgo-work-on-the-ios-18-4-simulator "Direct link to Does Capgo work on the iOS 18.4 Simulator?") No. Due to an upstream issue affecting the iOS 18.4 Simulator, Capgo does not run reliably there. Please test on a real device or use a different iOS simulator version. See details in the React Native issue: [facebook/react-native#50510](https://github.com/facebook/react-native/issues/50510) ### Does code push work with large applications?[](https://capgo.app/docs/faq/#does-code-push-work-with-large-applications "Direct link to Does code push work with large applications?") Yes. There is no limit on the size of the application that can be updated with code push. As noted [below](https://capgo.app/docs/faq/#what-types-of-changes-does-capgo-code-push-support), Capgo can change any JS code in your application regardless of size. To note: A bigger size make it harder for users to download updates. We recommend keeping your app as small as possible. ### What can I use Capgo code push for?[](https://capgo.app/docs/faq/#what-can-i-use-capgo-code-push-for "Direct link to What can I use Capgo code push for?") We’ve seen a variety of uses, including: * Emergency fixes to production apps. * Shipping bug fixes to users on older versions of your app. * Shipping constantly (e.g. every hour). Note that most app stores prohibit shipping code that changes the behavior of the app in a significant way. Please see [below](https://capgo.app/docs/faq/#how-does-this-relate-to-the-appplay-store-review-process-or-policies) for more information. ### What counts as a “MAU” for Capgo?[](https://capgo.app/docs/faq/#what-counts-as-a-mau-for-capgo "Direct link to What counts as a \"MAU\" for Capgo?") A MAU is a “Monthly Active User”. In Capgo’s context, this actually refers to a Monthly Active Device. We count a MAU as any device that has contacted our servers in the last 30 days. We do not count devices that have not contacted our servers in the last 30 days. Each time a device installs your app again, a new MAU is counted, this happen because Apple store limitation about privacy. We cannot track the same device if the user reinstall the app. During development, each time you reinstall the app, a new MAU is counted. Same for testflight download or switch channel in Android. Updating the app do not create a new Device ID. > We recommend after first setup, to disable dev devices and emulators to reduce the amount of duplicated devices. ### What can’t we use Capgo code push for?[](https://capgo.app/docs/faq/#what-cant-we-use-capgo-code-push-for "Direct link to What can't we use Capgo code push for?") As above, Capgo should not be used to violate app store polices. Please see [below](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines) for more information. Also Capgo does not support changing native code (e.g. Java/Kotlin on Android or Objective-C/Swift on iOS). The tool will warn you during an attempted update if you have changed native code. ### Does Capgo submit to the stores for me?[](https://capgo.app/docs/faq/#does-capgo-submit-to-the-stores-for-me "Direct link to Does Capgo submit to the stores for me?") Capgo does not currently support submitting to the app stores on your behalf. We have plans to add this in the future, but for now you will need to continue to use your existing processes to submit to the app stores. You can use our [CI guide Android](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) to automate this process and [CI guide iOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/). ### What does Capgo store on disk and where?[](https://capgo.app/docs/faq/#what-does-capgo-store-on-disk-and-where "Direct link to What does Capgo store on disk and where?") The Capgo updater (included in your application when you build your app) caches the latest downloaded bundle in the only directory that capacitor allow to load code. On Android, this is located in `/data/user/0/com.example.app/code_cache/capgo_updater` although the base of that path is provided by the Android system and can change dynamically at runtime. On iOS devices, data is stored under `Library/Application Support/capgo`. The Capgo command line tools (e.g. `npx @capgo/cli@latest bundle upload`) are installed on disk in npm caches, your logins are stored in your home directory in `~/.capgo`. ### How does this relate to Capacitor Hot Reload?[](https://capgo.app/docs/faq/#how-does-this-relate-to-capacitor-hot-reload "Direct link to How does this relate to Capacitor Hot Reload?") Capacitor’s Hot reload is a development-time-only feature. Code push is for production. Hot reload is a feature of Capacitor that allows you to change code on the device during development. It requires building the Capacitor app with a proxy to connect to your local machine. Code push is a feature that allows you to change code on the device in production. We will use a variety of different techniques to make this possible depending on the platform. ### What types of changes does Capgo code push support?[](https://capgo.app/docs/faq/#what-types-of-changes-does-capgo-code-push-support "Direct link to What types of changes does Capgo code push support?") Capgo can change any JS code in your application. This includes app code and generated code. You can also update dependencies in `package.json` as long as they don’t require native code changes. We do not have plans to support changing native code (e.g. Java/Kotlin on Android or Objective-C/Swift on iOS), and the tool will warn you if it detects that you have changed native code as it will not be included in the bundle. ### Does this support Web?[](https://capgo.app/docs/faq/#does-this-support-web "Direct link to Does this support Web?") Code push isn’t needed for web as the web already works this way. When a user opens a web app it downloads the latest version from the server if needed. If you have a use case for code push with web, we’d love to know! ### Will this work on iOS, Android, Mac, Windows, Linux, etc?[](https://capgo.app/docs/faq/#will-this-work-on-ios-android-mac-windows-linux-etc "Direct link to Will this work on iOS, Android, Mac, Windows, Linux, etc?") Yes. So far we’ve focused on Android and iOS support, but code push will eventually work everywhere Capacitor works. We’re ensuring we’ve built all the infrastructure needed to provide code push reliably and safely before expanding to more platforms. ### What OS versions does Capgo support?[](https://capgo.app/docs/faq/#what-os-versions-does-capgo-support "Direct link to What OS versions does Capgo support?") Capgo supports the same versions of Android that Capacitor supports. Capacitor currently supports Android API level 22+ and iOS 13.0+: [https://capacitorjs.com/docs/main/reference/support-policy](https://capacitorjs.com/docs/main/reference/support-policy/) ### What versions of Capacitor does Capgo support?[](https://capgo.app/docs/faq/#what-versions-of-capacitor-does-capgo-support "Direct link to What versions of Capacitor does Capgo support?") Capgo currently supports only recent stable releases of Capacitor. We could support older versions of Capacitor as well, we just haven’t built out the infrastructure necessary to maintain such over time. We intend to support more versions of Capacitor in the future, including any version for our enterprise customers. [https://github.com/Cap-go/capgo/issues/1100](https://github.com/Cap-go/capgo/issues/1100/) Capgo tracks Capacitor stable and generally updates within a few hours of any stable release. Our system for doing these updates is automated takes a few minutes to run. We then do an extra manual verification step before publishing to our servers. ### How does this relate to the App/Play Store review process or policies?[](https://capgo.app/docs/faq/#how-does-this-relate-to-the-appplay-store-review-process-or-policies "Direct link to How does this relate to the App/Play Store review process or policies?") Developers are bound by their agreements with store providers when they choose to use those stores. Code push is designed to allow developers to update their apps and still comply with store policies on iOS and Android. Similar to the variety of commercial products available to do so with React Native (e.g. [Microsoft](https://appcenter.ms/), [Expo](https://expo.dev/)). Microsoft also publishes a guide on how their solution complies with the app stores: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) Code push is a widely used technique throughout the app stores. All of the large apps I’m aware of use code push. The major policy to be aware of is not to change the behavior of the app in a significant way. Please see [below](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines) for more information. ### Does Capgo comply with Play Store guidelines?[](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines "Direct link to Does Capgo comply with Play Store guidelines?") Yes. The Play Store offers two restrictions relating to update tools. 1. Updates must use an interpreter or virtual machine (Capgo uses JavaScript in a WebView). [https://support.google.com/googleplay/android-developer/answer/9888379?hl=en](https://support.google.com/googleplay/android-developer/answer/9888379/?hl=en) ```plaintext An app distributed via Google Play may not modify, replace, or update itself
using any method other than Google Play's update mechanism. Likewise, an app
may not download executable code (such as dex, JAR, .so files) from a
source other than Google Play. *This restriction does not apply to code
that runs in a virtual machine or an interpreter* where either provides
indirect access to Android APIs (such as JavaScript in a webview or
browser).

Apps or third-party code, like SDKs, with interpreted languages (JavaScript,
Python, Lua, etc.) loaded at run time (for example, not packaged with the
app) must not allow potential violations of Google Play policies.
``` 2. Changes to the app must not be deceptive (e.g. changing the purpose of the app via update). [https://support.google.com/googleplay/android-developer/answer/9888077](https://support.google.com/googleplay/android-developer/answer/9888077/) Please be clear with your users about what you are providing with your application and do not violate their expectations with significant behavioral changes through the use of Capgo. Capgo is designed to be compatible with the Play Store guidelines. However Capgo is a tool, and as with any tool, can be abused. Deliberately abusing Capgo to violate Play Store guidelines is in violation of the Capgo [Terms of Service](https://capgo.app/tos/) and can result in termination of your account. Finally, code push services are widely used in the industry (all of the large apps I’m aware of use them) and there are multiple other code push services publicly available (e.g. expo.dev & appcenter.ms). This is a well trodden path. Microsoft also publishes a guide on how their react native “codepush” library complies with the app stores: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### Does Capgo comply with App Store guidelines?[](https://capgo.app/docs/faq/#does-capgo-comply-with-app-store-guidelines "Direct link to Does Capgo comply with App Store guidelines?") Yes. Similar to the Play Store, the App Store offers both technical and policy restrictions. ```plaintext 3.2.2
... interpreted code may be downloaded to an Application but only so long as
such code:
(a) does not change the primary purpose of the Application by providing
features or functionality that are inconsistent with the intended and
advertised purpose of the Application as submitted to the App Store,
(b) does not create a store or storefront for other code or applications, and
(c) does not bypass signing, sandbox, or other security features of the OS.
``` Capgo uses JavaScript in a WebView to comply with the interpreter-only restriction for updates on iOS. So long as your application is not engaging in deceptive behavior via updates (e.g. changing the purpose of the app via update), updating via Capgo (or any other code push solution) is standard industry practice and compliant with App Store guidelines. Deliberately abusing Capgo to violate App Store guidelines is in violation of the Capgo [Terms of Service](https://capgo.app/tos/) and can result in termination of your account. Microsoft also publishes a guide on how their react native “codepush” library complies with the app stores: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### Can I use Capgo in my country?[](https://capgo.app/docs/faq/#can-i-use-capgo-in-my-country "Direct link to Can I use Capgo in my country?") We have not attempted to restrict access to Capgo from any country. We recognize that some countries have restrictions on what urls can be accessed from within the country. Capgo currently uses Cloudflare Cloud for hosting, including R2 Storage and Cloudflare workers. The following URLs are used by Capgo: * [https://api.capgo.app](https://api.capgo.app/) — used by the `npx @capgo/cli` command line tools to interact with the Capgo servers as well as the Capgo updater on users’ devices to check for updates. * [https://\*.r2.cloudflarestorage.com](https://*.r2.cloudflarestorage.com/) — used by the `npx @capgo/cli` command line tool to upload and download bundle If all of those URLs are accessible from your country, then Capgo should work. If your region requires blocking access to any of those URLs, please let us know and we can work with you to find a solution. Proxy servers are one option. ### Can I self-host Capgo?[](https://capgo.app/docs/faq/#can-i-self-host-capgo "Direct link to Can I self-host Capgo?") Yes, you can self-host Capgo. The guide is not yet written, but the code is open source and available at [https://github.com/cap-go/capgo](https://github.com/cap-go/capgo/) ### Does code push require the internet to work?[](https://capgo.app/docs/faq/#does-code-push-require-the-internet-to-work "Direct link to Does code push require the internet to work?") Yes. One could imagine running a server to distribute the updates separately from the general internet, but some form of network connectivity is required to transport updates to the devices. ### How is Capgo affected by lack of network connectivity?[](https://capgo.app/docs/faq/#how-is-capgo-affected-by-lack-of-network-connectivity "Direct link to How is Capgo affected by lack of network connectivity?") Capgo updater (included in your application when you build your app with Capgo) is designed to be resilient to network connectivity issues. In the default update behavior, when the application launches it alerts the Capgo updater, which spawns a separate thread to make a network request to Capgo’s servers and ask for an update. We intentionally use a separate thread to avoid affecting blocking anything else the application might be doing. If the network request fails or times out, the updater will simply try to check again next time the application launches. Capgo command line tools (e.g. `npx @capgo/cli@latest bundle upload`) require network connectivity to function. If you are using Capgo to distribute your app, you should ensure that your CI system has network connectivity. ### What happens if a user doesn’t update for a long time and misses an update?[](https://capgo.app/docs/faq/#what-happens-if-a-user-doesnt-update-for-a-long-time-and-misses-an-update "Direct link to What happens if a user doesn't update for a long time and misses an update?") Our implementation always sends an update specifically tailored for the device that is requesting it updating the requestor always to the latest version available. Thus if a user doesn’t update for a while they will “miss” intermediate updates. The update server could be changed to support responding with either the next incremental version or the latest version depending on your application’s needs. Please let us know if alternative update behaviors are important to you. ### How does Capgo relate to Capacitor?[](https://capgo.app/docs/faq/#how-does-capgo-relate-to-capacitor "Direct link to How does Capgo relate to Capacitor?") Capgo is a plugin for Capacitor that adds code push. Capgo is not a replacement for Capacitor. You can continue to use the Capacitor tooling you already know and love. We track the latest stable release of Capacitor and update our code push plugin to work with it. ### When do updates happen?[](https://capgo.app/docs/faq/#when-do-updates-happen "Direct link to When do updates happen?") By default, the Capgo updater checks for updates on app startup. It runs on a background thread and does not block the UI thread. Any updates will be installed while the user is using the app and will be applied the next time the app is restarted. It is also possible to run the Capgo updater manually using the `@capgo/capacitor-updater` package, through which it is possible to trigger updates at any time, including via a push notification. The Capgo updater is designed such that when the network is not available, or the server is down or otherwise unreachable, the app will continue to run as normal. Should you ever choose to delete an update from our servers, all your clients will continue to run as normal. We have added the ability to rollback patches. The simplest thing is to simply attach a previous bundle to your channel to undo. ### Do I need to keep my app\_id secret?[](https://capgo.app/docs/faq/#do-i-need-to-keep-my-app_id-secret "Direct link to Do I need to keep my app_id secret?") No. The `app_id` is included in your app and is safe to be public. You can check it into version control (even publicly) and not worry about someone else accessing it. Someone who has your `app_id` can fetch the latest version of your app from Capgo servers, but they cannot push updates to your app or access any other aspect of your Capgo account. ### What information is sent to Capgo servers?[](https://capgo.app/docs/faq/#what-information-is-sent-to-capgo-servers "Direct link to What information is sent to Capgo servers?") Although Capgo connects to the network, it does not send any personally identifiable information. Including Capgo should not affect your declarations for the Play Store or App Store. Requests sent from the app to Capgo servers include: * app\_id (specified `capacitor.config.json`) * channel (optional in `capacitor.config.json`) * release\_version (versionName from AndroidManifest.xml or CFBundleShortVersionString from Info.plist or `capacitor.config.json` if set in [`CapacitorUpdater.version`](/docs/plugin/settings/#version) ) * version\_number (generated as part of `npx @capgo/cli@latest bundle upload`) * os\_version (e.g. ‘11.2.1’) * platform (e.g. ‘android’, needed to send down the right patch) That’s it. The code for this is in `updater/library/src/network.rs` * device\_id (generated on the device on first run, used to de-duplicate per-device installs and allow us to charge based on users installed to (e.g. monthly active users), rather than total patches or total patch installs) * custom\_id ( optional, set at runtime by the developer, used for you to link a device to a user in your system) ### What platforms does Capgo support?[](https://capgo.app/docs/faq/#what-platforms-does-capgo-support "Direct link to What platforms does Capgo support?") Currently, Capgo supports iOS and Android. Both are production ready. Use of Capgo for iOS or Android can be independent decisions. You can set in your channel to ship to Android and an ipa built to the App Store or vice versa. Capgo can (relatively easily) be made to support desktop or embedded targets. If those are important to you, please let us know. ### How does Capgo interact with Play Testing Tracks or Apple TestFlight?[](https://capgo.app/docs/faq/#how-does-capgo-interact-with-play-testing-tracks-or-apple-testflight "Direct link to How does Capgo interact with Play Testing Tracks or Apple TestFlight?") Each of the app stores have separate mechanisms for distributing apps to limited groups of users (e.g. “internal testing”, “closed beta”, etc.). These are all mechanisms for segmenting your users into groups and distributing specific versions of your apps to each. Unfortunately, these not all of these mechanisms allow 3rd parties to detect when apps are installed in any specific Test Track or via TestFlight. Thus, we do not have reliable visibility into composition of these groups, and cannot reliably gate access to Capgo patches based on these groups. [https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play](https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play/) [https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i](https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i/) If you’d like to segment availability of Capgo bundle, there are 4 potential options: 1. Use separate channel for each group. This is the most straightforward approach, but requires you to manage multiple channels. You may already have a dev channels and prod channels with different availability. You can thus update your dev channels, verify it and then separately update your prod channels. We recommend using branches / tags in your version control to help keep track of the sources associated with each release. 2. Track your own set of opt-in users, disable automatic updates, and trigger updates only for certain users via the `@capgo/capacitor-updater` package. This works today, but requires you to manage your own opt-in list. 3. Capgo allow creare its own opt-in mechanism on a per-device basis (similar to Test Tracks or TestFlight, just platform agnostic). This allow your QA team to opt-in to bundle before they’re promoted to the general public. 4. Capgo have percentage based rollouts. This does not let you choose which devices to send to, but can help you roll out incrementally and roll-back on sight of any problems. ## Billing[](https://capgo.app/docs/faq/#billing "Direct link to Billing") ### How do I upgrade or downgrade my plan?[](https://capgo.app/docs/faq/#how-do-i-upgrade-or-downgrade-my-plan "Direct link to How do I upgrade or downgrade my plan?") You can upgrade or downgrade your plan at any time in your dashboard: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### When does my billing period reset?[](https://capgo.app/docs/faq/#when-does-my-billing-period-reset "Direct link to When does my billing period reset?") Billing periods are reset automatically every month on the month you first subscribed to Capgo. For example, if you subscribed on the 15th of the month, your billing period will reset on the 15th of every month. ### How do I cancel my subscription?[](https://capgo.app/docs/faq/#how-do-i-cancel-my-subscription "Direct link to How do I cancel my subscription?") You can cancel your subscription at any time in your dashboard: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Can I pay for a year in advance?[](https://capgo.app/docs/faq/#can-i-pay-for-a-year-in-advance "Direct link to Can I pay for a year in advance?") Yes you can can at any time in your dashboard: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Stats and analytics[](https://capgo.app/docs/faq/#stats-and-analytics "Direct link to Stats and analytics") The stats in your dashboard are updated every midnight UTC. The stats are calculated based on the number of [MAU](https://capgo.app/docs/faq/#what-is-the-difference-between-a-bundle-and-a-release "Direct link to What is the difference between a bundle and a release?") that have been installed on your devices. ## How device ID is generated[](https://capgo.app/docs/faq/#how-device-id-is-generated "Direct link to How device ID is generated") The device ID is generated on the device on first run, and is used to de-duplicate per-device installs and allow us to charge based on users installed to (e.g. monthly active users), rather than total patches or total patch installs. MAU is a better solution than number of installs to price Capgo, as it is more accurate and reflects the actual cost of Capgo per device. For privacy reasons, we cannot track the same device if the user reinstall the app. The privacy rules are enforced by Apple and Google, and are not enforced by Capgo. Device ID will not be listed in your device list until they get they first patch installed. ## Why my device number is different than my MAU?[](https://capgo.app/docs/faq/#why-my-device-number-is-different-than-my-mau "Direct link to Why my device number is different than my MAU?") Currently, the device list is not updated as often as the MAU. The device list is updated only when a device installs an update. While the MAU is updated at every app launch. This is a current limitation of the platform. Our Analytics platform do not support raw updates so we use conventional database for Devices list. To limit the number of database queries, we do update row only on app update. This limitation will be removed in the future. ## How to have different update by platform?[](https://capgo.app/docs/faq/#how-to-have-different-update-by-platform "Direct link to How to have different update by platform?") You can create a channel for each platform. and disable platform specific updates in each channel. On ios channel disable android updates and on android channel disable ios updates. Then upload a bundle to each channel to have different update for each platform. If you need to have the same update for both platform, you can link one bundle to multiple channels. No need to duplicate the bundle. # Tech support for Capgo > How to get tech support for Capgo and our updater, please follow this guide to get help when the doc and our articles are not enough ## Support by discord Capgo has an official [discord server](https://discord.capgo.app). Getting tech support there is likely one of the fastest ways to get a response. Here is a crash course: Step 1 - go to the `questions` channel ![Ask on discord](/discord-questions.webp) Step 2 - create your thread ![Create a question on discord](/discord-newquestion.webp) Step 3 - Describe your problem and select the relevant tags ![Create a post on discord](/discord-new-post.webp) Step 4 - Share your secure account id (optional) This will allow the capgo staff to take a look at your account. Sharing this id is safe, as it was designed to be shared publicly. To share this, please go to [capgo’s settings](https://web.capgo.app/dashboard/settings/account/). There please click on `copy account id`. ![Share your id without leaking your info](/share-secure-id.webp) This will copy the secure account id to the clipboard. Please include that in your discord post. ## Support by email This is the slowest way to get support. Please use the discord server first. If you need to contact us by email, please send an email to . # Add an App > Add an app to your Capgo account, and install the plugin in your app ## Requirements Before getting started with Capgo, make sure you have: * A Capacitor app installed and configured. [Learn how to set up Capacitor](https://capacitorjs.com/docs/getting-started/) * Node.js 18 or later installed ## Introduction to Capgo [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## Live updates are 3 step away ### Guided setup 1. Create your account at . ![signup screenshot](/signup.webp "signup screenshot") 2. Use the Init commands to get started ```bash npx @capgo/cli@latest init [APIKEY] ``` You will be presented with a series of questions. Provide the necessary answers to complete the automated setup. Tip By following these steps, you’ll be up and running in no time. If you need any further assistance during the process, our support team is [here to help](https://support.capgo.app). Happy onboarding! 3. Deploy a live update [Deploy a live update ](/docs/getting-started/deploy/)Learn how to deploy a live update to your app ### Manual setup In case the init command doesn’t work for you, you can manually add an app. 1. Connect the CLI to your account: ```bash npx @capgo/cli@latest login [APIKEY] ``` 2. Add the app to your account with this command: ```bash npx @capgo/cli@latest app add [APP_NAME] ``` 3. Install the plugin in your app: ```bash npm i @capgo/capacitor-updater ``` 4. Configure the plugin in your `capacitor.config` ```json { "plugins": { CapacitorUpdater: { "appId": "Your appID", "autoUpdate": true, "version": "1.0.0" } } } ``` [See all option available](/docs/plugin/settings/). This informations will be infer if not provided. 5. Call the init method as early as possible in your app: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; CapacitorUpdater.notifyAppReady(); ``` 6. Deploy a live update [Deploy a live update ](/docs/getting-started/deploy/)Learn how to deploy a live update to your app # CI/CD Integration > Integrating Capgo into your CI/CD pipeline allows you to fully automate the process of building and deploying updates to your app. By leveraging the Capgo CLI and semantic-release, you can ensure consistent, reliable deployments and enable rapid iteration. Integrating Capgo into your CI/CD pipeline allows you to fully automate the process of building and deploying updates to your app. By leveraging the Capgo CLI and semantic-release, you can ensure consistent, reliable deployments and enable rapid iteration. ## Benefits of CI/CD Integration * **Automation**: No more manual steps or room for human error. Your entire build, test, and deployment process can be automated from end to end. * **Consistency**: Every deployment follows the same set of steps, ensuring a predictable and repeatable process. This is especially valuable when you have multiple team members contributing code. * **Faster iterations**: With automated deployments, you can ship updates more frequently and with confidence. No more waiting for manual QA or release approvals. ## Capgo CLI The Capgo CLI is the key to integrating Capgo into your CI/CD workflow. It provides commands for pushing new bundle versions, managing channels, and more. The most important command for CI/CD integration is `bundle upload`: ```shell npx @capgo/cli@latest bundle upload --channel Production --apikey YOUR_API_KEY ``` If you use encryption you should provide it from one of these ways: **Using a private key file path:** ```shell npx @capgo/cli@latest bundle upload --channel Production --apikey YOUR_API_KEY --key-v2 PRIVATE_KEY_PATH ``` **Using the private key content directly (recommended for CI/CD):** ```shell npx @capgo/cli@latest bundle upload --channel Production --apikey YOUR_API_KEY --key-data-v2 PRIVATE_KEY_CONTENT ``` **Using environment variables (best practice for CI/CD):** ```shell npx @capgo/cli@latest bundle upload --channel Production --apikey YOUR_API_KEY --key-data-v2 "$CAPGO_PRIVATE_KEY" ``` ### Setting up Environment Variables for Encryption For CI/CD environments, it’s recommended to store your private key as an environment variable rather than a file. Here’s how to set it up: 1. **Get your private key content:** ```shell cat .capgo_key_v2 | pbcopy ``` This copies the key content to your clipboard. 2. **Add it to your CI/CD environment:** * **GitHub Actions**: Add `CAPGO_PRIVATE_KEY` to your repository secrets * **GitLab CI**: Add it as a masked variable in your project settings * **CircleCI**: Add it as an environment variable in your project settings * **Jenkins**: Add it as a secret text credential 3. **Use it in your pipeline:** ```yaml - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secrets.CAPGO_API_KEY }} --key-data-v2 "${{ secrets.CAPGO_PRIVATE_KEY }}" ``` **Note**: The `--key-data-v2` flag allows you to pass the private key content directly as a string, making it perfect for environment variables in CI/CD pipelines where you don’t want to create temporary files. This command uploads the current web build to the specified channel. You’ll typically run this as the last step in your CI/CD pipeline, after your web build has completed successfully. ## Setting up Capgo in your CI/CD Pipeline While the exact steps will vary depending on your CI/CD tool of choice, the general process for integrating Capgo looks like this: 1. **Generate an API key**: Log in to the Capgo dashboard and create a new API key. This key will be used to authenticate the CLI in your CI/CD environment. Keep it secret and never commit it to your repository! 2. **Configure the `bundle upload` command**: Add a step to your CI/CD configuration that runs the `bundle upload` command with the appropriate arguments: upload.yml ```yaml - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secrets.CAPGO_API_KEY }} ``` \n Replace `Production` with the channel you want to deploy to, `${{ secrets.CAPGO_API_KEY }}` with the environment variable holding your API key, and add `--key-data-v2 "${{ secrets.CAPGO_PRIVATE_KEY }}"` if using encryption. 3. **Add the `upload` step after your web build**: Ensure that the `upload` step comes after your web build has completed successfully. This ensures you’re always deploying your latest code.\n Here’s an example configuration for GitHub Actions:\n upload.yml ```yaml name: Deploy to Capgo on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v4 with: node-version: 18 - run: npm ci - run: npm run build - run: npm install -g @capgo/cli - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secrets.CAPGO_API_KEY }} --key-data-v2 "${{ secrets.CAPGO_PRIVATE_KEY }}" ``` ## Version Management with Semantic-release The recommended way to handle versioning with Capgo is to set the version in your `capacitor.config.ts` file by importing it from `package.json`: ```ts import pkg from './package.json' const config: CapacitorConfig = { // ... other config plugins: { CapacitorUpdater: { version: pkg.version, } } } ``` This approach allows you to: 1. Use semantic-release (or any other tool) to update the `package.json` version 2. Build your app with the updated version automatically included 3. Upload the bundle with the correct version Your CI/CD workflow would look like this: ```yaml - run: npm ci - run: npx semantic-release # Updates package.json version - run: npm run build # Builds with new version from capacitor.config - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secrets.CAPGO_API_KEY }} ``` Here’s a sample `.releaserc` configuration file for semantic-release: ```json { "branches": [ "main", { "name": "beta", "prerelease": true } ], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", [ "@semantic-release/git", { "assets": ["CHANGELOG.md", "package.json"], "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" } ] ] } ``` This configuration does the following: 1. Analyzes commit messages to determine the next version number, following the Conventional Commits spec. 2. Generates release notes based on the commits since the last release. 3. Updates the `CHANGELOG.md` file with the new release notes. 4. Updates the `package.json` version, which will be picked up by your capacitor.config. 5. Commits the updated `CHANGELOG.md`, `package.json`, and any other changed files back to the repository. Make sure to run semantic-release before building your app so that the updated version from `package.json` is included in your build through the capacitor.config. ## Troubleshooting If you encounter issues with your Capgo CI/CD integration, here are a few things to check: * **API key**: Ensure your API key is valid and has the necessary permissions. If using an environment variable, double check that it’s set correctly. * **CLI version**: Make sure you’re using the latest version of the Capgo CLI. Older versions may have compatibility issues or lack certain features. * **Build artifacts**: Confirm that your web build is generating the expected output files. The Capgo CLI needs a valid web build to create a bundle. * **Network connectivity**: Check that your CI/CD environment has network access to the Capgo servers. Firewall or proxy issues can sometimes interfere with the `upload` command. If you’re still having trouble, reach out to Capgo support for assistance. They can help troubleshoot any issues with your specific setup. ## Conclusion Integrating Capgo into your CI/CD pipeline with proper version management can greatly streamline your development workflow. By automating your deployments and versioning through the capacitor.config approach, you can ship updates faster and with more confidence. The recommended approach of setting the version in your `capacitor.config.ts` file and using semantic-release to update `package.json` provides a robust and reliable deployment process that allows you to focus on building great features rather than worrying about manual release steps. For more details on the Capgo CLI commands and options, check out the [CLI reference](/docs/cli/overview). And for a deeper dive into semantic-release configuration, see the [semantic-release docs](https://github.com/semantic-release/semantic-release). Happy deploying! # Deploy a Live Update > Learn how to deploy a live update to your app using Capgo's Live Updates feature, enabling real-time UI and logic updates without app store resubmission. Use Capgo’s Live Updates feature to update the UI and business logic of your app remotely, in real-time. Push JS bundle updates directly to your users without going through the app store to instantly fix bugs and ship new features. This guide assumes you’ve completed the [Capgo Quickstart](/docs/getting-started/quickstart) and have already: 1. Installed the `@capgo/capacitor-updater` SDK in your Capacitor app 2. Configured your app ID and update channel in `capacitor.config.ts` 3. Added in your code the `CapacitorUpdater.notifyAppReady()` method If you haven’t done those steps yet, please go back and complete the quickstart first. [Add an app ](/docs/getting-started/add-an-app/)Add an app to your Capgo account, and install the plugin in your app ## Uploading a Bundle With the Capgo SDK installed and configured, you’re ready to upload your first live update bundle: 1. Build your web assets: ```shell npm run build ``` 2. Upload the bundle to Capgo: * Console ```shell npx @capgo/cli@latest bundle upload --channel=Production ``` * Github Actions .github/workflows/build\_and\_deploy.yml ```yml name: Build source code and send to Capgo concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true on: push: branches: - main jobs: deploy_to_capgo: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v5 - uses: actions/setup-node@v4 with: node-version: 18 - name: Install dependencies run: npm install - name: Build run: npm run build - name: Deploy to Capgo run: npx @capgo/cli@latest bundle upload -a ${{ secrets.CAPGO_TOKEN }} --channel ${{ env.CHANNEL }} env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} ``` * Gitlab .gitlab-ci.yml ```yml stages: - build build: stage: build image: node:18 cache: - key: files: - package-lock.json paths: - .node_modules/ script: - npm install - npm run build - npx @capgo/cli@latest bundle upload -a $CAPGO_TOKEN --channel $CAPGO_CHANNEL artifacts: paths: - node_modules/ - dist/ only: - master ``` This will upload a new bundle version to the channel specified in the command. ### Troubleshooting Uploads If your upload fails, double check: * Your app ID in `capacitor.config.ts` matches your app in the Capgo dashboard * You’re running the upload command from the root of your Capacitor project * Your web assets are built and up to date If you’re still having trouble, go to the [Troubleshooting](/docs/getting-started/troubleshooting/) section. ## Receiving an Update on a Device Once your bundle is uploaded, you can test the live update on a device: 1. Sync your app to the device: ```shell npx cap sync ios ``` 2. Open another terminal and run the following command to check the update status: ```shell npx @capgo/cli@latest app debug ``` 3. Run your app locally: ```shell npx cap run ios ``` Or open the iOS/Android project in Xcode/Android Studio and do a native run. 4. Keep the app open for about 30 seconds to allow the update to download in the background. 5. The logs will take a few seconds to update and show the update status. 6. Close and reopen the app. You should see your live update applied! Refer back to the [Capgo Quickstart](/docs/getting-started/quickstart#receiving-a-live-update-on-a-device) for more details on testing live updates. ## Next Steps Congrats on deploying your first live update with Capgo! 🎉 To learn more, review the rest of the [Capgo Live Updates documentation](/docs/live-updates). Some key topics to check out next: * [Targeting Updates with Channels](/docs/live-updates/channels) * [Customizing Update Behavior](/docs/live-updates/update-behavior) * [Live Update Rollbacks](/docs/live-updates/rollbacks) # Overview > Get started with Capgo by learning the key concepts and steps to integrate and deploy live updates to your app. The quickstart tutorial will walk you through the key concepts of Capgo! Concepts that will be explored include: 1. Adding an app to your Capgo account 2. Integrating Capgo with your CI/CD 3. Triggering bundle upload on Capgo by pushing commits 4. Configuring and customizing the Capgo bundle publishing 5. Setting up your app to enable live updates via Capgo 6. Deploying live updates to your app from Capgo Simply follow the guide step-by-step, or navigate directly to the documentation for the component that interests you. [ Start the Tutorial](/docs/getting-started/add-an-app/) [Follow the quickstart tutorial and get up and running with Capgo in no time!](/docs/getting-started/add-an-app/) [ Ship updates](/docs/getting-started/deploy/) [Ship updates to your app from the Capgo dashboard.](/docs/getting-started/deploy/) [ Automate updates](/docs/getting-started/cicd-integration/) [Integrate Capgo with your CI/CD and trigger bundle uploads on Capgo by pushing commits.](/docs/getting-started/cicd-integration/) [ Trouble Shooting](/docs/getting-started/troubleshooting/) [Common issues and how to solve them.](/docs/getting-started/troubleshooting/) [ Wrap Up](/docs/getting-started/wrapping-up/) [Wrap up the tutorial and get a quick overview of what you’ve learned.](/docs/getting-started/wrapping-up/) Tip The Over-the-Air (OTA) update feature is applicable only for modifications made to HTML, CSS, and JavaScript files. If you make any changes to the native code, such as updates to Capacitor plugins, it is mandatory to resubmit the application to the app store for approval. ## Join Discord Community [Join the Capgo Discord Server!](https://discord.capgo.app) ## Maintenance | Plugin version | Capacitor compatibility | Maintained | | -------------- | ----------------------- | -------------------------------------------------------- | | v7.\*.\* | v7.\*.\* | ✅ | | v6.\*.\* | v6.\*.\* | Critical bug only | | v5.\*.\* | v5.\*.\* | ⚠️ Deprecated | | v4.\*.\* | v4.\*.\* | ⚠️ Deprecated | | v3.\*.\* | v3.\*.\* | ⚠️ Deprecated | | >= 8 | v4.\*.\* | ⚠️ Deprecated due to versioning issues in our CI process | ## Store Guideline Compliance Android Google Play and iOS App Store have corresponding guidelines that have rules you should be aware of before integrating the Capacitor-updater solution within your application. ### Google play Third paragraph of [Device and Network Abuse](https://support.google.com/googleplay/android-developer/answer/9888379/?hl=en) topic describe that updating source code by any method other than Google Play’s update mechanism is restricted. But this restriction does not apply to updating javascript bundles. > This restriction does not apply to code that runs in a virtual machine and has limited access to Android APIs (such as JavaScript in a webview or browser). That fully allows Capacitor-updater as it updates just the JS bundles and won’t update native code. ### App Store Paragraph **3.3.2**, since back in 2015’s [Apple Developer Program License Agreement](https://developer.apple.com/programs/ios/information/) fully allows performing over-the-air updates of JavaScript and assets - and in its latest version (20170605) [downloadable here](https://developer.apple.com/terms/) this ruling is even broader: > Interpreted code may be downloaded to an Application but only so long as such code: (a) does not change the primary purpose of the Application by providing features or functionality that are inconsistent with the intended and advertised purpose of the Application as submitted to the App Store, (b) does not create a store or storefront for other code or applications, and (c) does not bypass signing, sandbox, or other security features of the OS. Capacitor Updater allows you to follow these rules in full compliance so long as the update you push does not significantly deviate your product from its original App Store approved intent. To further remain in compliance with Apple’s guidelines we suggest that App Store-distributed apps do not enable the `Force update` scenario, since in the [App Store Review Guidelines](https://developer.apple.com/app-store/review/guidelines/) state that: > Apps must not force users to rate the app, review the app, download other apps, or other similar actions in order to access functionality, content, or use of the app. This is not a problem for the default behavior of background update, since it won’t force the user to apply the new version until next time they close the app, but at least you should be aware of that role if you decide to show it. ## Open source The plugin is under the LGPL-3.0 License and the back-end is AGPL-3.0 License. > 💡 LGPL-3.0 means if someone modifies the code of the plugin, it’s mandatory to publish it, in open-source with the same licensing. If you use the code without modification, that doesn’t concern you. See the issue below for more details check the link 👇 [Licensing? ](https://github.com/Cap-go/capacitor-updater/issues/7) [Try GPTS Capgo to Get help instead of reading the docs ](https://chat.openai.com/g/g-3dMwHbF2w-capgo-doc-gpt) > You can include it in your app without worrying ## Final Notes If you self-host and find this tool useful, please consider supporting my work by becoming a [GitHub sponsor](https://github.com/sponsors/riderx/). I made a bet to open-source all the code I built here instead of paywalling it. By opening it up instead of fighting and hiding, I believe we can make the world a better place. To make this possible, it’s necessary for all of us to do our part, including you 🥹. If Capgo cloud doesn’t meet your needs, you can back a bootstrapped Maker [here](https://github.com/sponsors/riderx/) on your own terms. ## Simple Maths The price of the basic plan: $14\*12 = $168 a year. While average dev/hour = $60. That means that 3 hours wasted of dev time on self-host allows you to pay for a whole year, if you spent more than 3 hours you’re losing money ^^ # Troubleshooting > Resolve common issues encountered while using Capgo with detailed troubleshooting steps and advanced options for upload and debugging. Here are some common issues you might encounter while using Capgo and how to resolve them. 🚀 Need Expert Help? Stuck with a complex issue? Our expert team is here to help! Get personalized support, code reviews, and custom solutions tailored to your specific needs. [Get Professional Support](/consulting/) ### Upload failures If your bundle upload fails, double check: * Your app ID in `capacitor.config.ts` matches your app in the Capgo dashboard * You’re running the upload command from the root of your Capacitor project * Your web assets are built and up to date #### Advanced upload options The Capgo CLI provides some additional flags to help with common upload issues: * `--tus`: Uses the [tus resumable upload protocol](https://tus.io/) for more reliable uploads of large bundles or on poor network connections. If your bundle is over 10MB or you’re on a spotty connection, consider using `--tus`: ```shell npx @capgo/cli@latest bundle upload --tus ``` * `--package-json` and `--node-modules`: Tells Capgo where to find your root `package.json` and `node_modules` if your app uses a non-standard structure like a monorepo or npm workspace. Pass the path to the root `package.json` and the `--node_modules` path: ```shell npx @capgo/cli@latest bundle upload --package-json=path/to/package.json --node_modules=path/to/node_modules ``` Capgo needs this information to correctly bundle your app’s dependencies. You can combine these flags with other options like `--channel` as needed. See the [Capgo CLI docs](/docs/cli/overview/) for full details on the available upload options. If you’re still having trouble with uploads, reach out to [Capgo support](https://support.capgo.app) for further assistance. ### Debugging Updates If you’re encountering issues with live updates, the Capgo debug command is a helpful tool for troubleshooting. To use it: 1. Run the following command in your project directory: ```shell npx @capgo/cli@latest app debug ``` 2. Launch your app on a device or emulator and perform the action that should trigger an update (e.g. reopening the app after uploading a new bundle). 3. Watch the output of the debug command. It will log information about the update process, including: * When the app checks for an update * If an update is found and what version it is * Download and installation progress for the update * Any errors that occur during the update process 4. Use the debug logs to identify where the issue is occurring. For example: * If no update is found, double check that your bundle was uploaded successfully and the app is configured to use the correct channel. * If the update downloads but doesn’t install, make sure you’ve called `CapacitorUpdater.notifyAppReady()` and that the app was fully closed and reopened. * If you see an error message, look up that specific error in the Capgo docs or reach out to support for help. The debug command is especially useful for identifying issues with the update download and installation process. If the logs show the expected update version was found but not ultimately applied, focus your troubleshooting on the steps after the download. ### Debugging with Native Logs In addition to the Capgo debug command, the native logs on Android and iOS can provide valuable troubleshooting information, especially for issues on the native side of the update process. #### Android Logs To access the Android logs: 1. Connect your device or start your emulator 2. Open Android Studio and select “View > Tool Windows > Logcat” 3. In the Logcat window, filter the logs to just your app’s process by selecting it from the dropdown at the top 4. Look for any lines that include `Capgo` to find the SDK logs Alternatively, you can use the `adb logcat` command and grep for `Capgo` to filter the logs. The Capgo SDK will log key events during the update process, such as: * When an update check is initiated * If an update is found and what version it is * When the update download starts and completes * When the update installation is triggered * Any errors that occur during the native update steps Common Android-specific issues you might see in the logs include: * Network connectivity problems preventing the update download * File permissions errors when saving or reading the update bundle * Out of storage space for the update bundle * Failure to restart the app after the update is installed #### iOS Logs To access the iOS logs: 1. Connect your device or start your simulator 2. Open Xcode and go to “Window > Devices and Simulators” 3. Select your device and click on “Open Console” 4. In the console output, look for any lines that include `Capgo` to find the SDK logs You can also use the `log stream` command in the terminal and grep for `Capgo` to filter the logs. Similar to Android, the Capgo SDK will log key iOS-side events: * Update check initiation and result * Download start, progress, and completion * Installation trigger and result * Any errors during the native update process iOS-specific issues you might identify in the logs include: * SSL certificate problems when downloading the update * App transport security blocking the update download * Insufficient storage space for the update bundle * Failure to properly extract or apply the update bundle On both platforms, the native logs provide a lower-level view into the update process, with more details on the native implementation. They are especially useful for identifying issues that occur outside of the Capgo JavaScript layer. When troubleshooting a tricky live update problem, it’s a good idea to capture both the Capgo debug logs and the native logs for a comprehensive picture of what’s happening. The two logs together will give you the best chance of identifying and resolving the issue. ### Updates not applying If you’ve uploaded a bundle but aren’t seeing the changes on your device: * Make sure you’ve called `CapacitorUpdater.notifyAppReady()` in your app code as shown in the [quickstart](/docs/getting-started/quickstart) * Check that your device is connected to the internet and the Capgo debug logs show the update was downloaded * Try fully closing and reopening the app, as updates are only applied on a fresh launch * Look for any errors in the native logs that might indicate a problem applying the update Refer to the [deploying live updates](/docs/getting-started/deploy) guide for more details on the update process. If you’re still stuck, use the `npx @capgo/cli@latest app debug` command and native logs to get more visibility into what’s happening. ## SDK Installation If you’re having trouble installing the Capgo SDK, make sure: * Your app is using a supported version of Capacitor (4.0 or newer) * You’ve followed the [quickstart](/docs/getting-started/quickstart) steps in order, including syncing your app after installing the SDK ## CI/CD Integration For issues with triggering Capgo uploads from your CI/CD pipeline: * Double check your Capgo authentication token is set up correctly * Make sure you’re running the upload command after your web assets are built * Check that the upload command is using the correct channel name for your target environment See the [CI/CD integration](/docs/getting-started/cicd-integration/) docs for more troubleshooting tips. You can also use the `npx @capgo/cli@latest app debug` command to confirm if your CI/CD-triggered updates are being received by the app. # Wrapping up > Wrap up your Capgo journey with a concise overview of key concepts and next steps, ensuring a solid foundation for future exploration and mastery. Now that you have completed the quickstart guide, you should have a basic understanding of the key concepts of Capgo! The key concepts you have learned in this guide are: 1. Adding an app to your Capgo account 2. Integrating Capgo with your CI/CD pipeline 3. Triggering bundle uploads to Capgo on new commits 4. Configuring your app to enable live updates with the Capgo SDK 5. Deploying live updates to your app from the Capgo dashboard But there’s still more to learn about Capgo! Continue exploring the docs or check out some of these key topics: [ CI/CD Integration](/docs/getting-started/cicd-integration/) [Already have a CI/CD pipeline? Learn how to incorporate Capgo into your existing workflow.](/docs/getting-started/cicd-integration/) [ Live Updates](/docs/live-updates/) [Dive deeper into Capgo’s live update features and best practices.](/docs/live-updates/) [ FAQ](/docs/faq/) [Find answers to common questions about Capgo.](/docs/faq/) [ Troubleshooting](/docs/getting-started/troubleshooting/) [Get help with common issues that can come up while using Capgo.](/docs/getting-started/troubleshooting/) # How to > A comprehensive guide to Capgo, offering detailed tutorials, insightful tips, and advanced techniques to enhance your effective usage of the platform [How version works in Capgo ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [How to release major version in Capgo ](https://capgo.app/blog/how-to-release-major-version-in-capgo/)capgo.app [How to send specific update to one user or a group ](https://capgo.app/blog/how-to-send-specific-version-to-users/)capgo.app ## CI / CD [Automatic build and release with GitHub Actions ](https://capgo.app/blog/automatic-build-and-release-with-github-actions/)capgo.app [Manage development and production build with GitHub Actions ](https://capgo.app/blog/automatic-build-and-release-with-github-actions/)capgo.app ## Contributing [Contributing to Capgo open source ](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTING.md)github.com # Overview > Discover how Capgo's Live Updates enable seamless JavaScript bundle updates, allowing you to push changes directly to users without app store delays. Use Capgo’s Live Updates feature to update the JavaScript bundles of your app remotely, in real-time. Push JS updates directly to your users without going through the app store review process to instantly fix bugs and ship new features. Note Live Updates are limited to JavaScript bundle changes. If you need to update native code, such as adding or removing a plugin or changing native project configuration, you’ll need to submit a new native binary build to the app stores. ## How Live Updates Work Capgo’s Live Update system has two key components: 1. The Capgo SDK, which you install in your app. The SDK checks for available updates and downloads them in the background. 2. Channels, which let you target updates to specific groups of users. You can use channels to manage different release tracks, such as `Production`, `Staging`, and `Dev`. When you upload a new JS bundle to Capgo and assign it to a channel, the Capgo SDK in apps configured for that channel will detect the update and download it. The next time the app restarts, the new bundle will be loaded. ## Getting Started To start using Live Updates, follow these steps: 1. Complete the [Capgo Quickstart](/docs/getting-started/quickstart) to set up your app in Capgo and install the Capgo SDK. 2. In your app code, call `CapacitorUpdater.notifyAppReady()` after your app has finished initializing. This tells the Capgo SDK that your app is ready to receive updates. 3. Build your JS bundle and upload it to Capgo: ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. Open your app and wait for the update to download. You can check the status with: ```shell npx @capgo/cli@latest app debug ``` 5. Once the update is downloaded, close and reopen your app to load the new bundle. See the [Deploying Live Updates](/docs/getting-started/deploy) guide for more details. ## Next Steps [ Channels](/docs/live-updates/channels/) [Learn how to use channels to manage different release tracks and target updates to specific users.](/docs/live-updates/channels/) [ Rollbacks](/docs/live-updates/rollbacks/) [Discover how to roll back to a previous JS bundle version if an update causes issues.](/docs/live-updates/rollbacks/) [ Update Behavior](/docs/live-updates/update-behavior/) [Customize how and when updates are downloaded and applied in your app.](/docs/live-updates/update-behavior/) [ Fast Updates](/docs/live-updates/differentials/) [Learn how to use fast updates to speed up the update process.](/docs/live-updates/differentials/) # Breaking Changes > How to handle breaking changes with versioned channels This documentation explains how to handle breaking changes in your app using versioned channels. This approach allows you to maintain different versions of your app while ensuring users receive compatible updates. ## Example Scenario Let’s say you have: * App version 1.2.3 (old version) - uses production channel * App version 2.0.0 (new version with breaking changes) - uses v2 channel * Live update 1.2.4 (compatible with 1.2.3) * Live update 2.0.1 (compatible with 2.0.0) ## Strategy: Always Use defaultChannel for Major Versions **Recommended approach:** Set a `defaultChannel` for every major version. This ensures you can always push updates to specific user groups without relying on dynamic channel assignment. ```ts // Version 1.x releases defaultChannel: 'v1' // Version 2.x releases defaultChannel: 'v2' // Version 3.x releases (future) defaultChannel: 'v3' ``` Tip **Benefits of this approach:** * **Always have control** over which users receive updates * **No dynamic channel switching** needed in your app code * **Clear separation** between different app versions * **Flexibility** to push updates to any specific version group ## 1. Create Channel for New Version ```bash # Create channel for version 2.x npx @capgo/cli channel create v2 ``` ## 2. Update Capacitor Config for Version 2.0.0 Update your Capacitor config before building version 2.0.0 for the app store: capacitor.config.ts ```ts import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { appId: 'com.example.app', appName: 'Example App', plugins: { CapacitorUpdater: { // ... other options defaultChannel: 'v2' // All 2.0.0 users will use v2 channel } } }; export default config; ``` Note **For version 1.x:** If you didn’t set a `defaultChannel` initially, version 1.x users are on the `production` channel. For future major versions, always set a specific channel like `v3`, `v4`, etc. ## 3. Manage Separate Code Branches Create separate git branches to maintain compatibility between app versions: ```bash # Create and maintain a branch for version 1.x updates git checkout -b v1-maintenance git push origin v1-maintenance # Your main branch continues with version 2.x development git checkout main ``` **Critical:** Never push JavaScript bundles to older apps that expect native code/APIs they don’t have. Always build updates from the appropriate branch: * **v1-maintenance branch**: For updates to 1.x apps (production channel) * **main branch**: For updates to 2.x apps (v2 channel) ## 4. Upload Bundles to Respective Channels ```bash # For 1.x updates: Build from v1-maintenance branch git checkout v1-maintenance # Make your 1.x compatible changes here npx @capgo/cli bundle upload --channel production # For 2.x updates: Build from main branch git checkout main # Make your 2.x changes here npx @capgo/cli bundle upload --channel v2 ``` ## 5. Enable Self-Assignment ```bash # Allow apps to self-assign to v2 channel npx @capgo/cli channel set v2 --self-assign ``` ## 6. Deploy to App Store Build and deploy version 2.0.0 to the app store. All users who download this version (whether new users or existing users upgrading) will automatically use the v2 channel because it’s configured in the app bundle. Note **No code changes needed!** Since `defaultChannel: 'v2'` is bundled with the app store version, all users downloading version 2.0.0 will automatically use the correct channel. ## Scaling to Future Versions When you release version 3.0.0 with more breaking changes: ```bash # Create channel for version 3.x npx @capgo/cli channel create v3 ``` ```ts // capacitor.config.ts for version 3.0.0 const config: CapacitorConfig = { // ... plugins: { CapacitorUpdater: { defaultChannel: 'v3' // Version 3.x users } } }; ``` Now you can push updates to any version: * `production` channel → Version 1.x users * `v2` channel → Version 2.x users * `v3` channel → Version 3.x users ## 7. Cleanup (After Migration) Once all users have migrated to version 2.x (count 3-4 months): 1. Remove `defaultChannel` from your Capacitor config 2. Delete the v2 channel: ```bash npx @capgo/cli channel delete v2 ``` 3. Delete the v1-maintenance branch: ```bash git branch -d v1-maintenance git push origin --delete v1-maintenance ``` Tip This approach ensures users only receive updates compatible with their app version Always test updates thoroughly in each channel before deployment Note You can safely delete the v2 channel in Capgo even if some users still have the channel override. They will automatically receive updates from the production channel instead. ## Maintaining Version 1.x Updates To send updates compatible with version 1.x: 1. Switch to the v1-maintenance branch: ```bash git checkout v1-maintenance ``` 2. Make your changes and commit: ```bash # Make 1.x compatible changes git add . git commit -m "Fix for v1.x" git push origin v1-maintenance ``` 3. Build and upload to production channel: ```bash npx @capgo/cli bundle upload --channel production ``` Tip Keep your v1-maintenance branch up to date with bug fixes that are compatible with version 1.x, but never merge breaking changes from main # Channels > Learn how to manage and configure Live Update channels in Capgo, enabling seamless app updates by directing specific JS bundle builds to devices configured for those channels. A Live Update channel points to a specific JS bundle build of your app that will be shared with any devices configured to listen to that channel for updates. When you [install the Capgo Live Updates SDK](/docs/getting-started/quickstart/) in your app, any native binary configured to that channel will check for available updates whenever the app is launched. You can change the build a channel points to at any time and can also roll back to previous builds if needed. ## How a device picks a channel (precedence) When a device checks for an update, Capgo decides which channel to use in this strict order (highest priority first): 1. **Forced device mapping (Dashboard)** – Manually pin a specific device ID to a channel. Use for urgent debugging or controlled testing with a single real user. This always wins. 2. **Cloud override (per‑device) via `setChannel()` or Dashboard** – Created when your app calls `setChannel()` (often exposed in a QA/debug menu) or you change the device’s channel in the dashboard. Use for QA users switching between feature / PR channels or to reproduce a user issue. Reinstalling the binary does not clear it; deleting the device entry does. 3. **Capacitor config `defaultChannel` (test build default)** – If present in `capacitor.config.*` and no force/override exists, the app starts on this channel (e.g. `beta`, `qa`, `pr-123`). Intended for TestFlight / internal builds so testers land on a pre‑release channel automatically. Production builds typically leave this unset. 4. **Cloud Default Channel (primary path \~99% of users)** – If you mark a default channel in the dashboard, all normal end‑users (no force, no override, no config defaultChannel) attach here. Change it to roll out or roll back instantly—no new binary. If you have platform-specific defaults (one iOS-only, one Android-only), each device lands on the default matching its platform. Leaving the cloud default unset is allowed; in that case the device must match on steps 1–3 to receive updates. Best practice: * Treat 1–3 as exception / testing layers; when you set a cloud default, real users should flow into it. If you choose not to set one, be deliberate about how users attach (typically via `defaultChannel` in config or per-device overrides). * Only configure `defaultChannel` in binaries you explicitly ship to testers. Leaving it unset keeps production logic centralized in the dashboard. * Use `setChannel()` sparingly in production—mainly for QA or targeted diagnostics. If a channel is disabled for the platform (iOS/Android toggles) when it would otherwise be chosen, the selection process skips it and continues down the list. > Summary: Force > Override > Config `defaultChannel` > Cloud Default. ## Default Channel Behavior Setting a cloud default is optional, but it usually serves as the catch-all path for new devices. Without one, only devices that match on forced mappings, overrides, or a `defaultChannel` in the Capacitor config will receive updates. When you do choose to mark defaults, keep these patterns in mind: * **Single default (most common)** – If the channel has both iOS and Android enabled, it becomes the lone default; any device without overrides will attach here. * **Platform-specific defaults** – If you split channels by platform (for example, `ios-production` with only iOS enabled and `android-production` with only Android enabled), mark each one as the default for its platform. iOS devices go to the iOS default, Android devices go to the Android default. Remember that the cloud default and `defaultChannel` in `capacitor.config.*` both occupy the same decision layer. If you set a cloud default, you don’t need to duplicate the value in your Capacitor config—leave `defaultChannel` empty for production builds. Reserve `defaultChannel` for binaries you intentionally ship to testers or QA when you want them to start on a non-production channel even if the cloud default is different. You can change defaults at any time in the dashboard. When you swap a default, new devices obey the new routing immediately and existing devices follow the normal precedence rules the next time they check in. ## Setting up a Channel During onboarding you create the first channel (most teams name it “Production”), but nothing is locked—you can rename or delete any channel at any time. To add additional channels later: 1. Go to the “Channels” section of the Capgo dashboard 2. Click the “New Channel” button 3. Enter a name for the channel and click “Create” Channel names can be anything you’d like. A common strategy is to match channels to your development stages, such as: * `Development` - for testing live updates on local devices or emulators * `QA` - for your QA team to verify updates before wider release * `Staging` - for final testing in a production-like environment * `Production` - for the version of your app that end users receive from the app stores ## Configuring the Channel in Your App With your channels created, you need to configure your app to listen to the appropriate channel. In this example, we’ll use the `Development` channel. Open your `capacitor.config.ts` (or `capacitor.config.json`) file. Under the `plugins` section, optionally set `defaultChannel` for **test builds** (internal / QA). For production builds, prefer omitting it so devices use the Cloud Default unless explicitly overridden. ```ts import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { // For a QA/TestFlight build – testers start on the Development channel automatically. defaultChannel: 'Development', // Production builds usually omit this so users attach to the Cloud Default channel. }, }, }; ``` Next, build your web app and run `npx cap sync` to copy the updated config file to your iOS and Android projects. If you skip this sync step, your native projects will continue to use whichever channel they were previously configured for. Caution Channel selection order: Force > Override (`setChannel` / dashboard) > Config `defaultChannel` > Cloud Default. Use `defaultChannel` only in test/internal builds; leave it out for production so users follow the Cloud Default (when set) instead of duplicating the routing in native config. You can still force (pin) a device or apply an override later—those immediately supersede the config value. > Channel names are case sensitive. ## Channel Options and Strategies Channels have several options that control who can receive updates and how updates are delivered. The most important ones are below. You can configure these from the web app, the CLI, or the Public API. * Default channel: Optionally mark the channel or platform-specific channels that new devices attach to. See “Default Channel Behavior” for routing scenarios. * Platform filters: Enable or disable delivery to `iOS` and/or `Android` devices per channel. * Disable auto downgrade under native: Prevents sending an update when the device’s native app version is newer than the channel’s bundle (for example, device on 1.2.3 while channel has 1.2.2). * Allow development builds: Permit updates to development builds (useful for testing). * Allow emulator devices: Permit updates to emulators/simulators (useful for testing). * Allow device self‑assignment: Lets the app switch to this channel at runtime using `setChannel`. If disabled, `setChannel` will fail for this channel. ### Disable Auto Update strategies Use this to restrict which kinds of updates the channel will automatically deliver. Options: * major: Block cross‑major updates (0.0.0 → 1.0.0). Minor and patch updates still allowed. * minor: Block cross‑minor updates (e.g., 1.1.0 → 1.2.0) and majors. Patch updates still allowed. Note: does not block 0.1.0 → 1.1.0. * patch: Very strict. Allows only increasing patch versions within the same major and minor. Examples: 0.0.311 → 0.0.314 ✅, 0.1.312 → 0.0.314 ❌, 1.0.312 → 0.0.314 ❌. * metadata: Require a minimum update version metadata on each bundle. Configure via CLI using `--min-update-version` or `--auto-min-update-version`. If missing, the channel is marked misconfigured and updates will be rejected until set. * none: Allow all updates according to semver compatibility. Learn more details and examples in Disable updates strategy at /docs/cli/commands/#disable-updates-strategy. Example (CLI): ```bash # Block major updates on the Production channel npx @capgo/cli@latest channel set production com.example.app \ --disable-auto-update major # Allow devices to self-assign to the Beta channel npx @capgo/cli@latest channel set beta com.example.app --self-assign ``` ## Assigning a Bundle to a Channel To deploy a live update, you need to upload a new JS bundle build and assign it to a channel. You can do this in one step with the Capgo CLI: ```shell npx @capgo/cli@latest bundle upload --channel=Development ``` This will upload your built web assets and set the new bundle as the active build for the `Development` channel. Any apps configured to listen to that channel will receive the update the next time they check for one. You can also assign builds to channels from the “Bundles” section of the Capgo dashboard. Click the menu icon next to a build and select “Assign to Channel” to choose the channel for that build. ## Bundle Versioning and Channels It’s important to note that bundles in Capgo are global to your app, not specific to individual channels. The same bundle can be assigned to multiple channels. When versioning your bundles, we recommend using semantic versioning [semver](https://semver.org/) with pre-release identifiers for channel-specific builds. For example, a beta release might be versioned as `1.2.3-beta.1`. This approach has several benefits: * It clearly communicates the relationship between builds. `1.2.3-beta.1` is obviously a pre-release of `1.2.3`. * It allows for reusing version numbers across channels, reducing confusion. * It enables clear rollback paths. If you need to roll back from `1.2.3`, you know `1.2.2` is the previous stable release. Here’s an example of how you might align your bundle versions with a typical channel setup: * `Development` channel: `1.2.3-dev.1`, `1.2.3-dev.2`, etc. * `QA` channel: `1.2.3-qa.1`, `1.2.3-qa.2`, etc. * `Staging` channel: `1.2.3-rc.1`, `1.2.3-rc.2`, etc. * `Production` channel: `1.2.3`, `1.2.4`, etc. Using semver with pre-release identifiers is a recommended approach, but not strictly required. The key is to find a versioning scheme that clearly communicates the relationships between your builds and aligns with your team’s development process. ## Rolling Back a Live Update If you deploy a live update that introduces a bug or otherwise needs to be reverted, you can easily roll back to a previous build. From the “Channels” section of the dashboard: 1. Click the name of the channel you want to roll back 2. Find the build you want to revert to and click the crown icon ![Rollback build](/select_bundle.webp) 3. Confirm the action The selected build will immediately become the active build for that channel again. Apps will receive the rolled back version the next time they check for an update. ## Automating Deployments For more advanced workflows, you can automate your live update deployments as part of your CI/CD pipeline. By integrating Capgo into your build process, you can automatically upload new bundles and assign them to channels whenever you push to certain branches or create new releases. Check out the [CI/CD Integration](/docs/getting-started/cicd-integration/) docs to learn more about automating Capgo live updates. ## Deploying to a Device Now that you understand channels, you’re ready to start deploying live updates to real devices. The basic process is: 1. Install the Capgo SDK in your app 2. Configure the app to listen to your desired channel 3. Upload a build and assign it to that channel 4. Launch the app and wait for the update! For a more detailed walkthrough, see the [Deploying Live Updates](/docs/getting-started/deploy/) guide. Happy updating! ## Advanced Channel Usage: User Segmentation Channels can be used for more than just development stages. They’re a powerful tool for user segmentation, enabling features like: * Feature flags for different user tiers * A/B testing * Gradual feature rollouts * Beta testing programs Learn how to implement these advanced use cases in our guide: [How to Segment Users by Plan and Channels for Feature Flags and A/B Testing](/blog/how-to-segment-users-by-plan-and-channels/). # Compliance > Learn about Capgo's privacy practices, data collection, security compliance, and how we protect your users' information during live updates. Capgo is designed with privacy, security, and compliance in mind. This document explains what data is collected, how it’s used, and what measures are in place to protect your users’ privacy and ensure regulatory compliance when using Capgo’s live update service. ## Data Collection Overview Capgo collects minimal data necessary to provide the live update service effectively. The data collection is focused on operational requirements rather than user tracking or analytics. ### What Data is Collected Capgo collects only the data that is necessary to provide the live updates feature. When your app checks for updates or downloads new bundles, the following information is collected: * **App ID**: A unique identifier for your app that is used to associate the app with the correct account * **App Version Code**: The version code of the app that is used to determine which updates are compatible with the app * **App Version Name**: The version name of the app that is used for display purposes * **Platform**: The platform (iOS, Android) of the app that is used to determine which updates are compatible with the app * **Device ID**: A unique identifier for the device that is used to deliver updates to a specific device and for billing purposes. This identifier is a random string that is created when the app is started for the first time and is reset with every app installation to comply with app store guidelines * **Bundle ID**: The unique identifier for the bundle that is currently installed on the device * **Channel Name**: The name of the channel that is selected to receive updates * **OS Version**: The version of the operating system that is used to determine which updates are compatible with the device * **Plugin Version**: The version of the @capgo/capacitor-updater plugin that is used to deliver updates to the device **Additional Technical Data:** * Update check timestamps * Download success/failure status * Bundle installation status * Rollback events and reasons * IP address (for geolocation and CDN optimization) Note You can verify the data that is collected by inspecting the source code of the @capgo/capacitor-updater plugin, which is open-source and available on [GitHub](https://github.com/Cap-go/capacitor-updater). Capgo does not collect personally identifiable information (PII) such as names, email addresses, phone numbers, or persistent device identifiers that can be used to track individual users across apps. ### What Data is NOT Collected Capgo explicitly does not collect: * Personal user information or credentials * App usage analytics or user behavior data * Content from your app or user-generated data * Location data beyond general geographic region * Persistent device identifiers for tracking * Biometric or sensitive personal data ## Data Usage and Purpose The data collected by Capgo is used exclusively for: ### Service Operation * Determining which updates are available for specific app versions * Optimizing content delivery through geographic CDN selection * Ensuring compatibility between updates and device capabilities * Managing update rollouts and channel assignments ### Service Improvement * Monitoring update success rates and identifying issues * Optimizing download performance and reliability * Improving the overall update delivery system * Debugging and troubleshooting update failures ### Security and Integrity * Preventing abuse and ensuring service availability * Validating update authenticity and integrity * Protecting against malicious or corrupted updates * Maintaining service security and stability ## Data Storage and Retention ### Storage Location * Update bundles and metadata are stored on secure cloud infrastructure * Data is distributed across multiple geographic regions for performance * All data transmission is encrypted using industry-standard protocols (HTTPS/TLS) ### Data Retention * Update check logs are retained for operational purposes (typically 30-90 days) * Bundle files are retained as long as they’re assigned to active channels * Aggregated, non-personal metrics may be retained longer for service improvement * Personal data, if any, is deleted according to applicable data protection laws ### Data Security * All data is encrypted in transit and at rest * Access to data is restricted to authorized personnel only * Regular security audits and monitoring are performed * Industry-standard security practices are followed * **SOC 2 Certification**: Capgo is currently SOC 2 Type II certified, ensuring the highest standards of security, availability, and confidentiality. View our compliance status at [trust.capgo.app](https://trust.capgo.app) * **Continuous Code Auditing**: Every commit is automatically audited by [SonarCloud](https://sonarcloud.io/summary/overall?id=Cap-go_capacitor-updater\&branch=main) for the [plugin](https://sonarcloud.io/summary/overall?id=Cap-go_capgo\&branch=main) and [backend](https://sonarcloud.io/summary/overall?id=Cap-go_capgo\&branch=main), ensuring code quality, security vulnerabilities detection, and maintainability * **Vulnerability Scanning**: Additional security scanning is performed by [Snyk](https://snyk.io/test/github/Cap-go/capgo) to detect and remediate security vulnerabilities in dependencies * **Infrastructure Security**: Our hosting infrastructure is continuously monitored and verified through [hosting security checks](https://hosting-checker.net/websites/api.capgo.app) * **AI-Powered Code Review**: Every pull request is reviewed by CodeRabbit AI to catch potential issues, security concerns, and maintain code quality standards ## Privacy Controls ### For App Developers As a Capgo user, you have control over: * **Channel Management**: Control which updates are distributed to which users * **Data Minimization**: Configure what device information is shared * **Geographic Controls**: Manage where your updates are distributed * **Retention Settings**: Control how long update data is retained ### For End Users Your app users benefit from: * **Minimal Data Collection**: Only essential data for update delivery is collected * **No Tracking**: No cross-app or persistent user tracking * **Transparency**: This privacy policy explains exactly what data is collected * **Security**: All data transmission is encrypted and secure ## Compliance and Legal ### Data Protection Regulations Capgo is designed to comply with major data protection regulations including: * **GDPR** (General Data Protection Regulation) * **CCPA** (California Consumer Privacy Act) * **COPPA** (Children’s Online Privacy Protection Act) * Other applicable regional privacy laws ### App Store Compliance Capgo strictly adheres to app store guidelines and policies: * **Apple App Store**: Complies with [App Store Review Guidelines](https://developer.apple.com/app-store/review/guidelines/) section 3.3.2, ensuring that live updates only modify the app’s behavior in ways that are consistent with the submitted app * **Google Play Store**: Follows [Google Play Developer Policy](https://play.google.com/about/developer-content-policy/) requirements for dynamic code loading and app updates * **Content Restrictions**: Live updates cannot introduce functionality that wasn’t present in the original app submission or violate platform-specific content policies * **Security Requirements**: All updates maintain the same security posture and permissions as the original app ### Your Responsibilities As an app developer using Capgo, you should: * Include appropriate privacy disclosures in your app’s privacy policy * Inform users about the use of live update services * Ensure compliance with applicable laws in your jurisdiction * Implement appropriate consent mechanisms if required Tip **No Additional Privacy Implementation Required**: Capgo is designed to be privacy-compliant by default. You don’t need to implement any additional privacy controls or data handling mechanisms in your app code. The minimal data collection and privacy-by-design approach means that integrating Capgo typically doesn’t require changes to your existing privacy declarations or policies. ## Privacy by Design Capgo follows privacy-by-design principles: ### Data Minimization * Only collect data that is absolutely necessary for service operation * Avoid collecting personal or sensitive information * Use aggregated and anonymized data where possible ### Purpose Limitation * Use collected data only for the stated purposes * Do not repurpose data for unrelated activities * Maintain clear boundaries on data usage ### Transparency * Provide clear information about data collection and usage * Make privacy practices easily accessible and understandable * Regularly update privacy documentation ## Contact and Questions If you have questions about Capgo’s privacy practices or need to report a privacy concern: * Review our full Privacy Policy at [capgo.app/privacy](https://capgo.app/privacy) * View our security and compliance status at [capgo.app/trust](https://capgo.app/trust) * Contact our privacy team through the support channels * Report any privacy-related issues through our security contact Tip Remember to update your own app’s privacy policy to reflect the use of Capgo’s live update service and any data collection that may occur as part of the update process. ## Best Practices for Privacy When implementing Capgo in your app: 1. **Be Transparent**: Inform users about the live update functionality 2. **Minimize Data**: Only enable data collection features you actually need 3. **Secure Implementation**: Follow security best practices in your integration 4. **Regular Reviews**: Periodically review your privacy practices and update policies 5. **User Control**: Consider providing users with options to control update behavior By following these practices and understanding Capgo’s privacy approach, you can provide your users with a secure, privacy-respecting live update experience. # Custom Storage > Learn how to use custom storage solutions with Capgo Live Updates, including external URLs, S3 integration, and bundle encryption for secure deployments. Capgo supports custom storage solutions for your app bundles, allowing you to host your updates on your own infrastructure or third-party storage services. This is particularly useful for organizations with specific security requirements, compliance needs, or existing storage infrastructure. ## Overview Custom storage in Capgo works by uploading your bundle to an external location and providing Capgo with the URL to access it. The Capgo SDK will then download updates directly from your custom storage location instead of Capgo’s default cloud storage. Tip Custom storage is ideal for: * Organizations with strict data residency requirements * Teams with existing CDN or storage infrastructure * Applications requiring additional security layers * Cost optimization for large bundle sizes ## External URL Upload The simplest way to use custom storage is by uploading your bundle to any publicly accessible URL and providing that URL to Capgo. ### Basic External URL Upload ```shell npx @capgo/cli@latest bundle upload --external https://your-domain.com/bundles/v1.2.3.zip ``` This command tells Capgo to reference the bundle at the specified URL instead of uploading it to Capgo’s cloud storage. ### With Encryption For secure external storage, you can encrypt your bundle and provide the decryption keys: ```shell npx @capgo/cli@latest bundle upload --external https://your-domain.com/bundles/v1.2.3.zip --iv-session-key YOUR_IV_SESSION_KEY ``` ## S3 Integration Capgo provides built-in support for Amazon S3 and S3-compatible storage services. The CLI can automatically upload your bundle to S3 and configure Capgo to use the S3 URL. ### S3 Upload Options ```shell npx @capgo/cli@latest bundle upload \ --s3-region us-east-1 \ --s3-apikey YOUR_ACCESS_KEY \ --s3-apisecret YOUR_SECRET_KEY \ --s3-bucket-name your-bucket-name ``` ### Complete S3 Configuration For S3-compatible services or custom endpoints: ```shell npx @capgo/cli@latest bundle upload \ --s3-region us-east-1 \ --s3-apikey YOUR_ACCESS_KEY \ --s3-apisecret YOUR_SECRET_KEY \ --s3-endpoint https://s3.your-provider.com \ --s3-bucket-name your-bucket-name \ --s3-port 443 \ --no-s3-ssl # Only if your endpoint doesn't support SSL ``` ### S3 Configuration Parameters | Parameter | Description | Required | | ------------------ | ----------------------------- | -------- | | `--s3-region` | AWS region for your S3 bucket | Yes | | `--s3-apikey` | S3 access key ID | Yes | | `--s3-apisecret` | S3 secret access key | Yes | | `--s3-bucket-name` | Name of your S3 bucket | Yes | | `--s3-endpoint` | Custom S3 endpoint URL | No | | `--s3-port` | Port for S3 endpoint | No | | `--no-s3-ssl` | Disable SSL for S3 upload | No | ## Bundle Preparation and Encryption When using custom storage, especially with encryption, you need to prepare your bundles properly. This involves creating a zip file and optionally encrypting it. ### Step 1: Create a Zip Bundle First, create a zip file of your app bundle: ```shell npx @capgo/cli@latest bundle zip com.example.app --path ./dist ``` The zip command will return the checksum of the zip file. You can use this checksum to encrypt the zip file if needed. Use the `--json` option to get structured output including the checksum. #### Zip Command Options ```shell npx @capgo/cli@latest bundle zip [appId] \ --path ./dist \ --bundle 1.2.3 \ --name myapp-v1.2.3 \ --json \ --no-code-check \ --key-v2 \ --package-json ../../package.json,./package.json ``` | Option | Description | | ----------------- | -------------------------------------------------------------------- | | `--path` | Path to the folder to zip (defaults to webDir from capacitor.config) | | `--bundle` | Bundle version number to name the zip file | | `--name` | Custom name for the zip file | | `--json` | Output results in JSON format (includes checksum) | | `--no-code-check` | Skip checking for notifyAppReady() call and index file | | `--key-v2` | Use encryption v2 | | `--package-json` | Paths to package.json files for monorepos (comma separated) | ### Step 2: Encrypt the Bundle (Optional) For enhanced security, encrypt your zip bundle before uploading: ```shell # Using default local key npx @capgo/cli@latest bundle encrypt ./myapp.zip CHECKSUM # Using custom key file npx @capgo/cli@latest bundle encrypt ./myapp.zip CHECKSUM --key ./path/to/.capgo_key_v2 # Using key data directly npx @capgo/cli@latest bundle encrypt ./myapp.zip CHECKSUM --key-data "PRIVATE_KEY_CONTENT" ``` The `CHECKSUM` parameter is required and should be the checksum of your zip file. You can get the checksum from the zip command output (use `--json` option for structured output). By default, the encrypt command will use your local private signing key. You can specify a custom key using the `--key` or `--key-data` options. The encrypt command will return the `ivSessionKey` needed for upload or decryption. #### Encryption Command Options | Option | Description | | ------------ | ------------------------------------------------------------------------- | | `zipPath` | Path to the zip file to encrypt (required) | | `checksum` | Checksum of the zip file (required) - get it from zip command | | `--key` | Custom path for private signing key (optional, uses local key by default) | | `--key-data` | Private signing key data directly (optional) | | `--json` | Output results in JSON format | Caution The encrypt command will output an `ivSessionKey` that you’ll need to provide when uploading with the `--iv-session-key` option. ## Complete Workflow Examples ### Example 1: External URL with Encryption 1. **Build your app:** ```shell npm run build ``` 2. **Create a zip bundle:** ```shell npx @capgo/cli@latest bundle zip com.example.app --path ./dist --bundle 1.2.3 ``` Note the checksum returned by this command. 3. **Encrypt the bundle:** ```shell npx @capgo/cli@latest bundle encrypt ./com.example.app-1.2.3.zip CHECKSUM_FROM_STEP_2 ``` Note the `ivSessionKey` from the output. 4. **Upload to your storage:** Upload the encrypted zip file to your hosting service. 5. **Register with Capgo:** ```shell npx @capgo/cli@latest bundle upload \ --external https://your-cdn.com/bundles/com.example.app-1.2.3.zip \ --iv-session-key IV_SESSION_KEY_FROM_STEP_3 ``` ### Example 2: Direct S3 Upload 1. **Build your app:** ```shell npm run build ``` 2. **Upload directly to S3:** ```shell npx @capgo/cli@latest bundle upload \ --s3-region us-west-2 \ --s3-apikey YOUR_ACCESS_KEY \ --s3-apisecret YOUR_SECRET_KEY \ --s3-bucket-name your-app-bundles \ --channel Production ``` ### Example 3: S3 with Encryption 1. **Build and zip:** ```shell npm run build npx @capgo/cli@latest bundle zip com.example.app --path ./dist --key-v2 ``` 2. **Encrypt the bundle:** ```shell npx @capgo/cli@latest bundle encrypt ./com.example.app.zip CHECKSUM ``` 3. **Upload to S3 with encryption:** ```shell npx @capgo/cli@latest bundle upload \ --s3-region us-west-2 \ --s3-apikey YOUR_ACCESS_KEY \ --s3-apisecret YOUR_SECRET_KEY \ --s3-bucket-name your-app-bundles \ --iv-session-key IV_SESSION_KEY_FROM_STEP_2 \ --channel Production ``` ## Security Considerations When using custom storage, consider these security best practices: ### Access Control * Ensure your storage URLs are accessible to your app users but not publicly discoverable * Use signed URLs or token-based authentication when possible * Implement proper CORS headers for web-based apps ### Encryption * Always encrypt sensitive bundles using the Capgo encryption tools * Store encryption keys securely and rotate them regularly * Use HTTPS for all bundle URLs (required for iOS and Android) ### Monitoring * Monitor access logs to detect unusual download patterns * Set up alerts for failed bundle downloads * Regularly audit your storage permissions ## Troubleshooting ### Common Issues **Bundle not downloading:** * Verify the URL is publicly accessible and uses HTTPS (required for iOS and Android) * Check CORS headers for web apps * Ensure the bundle format is correct **Encryption errors:** * Verify the `ivSessionKey` matches the encrypted bundle * Check that the bundle was encrypted with the correct key * Ensure encryption v2 is used for new bundles **S3 upload failures:** * Verify your S3 credentials and permissions * Check bucket policies and CORS configuration * Ensure the specified region is correct ### Debug Commands Check bundle status: ```shell npx @capgo/cli@latest app debug ``` Verify bundle integrity: ```shell npx @capgo/cli@latest bundle list ``` ## Next Steps * Learn about [Channels](/docs/live-updates/channels/) to manage different deployment environments * Explore [Update Behavior](/docs/live-updates/update-behavior/) to customize how updates are applied * Set up [CI/CD Integration](/docs/getting-started/cicd-integration/) to automate your custom storage workflow # Delta updates > Learn how Capgo's differential updates optimize data transfer by only sending changed files, enhancing performance on slower networks. Capgo’s Live Update system can deliver updates faster and more efficiently by only sending the changed files, rather than the entire JS bundle. This is especially beneficial for users on slower or metered network connections, as it minimizes the amount of data that needs to be downloaded. A second benefit is when the app have large assets who change rarely, like images or videos, compare to zipped JS files it will be downloaded only once. ## How Differential Updates Work Differential updates in Capgo are handled by the Capgo plugin installed in your app. When you upload a new version of your app using the `--partial` flag, Capgo does the following: 1. Each file in your build is uploaded individually 2. Checksums are generated for each file 3. A new json manifest is created, listing all files and their checksums 4. This manifest is uploaded to the Capgo database When a device running your app checks for an update, the Capgo plugin receives the new manifest from the server. It compares this manifest to the one it currently has, identifying which files have changed based on the checksums and files path. The plugin then downloads only the changed files, rather than the entire JS bundle. It reconstructs the new version of the app by combining these downloaded files with the unchanged files it already has. Manifest In case of differential updates, the device stores all downloaded files in a common cache, Capgo will never clean it but the OS can at any time. ## Enabling Differential Updates To enable differential updates for your Capgo app, simply use the `--partial` flag when uploading a new version: ## Enforcing Differential Updates If you want to ensure that all uploads are differential updates and prevent any accidental full bundle uploads, you can use the `--partial-only` flag: ```shell npx @capgo/cli@latest bundle upload --partial-only ``` When `--partial-only` is used, Capgo will only upload individual files and generate a manifest. Any device who do not support partial will not be able to download the update. You might want to use `--partial-only` if: * You always want to use differential updates and never want to allow full bundle uploads * You’re setting up a CI/CD pipeline and want to ensure all automated uploads are differential * Your app is large and bandwidth is constrained, so you need to minimize upload/download sizes If you need to do a full bundle upload while `--partial-only` is set, simply run the upload command without `--partial-only`. This will override the setting for that single upload, allowing you to push a complete bundle when needed. ## Troubleshooting If differential updates don’t seem to be working (i.e. devices are always downloading the full JS bundle even for small changes), double check that: * You’re using the `--partial` flag every time you upload a new version * If using `--partial-only`, make sure you haven’t accidentally omitted the `--partial` flag * Your device is running the latest version of the Capgo plugin * Your device has a stable network connection and can reach the Capgo servers You can also use the Capgo webapp to check the details of your last upload: 1. Go to the [webapp](https://app.capgo.io) 2. Click on your app 3. Click on the bunldes number of the stats bar. 4. Select the last bundle 5. Check the `Partial` field ![bundle type](/bundle_type.webp) If you continue to have trouble, please reach out to Capgo support for further assistance. They can check the server logs to confirm that your partial uploads are being processed correctly and that devices are receiving the updated manifests. That’s it! The `--partial` flag tells Capgo to perform the individual file uploads and manifest generation needed for differential updates. Note that you need to use `--partial` every time you upload a new version that you want to be delivered as a differential update. If you omit the flag, Capgo will upload the entire JS bundle as a single file, and devices will download the whole bundle even if only a small part has changed. # Encryption > Learn how Capgo's end-to-end encryption secures your app bundles during transmission and storage, protecting your code and user data. Capgo provides robust end-to-end encryption for your app bundles, ensuring that your JavaScript code and assets are protected during transmission and storage. This encryption system is designed to give you complete control over your app’s security while maintaining the convenience of live updates. ## Overview Capgo’s encryption system uses industry-standard cryptographic methods to protect your bundles from unauthorized access. When encryption is enabled, your bundles are encrypted before leaving your development environment and remain encrypted until they’re decrypted by your app on the user’s device. **True End-to-End Encryption**: Unlike other OTA update platforms that only sign updates (leaving the code publicly readable), Capgo provides true end-to-end encryption. This means only your users can decrypt your updates - no one else, including Capgo itself. Your bundle content remains completely private and unreadable throughout the entire delivery process. Tip Encryption is particularly important for: * Apps handling sensitive data or business logic * Enterprise applications with compliance requirements * Apps deployed in regulated industries * Organizations with strict security policies ## How Encryption Works Capgo uses a hybrid encryption approach that combines RSA and AES encryption for optimal security and performance: ![Capgo Encryption Flow](/encryption_flow.webp) ### 1. Key Generation * **Private Key**: Generated and stored securely in your development environment (used for encryption) * **Public Key**: Derived from your private key and stored in your app’s Capacitor config (used for decryption) * **Session Keys**: Random AES keys generated for each bundle upload ### 2. Encryption Process 1. A random AES session key is generated for each bundle upload 2. Your bundle is encrypted using the AES session key 3. The bundle checksum is calculated 4. Both the AES session key and checksum are encrypted together using your RSA private key (creating the “signature”) 5. The encrypted bundle and encrypted signature are stored The checksum is encrypted alongside the AES key to prevent tampering. Since only your RSA private key can create this signature, and only the corresponding public key can decrypt it, this ensures that both the AES session key and the expected checksum are authentic and haven’t been modified by an attacker. ### 3. Decryption Process 1. Your app downloads the encrypted bundle and encrypted signature 2. The Capgo SDK uses your RSA public key (stored in the app) to decrypt the signature 3. This reveals the AES session key and the original checksum 4. The AES session key is used to decrypt the bundle 5. A checksum of the decrypted bundle is calculated and compared with the original checksum for integrity verification This process ensures that even if an attacker intercepts the encrypted bundle, they cannot modify the AES session key or provide a fake checksum, because they would need your private key to create a valid signature that the public key can decrypt. Tip RSA cannot encrypt large amounts of data efficiently, so AES is used for the actual bundle encryption while RSA secures the AES key and provides integrity verification through checksum signing. ## Capgo vs Other Platforms | Feature | Capgo | Other OTA Platforms | | ------------------- | ------------------------------------------------ | ----------------------------- | | **Bundle Content** | Fully encrypted (unreadable) | Publicly readable | | **Security Method** | True end-to-end encryption | Code signing only | | **Privacy Level** | Zero-knowledge (even Capgo can’t read your code) | Platform can access your code | | **Protection** | Content + integrity + authenticity | Integrity + authenticity only | **Why This Matters:** * **Code signing** only verifies that updates haven’t been tampered with and come from the right source * **End-to-end encryption** ensures that your actual code content remains private and unreadable during transmission and storage * With Capgo’s true end-to-end encryption, only your users can decrypt updates - no one else, including Capgo itself ## Encryption Methods Capgo uses Encryption V2 as the standard encryption method: ### Encryption V2 (Current Standard) * Uses RSA-4096 for enhanced security * AES-256-GCM for authenticated encryption * Provides integrity verification * Better performance and security ### Encryption V1 (Deprecated) * Uses RSA-2048 for key encryption * AES-256-CBC for bundle encryption * **No longer available in the current CLI** * Legacy apps using V1 must migrate to V2 Danger Encryption V1 is no longer supported in the current Capgo CLI. If you’re using V1 encryption, you must migrate to V2. See the [migration guide](/docs/upgrade/encryption-v1-to-v2/) for detailed instructions. ## Setting Up Encryption ### Step 1: Generate Encryption Keys First, generate your encryption keys using the Capgo CLI: ```shell # Generate new encryption keys (creates files in current directory) npx @capgo/cli@latest key create ``` This creates: * `.capgo_key_v2`: Your private key (keep this secure!) * `.capgo_key_v2.pub`: Your public key (used by your app) These files are created in the current directory where you run the command. Caution **Important Storage Notes:** * **Private Key (`.capgo_key_v2`)**: Never commit this to version control. This file should be kept secure and used only for encryption during bundle uploads. * **Public Key (`.capgo_key_v2.pub`)**: This is safe to commit to version control as it’s a backup of your public key. * **File Location**: Keys are created in the current directory where you run the `key create` command. * **Public Key in Config**: You must run `key save` to store the public key in your Capacitor config for the mobile app to use. For production use, store the private key securely (environment variables, key management services) and remove it from your local project after setup. ### Step 2: Save Your Public Key to Capacitor Config (Required) You **must** save your public key to the Capacitor config so your mobile app can decrypt bundles: ```shell # Save public key from file to Capacitor config (required) npx @capgo/cli@latest key save --key ./.capgo_key_v2.pub # Or save public key data directly npx @capgo/cli@latest key save --key-data "$CAPGO_PUBLIC_KEY" ``` ### Step 3: Sync Capacitor Platform (Required) After saving the public key, you **must** sync the Capacitor platform to copy the updated config to the native layer: ```shell # Sync the platform to copy config to native npx cap sync ``` Caution **Required Steps**: 1. The `key save` command stores the public key in your Capacitor config 2. `npx cap sync` copies this config to the native layer where the mobile app can access it 3. Without both steps, your app won’t be able to decrypt encrypted updates ## Encrypting Bundles ### Method 1: Encrypt During Upload The simplest way is to encrypt during the upload process: ```shell # Upload with automatic encryption npx @capgo/cli@latest bundle upload --key-v2 # For external storage, you must encrypt first (see Manual Encryption Workflow below) ``` ### Method 2: Manual Encryption Workflow For more control, you can manually encrypt bundles: 1. **Create a zip bundle:** ```shell npx @capgo/cli@latest bundle zip com.example.app --path ./dist --key-v2 ``` 2. **Encrypt the bundle:** ```shell npx @capgo/cli@latest bundle encrypt ./com.example.app.zip CHECKSUM_FROM_STEP_1 ``` 3. **Upload to your storage (e.g., S3) and register with Capgo:** ```shell # First upload the encrypted bundle to your storage (e.g., AWS S3) aws s3 cp ./encrypted-bundle.zip s3://your-bucket/encrypted-bundle.zip # Then register with Capgo using the external URL npx @capgo/cli@latest bundle upload --external https://your-storage.com/encrypted-bundle.zip --iv-session-key IV_SESSION_KEY_FROM_STEP_2 ``` ## Key Management ### Storing Keys Securely **Private Key Options:** 1. **File-based (local development):** ```shell # Key stored as .capgo_key_v2 file in project root npx @capgo/cli@latest bundle upload --key-v2 ``` 2. **Environment variable (CI/CD):** ```shell # Store in environment variable for CI export CAPGO_PRIVATE_KEY="$(cat .capgo_key_v2)" npx @capgo/cli@latest bundle upload --key-data-v2 "$CAPGO_PRIVATE_KEY" ``` **Public Key Setup (Required):** ```shell # Must save public key to Capacitor config for mobile app npx @capgo/cli@latest key save --key ./.capgo_key_v2.pub ``` **Production Environment:** * Store private keys in secure key management services (AWS KMS, Azure Key Vault, etc.) * Use CI/CD secret management for private keys * Never commit private keys to version control **Key Usage:** * **Private Key**: Used by CLI for encryption during bundle upload (keep secure) * **Public Key**: Stored in app configuration for decryption on device (safe to commit) ### Key Rotation Regularly rotate your encryption keys for enhanced security: 1. **Generate new keys:** ```shell # Navigate to desired directory first, then create keys mkdir ./new-keys && cd ./new-keys npx @capgo/cli@latest key create ``` 2. **Save the new public key to Capacitor config:** ```shell npx @capgo/cli@latest key save --key ./new-keys/.capgo_key_v2.pub ``` 3. **Update your app configuration** with the new public key 4. **Deploy the updated app** before uploading encrypted bundles with the new key ## Security Best Practices ### Key Security * **Never share private keys** between environments or team members * **Use different keys** for different environments (dev, staging, production) * **Rotate keys regularly** (recommended: every 6-12 months) * **Store keys securely** using proper key management systems ### Bundle Security * **Always verify** bundle integrity after decryption * **Monitor** for unusual download patterns or failures * **Use HTTPS** for all bundle URLs (required for mobile apps) * **Implement** proper error handling for decryption failures ### Access Control * **Limit access** to encryption keys to authorized personnel only * **Use role-based access** for key management operations * **Audit** key usage and access regularly * **Implement** proper backup and recovery procedures ## Troubleshooting Encryption ### Common Issues **Decryption failures:** * Verify the private key matches the public key used for encryption * Check that the `ivSessionKey` is correct * Ensure you’re using Encryption V2 (V1 is no longer supported) **Key-related errors:** * Confirm the private key format is correct (PEM format) * Verify the key hasn’t been corrupted during storage/transfer * Check that the key has proper permissions in your app configuration **Performance issues:** * Large bundles may take longer to encrypt/decrypt * Consider using differential updates to reduce bundle sizes * Monitor device performance during decryption ### Debug Commands Check encryption status: ```shell npx @capgo/cli@latest app debug ``` Test encryption/decryption workflow: ```shell # Test the complete workflow: zip → encrypt → decrypt → unzip npx @capgo/cli@latest bundle zip com.example.app --key-v2 npx @capgo/cli@latest bundle encrypt ./com.example.app.zip CHECKSUM --json npx @capgo/cli@latest bundle decrypt ./encrypted-bundle.zip IV_SESSION_KEY ``` ## Compliance and Standards Capgo’s encryption implementation follows industry standards: * **AES-256**: FIPS 140-2 approved encryption algorithm * **RSA-4096**: Strong asymmetric encryption for key protection * **GCM Mode**: Provides both confidentiality and authenticity * **Secure Random**: Cryptographically secure random number generation This makes Capgo suitable for applications requiring compliance with: * GDPR (General Data Protection Regulation) * HIPAA (Health Insurance Portability and Accountability Act) * SOC 2 (Service Organization Control 2) * ISO 27001 (Information Security Management) ## Performance Considerations ### Encryption Overhead * **Bundle size**: Encrypted bundles are slightly larger (\~1-2% overhead) * **Processing time**: Encryption/decryption adds minimal latency * **Memory usage**: Temporary increase during encryption/decryption operations ### Optimization Tips * Use differential updates to minimize encrypted data transfer * Optimize your bundle size by converting images to WebP format * Minimize JavaScript and CSS files before bundling * Remove unused dependencies and code * Monitor device performance on older/slower devices ## Next Steps * Learn about [Custom Storage](/docs/live-updates/custom-storage/) to use encryption with your own infrastructure * Explore [Channels](/docs/live-updates/channels/) to manage encrypted bundles across environments * Set up [CI/CD Integration](/docs/getting-started/cicd-integration/) to automate encrypted deployments # CI/CD Integrations > Integrate Capgo Live Updates with your favorite CI/CD platform for automated deployment workflows. Automate your Capgo Live Updates deployment process by integrating with popular CI/CD platforms. These integrations allow you to automatically deploy app updates whenever you push code changes, test feature branches, and manage multiple deployment environments. ## Available Integrations Choose your CI/CD platform to get started with automated deployments: [Azure DevOps ](/docs/live-updates/integrations/azure-devops/)Integrate with Azure DevOps Pipelines for automated builds, testing, and deployment workflows. [GitLab CI/CD ](/docs/live-updates/integrations/gitlab-ci/)Set up GitLab CI/CD pipelines to automatically deploy your app updates with comprehensive environment management. [GitHub Actions ](/docs/live-updates/integrations/github-actions/)Use GitHub Actions for powerful automation with multi-channel deployments and environment protection. [Bitbucket Pipelines ](/docs/live-updates/integrations/bitbucket-pipeline/)Deploy with Bitbucket Pipelines using simple or advanced configurations for multiple environments. ## What You’ll Get All integration guides include: * **Simple Setup**: Basic configuration to get started quickly * **Advanced Workflows**: Multi-environment deployments with staging and production * **Feature Branch Testing**: Automatic deployment of feature branches to test channels * **Security Best Practices**: Secure secret management and environment protection * **Monitoring**: Notifications and logging for deployment status Tip **New to CI/CD?** Start with the simple configuration for your platform, then gradually add more advanced features like multi-channel deployments and automated testing as your needs grow. ## Common Features Each integration supports: * **Automated Builds**: Trigger deployments on code changes * **Multi-Channel Support**: Deploy to different channels (development, staging, production) * **Pull Request/Merge Request Testing**: Test changes in isolated environments * **Encryption Support**: Secure deployments with Capgo’s encryption feature * **Environment Protection**: Manual approvals and restricted access for production * **Notifications**: Slack, email, and other notification integrations ## Prerequisites Before setting up any integration, ensure you have: * A Capgo account with an app configured * Your app’s source code in a Git repository * A Capgo API token from [web.capgo.app/apikeys](https://web.capgo.app/apikeys) * Node.js and npm/yarn configured in your project ## Related Documentation * [Channels](/docs/live-updates/channels/) - Learn how to manage different deployment environments * [Encryption](/docs/live-updates/encryption/) - Secure your deployments with end-to-end encryption * [Update Behavior](/docs/live-updates/update-behavior/) - Customize how updates are applied to your apps Choose your CI/CD platform above to start automating your Capgo deployments! # Azure DevOps Integration > Learn how to integrate Capgo Live Updates with Azure DevOps Pipelines for automated deployment of your app updates. Integrate Capgo Live Updates with Azure DevOps Pipelines to automatically deploy your app updates whenever you push code changes. This guide covers setting up automated builds, testing, and deployment workflows. ## Prerequisites Before setting up Azure DevOps integration, ensure you have: * An Azure DevOps organization and project * A Capgo account with an app configured * Your app’s source code in an Azure Repos Git repository * Node.js and npm/yarn configured in your project ## Setting Up Azure DevOps Pipeline ### Step 1: Create Pipeline Variables First, set up the necessary variables in your Azure DevOps project: 1. Navigate to your Azure DevOps project 2. Go to **Pipelines** → **Library** → **Variable groups** 3. Create a new variable group named `Capgo-Variables` 4. Add the following variables: | Variable Name | Value | Secure | | ------------- | -------------------- | ------ | | `CAPGO_TOKEN` | Your Capgo API token | ✅ Yes | Tip Get your Capgo API token from [web.capgo.app/apikeys](https://web.capgo.app/apikeys). Your app ID is already configured in your `capacitor.config.ts` file. ## Simple Basic configuration that deploys to production on every push to the main branch: ```yaml # Simple Azure DevOps Pipeline for Capgo Live Updates trigger: branches: include: - main variables: - group: Capgo-Variables jobs: - job: BuildAndDeploy displayName: 'Build and Deploy to Capgo' pool: vmImage: 'ubuntu-latest' steps: - task: NodeTool@0 displayName: 'Setup Node.js' inputs: versionSpec: '22.x' - script: | npm ci npm run test npm run build displayName: 'Install, test and build' - script: | npm install -g @capgo/cli npx @capgo/cli bundle upload --apikey $(CAPGO_TOKEN) --channel production displayName: 'Deploy to Capgo' ``` ## Advanced ### Feature Branch Deployments Deploy feature branches to test channels for review and testing: ```yaml # Feature branch deployment trigger: branches: include: - feature/* variables: - group: Capgo-Variables jobs: - job: DeployFeature displayName: 'Deploy Feature Branch' pool: vmImage: 'ubuntu-latest' condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/feature/') steps: - task: NodeTool@0 inputs: versionSpec: '22.x' - script: | npm ci npm run test npm run build displayName: 'Install, test and build' - script: | BRANCH_NAME=$(echo "$(Build.SourceBranchName)" | sed 's/[^a-zA-Z0-9-]/-/g') CHANNEL_NAME="feature-$BRANCH_NAME" npm install -g @capgo/cli npx @capgo/cli channel create $CHANNEL_NAME --apikey $(CAPGO_TOKEN) || true npx @capgo/cli bundle upload --apikey $(CAPGO_TOKEN) --channel $CHANNEL_NAME displayName: 'Deploy to Feature Channel' ``` Tip **Testing with Channels**: After deploying to a feature channel, you can test the update in your app by configuring it to use that specific channel. Learn more about [configuring channels in your app](/docs/live-updates/channels/#configuring-the-channel-in-your-app). ### Using Encryption If you’re using [Capgo’s encryption feature](/docs/live-updates/encryption/), you’ll need to store your private key securely in your CI/CD environment. After [setting up encryption keys](/docs/live-updates/encryption/#setting-up-encryption) locally, add your private key to Azure DevOps variables: ```shell # Display your private key content (copy this output) cat .capgo_key_v2 ``` Add this content as `CAPGO_PRIVATE_KEY` in your Azure DevOps variable group (mark as secret), then use it in pipelines: ```yaml # Deploy with encryption - script: | npm install -g @capgo/cli npx @capgo/cli bundle upload --apikey $(CAPGO_TOKEN) --key-data-v2 "$(CAPGO_PRIVATE_KEY)" --channel production displayName: 'Deploy to Capgo with Encryption' ``` Caution **Security Best Practices:** * Never commit the `.capgo_key_v2` file to version control * Store the private key only in secure CI/CD secret management * Use different keys for different environments ### Multi-Channel Configuration For comprehensive information about setting up and managing multiple deployment channels, see the [Channels documentation](/docs/live-updates/channels/). Complete configuration with multiple environments and pull request deployments: ```yaml # Advanced Azure DevOps Pipeline with Multiple Channels trigger: branches: include: - main - develop pr: branches: include: - main - develop variables: - group: Capgo-Variables stages: # Build stage - stage: Build jobs: - job: BuildApp pool: vmImage: 'ubuntu-latest' steps: - task: NodeTool@0 inputs: versionSpec: '22.x' - script: | npm ci npm run test npm run build displayName: 'Install, test and build' - task: PublishBuildArtifacts@1 inputs: pathToPublish: 'dist' artifactName: 'app-build' # Deploy to development - stage: DeployDev condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/develop')) jobs: - deployment: DeployDevelopment environment: development pool: vmImage: 'ubuntu-latest' strategy: runOnce: deploy: steps: - task: NodeTool@0 inputs: versionSpec: '22.x' - task: DownloadBuildArtifacts@0 inputs: artifactName: 'app-build' downloadPath: '$(Pipeline.Workspace)' - script: | npm install -g @capgo/cli npx @capgo/cli bundle upload --apikey $(CAPGO_TOKEN) --channel development --path $(Pipeline.Workspace)/app-build displayName: 'Deploy to Development' # Deploy PR to test channel - stage: DeployPR condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest')) jobs: - job: DeployPRChannel pool: vmImage: 'ubuntu-latest' steps: - task: NodeTool@0 inputs: versionSpec: '22.x' - task: DownloadBuildArtifacts@0 inputs: artifactName: 'app-build' downloadPath: '$(Pipeline.Workspace)' - script: | CHANNEL_NAME="pr-$(System.PullRequest.PullRequestNumber)" npm install -g @capgo/cli npx @capgo/cli channel create $CHANNEL_NAME --apikey $(CAPGO_TOKEN) || true npx @capgo/cli bundle upload --apikey $(CAPGO_TOKEN) --channel $CHANNEL_NAME --path $(Pipeline.Workspace)/app-build displayName: 'Deploy to PR Channel' # Deploy to production - stage: DeployProd condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')) jobs: - deployment: DeployProduction environment: production pool: vmImage: 'ubuntu-latest' strategy: runOnce: deploy: steps: - task: NodeTool@0 inputs: versionSpec: '22.x' - task: DownloadBuildArtifacts@0 inputs: artifactName: 'app-build' downloadPath: '$(Pipeline.Workspace)' - script: | npm install -g @capgo/cli npx @capgo/cli bundle upload --apikey $(CAPGO_TOKEN) --channel production --path $(Pipeline.Workspace)/app-build displayName: 'Deploy to Production' ``` ### Multi-Environment Deployment For complex scenarios with multiple environments: ```yaml # Extended pipeline with multiple environments parameters: - name: deployEnvironment displayName: 'Deploy Environment' type: string default: 'staging' values: - staging - production variables: - group: Capgo-Variables - name: channelName ${{ if eq(parameters.deployEnvironment, 'production') }}: value: 'production' ${{ else }}: value: 'staging' stages: # Build stage - stage: Build jobs: - job: BuildApp pool: vmImage: 'ubuntu-latest' steps: - task: NodeTool@0 inputs: versionSpec: '22.x' - script: | npm ci npm run test npm run build displayName: 'Install, test and build' - task: PublishBuildArtifacts@1 inputs: pathToPublish: 'dist' artifactName: 'app-build' - stage: DeployStaging displayName: 'Deploy to Staging' dependsOn: Build condition: and(succeeded(), eq('${{ parameters.deployEnvironment }}', 'staging')) jobs: - deployment: DeployStaging displayName: 'Deploy to Staging Channel' pool: vmImage: 'ubuntu-latest' environment: 'staging' strategy: runOnce: deploy: steps: - template: deploy-steps.yml parameters: channel: 'staging' - stage: DeployProduction displayName: 'Deploy to Production' dependsOn: Build condition: and(succeeded(), eq('${{ parameters.deployEnvironment }}', 'production')) jobs: - deployment: DeployProduction displayName: 'Deploy to Production Channel' pool: vmImage: 'ubuntu-latest' environment: 'production' strategy: runOnce: deploy: steps: - template: deploy-steps.yml parameters: channel: 'production' ``` ### Deployment Template (deploy-steps.yml) Create a reusable template file `deploy-steps.yml`: deploy-steps.yml ```yaml parameters: - name: channel type: string steps: - task: NodeTool@0 displayName: 'Install Node.js' inputs: versionSpec: '22.x' - task: DownloadBuildArtifacts@0 displayName: 'Download build artifacts' inputs: artifactName: 'app-build' downloadPath: '$(System.ArtifactsDirectory)' - script: | npm install -g @capgo/cli displayName: 'Install Capgo CLI' - script: | npx @capgo/cli bundle upload \ --apikey $(CAPGO_TOKEN) \ --channel ${{ parameters.channel }} \ --path $(System.ArtifactsDirectory)/app-build displayName: 'Upload to Capgo (${{ parameters.channel }})' ``` ### Branch-Based Deployment Strategy Configure different deployment strategies based on Git branches: ```yaml trigger: branches: include: - main - develop - feature/* variables: - group: Capgo-Variables - name: targetChannel ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}: value: 'production' ${{ elseif eq(variables['Build.SourceBranch'], 'refs/heads/develop') }}: value: 'staging' ${{ else }}: value: 'development' stages: - stage: Build jobs: - job: BuildApp pool: vmImage: 'ubuntu-latest' steps: - task: NodeTool@0 inputs: versionSpec: '22.x' - script: | npm ci npm run test npm run build displayName: 'Install, test and build' - task: PublishBuildArtifacts@1 inputs: pathToPublish: 'dist' artifactName: 'app-build' - stage: Deploy displayName: 'Deploy to $(targetChannel)' dependsOn: Build condition: succeeded() jobs: - deployment: DeployJob displayName: 'Deploy to $(targetChannel) Channel' pool: vmImage: 'ubuntu-latest' environment: '$(targetChannel)' strategy: runOnce: deploy: steps: - template: deploy-steps.yml parameters: channel: '$(targetChannel)' ``` ## Security Best Practices ### Secure Variable Management 1. **Use Variable Groups**: Store sensitive data in Azure DevOps variable groups 2. **Mark as Secret**: Always mark API tokens and keys as secret variables 3. **Scope Access**: Limit variable group access to specific pipelines and users 4. **Rotate Keys**: Regularly rotate your Capgo API tokens ## Monitoring and Notifications ### Teams Integration Add Microsoft Teams notifications to your pipeline: ```yaml - task: ms-teams-deploy-card@1.4.1 displayName: 'Notify Teams on Success' condition: succeeded() inputs: webhookUri: '$(TEAMS_WEBHOOK_URL)' title: 'Capgo Deployment Successful' text: 'App deployed to $(targetChannel) channel' themeColor: '00FF00' - task: ms-teams-deploy-card@1.4.1 displayName: 'Notify Teams on Failure' condition: failed() inputs: webhookUri: '$(TEAMS_WEBHOOK_URL)' title: 'Capgo Deployment Failed' text: 'Deployment to $(targetChannel) failed' themeColor: 'FF0000' ``` ### Email Notifications Configure email notifications for deployment status: ```yaml - task: EmailReport@1 displayName: 'Send Email Report' condition: always() inputs: sendMailConditionConfig: 'Always' subject: 'Capgo Deployment Report - $(Build.BuildNumber)' to: 'team@yourcompany.com' body: | Deployment Status: $(Agent.JobStatus) Channel: $(targetChannel) Build: $(Build.BuildNumber) Commit: $(Build.SourceVersion) ``` ## Troubleshooting ### Common Issues **Pipeline fails with “Capgo CLI not found”:** ```yaml # Ensure global installation - script: | npm install -g @capgo/cli which capgo || echo "Capgo CLI not found in PATH" displayName: 'Install and verify Capgo CLI' ``` **Authentication errors:** ```yaml # Verify token is correctly set - script: | echo "Token length: ${#CAPGO_TOKEN}" if [ -z "$CAPGO_TOKEN" ]; then echo "CAPGO_TOKEN is not set" exit 1 fi displayName: 'Verify Capgo token' env: CAPGO_TOKEN: $(CAPGO_TOKEN) ``` **Build artifacts not found:** ```yaml # List available artifacts for debugging - script: | ls -la $(System.ArtifactsDirectory) find $(System.ArtifactsDirectory) -name "*.js" -o -name "*.html" displayName: 'Debug artifacts' ``` ### Debug Pipeline Add debugging steps to troubleshoot issues: ```yaml - script: | echo "Build.SourceBranch: $(Build.SourceBranch)" echo "Build.BuildNumber: $(Build.BuildNumber)" echo "Target Channel: $(targetChannel)" displayName: 'Debug Pipeline Variables' - script: | npx @capgo/cli app debug --apikey $(CAPGO_TOKEN) displayName: 'Debug Capgo App Status' ``` ## Next Steps * Learn about [Channels](/docs/live-updates/channels/) to manage different deployment environments * Explore [Custom Storage](/docs/live-updates/custom-storage/) for advanced deployment scenarios * Set up [Encryption](/docs/live-updates/encryption/) for secure deployments * Configure [Update Behavior](/docs/live-updates/update-behavior/) to customize how updates are applied With Azure DevOps integration, you can automate your Capgo deployments and ensure consistent, reliable updates to your mobile app users. # Bitbucket Pipelines Integration > Learn how to integrate Capgo Live Updates with Bitbucket Pipelines for automated deployment of your app updates. Integrate Capgo Live Updates with Bitbucket Pipelines to automatically deploy your app updates whenever you push code changes. This guide covers setting up automated builds, testing, and deployment workflows. ## Prerequisites Before setting up Bitbucket Pipelines integration, ensure you have: * A Bitbucket account with a repository * A Capgo account with an app configured * Node.js and npm/yarn configured in your project ## Setting Up Bitbucket Pipelines ### Step 1: Configure Repository Variables First, set up the necessary variables in your Bitbucket repository: 1. Navigate to your Bitbucket repository 2. Go to **Repository settings** → **Pipelines** → **Repository variables** 3. Add the following variables: | Variable Name | Value | Secured | | ------------- | -------------------- | ------- | | `CAPGO_TOKEN` | Your Capgo API token | ✅ Yes | Tip Get your Capgo API token from [web.capgo.app/apikeys](https://web.capgo.app/apikeys). Your app ID is already configured in your `capacitor.config.ts` file. ## Simple Basic configuration that deploys to production on every push to the main branch: ```yaml # bitbucket-pipelines.yml - Simple Configuration image: node:22 pipelines: branches: main: - step: name: Build and Deploy to Production script: - npm ci - npm run test - npm run build - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel production artifacts: - dist/** ``` ## Advanced ### Feature Branch Deployments Deploy feature branches to test channels for review and testing: ```yaml # Feature branch deployment pipelines: branches: feature/*: - step: name: Deploy Feature Branch script: - npm ci - npm run test - npm run build - BRANCH_NAME=$(echo $BITBUCKET_BRANCH | sed 's/[^a-zA-Z0-9-]/-/g') - CHANNEL_NAME="feature-$BRANCH_NAME" - npm install -g @capgo/cli - npx @capgo/cli channel create $CHANNEL_NAME --apikey $CAPGO_TOKEN || true - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel $CHANNEL_NAME artifacts: - dist/** ``` Tip **Testing with Channels**: After deploying to a feature channel, you can test the update in your app by configuring it to use that specific channel. Learn more about [configuring channels in your app](/docs/live-updates/channels/#configuring-the-channel-in-your-app). ### Using Encryption If you’re using [Capgo’s encryption feature](/docs/live-updates/encryption/), you’ll need to store your private key securely in your CI/CD environment. After [setting up encryption keys](/docs/live-updates/encryption/#setting-up-encryption) locally, add your private key to Bitbucket variables: ```shell # Display your private key content (copy this output) cat .capgo_key_v2 ``` Add this content as `CAPGO_PRIVATE_KEY` in your Bitbucket repository variables (mark as secured), then use it in pipelines: ```yaml # Deploy with encryption - step: name: Deploy to Capgo with Encryption script: - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --key-data-v2 "$CAPGO_PRIVATE_KEY" --channel production ``` Caution **Security Best Practices:** * Never commit the `.capgo_key_v2` file to version control * Store the private key only in secure CI/CD secret management * Use different keys for different environments ### Multi-Channel Configuration For comprehensive information about setting up and managing multiple deployment channels, see the [Channels documentation](/docs/live-updates/channels/). Complete configuration with multiple environments and pull request deployments: ```yaml # bitbucket-pipelines.yml - Advanced Multi-Channel Configuration image: node:22 definitions: steps: - step: &build-step name: Build Application script: - npm ci - npm run test - npm run build artifacts: - dist/** - step: &deploy-step name: Deploy to Capgo script: - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel $CHANNEL_NAME pipelines: branches: main: - step: <<: *build-step - step: <<: *deploy-step name: Deploy to Production deployment: production trigger: manual script: - export CHANNEL_NAME=production - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel $CHANNEL_NAME develop: - step: <<: *build-step - step: <<: *deploy-step name: Deploy to Development deployment: development script: - export CHANNEL_NAME=development - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel $CHANNEL_NAME pull-requests: '**': - step: <<: *build-step - step: name: Deploy PR to Test Channel script: - CHANNEL_NAME="pr-$BITBUCKET_PR_ID" - npm install -g @capgo/cli - npx @capgo/cli channel create $CHANNEL_NAME --apikey $CAPGO_TOKEN || true - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel $CHANNEL_NAME artifacts: - dist/** ``` ### Multi-Environment Pipeline For complex deployment scenarios with staging and production environments: ```yaml # Multi-environment pipeline image: node:22 pipelines: branches: main: - step: name: Build script: - npm ci - npm run test - npm run build artifacts: - dist/** - step: name: Deploy to Staging deployment: staging script: - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel staging - step: name: Deploy to Production deployment: production trigger: manual script: - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel production develop: - step: name: Build and Deploy to Development script: - npm ci - npm run test - npm run build - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel development artifacts: - dist/** ``` ### Branch-Based Deployment Strategy Automatically deploy different branches to appropriate channels: ```yaml # Dynamic channel deployment image: node:22 definitions: scripts: - script: &determine-channel | if [ "$BITBUCKET_BRANCH" = "main" ]; then export CHANNEL_NAME="production" elif [ "$BITBUCKET_BRANCH" = "develop" ]; then export CHANNEL_NAME="staging" else export CHANNEL_NAME="development" fi echo "Deploying to channel: $CHANNEL_NAME" pipelines: default: - step: name: Build and Deploy script: - npm ci - npm run test - npm run build - *determine-channel - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel $CHANNEL_NAME artifacts: - dist/** ``` ### Parallel Pipeline Execution Optimize build times with parallel steps: ```yaml # Parallel execution pipeline image: node:22 pipelines: branches: main: - parallel: - step: name: Run Tests script: - npm ci - npm run test - step: name: Lint Code script: - npm ci - npm run lint - step: name: Build Application script: - npm ci - npm run build artifacts: - dist/** - step: name: Deploy to Production deployment: production script: - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel production ``` ## Security Best Practices ### Repository Variables 1. **Secured Variables**: Always mark API tokens as secured 2. **Environment Variables**: Use deployment-specific variables when needed 3. **Access Control**: Limit repository access to authorized team members 4. **Token Rotation**: Regularly rotate your Capgo API tokens ### Deployment Environments Configure deployment environments for better security: ```yaml # Deployment with environment restrictions pipelines: branches: main: - step: name: Deploy to Production deployment: production trigger: manual script: - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel production ``` ## Monitoring and Notifications ### Slack Integration Add Slack notifications to your pipeline: ```yaml # Pipeline with Slack notifications pipelines: branches: main: - step: name: Build and Deploy script: - npm ci - npm run test - npm run build - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel production after-script: - | if [ $BITBUCKET_EXIT_CODE -eq 0 ]; then curl -X POST -H 'Content-type: application/json' \ --data '{"text":"✅ Capgo deployment successful for '$BITBUCKET_BRANCH'"}' \ $SLACK_WEBHOOK_URL else curl -X POST -H 'Content-type: application/json' \ --data '{"text":"❌ Capgo deployment failed for '$BITBUCKET_BRANCH'"}' \ $SLACK_WEBHOOK_URL fi ``` ### Email Notifications Configure email notifications through Bitbucket’s built-in features or using external services: ```yaml # Email notification step - step: name: Send Notification script: - | curl -X POST \ -H "Content-Type: application/json" \ -d '{ "to": "team@yourcompany.com", "subject": "Capgo Deployment Status", "body": "Deployment of '$BITBUCKET_BRANCH' completed with status: '$BITBUCKET_EXIT_CODE'" }' \ $EMAIL_SERVICE_URL condition: result: [successful, failed] ``` ## Troubleshooting ### Common Issues **Pipeline fails with “Capgo CLI not found”:** ```yaml # Debug CLI installation - step: name: Debug CLI script: - npm install -g @capgo/cli - which capgo || echo "Capgo CLI not found" - npx @capgo/cli --version ``` **Authentication errors:** ```yaml # Verify token configuration - step: name: Debug Auth script: - | if [ -z "$CAPGO_TOKEN" ]; then echo "CAPGO_TOKEN is not set" exit 1 fi echo "Token length: ${#CAPGO_TOKEN}" ``` **Build artifacts not found:** ```yaml # List build outputs - step: name: Debug Build script: - ls -la dist/ - find dist/ -type f -name "*.js" -o -name "*.html" ``` ### Debug Pipeline Add debugging information to troubleshoot issues: ```yaml # Debug pipeline pipelines: branches: main: - step: name: Debug Information script: - echo "Branch: $BITBUCKET_BRANCH" - echo "Commit: $BITBUCKET_COMMIT" - echo "Build: $BITBUCKET_BUILD_NUMBER" - env | grep BITBUCKET_ | sort - step: name: Build and Deploy script: - npm ci - npm run test - npm run build - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel production ``` ### Pipeline Validation Enable pipeline validation to catch configuration errors: ```yaml # Enable pipeline validation options: docker: true size: 2x pipelines: branches: main: - step: name: Validate Pipeline script: - echo "Pipeline validation successful" - step: name: Build and Deploy script: # ... deployment steps ``` ## Next Steps * Learn about [Channels](/docs/live-updates/channels/) to manage different deployment environments * Explore [Custom Storage](/docs/live-updates/custom-storage/) for advanced deployment scenarios * Set up [Encryption](/docs/live-updates/encryption/) for secure deployments * Configure [Update Behavior](/docs/live-updates/update-behavior/) to customize how updates are applied With Bitbucket Pipelines integration, you can automate your Capgo deployments and ensure consistent, reliable updates to your mobile app users. # GitHub Actions Integration > Learn how to integrate Capgo Live Updates with GitHub Actions for automated deployment of your app updates. Integrate Capgo Live Updates with GitHub Actions to automatically deploy your app updates whenever you push code changes. This guide covers setting up automated builds, testing, and deployment workflows using GitHub’s powerful CI/CD platform. ## Prerequisites Before setting up GitHub Actions integration, ensure you have: * A GitHub repository with your app’s source code * A Capgo account with an app configured * Node.js and npm/yarn configured in your project * GitHub Actions enabled for your repository ## Setting Up GitHub Secrets ### Step 1: Configure Repository Secrets Set up the necessary secrets in your GitHub repository: 1. Navigate to your GitHub repository 2. Go to **Settings** → **Secrets and variables** → **Actions** 3. Click **New repository secret** and add the following: | Secret Name | Value | | ------------- | -------------------- | | `CAPGO_TOKEN` | Your Capgo API token | Tip Get your Capgo API token from [web.capgo.app/apikeys](https://web.capgo.app/apikeys). Your app ID is already configured in your `capacitor.config.ts` file. ## Simple Production Deployment Start with this basic configuration that deploys to production on every push to the main branch: ```yaml # Simple GitHub Actions Workflow for Capgo Live Updates name: Deploy to Capgo on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v5 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' - name: Install, test and build run: | npm ci npm run test npm run build - name: Deploy to Capgo run: | npm install -g @capgo/cli npx @capgo/cli bundle upload --apikey ${{ secrets.CAPGO_TOKEN }} --channel production # For encrypted uploads, add: --key-data-v2 "${{ secrets.CAPGO_PRIVATE_KEY }}" ``` ## Advanced Multi-Channel Configuration ### Feature Branch Deployments Deploy feature branches to temporary channels for testing: ```yaml # Feature branch deployment name: Deploy Feature Branch to Capgo on: push: branches: - 'feature/**' jobs: deploy-feature: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' - run: | npm ci npm run test npm run build - name: Deploy to feature channel run: | CHANNEL_NAME=$(echo "${{ github.ref_name }}" | sed 's/[^a-zA-Z0-9]/-/g' | tr '[:upper:]' '[:lower:]') npm install -g @capgo/cli npx @capgo/cli channel create $CHANNEL_NAME --apikey ${{ secrets.CAPGO_TOKEN }} || true npx @capgo/cli bundle upload --apikey ${{ secrets.CAPGO_TOKEN }} --channel $CHANNEL_NAME ``` ### Using Encryption If you’re using [Capgo’s encryption feature](/docs/live-updates/encryption/), you’ll need to store your private key securely in your CI/CD environment. After [setting up encryption keys](/docs/live-updates/encryption/#setting-up-encryption) locally, add your private key to GitHub secrets: ```shell # Display your private key content (copy this output) cat .capgo_key_v2 ``` Add this content as `CAPGO_PRIVATE_KEY` in your GitHub repository secrets, then use it in workflows: ```yaml # Deploy with encryption - name: Deploy to Capgo with Encryption run: | npm install -g @capgo/cli npx @capgo/cli bundle upload --apikey ${{ secrets.CAPGO_TOKEN }} --key-data-v2 "${{ secrets.CAPGO_PRIVATE_KEY }}" --channel production ``` Caution **Security Best Practices:** * Never commit the `.capgo_key_v2` file to version control * Store the private key only in secure CI/CD secret management * Use different keys for different environments ### Multi-Channel Configuration For comprehensive information about setting up and managing multiple deployment channels, see the [Channels documentation](/docs/live-updates/channels/). Complete workflow with development, pull requests, and production deployments: ```yaml # Complete multi-environment workflow name: Deploy to Capgo on: push: branches: [main, develop] pull_request: branches: [main, develop] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' - run: | npm ci npm run test npm run build - uses: actions/upload-artifact@v4 with: name: dist path: dist/ deploy-development: if: github.ref == 'refs/heads/develop' needs: build runs-on: ubuntu-latest environment: development steps: - uses: actions/setup-node@v4 with: node-version: '22' - uses: actions/download-artifact@v4 with: name: dist path: dist/ - run: | npm install -g @capgo/cli npx @capgo/cli bundle upload --apikey ${{ secrets.CAPGO_TOKEN }} --channel development deploy-pr: if: github.event_name == 'pull_request' needs: build runs-on: ubuntu-latest steps: - uses: actions/setup-node@v4 with: node-version: '22' - uses: actions/download-artifact@v4 with: name: dist path: dist/ - name: Deploy to PR channel run: | CHANNEL_NAME="pr-${{ github.event.number }}" npm install -g @capgo/cli npx @capgo/cli channel create $CHANNEL_NAME --apikey ${{ secrets.CAPGO_TOKEN }} || true npx @capgo/cli bundle upload --apikey ${{ secrets.CAPGO_TOKEN }} --channel $CHANNEL_NAME - name: Comment PR uses: actions/github-script@v7 with: script: | github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: `🚀 This PR has been deployed to Capgo channel: \`pr-${{ github.event.number }}\`\n\nTo test this update in your app, configure it to use this channel. [Learn how to configure channels →](/docs/live-updates/channels/#configuring-the-channel-in-your-app)` }) deploy-production: if: github.ref == 'refs/heads/main' needs: build runs-on: ubuntu-latest environment: production steps: - uses: actions/setup-node@v4 with: node-version: '22' - uses: actions/download-artifact@v4 with: name: dist path: dist/ - run: | npm install -g @capgo/cli npx @capgo/cli bundle upload --apikey ${{ secrets.CAPGO_TOKEN }} --channel production ``` Tip **Testing with Channels**: After deploying to a PR or development channel, you can test the update in your app by configuring it to use that specific channel. Learn more about [configuring channels in your app](/docs/live-updates/channels/#configuring-the-channel-in-your-app). ### Cleanup Feature Channels Automatically clean up feature channels when branches are deleted: ```yaml name: Cleanup Feature Channels on: delete: jobs: cleanup: runs-on: ubuntu-latest if: github.event.ref_type == 'branch' && startsWith(github.event.ref, 'feature/') steps: - uses: actions/setup-node@v4 with: node-version: '22' - name: Delete Capgo channel run: | CHANNEL_NAME=$(echo "${{ github.event.ref }}" | sed 's/[^a-zA-Z0-9]/-/g' | tr '[:upper:]' '[:lower:]') npm install -g @capgo/cli npx @capgo/cli channel delete $CHANNEL_NAME --apikey ${{ secrets.CAPGO_TOKEN }} || true ``` ## Security and Best Practices ### Environment Protection Rules Set up environment protection rules in GitHub: 1. Go to **Settings** → **Environments** in your repository 2. Create environments: `development`, `staging`, `production` 3. For production environment, add: * **Required reviewers**: Add team members who must approve deployments * **Wait timer**: Add a delay before deployment (optional) * **Deployment branches**: Restrict to `main` branch only ### Secure Secrets Management Use environment-specific secrets: ```yaml # Use different secrets per environment deploy-production: environment: production steps: - name: Deploy to Production run: | npx @capgo/cli bundle upload \ --apikey ${{ secrets.CAPGO_PROD_TOKEN }} \ --app ${{ secrets.CAPGO_PROD_APP_ID }} \ --channel production ``` ## Monitoring and Notifications ### Slack Integration Add Slack notifications to your workflow: ```yaml name: Deploy with Notifications jobs: deploy: runs-on: ubuntu-latest steps: # ... deployment steps - name: Notify Slack on Success if: success() uses: 8398a7/action-slack@v3 with: status: success text: '✅ Capgo deployment successful!' fields: repo,message,commit,author,action,eventName,ref,workflow env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - name: Notify Slack on Failure if: failure() uses: 8398a7/action-slack@v3 with: status: failure text: '❌ Capgo deployment failed!' fields: repo,message,commit,author,action,eventName,ref,workflow env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} ``` ### Discord Integration Send notifications to Discord: ```yaml - name: Discord notification if: always() uses: Ilshidur/action-discord@master with: args: | Capgo deployment ${{ job.status }}! App: ${{ secrets.CAPGO_APP_ID }} Channel: ${{ github.ref_name }} Commit: ${{ github.sha }} env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} ``` ### Email Notifications Configure email notifications: ```yaml - name: Send email notification if: failure() uses: dawidd6/action-send-mail@v3 with: server_address: smtp.gmail.com server_port: 465 username: ${{ secrets.EMAIL_USERNAME }} password: ${{ secrets.EMAIL_PASSWORD }} subject: 'Capgo Deployment Failed - ${{ github.repository }}' to: team@yourcompany.com from: ci-cd@yourcompany.com body: | Deployment failed for ${{ github.repository }} Branch: ${{ github.ref_name }} Commit: ${{ github.sha }} Workflow: ${{ github.workflow }} ``` ## Troubleshooting ### Debug Workflow Add debugging steps to troubleshoot issues: ```yaml - name: Debug environment run: | echo "Node version: $(node --version)" echo "NPM version: $(npm --version)" echo "Working directory: $(pwd)" echo "Files in dist/: $(ls -la dist/ || echo 'No dist directory')" echo "Environment variables:" env | grep -E "(GITHUB_|CAPGO_)" | sort - name: Test Capgo CLI run: | npx @capgo/cli --version npx @capgo/cli app debug --apikey ${{ secrets.CAPGO_TOKEN }} --app ${{ secrets.CAPGO_APP_ID }} ``` ### Common Issues and Solutions **Workflow fails with “CAPGO\_TOKEN not found”:** ```yaml - name: Verify secrets run: | if [ -z "${{ secrets.CAPGO_TOKEN }}" ]; then echo "ERROR: CAPGO_TOKEN secret is not set" exit 1 fi echo "CAPGO_TOKEN is set (length: ${#CAPGO_TOKEN})" env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} ``` **Build artifacts not found:** ```yaml - name: Debug artifacts run: | echo "Checking for build artifacts..." ls -la dist/ || echo "No dist directory found" find . -name "*.js" -o -name "*.html" | head -10 ``` **Network connectivity issues:** ```yaml - name: Test connectivity run: | ping -c 3 api.capgo.io || echo "Ping failed" curl -I https://api.capgo.io/health || echo "Health check failed" ``` ## Reusable Workflows Create reusable workflows for consistency across projects: .github/workflows/reusable-capgo-deploy.yml ```yaml name: Reusable Capgo Deploy on: workflow_call: inputs: environment: required: true type: string channel: required: true type: string secrets: CAPGO_TOKEN: required: true CAPGO_APP_ID: required: true jobs: deploy: runs-on: ubuntu-latest environment: ${{ inputs.environment }} steps: - uses: actions/checkout@v5 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' - name: Install and build run: | npm ci npm run build - name: Deploy to Capgo run: | npm install -g @capgo/cli npx @capgo/cli bundle upload \ --apikey ${{ secrets.CAPGO_TOKEN }} \ --app ${{ secrets.CAPGO_APP_ID }} \ --channel ${{ inputs.channel }} ``` Use the reusable workflow: .github/workflows/deploy.yml ```yaml name: Deploy App on: push: branches: [main, develop] jobs: deploy-dev: if: github.ref == 'refs/heads/develop' uses: ./.github/workflows/reusable-capgo-deploy.yml with: environment: development channel: development secrets: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} CAPGO_APP_ID: ${{ secrets.CAPGO_APP_ID }} deploy-prod: if: github.ref == 'refs/heads/main' uses: ./.github/workflows/reusable-capgo-deploy.yml with: environment: production channel: production secrets: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} CAPGO_APP_ID: ${{ secrets.CAPGO_APP_ID }} ``` ## Next Steps * Learn about [Channels](/docs/live-updates/channels/) to manage different deployment environments * Explore [Custom Storage](/docs/live-updates/custom-storage/) for advanced deployment scenarios * Set up [Encryption](/docs/live-updates/encryption/) for secure deployments * Configure [Update Behavior](/docs/live-updates/update-behavior/) to customize how updates are applied With GitHub Actions integration, you can leverage GitHub’s powerful CI/CD platform to create sophisticated deployment workflows with built-in security, monitoring, and collaboration features for your Capgo Live Updates. # GitLab CI/CD Integration > Learn how to integrate Capgo Live Updates with GitLab CI/CD for automated deployment of your app updates. Integrate Capgo Live Updates with GitLab CI/CD to automatically deploy your app updates whenever you push code changes. This guide covers setting up automated builds, testing, and deployment workflows. ## Prerequisites Before setting up GitLab CI/CD integration, ensure you have: * A GitLab account with a project repository * A Capgo account with an app configured * Node.js and npm/yarn configured in your project ## Setting Up GitLab CI/CD ### Step 1: Configure Environment Variables First, set up the necessary variables in your GitLab project: 1. Navigate to your GitLab project 2. Go to **Settings** → **CI/CD** → **Variables** 3. Add the following variables: | Variable Name | Value | Protected | Masked | | ------------- | -------------------- | --------- | ------ | | `CAPGO_TOKEN` | Your Capgo API token | ✅ Yes | ✅ Yes | Tip Get your Capgo API token from [web.capgo.app/apikeys](https://web.capgo.app/apikeys). Your app ID is already configured in your `capacitor.config.ts` file. ## Simple Basic configuration that deploys to production on every push to the main branch: ```yaml # .gitlab-ci.yml - Simple Configuration image: node:22 stages: - build - deploy variables: npm_config_cache: "$CI_PROJECT_DIR/.npm" build: stage: build script: - npm ci - npm run test - npm run build artifacts: paths: - dist/ expire_in: 1 hour only: - main deploy_production: stage: deploy script: - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel production # For encrypted uploads, add: --key-data-v2 "$CAPGO_PRIVATE_KEY" dependencies: - build only: - main ``` ## Advanced ### Feature Branch Deployments Deploy feature branches to test channels for review and testing: ```yaml # Feature branch deployment deploy_feature: stage: deploy script: - npm install -g @capgo/cli - CHANNEL_NAME="feature-$(echo $CI_COMMIT_REF_NAME | sed 's/[^a-zA-Z0-9-]/-/g')" - npx @capgo/cli channel create $CHANNEL_NAME --apikey $CAPGO_TOKEN || true - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel $CHANNEL_NAME dependencies: - build only: - /^feature\/.*$/ environment: name: feature/$CI_COMMIT_REF_NAME url: https://your-app.com/channels/$CHANNEL_NAME ``` Tip **Testing with Channels**: After deploying to a feature channel, you can test the update in your app by configuring it to use that specific channel. Learn more about [configuring channels in your app](/docs/live-updates/channels/#configuring-the-channel-in-your-app). ### Using Encryption If you’re using [Capgo’s encryption feature](/docs/live-updates/encryption/), you’ll need to store your private key securely in your CI/CD environment. After [setting up encryption keys](/docs/live-updates/encryption/#setting-up-encryption) locally, add your private key to GitLab variables: ```shell # Display your private key content (copy this output) cat .capgo_key_v2 ``` Add this content as `CAPGO_PRIVATE_KEY` in your GitLab project variables (mark as protected and masked), then use it in pipelines: ```yaml # Deploy with encryption deploy_production: script: - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --key-data-v2 "$CAPGO_PRIVATE_KEY" --channel production ``` Caution **Security Best Practices:** * Never commit the `.capgo_key_v2` file to version control * Store the private key only in secure CI/CD secret management * Use different keys for different environments ### Multi-Channel Configuration For comprehensive information about setting up and managing multiple deployment channels, see the [Channels documentation](/docs/live-updates/channels/). Complete configuration with multiple environments and merge request deployments: ```yaml # .gitlab-ci.yml - Advanced Multi-Channel Configuration image: node:22 stages: - build - deploy variables: npm_config_cache: "$CI_PROJECT_DIR/.npm" # Build stage build: stage: build script: - npm ci - npm run test - npm run build artifacts: paths: - dist/ expire_in: 24 hours # Deploy to development channel deploy_development: stage: deploy script: - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel development dependencies: - build only: - develop environment: name: development # Deploy merge requests to test channels deploy_mr: stage: deploy script: - npm install -g @capgo/cli - CHANNEL_NAME="mr-$CI_MERGE_REQUEST_IID" - npx @capgo/cli channel create $CHANNEL_NAME --apikey $CAPGO_TOKEN || true - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel $CHANNEL_NAME dependencies: - build only: - merge_requests environment: name: review/$CI_MERGE_REQUEST_IID url: https://your-app.com/channels/mr-$CI_MERGE_REQUEST_IID on_stop: cleanup_mr # Cleanup MR channels when MR is closed cleanup_mr: stage: deploy script: - npm install -g @capgo/cli - npx @capgo/cli channel delete mr-$CI_MERGE_REQUEST_IID --apikey $CAPGO_TOKEN || true when: manual environment: name: review/$CI_MERGE_REQUEST_IID action: stop only: - merge_requests # Deploy to staging deploy_staging: stage: deploy script: - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel staging dependencies: - build only: - develop environment: name: staging # Deploy to production deploy_production: stage: deploy script: - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel production dependencies: - build only: - main environment: name: production ``` ### Multi-Environment with Manual Approval For production deployments requiring manual approval: ```yaml deploy_production: stage: deploy script: - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel production dependencies: - build only: - main when: manual environment: name: production ``` ### Branch-Based Deployment Strategy Deploy different branches to appropriate channels automatically: ```yaml # Dynamic channel deployment based on branch deploy: stage: deploy script: - npm install -g @capgo/cli - | if [ "$CI_COMMIT_REF_NAME" = "main" ]; then CHANNEL="production" elif [ "$CI_COMMIT_REF_NAME" = "develop" ]; then CHANNEL="staging" else CHANNEL="development" fi - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel $CHANNEL dependencies: - build environment: name: $CHANNEL ``` ## Security Best Practices ### Protected Variables 1. **Mark Sensitive Variables**: Always mark API tokens as protected and masked 2. **Branch Protection**: Use protected variables for production deployments 3. **Access Control**: Limit variable access to maintainers only 4. **Regular Rotation**: Rotate API tokens regularly ### Secure Pipeline Configuration ```yaml # Use protected variables for production deploy_production: stage: deploy script: - npm install -g @capgo/cli - npx @capgo/cli bundle upload --apikey $CAPGO_TOKEN --channel production only: refs: - main variables: - $CI_COMMIT_REF_PROTECTED == "true" ``` ## Monitoring and Notifications ### Slack Integration Add Slack notifications to your pipeline: ```yaml notify_success: stage: .post image: alpine:latest before_script: - apk add --no-cache curl script: - | curl -X POST -H 'Content-type: application/json' \ --data '{"text":"✅ Capgo deployment successful for '"$CI_COMMIT_REF_NAME"'"}' \ $SLACK_WEBHOOK_URL when: on_success notify_failure: stage: .post image: alpine:latest before_script: - apk add --no-cache curl script: - | curl -X POST -H 'Content-type: application/json' \ --data '{"text":"❌ Capgo deployment failed for '"$CI_COMMIT_REF_NAME"'"}' \ $SLACK_WEBHOOK_URL when: on_failure ``` ### Email Notifications Configure email notifications in your GitLab project settings or use the API: ```yaml notify_email: stage: .post script: - | curl --request POST \ --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" \ --form "to=team@yourcompany.com" \ --form "subject=Capgo Deployment Status" \ --form "body=Deployment of $CI_COMMIT_REF_NAME completed with status: $CI_JOB_STATUS" \ "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/emails" when: always ``` ## Troubleshooting ### Common Issues **Pipeline fails with “Capgo CLI not found”:** ```yaml # Debug CLI installation debug_cli: script: - npm install -g @capgo/cli - which capgo || echo "Capgo CLI not found" - npx @capgo/cli --version ``` **Authentication errors:** ```yaml # Verify token configuration debug_auth: script: - | if [ -z "$CAPGO_TOKEN" ]; then echo "CAPGO_TOKEN is not set" exit 1 fi echo "Token length: ${#CAPGO_TOKEN}" ``` **Build artifacts not found:** ```yaml # List build outputs debug_build: script: - ls -la dist/ - find dist/ -type f -name "*.js" -o -name "*.html" ``` ### Debug Pipeline Add debugging information to troubleshoot issues: ```yaml debug: stage: build script: - echo "Branch: $CI_COMMIT_REF_NAME" - echo "Commit: $CI_COMMIT_SHA" - echo "Build: $CI_PIPELINE_ID" - env | grep CI_ | sort only: - branches ``` ## Next Steps * Learn about [Channels](/docs/live-updates/channels/) to manage different deployment environments * Explore [Custom Storage](/docs/live-updates/custom-storage/) for advanced deployment scenarios * Set up [Encryption](/docs/live-updates/encryption/) for secure deployments * Configure [Update Behavior](/docs/live-updates/update-behavior/) to customize how updates are applied With GitLab CI/CD integration, you can automate your Capgo deployments and ensure consistent, reliable updates to your mobile app users. # Rollbacks > Learn how to manage rollbacks in Capgo, allowing you to revert to previous app versions seamlessly when needed. While Capgo’s live updates allow you to quickly deliver improvements and fixes to your users, there may be situations where you need to roll back to a previous version of your app. Perhaps a new update introduced an unexpected critical issue, or maybe you want to revert a specific change while you work on a fix. Capgo provides several ways to manage a channel’s builds and control the version of your app that users receive, including both manual rollback options and automatic safety mechanisms. ## Automatic Rollback Protection Capgo includes a built-in safety mechanism to protect your users from broken updates. If a JavaScript error occurs before the `notifyAppReady()` method is called, the plugin will automatically roll back to the previous working version. ### How Automatic Rollback Works When a new update is downloaded and applied, Capgo expects your app to call `notifyAppReady()` within a configurable timeframe to confirm that the update loaded successfully. This method signals that: * The JavaScript bundle loaded without critical errors * Your app’s core functionality is working * The update is safe to keep If `notifyAppReady()` is not called due to a JavaScript crash or critical error, Capgo will: 1. Detect that the update failed to initialize properly 2. Automatically revert to the previous working bundle 3. Mark the problematic update as failed to prevent it from being applied again Tip Make sure to call `notifyAppReady()` in your app’s initialization code after your core components have loaded successfully. This ensures the automatic rollback protection works as intended. ```javascript import { CapacitorUpdater } from '@capgo/capacitor-updater' // Call this after your app has successfully initialized await CapacitorUpdater.notifyAppReady() ``` This automatic protection helps ensure that even if you accidentally push a broken update, your users won’t be stuck with a non-functional app. ### Configuring the Timeout You can configure how long Capgo waits for `notifyAppReady()` to be called by setting the `appReadyTimeout` in your Capacitor configuration: ```json { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 10000 } } } ``` The `appReadyTimeout` value is specified in milliseconds. The default timeout is typically 10 seconds, but you can adjust this based on your app’s initialization requirements. If your app takes longer to load due to complex initialization processes, you may want to increase this value. ## Rolling Back to a Previous Bundle Every time you upload a new build and assign it to a channel, Capgo keeps a history of those builds. If you need to revert a specific update, you can select one of these previous builds to redeploy to the channel. ![Rollback UI interface](/rollback_ui.webp) The primary way to roll back is through the rollback interface, which is located in the 4th tab (History) when viewing a channel in the Capgo Dashboard. This tab provides a comprehensive view of all available builds for the channel, allowing you to easily select and revert to any previous version. To roll back using the History tab: 1. Log in to the [Capgo Dashboard](https://app.capgo.io). 2. Navigate to the “Channels” section. 3. Click the name of the channel you want to roll back. 4. Go to the 4th tab (History) in the channel view. 5. Find the build you want to revert to in the build history. 6. Select that build to make it the active build for the channel. 7. Confirm that you want to roll back to this build. ### Alternative Method: Using the Crown Icon As a second way, you can also roll back directly from the first tab by clicking the crown icon next to any build in the channel’s build history: 1. In the first tab of the channel view, find the build you want to revert to. 2. Click the crown icon next to that build to make it the active build for the channel. ![Channel management options](/select_bundle.webp) 3. Confirm that you want to roll back to this build. Note Rolling back to a previous build only affects the selected channel. If you have multiple channels (e.g. Production, Staging, etc.), you’ll need to repeat the rollback process for each affected channel. After rolling back, devices configured to listen to the updated channel will receive the previous build the next time they check for an update. The rolled-back build will be treated as a new update, so the usual update flow and conditions apply. ## Unlinking a Channel If you want to temporarily halt updates on a channel while you investigate an issue, you can unlink the channel from its current build. To unlink a channel: 1. Navigate to the channel in the Capgo Dashboard. 2. Click the “Unlink” button next to the current build. 3. Confirm that you want to unlink the channel. Once a channel is unlinked, it will not distribute any new updates. Devices configured to that channel will stay on their current build until the channel is linked to a build again. This is useful if you’ve identified a problem with an update but aren’t yet sure which build you want to roll back to. Unlinking the channel gives you time to investigate without pushing out further updates. ## Forcing the Built-In Bundle In more severe situations, you may want to revert all devices on a channel back to the web build that was originally packaged with your app’s native binary. This is known as the “built-in bundle”. To force the built-in bundle on a channel: 1. Navigate to the channel in the Capgo Dashboard. 2. Click the “Built-in Bundle” button. 3. Confirm that you want to force the built-in bundle. When you force the built-in bundle, all devices configured to that channel will revert back to the original packaged web build on their next update check. This happens regardless of what build they’re currently on. This is a more aggressive rollback option than reverting to a specific previous build, as it discards all live updates released since the app was last published to the app stores. Caution Be cautious when forcing the built-in bundle, as it will affect all devices on the channel. Make sure you’ve considered the impact and have a plan to move forward before taking this action. ## Monitoring and Responding to Issues To catch issues quickly and minimize the impact of problematic updates, it’s important to have a plan for monitoring your releases and responding to problems. Some strategies include: * Monitoring crash reports and user feedback immediately after releasing an update * Using phased rollouts or a staged channel system to test updates on a smaller group before wide release * Having a clear decision process for when to roll back, unlink, or force the built-in bundle, and who has the authority to do so * Communicating to users about the issue and the resolution, if appropriate By combining careful monitoring with the ability to quickly manage problematic updates, you can deliver a continuously improving app experience while minimizing disruptions for your users. # Update Behavior > Explore the comprehensive update behavior of Capgo, designed to deliver seamless updates to your app users without interrupting their experience. When you release an update to your Capgo app, you probably want your users to receive that update as soon as possible. But you also don’t want to disrupt their experience by forcing them to wait for a download or restart the app in the middle of a session. Capgo’s update behavior is designed to strike a balance between delivering updates quickly and minimizing disruption to your users. ## Default Update Flow By default, here’s how Capgo handles app updates: 1. On app launch, the Capgo plugin checks to see if a new update is available. 2. If an update is found, it’s downloaded in the background while the user continues using the current version of the app. 3. Once the download completes, Capgo waits for the user to either background the app or kill it entirely. 4. When the user next launches the app, they’ll be running the updated version. This flow ensures that users are always running the latest version of your app, without ever being interrupted by update prompts or forced to wait for downloads. Tip Capgo also checks for updates when the app resumes from the background, so users will receive updates even if they don’t fully quit the app. ## Why This Approach? Applying updates on a background or kill event has a few key benefits for user experience: * Users aren’t interrupted by update prompts or forced to wait for downloads in the middle of a session. * Updates are applied seamlessly in between sessions, so the experience of launching the app is always fresh. * You can deliver updates frequently without worrying about disrupting active users. The main downside is that if a user backgrounds and quickly resumes your app, they may lose any unsaved state since the update was applied in between those actions. To mitigate this, we recommend: * Saving state frequently and restoring it gracefully when the app resumes. * Avoiding very frequent updates that modify large parts of the app state. * Considering customizing the update behavior for sensitive flows (see below). ## Customizing When Updates Are Applied In some cases, you may want more control over exactly when an update is applied. For example, you might want to ensure a user completes an in-progress flow before updating, or coordinate an app update with a server-side change. Capgo provides a `setDelay` function that lets you specify conditions that must be met before an update is installed: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; await CapacitorUpdater.setMultiDelay({ delayConditions: [ { kind: 'date', value: '2023-06-01T00:00:00.000Z', }, { kind: 'background', value: '60000', }, ], }); ``` This example would delay installing an update until after June 1, 2023 AND the app has been backgrounded for at least 60 seconds. The available delay conditions are: * `date`: Wait until after a specific date/time to apply the update. * `background`: Wait a minimum duration after the app is backgrounded to apply the update. * `nativeVersion`: Wait for a native binary with a minimum version to be installed before applying the update. * `kill`: Wait until the next app kill event to apply the update. You can mix and match these conditions to precisely control when an update is installed. Danger Note that the `kill` condition currently triggers the update after the first kill event, not the next background event like the other conditions. This inconsistency will be fixed in a future release. ## Applying Updates Immediately For critical updates or apps with very simple state, you may want to apply an update as soon as it’s downloaded, without waiting for a background or kill event. Capgo supports this via the `directUpdate` configuration option. `directUpdate` is set in your `capacitor.config.ts` file, not in JavaScript code. It supports three values: * `false` (default): Never do direct updates, use normal background update behavior * `'atInstall'`: Direct update only when the app is installed or updated from the store, otherwise use normal behavior * `'always'`: Always do direct updates immediately when available * `true` (deprecated): Same as `'always'` for backward compatibility ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: 'always', // or 'atInstall' for updates only on app install/update autoSplashscreen: true, // NEW: Automatically handle splashscreen keepUrlPathAfterReload: true, }, SplashScreen: { launchAutoHide: false, // Still required when using directUpdate }, }, }; export default config; ``` Note **Important**: `directUpdate` only applies updates when the app actually checks for them. By default, this happens only at app startup or when resuming from background. Note that `periodCheckDelay` is not compatible with `directUpdate`. With `directUpdate` enabled, Capgo will immediately apply an update as soon as the download completes during an update check, even if the user is actively using the app. Without periodic checking enabled, this means updates will only be applied when the app starts or resumes from background. Note that because `directUpdate` is a native configuration, it requires some additional handling in your JavaScript code. Caution When using `directUpdate`, you must set `launchAutoHide: false` in the SplashScreen configuration (as shown above) to prevent the splash screen from hiding automatically. This ensures you have full control over when the splash screen is hidden after the update process completes. ## Automatic Splashscreen Handling To make `directUpdate` easier to use, Capgo provides an `autoSplashscreen` option that automatically handles hiding the splashscreen for you (available since version 7.6.0): ```typescript const config: CapacitorConfig = { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: 'always', // or 'atInstall' autoSplashscreen: true, // Automatically hide splashscreen keepUrlPathAfterReload: true, }, SplashScreen: { launchAutoHide: false, }, }, }; ``` When `autoSplashscreen` is enabled: * The plugin automatically hides the splashscreen when an update is applied * The plugin automatically hides the splashscreen when no update is needed * You don’t need to manually listen for `appReady` events or call `SplashScreen.hide()` ### Manual Splashscreen Handling If you prefer manual control or need custom logic, you can disable `autoSplashscreen` and handle it yourself: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater'; import { SplashScreen } from '@capacitor/splash-screen'; CapacitorUpdater.addListener('appReady', () => { // Hide splash screen SplashScreen.hide(); }); CapacitorUpdater.notifyAppReady(); ``` The `appReady` event fires once the app has finished initializing and applying any pending updates. This is the point at which it’s safe to show your app’s UI, as it ensures the user will see the latest version. In addition to handling the `appReady` event, we recommend setting the `keepUrlPathAfterReload` configuration option to `true` when using `directUpdate`. This preserves the current URL path when the app is reloaded due to an update, helping maintain the user’s location in the app and reducing disorientation. If you don’t handle the `appReady` event and set `keepUrlPathAfterReload` when using `directUpdate`, the user may briefly see a stale version of the app, be taken back to the initial route, or see a flicker as the update is applied. Using `directUpdate` can be useful for delivering critical bug fixes or security patches, but it comes with some tradeoffs: * The user may see a brief flicker or loading state as the update is applied if you don’t properly handle the splashscreen (either with `autoSplashscreen` or manual `appReady` event handling). * If the update modifies the app state or UI, the user may see a disruptive change in the middle of a session. * The user’s location in the app may be lost if `keepUrlPathAfterReload` is not set, potentially disorienting them. * You’ll need to carefully handle saving and restoring state to ensure a smooth transition. If you do enable `directUpdate`, we recommend: * Using `autoSplashscreen: true` for the simplest setup, or manually handling the `appReady` event if you need custom logic. * Setting `keepUrlPathAfterReload` to `true` to preserve the user’s location in the app. * Saving and restoring the app state as needed to avoid losing user progress. * Thoroughly testing your app’s update behavior to ensure there are no jarring transitions, lost state, or disorienting location changes. In most cases, the default update behavior provides the best balance of delivering updates quickly and minimizing disruption. But for apps with specific needs, Capgo provides the flexibility to customize when and how updates are applied. # Functions and settings > All available method and settings of the plugin # Updater Plugin Config CapacitorUpdater can be configured with these options: | Prop | Type | Description | Default | Since | | ---------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **`appReadyTimeout`** | `number` | Configure the number of milliseconds the native plugin should wait before considering an update ‘failed’. Only available for Android and iOS. | `10000 // (10 seconds)` | | | **`responseTimeout`** | `number` | Configure the number of seconds the native plugin should wait before considering API timeout. Only available for Android and iOS. | `20 // (20 second)` | | | **`autoDeleteFailed`** | `boolean` | Configure whether the plugin should use automatically delete failed bundles. Only available for Android and iOS. | `true` | | | **`autoDeletePrevious`** | `boolean` | Configure whether the plugin should use automatically delete previous bundles after a successful update. Only available for Android and iOS. | `true` | | | **`autoUpdate`** | `boolean` | Configure whether the plugin should use Auto Update via an update server. Only available for Android and iOS. | `true` | | | **`resetWhenUpdate`** | `boolean` | Automatically delete previous downloaded bundles when a newer native app bundle is installed to the device. Only available for Android and iOS. | `true` | | | **`updateUrl`** | `string` | Configure the URL / endpoint to which update checks are sent. Only available for Android and iOS. | `https://plugin.capgo.app/updates` | | | **`channelUrl`** | `string` | Configure the URL / endpoint for channel operations. Only available for Android and iOS. | `https://plugin.capgo.app/channel_self` | | | **`statsUrl`** | `string` | Configure the URL / endpoint to which update statistics are sent. Only available for Android and iOS. Set to "" to disable stats reporting. | `https://plugin.capgo.app/stats` | | | **`publicKey`** | `string` | Configure the public key for end to end live update encryption Version 2 Only available for Android and iOS. | `undefined` | 6.2.0 | | **`version`** | `string` | Configure the current version of the app. This will be used for the first update request. If not set, the plugin will get the version from the native code. Only available for Android and iOS. | `undefined` | 4.17.48 | | **`directUpdate`** | \`boolean | ’always' | 'atInstall’\` | Configure when the plugin should direct install updates. Only for autoUpdate mode. Works well for apps less than 10MB and with uploads done using —partial flag. Zip or apps more than 10MB will be relatively slow for users to update. - false: Never do direct updates (default behavior) - atInstall: Direct update only when app is installed/updated from store, otherwise use normal background update - always: Always do direct updates immediately when available - true: (deprecated) Same as “always” for backward compatibility Only available for Android and iOS. | | **`autoSplashscreen`** | `boolean` | Automatically handle splashscreen hiding when using directUpdate. When enabled, the plugin will automatically hide the splashscreen after updates are applied or when no update is needed. This removes the need to manually listen for appReady events and call SplashScreen.hide(). Only works when directUpdate is set to “atInstall”, “always”, or true. Requires the @capacitor/splash-screen plugin to be installed and configured with launchAutoHide: false. Requires autoUpdate and directUpdate to be enabled. Only available for Android and iOS. | `false` | 7.6.0 | | **`periodCheckDelay`** | `number` | Configure the delay period for period update check. the unit is in seconds. Only available for Android and iOS. Cannot be less than 600 seconds (10 minutes). | `0 (disabled)` | | | **`localS3`** | `boolean` | Configure the CLI to use a local server for testing or self-hosted update server. | `undefined` | 4.17.48 | | **`localHost`** | `string` | Configure the CLI to use a local server for testing or self-hosted update server. | `undefined` | 4.17.48 | | **`localWebHost`** | `string` | Configure the CLI to use a local server for testing or self-hosted update server. | `undefined` | 4.17.48 | | **`localSupa`** | `string` | Configure the CLI to use a local server for testing or self-hosted update server. | `undefined` | 4.17.48 | | **`localSupaAnon`** | `string` | Configure the CLI to use a local server for testing. | `undefined` | 4.17.48 | | **`localApi`** | `string` | Configure the CLI to use a local api for testing. | `undefined` | 6.3.3 | | **`localApiFiles`** | `string` | Configure the CLI to use a local file api for testing. | `undefined` | 6.3.3 | | **`allowModifyUrl`** | `boolean` | Allow the plugin to modify the updateUrl, statsUrl and channelUrl dynamically from the JavaScript side. | `false` | 5.4.0 | | **`allowModifyAppId`** | `boolean` | Allow the plugin to modify the appId dynamically from the JavaScript side. | `false` | 7.14.0 | | **`persistCustomId`** | `boolean` | Persist the customId set through {@link CapacitorUpdaterPlugin.setCustomId} across app restarts. Only available for Android and iOS. | `false (will be true by default in a future major release v8.x.x)` | 7.17.3 | | **`defaultChannel`** | `string` | Set the default channel for the app in the config. Case sensitive. This will setting will override the default channel set in the cloud, but will still respect overrides made in the cloud. This requires the channel to allow devices to self dissociate/associate in the channel settings. | `undefined` | 5.5.0 | | **`appId`** | `string` | Configure the app id for the app in the config. | `undefined` | 6.0.0 | | **`keepUrlPathAfterReload`** | `boolean` | Configure the plugin to keep the URL path after a reload. WARNING: When a reload is triggered, ‘window\.history’ will be cleared. | `false` | 6.8.0 | | **`disableJSLogging`** | `boolean` | Disable the JavaScript logging of the plugin. if true, the plugin will not log to the JavaScript console. only the native log will be done | `false` | 7.3.0 | | **`shakeMenu`** | `boolean` | Enable shake gesture to show update menu for debugging/testing purposes | `false` | 7.5.0 | ## API Reference * [`notifyAppReady`](#notifyappready) * [`setUpdateUrl`](#setupdateurl) * [`setStatsUrl`](#setstatsurl) * [`setChannelUrl`](#setchannelurl) * [`download`](#download) * [`next`](#next) * [`set`](#set) * [`delete`](#delete) * [`list`](#list) * [`reset`](#reset) * [`current`](#current) * [`reload`](#reload) * [`setMultiDelay`](#setmultidelay) * [`cancelDelay`](#canceldelay) * [`getLatest`](#getlatest) * [`setChannel`](#setchannel) * [`unsetChannel`](#unsetchannel) * [`getChannel`](#getchannel) * [`listChannels`](#listchannels) * [`setCustomId`](#setcustomid) * [`getBuiltinVersion`](#getbuiltinversion) * [`getDeviceId`](#getdeviceid) * [`getPluginVersion`](#getpluginversion) * [`isAutoUpdateEnabled`](#isautoupdateenabled) * [`removeAllListeners`](#removealllisteners) * [`addListener('download')`](#addlistenerdownload-) * [`addListener('noNeedUpdate')`](#addlistenernoneedupdate-) * [`addListener('updateAvailable')`](#addlistenerupdateavailable-) * [`addListener('downloadComplete')`](#addlistenerdownloadcomplete-) * [`addListener('majorAvailable')`](#addlistenermajoravailable-) * [`addListener('updateFailed')`](#addlistenerupdatefailed-) * [`addListener('downloadFailed')`](#addlistenerdownloadfailed-) * [`addListener('appReloaded')`](#addlistenerappreloaded-) * [`addListener('appReady')`](#addlistenerappready-) * [`isAutoUpdateAvailable`](#isautoupdateavailable) * [`getNextBundle`](#getnextbundle) * [`setShakeMenu`](#setshakemenu) * [`isShakeMenuEnabled`](#isshakemenuenabled) * [`getAppId`](#getappid) * [`setAppId`](#setappid) ### notifyAppReady ```typescript notifyAppReady() => Promise ``` Notify Capacitor Updater that the current bundle is working (a rollback will occur if this method is not called on every app launch) By default this method should be called in the first 10 sec after app launch, otherwise a rollback will occur. Change this behaviour with {@link appReadyTimeout} **Returns** `Promise` — an Promise resolved directly **Throws:** {Error} *** ### setUpdateUrl ```typescript setUpdateUrl(options: UpdateUrl) => Promise ``` Set the updateUrl for the app, this will be used to check for updates. **Parameters** | Name | Type | Description | | --------- | ----------- | ------------------------------------------------- | | `options` | `UpdateUrl` | contains the URL to use for checking for updates. | **Returns** `Promise` **Since:** 5.4.0 **Throws:** {Error} *** ### setStatsUrl ```typescript setStatsUrl(options: StatsUrl) => Promise ``` Set the statsUrl for the app, this will be used to send statistics. Passing an empty string will disable statistics gathering. **Parameters** | Name | Type | Description | | --------- | ---------- | ----------------------------------------------- | | `options` | `StatsUrl` | contains the URL to use for sending statistics. | **Returns** `Promise` **Since:** 5.4.0 **Throws:** {Error} *** ### setChannelUrl ```typescript setChannelUrl(options: ChannelUrl) => Promise ``` Set the channelUrl for the app, this will be used to set the channel. **Parameters** | Name | Type | Description | | --------- | ------------ | ------------------------------------------------ | | `options` | `ChannelUrl` | contains the URL to use for setting the channel. | **Returns** `Promise` **Since:** 5.4.0 **Throws:** {Error} *** ### download ```typescript download(options: DownloadOptions) => Promise ``` Download a new bundle from the provided URL, it should be a zip file, with files inside or with a unique id inside with all your files **Parameters** | Name | Type | Description | | --------- | ----------------- | ------------------------------------------------------------- | | `options` | `DownloadOptions` | The {@link DownloadOptions} for downloading a new bundle zip. | **Returns** `Promise` — The {@link BundleInfo} for the specified bundle. **Example** ```ts const bundle = await CapacitorUpdater.download({ url: `https://example.com/versions/${version}/dist.zip`, version }); ``` *** ### next ```typescript next(options: BundleId) => Promise ``` Set the next bundle to be used when the app is reloaded. **Parameters** | Name | Type | Description | | --------- | ---------- | ----------------------------------------------------------------------------------- | | `options` | `BundleId` | Contains the ID of the next Bundle to set on next app launch. {@link BundleInfo.id} | **Returns** `Promise` — The {@link BundleInfo} for the specified bundle id. **Throws:** {Error} When there is no index.html file inside the bundle folder. *** ### set ```typescript set(options: BundleId) => Promise ``` Set the current bundle and immediately reloads the app. **Parameters** | Name | Type | Description | | --------- | ---------- | ------------------------------------------------------------------------- | | `options` | `BundleId` | A {@link BundleId} object containing the new bundle id to set as current. | **Returns** `Promise` **Throws:** {Error} When there are is no index.html file inside the bundle folder. *** ### delete ```typescript delete(options: BundleId) => Promise ``` Deletes the specified bundle from the native app storage. Use with {@link list} to get the stored Bundle IDs. **Parameters** | Name | Type | Description | | --------- | ---------- | --------------------------------------------------------------------------------------------------------------------- | | `options` | `BundleId` | A {@link BundleId} object containing the ID of a bundle to delete (note, this is the bundle id, NOT the version name) | **Returns** `Promise` — When the bundle is deleted **Throws:** {Error} *** ### list ```typescript list(options?: ListOptions | undefined) => Promise ``` Get all locally downloaded bundles in your app **Parameters** | Name | Type | Description | | --------- | ------------- | ----------- | | `options` | \`ListOptions | undefined\` | **Returns** `Promise` — A Promise containing the {@link BundleListResult.bundles} **Throws:** {Error} *** ### reset ```typescript reset(options?: ResetOptions | undefined) => Promise ``` Reset the app to the `builtin` bundle (the one sent to Apple App Store / Google Play Store ) or the last successfully loaded bundle. **Parameters** | Name | Type | Description | | --------- | -------------- | ----------- | | `options` | \`ResetOptions | undefined\` | **Returns** `Promise` **Throws:** {Error} *** ### current ```typescript current() => Promise ``` Get the current bundle, if none are set it returns `builtin`. currentNative is the original bundle installed on the device **Returns** `Promise` — A Promise evaluating to the {@link CurrentBundleResult} **Throws:** {Error} *** ### reload ```typescript reload() => Promise ``` Reload the view **Returns** `Promise` — A Promise which is resolved when the view is reloaded **Throws:** {Error} *** ### setMultiDelay ```typescript setMultiDelay(options: MultiDelayConditions) => Promise ``` Sets a {@link DelayCondition} array containing conditions that the Plugin will use to delay the update. After all conditions are met, the update process will run start again as usual, so update will be installed after a backgrounding or killing the app. For the `date` kind, the value should be an iso8601 date string. For the `background` kind, the value should be a number in milliseconds. For the `nativeVersion` kind, the value should be the version number. For the `kill` kind, the value is not used. The function has unconsistent behavior the option kill do trigger the update after the first kill and not after the next background like other options. This will be fixed in a future major release. **Parameters** | Name | Type | Description | | --------- | ---------------------- | ---------------------------------------------------------------------- | | `options` | `MultiDelayConditions` | Containing the {@link MultiDelayConditions} array of conditions to set | **Returns** `Promise` **Since:** 4.3.0 **Throws:** {Error} **Example** ```ts // Delay the update after the user kills the app or after a background of 300000 ms (5 minutes) await CapacitorUpdater.setMultiDelay({ delayConditions: [{ kind: 'kill' }, { kind: 'background', value: '300000' }] }) ``` **Example** ```ts // Delay the update after the specific iso8601 date is expired await CapacitorUpdater.setMultiDelay({ delayConditions: [{ kind: 'date', value: '2022-09-14T06:14:11.920Z' }] }) ``` **Example** ```ts // Delay the update after the first background (default behaviour without setting delay) await CapacitorUpdater.setMultiDelay({ delayConditions: [{ kind: 'background' }] }) ``` *** ### cancelDelay ```typescript cancelDelay() => Promise ``` Cancels a {@link DelayCondition} to process an update immediately. **Returns** `Promise` **Since:** 4.0.0 **Throws:** {Error} *** ### getLatest ```typescript getLatest(options?: GetLatestOptions | undefined) => Promise ``` Get Latest bundle available from update Url **Parameters** | Name | Type | Description | | --------- | ------------------ | ----------- | | `options` | \`GetLatestOptions | undefined\` | **Returns** `Promise` — A Promise resolved when url is loaded **Since:** 4.0.0 **Throws:** {Error} *** ### setChannel ```typescript setChannel(options: SetChannelOptions) => Promise ``` Sets the channel for this device. The channel has to allow for self assignment for this to work. Do not use this method to set the channel at boot. This method is to set the channel after the app is ready, and user interacted. If you want to set the channel at boot, use the {@link PluginsConfig} to set the default channel. This methods send to Capgo backend a request to link the device ID to the channel. Capgo can accept or refuse depending of the setting of your channel. **Parameters** | Name | Type | Description | | --------- | ------------------- | ----------------------------------------------- | | `options` | `SetChannelOptions` | Is the {@link SetChannelOptions} channel to set | **Returns** `Promise` — A Promise which is resolved when the new channel is set **Since:** 4.7.0 **Throws:** {Error} *** ### unsetChannel ```typescript unsetChannel(options: UnsetChannelOptions) => Promise ``` Unset the channel for this device. The device will then return to the default channel **Parameters** | Name | Type | Description | | --------- | --------------------- | ----------- | | `options` | `UnsetChannelOptions` | | **Returns** `Promise` — A Promise resolved when channel is set **Since:** 4.7.0 **Throws:** {Error} *** ### getChannel ```typescript getChannel() => Promise ``` Get the channel for this device **Returns** `Promise` — A Promise that resolves with the channel info **Since:** 4.8.0 **Throws:** {Error} *** ### listChannels ```typescript listChannels() => Promise ``` List all channels available for this device that allow self-assignment **Returns** `Promise` — A Promise that resolves with the available channels **Since:** 7.5.0 **Throws:** {Error} *** ### setCustomId ```typescript setCustomId(options: SetCustomIdOptions) => Promise ``` Set a custom ID for this device When {@link PluginsConfig.CapacitorUpdater.persistCustomId} is true, the value will be stored natively and restored on the next app launch. Pass an empty string to remove any previously stored customId. **Parameters** | Name | Type | Description | | --------- | -------------------- | ------------------------------------------------- | | `options` | `SetCustomIdOptions` | is the {@link SetCustomIdOptions} customId to set | **Returns** `Promise` — an Promise resolved instantly **Since:** 4.9.0 **Throws:** {Error} *** ### getBuiltinVersion ```typescript getBuiltinVersion() => Promise ``` Get the native app version or the builtin version if set in config **Returns** `Promise` — A Promise with version for this device **Since:** 5.2.0 *** ### getDeviceId ```typescript getDeviceId() => Promise ``` Get unique ID used to identify device (sent to auto update server) **Returns** `Promise` — A Promise with id for this device **Throws:** {Error} *** ### getPluginVersion ```typescript getPluginVersion() => Promise ``` Get the native Capacitor Updater plugin version (sent to auto update server) **Returns** `Promise` — A Promise with Plugin version **Throws:** {Error} *** ### isAutoUpdateEnabled ```typescript isAutoUpdateEnabled() => Promise ``` Get the state of auto update config. **Returns** `Promise` — The status for auto update. Evaluates to `false` in manual mode. **Throws:** {Error} *** ### removeAllListeners ```typescript removeAllListeners() => Promise ``` Remove all listeners for this plugin. **Returns** `Promise` **Since:** 1.0.0 *** ### addListener(‘download’) ```typescript addListener(eventName: 'download', listenerFunc: (state: DownloadEvent) => void) => Promise ``` Listen for bundle download event in the App. Fires once a download has started, during downloading and when finished. This will return you all download percent during the download **Parameters** | Name | Type | Description | | -------------- | -------------------------------- | ----------- | | `eventName` | `'download'` | | | `listenerFunc` | `(state: DownloadEvent) => void` | | **Returns** `Promise` **Since:** 2.0.11 *** ### addListener(‘noNeedUpdate’) ```typescript addListener(eventName: 'noNeedUpdate', listenerFunc: (state: NoNeedEvent) => void) => Promise ``` Listen for no need to update event, useful when you want force check every time the app is launched **Parameters** | Name | Type | Description | | -------------- | ------------------------------ | ----------- | | `eventName` | `'noNeedUpdate'` | | | `listenerFunc` | `(state: NoNeedEvent) => void` | | **Returns** `Promise` **Since:** 4.0.0 *** ### addListener(‘updateAvailable’) ```typescript addListener(eventName: 'updateAvailable', listenerFunc: (state: UpdateAvailableEvent) => void) => Promise ``` Listen for available update event, useful when you want to force check every time the app is launched **Parameters** | Name | Type | Description | | -------------- | --------------------------------------- | ----------- | | `eventName` | `'updateAvailable'` | | | `listenerFunc` | `(state: UpdateAvailableEvent) => void` | | **Returns** `Promise` **Since:** 4.0.0 *** ### addListener(‘downloadComplete’) ```typescript addListener(eventName: 'downloadComplete', listenerFunc: (state: DownloadCompleteEvent) => void) => Promise ``` Listen for downloadComplete events. **Parameters** | Name | Type | Description | | -------------- | ---------------------------------------- | ----------- | | `eventName` | `'downloadComplete'` | | | `listenerFunc` | `(state: DownloadCompleteEvent) => void` | | **Returns** `Promise` **Since:** 4.0.0 *** ### addListener(‘majorAvailable’) ```typescript addListener(eventName: 'majorAvailable', listenerFunc: (state: MajorAvailableEvent) => void) => Promise ``` Listen for Major update event in the App, let you know when major update is blocked by setting disableAutoUpdateBreaking **Parameters** | Name | Type | Description | | -------------- | -------------------------------------- | ----------- | | `eventName` | `'majorAvailable'` | | | `listenerFunc` | `(state: MajorAvailableEvent) => void` | | **Returns** `Promise` **Since:** 2.3.0 *** ### addListener(‘updateFailed’) ```typescript addListener(eventName: 'updateFailed', listenerFunc: (state: UpdateFailedEvent) => void) => Promise ``` Listen for update fail event in the App, let you know when update has fail to install at next app start **Parameters** | Name | Type | Description | | -------------- | ------------------------------------ | ----------- | | `eventName` | `'updateFailed'` | | | `listenerFunc` | `(state: UpdateFailedEvent) => void` | | **Returns** `Promise` **Since:** 2.3.0 *** ### addListener(‘downloadFailed’) ```typescript addListener(eventName: 'downloadFailed', listenerFunc: (state: DownloadFailedEvent) => void) => Promise ``` Listen for download fail event in the App, let you know when a bundle download has failed **Parameters** | Name | Type | Description | | -------------- | -------------------------------------- | ----------- | | `eventName` | `'downloadFailed'` | | | `listenerFunc` | `(state: DownloadFailedEvent) => void` | | **Returns** `Promise` **Since:** 4.0.0 *** ### addListener(‘appReloaded’) ```typescript addListener(eventName: 'appReloaded', listenerFunc: () => void) => Promise ``` Listen for reload event in the App, let you know when reload has happened **Parameters** | Name | Type | Description | | -------------- | --------------- | ----------- | | `eventName` | `'appReloaded'` | | | `listenerFunc` | `() => void` | | **Returns** `Promise` **Since:** 4.3.0 *** ### addListener(‘appReady’) ```typescript addListener(eventName: 'appReady', listenerFunc: (state: AppReadyEvent) => void) => Promise ``` Listen for app ready event in the App, let you know when app is ready to use, this event is retain till consumed. **Parameters** | Name | Type | Description | | -------------- | -------------------------------- | ----------- | | `eventName` | `'appReady'` | | | `listenerFunc` | `(state: AppReadyEvent) => void` | | **Returns** `Promise` **Since:** 5.1.0 *** ### isAutoUpdateAvailable ```typescript isAutoUpdateAvailable() => Promise ``` Get if auto update is available (not disabled by serverUrl). **Returns** `Promise` — The availability status for auto update. Evaluates to `false` when serverUrl is set. **Throws:** {Error} *** ### getNextBundle ```typescript getNextBundle() => Promise ``` Get the next bundle that will be used when the app reloads. Returns null if no next bundle is set. **Returns** `Promise` — A Promise that resolves with the next bundle information or null **Since:** 6.8.0 **Throws:** {Error} *** ### setShakeMenu ```typescript setShakeMenu(options: SetShakeMenuOptions) => Promise ``` Enable or disable the shake menu for debugging/testing purposes **Parameters** | Name | Type | Description | | --------- | --------------------- | -------------------------------------------------------- | | `options` | `SetShakeMenuOptions` | Contains enabled boolean to enable or disable shake menu | **Returns** `Promise` **Since:** 7.5.0 **Throws:** {Error} *** ### isShakeMenuEnabled ```typescript isShakeMenuEnabled() => Promise ``` Get the current state of the shake menu **Returns** `Promise` — The current state of shake menu **Since:** 7.5.0 **Throws:** {Error} *** ### getAppId ```typescript getAppId() => Promise ``` Get the configured App ID **Returns** `Promise` — The current App ID **Since:** 7.14.0 **Throws:** {Error} *** ### setAppId ```typescript setAppId(options: SetAppIdOptions) => Promise ``` Set the App ID for the app (requires allowModifyAppId to be true in config) **Parameters** | Name | Type | Description | | --------- | ----------------- | --------------------- | | `options` | `SetAppIdOptions` | The new App ID to set | **Returns** `Promise` **Since:** 7.14.0 **Throws:** {Error} If allowModifyAppId is false or if the operation fails *** # Capacitor Plugins by Capgo > Explore our comprehensive collection of Capacitor plugins to extend your app's native capabilities with powerful features. Welcome to the Capgo Capacitor Plugins collection! We maintain a suite of high-quality, well-documented plugins to help you build amazing native experiences in your Capacitor apps. ## ⭐ Capgo Cloud - Live Updates [Capacitor Updater ](/docs/plugins/updater/)The core plugin powering Capgo Cloud - deliver instant updates to your Capacitor apps without app store delays. Push fixes and features directly to your users. The Updater plugin is the foundation of Capgo Cloud, enabling you to: * 🚀 Deploy updates instantly without app store reviews * 📱 Update your app’s JavaScript, HTML, CSS, and assets * 🎯 Target specific user segments with channels * 📊 Monitor update success with built-in analytics * 🔒 Secure updates with encryption and code signing ## 🚀 Featured Plugins [Social Login ](/docs/plugins/social-login/)Seamless authentication with Google, Apple, and Facebook. One plugin for all major social providers. [Native Purchases ](/docs/plugins/native-purchases/)Implement in-app purchases and subscriptions with a unified API for iOS and Android. [Camera Preview ](/docs/plugins/camera-preview/)Display real-time camera feed in your app with full control over capture and settings. [Data Storage SQLite ](/docs/plugins/data-storage-sqlite/)Fast and secure key-value storage powered by SQLite with optional encryption. ## 📱 Device & System Plugins [Native Market ](/docs/plugins/native-market/)Link to app stores for ratings, reviews, and app updates. [Native Biometric ](/docs/plugins/native-biometric/)Access biometric authentication APIs for secure app access. [Shake ](/docs/plugins/shake/)Detect shake gestures for interactive features and debug menus. [Navigation Bar ](/docs/plugins/navigation-bar/)Customize Android navigation bar color to match your app theme. [Home Indicator ](/docs/plugins/home-indicator/)Control iOS home indicator visibility for immersive experiences. ## 🎥 Media & Camera Plugins [Screen Recorder ](/docs/plugins/screen-recorder/)Record your device screen for tutorials, demos, or user feedback. [IVS Player ](/docs/plugins/ivs-player/)Amazon IVS integration for ultra-low latency live streaming. [Native Audio ](/docs/plugins/native-audio/)High-performance native audio engine for games and apps. [Mute ](/docs/plugins/mute/)Detect if the device mute switch is enabled or disabled. ## 🛠️ Utility Plugins [Uploader ](/docs/plugins/uploader/)Background file upload with progress tracking and resumable uploads. [Flash ](/docs/plugins/flash/)Control device flashlight/torch for utility and camera features. [Native Geocoder ](/docs/plugins/nativegeocoder/)Forward and reverse geocoding using native platform APIs. [InAppBrowser ](/docs/plugins/inappbrowser/)Open web content in a customizable in-app browser. [Crisp ](/docs/plugins/crisp/)Integrate Crisp chat support directly into your mobile app. ## 🤖 AI & Advanced Media [LLM ](/docs/plugins/llm/)Run Large Language Models locally with Apple Intelligence support. [StreamCall ](/docs/plugins/streamcall/)Enable high-quality video streaming and calling capabilities. [JW Player ](/docs/plugins/jw-player/)Professional video player with advanced streaming features. [Ricoh 360 Camera ](/docs/plugins/ricoh360-camera/)Control and capture from Ricoh 360 degree cameras. ## 📍 Location & Background Services [Background Geolocation ](/docs/plugins/background-geolocation/)Track device location in background with battery optimization. [Alarm ](/docs/plugins/alarm/)Schedule native alarms and notifications even when app is closed. ## 📞 Communication & Analytics [Twilio Voice ](/docs/plugins/twilio-voice/)Make and receive phone calls using Twilio Voice API. [GTM ](/docs/plugins/gtm/)Google Tag Manager integration for analytics and tracking. ## 🔐 Security & System [Is Root ](/docs/plugins/is-root/)Detect if device is rooted or jailbroken for security. [Persistent Account ](/docs/plugins/persistent-account/)Maintain user accounts across app reinstalls. [Autofill Save Password ](/docs/plugins/autofill-save-password/)Enable password autofill and save functionality. ## 📊 Android-Specific Features [Android Usage Stats ](/docs/plugins/android-usagestatsmanager/)Access Android app usage statistics and screen time data. [Android Inline Install ](/docs/plugins/android-inline-install/)Enable inline app installation on Android devices. ## 📥 Download & Navigation [Downloader ](/docs/plugins/downloader/)Background file downloads with progress tracking. [Launch Navigator ](/docs/plugins/launch-navigator/)Launch navigation apps with addresses and coordinates. ## 🎯 Why Choose Capgo Plugins? **Well Maintained**: Regular updates and compatibility with latest Capacitor versions **Comprehensive Docs**: Detailed documentation with examples for every plugin **Easy Integration**: Simple APIs that follow Capacitor best practices **TypeScript Support**: Full TypeScript definitions for better development experience ## 🚀 Getting Started Each plugin follows a similar installation pattern: 1. **Install the plugin** using your preferred package manager 2. **Sync your project** with `npx cap sync` 3. **Configure platform-specific settings** if needed 4. **Start using the plugin** in your code Visit each plugin’s documentation for detailed setup instructions and API references. ## 💡 Need Help? * 📖 Check the individual plugin documentation * 💬 Join our [Discord community](https://discord.capgo.app) * 🐛 Report issues on the plugin’s GitHub repository * 📧 Contact support for enterprise inquiries ## 🛠️ Need a Custom Plugin? Can’t find the exact functionality you need? We can help! [Custom Plugin Development ](/consulting/)Our team specializes in building custom Capacitor plugins tailored to your specific requirements. From complex native integrations to unique device features, we've got you covered. Whether you need: * 🔧 A completely new plugin built from scratch * 🔄 Modifications to existing plugins * 🤝 Expert consulting on native development * 📱 Platform-specific implementations [Get in touch with our team](/consulting/) to discuss your custom plugin needs. ## 🤝 Contributing We welcome contributions! Each plugin is open source and available on GitHub. Feel free to: * Report bugs and request features * Submit pull requests * Improve documentation * Share your use cases *** **Built with ❤️ by the Capgo team** # @capgo/capacitor-alarm > Manage native alarm Capacitor plugin # @capgo/capacitor-alarm Manage native alarm Capacitor plugin ## Installation * npm ```bash npm install @capgo/capacitor-alarm npx cap sync ``` * yarn ```bash yarn add @capgo/capacitor-alarm npx cap sync ``` * pnpm ```bash pnpm add @capgo/capacitor-alarm npx cap sync ``` * bun ```bash bun add @capgo/capacitor-alarm npx cap sync ``` ## Requirements * **iOS**: iOS 26+ only. This plugin relies on `AlarmKit` APIs and will report unsupported on earlier versions or when the framework is unavailable. * **Android**: Uses `AlarmClock` intents; behavior depends on the default Clock app and OEM policies. Note: This plugin only exposes native alarm actions (create/open). It does not implement any custom in-app alarm scheduling/CRUD. ## API ### createAlarm(…) ```typescript createAlarm(options: NativeAlarmCreateOptions) => Promise ``` Create a native OS alarm using the platform clock app. On Android this uses the Alarm Clock intent; on iOS this use AlarmKit if available (iOS 26+). | Param | Type | | ------------- | -------------------------- | | **`options`** | `NativeAlarmCreateOptions` | **Returns:** `Promise` ### openAlarms() ```typescript openAlarms() => Promise ``` Open the platform’s native alarm list UI, if available. **Returns:** `Promise` ### getOSInfo() ```typescript getOSInfo() => Promise ``` Get information about the OS and capabilities. **Returns:** `Promise` ### requestPermissions(…) ```typescript requestPermissions(options?: { exactAlarm?: boolean | undefined; } | undefined) => Promise ``` Request relevant permissions for alarm usage on the platform. On Android, may route to settings for exact alarms. | Param | Type | | ------------- | --------------------------- | | **`options`** | `{ exactAlarm?: boolean; }` | **Returns:** `Promise` ## Interfaces ### NativeActionResult | Prop | Type | | ------------- | --------- | | **`success`** | `boolean` | | **`message`** | `string` | ### NativeAlarmCreateOptions Options for creating a native OS alarm via the platform clock app. | Prop | Type | Description | | ------------- | --------- | -------------------------------------------- | | **`hour`** | `number` | Hour of day in 24h format (0-23) | | **`minute`** | `number` | Minute of hour (0-59) | | **`label`** | `string` | Optional label for the alarm | | **`skipUi`** | `boolean` | Android only: attempt to skip UI if possible | | **`vibrate`** | `boolean` | Android only: set alarm to vibrate | ### OSInfo Returned info about current OS and capabilities. | Prop | Type | Description | | ------------------------------------ | --------- | ----------------------------------------------------------- | | **`platform`** | `string` | ’ios’ \| ‘android’ \| ‘web’ | | **`version`** | `string` | OS version string | | **`supportsNativeAlarms`** | `boolean` | Whether the platform exposes a native alarm app integration | | **`supportsScheduledNotifications`** | `boolean` | Whether scheduling local notifications is supported | | **`canScheduleExactAlarms`** | `boolean` | Android only: whether exact alarms are allowed | ### PermissionResult Result of a permissions request. | Prop | Type | Description | | ------------- | ------------------------- | ---------------------------------- | | **`granted`** | `boolean` | Overall grant for requested scope | | **`details`** | `Record` | Optional details by permission key | # @capgo/capacitor-android-inline-install > Enable seamless in-app installation and updates for Android apps with inline installation capabilities and user-friendly flows. ## Overview The Capacitor Android Inline Install plugin enables triggering Google Play’s Inline Install overlay for Android applications. This plugin provides a seamless in-app installation experience using Google’s Premium Growth Tools, allowing users to install apps without leaving your application. Google Play overlay Trigger native Google Play install overlay 📱 Seamless experience Install apps without leaving your app 🔄 Fallback support Automatic fallback to full Play Store page ❤️ Campaign tracking Support for referrer tracking and analytics 📊 ## Installation ```bash npm install @capgo/capacitor-android-inline-install npx cap sync ``` ## Core API Methods ### Installation Management * `startInlineInstall(options)` - Trigger Google Play inline install overlay for specified app ## Configuration Options ```typescript interface InlineInstallOptions { id: string; // Target app package name (required) referrer?: string; // Tracking campaign string (optional) callerId?: string; // Caller app package name (defaults to current app) overlay?: boolean; // Enable/disable Play overlay (default: true) fallback?: boolean; // Use full store page if overlay fails (default: true) } ``` ## Usage Example ```typescript import { AndroidInlineInstall } from '@capgo/capacitor-android-inline-install'; // Basic inline install await AndroidInlineInstall.startInlineInstall({ id: 'com.example.targetapp' }); // Advanced install with tracking await AndroidInlineInstall.startInlineInstall({ id: 'com.example.targetapp', referrer: 'campaign=my-campaign&source=app', overlay: true, fallback: true }); // Handle the installation flow try { await AndroidInlineInstall.startInlineInstall({ id: 'com.spotify.music', referrer: 'utm_source=myapp&utm_campaign=music_promotion' }); console.log('Install overlay triggered successfully'); } catch (error) { console.error('Install failed:', error); } ``` ## Google Play Requirements ### Premium Growth Tools Eligibility Your app must qualify for Google Play’s Premium Growth Tools to use inline install: * Apps with significant user engagement * Good Play Store ratings and reviews * Compliance with Google Play policies ### Target App Requirements * Target app must be available on Google Play Store * Target app must support inline installation * User must be signed into Google Play Store ## Behavior and Fallbacks ### Overlay Mode (default) 1. Attempts to open Google Play overlay within your app 2. If overlay is unavailable, falls back to full Play Store page 3. If Play Store is not available, shows error ### Full Store Mode * Directly opens the full Google Play Store page * Bypasses overlay attempt entirely ## Platform Support * **Android**: Full support with Google Play Services * **iOS**: Not supported (Android-specific feature) * **Web**: Not supported (native Android feature) ## Implementation Details The plugin uses Android intents to communicate with Google Play Store: * Intent action for inline install overlay * Fallback to standard Play Store intent * Automatic handling of Play Services availability ## Use Cases * **App discovery**: Promote related apps within your ecosystem * **Cross-promotion**: Drive installs for partner applications * **Feature unlocking**: Install additional modules or extensions * **Companion apps**: Install supporting applications seamlessly ## Best Practices * Always provide fallback options for users without Play Services * Test with different device configurations and Play Store versions * Use referrer tracking to measure conversion rates * Handle installation errors gracefully * Respect user choice if they decline installation ## Limitations * Android-only functionality * Requires Google Play Services * Only works with apps qualifying for Premium Growth Tools * Subject to Google Play Store policies and availability ## Documentation Check the [complete documentation](/docs/plugins/android-inline-install/getting-started/) for detailed implementation guides and advanced integration patterns. # @capgo/capacitor-android-usagestatsmanager > Access Android usage statistics to monitor app usage, screen time, and user behavior analytics with system-level data. ## Overview The Capacitor Android Usage Stats Manager plugin exposes Android’s UsageStatsManager SDK to Capacitor applications, enabling access to detailed app usage statistics and device usage data. This plugin allows developers to track app usage patterns, screen time, and user behavior analytics on Android devices. Usage statistics Access Android UsageStatsManager SDK data 📱 App monitoring Track individual app usage time and frequency 🕐 Permission management Handle usage stats permissions seamlessly 🛡️ Package information Query installed package details and metadata 📦 ## Installation ```bash npm install @capgo/capacitor-android-usagestatsmanager npx cap sync ``` ## Required Permissions Add these permissions to your `android/app/src/main/AndroidManifest.xml`: ```xml ``` ## Core API Methods ### Usage Statistics * `queryAndAggregateUsageStats(options)` - Retrieve detailed usage statistics for installed apps * `isUsageStatsPermissionGranted()` - Check if usage stats permission is granted * `openUsageStatsSettings()` - Open system settings for usage stats permission ### Package Information * `queryAllPackages()` - Get information about all installed packages ## Usage Example ```typescript import { AndroidUsageStatsManager } from '@capgo/capacitor-android-usagestatsmanager'; // Check if permission is granted const permissionResult = await AndroidUsageStatsManager.isUsageStatsPermissionGranted(); if (!permissionResult.granted) { // Open settings to grant permission await AndroidUsageStatsManager.openUsageStatsSettings(); return; } // Query usage statistics const statsOptions = { intervalType: 0, // INTERVAL_DAILY startTime: Date.now() - (7 * 24 * 60 * 60 * 1000), // 7 days ago endTime: Date.now() }; const usageStats = await AndroidUsageStatsManager.queryAndAggregateUsageStats(statsOptions); console.log('Usage statistics:', usageStats); // Get all installed packages const packages = await AndroidUsageStatsManager.queryAllPackages(); console.log('Installed packages:', packages); ``` ## Permission Handling The plugin requires special permissions that cannot be granted through normal runtime permission requests: 1. **PACKAGE\_USAGE\_STATS**: Allows access to usage statistics 2. **QUERY\_ALL\_PACKAGES**: Required for package information (Android 11+) Users must manually grant these permissions through system settings. Use `openUsageStatsSettings()` to direct users to the appropriate settings page. ## Data Types ### Usage Statistics * App usage time and frequency * First and last time used * Total time in foreground * Launch count ### Package Information * Package name and version * Installation time * App labels and icons * System vs user apps ## Use Cases * **Digital wellbeing apps**: Monitor screen time and app usage * **Parental controls**: Track children’s device usage * **Productivity apps**: Analyze work patterns and focus time * **Analytics**: Understand user behavior and app engagement ## Android Compatibility * **Minimum Android version**: API level 21 (Android 5.0) * **Advanced features**: API level 29+ (Android 10+) for enhanced statistics * **Package queries**: API level 30+ (Android 11+) requires QUERY\_ALL\_PACKAGES ## Security Considerations * Usage stats permission is sensitive and requires user consent * Consider user privacy when collecting usage data * Implement proper data handling and storage practices * Follow Google Play policies for usage data collection ## Documentation Check the [complete documentation](/docs/plugins/android-usagestatsmanager/getting-started/) for detailed implementation guides and advanced usage patterns. # @capgo/capacitor-autofill-save-password > Enable password autofill and credential management with system integration for seamless authentication experiences. ## Overview The Capacitor Autofill Save Password plugin provides password saving and autofill functionality for Capacitor applications. This plugin integrates with system-level credential management to offer seamless authentication experiences with secure password storage and retrieval. Password saving Save credentials to system keychain securely 🔐 Autofill integration System-level password autofill support 🗝️ Cross-platform iOS support with Android development in progress 📱 Domain association Associated domains for seamless authentication ❤️ ## Installation ```bash npm install @capgo/capacitor-autofill-save-password npx cap sync ``` ## Platform Support * **iOS**: Full support (works with iOS 18.3 and older versions) * **Android**: Work in progress ## iOS Configuration ### 1. Associated Domains Setup Configure associated domains in your Apple Developer account and add them to your `App.entitlements` file: ```xml com.apple.developer.associated-domains webcredentials:yourdomain.com webcredentials:www.yourdomain.com ``` ### 2. Web Credential Configuration Add a `.well-known/apple-app-site-association` file to your website: ```json { "webcredentials": { "apps": [ "TEAMID.com.yourcompany.yourapp" ] } } ``` ## Core API Methods ### Password Management * `promptDialog(options)` - Save password to system keychain * `readPassword()` - Read saved password from keychain ## Usage Example ```typescript import { SavePassword } from '@capgo/capacitor-autofill-save-password'; // Save password after successful login async function login(username: string, password: string) { try { // Perform your login logic here const loginSuccess = await performLogin(username, password); if (loginSuccess) { // Prompt user to save password await SavePassword.promptDialog({ username: username, password: password, url: 'https://yourdomain.com' // iOS only }); console.log('Password saved successfully'); } } catch (error) { console.error('Failed to save password:', error); } } // Read saved password for autofill async function loadSavedCredentials() { try { const credentials = await SavePassword.readPassword(); if (credentials.username && credentials.password) { console.log('Found saved credentials'); // Pre-fill login form return { username: credentials.username, password: credentials.password }; } } catch (error) { console.error('Failed to read saved password:', error); } return null; } ``` ## Android Configuration (Work in Progress) For future Android support, the following configuration will be required: ### 1. Google Services Plugin Add to `android/app/build.gradle`: ```kotlin apply plugin: 'com.google.gms.google-services' ``` ### 2. Domain Configuration Add to `android/app/src/main/res/values/strings.xml`: ```xml [{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "web", "site": "https://yourdomain.com" } }] ``` ### 3. Google Services JSON Add `google-services.json` to your Android project. ## API Reference ### promptDialog(options) Saves user credentials to the system keychain. ```typescript interface SavePasswordOptions { username: string; password: string; url?: string; // iOS only - associated domain URL } ``` ### readPassword() Retrieves saved credentials from the system keychain. ```typescript interface SavedCredentials { username: string; password: string; } ``` ## Integration with Login Flow ```typescript import { SavePassword } from '@capgo/capacitor-autofill-save-password'; class AuthService { async login(username: string, password: string) { try { // Authenticate with your backend const response = await fetch('/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) }); if (response.ok) { // Offer to save credentials await this.offerToSavePassword(username, password); return true; } } catch (error) { console.error('Login failed:', error); } return false; } private async offerToSavePassword(username: string, password: string) { try { await SavePassword.promptDialog({ username, password, url: 'https://yourdomain.com' }); } catch (error) { // User declined to save or error occurred console.log('Password not saved:', error); } } async loadSavedCredentials() { try { return await SavePassword.readPassword(); } catch (error) { console.log('No saved credentials found'); return null; } } } ``` ## Best Practices * Only prompt to save passwords after successful authentication * Handle cases where users decline to save passwords gracefully * Implement proper error handling for keychain access failures * Use associated domains for seamless web-app credential sharing * Test autofill functionality across different iOS versions ## Security Considerations * Credentials are stored in the system keychain with appropriate security flags * Associated domains ensure credentials are only accessible to authorized apps * Follow platform security guidelines for credential management * Consider implementing additional security measures for sensitive applications ## Limitations * Android support is currently under development * iOS requires proper associated domains configuration * Autofill behavior may vary across different iOS versions * Requires user consent for saving and accessing credentials ## Documentation Check the [complete documentation](/docs/plugins/autofill-save-password/getting-started/) for detailed implementation guides and advanced integration patterns. # Background Geolocation > A Capacitor plugin that lets you receive accurate geolocation updates even while the app is backgrounded # Background Geolocation A Capacitor plugin that lets you receive accurate geolocation updates even while the app is backgrounded. It has a web API to facilitate for a similar usage, but background geolocation is not supported in a regular browser, only in an app environment. ## This plugin’s history Interestingly enough, this plugin has a lot of history. The initial solution from [Transistorsoft](https://github.com/transistorsoft) was a great piece of software, and I ([HarelM](https://github.com/HarelM)) encourage using it if it fits your needs. I tried it and understood that it prioritizes battery life over accuracy, which wasn’t the right fit for my hiking app. There was a very good fork maintained by **mauron85** specifically for that use case, and I was happy to help maintain it. But at some point, **mauron85** stopped responding to messages on GitHub, and no one could continue maintaining it. I hope mauron85 is safe and sound somewhere. So I created a fork and started maintaining it [here](https://github.com/HaylLtd/cordova-background-geolocation-plugin). It served me well for over half a decade, but I felt it was hard to maintain due to all its history, features, and bug fixes. I also felt like there was a barrier to introducing new features because of its complexity. So I started exploring what it would take to reduce that complexity—at the same time, I was envious of how small [`@capacitor-community/background-geolocation`](https://github.com/capacitor-community/background-geolocation) is. I took the best of both worlds: tried to reduce the codebase in the original Cordova plugin and add some robustness to the Capacitor plugin. That’s how I ended up maintaining this one. I hope you’ll enjoy it! ## Plugin comparison A short comparison between the three main background-geolocation plugins commonly used in Capacitor apps. | Plugin | Accuracy | Background | HTTP Upload | Pricing | | --------------------------------------------------------- | ------------ | ---------- | ---------------------------------------- | ------- | | `@capacitor-community/background-geolocation` (Community) | Not accurate | Yes | No | Free | | `@capgo/background-geolocation` (this plugin) | Accurate | Yes | No | Free | | Transistorsoft (original) | Accurate | Yes | Yes — built-in HTTP uploader to your API | Paid | Notes: * The Community plugin is lightweight and continues to work in the background, but it is known to be less accurate than the options below. * This Cap-go plugin aims to provide accurate location fixes and reliable background operation without requiring a paid license. * Transistorsoft’s plugin is a mature, accurate solution that also includes an HTTP uploader (it can send location updates to your API). It is a commercial product and requires a paid license for full use. ## Installation This plugin supports Capacitor v7: | Capacitor | Plugin | | --------- | ------ | | v7 | v7 | * npm ```bash npm install @capgo/background-geolocation npx cap update ``` * yarn ```bash yarn add @capgo/background-geolocation npx cap update ``` * pnpm ```bash pnpm add @capgo/background-geolocation npx cap update ``` * bun ```bash bun add @capgo/background-geolocation npx cap update ``` ## Platform Setup ### iOS Add the following keys to `Info.plist.`: ```xml ... NSLocationWhenInUseUsageDescription We need to track your location NSLocationAlwaysAndWhenInUseUsageDescription We need to track your location while your device is locked. UIBackgroundModes location ... ``` ### Android Set the the `android.useLegacyBridge` option to `true` in your Capacitor configuration. This prevents location updates halting after 5 minutes in the background. See and . On Android 13+, the app needs the `POST_NOTIFICATIONS` runtime permission to show the persistent notification informing the user that their location is being used in the background. This runtime permission is requested after the location permission is granted. If your app forwards location updates to a server in real time, be aware that after 5 minutes in the background Android will throttle HTTP requests initiated from the WebView. The solution is to use a native HTTP plugin such as [CapacitorHttp](https://capacitorjs.com/docs/apis/http). See . Configuration specific to Android can be made in `strings.xml`: ```xml Background Tracking drawable/ic_tracking yellow ``` ## Usage ```javascript import { BackgroundGeolocation } from "@capgo/background-geolocation"; BackgroundGeolocation.start( { backgroundMessage: "Cancel to prevent battery drain.", backgroundTitle: "Tracking You.", requestPermissions: true, stale: false, distanceFilter: 50 }, (location, error) => { if (error) { if (error.code === "NOT_AUTHORIZED") { if (window.confirm( "This app needs your location, " + "but does not have permission.\n\n" + "Open settings now?" )) { // It can be useful to direct the user to their device's // settings when location permissions have been denied. The // plugin provides the 'openSettings' method to do exactly // this. BackgroundGeolocation.openSettings(); } } return console.error(error); } return console.log(location); } ).then(() => { // When location updates are no longer needed, the plugin should be stopped by calling BackgroundGeolocation.stop(); }); // Set a planned route to get a notification sound when a new location arrives and it's not on the route: BackgroundGeolocation.setPlannedRoute({soundFile: "assets/myFile.mp3", route: [[1,2], [3,4]], distance: 30 }); // If you just want the current location, try something like this. The longer // the timeout, the more accurate the guess will be. I wouldn't go below about 100ms. function guessLocation(callback, timeout) { let last_location; BackgroundGeolocation.start( { requestPermissions: false, stale: true }, (location) => { last_location = location || undefined; } ).then(() => { setTimeout(() => { callback(last_location); BackgroundGeolocation.stop(); }, timeout); }); } ``` ## API ### start(…) ```typescript start(options: StartOptions, callback: (position?: Location | undefined, error?: CallbackError | undefined) => void) => Promise ``` To start listening for changes in the device’s location, call this method. A Promise is returned to indicate that it finished the call. The callback will be called every time a new location is available, or if there was an error when calling this method. Don’t rely on promise rejection for this. | Param | Type | Description | | -------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------- | | **`options`** | `StartOptions` | The configuration options | | **`callback`** | `(position?: Location, error?: CallbackError) => void` | The callback function invoked when a new location is available or an error occurs | ### stop() ```typescript stop() => Promise ``` Stops location updates. ### openSettings() ```typescript openSettings() => Promise ``` Opens the device’s location settings page. Useful for directing users to enable location services or adjust permissions. ### setPlannedRoute(…) ```typescript setPlannedRoute(options: SetPlannedRouteOptions) => Promise ``` Plays a sound file when the user deviates from the planned route. This should be used to play a sound (in the background too, only for native). | Param | Type | Description | | ------------- | ------------------------ | -------------------------------------------------------- | | **`options`** | `SetPlannedRouteOptions` | The options for setting the planned route and sound file | ## Interfaces ### StartOptions The options for configuring for location updates. | Prop | Type | Description | Default | | ------------------------ | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | | **`backgroundMessage`** | `string` | If the “backgroundMessage” option is defined, the plugin will provide location updates whether the app is in the background or the foreground. If it is not defined, location updates are only guaranteed in the foreground. This is true on both platforms. On Android, a notification must be shown to continue receiving location updates in the background. This option specifies the text of that notification. | | | **`backgroundTitle`** | `string` | The title of the notification mentioned above. | `"Using your location"` | | **`requestPermissions`** | `boolean` | Whether permissions should be requested from the user automatically, if they are not already granted. | `true` | | **`stale`** | `boolean` | If “true”, stale locations may be delivered while the device obtains a GPS fix. You are responsible for checking the “time” property. If “false”, locations are guaranteed to be up to date. | `false` | | **`distanceFilter`** | `number` | The distance in meters that the device must move before a new location update is triggered. This is used to filter out small movements and reduce the number of updates. | `0` | ### Location Represents a geographical location with various attributes. Contains all the standard location properties returned by GPS/network providers. | Prop | Type | Description | | ---------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | **`latitude`** | `number` | Latitude in degrees. Range: -90.0 to +90.0 | | **`longitude`** | `number` | Longitude in degrees. Range: -180.0 to +180.0 | | **`accuracy`** | `number` | Radius of horizontal uncertainty in metres, with 68% confidence. Lower values indicate more accurate location. | | **`altitude`** | `number \| null` | Metres above sea level (or null if not available). | | **`altitudeAccuracy`** | `number \| null` | Vertical uncertainty in metres, with 68% confidence (or null if not available). | | **`simulated`** | `boolean` | `true` if the location was simulated by software, rather than GPS. Useful for detecting mock locations in development or testing. | | **`bearing`** | `number \| null` | Deviation from true north in degrees (or null if not available). Range: 0.0 to 360.0 | | **`speed`** | `number \| null` | Speed in metres per second (or null if not available). | | **`time`** | `number \| null` | Time the location was produced, in milliseconds since the unix epoch. Use this to check if a location is stale when using stale: true. | ### CallbackError Error object that may be passed to the location start callback. Extends the standard Error with optional error codes. | Prop | Type | Description | | ---------- | -------- | ----------------------------------------------------- | | **`code`** | `string` | Optional error code for more specific error handling. | ### SetPlannedRouteOptions | Prop | Type | Description | Default | | --------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | | **`soundFile`** | `string` | The name of the sound file to play. Must be a valid sound relative path in the app’s public folder to work for both web and native platforms. There’s no need to include the public folder in the path. | | | **`route`** | `[number, number][]` | The planned route as an array of longitude and latitude pairs. Each pair represents a point on the route. This is used to define a route that the user can follow. The route is used to play a sound when the user deviates from it. | | | **`distance`** | `number` | The distance in meters that the user must deviate from the planned route to trigger the sound. This is used to determine how far off the route the user can be before the sound is played. If not specified, a default value of 50 meters is used. | `50` | # @capgo/camera-preview > Display camera preview in your app with full control over camera settings, capture photos and videos directly from the preview. Real-time preview Display live camera feed directly in your app UI 🚀 Full control Control flash, zoom, focus, and switch between cameras 📸 Capture capabilities Take photos and record videos from the preview 🎥 Comprehensive Documentation Check the [Documentation](/docs/plugins/camera-preview/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and use the Camera Preview plugin to display real-time camera feed and capture photos/videos in your Capacitor app. 1. **Install the package** * npm ```sh npm i @capgo/camera-preview ``` * pnpm ```sh pnpm add @capgo/camera-preview ``` * yarn ```sh yarn add @capgo/camera-preview ``` * bun ```sh bun add @capgo/camera-preview ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` 3. **Configure permissions** ### iOS Add camera usage description to your `Info.plist`: ```xml NSCameraUsageDescription To take photos and videos NSMicrophoneUsageDescription To record audio with videos NSPhotoLibraryUsageDescription To save photos and videos ``` ### Android Add camera permissions to your `AndroidManifest.xml`: ```xml ``` ## Usage Import the plugin and use its methods to control the camera: ```typescript import { CameraPreview } from '@capgo/camera-preview'; import { CameraPreviewOptions, CameraPreviewPictureOptions } from '@capgo/camera-preview'; // Start camera preview const startCamera = async () => { const cameraPreviewOptions: CameraPreviewOptions = { position: 'rear', height: 1920, width: 1080, quality: 50, toBack: false, paddingBottom: 0, rotateWhenOrientationChanged: true, x: 0, y: 0 }; await CameraPreview.start(cameraPreviewOptions); }; // Stop camera preview const stopCamera = async () => { await CameraPreview.stop(); }; // Take a picture const takePicture = async () => { const pictureOptions: CameraPreviewPictureOptions = { quality: 90, width: 1920, height: 1080 }; const result = await CameraPreview.capture(pictureOptions); const base64PictureData = result.value; // Use the base64 image data console.log(base64PictureData); }; // Switch camera const flipCamera = async () => { await CameraPreview.flip(); }; // Control flash const setFlashMode = async (mode: 'on' | 'off' | 'auto' | 'torch') => { await CameraPreview.setFlashMode({ flashMode: mode }); }; // Start recording video const startRecording = async () => { await CameraPreview.startRecordVideo({ storeToFile: true, fileName: 'myvideo' }); }; // Stop recording const stopRecording = async () => { const result = await CameraPreview.stopRecordVideo(); console.log('Video path:', result.videoFilePath); }; ``` ## API Reference ### start(options) Starts the camera preview. ```typescript interface CameraPreviewOptions { position?: 'rear' | 'front'; height?: number; width?: number; x?: number; y?: number; toBack?: boolean; paddingBottom?: number; rotateWhenOrientationChanged?: boolean; storeToFile?: boolean; disableExifHeaderStripping?: boolean; enableHighResolution?: boolean; disableAudio?: boolean; lockAndroidOrientation?: boolean; enableOpacity?: boolean; enableZoom?: boolean; } ``` ### stop() Stops the camera preview. ### capture(options) Takes a picture and returns it as base64 encoded string. ```typescript interface CameraPreviewPictureOptions { height?: number; width?: number; quality?: number; } ``` ### flip() Switches between front and rear camera. ### setFlashMode(options) Sets the flash mode. ```typescript interface CameraPreviewFlashMode { flashMode: 'off' | 'on' | 'auto' | 'torch'; } ``` ### startRecordVideo(options) Starts video recording. ```typescript interface CameraPreviewVideoOptions { storeToFile?: boolean; fileName?: string; width?: number; height?: number; quality?: number; withFlash?: boolean; } ``` ### stopRecordVideo() Stops video recording and returns the video file path. ## Advanced Features ### Focus Control ```typescript // Set focus await CameraPreview.setFocusCoordinate({ x: 100, y: 100 }); // Get supported focus modes const focusModes = await CameraPreview.getFocusModes(); // Set focus mode await CameraPreview.setFocusMode({ focusMode: 'continuous-picture' }); ``` ### Zoom Control ```typescript // Get max zoom const maxZoom = await CameraPreview.getMaxZoom(); // Set zoom await CameraPreview.setZoom({ zoom: 2.0 }); // Get current zoom const currentZoom = await CameraPreview.getZoom(); ``` ### Exposure Control ```typescript // Get exposure compensation range const range = await CameraPreview.getExposureCompensationRange(); // Set exposure compensation await CameraPreview.setExposureCompensation({ exposureCompensation: 0.5 }); ``` ## Best Practices 1. **Request permissions first** ```typescript import { Camera } from '@capacitor/camera'; const requestPermissions = async () => { const permissions = await Camera.requestPermissions(); if (permissions.camera === 'granted') { // Start camera preview } }; ``` 2. **Handle orientation changes** Set `rotateWhenOrientationChanged: true` to automatically adjust the preview. 3. **Optimize performance** * Use appropriate resolution settings * Stop the preview when not in use * Disable features you don’t need 4. **Error handling** ```typescript try { await CameraPreview.start(options); } catch (error) { console.error('Failed to start camera:', error); } ``` ## Platform Notes ### iOS * Requires iOS 10.0+ * Uses AVFoundation framework * Hardware acceleration supported ### Android * Requires Android 5.0 (API 21)+ * Uses Camera2 API * Supports various camera features based on device capabilities # @capgo/capacitor-crisp > Integrate Crisp native chat SDK into your Capacitor app for seamless in-app customer support and real-time messaging. Native performance Native SDK integration for smooth chat experience 🚀 Real-time messaging Live chat with customers directly in your app 💬 Rich features Support for user data, events, and custom styling ✨ Comprehensive Documentation Check the [Documentation](/docs/plugins/crisp/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and use the Crisp chat SDK plugin for in-app customer support in your Capacitor app. 1. **Install the package** * npm ```sh npm i @capgo/capacitor-crisp ``` * pnpm ```sh pnpm add @capgo/capacitor-crisp ``` * yarn ```sh yarn add @capgo/capacitor-crisp ``` * bun ```sh bun add @capgo/capacitor-crisp ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` 3. **Get your Crisp Website ID** * Sign up at [crisp.chat](https://crisp.chat) * Create a website/project * Find your Website ID in Settings > Setup Instructions ## Basic Usage Import the plugin and configure it with your Website ID: ```typescript import { CapacitorCrisp } from '@capgo/capacitor-crisp'; // Configure Crisp with your website ID const configureCrisp = async () => { await CapacitorCrisp.configure({ websiteID: 'YOUR_WEBSITE_ID' }); }; // Open the chat const openChat = async () => { await CapacitorCrisp.openMessenger(); }; // Set user information const setUserInfo = async () => { await CapacitorCrisp.setUser({ email: 'user@example.com', nickname: 'John Doe', phone: '+1234567890', avatar: 'https://example.com/avatar.jpg' }); }; // Reset user session (logout) const logout = async () => { await CapacitorCrisp.resetChatSession(); }; ``` ## API Reference ### configure(options) Configure Crisp with your website ID and optional settings. ```typescript interface ConfigureOptions { websiteID: string; locale?: string; // e.g., 'en', 'fr', 'es' tokenID?: string; // For authenticated sessions } await CapacitorCrisp.configure({ websiteID: 'YOUR_WEBSITE_ID', locale: 'en' }); ``` ### openMessenger() Opens the Crisp chat interface. ```typescript await CapacitorCrisp.openMessenger(); ``` ### setUser(options) Sets user information for the chat session. ```typescript interface UserOptions { email?: string; nickname?: string; phone?: string; avatar?: string; } await CapacitorCrisp.setUser({ email: 'user@example.com', nickname: 'John Doe' }); ``` ### setUserCompany(options) Sets company information for business users. ```typescript interface CompanyOptions { name: string; url?: string; description?: string; employment?: { title?: string; role?: string; }; geolocation?: { city?: string; country?: string; }; } await CapacitorCrisp.setUserCompany({ name: 'Acme Corp', url: 'https://acme.com', employment: { title: 'CEO', role: 'Leadership' } }); ``` ### pushEvent(options) Send custom events to track user actions. ```typescript interface EventOptions { name: string; color?: 'red' | 'orange' | 'yellow' | 'green' | 'blue' | 'purple' | 'pink' | 'brown' | 'grey' | 'black'; data?: { [key: string]: any }; } await CapacitorCrisp.pushEvent({ name: 'checkout_completed', color: 'green', data: { price: 99.99, currency: 'USD' } }); ``` ### setSessionSegment(segment) Set a segment to categorize the chat session. ```typescript await CapacitorCrisp.setSessionSegment('premium_customer'); ``` ### resetChatSession() Reset the current chat session (useful for logout). ```typescript await CapacitorCrisp.resetChatSession(); ``` ## Advanced Features ### Custom User Data ```typescript // Set multiple custom data fields await CapacitorCrisp.setSessionData({ key: 'plan', value: 'premium' }); await CapacitorCrisp.setSessionData({ key: 'signup_date', value: '2024-01-15' }); ``` ### Message Preset Set a pre-filled message in the chat input: ```typescript await CapacitorCrisp.setMessageText( "Hello, I need help with my order #12345" ); ``` ### Chat Availability Control when the chat widget is available: ```typescript // Hide chat temporarily await CapacitorCrisp.setTokenID('user_token_12345'); ``` ## Complete Example ```typescript import { CapacitorCrisp } from '@capgo/capacitor-crisp'; export class ChatService { async initialize() { // Configure Crisp await CapacitorCrisp.configure({ websiteID: 'YOUR_WEBSITE_ID', locale: 'en' }); } async loginUser(user: any) { // Set user information await CapacitorCrisp.setUser({ email: user.email, nickname: user.name, phone: user.phone, avatar: user.avatarUrl }); // Set custom data await CapacitorCrisp.setSessionData({ key: 'user_id', value: user.id }); await CapacitorCrisp.setSessionData({ key: 'account_type', value: user.accountType }); // Set segment if (user.isPremium) { await CapacitorCrisp.setSessionSegment('premium'); } // Track login event await CapacitorCrisp.pushEvent({ name: 'user_login', color: 'blue', data: { method: 'email' } }); } async openSupport(context?: string) { if (context) { await CapacitorCrisp.setMessageText( `I need help with: ${context}` ); } await CapacitorCrisp.openMessenger(); } async logout() { await CapacitorCrisp.resetChatSession(); } } ``` ## Styling and Customization Crisp automatically adapts to your app’s theme, but you can customize it further through the Crisp dashboard: 1. Go to your Crisp dashboard 2. Navigate to Settings > Website Settings > Chatbox & Email Settings 3. Customize colors, position, and behavior ## Best Practices 1. **Initialize early** Configure Crisp during app initialization for immediate availability: ```typescript import { App } from '@capacitor/app'; App.addListener('appStateChange', async ({ isActive }) => { if (isActive) { await CapacitorCrisp.configure({ websiteID: 'YOUR_WEBSITE_ID' }); } }); ``` 2. **Set user context** Always provide user information when available for better support: ```typescript if (user.isAuthenticated) { await CapacitorCrisp.setUser({ email: user.email, nickname: user.name }); } ``` 3. **Track important events** Use events to provide context to support agents: ```typescript await CapacitorCrisp.pushEvent({ name: 'error_occurred', color: 'red', data: { error: error.message, screen: 'checkout' } }); ``` 4. **Handle logout properly** Always reset the session when users log out: ```typescript async logout() { await CapacitorCrisp.resetChatSession(); // Your other logout logic } ``` ## Platform Notes ### iOS * Requires iOS 10.0+ * Uses native Crisp iOS SDK * Supports push notifications (configure in Crisp dashboard) ### Android * Requires Android 5.0 (API 21)+ * Uses native Crisp Android SDK * Material Design compliant ### Web * Falls back to Crisp JavaScript SDK * Full feature parity with native platforms # @capgo/capacitor-data-storage-sqlite > Fast and reliable SQLite-based key-value storage for your Capacitor apps with encryption support. SQLite powered Fast and reliable data storage using SQLite 💾 Encryption support Optional encryption for sensitive data 🔐 Key-value simplicity Simple key-value API with powerful features 🗂️ Comprehensive Documentation Check the [Documentation](/docs/plugins/data-storage-sqlite/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and configure the Capacitor Data Storage SQLite plugin for fast key-value storage with optional encryption. 1. **Install the package** * npm ```sh npm i @capgo/capacitor-data-storage-sqlite ``` * pnpm ```sh pnpm add @capgo/capacitor-data-storage-sqlite ``` * yarn ```sh yarn add @capgo/capacitor-data-storage-sqlite ``` * bun ```sh bun add @capgo/capacitor-data-storage-sqlite ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` 3. **Configure the plugin** **Basic Storage Example:** ```typescript import { CapacitorDataStorageSqlite } from '@capgo/capacitor-data-storage-sqlite'; // Open a storage database await CapacitorDataStorageSqlite.openStore({ database: 'myapp_storage' }); // Store data await CapacitorDataStorageSqlite.set({ key: 'user_preferences', value: JSON.stringify({ theme: 'dark' }) }); ``` **Encrypted Storage Example:** ```typescript // Open encrypted storage await CapacitorDataStorageSqlite.openStore({ database: 'secure_storage', encrypted: true, mode: 'encryption' }); // Store sensitive data await CapacitorDataStorageSqlite.set({ key: 'api_token', value: 'secret_token_value' }); ``` * iOS No additional setup required for iOS. * Android No additional setup required for Android. 4. **Basic operations** ```typescript import { CapacitorDataStorageSqlite } from '@capgo/capacitor-data-storage-sqlite'; // Set a value await CapacitorDataStorageSqlite.set({ key: 'username', value: 'john_doe' }); // Get a value const { value } = await CapacitorDataStorageSqlite.get({ key: 'username' }); console.log('Username:', value); // "john_doe" // Remove a value await CapacitorDataStorageSqlite.remove({ key: 'username' }); // Clear all data await CapacitorDataStorageSqlite.clear(); // Check if key exists const { result } = await CapacitorDataStorageSqlite.iskey({ key: 'username' }); console.log('Key exists:', result); // true or false // Get all keys const { keys } = await CapacitorDataStorageSqlite.keys(); console.log('All keys:', keys); // Get all values const { values } = await CapacitorDataStorageSqlite.values(); console.log('All values:', values); ``` 5. **Advanced usage** ```typescript import { CapacitorDataStorageSqlite } from '@capgo/capacitor-data-storage-sqlite'; export class StorageService { private dbName = 'app_storage'; private isEncrypted = false; async initialize(encrypted = false) { this.isEncrypted = encrypted; // Open storage with options await CapacitorDataStorageSqlite.openStore({ database: this.dbName, encrypted: encrypted, mode: encrypted ? 'encryption' : 'no-encryption', version: 1 }); } // Generic storage methods async setObject(key: string, data: T): Promise { const value = JSON.stringify(data); await CapacitorDataStorageSqlite.set({ key, value }); } async getObject(key: string): Promise { try { const { value } = await CapacitorDataStorageSqlite.get({ key }); return value ? JSON.parse(value) : null; } catch (error) { console.error('Error getting object:', error); return null; } } // Batch operations async setMultiple(items: Record): Promise { for (const [key, value] of Object.entries(items)) { await CapacitorDataStorageSqlite.set({ key, value: typeof value === 'string' ? value : JSON.stringify(value) }); } } async getMultiple(keys: string[]): Promise> { const results: Record = {}; for (const key of keys) { try { const { value } = await CapacitorDataStorageSqlite.get({ key }); results[key] = value; } catch (error) { results[key] = null; } } return results; } // Table management async getTables(): Promise { const { tables } = await CapacitorDataStorageSqlite.tables(); return tables; } async deleteTable(table: string): Promise { await CapacitorDataStorageSqlite.deleteTable({ table }); } // Import/Export functionality async exportToJson(): Promise { const { keys } = await CapacitorDataStorageSqlite.keys(); const { values } = await CapacitorDataStorageSqlite.values(); return keys.map((key, index) => ({ key, value: values[index] })); } async importFromJson(data: Array<{ key: string; value: string }>): Promise { // Clear existing data await CapacitorDataStorageSqlite.clear(); // Import new data for (const item of data) { await CapacitorDataStorageSqlite.set({ key: item.key, value: item.value }); } } // Filtering and searching async keysStartingWith(prefix: string): Promise { const { keys } = await CapacitorDataStorageSqlite.keys(); return keys.filter(key => key.startsWith(prefix)); } async filterByPrefix(prefix: string): Promise> { const { keys } = await CapacitorDataStorageSqlite.keys(); const { values } = await CapacitorDataStorageSqlite.values(); const filtered: Array<{ key: string; value: string }> = []; keys.forEach((key, index) => { if (key.startsWith(prefix)) { filtered.push({ key, value: values[index] }); } }); return filtered; } // Close database when done async close(): Promise { await CapacitorDataStorageSqlite.closeStore({ database: this.dbName }); } } // Usage example const storage = new StorageService(); await storage.initialize(true); // Use encryption // Store user data await storage.setObject('user_profile', { id: 123, name: 'John Doe', email: 'john@example.com' }); // Retrieve user data const profile = await storage.getObject('user_profile'); console.log('User profile:', profile); ``` ## API Reference ### Methods #### `openStore(options: OpenStoreOptions)` Open a storage database. **Parameters:** * `options.database`: string - Database name * `options.encrypted`: boolean - Enable encryption * `options.mode`: string - ‘encryption’ or ‘no-encryption’ * `options.version`: number - Database version #### `closeStore(options: CloseStoreOptions)` Close the storage database. #### `set(options: SetOptions)` Store a key-value pair. **Parameters:** * `options.key`: string - Storage key * `options.value`: string - Value to store #### `get(options: GetOptions)` Retrieve a value by key. **Returns:** `Promise<{ value: string }>` #### `remove(options: RemoveOptions)` Remove a key-value pair. #### `clear()` Clear all data from storage. #### `iskey(options: IskeyOptions)` Check if a key exists. **Returns:** `Promise<{ result: boolean }>` #### `keys()` Get all storage keys. **Returns:** `Promise<{ keys: string[] }>` #### `values()` Get all storage values. **Returns:** `Promise<{ values: string[] }>` #### `tables()` Get all table names. **Returns:** `Promise<{ tables: string[] }>` #### `deleteTable(options: DeleteTableOptions)` Delete a specific table. ### Interfaces ```typescript interface OpenStoreOptions { database: string; encrypted?: boolean; mode?: string; version?: number; } interface SetOptions { key: string; value: string; } interface GetOptions { key: string; } interface RemoveOptions { key: string; } ``` ## Platform Notes ### iOS * Uses SQLite3 with optional SQLCipher for encryption * Data persists across app updates * Supports iOS 11.0+ ### Android * Uses SQLite with optional SQLCipher * Data persists across app updates * Supports Android 5.0 (API 21)+ ## Common Use Cases 1. **User Preferences**: Store app settings and preferences 2. **Cache Management**: Cache API responses and data 3. **Offline Storage**: Store data for offline access 4. **Session Management**: Manage user sessions securely 5. **Token Storage**: Securely store authentication tokens ## Best Practices 1. **Use Encryption for Sensitive Data** ```typescript // For sensitive data like tokens await openStore({ database: 'secure_db', encrypted: true, mode: 'encryption' }); ``` 2. **Organize Keys with Prefixes** ```typescript // Use prefixes for organization await set({ key: 'user:123:profile', value: userData }); await set({ key: 'cache:api:users', value: apiData }); ``` 3. **Handle Large Data Carefully** ```typescript // For large objects, consider compression const compressed = compress(largeData); await set({ key: 'large_data', value: compressed }); ``` 4. **Regular Cleanup** ```typescript // Remove expired cache entries const keys = await keys(); for (const key of keys.keys) { if (key.startsWith('cache:') && isExpired(key)) { await remove({ key }); } } ``` ## Troubleshooting **Database not opening:** * Check database name is valid (alphanumeric, underscores) * Ensure no special characters in database name * Verify encryption mode matches existing database **Data not persisting:** * Ensure `openStore` is called before operations * Check for any errors in console * Verify key names are strings **Performance issues:** * Avoid storing very large values * Use batch operations when possible * Consider using multiple databases for different data types # @capgo/capacitor-downloader > Download files with background support, progress tracking, pause/resume capabilities, and efficient download management. ## Overview The Capacitor Downloader plugin provides powerful file download capabilities with support for background downloads, progress tracking, and comprehensive download management. This plugin enables robust file downloading with pause/resume functionality and detailed progress monitoring. > ⚠️ **Work in Progress**: This plugin is currently under development and not yet ready for production use. Background downloads Continue downloads when app is backgrounded 📥 Progress tracking Real-time download progress and status monitoring 📊 Download control Pause, resume, and stop downloads dynamically ⏯️ Network options Configure network preferences and priorities 📶 ## Installation ```bash npm install @capgo/capacitor-downloader npx cap sync ``` ## Core API Methods ### Download Management * `download(options)` - Start a new file download * `pause(id)` - Pause an ongoing download * `resume(id)` - Resume a paused download * `stop(id)` - Stop and cancel a download * `checkStatus(id)` - Get current download status ### File Operations * `getFileInfo(path)` - Retrieve file information and metadata ## Download Configuration ```typescript interface DownloadOptions { id: string; // Unique download identifier url: string; // Download source URL destination: string; // Local save path headers?: Record; // Custom HTTP headers network?: 'cellular' | 'wifi-only'; // Network restrictions priority?: 'high' | 'normal' | 'low'; // Download priority } ``` ## Event Listeners The plugin provides comprehensive event handling: * `downloadProgress` - Track real-time download progress * `downloadCompleted` - Handle successful download completion * `downloadFailed` - Handle download errors and failures ## Usage Example ```typescript import { Downloader } from '@capgo/capacitor-downloader'; // Start a download const downloadId = 'my-download-001'; await Downloader.download({ id: downloadId, url: 'https://example.com/large-file.zip', destination: '/downloads/large-file.zip', headers: { 'Authorization': 'Bearer token123' }, network: 'wifi-only', priority: 'high' }); // Listen for progress updates Downloader.addListener('downloadProgress', (data) => { console.log(`Download ${data.id}: ${data.progress}% complete`); console.log(`Downloaded: ${data.bytesDownloaded}/${data.totalBytes} bytes`); }); // Handle completion Downloader.addListener('downloadCompleted', (data) => { console.log(`Download completed: ${data.id}`); console.log(`File saved to: ${data.path}`); }); // Handle errors Downloader.addListener('downloadFailed', (error) => { console.error(`Download failed: ${error.id}`, error.message); }); // Pause a download await Downloader.pause(downloadId); // Resume the download await Downloader.resume(downloadId); // Check download status const status = await Downloader.checkStatus(downloadId); console.log('Download status:', status); // Stop the download await Downloader.stop(downloadId); ``` ## Network Configuration ### WiFi-Only Downloads ```typescript await Downloader.download({ id: 'large-file', url: 'https://example.com/video.mp4', destination: '/downloads/video.mp4', network: 'wifi-only' // Restricts to WiFi networks only }); ``` ### Priority Management ```typescript // High priority download await Downloader.download({ id: 'urgent-update', url: 'https://example.com/update.zip', destination: '/downloads/update.zip', priority: 'high' }); ``` ## Download States Downloads can be in various states: * **Pending**: Queued for download * **Running**: Currently downloading * **Paused**: Temporarily stopped * **Completed**: Successfully finished * **Failed**: Encountered an error * **Stopped**: Manually cancelled ## File Information ```typescript // Get file details const fileInfo = await Downloader.getFileInfo('/downloads/my-file.pdf'); console.log('File size:', fileInfo.size); console.log('Last modified:', fileInfo.lastModified); console.log('MIME type:', fileInfo.mimeType); ``` ## Best Practices * Use unique download IDs to avoid conflicts * Implement proper error handling for network failures * Consider storage space before starting large downloads * Use WiFi-only mode for large files to preserve mobile data * Clean up completed downloads to manage storage ## Development Status This plugin is inspired by react-native-background-downloader and is currently being developed. Features may change as development progresses. ## Documentation Check the [complete documentation](/docs/plugins/downloader/getting-started/) for detailed implementation guides when the plugin reaches production readiness. # @capgo/capacitor-flash > Switch your device's flashlight/torch on and off programmatically with this lightweight Capacitor plugin. Simple API Turn flashlight on/off with just one method call 🚀 Cross-platform Works on both iOS and Android devices 📱 Lightweight Minimal footprint with no dependencies ⚡ Comprehensive Documentation Check the [Documentation](/docs/plugins/flash/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and use the Flash plugin to control your device's flashlight in your Capacitor app. 1. **Install the package** * npm ```sh npm i @capgo/capacitor-flash ``` * pnpm ```sh pnpm add @capgo/capacitor-flash ``` * yarn ```sh yarn add @capgo/capacitor-flash ``` * bun ```sh bun add @capgo/capacitor-flash ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` ## Usage Import the plugin and use its methods to control the flashlight: ```typescript import { CapacitorFlash } from '@capgo/capacitor-flash'; // Check if flashlight is available const checkFlashlight = async () => { const { value } = await CapacitorFlash.isAvailable(); console.log('Flashlight available:', value); }; // Turn on flashlight const turnOn = async () => { await CapacitorFlash.switchOn(); }; // Turn off flashlight const turnOff = async () => { await CapacitorFlash.switchOff(); }; // Check if flashlight is on const checkStatus = async () => { const { value } = await CapacitorFlash.isSwitchedOn(); console.log('Flashlight is on:', value); }; // Toggle flashlight const toggle = async () => { await CapacitorFlash.toggle(); }; ``` ## API Reference ### isAvailable() Checks if flashlight is available on the device. ```typescript const result = await CapacitorFlash.isAvailable(); // Returns: { value: boolean } ``` ### switchOn(options?) Turns the flashlight on. ```typescript interface SwitchOnOptions { intensity?: number; // 0.0 to 1.0 (iOS only) } await CapacitorFlash.switchOn({ intensity: 0.5 }); ``` ### switchOff() Turns the flashlight off. ```typescript await CapacitorFlash.switchOff(); ``` ### isSwitchedOn() Checks if the flashlight is currently on. ```typescript const result = await CapacitorFlash.isSwitchedOn(); // Returns: { value: boolean } ``` ### toggle() Toggles the flashlight on/off. ```typescript await CapacitorFlash.toggle(); ``` ## Complete Example ```typescript import { CapacitorFlash } from '@capgo/capacitor-flash'; export class FlashlightService { private isOn = false; async init() { const { value } = await CapacitorFlash.isAvailable(); if (!value) { throw new Error('Flashlight not available on this device'); } } async toggle() { if (this.isOn) { await CapacitorFlash.switchOff(); } else { await CapacitorFlash.switchOn(); } this.isOn = !this.isOn; } async turnOn(intensity?: number) { await CapacitorFlash.switchOn({ intensity }); this.isOn = true; } async turnOff() { await CapacitorFlash.switchOff(); this.isOn = false; } async strobe(intervalMs: number = 100, duration: number = 3000) { const endTime = Date.now() + duration; while (Date.now() < endTime) { await CapacitorFlash.toggle(); await new Promise(resolve => setTimeout(resolve, intervalMs)); } // Ensure flashlight is off after strobe await CapacitorFlash.switchOff(); this.isOn = false; } } ``` ## Best Practices 1. **Check availability first** Always verify flashlight availability before using it: ```typescript const { value } = await CapacitorFlash.isAvailable(); if (!value) { // Show alternative UI or disable flashlight features } ``` 2. **Handle errors gracefully** ```typescript try { await CapacitorFlash.switchOn(); } catch (error) { console.error('Failed to turn on flashlight:', error); } ``` 3. **Turn off when not needed** Always turn off the flashlight when your app goes to background or when the feature is no longer needed to save battery. 4. **Avoid rapid toggling** Implement debouncing to prevent rapid on/off switching which could damage the LED or drain battery. ## Platform Notes ### iOS * Requires iOS 10.0+ * Uses `AVCaptureDevice` torch mode * Supports intensity control (0.0 to 1.0) ### Android * Requires Android 6.0 (API 23)+ * Uses Camera2 API * Intensity control not supported (uses default brightness) ### Web * Not supported on web platform * Will return `isAvailable: false` # Capacitor Google Tag Manager Plugin > A Capacitor plugin for integrating Google Tag Manager into your mobile applications # Capacitor Google Tag Manager Plugin A Capacitor plugin for integrating Google Tag Manager into your mobile applications. > **Note**: This plugin uses the official Google Tag Manager SDK directly for both iOS and Android platforms. ## Installation * npm ```bash npm install capacitor-gtm npx cap sync ``` * yarn ```bash yarn add capacitor-gtm npx cap sync ``` * pnpm ```bash pnpm add capacitor-gtm npx cap sync ``` * bun ```bash bun add capacitor-gtm npx cap sync ``` ## Platform Setup ### iOS Setup 1. **Add GTM container file** * Download your container from Google Tag Manager console (GTM-XXXXXX.json) * In Xcode, add the file to your project * Make sure to add it to your app target ### Android Setup 1. **Add GTM container file** * Download your container from Google Tag Manager console (GTM-XXXXXX.json) * Place the file in `android/app/src/main/assets/containers/` * Create the `containers` directory if it doesn’t exist ## API ### initialize(…) ```typescript initialize(options: { containerId: string; timeout?: number; }) => Promise ``` Initializes Google Tag Manager with the specified container ID. | Param | Type | Description | | ------------- | -------------------------------------------- | --------------------------- | | **`options`** | `{ containerId: string; timeout?: number; }` | The initialization options. | ### push(…) ```typescript push(options: { event: string; parameters?: Record; }) => Promise ``` Pushes an event to the Google Tag Manager dataLayer. | Param | Type | Description | | ------------- | ------------------------------------------------------ | ------------------ | | **`options`** | `{ event: string; parameters?: Record; }` | The event options. | ### setUserProperty(…) ```typescript setUserProperty(options: { key: string; value: string | number | boolean; }) => Promise ``` Sets a user property in the Google Tag Manager dataLayer. | Param | Type | Description | | ------------- | ------------------------------------------------------ | -------------------------- | | **`options`** | `{ key: string; value: string \| number \| boolean; }` | The user property options. | ### getValue(…) ```typescript getValue(options: { key: string; }) => Promise<{ value: any; }> ``` Gets a value from the Google Tag Manager dataLayer. Searches through the dataLayer for the most recent value of the specified key. | Param | Type | Description | | ------------- | ------------------ | ----------------------------------- | | **`options`** | `{ key: string; }` | The options for retrieving a value. | **Returns:** `Promise<{ value: any; }>` ### reset() ```typescript reset() => Promise ``` Resets the Google Tag Manager instance and clears all data. This will remove all data from the dataLayer and require re-initialization. ## Usage Example ```typescript import { GoogleTagManager } from 'capacitor-gtm'; // Initialize GTM await GoogleTagManager.initialize({ containerId: 'GTM-XXXXXX', timeout: 2000 // optional, defaults to 2000ms }); // Track an event await GoogleTagManager.push({ event: 'purchase', parameters: { value: 29.99, currency: 'USD', items: ['item1', 'item2'] } }); // Set user property await GoogleTagManager.setUserProperty({ key: 'user_type', value: 'premium' }); // Get a value from container const result = await GoogleTagManager.getValue({ key: 'api_key' }); console.log('API Key:', result.value); // Reset data layer await GoogleTagManager.reset(); ``` ## Common Use Cases ### E-commerce Tracking ```typescript // Track product view await GoogleTagManager.push({ event: 'view_item', parameters: { currency: 'USD', value: 15.99, items: [{ item_id: 'SKU123', item_name: 'Product Name', price: 15.99, quantity: 1 }] } }); // Track purchase await GoogleTagManager.push({ event: 'purchase', parameters: { transaction_id: '12345', value: 45.99, currency: 'USD', items: [{ item_id: 'SKU123', item_name: 'Product Name', price: 15.99, quantity: 2 }] } }); ``` ### User Engagement ```typescript // Track screen view await GoogleTagManager.push({ event: 'screen_view', parameters: { screen_name: 'Home', screen_class: 'HomeViewController' } }); // Track custom event await GoogleTagManager.push({ event: 'level_complete', parameters: { level: 5, score: 1000, time_spent: 300 } }); ``` ## Troubleshooting ### iOS Issues 1. **Container not loading**: Ensure the GTM container JSON file is properly added to your Xcode project and included in the app bundle. 2. **Build errors**: Make sure you’ve run `npx cap sync` after installation. ### Android Issues 1. **Container not found**: Verify the container file is in the correct location: `android/app/src/main/assets/containers/GTM-XXXXXX.json` 2. **Initialization failures**: Check that the container ID matches your GTM container exactly. ### General Issues 1. **Events not appearing in GTM**: Remember that GTM has a delay in showing real-time events. Also ensure your GTM container is published. 2. **Values returning null**: Make sure the keys exist in your GTM container configuration. ## License MIT # @capgo/home-indicator > Hide or show the home indicator on iOS devices to create truly immersive full-screen experiences in your app. iOS home indicator control Full control over the home indicator visibility 📱 Immersive experiences Create full-screen experiences without distractions 🎮 Auto-hide support Configure auto-hide behavior for seamless UX ✨ Comprehensive Documentation Check the [Documentation](/docs/plugins/home-indicator/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and configure the Capacitor Home Indicator plugin to control the home indicator on iOS devices. 1. **Install the package** * npm ```sh npm i @capgo/home-indicator ``` * pnpm ```sh pnpm add @capgo/home-indicator ``` * yarn ```sh yarn add @capgo/home-indicator ``` * bun ```sh bun add @capgo/home-indicator ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` 3. **Configure the plugin** **Hide Home Indicator:** ```typescript import { HomeIndicator } from '@capgo/home-indicator'; // Hide the home indicator await HomeIndicator.hide(); ``` **Show Home Indicator:** ```typescript // Show the home indicator await HomeIndicator.show(); // Check visibility status const { hidden } = await HomeIndicator.isHidden(); console.log('Is hidden:', hidden); ``` * iOS No additional setup required. The plugin only works on iOS devices with a home indicator (iPhone X and later). * Android This plugin has no effect on Android devices as they don’t have an iOS-style home indicator. 4. **Auto-hide configuration** ```typescript import { HomeIndicator } from '@capgo/home-indicator'; // Configure auto-hide behavior await HomeIndicator.setAutoHidden({ autoHidden: true // Enable auto-hide }); // The home indicator will automatically hide after a few seconds // and reappear when the user touches the screen ``` 5. **Advanced usage** ```typescript import { HomeIndicator } from '@capgo/home-indicator'; import { App } from '@capacitor/app'; export class ImmersiveMode { private isImmersive = false; async enterImmersiveMode() { this.isImmersive = true; // Hide home indicator await HomeIndicator.hide(); // Enable auto-hide for better UX await HomeIndicator.setAutoHidden({ autoHidden: true }); // Hide status bar for full immersion // StatusBar.hide(); // If using @capacitor/status-bar } async exitImmersiveMode() { this.isImmersive = false; // Show home indicator await HomeIndicator.show(); // Disable auto-hide await HomeIndicator.setAutoHidden({ autoHidden: false }); // Show status bar // StatusBar.show(); // If using @capacitor/status-bar } async toggleImmersiveMode() { const { hidden } = await HomeIndicator.isHidden(); if (hidden) { await this.exitImmersiveMode(); } else { await this.enterImmersiveMode(); } } setupAppLifecycle() { // Handle app state changes App.addListener('appStateChange', async ({ isActive }) => { if (!isActive && this.isImmersive) { // App went to background, might want to show indicator await HomeIndicator.show(); } else if (isActive && this.isImmersive) { // App came to foreground, restore immersive mode await HomeIndicator.hide(); } }); } } ``` ## API Reference ### Methods #### `hide()` Hide the home indicator. **Returns:** `Promise` #### `show()` Show the home indicator. **Returns:** `Promise` #### `isHidden()` Check if the home indicator is currently hidden. **Returns:** `Promise<{ hidden: boolean }>` #### `setAutoHidden(options: { autoHidden: boolean })` Configure auto-hide behavior for the home indicator. **Parameters:** * `options.autoHidden`: boolean - Enable or disable auto-hide **Returns:** `Promise` ### Interfaces ```typescript interface AutoHiddenOptions { autoHidden: boolean; } interface HiddenResult { hidden: boolean; } ``` ## Platform Notes ### iOS * Only works on devices with home indicator (iPhone X and later) * Requires iOS 11.0 or later * Auto-hide makes the indicator translucent and hides after inactivity * The indicator reappears when users swipe from the bottom ### Android * This plugin has no effect on Android * Android uses different navigation gestures/buttons ## Common Use Cases 1. **Games**: Full-screen gaming without distractions 2. **Video Players**: Immersive video playback 3. **Photo Viewers**: Full-screen photo galleries 4. **Presentations**: Distraction-free presentations 5. **Kiosk Apps**: Public display applications ## Best Practices 1. **User Control**: Always provide a way to exit immersive mode ```typescript // Add a gesture or button to toggle immersive mode const toggleButton = document.getElementById('toggle-immersive'); toggleButton.addEventListener('click', () => { immersiveMode.toggleImmersiveMode(); }); ``` 2. **Auto-Hide for Games**: Use auto-hide for better gaming experience ```typescript // For games, auto-hide provides the best balance await HomeIndicator.setAutoHidden({ autoHidden: true }); ``` 3. **Respect System Gestures**: Don’t interfere with system navigation 4. **Save State**: Remember user’s preference for immersive mode ## Troubleshooting **Home indicator not hiding:** * Verify the device has a home indicator (iPhone X+) * Check iOS version is 11.0 or higher * Ensure the app has focus **Auto-hide not working:** * Auto-hide requires user interaction to activate * The indicator becomes translucent, not completely hidden **Indicator reappears unexpectedly:** * This is normal iOS behavior for system gestures * Use auto-hide for less intrusive behavior # @capgo/inappbrowser > Open web content in your app with a fully-featured in-app browser that supports URL change events and navigation controls. URL change events Track navigation with URL change event listeners 🔗 Full navigation control Back, forward, reload, and close controls 🎮 Customizable UI Toolbar color, buttons, and display options 🎨 Comprehensive Documentation Check the [Documentation](/docs/plugins/inappbrowser/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and use the InAppBrowser plugin with URL change events for embedded web content in your Capacitor app. 1. **Install the package** * npm ```sh npm i @capgo/inappbrowser ``` * pnpm ```sh pnpm add @capgo/inappbrowser ``` * yarn ```sh yarn add @capgo/inappbrowser ``` * bun ```sh bun add @capgo/inappbrowser ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` ## Usage Import the plugin and use its methods to open web content: ```typescript import { InAppBrowser } from '@capgo/inappbrowser'; // Open a URL const openBrowser = async () => { await InAppBrowser.open({ url: 'https://capgo.app', showTitle: true, toolbarColor: '#000000', showToolbar: true, showReload: true }); }; // Listen for URL changes const setupListeners = async () => { // URL change event await InAppBrowser.addListener('urlChangeEvent', (event) => { console.log('URL changed to:', event.url); // Handle OAuth callbacks if (event.url.startsWith('myapp://oauth-callback')) { InAppBrowser.close(); // Process OAuth response } }); // Browser closed event await InAppBrowser.addListener('closeEvent', () => { console.log('Browser closed'); }); // Browser opened event await InAppBrowser.addListener('openEvent', () => { console.log('Browser opened'); }); }; // Close the browser const closeBrowser = async () => { await InAppBrowser.close(); }; // Reload current page const reloadPage = async () => { await InAppBrowser.reload(); }; // Navigate to a new URL const navigateTo = async (url: string) => { await InAppBrowser.openWebView({ url }); }; ``` ## API Reference ### open(options) Opens a URL in the in-app browser. ```typescript interface OpenOptions { url: string; showTitle?: boolean; toolbarColor?: string; showToolbar?: boolean; showReload?: boolean; closeButtonText?: string; closeButtonColor?: string; presentationStyle?: 'fullscreen' | 'popover'; transitionStyle?: 'coververtical' | 'crossdissolve' | 'fliphorizontal'; enableBarsCollapsing?: boolean; } await InAppBrowser.open({ url: 'https://example.com', showTitle: true, toolbarColor: '#1976d2', showToolbar: true }); ``` ### close() Closes the in-app browser. ```typescript await InAppBrowser.close(); ``` ### reload() Reloads the current page. ```typescript await InAppBrowser.reload(); ``` ### openWebView(options) Navigates to a new URL in the already open browser. ```typescript interface OpenWebViewOptions { url: string; } await InAppBrowser.openWebView({ url: 'https://new-page.com' }); ``` ### goBack() Navigates back in the browser history. ```typescript await InAppBrowser.goBack(); ``` ### goForward() Navigates forward in the browser history. ```typescript await InAppBrowser.goForward(); ``` ## Events ### urlChangeEvent Fired when the URL changes in the browser. ```typescript interface UrlChangeEvent { url: string; } InAppBrowser.addListener('urlChangeEvent', (event) => { console.log('New URL:', event.url); }); ``` ### closeEvent Fired when the browser is closed. ```typescript InAppBrowser.addListener('closeEvent', () => { console.log('Browser closed'); }); ``` ### openEvent Fired when the browser is opened. ```typescript InAppBrowser.addListener('openEvent', () => { console.log('Browser opened'); }); ``` ## Advanced Usage ### OAuth Flow Implementation ```typescript import { InAppBrowser } from '@capgo/inappbrowser'; export class OAuthService { private listeners: any[] = []; async authenticate(authUrl: string, redirectUri: string) { return new Promise((resolve, reject) => { // Listen for URL changes const urlListener = InAppBrowser.addListener('urlChangeEvent', (event) => { if (event.url.startsWith(redirectUri)) { // Extract OAuth code/token from URL const url = new URL(event.url); const code = url.searchParams.get('code'); if (code) { InAppBrowser.close(); resolve(code); } else { const error = url.searchParams.get('error'); reject(new Error(error || 'OAuth failed')); } } }); this.listeners.push(urlListener); // Open OAuth provider InAppBrowser.open({ url: authUrl, showTitle: true, toolbarColor: '#1976d2' }); }); } cleanup() { this.listeners.forEach(listener => listener.remove()); this.listeners = []; } } ``` ### Custom Browser UI ```typescript const openCustomBrowser = async () => { await InAppBrowser.open({ url: 'https://example.com', showTitle: true, toolbarColor: '#FF5722', showToolbar: true, showReload: true, closeButtonText: 'Done', closeButtonColor: '#FFFFFF', presentationStyle: 'fullscreen', transitionStyle: 'coververtical', enableBarsCollapsing: true }); }; ``` ### Handling External Links ```typescript import { InAppBrowser } from '@capgo/inappbrowser'; export class LinkHandler { async openExternalLink(url: string) { // Check if URL should open in browser if (this.shouldOpenInBrowser(url)) { await InAppBrowser.open({ url, showTitle: true, showToolbar: true }); } else { // Handle internally window.location.href = url; } } private shouldOpenInBrowser(url: string): boolean { // External domains const externalDomains = ['youtube.com', 'twitter.com', 'facebook.com']; const urlDomain = new URL(url).hostname; return externalDomains.some(domain => urlDomain.includes(domain)); } } ``` ## Best Practices 1. **Always remove listeners** ```typescript const listener = await InAppBrowser.addListener('urlChangeEvent', handler); // When done listener.remove(); ``` 2. **Handle browser states** ```typescript let browserOpen = false; InAppBrowser.addListener('openEvent', () => { browserOpen = true; }); InAppBrowser.addListener('closeEvent', () => { browserOpen = false; }); ``` 3. **Validate URLs before opening** ```typescript const isValidUrl = (url: string): boolean => { try { new URL(url); return true; } catch { return false; } }; if (isValidUrl(url)) { await InAppBrowser.open({ url }); } ``` 4. **Customize for platform** ```typescript import { Capacitor } from '@capacitor/core'; const options = { url: 'https://example.com', showTitle: true, toolbarColor: Capacitor.getPlatform() === 'ios' ? '#007AFF' : '#1976D2' }; ``` ## Platform Notes ### iOS * Uses `SFSafariViewController` * Supports iOS 11.0+ * Respects Safe Area insets * Supports custom presentation styles ### Android * Uses Chrome Custom Tabs * Falls back to WebView if Chrome not available * Supports Android 5.0 (API 21)+ * Toolbar customization supported ### Web * Opens in new browser tab/window * Limited customization options * No URL change events # @capgo/capacitor-is-root > Detect rooted Android devices and jailbroken iOS devices to enhance app security and protect sensitive data. ## Overview The Capacitor Is Root plugin provides comprehensive root and jailbreak detection for Android devices and emulator detection. This plugin helps enhance app security by identifying compromised devices and emulated environments that may pose security risks. Root detection Advanced Android root detection with multiple methods 🔒 Emulator detection Identify emulated environments and testing frameworks 🛡️ Security validation Multiple detection techniques for enhanced accuracy ✅ Android focused Specialized detection for Android security assessment 🤖 ## Installation ```bash npm install @capgo/capacitor-is-root npx cap sync ``` ## Core API Methods ### Root Detection * `isRooted()` - Performs comprehensive root detection using default methods * `isRootedWithBusyBox()` - Extended detection including BusyBox checks * `detectRootManagementApps()` - Identifies installed root management applications * `checkForSuBinary()` - Checks for `su` binary presence in system paths ### Emulator Detection * `isRunningOnEmulator()` - Detects common Android emulator fingerprints ## Detection Techniques The plugin employs multiple detection methods: ### Root Detection * Checks for root management applications (SuperSU, Magisk, etc.) * Scans for suspicious system properties * Identifies test build tags and debug flags * Validates dangerous binary locations * Examines system path permissions ### Emulator Detection * Hardware fingerprint analysis * Build property inspection * Emulator-specific characteristics * Virtual environment indicators ## Usage Example ```typescript import { IsRoot } from '@capgo/capacitor-is-root'; // Basic root detection const rootResult = await IsRoot.isRooted(); if (rootResult.isRooted) { console.log('Device is rooted'); // Handle rooted device appropriately } // Extended root detection with BusyBox const extendedResult = await IsRoot.isRootedWithBusyBox(); if (extendedResult.isRooted) { console.log('Device is rooted (extended check)'); } // Check for emulator const emulatorResult = await IsRoot.isRunningOnEmulator(); if (emulatorResult.isEmulator) { console.log('Running on emulator'); } // Detect root management apps const rootAppsResult = await IsRoot.detectRootManagementApps(); if (rootAppsResult.hasRootApps) { console.log('Root management apps detected'); } ``` ## Security Considerations * Use multiple detection methods for higher accuracy * Implement graceful degradation for detected environments * Consider user privacy when implementing security measures * Regular updates recommended as detection methods evolve ## Documentation Check the [complete documentation](/docs/plugins/is-root/getting-started/) for detailed implementation guides and advanced security patterns. # @capgo/ivs-player > Integrate Amazon IVS player for ultra-low latency live streaming with interactive features in your Capacitor apps. Low-latency streaming Stream with sub-second latency using Amazon IVS 📡 Interactive features Support for timed metadata and viewer interactions 💬 Quality adaptation Automatic quality switching based on network conditions 📶 Comprehensive Documentation Check the [Documentation](/docs/plugins/ivs-player/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and configure the Capacitor IVS Player plugin to integrate Amazon IVS low-latency streaming in your app. 1. **Install the package** * npm ```sh npm i @capgo/ivs-player ``` * pnpm ```sh pnpm add @capgo/ivs-player ``` * yarn ```sh yarn add @capgo/ivs-player ``` * bun ```sh bun add @capgo/ivs-player ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` 3. **Configure the plugin** **Basic Player Setup:** ```typescript import { IvsPlayer } from '@capgo/ivs-player'; // Create a player const { playerId } = await IvsPlayer.create({ url: 'https://your-ivs-playback-url.m3u8', autoplay: true }); // Start playback await IvsPlayer.play({ playerId }); ``` **Player Controls:** ```typescript // Pause playback await IvsPlayer.pause({ playerId }); // Set volume await IvsPlayer.setVolume({ playerId, volume: 0.5 // 0.0 to 1.0 }); // Seek to position await IvsPlayer.seekTo({ playerId, position: 30 // seconds }); ``` * iOS Add to your `Info.plist`: ```xml NSAppTransportSecurity NSAllowsArbitraryLoads ``` * Android Add to your `AndroidManifest.xml`: ```xml ``` 4. **Event handling** ```typescript import { IvsPlayer } from '@capgo/ivs-player'; // Listen for player events IvsPlayer.addListener('onState', (event) => { console.log('Player state:', event.state); // States: idle, buffering, ready, playing, ended }); IvsPlayer.addListener('onError', (event) => { console.error('Player error:', event.error); }); IvsPlayer.addListener('onDuration', (event) => { console.log('Video duration:', event.duration); }); IvsPlayer.addListener('onProgress', (event) => { console.log('Current position:', event.position); }); // Listen for timed metadata IvsPlayer.addListener('onMetadata', (event) => { console.log('Timed metadata:', event.metadata); }); ``` 5. **Advanced usage** ```typescript import { IvsPlayer } from '@capgo/ivs-player'; export class StreamPlayer { private playerId: string | null = null; private listeners: any[] = []; async initialize(streamUrl: string) { // Create player with custom configuration const result = await IvsPlayer.create({ url: streamUrl, autoplay: false, muted: true, // Start muted for autoplay policies controls: true }); this.playerId = result.playerId; this.setupEventListeners(); } private setupEventListeners() { // State changes const stateListener = IvsPlayer.addListener('onState', (event) => { this.handleStateChange(event.state); }); this.listeners.push(stateListener); // Quality changes const qualityListener = IvsPlayer.addListener('onQuality', (event) => { console.log(`Quality changed to: ${event.quality.name}`); }); this.listeners.push(qualityListener); // Buffer updates const bufferListener = IvsPlayer.addListener('onBuffer', (event) => { console.log(`Buffer: ${event.percentage}%`); }); this.listeners.push(bufferListener); } private handleStateChange(state: string) { switch (state) { case 'playing': console.log('Stream is playing'); break; case 'buffering': console.log('Stream is buffering'); break; case 'ended': console.log('Stream ended'); break; } } async play() { if (this.playerId) { await IvsPlayer.play({ playerId: this.playerId }); } } async pause() { if (this.playerId) { await IvsPlayer.pause({ playerId: this.playerId }); } } async setQuality(qualityName: string) { if (this.playerId) { await IvsPlayer.setQuality({ playerId: this.playerId, quality: qualityName }); } } async destroy() { // Remove listeners this.listeners.forEach(listener => listener.remove()); // Destroy player if (this.playerId) { await IvsPlayer.destroy({ playerId: this.playerId }); } } } ``` ## API Reference ### Methods #### `create(options: CreateOptions)` Create a new IVS player instance. **Parameters:** * `options`: Player configuration * `url`: string - IVS playback URL * `autoplay`: boolean - Auto-start playback * `muted`: boolean - Start muted * `controls`: boolean - Show native controls **Returns:** `Promise<{ playerId: string }>` #### `play(options: PlayerOptions)` Start playback. #### `pause(options: PlayerOptions)` Pause playback. #### `stop(options: PlayerOptions)` Stop playback and reset position. #### `seekTo(options: SeekOptions)` Seek to a specific position. #### `setVolume(options: VolumeOptions)` Set player volume (0.0 to 1.0). #### `setQuality(options: QualityOptions)` Set playback quality. #### `destroy(options: PlayerOptions)` Destroy the player instance. ### Events * `onState`: Player state changes * `onError`: Playback errors * `onDuration`: Video duration available * `onProgress`: Playback progress updates * `onQuality`: Quality changes * `onMetadata`: Timed metadata events * `onBuffer`: Buffer status updates ### Interfaces ```typescript interface CreateOptions { url: string; autoplay?: boolean; muted?: boolean; controls?: boolean; } interface PlayerOptions { playerId: string; } interface SeekOptions extends PlayerOptions { position: number; // seconds } interface VolumeOptions extends PlayerOptions { volume: number; // 0.0 to 1.0 } interface QualityOptions extends PlayerOptions { quality: string; // quality name } ``` ## Platform Notes ### iOS * Requires iOS 12.0 or later * Uses native AVPlayer with IVS extensions * Supports Picture-in-Picture on iPads ### Android * Requires Android 5.0 (API level 21) or later * Uses Amazon IVS Player SDK * Hardware acceleration recommended ## Common Use Cases 1. **Live Streaming**: Real-time events, sports, gaming 2. **Interactive Streaming**: Viewer polls, Q\&A sessions 3. **E-commerce**: Live shopping with product highlights 4. **Education**: Live classes with timed content 5. **Entertainment**: Concerts, shows with audience interaction ## Best Practices 1. **Network Handling**: Monitor connection quality ```typescript IvsPlayer.addListener('onError', (event) => { if (event.error.includes('network')) { // Handle network errors showRetryButton(); } }); ``` 2. **Resource Management**: Always destroy players when done 3. **Autoplay Policies**: Start muted for reliable autoplay 4. **Quality Selection**: Let IVS handle automatic quality switching ## Troubleshooting **Stream not playing:** * Verify the IVS playback URL is valid * Check network permissions * Ensure the stream is live **High latency:** * IVS is optimized for low latency, check your encoder settings * Verify you’re using the IVS-specific playback URL **Quality issues:** * Allow automatic quality switching * Check network bandwidth requirements # @capgo/capacitor-jw-player > JW Player integration plugin for Capacitor apps with video streaming, playlists, and comprehensive player controls # @capgo/capacitor-jw-player > **WIP: Do not use it yet, it’s in development** Play videos from jwplayer.com with a fullscreen player interface. The plugin provides a comprehensive API for controlling JW Player playback, playlists, and tracks. ## Key Features * Always fullscreen player * Supports both single videos and playlists * Complete control over playback (play, pause, seek, etc.) * Audio track selection * Caption/subtitle support * Event listeners for player state changes ## Installation * npm ```bash npm install @capgo/capacitor-jw-player npx cap sync ``` * yarn ```bash yarn add @capgo/capacitor-jw-player npx cap sync ``` * pnpm ```bash pnpm add @capgo/capacitor-jw-player npx cap sync ``` * bun ```bash bun add @capgo/capacitor-jw-player npx cap sync ``` ## Android Configuration Edit `build.gradle` in order for the plugin to work: ```kotlin allprojects { repositories { google() mavenCentral() maven { url 'https://mvn.jwplayer.com/content/repositories/releases/' } } } ``` ## Usage Examples ### Basic Setup and Playback ```typescript import { JwPlayer } from '@capgo/capacitor-jw-player'; // Initialize the player with your license key await JwPlayer.initialize({ licenseKey: 'YOUR_JW_PLAYER_LICENSE_KEY' }); // Play a video await JwPlayer.play({ mediaUrl: 'https://example.com/video.mp4', mediaType: 'video' }); // Play a playlist await JwPlayer.play({ mediaUrl: 'https://cdn.jwplayer.com/v2/playlists/PLAYLIST_ID', mediaType: 'playlist' }); ``` ### Playback Controls ```typescript // Pause playback await JwPlayer.pause(); // Resume playback // Note: No need to call play() again with the URL, it resumes current content await JwPlayer.play(); // Seek to a specific position (in seconds) await JwPlayer.seekTo({ time: 30 }); // Set volume (0.0 to 1.0) await JwPlayer.setVolume({ volume: 0.5 }); // Change playback speed await JwPlayer.setSpeed({ speed: 1.5 }); // Stop and release the player await JwPlayer.stop(); ``` ### Working with Playlists ```typescript // Load a playlist by URL await JwPlayer.loadPlaylist({ playlistUrl: 'https://cdn.jwplayer.com/v2/playlists/PLAYLIST_ID' }); // Load a playlist with custom items await JwPlayer.loadPlaylistWithItems({ playlist: [ { file: 'https://example.com/video1.mp4', title: 'Video 1' }, { file: 'https://example.com/video2.mp4', title: 'Video 2' } ] }); // Jump to a specific item in the playlist await JwPlayer.setPlaylistIndex({ index: 2 }); // Get information about the current playlist const playlistInfo = await JwPlayer.currentPlaylist(); console.log(playlistInfo.playlist); ``` ### Audio and Caption Tracks ```typescript // Get available audio tracks const { tracks } = await JwPlayer.getAudioTracks(); console.log('Available audio tracks:', tracks); // Get current audio track const { index } = await JwPlayer.getCurrentAudioTrack(); console.log('Current audio track index:', index); // Set audio track await JwPlayer.setCurrentAudioTrack({ index: 1 }); // Get available captions const { captions } = await JwPlayer.getCaptions(); console.log('Available captions:', captions); // Set captions track (0 is usually "Off") await JwPlayer.setCurrentCaptions({ index: 1 }); ``` ### Event Listeners ```typescript import { JwPlayer } from '@capgo/capacitor-jw-player'; // Listen for player ready event JwPlayer.addListener('ready', () => { console.log('Player is ready'); }); // Listen for playback state changes JwPlayer.addListener('play', () => { console.log('Playback started'); }); JwPlayer.addListener('pause', (data) => { console.log('Playback paused, reason:', data.reason); }); JwPlayer.addListener('complete', () => { console.log('Playback completed'); }); // Listen for time updates JwPlayer.addListener('time', (data) => { console.log(`Position: ${data.position}, Duration: ${data.duration}`); }); // Listen for playlist changes JwPlayer.addListener('playlist', (data) => { console.log(`Playlist loaded with ${data.playlistSize} items`); }); JwPlayer.addListener('playlistItem', (data) => { console.log(`Now playing item at index ${data.index}`); }); // Listen for errors JwPlayer.addListener('error', (data) => { console.error('Player error:', data.message); }); // Clean up listeners when done function cleanup() { JwPlayer.removeAllListeners(); } ``` ## API ### initialize(…) ```typescript initialize(options: { licenseKey: string; playerUrl?: string; }) => Promise ``` Initialize the JW Player | Param | Type | Description | | ------------- | --------------------------------------------- | ----------------------------- | | **`options`** | `{ licenseKey: string; playerUrl?: string; }` | The options for the JW Player | ### play(…) ```typescript play(options: { mediaUrl: string; mediaType: 'video' | 'playlist'; autostart?: boolean; }) => Promise ``` Play a video | Param | Type | Description | | ------------- | ------------------------------------------------------------------------------ | ----------------------------- | | **`options`** | `{ mediaUrl: string; mediaType: 'video' \| 'playlist'; autostart?: boolean; }` | The options for the JW Player | ### pause() ```typescript pause() => Promise ``` Pause the currently playing media ### resume() ```typescript resume() => Promise ``` Resume the currently paused media ### stop() ```typescript stop() => Promise ``` Stop the currently playing media ### seekTo(…) ```typescript seekTo(options: { time: number; }) => Promise ``` Seek to a specific position in the currently playing media | Param | Type | Description | | ------------- | ------------------- | ------------------- | | **`options`** | `{ time: number; }` | Options for seeking | ### setVolume(…) ```typescript setVolume(options: { volume: number; }) => Promise ``` Set the volume level | Param | Type | Description | | ------------- | --------------------- | -------------------------- | | **`options`** | `{ volume: number; }` | Options for setting volume | ### getPosition() ```typescript getPosition() => Promise<{ position: number; }> ``` Get the current position in the media **Returns:** `Promise<{ position: number; }>` ### getState() ```typescript getState() => Promise<{ state: number; }> ``` Get the current player state **Returns:** `Promise<{ state: number; }>` ### setSpeed(…) ```typescript setSpeed(options: { speed: number; }) => Promise ``` Set the playback speed | Param | Type | Description | | ------------- | -------------------- | ------------------------- | | **`options`** | `{ speed: number; }` | Options for setting speed | ### setPlaylistIndex(…) ```typescript setPlaylistIndex(options: { index: number; }) => Promise ``` Set the current item in the playlist by index | Param | Type | Description | | ------------- | -------------------- | --------------------------------- | | **`options`** | `{ index: number; }` | Options for setting playlist item | ### loadPlaylist(…) ```typescript loadPlaylist(options: { playlistUrl: string; }) => Promise ``` Load a playlist | Param | Type | Description | | ------------- | -------------------------- | ------------------------------ | | **`options`** | `{ playlistUrl: string; }` | Options for loading a playlist | ### loadPlaylistWithItems(…) ```typescript loadPlaylistWithItems(options: { playlist: any[]; }) => Promise ``` Load a playlist with items | Param | Type | Description | | ------------- | ---------------------- | ------------------------------ | | **`options`** | `{ playlist: any[]; }` | Options for loading a playlist | ### getAudioTracks() ```typescript getAudioTracks() => Promise<{ tracks: any[]; }> ``` Get available audio tracks **Returns:** `Promise<{ tracks: any[]; }>` ### getCurrentAudioTrack() ```typescript getCurrentAudioTrack() => Promise<{ index: number; }> ``` Get the current audio track **Returns:** `Promise<{ index: number; }>` ### setCurrentAudioTrack(…) ```typescript setCurrentAudioTrack(options: { index: number; }) => Promise ``` Set the current audio track | Param | Type | Description | | ------------- | -------------------- | ------------------------------- | | **`options`** | `{ index: number; }` | Options for setting audio track | ### getCaptions() ```typescript getCaptions() => Promise<{ captions: any[]; }> ``` Get the available captions/subtitles **Returns:** `Promise<{ captions: any[]; }>` ### getCurrentCaptions() ```typescript getCurrentCaptions() => Promise<{ index: number; }> ``` Get the current captions/subtitles track **Returns:** `Promise<{ index: number; }>` ### setCurrentCaptions(…) ```typescript setCurrentCaptions(options: { index: number; }) => Promise ``` Set the current captions/subtitles track | Param | Type | Description | | ------------- | -------------------- | ---------------------------------- | | **`options`** | `{ index: number; }` | Options for setting captions track | ### currentPlaylist() ```typescript currentPlaylist() => Promise ``` Get the current playlist **Returns:** `Promise` ## Event Listeners The plugin emits the following events that you can listen for: | Event | Description | Data | | ----------------- | ---------------------------------------- | ------------------------------------------------ | | `ready` | Player is ready to use | None | | `play` | Playback has started | None | | `pause` | Playback is paused | `{ reason: number }` | | `complete` | Playback of the current item is complete | None | | `time` | Playback time has updated | `{ position: number, duration: number }` | | `setupError` | Error during setup | `{ code: number, message: string }` | | `error` | General playback error | `{ code: number, message: string }` | | `warning` | Player warning | `{ code: number, message: string }` | | `playlist` | Playlist has been loaded | `{ playlistSize: number }` | | `playlistItem` | Current playlist item has changed | `{ index: number, file: string, title: string }` | | `playerDismissed` | Player has been closed/dismissed | None | # @capgo/capacitor-launch-navigator > Launch navigation apps with turn-by-turn directions, supporting multiple map providers and custom routing options. ## Overview The Capacitor Launch Navigator plugin enables launching native navigation apps on iOS and Android devices with coordinate-based navigation. This plugin provides seamless integration with popular mapping applications and supports multiple transportation modes for comprehensive navigation solutions. Multi-app support Google Maps, Apple Maps, Waze, Citymapper and more 🗺️ Transport modes Driving, walking, transit, and cycling directions 🧭 App detection Check availability and list installed navigation apps 🔍 Coordinate-based Navigate using latitude/longitude coordinates 📍 ## Installation ```bash npm install @capgo/capacitor-launch-navigator npx cap sync ``` ## iOS Configuration Add URL schemes to your `Info.plist` to detect installed navigation apps: ```xml LSApplicationQueriesSchemes googlemaps waze citymapper ``` ## Core API Methods ### Navigation * `navigate(options)` - Launch navigation to specified coordinates * `isAppAvailable(options)` - Check if a specific navigation app is installed * `getAvailableApps()` - List all available navigation apps on device * `getSupportedApps()` - Get all supported apps for current platform ## Usage Example ```typescript import { LaunchNavigator, TransportMode } from '@capgo/capacitor-launch-navigator'; // Basic navigation to coordinates await LaunchNavigator.navigate({ destination: [37.7749, -122.4194], // San Francisco coordinates }); // Advanced navigation with options await LaunchNavigator.navigate({ destination: [37.7749, -122.4194], options: { start: [37.7849, -122.4094], // Optional starting point transportMode: TransportMode.DRIVING, app: 'google_maps', // Preferred navigation app appDisplayName: 'Google Maps' } }); // Check if specific app is available const result = await LaunchNavigator.isAppAvailable({ app: 'google_maps' }); if (result.available) { console.log('Google Maps is installed'); } else { console.log('Google Maps is not available'); } // Get all available navigation apps const availableApps = await LaunchNavigator.getAvailableApps(); console.log('Available navigation apps:', availableApps); // Get all supported apps for platform const supportedApps = await LaunchNavigator.getSupportedApps(); console.log('Supported apps:', supportedApps); ``` ## Navigation Options ```typescript interface NavigationOptions { start?: [number, number]; // Starting coordinates [lat, lng] transportMode?: TransportMode; // Transportation method app?: string; // Preferred navigation app appDisplayName?: string; // Display name for app launchMode?: LaunchMode; // How to launch the app } ``` ## Transport Modes ```typescript enum TransportMode { DRIVING = 'driving', WALKING = 'walking', TRANSIT = 'transit', CYCLING = 'cycling' } ``` ## Supported Navigation Apps ### iOS * Apple Maps (built-in) * Google Maps * Waze * Citymapper * Transit * Moovit * Uber * Lyft * And many more… ### Android * Google Maps (built-in) * Waze * Citymapper * HERE WeGo * Sygic * MapQuest * Moovit * And many more… ## Coordinate Requirements > ⚠️ **Important**: This plugin only accepts latitude/longitude coordinates for navigation. Use [@capgo/capacitor-nativegeocoder](https://github.com/Cap-go/capacitor-nativegeocoder) to convert addresses to coordinates. ```typescript // Example with geocoding import { NativeGeocoder } from '@capgo/capacitor-nativegeocoder'; // Convert address to coordinates const geocodeResult = await NativeGeocoder.forwardGeocode({ address: '1600 Amphitheatre Parkway, Mountain View, CA' }); if (geocodeResult.results.length > 0) { const coords = geocodeResult.results[0]; // Launch navigation with geocoded coordinates await LaunchNavigator.navigate({ destination: [coords.latitude, coords.longitude] }); } ``` ## App Detection and Selection ```typescript // Check multiple apps and use the first available const appsToCheck = ['google_maps', 'waze', 'apple_maps']; let selectedApp = null; for (const app of appsToCheck) { const result = await LaunchNavigator.isAppAvailable({ app }); if (result.available) { selectedApp = app; break; } } if (selectedApp) { await LaunchNavigator.navigate({ destination: [37.7749, -122.4194], options: { app: selectedApp } }); } else { console.log('No supported navigation apps found'); } ``` ## Error Handling ```typescript try { await LaunchNavigator.navigate({ destination: [37.7749, -122.4194], options: { app: 'google_maps', transportMode: TransportMode.DRIVING } }); } catch (error) { console.error('Navigation failed:', error); // Handle error - app not available, invalid coordinates, etc. } ``` ## Use Cases * **Location-based services**: Navigate users to points of interest * **Delivery apps**: Guide drivers to delivery locations * **Event apps**: Direct attendees to venue locations * **Real estate apps**: Navigate to property locations * **Travel apps**: Guide tourists to attractions ## Best Practices * Always check app availability before attempting navigation * Provide fallback options when preferred apps aren’t available * Use meaningful app display names for user selection * Handle errors gracefully with user-friendly messages * Consider user preferences for default navigation apps ## Documentation Check the [complete documentation](/docs/plugins/launch-navigator/getting-started/) for detailed implementation guides and advanced navigation patterns. # Capacitor LLM Plugin > Run LLM models locally in iOS and Android with Apple Intelligence support # Capacitor LLM Plugin Capacitor SDK to run LLM models locally in iOS and Android, with native Apple Intelligence support. ## Features * 🤖 Run LLM models directly on device for privacy and offline capabilities * 🍎 Native Apple Intelligence integration on iOS 18.0+ * 🤖 MediaPipe tasks-genai support on Android * 📦 Support for multiple model formats (`.gguf`, `.task`, `.litertlm`) * ⚡ Hardware acceleration for fast inference * 💾 Model download and caching support * 🔄 Real-time streaming responses ## Installation * npm ```bash npm install @capgo/capacitor-llm npx cap sync ``` * yarn ```bash yarn add @capgo/capacitor-llm npx cap sync ``` * pnpm ```bash pnpm add @capgo/capacitor-llm npx cap sync ``` * bun ```bash bun add @capgo/capacitor-llm npx cap sync ``` ## Platform Configuration ### iOS Configuration * **iOS 18.0+**: Uses Apple Intelligence by default (no model needed) * **iOS < 18.0**: Requires MediaPipe custom models (experimental) ### Android Configuration Place model files in your Android assets folder: * Path: `android/app/src/main/assets/` * Supported formats: `.task`, `.litertlm` ## Recommended Models ### Gemma-3 Models (Best Performance) * **270M** - Smallest, most efficient for mobile * **1B** - Larger text generation model * **2B** - Cross-platform experimental ## Usage ```typescript import { CapacitorLLM } from '@capgo/capacitor-llm'; import { Capacitor } from '@capacitor/core'; // Check if LLM is ready const { readiness } = await CapacitorLLM.getReadiness(); console.log('LLM readiness:', readiness); // Set the model path based on platform await CapacitorLLM.setModelPath({ path: Capacitor.getPlatform() === 'ios' ? 'gemma-3-270m.gguf' // iOS model : '/android_asset/gemma-3-270m-it-int8.task' // Android model }); // Create a chat session const { id: chatId } = await CapacitorLLM.createChat(); // Send a message await CapacitorLLM.sendMessage({ chatId, message: 'Hello! How are you today?' }); // Listen for AI responses CapacitorLLM.addListener('onAiText', (event) => { console.log('AI response:', event.text); }); // Listen for completion CapacitorLLM.addListener('onAiCompletion', (event) => { console.log('AI completed response'); }); ``` ## Advanced Features ### Download Models ```typescript // Download a model from URL await CapacitorLLM.downloadModel({ url: 'https://example.com/model.task', filename: 'model.task' }); ``` ### Model Management ```typescript // Set a specific model await CapacitorLLM.setModel({ model: 'gemma-3-1b' }); // Check readiness const { readiness } = await CapacitorLLM.getReadiness(); if (readiness === 'ready') { // Model is loaded and ready } ``` ## API Methods * `createChat()` - Create a new chat session * `sendMessage()` - Send a message to the LLM * `getReadiness()` - Check if the LLM is ready * `setModel()` - Set the active model * `setModelPath()` - Set the path to model file * `downloadModel()` - Download a model from URL ## Events * `onAiText` - Fired when AI generates text * `onAiCompletion` - Fired when AI completes response ## Platform Support | Platform | Supported | Requirements | | -------- | --------- | ---------------------------------------- | | iOS | ✅ | iOS 13.0+ (18.0+ for Apple Intelligence) | | Android | ✅ | API 24+ | | Web | ❌ | Not supported | ## Contributing We welcome contributions! Please see our [Contributing Guide](https://github.com/Cap-go/capacitor-llm/blob/main/CONTRIBUTING.md) for more details. ## License This plugin is licensed under the MIT License. See [LICENSE](https://github.com/Cap-go/capacitor-llm/blob/main/LICENSE) for more information. ## Support If you encounter any issues or have questions, please file an issue on our [GitHub repository](https://github.com/Cap-go/capacitor-llm/issues). # @capgo/capacitor-mute > Check if a device is muted or set to silent mode. Detects mute switch on iOS and volume state on Android. Silent mode detection Detect if device is in silent/mute mode 🔇 Cross-platform Works on both iOS (mute switch) and Android (volume) 📱 Simple API Easy to use with straightforward methods 🎯 Comprehensive Documentation Check the [Documentation](/docs/plugins/mute/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and use the Mute plugin to detect silent mode state in your Capacitor app. 1. **Install the package** * npm ```sh npm i @capgo/capacitor-mute ``` * pnpm ```sh pnpm add @capgo/capacitor-mute ``` * yarn ```sh yarn add @capgo/capacitor-mute ``` * bun ```sh bun add @capgo/capacitor-mute ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` ## Usage Import the plugin and use its methods to check mute state: ```typescript import { CapacitorMute } from '@capgo/capacitor-mute'; // Check if device is muted const checkMuteState = async () => { const { value } = await CapacitorMute.isMuted(); if (value) { console.log('Device is muted/silent'); // Adjust app behavior for silent mode } else { console.log('Device sound is on'); } }; // Listen for mute state changes (iOS only) const listenForChanges = async () => { await CapacitorMute.addListener('muteChanged', (state) => { console.log('Mute state changed:', state.value); updateUIForMuteState(state.value); }); }; // Check if feature is available const checkAvailability = async () => { const { value } = await CapacitorMute.isAvailable(); console.log('Mute detection available:', value); }; ``` ## API Reference ### isMuted() Checks if the device is currently muted/in silent mode. ```typescript const result = await CapacitorMute.isMuted(); // Returns: { value: boolean } ``` ### isAvailable() Checks if mute detection is available on the device. ```typescript const result = await CapacitorMute.isAvailable(); // Returns: { value: boolean } ``` ## Events ### muteChanged Fired when the mute state changes (iOS only). ```typescript interface MuteChangedEvent { value: boolean; } CapacitorMute.addListener('muteChanged', (event) => { console.log('Is muted:', event.value); }); ``` ## Complete Example ```typescript import { CapacitorMute } from '@capgo/capacitor-mute'; export class SoundManager { private isMuted = false; private listener: any; async initialize() { // Check if mute detection is available const { value: isAvailable } = await CapacitorMute.isAvailable(); if (!isAvailable) { console.log('Mute detection not available'); return; } // Get initial mute state await this.checkMuteState(); // Listen for changes (iOS only) this.setupListener(); } async checkMuteState() { try { const { value } = await CapacitorMute.isMuted(); this.isMuted = value; this.updateAppBehavior(); } catch (error) { console.error('Failed to check mute state:', error); } } private setupListener() { this.listener = CapacitorMute.addListener('muteChanged', (event) => { this.isMuted = event.value; this.updateAppBehavior(); }); } private updateAppBehavior() { if (this.isMuted) { // Device is muted - adjust app behavior this.disableSoundEffects(); this.showVisualNotifications(); } else { // Device sound is on this.enableSoundEffects(); this.useAudioNotifications(); } } private disableSoundEffects() { // Disable in-app sounds console.log('Disabling sound effects'); } private enableSoundEffects() { // Enable in-app sounds console.log('Enabling sound effects'); } private showVisualNotifications() { // Use visual feedback instead of audio console.log('Using visual notifications'); } private useAudioNotifications() { // Use audio notifications console.log('Using audio notifications'); } cleanup() { if (this.listener) { this.listener.remove(); } } } // Usage const soundManager = new SoundManager(); await soundManager.initialize(); ``` ## Platform Behavior ### iOS * Detects the physical mute switch state * Provides real-time change events * Works on iPhone and iPad with mute switch ### Android * Checks if ringer mode is set to silent or vibrate * No change events (polling required) * Based on AudioManager ringer mode ## Best Practices 1. **Check availability first** ```typescript const { value } = await CapacitorMute.isAvailable(); if (!value) { // Fallback to default behavior } ``` 2. **Respect user preferences** Always honor the mute state and adjust your app’s audio behavior accordingly. 3. **Provide visual alternatives** ```typescript if (isMuted) { // Show visual notifications showToast('New message received'); } else { // Play sound notification playNotificationSound(); } ``` 4. **Handle platform differences** ```typescript import { Capacitor } from '@capacitor/core'; if (Capacitor.getPlatform() === 'ios') { // Set up change listener CapacitorMute.addListener('muteChanged', handler); } else { // Poll periodically on Android setInterval(checkMuteState, 5000); } ``` ## Use Cases 1. **Game Sound Management** ```typescript const shouldPlaySound = async () => { const { value: isMuted } = await CapacitorMute.isMuted(); return !isMuted && userPreferences.soundEnabled; }; ``` 2. **Notification Handling** ```typescript const sendNotification = async (message: string) => { const { value: isMuted } = await CapacitorMute.isMuted(); if (isMuted) { // Use vibration or visual notification await Haptics.vibrate(); showBanner(message); } else { // Play notification sound await playSound('notification.mp3'); } }; ``` 3. **Video Player** ```typescript const initVideoPlayer = async () => { const { value: isMuted } = await CapacitorMute.isMuted(); videoPlayer.setMuted(isMuted); if (isMuted) { showSubtitles(true); showMuteIndicator(); } }; ``` ## Troubleshooting 1. **Always returns false on Android** * Check if device ringer mode is actually set to silent * Some Android devices may have different behavior 2. **No change events on Android** * This is expected - Android doesn’t provide mute switch events * Implement polling if real-time detection is needed 3. **Not working on simulator** * iOS Simulator doesn’t have a mute switch * Test on real devices for accurate results # @capgo/native-audio > Play audio with native performance, low latency, and concurrent playback. Perfect for games, sound effects, and background music. Low latency Native audio APIs for instant playback 🚀 Concurrent playback Play multiple sounds simultaneously 🎵 Background audio Continue playback when app is in background 🎧 Comprehensive Documentation Check the [Documentation](/docs/plugins/native-audio/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and use the Native Audio plugin for high-performance audio playback in your Capacitor app. 1. **Install the package** * npm ```sh npm i @capgo/native-audio ``` * pnpm ```sh pnpm add @capgo/native-audio ``` * yarn ```sh yarn add @capgo/native-audio ``` * bun ```sh bun add @capgo/native-audio ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` 3. **Add audio files** Place your audio files in the appropriate platform folders: * **iOS**: `ios/App/App/sounds/` * **Android**: `android/app/src/main/res/raw/` ## Usage Import the plugin and preload audio files before playing: ```typescript import { NativeAudio } from '@capgo/native-audio'; // Preload audio files const preloadAudio = async () => { // Simple preload for short sounds await NativeAudio.preload({ assetId: 'click', assetPath: 'sounds/click.mp3', audioChannelNum: 1, isUrl: false }); // Complex preload for music/longer audio await NativeAudio.preloadComplex({ assetId: 'background-music', assetPath: 'sounds/background.mp3', audioChannelNum: 1, volume: 0.5, delay: 0, isUrl: false }); }; // Play audio const playSound = async () => { await NativeAudio.play({ assetId: 'click' }); }; // Play with options const playMusic = async () => { await NativeAudio.play({ assetId: 'background-music', time: 0 // Start from beginning }); }; // Loop audio const loopMusic = async () => { await NativeAudio.loop({ assetId: 'background-music' }); }; // Stop audio const stopMusic = async () => { await NativeAudio.stop({ assetId: 'background-music' }); }; // Unload when done const cleanup = async () => { await NativeAudio.unload({ assetId: 'click' }); await NativeAudio.unload({ assetId: 'background-music' }); }; ``` ## API Reference ### preload(options) Preloads an audio file for simple playback (best for short sounds). ```typescript interface PreloadOptions { assetId: string; assetPath: string; audioChannelNum?: number; isUrl?: boolean; } await NativeAudio.preload({ assetId: 'sound-effect', assetPath: 'sounds/effect.mp3', audioChannelNum: 1, isUrl: false }); ``` ### preloadComplex(options) Preloads audio with advanced options (best for music/background audio). ```typescript interface PreloadComplexOptions { assetId: string; assetPath: string; volume?: number; // 0.0 to 1.0 audioChannelNum?: number; delay?: number; isUrl?: boolean; fadeDuration?: number; } await NativeAudio.preloadComplex({ assetId: 'theme-song', assetPath: 'sounds/theme.mp3', volume: 0.7, audioChannelNum: 2, isUrl: false }); ``` ### play(options) Plays a preloaded audio file. ```typescript interface PlayOptions { assetId: string; time?: number; // Start time in seconds } await NativeAudio.play({ assetId: 'sound-effect', time: 0 }); ``` ### loop(options) Loops a preloaded audio file continuously. ```typescript await NativeAudio.loop({ assetId: 'background-music' }); ``` ### stop(options) Stops playing an audio file. ```typescript await NativeAudio.stop({ assetId: 'background-music' }); ``` ### pause(options) Pauses audio playback. ```typescript await NativeAudio.pause({ assetId: 'background-music' }); ``` ### resume(options) Resumes paused audio. ```typescript await NativeAudio.resume({ assetId: 'background-music' }); ``` ### setVolume(options) Sets the volume for an audio asset. ```typescript interface SetVolumeOptions { assetId: string; volume: number; // 0.0 to 1.0 } await NativeAudio.setVolume({ assetId: 'background-music', volume: 0.3 }); ``` ### getDuration(options) Gets the duration of an audio file in seconds. ```typescript const { duration } = await NativeAudio.getDuration({ assetId: 'background-music' }); console.log(`Duration: ${duration} seconds`); ``` ### getCurrentTime(options) Gets the current playback time in seconds. ```typescript const { currentTime } = await NativeAudio.getCurrentTime({ assetId: 'background-music' }); console.log(`Current time: ${currentTime} seconds`); ``` ### isPlaying(options) Checks if audio is currently playing. ```typescript const { isPlaying } = await NativeAudio.isPlaying({ assetId: 'background-music' }); console.log(`Is playing: ${isPlaying}`); ``` ### unload(options) Unloads an audio file from memory. ```typescript await NativeAudio.unload({ assetId: 'sound-effect' }); ``` ## Advanced Usage ### Sound Manager Class ```typescript import { NativeAudio } from '@capgo/native-audio'; export class SoundManager { private sounds: Map = new Map(); private volume = 1.0; async init() { // Preload all sounds await this.preloadSound('click', 'sounds/click.mp3'); await this.preloadSound('success', 'sounds/success.mp3'); await this.preloadSound('error', 'sounds/error.mp3'); // Preload music await this.preloadMusic('background', 'sounds/background.mp3', 0.5); } private async preloadSound(id: string, path: string) { try { await NativeAudio.preload({ assetId: id, assetPath: path, audioChannelNum: 1, isUrl: false }); this.sounds.set(id, true); } catch (error) { console.error(`Failed to preload ${id}:`, error); } } private async preloadMusic(id: string, path: string, volume: number) { try { await NativeAudio.preloadComplex({ assetId: id, assetPath: path, volume, audioChannelNum: 2, isUrl: false }); this.sounds.set(id, true); } catch (error) { console.error(`Failed to preload ${id}:`, error); } } async playSound(id: string) { if (!this.sounds.has(id)) { console.warn(`Sound ${id} not preloaded`); return; } try { await NativeAudio.play({ assetId: id }); } catch (error) { console.error(`Failed to play ${id}:`, error); } } async playMusic(id: string) { if (!this.sounds.has(id)) return; try { await NativeAudio.loop({ assetId: id }); } catch (error) { console.error(`Failed to play music ${id}:`, error); } } async stopMusic(id: string) { try { await NativeAudio.stop({ assetId: id }); } catch (error) { console.error(`Failed to stop ${id}:`, error); } } async setMasterVolume(volume: number) { this.volume = Math.max(0, Math.min(1, volume)); // Update all loaded sounds for (const [id] of this.sounds) { await NativeAudio.setVolume({ assetId: id, volume: this.volume }); } } async cleanup() { for (const [id] of this.sounds) { await NativeAudio.unload({ assetId: id }); } this.sounds.clear(); } } ``` ### Loading from URLs ```typescript // Load audio from URL await NativeAudio.preloadComplex({ assetId: 'remote-audio', assetPath: 'https://example.com/audio.mp3', isUrl: true, volume: 0.8 }); ``` ### Fade In/Out Effects ```typescript const fadeIn = async (assetId: string, duration: number) => { const steps = 20; const stepDuration = duration / steps; await NativeAudio.setVolume({ assetId, volume: 0 }); await NativeAudio.play({ assetId }); for (let i = 1; i <= steps; i++) { await new Promise(resolve => setTimeout(resolve, stepDuration)); await NativeAudio.setVolume({ assetId, volume: i / steps }); } }; const fadeOut = async (assetId: string, duration: number) => { const steps = 20; const stepDuration = duration / steps; for (let i = steps; i >= 0; i--) { await NativeAudio.setVolume({ assetId, volume: i / steps }); await new Promise(resolve => setTimeout(resolve, stepDuration)); } await NativeAudio.stop({ assetId }); }; ``` ## Best Practices 1. **Preload during app initialization** ```typescript import { App } from '@capacitor/app'; App.addListener('appStateChange', async ({ isActive }) => { if (isActive) { await soundManager.init(); } }); ``` 2. **Handle errors gracefully** ```typescript try { await NativeAudio.play({ assetId: 'sound' }); } catch (error) { console.log('Audio playback failed, continuing silently'); } ``` 3. **Unload unused audio** ```typescript // Unload sounds when leaving a screen ionViewWillLeave() { this.unloadScreenSounds(); } ``` 4. **Use appropriate preload methods** * `preload()` for short sound effects (< 5 seconds) * `preloadComplex()` for music and longer audio ## Platform Notes ### iOS * Supports AAC, MP3, WAV, and other Core Audio formats * Uses AVAudioPlayer for complex audio * Uses System Sound Services for simple audio * Supports background audio with proper configuration ### Android * Supports MP3, OGG, WAV formats * Uses SoundPool for simple audio * Uses MediaPlayer for complex audio * May require WAKE\_LOCK permission for background playback ### File Placement #### iOS Place files in `ios/App/App/sounds/` or create a folder reference in Xcode. #### Android Place files in `android/app/src/main/res/raw/`. Note: File names must be lowercase with no special characters. ## Common Issues 1. **Audio not playing** * Ensure files are in correct directories * Check file format compatibility * Verify assetId matches exactly 2. **Delay in playback** * Use `preload()` for sound effects * Preload before you need to play 3. **Memory issues** * Unload audio files when not needed * Don’t preload too many large files 4. **Background playback** * Configure background audio capability on iOS * Handle audio focus on Android # @capgo/capacitor-native-biometric > Access native biometric authentication APIs for Android and iOS, providing secure and convenient user authentication. Multiple biometrics Supports fingerprint, Face ID, Touch ID, and other biometric sensors 🚀 Secure authentication Provides secure biometric authentication for sensitive operations 🔒 Fallback options Includes device passcode fallback when biometrics are unavailable 😊 Comprehensive Documentation Check the [Documentation](/docs/plugins/native-biometric/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and use the Native Biometric plugin for secure biometric authentication in your Capacitor app. 1. **Install the package** * npm ```sh npm i @capgo/capacitor-native-biometric ``` * pnpm ```sh pnpm add @capgo/capacitor-native-biometric ``` * yarn ```sh yarn add @capgo/capacitor-native-biometric ``` * bun ```sh bun add @capgo/capacitor-native-biometric ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` 3. **Configure permissions** ### iOS Add Face ID usage description to your `Info.plist`: ```xml NSFaceIDUsageDescription For secure authentication ``` ### Android Add biometric permission to your `AndroidManifest.xml`: ```xml ``` ## Usage Import the plugin and use its methods for biometric authentication: ```typescript import { NativeBiometric } from '@capgo/capacitor-native-biometric'; // Check if biometric authentication is available const checkBiometric = async () => { const result = await NativeBiometric.isAvailable(); if (result.isAvailable) { console.log(`Biometric type: ${result.biometryType}`); } }; // Perform biometric verification const verify = async () => { const verified = await NativeBiometric.verifyIdentity({ reason: "For secure access to your account", title: "Authentication", subtitle: "Verify your identity", description: "Place your finger on the sensor" }) .then(() => true) .catch(() => false); if (verified) { console.log("Authentication successful"); } }; // Store credentials securely const saveCredentials = async () => { await NativeBiometric.setCredentials({ username: "user@example.com", password: "securepassword", server: "https://api.example.com" }); }; // Retrieve stored credentials const getCredentials = async () => { const credentials = await NativeBiometric.getCredentials({ server: "https://api.example.com" }); console.log(credentials.username); console.log(credentials.password); }; // Delete stored credentials const deleteCredentials = async () => { await NativeBiometric.deleteCredentials({ server: "https://api.example.com" }); }; ``` ## API Reference ### isAvailable() Checks if biometric authentication is available on the device. ```typescript interface AvailableResult { isAvailable: boolean; biometryType?: BiometryType; errorCode?: number; } enum BiometryType { NONE = 0, TOUCH_ID = 1, FACE_ID = 2, FINGERPRINT = 3, FACE_AUTHENTICATION = 4, IRIS_AUTHENTICATION = 5 } ``` ### verifyIdentity(options) Performs biometric authentication. ```typescript interface BiometricOptions { reason?: string; title?: string; subtitle?: string; description?: string; fallbackTitle?: string; useFallback?: boolean; maxAttempts?: number; } ``` ### setCredentials(options) Stores credentials securely with biometric protection. ```typescript interface Credentials { username: string; password: string; server: string; } ``` ### getCredentials(options) Retrieves stored credentials after biometric authentication. ```typescript interface GetCredentialOptions { server: string; } ``` ### deleteCredentials(options) Deletes stored credentials. ```typescript interface DeleteCredentialOptions { server: string; } ``` ## Best Practices 1. **Always check availability first** ```typescript const result = await NativeBiometric.isAvailable(); if (!result.isAvailable) { // Fall back to password authentication } ``` 2. **Provide clear reasons** Always explain why you need biometric authentication to build user trust. 3. **Handle errors gracefully** ```typescript try { await NativeBiometric.verifyIdentity({ reason: "Access your secure data" }); } catch (error) { // Handle cancellation or failure console.log("Authentication failed or cancelled"); } ``` 4. **Use appropriate fallbacks** Enable passcode fallback for devices where biometrics may fail. ## Platform Differences ### iOS * Supports Touch ID and Face ID * Requires `NSFaceIDUsageDescription` for Face ID * Fallback to device passcode available ### Android * Supports fingerprint, face, and iris recognition * Requires `USE_BIOMETRIC` permission * Biometric Prompt API for Android 9+ # @capgo/native-market > A Capacitor plugin for redirecting users to app stores (Google Play or Apple App Store) from your mobile application. Cross-platform Works seamlessly on both Android and iOS platforms 🚀 Easy integration Simple API to redirect users to rate or view your app on their respective app stores 💨 TypeScript support Full TypeScript support for better development experience 😊 Comprehensive Documentation Check the [Documentation](/docs/plugins/native-market/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and use the Native Market plugin to redirect users to Google Play Store or Apple App Store from your Capacitor app. 1. **Install the package** * npm ```sh npm i @capgo/native-market ``` * pnpm ```sh pnpm add @capgo/native-market ``` * yarn ```sh yarn add @capgo/native-market ``` * bun ```sh bun add @capgo/native-market ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` ## Usage Import the plugin and use its methods to redirect users to app stores: ```typescript import { NativeMarket } from '@capgo/native-market'; // Open app store listing const openAppStore = async () => { await NativeMarket.openStoreListing({ appId: 'com.example.app' // Your app's bundle ID }); }; // Request app review const requestReview = async () => { await NativeMarket.requestReview(); }; // Open app store search const searchInStore = async () => { await NativeMarket.search({ terms: 'fitness app' // Search terms }); }; ``` ## API Reference ### openStoreListing(options) Opens the app store listing for the specified app. ```typescript interface OpenStoreListingOptions { appId: string; // Bundle ID on iOS, Package name on Android } ``` ### requestReview() Requests an in-app review from the user. On iOS 10.3+, this shows the rating dialog without leaving the app. ### search(options) Opens the app store with search results. ```typescript interface SearchOptions { terms: string; // Search terms to use } ``` ## Platform Notes ### iOS * Uses `SKStoreReviewController` for in-app reviews on iOS 10.3+ * Falls back to opening App Store for older versions ### Android * Opens Google Play Store * Uses in-app review API when available ## Example ```typescript import { NativeMarket } from '@capgo/native-market'; import { Capacitor } from '@capacitor/core'; export class AppService { async rateApp() { try { // Try in-app review first await NativeMarket.requestReview(); } catch (error) { // Fallback to opening store listing const platform = Capacitor.getPlatform(); const appId = platform === 'ios' ? 'id123456789' // Your iOS app ID : 'com.example.app'; // Your Android package name await NativeMarket.openStoreListing({ appId }); } } } ``` # @capgo/native-purchases > Simplify in-app purchases and subscriptions with a unified API that works seamlessly across iOS and Android platforms. Unified API Single API for iOS and Android purchases 💳 Subscription management Handle subscriptions with automatic renewal 🔄 Receipt validation Built-in receipt validation for security 🔒 Comprehensive Documentation Check the [Documentation](/docs/plugins/native-purchases/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and configure the Capacitor Native Purchases plugin to implement in-app purchases and subscriptions. 1. **Install the package** * npm ```sh npm i @capgo/native-purchases ``` * pnpm ```sh pnpm add @capgo/native-purchases ``` * yarn ```sh yarn add @capgo/native-purchases ``` * bun ```sh bun add @capgo/native-purchases ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` 3. **Configure the plugin** **Initialize Purchases:** ```typescript import { NativePurchases } from '@capgo/native-purchases'; // Initialize with your app's API keys await NativePurchases.configure({ apiKey: 'your_api_key_here', appUserID: 'user123' // Optional custom user ID }); ``` **Get Products:** ```typescript // Fetch available products const { products } = await NativePurchases.getProducts({ productIdentifiers: [ 'premium_monthly', 'premium_yearly' ] }); console.log('Available products:', products); ``` * iOS 1. Configure in App Store Connect: * Create your in-app purchases * Submit for review 2. Add to `Info.plist`: ```xml SKAdNetworkItems SKAdNetworkIdentifier your-network-id.skadnetwork ``` * Android 1. Configure in Google Play Console: * Create in-app products * Add your app’s signing certificate 2. Add to `AndroidManifest.xml`: ```xml ``` 4. **Making purchases** ```typescript import { NativePurchases } from '@capgo/native-purchases'; // Purchase a product try { const { customerInfo } = await NativePurchases.purchaseProduct({ productIdentifier: 'premium_monthly' }); console.log('Purchase successful:', customerInfo); // Check if user has active entitlements if (customerInfo.entitlements.active['premium']) { console.log('User has premium access!'); } } catch (error) { console.error('Purchase failed:', error); } // Restore purchases const { customerInfo } = await NativePurchases.restorePurchases(); console.log('Restored purchases:', customerInfo); ``` 5. **Advanced implementation** ```typescript import { NativePurchases } from '@capgo/native-purchases'; export class PurchaseService { private products: any[] = []; private customerInfo: any = null; async initialize(userId?: string) { try { // Configure SDK await NativePurchases.configure({ apiKey: process.env.PURCHASES_API_KEY, appUserID: userId, observerMode: false, // Set true if using with other purchase SDKs userDefaultsSuiteName: 'group.com.yourapp' }); // Set user attributes await NativePurchases.setAttributes({ '$email': 'user@example.com', 'user_level': 'gold', 'app_version': '1.0.0' }); // Get initial customer info await this.syncCustomerInfo(); // Listen for updates this.setupListeners(); } catch (error) { console.error('Failed to initialize purchases:', error); } } private setupListeners() { // Listen for customer info updates NativePurchases.addListener('customerInfoUpdate', (info) => { this.customerInfo = info.customerInfo; this.checkSubscriptionStatus(); }); // Listen for promotional purchases (iOS) NativePurchases.addListener('shouldPurchasePromoProduct', async (data) => { // Handle App Store promotional purchases const { product } = data; const shouldPurchase = await this.showPromotionalOffer(product); if (shouldPurchase) { await this.purchaseProduct(product.identifier); } }); } async loadProducts() { const { products } = await NativePurchases.getProducts({ productIdentifiers: [ 'premium_monthly', 'premium_yearly', 'lifetime_access' ] }); this.products = products; return products; } async purchaseProduct(productId: string) { try { // Show loading this.showLoading(true); const { customerInfo } = await NativePurchases.purchaseProduct({ productIdentifier: productId }); this.customerInfo = customerInfo; // Handle successful purchase if (this.hasActiveSubscription()) { this.unlockPremiumFeatures(); this.showSuccessMessage(); } return customerInfo; } catch (error: any) { // Handle different error cases if (error.userCancelled) { console.log('User cancelled purchase'); } else if (error.code === 'PRODUCT_ALREADY_PURCHASED') { await this.restorePurchases(); } else { this.showErrorMessage(error.message); } throw error; } finally { this.showLoading(false); } } async restorePurchases() { const { customerInfo } = await NativePurchases.restorePurchases(); this.customerInfo = customerInfo; if (this.hasActiveSubscription()) { this.showSuccessMessage('Purchases restored!'); this.unlockPremiumFeatures(); } else { this.showInfoMessage('No purchases to restore'); } return customerInfo; } async checkTrialOrIntroductoryPrice(productId: string) { const { eligible } = await NativePurchases.checkTrialOrIntroductoryPriceEligibility({ productIdentifiers: [productId] }); return eligible[productId]; } hasActiveSubscription(): boolean { return this.customerInfo?.entitlements?.active?.['premium'] !== undefined; } getSubscriptionExpirationDate(): Date | null { const premium = this.customerInfo?.entitlements?.active?.['premium']; return premium ? new Date(premium.expirationDate) : null; } async syncCustomerInfo() { const { customerInfo } = await NativePurchases.getCustomerInfo(); this.customerInfo = customerInfo; return customerInfo; } private unlockPremiumFeatures() { // Enable premium features in your app localStorage.setItem('isPremium', 'true'); // Update UI, enable features, etc. } private showLoading(show: boolean) { // Show/hide loading indicator } private showSuccessMessage(message = 'Purchase successful!') { // Show success notification } private showErrorMessage(message: string) { // Show error notification } private showInfoMessage(message: string) { // Show info notification } private async showPromotionalOffer(product: any): Promise { // Show UI for promotional offer return true; // or false based on user choice } } ``` ## API Reference ### Methods #### `configure(options: ConfigureOptions)` Initialize the SDK with your credentials. **Parameters:** * `options.apiKey`: string - Your app’s API key * `options.appUserID`: string (optional) - Custom user identifier * `options.observerMode`: boolean (optional) - Disable automatic transaction finishing * `options.userDefaultsSuiteName`: string (optional) - iOS App Group name #### `getProducts(options: GetProductsOptions)` Fetch product details from the store. **Returns:** `Promise<{ products: Product[] }>` #### `purchaseProduct(options: PurchaseOptions)` Initiate a purchase. **Returns:** `Promise<{ customerInfo: CustomerInfo }>` #### `restorePurchases()` Restore previous purchases. **Returns:** `Promise<{ customerInfo: CustomerInfo }>` #### `getCustomerInfo()` Get current customer information. **Returns:** `Promise<{ customerInfo: CustomerInfo }>` ### Events * `customerInfoUpdate`: Fired when customer info changes * `shouldPurchasePromoProduct`: iOS promotional purchase events ## Platform Notes ### iOS * Requires iOS 11.0 or later * App Store receipt validation * Support for promotional offers * StoreKit 2 support on iOS 15+ ### Android * Requires Android 5.0 (API 21) or later * Google Play Billing Library * Supports immediate and deferred purchases ## Common Use Cases 1. **Subscriptions**: Monthly/yearly premium access 2. **One-time Purchases**: Remove ads, unlock features 3. **Consumables**: In-game currency, credits 4. **Free Trials**: Introductory offers for new users 5. **Family Sharing**: Shared subscriptions (iOS) ## Best Practices 1. **Always Restore**: Provide restore functionality 2. **Cache Products**: Store product info locally 3. **Handle Errors**: Graceful error handling 4. **Receipt Validation**: Always validate on your server 5. **Test Thoroughly**: Use sandbox/test accounts ## Troubleshooting **Products not loading:** * Verify product IDs match store configuration * Ensure agreements are signed in store consoles * Check products are approved/active **Purchases failing:** * Check internet connectivity * Verify test accounts are configured * Ensure billing permissions are granted **Subscription status incorrect:** * Call `syncCustomerInfo()` to refresh * Check timezone/date settings * Verify receipt validation # @capgo/nativegeocoder > Convert between addresses and geographic coordinates using native platform geocoding APIs for accurate location data. Forward geocoding Convert addresses to geographic coordinates 📍 Reverse geocoding Convert coordinates to human-readable addresses 🏠 Native accuracy Uses platform-native geocoding for best results 🎯 Comprehensive Documentation Check the [Documentation](/docs/plugins/nativegeocoder/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and use the Native Geocoder plugin for address and coordinate conversion in your Capacitor app. 1. **Install the package** * npm ```sh npm i @capgo/nativegeocoder ``` * pnpm ```sh pnpm add @capgo/nativegeocoder ``` * yarn ```sh yarn add @capgo/nativegeocoder ``` * bun ```sh bun add @capgo/nativegeocoder ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` 3. **Configure permissions** ### iOS Add location usage description to your `Info.plist`: ```xml NSLocationWhenInUseUsageDescription To convert addresses to coordinates ``` ### Android Add permissions to your `AndroidManifest.xml`: ```xml ``` ## Usage Import the plugin and use its geocoding methods: ```typescript import { NativeGeocoder } from '@capgo/nativegeocoder'; // Forward geocoding: Address to coordinates const forwardGeocode = async () => { const results = await NativeGeocoder.forwardGeocode({ addressString: '1600 Amphitheatre Parkway, Mountain View, CA', useLocale: true, maxResults: 1 }); const location = results.addresses[0]; console.log('Latitude:', location.latitude); console.log('Longitude:', location.longitude); }; // Reverse geocoding: Coordinates to address const reverseGeocode = async () => { const results = await NativeGeocoder.reverseGeocode({ latitude: 37.4220656, longitude: -122.0840897, useLocale: true, maxResults: 1 }); const address = results.addresses[0]; console.log('Street:', address.thoroughfare); console.log('City:', address.locality); console.log('Country:', address.countryName); }; ``` ## API Reference ### forwardGeocode(options) Converts an address string to geographic coordinates. ```typescript interface ForwardGeocodeOptions { addressString: string; useLocale?: boolean; maxResults?: number; apiKey?: string; // Android only } interface GeocodeResult { addresses: Address[]; } interface Address { latitude: number; longitude: number; countryCode?: string; countryName?: string; postalCode?: string; administrativeArea?: string; subAdministrativeArea?: string; locality?: string; subLocality?: string; thoroughfare?: string; subThoroughfare?: string; } ``` ### reverseGeocode(options) Converts geographic coordinates to address information. ```typescript interface ReverseGeocodeOptions { latitude: number; longitude: number; useLocale?: boolean; maxResults?: number; apiKey?: string; // Android only } ``` ## Complete Examples ### Address Search with Error Handling ```typescript import { NativeGeocoder } from '@capgo/nativegeocoder'; export class GeocodingService { async searchAddress(address: string): Promise<{lat: number, lng: number} | null> { try { const results = await NativeGeocoder.forwardGeocode({ addressString: address, useLocale: true, maxResults: 5 }); if (results.addresses.length > 0) { const location = results.addresses[0]; return { lat: location.latitude, lng: location.longitude }; } return null; } catch (error) { console.error('Geocoding failed:', error); return null; } } async getAddressFromCoordinates(lat: number, lng: number): Promise { try { const results = await NativeGeocoder.reverseGeocode({ latitude: lat, longitude: lng, useLocale: true, maxResults: 1 }); if (results.addresses.length > 0) { const address = results.addresses[0]; return this.formatAddress(address); } return null; } catch (error) { console.error('Reverse geocoding failed:', error); return null; } } private formatAddress(address: Address): string { const parts = [ address.subThoroughfare, address.thoroughfare, address.locality, address.administrativeArea, address.postalCode, address.countryName ].filter(part => part != null && part !== ''); return parts.join(', '); } } ``` ### Location Picker Component ```typescript import { NativeGeocoder } from '@capgo/nativegeocoder'; import { Geolocation } from '@capacitor/geolocation'; export class LocationPicker { currentLocation: { lat: number; lng: number } | null = null; currentAddress: string = ''; async getCurrentLocation() { try { // Get current coordinates const position = await Geolocation.getCurrentPosition(); this.currentLocation = { lat: position.coords.latitude, lng: position.coords.longitude }; // Get address for coordinates const results = await NativeGeocoder.reverseGeocode({ latitude: this.currentLocation.lat, longitude: this.currentLocation.lng, useLocale: true, maxResults: 1 }); if (results.addresses.length > 0) { const address = results.addresses[0]; this.currentAddress = [ address.thoroughfare, address.locality, address.countryName ].filter(Boolean).join(', '); } } catch (error) { console.error('Failed to get location:', error); } } async searchLocation(query: string) { try { const results = await NativeGeocoder.forwardGeocode({ addressString: query, useLocale: true, maxResults: 10 }); return results.addresses.map(address => ({ coordinates: { lat: address.latitude, lng: address.longitude }, displayName: this.formatDisplayName(address) })); } catch (error) { console.error('Search failed:', error); return []; } } private formatDisplayName(address: Address): string { const mainPart = [ address.thoroughfare, address.locality ].filter(Boolean).join(', '); const subPart = [ address.administrativeArea, address.countryName ].filter(Boolean).join(', '); return mainPart + (subPart ? ` (${subPart})` : ''); } } ``` ## Best Practices 1. **Request permissions first** ```typescript import { Geolocation } from '@capacitor/geolocation'; const requestPermissions = async () => { const permissions = await Geolocation.requestPermissions(); if (permissions.location !== 'granted') { throw new Error('Location permission required'); } }; ``` 2. **Handle errors gracefully** ```typescript try { const results = await NativeGeocoder.forwardGeocode({ addressString: address }); } catch (error) { // Handle specific error cases if (error.message.includes('network')) { console.error('Network error'); } else if (error.message.includes('permission')) { console.error('Permission denied'); } } ``` 3. **Use maxResults wisely** * For user search: Use 5-10 results * For automatic conversion: Use 1 result * More results = slower response 4. **Cache results when possible** ```typescript const geocodeCache = new Map(); async function geocodeWithCache(address: string) { if (geocodeCache.has(address)) { return geocodeCache.get(address); } const result = await NativeGeocoder.forwardGeocode({ addressString: address }); geocodeCache.set(address, result); return result; } ``` ## Platform Differences ### iOS * Uses `CLGeocoder` from CoreLocation * No API key required * Respects user’s locale automatically ### Android * Uses Android Geocoder API * Optional Google API key for better results * May fall back to Google’s web service ### API Key Configuration (Android) For better results on Android, you can provide a Google API key: ```typescript await NativeGeocoder.forwardGeocode({ addressString: address, apiKey: 'YOUR_GOOGLE_API_KEY' // Android only }); ``` ## Common Issues 1. **No results returned** * Check internet connection * Verify address format * Try with more general address 2. **Permission errors** * Ensure location permissions are granted * Check Info.plist/AndroidManifest.xml 3. **Inaccurate results** * Use more specific addresses * Include postal codes when available * Consider using coordinates for precise locations # @capgo/capacitor-navigation-bar > Set custom colors for the Android navigation bar to match your app's theme and create a cohesive visual experience. Android customization Full control over Android navigation bar appearance 🎨 Dynamic theming Change colors dynamically to match your app’s theme 🌈 Light/Dark support Support for light and dark navigation bar styles 🌓 Comprehensive Documentation Check the [Documentation](/docs/plugins/navigation-bar/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and configure the Capacitor Navigation Bar plugin to customize the Android navigation bar color and style. 1. **Install the package** * npm ```sh npm i @capgo/capacitor-navigation-bar ``` * pnpm ```sh pnpm add @capgo/capacitor-navigation-bar ``` * yarn ```sh yarn add @capgo/capacitor-navigation-bar ``` * bun ```sh bun add @capgo/capacitor-navigation-bar ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` 3. **Configure the plugin** **Set Navigation Bar Color:** ```typescript import { NavigationBar } from '@capgo/capacitor-navigation-bar'; // Set navigation bar color await NavigationBar.setColor({ color: '#FF0000', // Red color darkButtons: false // Use light buttons }); ``` **Dynamic Theme Support:** ```typescript // Set color based on theme const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches; await NavigationBar.setColor({ color: isDarkMode ? '#000000' : '#FFFFFF', darkButtons: !isDarkMode }); ``` * Android **Minimum Requirements:** * Android 5.0 (API level 21) or higher * The plugin only works on Android devices No additional setup required in AndroidManifest.xml. * iOS This plugin is Android-only. iOS does not have a customizable navigation bar. 4. **Advanced usage** ```typescript import { NavigationBar } from '@capgo/capacitor-navigation-bar'; export class ThemeService { // Set transparent navigation bar async setTransparent() { await NavigationBar.setColor({ color: '#00000000', // Transparent darkButtons: true }); } // Match app theme async matchAppTheme(primaryColor: string, isLight: boolean) { await NavigationBar.setColor({ color: primaryColor, darkButtons: isLight }); } // Get current navigation bar color async getCurrentColor() { const result = await NavigationBar.getColor(); console.log('Current color:', result.color); return result.color; } // Reset to default async resetToDefault() { await NavigationBar.setColor({ color: '#000000', darkButtons: false }); } } ``` 5. **Integration with app lifecycle** ```typescript import { App } from '@capacitor/app'; import { NavigationBar } from '@capgo/capacitor-navigation-bar'; // Update navigation bar on app state changes App.addListener('appStateChange', async ({ isActive }) => { if (isActive) { // Restore your app's navigation bar color await NavigationBar.setColor({ color: '#YourAppColor', darkButtons: true }); } }); // Handle theme changes window.matchMedia('(prefers-color-scheme: dark)') .addEventListener('change', async (e) => { await NavigationBar.setColor({ color: e.matches ? '#121212' : '#FFFFFF', darkButtons: !e.matches }); }); ``` ## API Reference ### Methods #### `setColor(options: ColorOptions)` Set the navigation bar color and button style. **Parameters:** * `options`: Configuration object * `color`: string - Hex color code (e.g., ‘#FF0000’) * `darkButtons`: boolean - Use dark buttons (true) or light buttons (false) **Returns:** `Promise` #### `getColor()` Get the current navigation bar color. **Returns:** `Promise<{ color: string }>` ### Interfaces ```typescript interface ColorOptions { color: string; // Hex color code darkButtons: boolean; // Button style } interface ColorResult { color: string; // Current hex color } ``` ## Platform Notes ### Android * Requires Android 5.0 (API level 21) or higher * Color changes are immediate * Transparent colors are supported (use alpha channel) * The navigation bar might not be visible on devices with gesture navigation ### iOS * This plugin has no effect on iOS devices * iOS does not provide APIs to customize the system navigation ## Common Use Cases 1. **Brand Consistency**: Match navigation bar with your app’s primary color 2. **Theme Support**: Adapt to light/dark themes dynamically 3. **Immersive Experiences**: Use transparent navigation for full-screen content 4. **Status Indication**: Change color to indicate app states (recording, errors, etc.) ## Best Practices 1. **Color Contrast**: Ensure sufficient contrast between navigation bar and buttons ```typescript // Good contrast examples setColor({ color: '#FFFFFF', darkButtons: true }); // White bar, dark buttons setColor({ color: '#000000', darkButtons: false }); // Black bar, light buttons ``` 2. **Theme Consistency**: Update navigation bar when theme changes 3. **Accessibility**: Consider users with visual impairments when choosing colors 4. **Performance**: Avoid frequent color changes that might distract users ## Troubleshooting **Navigation bar not changing:** * Verify the device is running Android 5.0+ * Check if the device has gesture navigation enabled * Ensure color format is valid hex (e.g., ‘#FF0000’) **Buttons not visible:** * Check the `darkButtons` parameter matches your background color * Light backgrounds need `darkButtons: true` * Dark backgrounds need `darkButtons: false` **Color appears different:** * Some Android versions may modify the color slightly * Use fully opaque colors for best results # @capgo/capacitor-persistent-account > Manage user accounts with persistent storage, secure session handling, and seamless authentication across app sessions. ## Overview The Capacitor Persistent Account plugin enables secure storage and persistence of user account data between app installations. This plugin ensures that user account information remains available even after app reinstalls, providing seamless user experience and account continuity. Cross-install persistence Data survives app uninstall/reinstall cycles 💾 Secure storage Secure account data storage with system integration 🔐 Simple API Clean read/write interface for account management 📊 Cross-platform Native iOS and Android implementation 📱 ## Installation ```bash npm install @capgo/capacitor-persistent-account npx cap sync ``` ## Core API Methods ### Data Management * `saveAccount(options: { data: unknown })` - Securely save account data to persistent storage * `readAccount()` - Retrieve stored account data, returns `Promise<{ data: unknown | null }>` ## Key Features * **Cross-installation persistence**: Account data survives app uninstall and reinstall * **Secure storage**: Uses platform-specific secure storage mechanisms * **Type flexibility**: Store any serializable account data structure * **Cross-platform support**: Native implementation for both iOS and Android ## Usage Example ```typescript import { PersistentAccount } from '@capgo/capacitor-persistent-account'; // Define your account data structure interface UserAccount { userId: string; username: string; email: string; preferences: { theme: string; notifications: boolean; }; } // Save account data const accountData: UserAccount = { userId: '12345', username: 'john_doe', email: 'john@example.com', preferences: { theme: 'dark', notifications: true } }; await PersistentAccount.saveAccount({ data: accountData }); // Read account data const result = await PersistentAccount.readAccount(); if (result.data) { const account = result.data as UserAccount; console.log('Restored account:', account.username); } else { console.log('No account data found'); } ``` ## Use Cases * **User onboarding**: Preserve user progress through app reinstalls * **Account recovery**: Restore user sessions after app updates * **Preferences storage**: Maintain user settings and configurations * **Offline-first apps**: Store essential user data locally ## Platform Implementation ### iOS * Utilizes iOS Keychain Services for secure, persistent storage * Data survives app deletion and device restores ### Android * Uses Android Account Manager or shared preferences with backup * Maintains data across app reinstalls and device migrations ## Security Considerations * Account data is stored using platform-specific secure storage * Consider data encryption for sensitive information * Implement proper data validation when reading stored accounts * Follow platform guidelines for user data handling ## Documentation Check the [complete documentation](/docs/plugins/persistent-account/getting-started/) for detailed implementation guides and best practices. # @capgo/capacitor-ricoh360-camera > Control Ricoh 360° cameras for immersive panoramic photo and video capture with full device integration. 360° capture Capture immersive panoramic photos and videos 🌐 Device control Full control over Ricoh Theta camera settings 📸 Live preview Real-time 360° preview streaming 👁️ Comprehensive Documentation Check the [Documentation](/docs/plugins/ricoh360-camera/getting-started/) to master the plugin in just a few minutes. # @capgo/capacitor-screen-recorder > Record your device's screen with this powerful Capacitor plugin, perfect for creating tutorials, demos, and capturing app interactions. High quality recording Record screen in high quality with customizable settings 🎥 Audio support Record with microphone audio and system sounds 🎤 Easy integration Simple API with start/stop recording methods 😊 Comprehensive Documentation Check the [Documentation](/docs/plugins/screen-recorder/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and use the Screen Recorder plugin to capture screen recordings in your Capacitor app. 1. **Install the package** * npm ```sh npm i @capgo/capacitor-screen-recorder ``` * pnpm ```sh pnpm add @capgo/capacitor-screen-recorder ``` * yarn ```sh yarn add @capgo/capacitor-screen-recorder ``` * bun ```sh bun add @capgo/capacitor-screen-recorder ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` 3. **Configure permissions** ### iOS Add usage descriptions to your `Info.plist`: ```xml NSMicrophoneUsageDescription To record audio with screen recording NSPhotoLibraryUsageDescription To save screen recordings ``` ### Android Add permissions to your `AndroidManifest.xml`: ```xml ``` ## Usage Import the plugin and use its methods to record the screen: ```typescript import { ScreenRecorder } from '@capgo/capacitor-screen-recorder'; // Start recording const startRecording = async () => { try { await ScreenRecorder.start(); console.log('Recording started'); } catch (error) { console.error('Failed to start recording:', error); } }; // Stop recording const stopRecording = async () => { try { const result = await ScreenRecorder.stop(); console.log('Recording saved to:', result.videoUrl); // You can now use the video URL // For example, share it or play it back } catch (error) { console.error('Failed to stop recording:', error); } }; // Check if recording is supported const checkSupport = async () => { const { value } = await ScreenRecorder.isSupported(); console.log('Screen recording supported:', value); }; // Check if currently recording const checkRecordingStatus = async () => { const { value } = await ScreenRecorder.isRecording(); console.log('Currently recording:', value); }; ``` ## API Reference ### start() Starts screen recording. ```typescript await ScreenRecorder.start(); ``` ### stop() Stops recording and returns the video file path. ```typescript interface RecordingResult { videoUrl: string; } const result = await ScreenRecorder.stop(); ``` ### isSupported() Checks if screen recording is supported on the device. ```typescript const { value } = await ScreenRecorder.isSupported(); // Returns: { value: boolean } ``` ### isRecording() Checks if screen recording is currently active. ```typescript const { value } = await ScreenRecorder.isRecording(); // Returns: { value: boolean } ``` ## Advanced Usage ### Recording with Options ```typescript // iOS-specific options const startWithOptions = async () => { await ScreenRecorder.start({ // iOS only options recordAudio: true, microphoneAudio: true, showIOSNotification: true, notificationText: "Recording in progress..." }); }; ``` ### Complete Recording Flow ```typescript import { ScreenRecorder } from '@capgo/capacitor-screen-recorder'; import { Share } from '@capacitor/share'; export class RecordingService { private isRecording = false; async toggleRecording() { if (this.isRecording) { await this.stopRecording(); } else { await this.startRecording(); } } private async startRecording() { try { // Check if supported const { value: isSupported } = await ScreenRecorder.isSupported(); if (!isSupported) { throw new Error('Screen recording not supported'); } // Start recording await ScreenRecorder.start(); this.isRecording = true; console.log('Recording started'); } catch (error) { console.error('Failed to start recording:', error); throw error; } } private async stopRecording() { try { const result = await ScreenRecorder.stop(); this.isRecording = false; console.log('Recording saved:', result.videoUrl); // Option to share the recording await this.shareRecording(result.videoUrl); } catch (error) { console.error('Failed to stop recording:', error); throw error; } } private async shareRecording(videoUrl: string) { try { await Share.share({ title: 'Screen Recording', text: 'Check out my screen recording!', url: videoUrl, dialogTitle: 'Share Recording' }); } catch (error) { console.error('Failed to share recording:', error); } } } ``` ## Best Practices 1. **Check support before use** ```typescript const { value } = await ScreenRecorder.isSupported(); if (!value) { // Hide recording feature or show alternative } ``` 2. **Handle permissions properly** On iOS, the system will automatically prompt for permission. On Android, ensure you request necessary permissions. 3. **Provide user feedback** Show clear indicators when recording is active: ```typescript let recordingInterval: any; const startRecording = async () => { await ScreenRecorder.start(); // Show recording indicator recordingInterval = setInterval(() => { // Update UI to show recording duration }, 1000); }; const stopRecording = async () => { clearInterval(recordingInterval); await ScreenRecorder.stop(); }; ``` 4. **Handle interruptions** ```typescript import { App } from '@capacitor/app'; App.addListener('appStateChange', async ({ isActive }) => { if (!isActive) { // Consider stopping recording when app goes to background const { value } = await ScreenRecorder.isRecording(); if (value) { await ScreenRecorder.stop(); } } }); ``` ## Platform Notes ### iOS * Requires iOS 11.0+ * Uses `ReplayKit` framework * System shows recording indicator in status bar * User must confirm recording start ### Android * Requires Android 5.0 (API 21)+ * Uses `MediaProjection` API * Shows notification during recording * Some devices may have manufacturer-specific limitations ### Web * Not supported on web platform * Will return `isSupported: false` ## Troubleshooting 1. **Recording fails to start** * Ensure all permissions are granted * Check if another app is already recording * Verify device supports screen recording 2. **No audio in recording** * Check microphone permissions * Ensure `recordAudio` option is enabled * Some devices may not support system audio recording 3. **Video file not found** * Check file permissions * Ensure sufficient storage space * Verify the returned video URL is valid # @capgo/capacitor-shake > Detect shake gestures in your app to trigger actions, show debug menus, or create interactive experiences. Simple gesture detection Easily detect when users shake their device 📱 Customizable sensitivity Adjust shake detection sensitivity to your needs ⚡ Cross-platform Works seamlessly on iOS and Android devices 🌍 Comprehensive Documentation Check the [Documentation](/docs/plugins/shake/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and configure the Capacitor Shake plugin to detect shake gestures and create interactive experiences in your app. 1. **Install the package** * npm ```sh npm i @capgo/capacitor-shake ``` * pnpm ```sh pnpm add @capgo/capacitor-shake ``` * yarn ```sh yarn add @capgo/capacitor-shake ``` * bun ```sh bun add @capgo/capacitor-shake ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` 3. **Configure the plugin** **Basic Usage Example:** ```typescript import { Shake } from '@capgo/capacitor-shake'; // Start listening for shake gestures await Shake.start(); // Listen for shake events Shake.addListener('shake', () => { console.log('Device was shaken!'); // Perform your action here }); ``` **Sensitivity Configuration:** ```typescript // Configure shake sensitivity await Shake.start({ threshold: 3.5 // Adjust sensitivity (default: 3.5) }); ``` * iOS No additional setup required for iOS. * Android No additional setup required for Android. 4. **Stop listening for shakes** ```typescript // Stop shake detection when not needed await Shake.stop(); // Remove specific listener const handle = await Shake.addListener('shake', () => { console.log('Shaken!'); }); handle.remove(); ``` 5. **Example implementation** ```typescript import { Shake } from '@capgo/capacitor-shake'; import { App } from '@capacitor/app'; export class ShakeService { private shakeListener: any; async initialize() { // Start shake detection await Shake.start({ threshold: 4.0 }); // Add shake listener this.shakeListener = await Shake.addListener('shake', () => { this.handleShake(); }); // Clean up on app pause App.addListener('pause', () => { Shake.stop(); }); // Resume on app resume App.addListener('resume', () => { Shake.start({ threshold: 4.0 }); }); } private handleShake() { console.log('Shake detected!'); // Show debug menu, refresh data, or trigger any action } async cleanup() { if (this.shakeListener) { this.shakeListener.remove(); } await Shake.stop(); } } ``` ## API Reference ### Methods #### `start(options?: ShakeOptions)` Start listening for shake gestures. **Parameters:** * `options` (optional): Configuration object * `threshold`: number - Sensitivity threshold (default: 3.5) #### `stop()` Stop listening for shake gestures. #### `addListener('shake', callback: () => void)` Add a listener for shake events. **Returns:** Promise with a handle to remove the listener ### Interfaces ```typescript interface ShakeOptions { threshold?: number; // Shake sensitivity threshold } ``` ## Platform Notes ### iOS * Uses the device’s accelerometer to detect shake gestures * Works in both foreground and background (if app has background permissions) ### Android * Uses the SensorManager to detect shake events * Requires no special permissions * Works when app is in foreground ## Common Use Cases 1. **Debug Menu**: Show developer options when device is shaken 2. **Feedback**: Trigger feedback form or bug report 3. **Refresh**: Refresh app data or clear cache 4. **Games**: Use shake as a game control mechanism 5. **Undo**: Implement shake-to-undo functionality ## Troubleshooting **Shake not detected:** * Ensure the plugin is started with `Shake.start()` * Try adjusting the threshold value (lower = more sensitive) * Check that listeners are properly registered **Too sensitive/not sensitive enough:** * Adjust the `threshold` parameter in `start()` options * Values typically range from 2.0 (very sensitive) to 5.0 (less sensitive) # @capgo/capacitor-social-login > A Capacitor plugin for social authentication with Google, Apple, and Facebook, making user login seamless and secure. Google login Provides a frictionless login experience for your users 🚀 Facebook login Makes Facebook login a breeze 💨 Apple login Apple login can be challenging to implement, but we make it easy 😊 Comprehensive Documentation Check the [Documentation](/docs/plugins/social-login/getting-started/) to master the plugin in just a few minutes. # Apple login on Android > This guide provides a comprehensive walkthrough on setting up Apple Login using Capacitor for iOS devices, detailing each step to ensure a smooth integration process. Apple login on android is hacky. Apple has no official support for `Sign in with Apple` on Android, so the solution is slightly hacky. Android currently uses a chrome tabs to display an OAuth2 website. This approach has the challanges: * Difficult configuration * A backend is required ## Understanding the flow on android. Let me use a diagram to explain the flow on android: ``` flowchart TD A("await SocialLogin.login()") -->|Handled in the plugin|B(Generate the login URL) B --> |Pass the link| C(Open the Chrome browser) C --> D(Wait for the user to login) D --> |Apple redirects to your backend|E(Handle the data returned from Apple) E --> F(Redirect back to the app) F --> G(Return to JS) ``` Now that you are aware of the challlanges and the flow, let’s begin the configuration. ## Creating the service ID 1. Login into the [Apple Developer Portal](https://developer.apple.com). 2. Click on `Identifiers`. ![Apple Developer Portal Identifiers section](/social-login-assets/apple_dev_portal_iden.png) You should see a screen that looks like this: ![Apple Developer Portal Identifiers screen](/social-login-assets/apple_dev_portal_iden_2.png) 1. Ensure that this field says `App IDs` 2. Make sure that you can find your App ID. Note If you don’t have configured Apple Login for IOS, you will have to create one. For me, I already have one created. The app ID I will use is `me.wcaleniewolny.test.ionic.vue`. If you don’t have one, please create one using the [create app step](#creating-the-app). 3. Make sure that the `Sign in with Apple` capability is enabled for your app 1. Click on your app ![Selecting your app from the list](/social-login-assets/apple_dev_click_on_app.png) 2. Ensure that the `Sign in with Apple` capability is enabled ![Sign in with Apple capability enabled checkbox](/social-login-assets/apple_dev_sign_in_with_apple_enabled.png) 3. If it isn’t enabled, enable it. 4. Go back to all `All Identifiers` ![All Identifiers navigation button](/social-login-assets/apple_dev_go_back_iden.png) 5. Click on `App Ids` and go to `Services IDs` ![Navigation to Services IDs section](/social-login-assets/apple_dev_go_to_services_id.png) 6. Creare a new identifier 1. Click on the plus button ![Add new service ID button](/social-login-assets/apple_dev_iden_add.png) 2. Select `Servcice IDs` and click `Continue` ![Selecting Service IDs option](/social-login-assets/apple_dev_service_and_cont.png) 3. Enter a description and a identifiers and click `Continuie`. ![Entering service ID details](/social-login-assets/apple_dev_reg_service_2.png) Note This `identifiers` will become the `clientId` that you will pass in the `initialize` function AND `ANDROID_SERVICE_ID` for the backend. **Please save it!!!** Note Service ID doesn’t have to match the App ID, but I recomend setting the service ID to `YOUR_APP_ID.serivce` . As a reminder, I am using `me.wcaleniewolny.test.ionic.vue` for my app ID but I am using `ee.forgr.io.ionic.service2` as the service ID. 4. Please verify the details and click `Register` ![Confirming service ID registration](/social-login-assets/apple_dev_service_ref_fin.png) 5. Click on the the newly created service ![Selecting newly created service ID](/social-login-assets/apple_dev_open_serv.png) 6. Enable the `Sign in with Apple` option ![Enabling Sign in with Apple for service ID](/social-login-assets/apple_dev_serv_enable_sign_with_apple.png) 7. Configure the `Sign In with Apple` ![Configure button for Sign in with Apple](/social-login-assets/apple_dev_conf_serv_sign_with_apple.png) 8. Ensure that the `Primary App ID` is set to the App ID configured in the previous step ![Setting Primary App ID dropdown](/social-login-assets/apple_dev_service_prim_id.png) 9. Add the domain that you are going to host you backend on. ![Setting domain and return URL fields](/social-login-assets/apple_dev_serv_create_next.png) Note This backend **has** to be running on HTTPS. As for the `Return URLs`, you might want to come back to this after reading the next section of this tutorial and after configuring the backend. For the purposes of this tutorial, I will use `https://xyz.wcaleniewolny.me/login/callback` for the return URL and `xyz.wcaleniewolny.me` the doman. Press next. 10. Confirm the data and click `Done` ![Confirming domain and return URL configuration](/social-login-assets/apple_dev_serv_conf_done.png) 11. Click on `Continue` ![Continue button for service configuration](/social-login-assets/apple_dev_cont_serv_creat.png) 12. Click on `Save` ![Save button for service configuration](/social-login-assets/apple_dev_cont_serv_creat_save.png) ## Creating the key 1. Go back to all `All Identifiers` ![All Identifiers navigation button](/social-login-assets/apple_dev_go_back_iden.png) 2. Click on `Keys` ![Keys section in Apple Developer Portal](/social-login-assets/apple_dev_key_selc.png) 3. Click on the plus icon ![Add new key button](/social-login-assets/apple_dev_key_plus.png) 4. Name your key ![Entering key name field](/social-login-assets/apple_key_name.png) Note This name isn’t important, you can put anything. 5. Select `Sign in with Apple` and click `Configure` ![Enabling and configuring Sign in with Apple for the key](/social-login-assets/apple_dev_key_sing_apple_conf.png) 6. Select the primary App ID, and press `Save` ![Selecting primary App ID for the key](/social-login-assets/apple_dev_key_prim_app_id.png) Note This must be the same App ID as the ID in the previous steps. 7. Click on `Continue` ![Continue button for key configuration](/social-login-assets/apple_dev_key_const.png) 8. Click on `Register` ![Register button for key creation](/social-login-assets/apple_dev_key_reg.png) 9. Copy the key ID and download the key. ![Key ID and download button screen](/social-login-assets/apple_dev_key_downl.png) Caution **IMPORTANT:** Save this ID, in the backend it will be called `KEY_ID`. Download the key. Make sure to never share this key. 10. Find the downloaded key and save it in the backend folder. ![Downloaded key file](/social-login-assets/apple_dev_downloaded_key.png) ## Getting the Team ID In order to use `Login with Apple` on Android, you need to get the `Team ID`. It will be used in the backend. 1. Go to [this website](https://developer.apple.com/account/) and scroll down 2. Find the `Team ID` ![Team ID location in developer account](/social-login-assets/apple_dev_team_id.png) ## Configuring the app redirect As you saw in the diagram, the backend performs a step called `Redirect back to the app`. This requires manual changes to your app. 1. Modify the `AndroidManifest.xml` 1. Open the file, I will use `AndroidStuido` ![AndroidManifest.xml file in Android Studio](/social-login-assets/studio_android_manifest_file.png) 2. Find the `MainActivity` and add the following Intent filter ![Intent filter code to add in MainActivity](/social-login-assets/studio_manifest_code_to_add.png) ```xml ``` 2. Modify the `MainActivity` 1. Please open the `MainActivity` ![MainActivity.java file in Android Studio](/social-login-assets/studio_main_activ_file.png) 2. Add the following code: ![Code to add to MainActivity for handling deep links](/social-login-assets/studio_main_actv_new_code.png) ```java @Override protected void onNewIntent(Intent intent) { String action = intent.getAction(); Uri data = intent.getData(); if (Intent.ACTION_VIEW.equals(action) && data != null) { PluginHandle pluginHandle = getBridge().getPlugin("SocialLogin"); if (pluginHandle == null) { Log.i("Apple Login Intent", "SocialLogin login handle is null"); return; } Plugin plugin = pluginHandle.getInstance(); if (!(plugin instanceof SocialLoginPlugin)) { Log.i("Apple Login Intent", "SocialLogin plugin instance is not SocialLoginPlugin"); return; } ((SocialLoginPlugin) plugin).handleAppleLoginIntent(intent); return; } super.onNewIntent(intent); } ``` Caution This example assumes that you don’t have any deep links configured. If you do, please adjust the code Note You have just added a new deep link into your app. The deep link will look something like this: `capgo-demo-app://path`. You can change the `android:scheme` and the `android:host` to modify how this deep link looks. **Important:** In the backend configuration, this deep link will become `BASE_REDIRECT_URL` ## Backend configuration A backend is required for Android, but configuring a backend will also impact IOS. An example backend is provided [here](https://github.com/WcaleNieWolny/capgo-social-login-backend-demo/blob/main/index.ts) This example provides the following: * A simple JSON database * A way to request the JWT from Apple’s servers * A simple JWT verification Note I use `PM2` in order to host this example. An example `ecosystem.config.js` can be found [here](https://github.com/WcaleNieWolny/capgo-social-login-backend-demo/blob/main/ecosystem.config.js.example) Given everything that I said in this tutorial, here is how the `env` section would look: * `ANDROID_SERVICE_ID` = Service ID * `IOS_SERVICE_ID` = App ID ```js env: { PRIVATE_KEY_FILE: "AuthKey_U93M8LBQK3.p8", KEY_ID: "U93M8LBQK3", TEAM_ID: "UVTJ336J2D", ANDROID_SERVICE_ID: "ee.forgr.io.ionic.starter.service2", IOS_SERVICE_ID: "me.wcaleniewolny.test.ionic.vue", PORT: 3000, REDIRECT_URI: "https://xyz.wcaleniewolny.me/login/callback", BASE_REDIRECT_URL: "capgo-demo-app://path" } ``` #### Using the plugin The usage of the `login` function doesn’t change, it’s the same as IOS. Please take a look at that section for more info. **HOWEVER**, the `initialize` method changes a bit. ```typescript await SocialLogin.initialize({ apple: { clientId: 'ee.forgr.io.ionic.starter.service2', redirectUrl: 'https://appleloginvps.wcaleniewolny.me/login/callback' } }) ``` Danger Note, that adding `redirectUrl` **WILL** affect IOS !!!!! ## Creating the app Note If you already have an App ID, you can skip this step. Don’t follow this step if you have configured Apple Login for IOS. 1. If you don’t already have an App ID, click on the plus button ![Add new identifier plus button](/social-login-assets/apple_dev_iden_plus.png) 2. Select `App IDs` and click continue ![Selecting App IDs type](/social-login-assets/apple_dev_new_app_id.png) 3. Click on type `App` and click `Continue` ![Selecting App type](/social-login-assets/apple_dev_new_app_type.png) 4. Enter the description and the app ID ![Entering app description and bundle ID](/social-login-assets/apple_dev_new_app_desc_id.png) 5. Enable `Sign with Apple` capability ![Enabling Sign in with Apple capability](/social-login-assets/apple_dev_enable_sign_with_apple.png) 6. Click `Continue` ![Continue button for app registration](/social-login-assets/apple_dev_register_continue.png) 7. Confirm the details and click `Register` ![Confirming app registration details](/social-login-assets/apple_dev_confirm_register.png) # Apple Login Setup > This guide provides detailed instructions on setting up Apple Login using Capacitor, covering all necessary steps and requirements for a successful integration. ### Introduction In this guide, you are going to learn how to configure Apple Login with Capacitor. In order to do this, you will need the following: * an Apple Developer Account * A computer running macOS (IOS only) * Xcode installed (IOS only) * A custom backend (Android only) # Apple login on IOS > This comprehensive guide will walk you through the process of setting up Apple Login using Capacitor on iOS devices, ensuring a seamless integration by covering all necessary steps and configurations. Let’s break down what you are going to need in order to setup Apple login on IOS. 1. Configure the capabilities of your app. In order to do this, please open Xcode, click on `App` ![App XCode](/social-login-assets/app-xcode.png) 2. Make sure that you sellect the right target. ![XCode App Target](/social-login-assets/xcode-app-target.png) 3. Please make sure that you add the `Sign in with Apple` capability. ![App XCode Add Capability](/social-login-assets/app-xcode-add-cap.png) ![App XCode Add Capability](/social-login-assets/sign-with-apple-cap.png) Caution If you don’t see the `Sign in with Apple` capability, configure the [Account & Organizational Data Sharing](https://developer.apple.com/account/resources/services/cwa/configure/) 4. Initialize the Apple Login in your app. Note I am using Vue as my framework, the exact implementation will vary depening on the framework of your choice ```ts // onMounted is vue specific onMounted(() => { SocialLogin.initialize({ apple: {} }) }); ``` 5. Create a button that will begin the login process. Said button should call the following function: ```ts async function loginApple() { const res = await SocialLogin.login({ provider: 'apple', options: {} }) ``` 6. Run your app on a ***PHYSICAL*** device and test it. If you followed the steps closely you will see the following screen after clicking your button. ![Apple Sign In prompt on iOS device](/social-login-assets/apple-sign-in-ios-final.png) That’s it! You are all set. # Apple login for web browsers > This guide provides a detailed walkthrough on setting up Apple Login using Capacitor for web applications, utilizing the @capgo/capacitor-social-login plugin to ensure a seamless integration process. Configuring the web login is not trivial. It’s more difficult than setting up `Sign in with Apple` on iOS but more difficult than setting up `Sign in with Apple` on Android. ## Generating the service Note This step is redundent if you have already configured `Sign in with Apple` on Android. Please follow the guide [here](/docs/plugins/social-login/apple/android/#creating-the-service-id/) to generate the service. ## Configuring the `Return URLs` 1. **Go to your Service ID configuration** In the [Apple Developer Portal](https://developer.apple.com), navigate to `Identifiers` > `Services IDs` and click on your service ID. 2. **Configure Sign in with Apple** Click on `Configure` next to `Sign in with Apple`. ![apple\_dev\_configure\_login](/social-login-assets/apple_dev_configure_login.webp) 3. **Add the Return URLs** Click on the `+` button to add a new return URL. ![apple\_dev\_return\_url\_plus](/social-login-assets/apple_dev_return_url_plus.webp) 4. **Add the Return URLs** Add your domain for your web application in `Domains and Subdomains`. Caution You **CANNOT** add `localhost` or `127.0.0.1` as a domain here. Then, add your domain with the `https://` prefix and the path from which you will call Apple Login. For example, if your domain is `https://my-app.com` and you will call Apple Login from `/login`, you should add `https://my-app.com/login` as the return URL. Caution You **MUST** add both the domain with a trailing slash and without a trailing slash. ![apple\_dev\_return\_url\_add](/social-login-assets/apple_dev_return_url_add.webp) 5. **Save the changes** 1. Click on the `Next` button to save the changes. 2. Click on the `Save` button to save the changes. 6. You should be ready to test the login for JavaScript. Please note that you cannot test from localhost. # Facebook Login Setup > This guide provides a comprehensive walkthrough on setting up Facebook Login using Capacitor, ensuring seamless integration and enhanced user authentication for your application. ## Introduction In this guide, you will learn how to setup Facebook Login with Capgo Social Login. You will need the following: * A Facebook Developer Account * Your app’s package name/bundle ID * Access to a terminal for generating key hashes (Android) ## General Setup If you don’t already have a Facebook app created, follow these steps: 1. Create a Facebook App Follow the tutorial to [Create an App](https://developers.facebook.com/docs/development/create-an-app/) 2. Add Facebook Login to your app In your Facebook Developer Dashboard, add the Facebook Login product to your app 3. Before you can release your app to the public, follow this [tutorial](https://developers.facebook.com/docs/development/release/) to publish it ## Important Information Here’s where to find the key information you’ll need for integration: 1. `CLIENT_TOKEN`: ![Facebook developer dashboard showing where to find the client token](/social-login-assets/fb_where_to_fiind_client_token.png) 2. `APP_ID`: ![Facebook developer dashboard showing where to find the app ID](/social-login-assets/fb_where_to_find_app_id.png) 3. `APP_NAME`: ![Facebook developer dashboard showing where to find the app name](/social-login-assets/fb_where_to_find_app_name.png) ## Android Setup 1. Add internet permission to your `AndroidManifest.xml` Ensure this line is present: ```xml ``` 2. Generate your Android key hash This is a crucial security step required by Facebook. Open your terminal and run: ```bash keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl base64 -A ``` When prompted for a password, use: `android` Note For release builds, you’ll need to use your release keystore: ```bash keytool -exportcert -alias your-key-name -keystore your-keystore-path | openssl base64 -A ``` 3. Add the key hash to your Facebook app 1. Go to your app’s dashboard on Facebook Developers 2. Navigate to Settings > Basic 3. Scroll down to “Android” section 4. Click “Add Platform” if Android isn’t added yet and fill in the details 5. Add the key hash you generated 6. For production, add both debug and release key hashes 4. Update your `AndroidManifest.xml` to include: ```xml ... ``` Caution Make sure to replace `[APP_ID]` with your actual Facebook app ID in the `android:scheme` attribute ## iOS Setup 1. Add the iOS platform in Facebook Developer Console 1. Go to your app’s dashboard on Facebook Developers 2. Navigate to Settings > Basic 3. Scroll down to very bottom of the page and click “Add Platform” 4. Select iOS and fill in the required details 2. Open your Xcode project and navigate to Info.plist 3. Add the following entries to your Info.plist: ```xml FacebookAppID [APP-ID] FacebookClientToken [CLIENT-TOKEN] FacebookDisplayName [APP-NAME] LSApplicationQueriesSchemes fbapi fb-messenger-share-api CFBundleURLTypes CFBundleURLSchemes fb[APP-ID] ``` Caution Replace the following values: * `[APP-ID]` with your Facebook app ID * `[CLIENT-TOKEN]` with your client token * `[APP-NAME]` with your app’s name 4. Modify the `AppDelegate.swift` ```swift import FBSDKCoreKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. // Initialize Facebook SDK FBSDKCoreKit.ApplicationDelegate.shared.application( application, didFinishLaunchingWithOptions: launchOptions ) return true } func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { // Called when the app was launched with a url. Feel free to add additional processing here, // but if you want the App API to support tracking app url opens, make sure to keep this call if (FBSDKCoreKit.ApplicationDelegate.shared.application( app, open: url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String, annotation: options[UIApplication.OpenURLOptionsKey.annotation] )) { return true; } else { return ApplicationDelegateProxy.shared.application(app, open: url, options: options) } } } ``` ## Using Facebook Login in Your App Caution **Before You Start**: Remember that with the new Facebook SDK, the token type you receive depends entirely on the user’s App Tracking choice, not on your code configuration. Always implement both access token and JWT token handling in your backend to ensure authentication works for all users. 1. Initialize the Facebook login in your app ```typescript import { SocialLogin } from '@capgo/capacitor-social-login'; // Initialize during app startup await SocialLogin.initialize({ facebook: { appId: 'APP_ID', clientToken: 'CLIENT_TOKEN', } }) ``` 2. Implement the login function ```typescript async function loginWithFacebook() { try { const result = await SocialLogin.login({ provider: 'facebook', options: { permissions: ['email', 'public_profile'], limitedLogin: false // this will depend if you want to use the limited login or not } }); console.log('Facebook login result:', result); // Handle successful login } catch (error) { console.error('Facebook login error:', error); // Handle error } } ``` Note Set `limitedLogin` to true if you want to use Facebook’s Limited Login feature. You can learn more about Limited Login [here](https://developers.facebook.com/docs/facebook-login/limited-login/). 3. **Get User Profile Data** After successful login, you can retrieve additional profile information: ```typescript async function getFacebookProfile() { try { const profileResponse = await SocialLogin.providerSpecificCall({ call: 'facebook#getProfile', options: { fields: ['id', 'name', 'email', 'first_name', 'last_name', 'picture'] } }); console.log('Facebook profile:', profileResponse.profile); return profileResponse.profile; } catch (error) { console.error('Failed to get Facebook profile:', error); return null; } } // Example usage after login async function loginAndGetProfile() { const loginResult = await loginWithFacebook(); if (loginResult) { const profile = await getFacebookProfile(); if (profile) { console.log('User ID:', profile.id); console.log('Name:', profile.name); console.log('Email:', profile.email); console.log('Profile Picture:', profile.picture?.data?.url); } } } ``` Tip **Available Profile Fields**: You can request any fields available in Facebook’s Graph API. Common fields include: `id`, `name`, `email`, `first_name`, `last_name`, `picture`, `birthday`, `gender`, `location`, `hometown`. Note that some fields may require additional permissions. **Token Type Limitation**: The `getProfile` call only works when you have an **access token** (standard login with tracking allowed). If the user denied tracking or you’re using limited login (JWT token only), this call will fail. In that case, use the profile data provided in the initial login response. ## ⚠️ Critical: Understanding Facebook Login Token Types Danger **IMPORTANT**: With the new Facebook SDK, requesting a normal access token does **NOT** guarantee you’ll receive one. The user must accept “App Tracking” permission. If they refuse or have opted out at the OS level, you will **ALWAYS** receive a JWT token instead, regardless of your request. This is **NEW** behavior with the current SDK. The old SDK will be deprecated soon. Facebook login behavior has changed significantly, especially on iOS with App Tracking Transparency (ATT). Your backend must handle two different token types depending on user permissions and tracking settings. ### Token Types Explained Facebook now returns different token types based on **what you request** and **user consent**: | Your Request + User Choice | What You Get | Backend Handling | | ------------------------------------------------ | ------------ | ----------------------- | | **`limitedLogin: true`** | JWT Token | Validate as ID token | | **`limitedLogin: false` + User ALLOWS tracking** | Access Token | Use as OAuth credential | | **`limitedLogin: false` + User DENIES tracking** | JWT Token | Validate as ID token | **Key Points**: * If you set `limitedLogin: true` → **Always JWT token** (guaranteed) * If you set `limitedLogin: false` → **User choice determines the result** (access token OR JWT token) * You cannot force an access token if tracking is denied ### iOS App Tracking Transparency Impact On iOS, the user’s App Tracking Transparency choice directly affects the token type you receive: * **Tracking Allowed**: You get an access token (if not using limited login) * **Tracking Denied**: Automatically falls back to JWT token, regardless of your settings #### ATT Status Values When requesting tracking permission, you’ll receive one of these status values: | Status | Description | Login Behavior | | --------------- | -------------------------------------- | --------------------------------------------- | | `authorized` | User granted tracking permission | Will receive access token | | `denied` | User explicitly denied tracking | Falls back to JWT token | | `notDetermined` | User hasn’t been asked yet | Shows ATT prompt, then returns updated status | | `restricted` | Tracking restricted by device settings | Falls back to JWT token | ### Implementation with Token Detection 1. **Frontend Implementation with ATT Check** ```typescript import { SocialLogin } from '@capgo/capacitor-social-login'; import { Capacitor } from '@capacitor/core'; async function loginWithFacebook() { // Check ATT permission on iOS let proceed = true; if (Capacitor.getPlatform() === 'ios') { const trackingResponse = await SocialLogin.providerSpecificCall({ call: 'facebook#requestTracking', options: {} }); // Only proceed if user authorized tracking proceed = trackingResponse.status === 'authorized'; if (!proceed) { console.log(`App tracking status: ${trackingResponse.status}`); // You can still attempt login - it will fall back to JWT } } // Generate nonce for security const nonce = Math.random().toString(36).substring(2, 10); const hashedNonceHex = await sha256(nonce); try { const loginResult = await SocialLogin.login({ provider: 'facebook', options: { permissions: ['email', 'public_profile'], limitedLogin: false, // true for limited login, false for standard tracking nonce: nonce } }); // ⚠️ IMPORTANT: Token type behavior: // - limitedLogin: true → ALWAYS JWT token (guaranteed) // - limitedLogin: false → depends on user's App Tracking choice if (loginResult.accessToken) { // Access token - user allowed tracking console.log('Received access token:', loginResult.accessToken.token); return handleAccessToken(loginResult.accessToken.token, nonce); } else if (loginResult.idToken) { // JWT token - user denied tracking, opted out at OS level, or limited login console.log('Received JWT token:', loginResult.idToken); return handleJWTToken(loginResult.idToken); } else { console.log('Facebook login failed - no token received'); return false; } } catch (error) { console.error('Facebook login error:', error); return false; } } async function sha256(message: string) { const msgBuffer = new TextEncoder().encode(message); const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer); const hashArray = Array.from(new Uint8Array(hashBuffer)); const hashHex = hashArray .map((b) => b.toString(16).padStart(2, "0")) .join(""); return hashHex; } ``` 2. **Firebase Integration Example** ```typescript import { OAuthProvider, FacebookAuthProvider, signInWithCredential } from 'firebase/auth'; async function handleAccessToken(accessToken: string, nonce: string) { // For access tokens, use OAuthProvider (new method) const fbOAuth = new OAuthProvider("facebook.com"); const credential = fbOAuth.credential({ idToken: accessToken, rawNonce: nonce }); try { const userResponse = await signInWithCredential(auth, credential); return userResponse; } catch (error) { console.error('Firebase OAuth error:', error); return false; } } async function handleJWTToken(jwtToken: string) { // For JWT tokens, send to your backend for validation try { const response = await fetch('/api/auth/facebook-jwt', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ jwtToken }) }); const result = await response.json(); return result; } catch (error) { console.error('JWT validation error:', error); return false; } } ``` 3. **Backend JWT Validation** ```typescript // Backend: Validate JWT token from Facebook import jwt from 'jsonwebtoken'; import { Request, Response } from 'express'; app.post('/api/auth/facebook-jwt', async (req: Request, res: Response) => { const { jwtToken } = req.body; try { // Verify JWT token with Facebook's public key const decoded = jwt.verify(jwtToken, getApplePublicKey(), { algorithms: ['RS256'], audience: process.env.FACEBOOK_APP_ID, issuer: 'https://appleid.apple.com' }); // Extract user info from JWT const userInfo = { id: decoded.sub, email: decoded.email, name: decoded.name, isJWTAuth: true }; // Create your app's session/token const sessionToken = createUserSession(userInfo); res.json({ success: true, token: sessionToken, user: userInfo }); } catch (error) { console.error('JWT validation failed:', error); res.status(401).json({ success: false, error: 'Invalid token' }); } }); ``` 4. **Generic Backend Token Handler** ```typescript // Handle both token types in your backend async function authenticateFacebookUser(tokenData: any) { if (tokenData.accessToken) { // Handle access token - validate with Facebook Graph API const response = await fetch(`https://graph.facebook.com/me?access_token=${tokenData.accessToken}&fields=id,name,email`); const userInfo = await response.json(); return { user: userInfo, tokenType: 'access_token', expiresIn: tokenData.expiresIn || 3600 }; } else if (tokenData.jwtToken) { // Handle JWT token - decode and validate const decoded = jwt.verify(tokenData.jwtToken, getFacebookPublicKey()); return { user: { id: decoded.sub, name: decoded.name, email: decoded.email }, tokenType: 'jwt', expiresIn: decoded.exp - Math.floor(Date.now() / 1000) }; } else { throw new Error('No valid token provided'); } } ``` ### Key Considerations Danger **Critical Understanding**: You cannot control which token type you receive. The user’s App Tracking choice determines this, NOT your code settings. **Access Token (Standard Login)**: * ✅ Only available when user **explicitly allows** app tracking on iOS * ✅ Can be used to access Facebook Graph API * ✅ Longer expiration times * ✅ More user data available * ❌ **Becoming less common** as users increasingly deny tracking **JWT Token (New Default)**: * ✅ Always available regardless of tracking permissions * ✅ Respects user privacy preferences * ❌ Contains basic user info only * ❌ Shorter expiration times * ❌ No access to Facebook Graph API or additional profile data * ⚠️ **Now the most common scenario** with iOS users **Important**: The old method using `FacebookAuthProvider.credential(accessToken)` no longer works because Facebook now returns JWT tokens in the majority of cases. Always check the token type first. Tip **Essential**: You MUST implement both token handling methods in your app. Many developers assume they’ll always get access tokens and their apps break when users deny tracking. ## Secure Context Requirements (Web/Capacitor) ### Crypto API Limitations The updated Facebook login flow requires the **Web Crypto API** for nonce generation, which is only available in **secure contexts**: ```typescript // This requires secure context (HTTPS or localhost) async function sha256(message: string) { const msgBuffer = new TextEncoder().encode(message); const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer); // ❌ Fails in insecure context // ... } ``` ### Development Environment Issues **Common Problem**: `ionic serve` with HTTP URLs breaks Facebook authentication | Environment | Crypto API Available | Facebook Login Works | | --------------------------- | -------------------- | -------------------- | | `http://localhost:3000` | ✅ Yes | ✅ Yes | | `http://127.0.0.1:3000` | ✅ Yes | ✅ Yes | | `http://192.168.1.100:3000` | ❌ No | ❌ No | | `https://any-domain.com` | ✅ Yes | ✅ Yes | ### Solutions for Capacitor Development 1. **Use localhost for web testing** ```bash # Instead of ionic serve --host=0.0.0.0 ionic serve --host=localhost ``` 2. **Enable HTTPS in Ionic** ```bash ionic serve --ssl ``` 3. **Test on actual devices** ```bash # Capacitor apps run in secure context on devices ionic cap run ios ionic cap run android ``` 4. **Alternative nonce generation for development** ```typescript async function generateNonce() { if (typeof crypto !== 'undefined' && crypto.subtle) { // Secure context - use crypto.subtle return await sha256(Math.random().toString(36).substring(2, 10)); } else { // Fallback for development (not secure for production) console.warn('Using fallback nonce - not secure for production'); return btoa(Math.random().toString(36).substring(2, 10)); } } ``` ### Firebase Integration Note Recent Firebase documentation requires JWT tokens with nonces for Facebook authentication, regardless of login settings. This approach works with both `limitedLogin: true` and `limitedLogin: false`: ```typescript // Both modes can return JWT tokens depending on user choice const loginResult = await SocialLogin.login({ provider: 'facebook', options: { permissions: ['email', 'public_profile'], limitedLogin: false, // true = always JWT, false = depends on user tracking choice nonce: nonce } }); ``` **Development Limitation**: If you’re using `ionic serve` on a network IP (not localhost), Facebook login will fail due to crypto API restrictions. Use localhost or HTTPS for web testing. Tip **Production Safety**: Capacitor apps on iOS/Android always run in secure contexts, so this limitation only affects web development environments. ## Troubleshooting ### Common Issues and Solutions 1. **Key hash errors on Android** * Double check that you’ve added the correct key hash to the Facebook dashboard * For release builds, make sure you’ve added both debug and release key hashes * Verify you’re using the correct keystore when generating the hash 2. **Facebook login button doesn’t appear** * Verify all manifest entries are correct * Check that your Facebook App ID and Client Token are correct * Ensure you’ve properly initialized the SDK 3. **Common iOS issues** * Make sure all Info.plist entries are correct * Verify URL schemes are properly configured * Check that your bundle ID matches what’s registered in the Facebook dashboard ### Testing 1. **Before testing, add test users in the Facebook Developer Console** * Go to Roles > Test Users * Create a test user * Use these credentials for testing 2. **Test both debug and release builds** * Debug build with debug key hash * Release build with release key hash * Test on both emulator and physical devices Remember to test the full login flow, including: * Successful login * Login cancellation * Error handling * Logout functionality # Getting Started > Discover how to install and configure the Capacitor Social Login plugin to enhance your app's authentication with seamless integration for Google, Apple, and Facebook logins. 1. **Install the package** * npm ```sh npm i @capgo/capacitor-social-login ``` * pnpm ```sh pnpm add @capgo/capacitor-social-login ``` * yarn ```sh yarn add @capgo/capacitor-social-login ``` * bun ```sh bun add @capgo/capacitor-social-login ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` 3. **Configure the plugin** [![](/icons/google.svg) Google](/docs/plugins/social-login/google/general/) [Configure Google Sign-In for your app](/docs/plugins/social-login/google/general/) [ Facebook](/docs/plugins/social-login/facebook/) [Set up Facebook Login integration](/docs/plugins/social-login/facebook/) [ Apple](/docs/plugins/social-login/apple/general/) [Enable Sign in with Apple](/docs/plugins/social-login/apple/general/) # Google Login on Android > This guide provides a comprehensive walkthrough on setting up Google Login using Capacitor for Android devices, detailing each step to ensure a smooth integration process and addressing potential challenges you may encounter. ## Introduction In this guide, you will learn how to setup Google Login with Capgo Social Login for Android. I assume that you have already read the [general setup guide](/docs/plugins/social-login/google/general/). ## Using Google login on Android In this part, you will learn how to setup Google login in Android. Caution The Android SHA1 certificate is beyond painful and I wouldn’t wish it on anyone to have to set this up. The following steps assume the simplest scenario of an app that isn’t published to Google Play Store and that is only used by the local simulator, or development hardware device. If you have deployed your app to Google Play Store, you **MUST** add an additional Android client ID that contains the SHA1 from Google Play console for production releases. You can find the SHA1 hash that Google Play uses to sign your release bundle under `Test and release > Setup > App Signing`. Finally, it’s important to mention that if you mess up, the error will NOT be obvious. It may be very difficult to debug. If you struggle with the setup, please look at the [Github issues](https://github.com/Cap-go/capacitor-social-login/issues). Additionally, you may look at the troubleshooting section of the [Google Login setup for Android](#troubleshooting) for more information. Note You may create multiple Android client IDs. This is required if you have multiple SHA1 certificates. 1. Create an Android client ID. 1. Click on the search bar ![Google Console search bar](/social-login-assets/google_cons_search.png) 2. Search for `credentials` and click on the `APIs and Services` one (number 2 on the screenshot) ![Search results showing credentials option with APIs and Services highlighted](/social-login-assets/google_cons_cred_search.png) 3. Click on the `create credentials` ![Create credentials button in Google Console](/social-login-assets/google_cons_create_cred.png) 4. Select `OAuth client ID` ![OAuth client ID option in credentials creation menu](/social-login-assets/google_cons_cred_oauth.png) 5. Select the `Android` application type ![Application type selection with Android option highlighted](/social-login-assets/google_cons_app_type_android.png) 6. Open Android Studio 7. At the very bottom of the navigator, find the `Gradle Scripts` ![Gradle Scripts section in Android Studio project navigator](/social-login-assets/studio_gradle_scripts.png) 8. Find `build.gradle` for the module `app` ![build.gradle (Module: app) file in Gradle Scripts section](/social-login-assets/studio_build_gradle.png) 9. Copy the `android.defaultConfig.applicationId`. This will be your `package name` in the Google console ![Build.gradle file showing applicationId configuration](/social-login-assets/studio_build_gradle_app_id.png) 10. Now, open the terminal. Make sure that you are in the `android` folder of your app and run `./gradlew signInReport` ![Terminal showing gradlew signInReport command](/social-login-assets/term_sign_report.png) 11. Scroll to the top of this command. You should see the following. Copy the `SHA1`. ![Terminal output showing SHA1 certificate fingerprint](/social-login-assets/term_sign_report_res.png) 12. Now, go back to the Google Console. Enter your `applicationId` as the `Package Name` and your SHA1 in the certificate field and click `create` ![Android client creation form with package name and SHA1 fields filled in](/social-login-assets/google_cons_creat_android_client.png) 2. Create a web client (this is required for Android) 1. Go to the `Create credentials` page in Google Console 2. Set application type to `Web` ![Application type selection with Web option highlighted](/social-login-assets/google_cons_app_type_web.png) 3. Click `Create` ![Web client creation form with Create button at bottom](/social-login-assets/google_cons_web_app_create.png) 4. Copy the client ID, you’ll use this as the `webClientId` in your JS/TS code ![Client ID details showing Web client ID to copy](/social-login-assets/google_cons_copy_web_client_id.png) 3. Modify your `MainActivity` 1. Please open your app in Android Studio. You can run `cap open android` 2. Find `MainActivity.java` 1. Open the `app` folder ![App folder in Android Studio project navigator](/social-login-assets/studio_app_folder.png) 2. Find `java` ![Java folder in Android Studio project structure](/social-login-assets/studio_app_java.png) 3. Find your `MainActivity.java` and click on it ![MainActivity.java file in package structure](/social-login-assets/studio_app_java_activity_main.png) 3. Modify `MainActivity.java`. Please add the following code ```java import ee.forgr.capacitor.social.login.GoogleProvider; import ee.forgr.capacitor.social.login.SocialLoginPlugin; import ee.forgr.capacitor.social.login.ModifiedMainActivityForSocialLoginPlugin; import com.getcapacitor.PluginHandle; import com.getcapacitor.Plugin; import android.content.Intent; import android.util.Log; import com.getcapacitor.BridgeActivity; // ModifiedMainActivityForSocialLoginPlugin is VERY VERY important !!!!!! public class MainActivity extends BridgeActivity implements ModifiedMainActivityForSocialLoginPlugin { @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode >= GoogleProvider.REQUEST_AUTHORIZE_GOOGLE_MIN && requestCode < GoogleProvider.REQUEST_AUTHORIZE_GOOGLE_MAX) { PluginHandle pluginHandle = getBridge().getPlugin("SocialLogin"); if (pluginHandle == null) { Log.i("Google Activity Result", "SocialLogin login handle is null"); return; } Plugin plugin = pluginHandle.getInstance(); if (!(plugin instanceof SocialLoginPlugin)) { Log.i("Google Activity Result", "SocialLogin plugin instance is not SocialLoginPlugin"); return; } ((SocialLoginPlugin) plugin).handleGoogleLoginIntent(requestCode, data); } } // This function will never be called, leave it empty @Override public void IHaveModifiedTheMainActivityForTheUseWithSocialLoginPlugin() {} } ``` 4. Save the file 4. Use Google Login in your application 1. First, import `SocialLogin` ```typescript import { SocialLogin } from '@capgo/capacitor-social-login'; ``` 2. Call initialize. This should be called only once. ```typescript // onMounted is Vue specific // webClientId is the client ID you got in the web client creation step not the android client ID. onMounted(() => { SocialLogin.initialize({ google: { webClientId: '673324426943-avl4v9ubdas7a0u7igf7in03pdj1dkmg.apps.googleusercontent.com', } }) }) ``` 3. Call `SocialLogin.login`. Create a button and run the following code on click. ```typescript const res = await SocialLogin.login({ provider: 'google', options: {} }) // handle the response console.log(JSON.stringify(res)) ``` 5. Configure the emulator for testing 1. Go into `Device manager` and click the plus button ![Device Manager in Android Studio with plus button highlighted](/social-login-assets/studio_device_man.png) 2. Create a virtual device ![Create Virtual Device button in Virtual Device Configuration](/social-login-assets/studio_create_virt_dev.png) 3. Select any device with a `Play Store` icon ![Hardware selection showing devices with Play Store support](/social-login-assets/studio_new_dev_select_hardware.png) As you can see, the `pixel 8` supports the `Play Store` services 4. Click `next` ![Next button in device creation wizard](/social-login-assets/studio_new_dev_next_1.png) 5. Make sure that the OS image is of type `Google Play`. **IT MUST** be of type `Google Play` ![System image selection showing Google Play type images](/social-login-assets/studio_new_dev_google_play_dev_type.png) 6. Click next ![Next button in system image selection screen](/social-login-assets/studio_new_dev_next_1.png) 7. Confirm your device. You can name your emulator as you prefer ![Device configuration verification screen with Finish button](/social-login-assets/studio_new_dev_next_3.png) 8. Go into `Device Manager` and boot up your simulator ![Device Manager with virtual device listed and play button](/social-login-assets/studio_dev_manager.png) 9. After the simulator boots up, go into its settings ![Android emulator showing settings app](/social-login-assets/emul_and_settings_1.png) 10. Go into `Google Play` ![Settings screen with Google Play option](/social-login-assets/emul_and_settings_2.png) 11. Click `Update` and wait about 60 seconds ![Google Play update screen with Update button](/social-login-assets/emul_and_settings_update_play_store.png) 6. Test your application If you did everything correctly, you should see the Google login flow working properly: ![Demo of Google login flow on Android showing sign-in process and successful authentication](/social-login-assets/google_android_final_login_show.gif) ## Troubleshooting If you have any issues, please look at the [Github issues](https://github.com/Cap-go/capacitor-social-login/issues). The issues with Google login are **ALWAYS** related to the SHA1 certificate. If you cannot get the development SHA1 certificate, try to use a custom keystore. [Here](https://github.com/Cap-go/capacitor-social-login/issues/147#issuecomment-2849742574) is a comment explaining how to add keystore to your project. # Google Login Setup > This guide provides a comprehensive overview on setting up Google Login using Capacitor, detailing each step to ensure a seamless integration process and addressing potential challenges you may encounter. ## Introduction In this guide, you will learn how to setup Google Login with Capgo Social Login. You will need the following in order to setup Google Login: * A Google account ## General setup Note This step is required regardless of which the platform you decide to use. In this part, you will setup the login screen displayed by Google. 1. Please go to [console.cloud.google.com](https://console.cloud.google.com/) 2. Click on the project selector ![Google Console Project Selector](/social-login-assets/google_cons_project_selector.png) 3. If you don’t have a project already, please **create a new project**. 1. Click on `New project` ![New Project button in Google Console](/social-login-assets/google_cons_new_project_btn.png) 2. Name your project and click `Create` ![Project naming screen showing name field and Create button](/social-login-assets/google_cons_name_projec.png) 3. Ensure that you are on the right project ![Project name showing in the selector indicating correct project selection](/social-login-assets/google_cons_right_proj.png) 4. Start to configure the `OAuth consent screen` 1. Click on the search bar ![Google Console search bar](/social-login-assets/google_cons_search.png) 2. Search for `OAuth consent screen` and click on it ![Search results showing OAuth consent screen option](/social-login-assets/google_cons_search_2.png) 3. Configure the consent screen Note I will assume that you are developing an app open to the public, so I will use the `external` user type. Please select the user type that suits you the best AND click `create` Click on `create` ![OAuth consent screen user type selection with External and Internal options](/social-login-assets/google_cons_oauth_const_scr.png) 5. Fill the information about your app 1. Let’s start with the `App Information` ![App Information section showing App name and User support email fields](/social-login-assets/google_cons_app_inf.png) * Please type in your `App Name` Caution **THIS WILL BE DISPLAYED TO THE USERS** * Enter the `user support email` Note You can learn more about the support email [here](https://support.google.com/cloud/answer/10311615#user-support-email\&zippy=%2Cuser-support-email/) 2. You **CAN** add the app logo. ![App logo upload section in OAuth consent screen](/social-login-assets/google_cons_app_logo.png) Note This is not obligatory and I will skip this step 3. You **SHOULD** configure the `App domain` ![App domain configuration section with authorized domains field](/social-login-assets/google_cons_app_doma.png) Note I will not do that because this is just a simple demonstration that will **NOT** get published, but I strongly recommend filling this section. 4. You **HAVE TO** provide the developer’s email ![Developer contact information section with email field](/social-login-assets/google_cons_dev_cont_inf.png) 5. Click on `save and continue` ![Save and Continue button at bottom of form](/social-login-assets/google_cons_cons_sav_cont.png) 6. Configure the scopes 1. Click on `add or remove scopes` ![Add or remove scopes button in scopes configuration screen](/social-login-assets/google_cons_add_rm_sco.png) 2. Select the following scopes and click `update` ![Scope selection dialog with email and profile scopes selected](/social-login-assets/google_cons_update_scope.png) 3. Click `save and continue` ![Save and Continue button in scopes screen](/social-login-assets/google_cons_scope_save.png) 7. Add a test user 1. Click on `add users` ![Add users button in test users section](/social-login-assets/google_cons_add_test_usr.png) 2. Enter your Google email, click enter, and click `add` ![Email input field and Add button for test users](/social-login-assets/google_cons_add_test_usr_2.png) 3. Click `save and continue` ![Save and Continue button in test users screen](/social-login-assets/google_cons_test_usr_save.png) 8. Click `back to dashboard` ![Back to dashboard button at bottom of completion page](/social-login-assets/google_cons_back_to_dahs.png) 9. Submit your app for verification Note I strongly recommend submitting you app for verification. This is outside the scope of this tutorial. You can learn more [here](https://support.google.com/cloud/answer/13463073/). This isn’t required for local testing, but is required for production. ## Differences between online access and offline access There are multiple ways to use Google Login with Capacitor. Here is a table that summarizes the differences between the two: | | Online access | Offline access | | :---------------------: | :-----------: | :------------: | | Requires a backend | ❌ | ✅ | | Long-lived access token | ❌ | ✅ | | Easy setup | ✅ | ❌ | Note Long lived access tokens allow the backend to call Google API’s even when the user is not present If you still do not know which one you should choose, please consider the following scenarios: 1. You want the user to login, immediately after you are going to issue him a custom JWT. Your app will NOT call Google APIs In this case, choose online access. 2. Your app will call some Google APIs from the client, but never from the backend In this case, choose online access 3. Your app will call some google APIs from the backend, but only when the user is actively using the app In this case, choose online access 4. Your app will periodically check the user’s calendar, even when he is not actively using the app In this case, choose offline access ## An example backend for online access In this part of the tutorial, I will show how to validate the user on your backend. This example will be very simple and it will be based on the following technologies: * [Typescript](https://www.typescriptlang.org/) * [Hono](https://hono.dev/) * [Javascript’s fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Window/fetch) You can find the code for this example [here](https://github.com/WcaleNieWolny/capgo-social-login-backend-demo/blob/141c01d93a85240e31a0d488a89df13c842708b1/index.ts#L135-L153) As you can see: ![VS Code showing Google authentication code that verifies tokens](/social-login-assets/vscode_auth_google.png) The idea is rather simple. You send a simple `GET` request to `https://www.googleapis.com/oauth2/v3/tokeninfo` and this returns you whether the token is valid or not and if it it is, it gives you the email of the user. It also gives you some other info about the user token ![Google OAuth Playground showing token information response with user details](/social-login-assets/google_auth_playground_token_info.png) From there, you could issue the user with your own JWT or issue some sort of session cookie. The possibilities are endless, for the final auth implementation. If you do want to call Google API’s, I would strongly recommend looking at [Google’s OAuth 2.0 Playground](https://developers.google.com/oauthplayground). From there you can easily see what APIs you can call. ## Using offline access with your own backend In order to use online access you will need the following: * An HTTP server In this example, I will be using the following technologies to provide the offline access in my app: * [Hono](https://hono.dev/) * [Hono Zod validator](https://hono.dev/docs/guides/validation#with-zod) * [Zod](https://zod.dev/) * [Hono JWT](https://hono.dev/docs/helpers/jwt#jwt-authentication-helper) * [LowDb](https://www.npmjs.com/package/lowdb) (a simple database) The code for this example can be found [here](https://github.com/WcaleNieWolny/capgo-social-login-backend-demo/blob/aac7a8c909f650a8c2cd7f88c97f5f3c594ce9ba/index.ts#L139-L287) As for the client code, it looks like this: ```typescript import { Capacitor } from '@capacitor/core'; import { GoogleLoginOfflineResponse, SocialLogin } from '@capgo/capacitor-social-login'; import { usePopoutStore } from '@/popoutStore'; // <-- specific to my app const baseURL = "[redacted]"; async function fullLogin() { await SocialLogin.initialize({ google: { webClientId: '[redacted]', iOSClientId: '[redacted]', iOSServerClientId: 'The same value as webClientId', mode: 'offline' // <-- important } }) const response = await SocialLogin.login({ provider: 'google', options: { forceRefreshToken: true // <-- important } }) if (response.provider === 'google') { const result = response.result as GoogleLoginOfflineResponse const res = await fetch(`${baseURL}/auth/google_offline`, { headers: { "Content-Type": "application/json" }, body: JSON.stringify({ serverAuthCode: result.serverAuthCode, platform: Capacitor.getPlatform() }), method: "POST" }) if (res.status !== 200) { popoutStore.popout("Full google login failed", "check console"); return } const { jwt } = await res.json(); const userinfo = await fetch(`${baseURL}/auth/get_google_user`, { headers: { Authorization: `Bearer ${jwt}` } }) if (userinfo.status !== 200) { popoutStore.popout("Full google (userinfo) login failed", "check console"); return } popoutStore.popout("userinfo res", await userinfo.text()); } } ``` # Google Login on iOS > This guide offers a comprehensive walkthrough for configuring Google Login with Capacitor on iOS, detailing each step to ensure a smooth integration process. ## Introduction In this guide, you will learn how to setup Google Login with Capgo Social Login for iOS. I assume that you have already read the [general setup guide](/docs/plugins/social-login/google/general/). ## Using Google login on iOS In this part, you will learn how to setup Google login in iOS. 1. Create an iOS client ID in the Google console 1. Click on the search bar ![Google Console search bar](/social-login-assets/google_cons_search.png) 2. Search for `credentials` and click on the `APIs and Services` one (number 2 on the screenshot) ![Search results showing credentials option with APIs and Services highlighted](/social-login-assets/google_cons_cred_search.png) 3. Click on the `create credentials` ![Create credentials button in Google Console](/social-login-assets/google_cons_create_cred.png) 4. Select `OAuth client ID` ![OAuth client ID option in credentials creation menu](/social-login-assets/google_cons_cred_oauth.png) 5. Select the `Application type` to `iOS` ![Application type selection with iOS option highlighted](/social-login-assets/goolge_cons_cred_type_app_tye.png) 6. Find the bundle ID 1. Open Xcode 2. Double click on `App` ![App target in Xcode project navigator](/social-login-assets/xcode_app_click.png) 3. Ensure that you are on `Targets -> App` ![Targets section in Xcode with App selected](/social-login-assets/xcode_targets_app.png) 4. Find your `Bundle Identifier` ![Bundle Identifier field in Xcode project settings](/social-login-assets/xcode_bundle_id.png) 5. Go back to the Google Console and paste your `Bundle Identifier` into `Bundle ID` ![Bundle ID field in Google Console iOS client creation form](/social-login-assets/google_cons_ios_bd_id.png) 7. Optionally, add your `App Store ID` or `Team ID` into the client ID if you have published your app to App Store 8. After filling all the details, click `create` ![Create button at bottom of iOS client creation form](/social-login-assets/google_cons_ios_cred_creat.png) 9. Click `OK` ![OK button on client ID created confirmation dialog](/social-login-assets/google_cons_ios_click_ok.png) 10. Open the newly created iOS client ![Newly created iOS client in credentials list](/social-login-assets/google_cons_open_new_ios.png) 11. Copy the following data ![Client ID details showing Client ID and reversed client ID to copy](/social-login-assets/google_cons_ios_what_to_copy.png) Note The `nr. 1` in this image will later become the `iOSClientId` in the `initialize` call. The `nr. 2` in this image will later become `YOUR_DOT_REVERSED_IOS_CLIENT_ID` 2. Modify your app’s Info.plist 1. Open Xcode and find the `Info.plist` file ![Info.plist file in Xcode project navigator](/social-login-assets/xcode_info_file.png) 2. Right click this file and open it as source code ![Right-click menu showing Open As Source Code option](/social-login-assets/xcode_open_as_src_code.png) 3. At the bottom of your `Plist` file, you will see a `` tag ![Closing dict tag in Info.plist file](/social-login-assets/xcode_dict_tag.png) 4. Insert the following fragment just before the closing `` tag ![Info.plist with URL schemes code inserted before closing dict tag](/social-login-assets/xcode_plist_inserted.png) ```xml CFBundleURLTypes CFBundleURLSchemes YOUR_DOT_REVERSED_IOS_CLIENT_ID ``` 5. Change the `YOUR_DOT_REVERSED_IOS_CLIENT_ID` to the value copied in the previous step ![Info.plist with actual reversed client ID inserted in URL schemes](/social-login-assets/xcode_plist_final.png) Caution Ensure that this value **STARTS** with `com.googleusercontent.apps` 6. Save the file with `Command + S` 3. Modify the `AppDelegate.swift` 1. Open the AppDelegate ![AppDelegate.swift file in Xcode project navigator](/social-login-assets/xcode_app_deleg.png) 2. Insert `import GoogleSignIn` at the top of the file ![AppDelegate.swift with GoogleSignIn import added](/social-login-assets/xcode_app_deleg_google_sign_in.png) 3. Find the `func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:])` function ![Original application openURL function in AppDelegate](/social-login-assets/xcode_app_deleg_app_fn.png) 4. Modify the function to look like this ```swift func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { // Called when the app was launched with a url. Feel free to add additional processing here, // but if you want the App API to support tracking app url opens, make sure to keep this call var handled: Bool handled = GIDSignIn.sharedInstance.handle(url) if handled { return true } return ApplicationDelegateProxy.shared.application(app, open: url, options: options) } ``` ![Modified application openURL function with GoogleSignIn handling](/social-login-assets/xcode_app_deleg_app_fn_mod.png) 5. Save the file with `Command + S` 4. Setup Google login in your JavaScript/TypeScript code 1. Import `SocialLogin` and `Capacitor` ```typescript import { SocialLogin } from '@capgo/capacitor-social-login'; import { Capacitor } from '@capacitor/core'; ``` 2. Call the initialize method (this should be called only once) ```typescript // onMounted is Vue specific onMounted(() => { SocialLogin.initialize({ google: { iOSClientId: '673324426943-redacted.apps.googleusercontent.com', } }) }) ``` Caution Ensure that `iOSClientId` **ENDS** with `googleusercontent.com` 3. Implement the login function. Create a button and run the following code on click ```typescript const res = await SocialLogin.login({ provider: 'google', options: {} }) // handle the response console.log(JSON.stringify(res)) ``` 5. Test your application 1. Build your app and run `cap sync` 2. If you’ve done everything correctly, you should see the Google login flow working properly ![Demo of Google login flow on iOS showing sign-in process and successful authentication](/social-login-assets/google_final_ios_v2.gif) Note The language in the Google prompt depends on your device’s language settings. # Google Login on Web > This guide provides a comprehensive walkthrough for setting up Google Login on web applications using Capacitor and the @capgo/capacitor-social-login plugin, ensuring a seamless integration process by covering all necessary steps and configurations. ## Introduction In this guide, you will learn how to setup Google Login with Capgo Social Login for web applications. I assume that you have already read the [general setup guide](/docs/plugins/social-login/google/general/). ## Using Google login on the web Using the google login on the web is rather simple. In order to use it, you have to do the following: 1. Create a web client in the Google Console Note If you have already configured Google Login for Android, you can skip this step as you’ve already created a web client. You can proceed directly to step 2. 1. Click on the search bar ![Google Console search bar](/social-login-assets/google_cons_search.png) 2. Search for `credentials` and click on the `APIs and Services` option (number 2 on the screenshot) ![Search results showing credentials option with APIs and Services highlighted](/social-login-assets/google_cons_cred_search.png) 3. Click on the `create credentials` ![Create credentials button in Google Console](/social-login-assets/google_cons_create_cred.png) 4. Select `OAuth client ID` ![OAuth client ID option in credentials creation menu](/social-login-assets/google_cons_cred_oauth.png) 5. Select the `Application type` as `Web application` ![Application type selection with Web option highlighted](/social-login-assets/google_cons_app_type_web.png) 6. Name your client and click `Create` ![Web client creation form with name field highlighted](/social-login-assets/google_cons_web_app_create.png) 7. Copy the client ID, you’ll use this as the `webClientId` in your application ![Client ID details showing Web client ID to copy](/social-login-assets/google_cons_copy_web_client_id.png) 2. Configure the web client in the Google Console 1. Please open the [credentials page](https://console.cloud.google.com/apis/credentials) and click on your web client ![Credentials list showing web client to click](/social-login-assets/google_cons_open_web_client_id.png) 2. Now, please add the `Authorized JavaScript origins`. This should include all the addresses that you might use for your app. In might case, I will **ONLY** use localhost, but since I use a custom port I have to add both `http://localhost` and `http://localhost:5173` 1. Please click on `add URI` ![Authorized JavaScript origins section with ADD URI button](/social-login-assets/google_cons_authorized_js_add_btn.png) 2. Please type your URL ![ADD URI dialog with localhost URL entered](/social-login-assets/google_cons_authorized_js_typed_url.png) 3. Please repeat until you added all the URLs 4. When you finish, your screen should look something like this ![Authorized JavaScript origins with multiple localhost URLs added](/social-login-assets/google_cons_authorized_js_final.png) 3. Now, please add some `Authorized redirect URIs`. This will depend on what page do you depend to use the CapacitorSocialLogin plugin on. In my case, I am going to be using it on `http://localhost:5173/auth` 1. Please click on `ADD URI` ![Authorized redirect URIs section with ADD URI button](/social-login-assets/google_cons_web_add_redirect_url_1.png) 2. Enter your URL and click `ADD URL` again ![ADD URI dialog with redirect URL entered](/social-login-assets/google_cons_web_add_redirect_url_2.png) 4. Click `save` ![Save button at bottom of web client configuration](/social-login-assets/google_cons_web_app_save.png) 3. Now, you should be ready to call `login` from JavaScript like so: 1. First, import `SocialLogin` ```typescript import { SocialLogin } from '@capgo/capacitor-social-login'; ``` 2. Then, call initialize. This should be called ONLY once. ```typescript // onMounted is Vue specific // webClientId is the client ID you got in the web client creation step not the android client ID. onMounted(() => { SocialLogin.initialize({ google: { webClientId: '673324426943-avl4v9ubdas7a0u7igf7in03pdj1dkmg.apps.googleusercontent.com', } }) }) ``` 3. Create a login button that calls `SocialLogin.login` when clicked ```typescript const res = await SocialLogin.login({ provider: 'google', options: {} }) // Handle the response console.log(JSON.stringify(res)); ``` # Migration Guide from @capacitor-community/apple-sign-in to @capgo/capacitor-social-login > This comprehensive guide provides detailed instructions for transitioning from the @capacitor-community/apple-sign-in plugin to the @capgo/capacitor-social-login plugin, ensuring a smooth migration process. ## Installation 1. Remove the old package: ```bash npm uninstall @capacitor-community/apple-sign-in ``` 2. Install the new package: ```bash npm install @capgo/capacitor-social-login npx cap sync ``` ## Code Changes ### Import Changes ```diff import { SignInWithApple } from '@capacitor-community/apple-sign-in'; import { SocialLogin } from '@capgo/capacitor-social-login'; ``` ### Initialization ```diff // No initialization needed in old package await SocialLogin.initialize({ apple: {} // Basic iOS configuration }); // For Android, you need additional configuration: await SocialLogin.initialize({ apple: { clientId: 'YOUR_SERVICE_ID', // Service ID from Apple Developer Portal redirectUrl: 'https://your-backend.com/callback' // Your backend callback URL. Please note that this URL behaves differently than in @capacitor-community/apple-sign-in. Please refer to the documentation for more details. } }); ``` ### Sign In ```diff const result = await SignInWithApple.authorize({ clientId: 'com.your.app', redirectURI: 'https://your-app.com/callback', scopes: 'email name', state: '12345', nonce: 'nonce' }); const result = await SocialLogin.login({ provider: 'apple', options: { // Optional: Add scopes if needed scopes: ['email', 'name'], nonce: 'nonce' } }); ``` ### Response Type Changes The response object structure has changed. Here’s how to handle the new response: ```typescript // Old response type interface AppleSignInResponse { response: { user: string; email: string | null; givenName: string | null; familyName: string | null; identityToken: string | null; authorizationCode: string | null; }; } // New response type interface SocialLoginResponse { provider: 'apple'; result: { accessToken: { token: string; expiresIn?: number; refreshToken?: string; } | null; idToken: string | null; profile: { user: string; email: string | null; givenName: string | null; familyName: string | null; }; }; } ``` ### Checking Login Status ```diff // Not available in old package const status = await SocialLogin.isLoggedIn({ provider: 'apple' }); ``` ### Logout ```diff // Not available in old package await SocialLogin.logout({ provider: 'apple' }); ``` ## Platform Specific Changes ### iOS Setup 1. The iOS setup remains largely the same. You still need to: * Enable “Sign In with Apple” capability in Xcode * Configure your app in the Apple Developer Portal * No additional code changes required for iOS ### Android Setup The new plugin provides Android support out of the box, but requires additional setup: 1. Create a Services ID in the Apple Developer Portal 2. Configure a web authentication endpoint 3. Set up your Android app to handle the OAuth flow For detailed Android setup instructions, please refer to the [Android Setup Guide](/docs/plugins/social-login/apple/android/). ## Additional Features The new plugin offers several advantages: 1. Built-in Android support through web-based authentication 2. Unified API for multiple social login providers (Google, Facebook) 3. Persistent login state management 4. TypeScript support with better type definitions 5. Active maintenance and community support ## Breaking Changes 1. The initialization step is now required 2. Response object structure has changed 3. Android implementation requires a backend service 4. Token refresh handling is different 5. Error handling and error types have changed For more detailed setup instructions, please refer to the [official documentation](/docs/plugins/social-login/apple/general/). # Migration Guide from @capacitor-community/facebook-login to @capgo/capacitor-social-login > This detailed guide provides step-by-step instructions for transitioning from the @capacitor-community/facebook-login plugin to the @capgo/capacitor-social-login plugin, ensuring a smooth migration process. ## Installation 1. Remove the old package: ```bash npm uninstall @capacitor-community/facebook-login ``` 2. Install the new package: ```bash npm install @capgo/capacitor-social-login npx cap sync ``` ## Code Changes ### Import Changes ```diff import { FacebookLogin } from '@capacitor-community/facebook-login'; import { SocialLogin } from '@capgo/capacitor-social-login'; ``` ### Initialization ```diff // Old package required no explicit initialization in code // Configuration was done only in native platforms // New package requires explicit initialization await SocialLogin.initialize({ facebook: { appId: 'YOUR_FACEBOOK_APP_ID', // Required for web and Android clientToken: 'YOUR_CLIENT_TOKEN' // Required for Android } }); ``` ### Login ```diff const FACEBOOK_PERMISSIONS = ['email', 'public_profile']; const result = await FacebookLogin.login({ permissions: FACEBOOK_PERMISSIONS }); const result = await SocialLogin.login({ provider: 'facebook', options: { permissions: ['email', 'public_profile'], limitedLogin: false, nonce: 'optional_nonce' } }); ``` ### Response Type Changes The response object structure has changed. Here’s how to handle the new response: ```typescript // Old response type interface FacebookLoginResponse { accessToken: { applicationId: string; userId: string; token: string; expires: string; }; recentlyGrantedPermissions: string[]; recentlyDeniedPermissions: string[]; } // New response type interface FacebookLoginResponse { provider: 'facebook'; result: { accessToken: { token: string; applicationId?: string; expires?: string; userId?: string; permissions?: string[]; declinedPermissions?: string[]; } | null; idToken: string | null; profile: { userID: string; email: string | null; friendIDs: string[]; birthday: string | null; ageRange: { min?: number; max?: number } | null; gender: string | null; location: { id: string; name: string } | null; hometown: { id: string; name: string } | null; profileURL: string | null; name: string | null; imageURL: string | null; }; }; } ``` ### Checking Login Status ```diff const result = await FacebookLogin.getCurrentAccessToken(); const isLoggedIn = result && result.accessToken; const status = await SocialLogin.isLoggedIn({ provider: 'facebook' }); const isLoggedIn = status.isLoggedIn; ``` ### Logout ```diff await FacebookLogin.logout(); await SocialLogin.logout({ provider: 'facebook' }); ``` ## Platform Specific Changes ### Android Setup 1. The Android setup remains similar, but configuration is now done through the plugin’s initialize method: ```diff // AndroidManifest.xml changes remain the same // strings.xml become irrelevant // Additionally initialize in your code: await SocialLogin.initialize({ facebook: { appId: 'your-app-id', clientToken: 'your-client-token' // New requirement } }); ``` ### iOS Setup 1. The iOS setup in `AppDelegate.swift` remains the same: ```swift import FBSDKCoreKit // In application:didFinishLaunchingWithOptions: FBSDKCoreKit.ApplicationDelegate.shared.application( application, didFinishLaunchingWithOptions: launchOptions ) // In application:openURL:options: ApplicationDelegate.shared.application( app, open: url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String, annotation: options[UIApplication.OpenURLOptionsKey.annotation] ) ``` 2. The `Info.plist` configuration remains the same: ```xml CFBundleURLTypes CFBundleURLSchemes fb[APP_ID] FacebookAppID [APP_ID] FacebookClientToken [CLIENT_TOKEN] FacebookDisplayName [APP_NAME] LSApplicationQueriesSchemes fbapi fbauth fb-messenger-share-api fbauth2 fbshareextension ``` ## Breaking Changes 1. Explicit initialization is now required 2. Response object structure has changed significantly 3. Client token is now required for Android 4. Different method names and parameter structures 5. Error handling and error types have changed For more detailed setup instructions, please refer to the [official documentation](/docs/plugins/social-login/facebook/). # Migration Guide from @codetrix-studio/capacitor-google-auth to @capgo/capacitor-social-login > This guide provides detailed steps for migrating from @codetrix-studio/capacitor-google-auth to @capgo/capacitor-social-login, ensuring a smooth transition and improved authentication. ## Installation 1. Remove the old package: ```bash npm uninstall @codetrix-studio/capacitor-google-auth ``` 2. Install the new package: ```bash npm install @capgo/capacitor-social-login npx cap sync ``` ## Important Changes in Google Auth Setup ### Web Client ID The plugin now uses exclusively the Web Client ID for authentication. You’ll need to: 1. Create a Web Client ID in Google Cloud Console if you don’t have one ([How to get the credentials](/docs/plugins/social-login/google/general/)) 2. Use this Web Client ID in the `webClientId` field for all platforms 3. For Android, you still need to create an Android Client ID with your SHA1, but this is only for verification - the token won’t be used ([Android setup guide](/docs/plugins/social-login/google/android/)) ## Code Changes ### Import Changes ```diff import { GoogleAuth } from '@codetrix-studio/capacitor-google-auth'; import { SocialLogin } from '@capgo/capacitor-social-login'; ``` ### Initialization ```diff GoogleAuth.initialize({ clientId: 'CLIENT_ID.apps.googleusercontent.com', scopes: ['profile', 'email'], grantOfflineAccess: true, }); await SocialLogin.initialize({ google: { webClientId: 'WEB_CLIENT_ID.apps.googleusercontent.com', // Use Web Client ID for all platforms iOSClientId: 'IOS_CLIENT_ID', // for iOS mode: 'offline' // replaces grantOfflineAccess } }); ``` ### Sign In ```diff const user = await GoogleAuth.signIn(); const res = await SocialLogin.login({ provider: 'google', options: { scopes: ['email', 'profile'], forceRefreshToken: true // if you need refresh token } }); ``` ## Platform Specific Changes ### Android 1. Update your `MainActivity.java` ([Full Android setup guide](/docs/plugins/social-login/google/android/)): ```diff import ee.forgr.capacitor.social.login.GoogleProvider; import ee.forgr.capacitor.social.login.SocialLoginPlugin; import ee.forgr.capacitor.social.login.ModifiedMainActivityForSocialLoginPlugin; import com.getcapacitor.PluginHandle; import com.getcapacitor.Plugin; import android.content.Intent; import android.util.Log; public class MainActivity extends BridgeActivity { public class MainActivity extends BridgeActivity implements ModifiedMainActivityForSocialLoginPlugin { @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode >= GoogleProvider.REQUEST_AUTHORIZE_GOOGLE_MIN && requestCode < GoogleProvider.REQUEST_AUTHORIZE_GOOGLE_MAX) { PluginHandle pluginHandle = getBridge().getPlugin("SocialLogin"); if (pluginHandle == null) { Log.i("Google Activity Result", "SocialLogin login handle is null"); return; } Plugin plugin = pluginHandle.getInstance(); if (!(plugin instanceof SocialLoginPlugin)) { Log.i("Google Activity Result", "SocialLogin plugin instance is not SocialLoginPlugin"); return; } ((SocialLoginPlugin) plugin).handleGoogleLoginIntent(requestCode, data); } } public void IHaveModifiedTheMainActivityForTheUseWithSocialLoginPlugin() {} } ``` ### iOS 1. No major changes needed in AppDelegate.swift ([iOS setup guide](/docs/plugins/social-login/google/ios/)) 2. Update your configuration in `capacitor.config.json`, we don’t use it in the new plugin: ```diff { "plugins": { "GoogleAuth": { "scopes": ["profile", "email"], "serverClientId": "xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com", "forceCodeForRefreshToken": true } } ``` ### Web 1. Remove the Google Sign-In meta tags from your `index.html` if you were using them: ```diff ``` ## Response Type Changes The response object structure has changed. Here’s how to handle the new response: ```typescript interface GoogleLoginResponse { provider: 'google'; result: { accessToken: { token: string; expires: string; // ... other token fields } | null; idToken: string | null; profile: { email: string | null; familyName: string | null; givenName: string | null; id: string | null; name: string | null; imageUrl: string | null; }; }; } ``` ## Additional Features The new plugin offers additional social login providers: * [Apple Sign-In](/docs/plugins/social-login/apple/general/) * [Facebook Login](/docs/plugins/social-login/facebook/) Check the [main documentation](/docs/plugins/social-login/google/general/) for setting up these additional providers. # V7 Migration Guide > Guide for migrating from earlier versions to V7 of @capgo/capacitor-social-login ## Introduction Caution This guide is for the `V1`/`V7` version of the plugin for people who were still using this plugin with the `0.x.x` version. This guide will cover the following: * Migrating to the V1 version from the `main` version * Migrating to the V1 version from the `development` version ## Important changes in V1 V1 is just a port of the development version into main. It does, however, include a lot of important changes that are not available in the `main` V0 version. Those changes include: * Access scopes for Google login * Offline mode for Google login * Unification of the different implementations * Extensive testing was conducted to ensure that all implementations of the Google Provider behave in the same way between platforms ## Migration from the V0 main version * Changes in the `MainActivity.java` for Android * Please follow the [Google Setup Guide](/docs/plugins/social-login/google/android/). Specifically, please search for `MainActivity.java` * Please add redirect urls in the Google Console. Without adding redirect urls, Google login will not work. * Again, please follow the [Google Setup Guide](/docs/plugins/social-login/google/android/). Specifically, please search for `Authorized redirect URIs` * Please ensure that you are not using `grantOfflineAccess` in the config. This feature is not supported in V1. * Please ensure that authentication works on all the platforms. ## Migration from the V0 development version * Changes in the `MainActivity.java` for Android * Please follow the [Google Setup Guide](/docs/plugins/social-login/google/android/). Specifically, please search for `MainActivity.java`. In V1, you **HAVE TO** implement `ModifiedMainActivityForSocialLoginPlugin` in your main activity. This change is crucial for the plugin to work * Please add redirect urls in the Google Console. Without adding redirect urls, Google login will not work. * Again, please follow the [Google Setup Guide](/docs/plugins/social-login/google/android/). Specifically, please search for `Authorized redirect URIs` * Please ensure that types and variable names are correct. Please know that types and variables might not match between development and V1. * Please ensure that authentication works on all the platforms. # Capacitor Stream Call Plugin > A Capacitor plugin that uses the Stream Video SDK to enable video calling functionality in your app # @capgo/capacitor-stream-call A Capacitor plugin that uses the [Stream Video SDK](https://getstream.io/) to enable video calling functionality in your app. ## Installation * npm ```bash npm install @capgo/capacitor-stream-call npx cap sync ``` * yarn ```bash yarn add @capgo/capacitor-stream-call npx cap sync ``` * pnpm ```bash pnpm add @capgo/capacitor-stream-call npx cap sync ``` * bun ```bash bun add @capgo/capacitor-stream-call npx cap sync ``` ## Configuration ### iOS Setup #### 1. API Key Configuration Add your Stream Video API key to `ios/App/App/Info.plist`: ```xml CAPACITOR_STREAM_VIDEO_APIKEY your_api_key_here ``` #### 2. Localization (Optional) To support multiple languages: 1. Add localization files to your Xcode project: * `/App/App/en.lproj/Localizable.strings` * `/App/App/en.lproj/Localizable.stringsdict` 2. Add translations in `Localizable.strings`: ```swift "stream.video.call.incoming" = "Incoming call from %@"; "stream.video.call.accept" = "Accept"; "stream.video.call.reject" = "Reject"; "stream.video.call.hangup" = "Hang up"; "stream.video.call.joining" = "Joining..."; "stream.video.call.reconnecting" = "Reconnecting..."; ``` 3. Configure localization in your `AppDelegate.swift`: ```swift import StreamVideo @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { Appearance.localizationProvider = { key, table in Bundle.main.localizedString(forKey: key, value: nil, table: table) } return true } } ``` ### Android Setup #### 1. API Key Configuration Add your Stream Video API key to `android/app/src/main/res/values/strings.xml`: ```xml your_api_key_here ``` #### 2. MainActivity Configuration Modify your `MainActivity.java` to handle incoming calls: ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Enable activity to show over lock screen if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O_MR1) { setShowWhenLocked(true); setTurnScreenOn(true); } else { getWindow().addFlags(android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); } } ``` #### 3. Application Class Configuration Create or modify your Application class to initialize the plugin: ```java import ee.forgr.capacitor.streamcall.StreamCallPlugin; @Override public void onCreate() { super.onCreate(); // Initialize Firebase com.google.firebase.FirebaseApp.initializeApp(this); // Pre-initialize StreamCall plugin try { StreamCallPlugin.preLoadInit(this, this); } catch (Exception e) { Log.e("App", "Failed to pre-initialize StreamVideo Plugin", e); } } ``` > **Note:** If you don’t have an Application class, you need to create one and reference it in your `AndroidManifest.xml` with `android:name=".YourApplicationClass"`. #### 4. Localization (Optional) Add string resources for different languages: **Default (`values/strings.xml`):** ```xml Incoming call from %1$s Accept Reject Hang up Joining... Reconnecting... ``` **French (`values-fr/strings.xml`):** ```xml Appel entrant de %1$s Accepter Refuser Raccrocher Connexion... Reconnexion... ``` ## Displaying Caller Information When receiving incoming calls, you can access caller information including name, user ID, and profile image. This information is automatically extracted from the call data and passed through the event system. ### Getting Caller Information The caller information is available in two ways: **1. Through Call Events** The `callEvent` listener provides caller information for incoming calls: ```typescript StreamCall.addListener('callEvent', (event) => { if (event.state === 'ringing' && event.caller) { console.log('Incoming call from:', event.caller.name || event.caller.userId); console.log('Caller image:', event.caller.imageURL); // Update your UI to show caller information showIncomingCallUI(event.caller); } }); ``` **2. Through Incoming Call Events (Android lock-screen)** The `incomingCall` listener also includes caller information: ```typescript StreamCall.addListener('incomingCall', (payload) => { if (payload.caller) { console.log('Lock-screen call from:', payload.caller.name || payload.caller.userId); // Update your lock-screen UI updateLockScreenUI(payload.caller); } }); ``` ### Caller Information Structure ```typescript interface CallMember { userId: string; // User ID (always present) name?: string; // Display name (optional) imageURL?: string; // Profile image URL (optional) role?: string; // User role (optional) } ``` ## API ### login(…) ```typescript login(options: LoginOptions) => Promise ``` Login to Stream Video service | Param | Type | Description | | ------------- | -------------- | ------------------- | | **`options`** | `LoginOptions` | Login configuration | ### logout() ```typescript logout() => Promise ``` Logout from Stream Video service ### call(…) ```typescript call(options: CallOptions) => Promise ``` Initiate a call to another user | Param | Type | Description | | ------------- | ------------- | ------------------ | | **`options`** | `CallOptions` | Call configuration | ### endCall() ```typescript endCall() => Promise ``` End the current call ### setMicrophoneEnabled(…) ```typescript setMicrophoneEnabled(options: { enabled: boolean; }) => Promise ``` Enable or disable microphone | Param | Type | Description | | ------------- | ----------------------- | ---------------- | | **`options`** | `{ enabled: boolean; }` | Microphone state | ### setCameraEnabled(…) ```typescript setCameraEnabled(options: { enabled: boolean; }) => Promise ``` Enable or disable camera | Param | Type | Description | | ------------- | ----------------------- | ------------ | | **`options`** | `{ enabled: boolean; }` | Camera state | ### addListener(‘callEvent’, …) ```typescript addListener(eventName: 'callEvent', listenerFunc: (event: CallEvent) => void) => Promise<{ remove: () => Promise; }> ``` Add listener for call events | Param | Type | Description | | ------------------ | ---------------------------- | ------------------------------- | | **`eventName`** | `'callEvent'` | Name of the event to listen for | | **`listenerFunc`** | `(event: CallEvent) => void` | Callback function | ### addListener(‘incomingCall’, …) ```typescript addListener(eventName: 'incomingCall', listenerFunc: (event: IncomingCallPayload) => void) => Promise<{ remove: () => Promise; }> ``` Listen for lock-screen incoming call (Android only). Fired when the app is shown by full-screen intent before user interaction. | Param | Type | | ------------------ | -------------------------------------- | | **`eventName`** | `'incomingCall'` | | **`listenerFunc`** | `(event: IncomingCallPayload) => void` | ### acceptCall() ```typescript acceptCall() => Promise ``` Accept an incoming call ### rejectCall() ```typescript rejectCall() => Promise ``` Reject an incoming call ### isCameraEnabled() ```typescript isCameraEnabled() => Promise ``` Check if camera is enabled ### getCallStatus() ```typescript getCallStatus() => Promise ``` Get the current call status ### setSpeaker(…) ```typescript setSpeaker(options: { name: string; }) => Promise ``` Set speakerphone on | Param | Type | Description | | ------------- | ------------------- | ----------------- | | **`options`** | `{ name: string; }` | Speakerphone name | ### switchCamera(…) ```typescript switchCamera(options: { camera: 'front' | 'back'; }) => Promise ``` Switch camera | Param | Type | Description | | ------------- | -------------------------------- | ------------------- | | **`options`** | `{ camera: 'front' \| 'back'; }` | Camera to switch to | ### getCallInfo(…) ```typescript getCallInfo(options: { callId: string; }) => Promise ``` Get detailed information about an active call including caller details | Param | Type | Description | | ------------- | --------------------- | ------------------------------ | | **`options`** | `{ callId: string; }` | Options containing the call ID | ### setDynamicStreamVideoApikey(…) ```typescript setDynamicStreamVideoApikey(options: { apiKey: string; }) => Promise ``` Set a dynamic Stream Video API key that overrides the static one | Param | Type | Description | | ------------- | --------------------- | ------------------ | | **`options`** | `{ apiKey: string; }` | The API key to set | ### getDynamicStreamVideoApikey() ```typescript getDynamicStreamVideoApikey() => Promise ``` Get the currently set dynamic Stream Video API key ### getCurrentUser() ```typescript getCurrentUser() => Promise ``` Get the current user’s information ## Usage Example ```typescript import { StreamCall } from '@capgo/capacitor-stream-call'; // Login to Stream Video service await StreamCall.login({ token: 'your_stream_token', userId: 'user123', name: 'John Doe', imageURL: 'https://example.com/avatar.jpg', apiKey: 'your_stream_api_key', magicDivId: 'video-container', pushNotificationsConfig: { pushProviderName: 'firebase', voipProviderName: 'apns' } }); // Set up event listeners StreamCall.addListener('callEvent', (event) => { console.log('Call event:', event.state); if (event.state === 'ringing' && event.caller) { console.log('Incoming call from:', event.caller.name); } }); // Make a call await StreamCall.call({ userIds: ['user456'], type: 'default', ring: true, video: true }); // Accept an incoming call await StreamCall.acceptCall(); // End the call await StreamCall.endCall(); // Logout await StreamCall.logout(); ``` ## License MIT # @capgo/capacitor-twilio-voice > Integrate Twilio Voice API for high-quality VoIP calling with call management, audio controls, and real-time communication. ## Overview The Capacitor Twilio Voice plugin enables high-quality VoIP calling functionality in iOS and Android applications using Twilio’s Voice API. This plugin provides comprehensive call management, authentication, and audio controls for creating professional calling experiences. VoIP calling High-quality voice calls over internet using Twilio Voice API 📞 Call management Make, accept, reject, and end calls with full lifecycle control 🎛️ Audio controls Mute, speaker toggle, and audio routing options 🎤 Platform support Native iOS and Android implementation with push notifications 📱 ## Installation ```bash npm install @capgo/capacitor-twilio-voice npx cap sync ``` ## Core API Methods ### Authentication * `login(options: { accessToken: string })` - Authenticate with Twilio using access token * `logout()` - End user session and clear call state * `isLoggedIn()` - Check current authentication status ### Call Management * `makeCall(options: { to: string })` - Initiate outgoing call to specified number * `acceptCall(options: { callSid: string })` - Accept incoming call * `rejectCall(options: { callSid: string })` - Reject incoming call * `endCall(options?: { callSid?: string })` - Terminate active call * `muteCall(options: { muted: boolean, callSid?: string })` - Mute/unmute call audio * `setSpeaker(options: { enabled: boolean })` - Toggle speaker output ## Event Listeners The plugin provides comprehensive event handling for: * Registration events for connection status * Call state changes (connected, disconnected, ringing) * Quality warnings and connection issues * Incoming call notifications ## Platform Configuration ### iOS Setup * Requires PushKit integration for incoming calls * Certificate configuration for production use * Microphone permissions in Info.plist ### Android Setup * Firebase setup for push notifications * Microphone permissions in AndroidManifest.xml * Background service configuration ## Quick Start Example ```typescript import { TwilioVoice } from '@capgo/capacitor-twilio-voice'; // Authenticate with Twilio await TwilioVoice.login({ accessToken: 'your-twilio-access-token' }); // Make a call await TwilioVoice.makeCall({ to: '+1234567890' }); // Listen for call events TwilioVoice.addListener('callConnected', (data) => { console.log('Call connected:', data); }); ``` ## Documentation Check the [complete documentation](/docs/plugins/twilio-voice/getting-started/) for detailed setup instructions, advanced configuration, and integration examples. # @capgo/capacitor-updater > The core technology that enables live updates in Capacitor apps, allowing you to push updates without app store approvals. Over-the-air updates Push updates instantly without app store reviews 🚀 Advanced API Full control over update flow with comprehensive API methods 🛠️ Self-hosting ready Run your own update server for complete control 🏠 Comprehensive Documentation Check the [Plugin API](/docs/plugins/updater/api/) to master the plugin in just a few minutes. ## Quick Links [Live Updates Documentation ](/docs/live-updates/)Learn about channels, update behavior, rollbacks, and more in the main Live Updates section. [Getting Started Guide ](/docs/getting-started/quickstart/)Follow our quickstart guide to add live updates to your app. ## Plugin Documentation This technical reference covers: * **[Plugin API](/docs/plugins/updater/api/)** - All available methods and their usage * **[Plugin Settings](/docs/plugins/updater/settings/)** - Configuration options for capacitor.config * **[Known Issues](/docs/plugins/updater/known-issues/)** - Common problems and solutions * **[Debugging](/docs/plugins/updater/debugging/)** - How to troubleshoot update issues * **[Events](/docs/plugins/updater/events/)** - Available update events * **[Local Development](/docs/plugins/updater/local-dev/getting-started/)** - Test updates locally * **[Self-Hosted Mode](/docs/plugins/updater/self-hosted/getting-started/)** - Run your own update server ## Installation ```bash npm install @capgo/capacitor-updater npx cap sync ``` For setup and configuration, see the [Getting Started guide](/docs/getting-started/quickstart/). # Functions and settings > All available method and settings of the plugin # Updater Plugin Config See the Github [Readme](https://github.com/Cap-go/capacitor-updater) for more information. CapacitorUpdater can be configured with these options: | Prop | Type | Description | Default | Since | | ---------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | ------- | | **`appReadyTimeout`** | `number` | Configure the number of milliseconds the native plugin should wait before considering an update ‘failed’. Only available for Android and iOS. | `10000 // (10 seconds)` | | | **`responseTimeout`** | `number` | Configure the number of milliseconds the native plugin should wait before considering API timeout. Only available for Android and iOS. | `20 // (20 second)` | | | **`autoDeleteFailed`** | `boolean` | Configure whether the plugin should use automatically delete failed bundles. Only available for Android and iOS. | `true` | | | **`autoDeletePrevious`** | `boolean` | Configure whether the plugin should use automatically delete previous bundles after a successful update. Only available for Android and iOS. | `true` | | | **`autoUpdate`** | `boolean` | Configure whether the plugin should use Auto Update via an update server. Only available for Android and iOS. | `true` | | | **`resetWhenUpdate`** | `boolean` | Automatically delete previous downloaded bundles when a newer native app bundle is installed to the device. Only available for Android and iOS. | `true` | | | **`updateUrl`** | `string` | Configure the URL / endpoint to which update checks are sent. Only available for Android and iOS. | `https://plugin.capgo.app/updates` | | | **`channelUrl`** | `string` | Configure the URL / endpoint for channel operations. Only available for Android and iOS. | `https://plugin.capgo.app/channel_self` | | | **`statsUrl`** | `string` | Configure the URL / endpoint to which update statistics are sent. Only available for Android and iOS. Set to "" to disable stats reporting. | `https://plugin.capgo.app/stats` | | | **`publicKey`** | `string` | Configure the public key for end to end live update encryption Version 2 Only available for Android and iOS. | `undefined` | 6.2.0 | | **`version`** | `string` | Configure the current version of the app. This will be used for the first update request. If not set, the plugin will get the version from the native code. Only available for Android and iOS. | `undefined` | 4.17.48 | | **`directUpdate`** | `boolean \| ‘always’ \| ‘atInstall’` | Configure when the plugin should direct install updates. Only for autoUpdate mode. Works well for apps less than 10MB and with uploads done using —partial flag. Zip or apps more than 10MB will be relatively slow for users to update. - false: Never do direct updates (default behavior) - atInstall: Direct update only when app is installed/updated from store, otherwise use normal background update - always: Always do direct updates immediately when available - true: (deprecated) Same as “always” for backward compatibility Only available for Android and iOS. | `false` | 5.1.0 | | **`autoSplashscreen`** | `boolean` | Automatically handle splashscreen hiding when using directUpdate. When enabled, the plugin will automatically hide the splashscreen after updates are applied or when no update is needed. This removes the need to manually listen for appReady events and call SplashScreen.hide(). Only works when directUpdate is set to “atInstall”, “always”, or true. Requires the @capacitor/splash-screen plugin to be installed and configured with launchAutoHide: false. Requires autoUpdate and directUpdate to be enabled. Only available for Android and iOS. | `false` | 7.6.0 | | **`periodCheckDelay`** | `number` | Configure the delay period for period update check. the unit is in seconds. Only available for Android and iOS. Cannot be less than 600 seconds (10 minutes). | `600 // (10 minutes)` | | | **`localS3`** | `boolean` | Configure the CLI to use a local server for testing or self-hosted update server. | `undefined` | 4.17.48 | | **`localHost`** | `string` | Configure the CLI to use a local server for testing or self-hosted update server. | `undefined` | 4.17.48 | | **`localWebHost`** | `string` | Configure the CLI to use a local server for testing or self-hosted update server. | `undefined` | 4.17.48 | | **`localSupa`** | `string` | Configure the CLI to use a local server for testing or self-hosted update server. | `undefined` | 4.17.48 | | **`localSupaAnon`** | `string` | Configure the CLI to use a local server for testing. | `undefined` | 4.17.48 | | **`localApi`** | `string` | Configure the CLI to use a local api for testing. | `undefined` | 6.3.3 | | **`localApiFiles`** | `string` | Configure the CLI to use a local file api for testing. | `undefined` | 6.3.3 | | **`allowModifyUrl`** | `boolean` | Allow the plugin to modify the updateUrl, statsUrl and channelUrl dynamically from the JavaScript side. | `false` | 5.4.0 | | **`defaultChannel`** | `string` | Set the default channel for the app in the config. Case sensitive. This will setting will override the default channel set in the cloud, but will still respect overrides made in the cloud. | `undefined` | 5.5.0 | | **`appId`** | `string` | Configure the app id for the app in the config. | `undefined` | 6.0.0 | | **`keepUrlPathAfterReload`** | `boolean` | Configure the plugin to keep the URL path after a reload. WARNING: When a reload is triggered, ‘window\.history’ will be cleared. | `false` | 6.8.0 | | **`disableJSLogging`** | `boolean` | Disable the JavaScript logging of the plugin. if true, the plugin will not log to the JavaScript console. only the native log will be done | `false` | 7.3.0 | | **`shakeMenu`** | `boolean` | Enable shake gesture to show update menu for debugging/testing purposes | `false` | 7.5.0 | ## Examples In `capacitor.config.json`: ```json { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 // (1 second), "responseTimeout": 10 // (10 second), "autoDeleteFailed": false, "autoDeletePrevious": false, "autoUpdate": false, "resetWhenUpdate": false, "updateUrl": https://example.com/api/auto_update, "channelUrl": https://example.com/api/channel, "statsUrl": https://example.com/api/stats, "publicKey": undefined, "version": undefined, "directUpdate": undefined, "autoSplashscreen": undefined, "periodCheckDelay": undefined, "localS3": undefined, "localHost": undefined, "localWebHost": undefined, "localSupa": undefined, "localSupaAnon": undefined, "localApi": undefined, "localApiFiles": undefined, "allowModifyUrl": undefined, "defaultChannel": undefined, "appId": undefined, "keepUrlPathAfterReload": undefined, "disableJSLogging": undefined, "shakeMenu": undefined } } } ``` In `capacitor.config.ts`: ```ts /// import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { appReadyTimeout: 1000 // (1 second), responseTimeout: 10 // (10 second), autoDeleteFailed: false, autoDeletePrevious: false, autoUpdate: false, resetWhenUpdate: false, updateUrl: https://example.com/api/auto_update, channelUrl: https://example.com/api/channel, statsUrl: https://example.com/api/stats, publicKey: undefined, version: undefined, directUpdate: undefined, autoSplashscreen: undefined, periodCheckDelay: undefined, localS3: undefined, localHost: undefined, localWebHost: undefined, localSupa: undefined, localSupaAnon: undefined, localApi: undefined, localApiFiles: undefined, allowModifyUrl: undefined, defaultChannel: undefined, appId: undefined, keepUrlPathAfterReload: undefined, disableJSLogging: undefined, shakeMenu: undefined, }, }, }; export default config; ``` * [`notifyAppReady()`](#notifyappready) * [`setUpdateUrl(...)`](#setupdateurl) * [`setStatsUrl(...)`](#setstatsurl) * [`setChannelUrl(...)`](#setchannelurl) * [`download(...)`](#download) * [`next(...)`](#next) * [`set(...)`](#set) * [`delete(...)`](#delete) * [`list(...)`](#list) * [`reset(...)`](#reset) * [`current()`](#current) * [`reload()`](#reload) * [`setMultiDelay(...)`](#setmultidelay) * [`cancelDelay()`](#canceldelay) * [`getLatest(...)`](#getlatest) * [`setChannel(...)`](#setchannel) * [`unsetChannel(...)`](#unsetchannel) * [`getChannel()`](#getchannel) * [`listChannels()`](#listchannels) * [`setCustomId(...)`](#setcustomid) * [`getBuiltinVersion()`](#getbuiltinversion) * [`getDeviceId()`](#getdeviceid) * [`getPluginVersion()`](#getpluginversion) * [`isAutoUpdateEnabled()`](#isautoupdateenabled) * [`removeAllListeners()`](#removealllisteners) * [`addListener('download', ...)`](#addlistenerdownload-) * [`addListener('noNeedUpdate', ...)`](#addlistenernoneedupdate-) * [`addListener('updateAvailable', ...)`](#addlistenerupdateavailable-) * [`addListener('downloadComplete', ...)`](#addlistenerdownloadcomplete-) * [`addListener('majorAvailable', ...)`](#addlistenermajoravailable-) * [`addListener('updateFailed', ...)`](#addlistenerupdatefailed-) * [`addListener('downloadFailed', ...)`](#addlistenerdownloadfailed-) * [`addListener('appReloaded', ...)`](#addlistenerappreloaded-) * [`addListener('appReady', ...)`](#addlistenerappready-) * [`isAutoUpdateAvailable()`](#isautoupdateavailable) * [`getNextBundle()`](#getnextbundle) * [`setShakeMenu(...)`](#setshakemenu) * [`isShakeMenuEnabled()`](#isshakemenuenabled) * [Interfaces](#interfaces) * [Type Aliases](#type-aliases) # Methods ## notifyAppReady() ```typescript notifyAppReady() => Promise ``` Notify Capacitor Updater that the current bundle is working (a rollback will occur if this method is not called on every app launch) By default this method should be called in the first 10 sec after app launch, otherwise a rollback will occur. Change this behaviour with {@link appReadyTimeout} **Returns:** `Promise` *** ## setUpdateUrl(…) ```typescript setUpdateUrl(options: UpdateUrl) => Promise ``` Set the updateUrl for the app, this will be used to check for updates. | Param | Type | Description | | ------------- | ----------- | ------------------------------------------------- | | **`options`** | `UpdateUrl` | contains the URL to use for checking for updates. | **Since:** 5.4.0 *** ## setStatsUrl(…) ```typescript setStatsUrl(options: StatsUrl) => Promise ``` Set the statsUrl for the app, this will be used to send statistics. Passing an empty string will disable statistics gathering. | Param | Type | Description | | ------------- | ---------- | ----------------------------------------------- | | **`options`** | `StatsUrl` | contains the URL to use for sending statistics. | **Since:** 5.4.0 *** ## setChannelUrl(…) ```typescript setChannelUrl(options: ChannelUrl) => Promise ``` Set the channelUrl for the app, this will be used to set the channel. | Param | Type | Description | | ------------- | ------------ | ------------------------------------------------ | | **`options`** | `ChannelUrl` | contains the URL to use for setting the channel. | **Since:** 5.4.0 *** ## download(…) ```typescript download(options: DownloadOptions) => Promise ``` Download a new bundle from the provided URL, it should be a zip file, with files inside or with a unique id inside with all your files | Param | Type | Description | | ------------- | ----------------- | --------------------------------------------------------------------------------- | | **`options`** | `DownloadOptions` | The {@link [DownloadOptions](#downloadoptions)} for downloading a new bundle zip. | **Returns:** `Promise` *** ## next(…) ```typescript next(options: BundleId) => Promise ``` Set the next bundle to be used when the app is reloaded. | Param | Type | Description | | ------------- | ---------- | -------------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | Contains the ID of the next Bundle to set on next app launch. {@link [BundleInfo.id](#bundleinfo)} | **Returns:** `Promise` *** ## set(…) ```typescript set(options: BundleId) => Promise ``` Set the current bundle and immediately reloads the app. | Param | Type | Description | | ------------- | ---------- | -------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | A {@link [BundleId](#bundleid)} object containing the new bundle id to set as current. | *** ## delete(…) ```typescript delete(options: BundleId) => Promise ``` Deletes the specified bundle from the native app storage. Use with {@link list} to get the stored Bundle IDs. | Param | Type | Description | | ------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | A {@link [BundleId](#bundleid)} object containing the ID of a bundle to delete (note, this is the bundle id, NOT the version name) | *** ## list(…) ```typescript list(options?: ListOptions | undefined) => Promise ``` Get all locally downloaded bundles in your app | Param | Type | Description | | ------------- | ------------- | ----------------------------------------------------------- | | **`options`** | `ListOptions` | The {@link [ListOptions](#listoptions)} for listing bundles | **Returns:** `Promise` *** ## reset(…) ```typescript reset(options?: ResetOptions | undefined) => Promise ``` Reset the app to the `builtin` bundle (the one sent to Apple App Store / Google Play Store ) or the last successfully loaded bundle. | Param | Type | Description | | ------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **`options`** | `ResetOptions` | Containing {@link [ResetOptions.toLastSuccessful](#resetoptions)}, `true` resets to the builtin bundle and `false` will reset to the last successfully loaded bundle. | *** ## current() ```typescript current() => Promise ``` Get the current bundle, if none are set it returns `builtin`. currentNative is the original bundle installed on the device **Returns:** `Promise` *** ## reload() ```typescript reload() => Promise ``` Reload the view *** ## setMultiDelay(…) ```typescript setMultiDelay(options: MultiDelayConditions) => Promise ``` Sets a {@link [DelayCondition](#delaycondition)} array containing conditions that the Plugin will use to delay the update. After all conditions are met, the update process will run start again as usual, so update will be installed after a backgrounding or killing the app. For the `date` kind, the value should be an iso8601 date string. For the `background` kind, the value should be a number in milliseconds. For the `nativeVersion` kind, the value should be the version number. For the `kill` kind, the value is not used. The function has unconsistent behavior the option kill do trigger the update after the first kill and not after the next background like other options. This will be fixed in a future major release. | Param | Type | Description | | ------------- | ---------------------- | ----------------------------------------------------------------------------------------------- | | **`options`** | `MultiDelayConditions` | Containing the {@link [MultiDelayConditions](#multidelayconditions)} array of conditions to set | **Since:** 4.3.0 *** ## cancelDelay() ```typescript cancelDelay() => Promise ``` Cancels a {@link [DelayCondition](#delaycondition)} to process an update immediately. **Since:** 4.0.0 *** ## getLatest(…) ```typescript getLatest(options?: GetLatestOptions | undefined) => Promise ``` Get Latest bundle available from update Url | Param | Type | | ------------- | ------------------ | | **`options`** | `GetLatestOptions` | **Returns:** `Promise` **Since:** 4.0.0 *** ## setChannel(…) ```typescript setChannel(options: SetChannelOptions) => Promise ``` Sets the channel for this device. The channel has to allow for self assignment for this to work. Do not use this method to set the channel at boot. This method is to set the channel after the app is ready, and user interacted. If you want to set the channel at boot, use the {@link PluginsConfig} to set the default channel. This methods send to Capgo backend a request to link the device ID to the channel. Capgo can accept or refuse depending of the setting of your channel. | Param | Type | Description | | ------------- | ------------------- | --------------------------------------------------------------------- | | **`options`** | `SetChannelOptions` | Is the {@link [SetChannelOptions](#setchanneloptions)} channel to set | **Returns:** `Promise` **Since:** 4.7.0 *** ## unsetChannel(…) ```typescript unsetChannel(options: UnsetChannelOptions) => Promise ``` Unset the channel for this device. The device will then return to the default channel | Param | Type | | ------------- | --------------------- | | **`options`** | `UnsetChannelOptions` | **Since:** 4.7.0 *** ## getChannel() ```typescript getChannel() => Promise ``` Get the channel for this device **Returns:** `Promise` **Since:** 4.8.0 *** ## listChannels() ```typescript listChannels() => Promise ``` List all channels available for this device that allow self-assignment **Returns:** `Promise` **Since:** 7.5.0 *** ## setCustomId(…) ```typescript setCustomId(options: SetCustomIdOptions) => Promise ``` Set a custom ID for this device | Param | Type | Description | | ------------- | -------------------- | ------------------------------------------------------------------------ | | **`options`** | `SetCustomIdOptions` | is the {@link [SetCustomIdOptions](#setcustomidoptions)} customId to set | **Since:** 4.9.0 *** ## getBuiltinVersion() ```typescript getBuiltinVersion() => Promise ``` Get the native app version or the builtin version if set in config **Returns:** `Promise` **Since:** 5.2.0 *** ## getDeviceId() ```typescript getDeviceId() => Promise ``` Get unique ID used to identify device (sent to auto update server) **Returns:** `Promise` *** ## getPluginVersion() ```typescript getPluginVersion() => Promise ``` Get the native Capacitor Updater plugin version (sent to auto update server) **Returns:** `Promise` *** ## isAutoUpdateEnabled() ```typescript isAutoUpdateEnabled() => Promise ``` Get the state of auto update config. **Returns:** `Promise` *** ## removeAllListeners() ```typescript removeAllListeners() => Promise ``` Remove all listeners for this plugin. **Since:** 1.0.0 *** ## addListener(‘download’, …) ```typescript addListener(eventName: 'download', listenerFunc: (state: DownloadEvent) => void) => Promise ``` Listen for bundle download event in the App. Fires once a download has started, during downloading and when finished. This will return you all download percent during the download | Param | Type | | ------------------ | -------------------------------- | | **`eventName`** | `’download’` | | **`listenerFunc`** | `(state: DownloadEvent) => void` | **Returns:** `Promise` **Since:** 2.0.11 *** ## addListener(‘noNeedUpdate’, …) ```typescript addListener(eventName: 'noNeedUpdate', listenerFunc: (state: NoNeedEvent) => void) => Promise ``` Listen for no need to update event, useful when you want force check every time the app is launched | Param | Type | | ------------------ | ------------------------------ | | **`eventName`** | `’noNeedUpdate’` | | **`listenerFunc`** | `(state: NoNeedEvent) => void` | **Returns:** `Promise` **Since:** 4.0.0 *** ## addListener(‘updateAvailable’, …) ```typescript addListener(eventName: 'updateAvailable', listenerFunc: (state: UpdateAvailableEvent) => void) => Promise ``` Listen for available update event, useful when you want to force check every time the app is launched | Param | Type | | ------------------ | --------------------------------------- | | **`eventName`** | `’updateAvailable’` | | **`listenerFunc`** | `(state: UpdateAvailableEvent) => void` | **Returns:** `Promise` **Since:** 4.0.0 *** ## addListener(‘downloadComplete’, …) ```typescript addListener(eventName: 'downloadComplete', listenerFunc: (state: DownloadCompleteEvent) => void) => Promise ``` Listen for downloadComplete events. | Param | Type | | ------------------ | ---------------------------------------- | | **`eventName`** | `’downloadComplete’` | | **`listenerFunc`** | `(state: DownloadCompleteEvent) => void` | **Returns:** `Promise` **Since:** 4.0.0 *** ## addListener(‘majorAvailable’, …) ```typescript addListener(eventName: 'majorAvailable', listenerFunc: (state: MajorAvailableEvent) => void) => Promise ``` Listen for Major update event in the App, let you know when major update is blocked by setting disableAutoUpdateBreaking | Param | Type | | ------------------ | -------------------------------------- | | **`eventName`** | `’majorAvailable’` | | **`listenerFunc`** | `(state: MajorAvailableEvent) => void` | **Returns:** `Promise` **Since:** 2.3.0 *** ## addListener(‘updateFailed’, …) ```typescript addListener(eventName: 'updateFailed', listenerFunc: (state: UpdateFailedEvent) => void) => Promise ``` Listen for update fail event in the App, let you know when update has fail to install at next app start | Param | Type | | ------------------ | ------------------------------------ | | **`eventName`** | `’updateFailed’` | | **`listenerFunc`** | `(state: UpdateFailedEvent) => void` | **Returns:** `Promise` **Since:** 2.3.0 *** ## addListener(‘downloadFailed’, …) ```typescript addListener(eventName: 'downloadFailed', listenerFunc: (state: DownloadFailedEvent) => void) => Promise ``` Listen for download fail event in the App, let you know when a bundle download has failed | Param | Type | | ------------------ | -------------------------------------- | | **`eventName`** | `’downloadFailed’` | | **`listenerFunc`** | `(state: DownloadFailedEvent) => void` | **Returns:** `Promise` **Since:** 4.0.0 *** ## addListener(‘appReloaded’, …) ```typescript addListener(eventName: 'appReloaded', listenerFunc: () => void) => Promise ``` Listen for reload event in the App, let you know when reload has happened | Param | Type | | ------------------ | --------------- | | **`eventName`** | `’appReloaded’` | | **`listenerFunc`** | `() => void` | **Returns:** `Promise` **Since:** 4.3.0 *** ## addListener(‘appReady’, …) ```typescript addListener(eventName: 'appReady', listenerFunc: (state: AppReadyEvent) => void) => Promise ``` Listen for app ready event in the App, let you know when app is ready to use | Param | Type | | ------------------ | -------------------------------- | | **`eventName`** | `’appReady’` | | **`listenerFunc`** | `(state: AppReadyEvent) => void` | **Returns:** `Promise` **Since:** 5.1.0 *** ## isAutoUpdateAvailable() ```typescript isAutoUpdateAvailable() => Promise ``` Get if auto update is available (not disabled by serverUrl). **Returns:** `Promise` *** ## getNextBundle() ```typescript getNextBundle() => Promise ``` Get the next bundle that will be used when the app reloads. Returns null if no next bundle is set. **Returns:** `Promise` **Since:** 6.8.0 *** ## setShakeMenu(…) ```typescript setShakeMenu(options: SetShakeMenuOptions) => Promise ``` Enable or disable the shake menu for debugging/testing purposes | Param | Type | Description | | ------------- | --------------------- | -------------------------------------------------------- | | **`options`** | `SetShakeMenuOptions` | Contains enabled boolean to enable or disable shake menu | **Since:** 7.5.0 *** ## isShakeMenuEnabled() ```typescript isShakeMenuEnabled() => Promise ``` Get the current state of the shake menu **Returns:** `Promise` **Since:** 7.5.0 *** ## Interfaces ### AppReadyResult | Prop | Type | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | ### BundleInfo | Prop | Type | | ---------------- | -------------- | | **`id`** | `string` | | **`version`** | `string` | | **`downloaded`** | `string` | | **`checksum`** | `string` | | **`status`** | `BundleStatus` | ### UpdateUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### StatsUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### ChannelUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### DownloadOptions This URL and versions are used to download the bundle from the server, If you use backend all information will be gived by the method getLatest. If you don’t use backend, you need to provide the URL and version of the bundle. Checksum and sessionKey are required if you encrypted the bundle with the CLI command encrypt, you should receive them as result of the command. | Prop | Type | Description | Default | Since | | ---------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ----- | | **`url`** | `string` | The URL of the bundle zip file (e.g: dist.zip) to be downloaded. (This can be any URL. E.g: Amazon S3, a GitHub tag, any other place you’ve hosted your bundle.) | | | | **`version`** | `string` | The version code/name of this bundle/version | | | | **`sessionKey`** | `string` | The session key for the update, when the bundle is encrypted with a session key | `undefined` | 4.0.0 | | **`checksum`** | `string` | The checksum for the update, it should be in sha256 and encrypted with private key if the bundle is encrypted | `undefined` | 4.0.0 | | **`manifest`** | `ManifestEntry[]` | The manifest for multi-file downloads | `undefined` | 6.1.0 | ### ManifestEntry | Prop | Type | | ------------------ | ---------------- | | **`file_name`** | `string \| null` | | **`file_hash`** | `string \| null` | | **`download_url`** | `string \| null` | ### BundleId | Prop | Type | | -------- | -------- | | **`id`** | `string` | ### BundleListResult | Prop | Type | | ------------- | -------------- | | **`bundles`** | `BundleInfo[]` | ### ListOptions | Prop | Type | Description | Default | Since | | --------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------ | | **`raw`** | `boolean` | Whether to return the raw bundle list or the manifest. If true, the list will attempt to read the internal database instead of files on disk. | `false` | 6.14.0 | ### ResetOptions | Prop | Type | | ---------------------- | --------- | | **`toLastSuccessful`** | `boolean` | ### CurrentBundleResult | Prop | Type | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | | **`native`** | `string` | ### MultiDelayConditions | Prop | Type | | --------------------- | ------------------ | | **`delayConditions`** | `DelayCondition[]` | ### DelayCondition | Prop | Type | Description | | ----------- | ---------------- | ---------------------------------------- | | **`kind`** | `DelayUntilNext` | Set up delay conditions in setMultiDelay | | **`value`** | `string` | | ### LatestVersion | Prop | Type | Description | Since | | ---------------- | ----------------- | -------------------------- | ----- | | **`version`** | `string` | Result of getLatest method | 4.0.0 | | **`checksum`** | `string` | | 6 | | **`major`** | `boolean` | | | | **`message`** | `string` | | | | **`sessionKey`** | `string` | | | | **`error`** | `string` | | | | **`old`** | `string` | | | | **`url`** | `string` | | | | **`manifest`** | `ManifestEntry[]` | | 6.1 | ### GetLatestOptions | Prop | Type | Description | Default | Since | | ------------- | -------- | ------------------------------------------------------------------------------------------------ | ----------- | ----- | | **`channel`** | `string` | The channel to get the latest version for The channel must allow ‘self\_assign’ for this to work | `undefined` | 6.8.0 | ### ChannelRes | Prop | Type | Description | Since | | ------------- | -------- | ----------------------------- | ----- | | **`status`** | `string` | Current status of set channel | 4.7.0 | | **`error`** | `string` | | | | **`message`** | `string` | | | ### SetChannelOptions | Prop | Type | | ----------------------- | --------- | | **`channel`** | `string` | | **`triggerAutoUpdate`** | `boolean` | ### UnsetChannelOptions | Prop | Type | | ----------------------- | --------- | | **`triggerAutoUpdate`** | `boolean` | ### GetChannelRes | Prop | Type | Description | Since | | -------------- | --------- | ----------------------------- | ----- | | **`channel`** | `string` | Current status of get channel | 4.8.0 | | **`error`** | `string` | | | | **`message`** | `string` | | | | **`status`** | `string` | | | | **`allowSet`** | `boolean` | | | ### ListChannelsResult | Prop | Type | Description | Since | | -------------- | --------------- | -------------------------- | ----- | | **`channels`** | `ChannelInfo[]` | List of available channels | 7.5.0 | ### ChannelInfo | Prop | Type | Description | Since | | -------------------- | --------- | ----------------------------------------------- | ----- | | **`id`** | `string` | The channel ID | 7.5.0 | | **`name`** | `string` | The channel name | 7.5.0 | | **`public`** | `boolean` | Whether this is a public channel | 7.5.0 | | **`allow_self_set`** | `boolean` | Whether devices can self-assign to this channel | 7.5.0 | ### SetCustomIdOptions | Prop | Type | | -------------- | -------- | | **`customId`** | `string` | ### BuiltinVersion | Prop | Type | | ------------- | -------- | | **`version`** | `string` | ### DeviceId | Prop | Type | | -------------- | -------- | | **`deviceId`** | `string` | ### PluginVersion | Prop | Type | | ------------- | -------- | | **`version`** | `string` | ### AutoUpdateEnabled | Prop | Type | | ------------- | --------- | | **`enabled`** | `boolean` | ### PluginListenerHandle | Prop | Type | | ------------ | --------------------- | | **`remove`** | `() => Promise` | ### DownloadEvent | Prop | Type | Description | Since | | ------------- | ------------ | ---------------------------------------------- | ----- | | **`percent`** | `number` | Current status of download, between 0 and 100. | 4.0.0 | | **`bundle`** | `BundleInfo` | | | ### NoNeedEvent | Prop | Type | Description | Since | | ------------ | ------------ | ---------------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Current status of download, between 0 and 100. | 4.0.0 | ### UpdateAvailableEvent | Prop | Type | Description | Since | | ------------ | ------------ | ---------------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Current status of download, between 0 and 100. | 4.0.0 | ### DownloadCompleteEvent | Prop | Type | Description | Since | | ------------ | ------------ | ------------------------------------ | ----- | | **`bundle`** | `BundleInfo` | Emit when a new update is available. | 4.0.0 | ### MajorAvailableEvent | Prop | Type | Description | Since | | ------------- | -------- | ------------------------------------------ | ----- | | **`version`** | `string` | Emit when a new major bundle is available. | 4.0.0 | ### UpdateFailedEvent | Prop | Type | Description | Since | | ------------ | ------------ | ------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Emit when a update failed to install. | 4.0.0 | ### DownloadFailedEvent | Prop | Type | Description | Since | | ------------- | -------- | -------------------------- | ----- | | **`version`** | `string` | Emit when a download fail. | 4.0.0 | ### AppReadyEvent | Prop | Type | Description | Since | | ------------ | ------------ | ------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Emitted when the app is ready to use. | 5.2.0 | | **`status`** | `string` | | | ### AutoUpdateAvailable | Prop | Type | | --------------- | --------- | | **`available`** | `boolean` | ### SetShakeMenuOptions | Prop | Type | | ------------- | --------- | | **`enabled`** | `boolean` | ### ShakeMenuEnabled | Prop | Type | | ------------- | --------- | | **`enabled`** | `boolean` | ## Type Aliases ### BundleStatus pending: The bundle is pending to be **SET** as the next bundle. downloading: The bundle is being downloaded. success: The bundle has been downloaded and is ready to be **SET** as the next bundle. error: The bundle has failed to download. `‘success’ | ‘error’ | ‘pending’ | ‘downloading’` ### DelayUntilNext `‘background’ | ‘kill’ | ‘nativeVersion’ | ‘date’` # Cordova > Exploring the potential availability of the capacitor-updater plugin for Cordova and the challenges involved in its development. You’ve been wondering if this plugin will ever be available for Cordova. We have started a R\&D repository for that, but it’s a huge amount of work. ## Problems We know we can do it but for that, we have to read all the code of Cordova codebase as we did for Capacitor, to understand how to make it work with ap Capgo features. The Android version is easier to do since both use Java, but iOS needs a full rewrite because Swift is still not well-supported in Cordova ## Solution In the mean time heres what you can do: * [Support us](https://github.com/sponsors/cap-go) on GitHub and we can prioritize that. This will need at least 1 month of work. * Hire us as a [Consultant](https://capgo.app/consulting/), we are used to help big companies migrate to Capacitor, it usually takes a month, and the [benefit](https://ionic.io/resources/articles/capacitor-vs-cordova-modern-hybrid-app-development) is huge for your team # Debugging > How to debug your updates of Capgo and understand the issue you can have with your configuration ## Understanding cloud logs: ### Sent from the backend | code | Description | | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **InvalidIp** | The user is located in a Google data center and the update is less than 4 hours old. This is done to prevent Google bots’ devices from counting as devices in your account. | | **needPlanUpgrade** (previously **needUpgrade**) | Indicates that you have reached the limit of your plan, and the device will not receive updates until you upgrade or until the next month. | | **noNew** | The device has the latest available version. | | **disablePlatformIos** | The device is on the iOS platform, but that is disabled in the channel settings. | | **disablePlatformAndroid** | The device is on the Android platform, but that is disabled in the channel settings. | | **disableAutoUpdate** | ”major" | | **disableAutoUpdateUnderNative** | The device has version (`1.2.3`), and the channel has an update (`1.2.2`) under the device version to send, but that is disabled in the channel settings. | | **disableDevBuild** | The device has a dev build, but that is disabled in the channel settings. | | **disableEmulator** | The device is an emulator, but that is disabled in the channel settings. | | **cannotGetBundle** | An error occurred while trying to retrieve the bundle information. | | **cannotUpdateViaPrivateChannel** | Device attempted an update via a private channel it doesn’t have access to. | | **channelMisconfigured** | The channel configuration is invalid or incomplete. | | **disableAutoUpdateMetadata** | Automatic updates based on metadata changes are disabled. | | **disableAutoUpdateToMajor** | Automatic updates to major versions are disabled in channel settings. | | **disableAutoUpdateToMinor** | Automatic updates to minor versions are disabled in channel settings. | | **disableAutoUpdateToPatch** | Automatic updates to patch versions are disabled in channel settings. | | **missingBundle** | The requested bundle was not found on the server. | | **NoChannelOrOverride** | No channel is set for the device and no override is provided. | ### Sent from the device | code | Description | | ------------------------------ | --------------------------------------------------------------------------------- | | **get** | Info for downloading the new version has been sent to the device. | | **delete** | One bundle has been deleted on the device. | | **set** | A bundle has been set on the device. | | **set\_fail** | The bundle failed to set. | | **reset** | The device reset to the `builtin` bundle. | | **download\_XX** | A new bundle has been downloaded - progress indicated by XX% (increments of 10%). | | **download\_complete** | The new bundle has finished downloading. | | **download\_fail** | The new bundle failed to download. | | **update\_fail** | The new bundle has been installed but failed to call `notifyAppReady`. | | **checksum\_fail** | The new bundle failed to validate the checksum. | | **windows\_path\_fail** | The zip has files who contain windows path who are illegal | | **canonical\_path\_fail** | The path of files is not canonical | | **directory\_path\_fail** | There is an error in the path of zip files | | **unzip\_fail** | unzip failed | | **low\_mem\_fail** | Download failed because of low memory in the device | | **app\_moved\_to\_background** | The application entered the background state. | | **app\_moved\_to\_foreground** | The application entered the foreground state. | | **decrypt\_fail** | Failed to decrypt the downloaded bundle. | | **getChannel** | The current channel for the device was queried. | | **setChannel** | A channel was successfully set for the device. | | **uninstall** | The application was uninstalled or Capgo data cleared. | ### Bundle status * `SUCCESS`: install bundle done * `ERROR`: install or download failed * `PENDING`: Download done, pending release * `DELETED`: Bundle deleted, still presented for stats * `DOWNLOADING`: Currently downloading a bundle ## Understanding device logs: ### Debug command: There is a debug command for Capgo cloud users. ```bash npx @capgo/cli@latest app debug ``` This will allow you to check all events happening in the app and find a solution if updates don’t happen. ### IOS to find your logs on Xcode [Getting the Device Log in Xcode ](https://intercom.help/deploygate/en/articles/4682692-getting-the-device-log-in-xcode) ### Android: to find your logs on Android studio [View logs with Logcat ](https://developer.android.com/studio/debug/am-logcat) ### Explanations Logs * `Failed to download from` **=>** same as **download\_fail** * `notifyAppReady was not called, roll back current bundle` => same as as **update\_fail** ## Finding the downloaded bundle in your device ### iOS To debug on iOS, you need to dump the app on your computer, you can do it like this: Xcode has a built-in feature for inspecting the file system of developer-installed apps on an iOS device. ![image](/ios_debug_update_1.webp) To achieve this: * Connect your device to your Mac and select Window > Devices in the Xcode menubar. * Select your device in the left pane under the Devices section. * This will show a list of developer-installed apps for that device. * Select the app you want to inspect and then select the 3 dots icon near the bottom of the screen. * Here you can view the current file system by selecting download a snapshot of it. ![image](/ios_debug_update_2.webp) Selecting Download Container… will download and export a snapshot of the file system as a .xcappdata file that you can browse through. ![image](/ios_debug_update_3.webp) Right-click on this file and select Show Package Contents to open the folder. Open the App Data folder, and you should now see a few folders like Documents, Library, tmp, etc. ![image](/ios_debug_update_4.webp) Then you will find a version in 2 folders: `library/NoCloud/ionic_built_snapshots` is necessary after the app reboot and `documents/versions` for hot reload ### Android To debug on Android, you need to access the device from Android Studio: * Click View > Tool Windows > Device File Explorer or click the Device File Explorer button in the tool window bar to open the Device File Explorer. * Select a device from the dropdown list. * Open the path **data/data/APP\_NAME/** where **APP\_NAME is your app ID.** ![image](/android_debug_update.webp) Then Find the `versions` folder to see all the versions Did you know? On Android, all versions are stored in one folder, unlike IOS where it has to be duplicated in two locations. ## Understanding ios production crash logs [How to review your app's crash logs ](https://developer.apple.com/news/?id=nra79npr) # Events > All events you can listen to in the Capacitor Updater plugin for monitoring update status and progress The Capacitor Updater plugin provides several events you can listen to for monitoring the update process and responding to different states. ## Event Listener Setup To listen to events, use the `addListener` method on the `CapacitorUpdater` object: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; // Add a listener const listener = await CapacitorUpdater.addListener('eventName', (event) => { // Handle the event }); // Remove the listener when no longer needed listener.remove(); // Remove all listeners await CapacitorUpdater.removeAllListeners(); ``` ## Available Events ### `download` Fired during the bundle download process. Provides download progress information. ```typescript CapacitorUpdater.addListener('download', (event) => { console.log(`Download progress: ${event.percent}%`); console.log('Bundle info:', event.bundle); }); ``` **Event Data:** * `percent`: number - Download progress percentage (0-100) * `bundle`: BundleInfo - Information about the bundle being downloaded Note This event fires multiple times during download to report progress. ### `noNeedUpdate` Fired when a check for updates determines that no update is needed. ```typescript CapacitorUpdater.addListener('noNeedUpdate', (event) => { console.log('App is up to date'); console.log('Current bundle:', event.bundle); }); ``` **Event Data:** * `bundle`: BundleInfo - Information about the current bundle ### `updateAvailable` Fired when a new update is available for download. ```typescript CapacitorUpdater.addListener('updateAvailable', (event) => { console.log('Update available'); console.log('New bundle:', event.bundle); // You can trigger a download here if needed }); ``` **Event Data:** * `bundle`: BundleInfo - Information about the available update bundle ### `downloadComplete` Fired when a bundle download has completed successfully. ```typescript CapacitorUpdater.addListener('downloadComplete', (event) => { console.log('Download completed'); console.log('Downloaded bundle:', event.bundle); // You might want to set this bundle as next }); ``` **Event Data:** * `bundle`: BundleInfo - Information about the downloaded bundle ### `majorAvailable` Fired when a major update is available but blocked by auto-update settings. ```typescript CapacitorUpdater.addListener('majorAvailable', (event) => { console.log('Major update available:', event.version); // Notify user about major update }); ``` **Event Data:** * `version`: string - The version number of the major update Tip Major updates typically require user confirmation or app store updates. Use this event to notify users appropriately. ### `updateFailed` Fired when an update has failed to install at the next app start. ```typescript CapacitorUpdater.addListener('updateFailed', (event) => { console.error('Update failed to install'); console.log('Failed bundle:', event.bundle); // Handle rollback or retry logic }); ``` **Event Data:** * `bundle`: BundleInfo - Information about the bundle that failed to install ### `downloadFailed` Fired when a bundle download has failed. ```typescript CapacitorUpdater.addListener('downloadFailed', (event) => { console.error('Download failed for version:', event.version); // Handle download retry logic }); ``` **Event Data:** * `version`: string - The version that failed to download ### `appReloaded` Fired when the app has been reloaded. ```typescript CapacitorUpdater.addListener('appReloaded', () => { console.log('App has been reloaded'); // Perform any necessary reinitialization }); ``` **Event Data:** None ### `appReady` Fired when the app is ready to use after an update. ```typescript CapacitorUpdater.addListener('appReady', (event) => { console.log('App is ready'); console.log('Current bundle:', event.bundle); console.log('Status:', event.status); }); ``` **Event Data:** * `bundle`: BundleInfo - Information about the current bundle * `status`: string - The ready status Caution Remember to call `notifyAppReady()` within the configured timeout (default 10 seconds) to prevent automatic rollback. ## BundleInfo Object Many events include a `BundleInfo` object with the following properties: ```typescript interface BundleInfo { id: string; // Unique bundle identifier version: string; // Bundle version downloaded: string; // Download timestamp checksum?: string; // Bundle checksum (if available) status: BundleStatus; // Bundle status } ``` Where `BundleStatus` can be: * `'success'` - Bundle downloaded successfully * `'error'` - Bundle download/installation failed * `'pending'` - Bundle is pending to be set as next * `'downloading'` - Bundle is currently downloading ## Example: Complete Update Flow Here’s an example of handling the complete update flow with events: Caution This `UpdateManager` class does not include the `CapacitorUpdater.notifyAppReady()` call required for auto-update flow. Please see the [placing notifyAppReady call correctly](/docs/plugins/updater/auto-update#placing-notifyappready-call-correctly) docs for more information. ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; export class UpdateManager { private listeners: any[] = []; async setupListeners() { // Listen for available updates this.listeners.push( await CapacitorUpdater.addListener('updateAvailable', async (event) => { console.log('Update available:', event.bundle.version); // Auto-download the update await CapacitorUpdater.download({ url: event.bundle.url, version: event.bundle.version }); }) ); // Monitor download progress this.listeners.push( await CapacitorUpdater.addListener('download', (event) => { console.log(`Downloading: ${event.percent}%`); // Update UI progress bar this.updateProgressBar(event.percent); }) ); // Handle download completion this.listeners.push( await CapacitorUpdater.addListener('downloadComplete', async (event) => { console.log('Download complete:', event.bundle.version); // Set as next bundle await CapacitorUpdater.next({ id: event.bundle.id }); }) ); // Handle failures this.listeners.push( await CapacitorUpdater.addListener('downloadFailed', (event) => { console.error('Download failed:', event.version); this.showError('Update download failed. Please try again later.'); }) ); this.listeners.push( await CapacitorUpdater.addListener('updateFailed', (event) => { console.error('Update installation failed:', event.bundle.version); this.showError('Update installation failed. The app has been rolled back.'); }) ); // Handle app ready this.listeners.push( await CapacitorUpdater.addListener('appReady', async (event) => { console.log('App ready with bundle:', event.bundle.version); }) ); } cleanup() { // Remove all listeners when no longer needed this.listeners.forEach(listener => listener.remove()); this.listeners = []; } private updateProgressBar(percent: number) { // Update your UI progress bar } private showError(message: string) { // Show error to user } } ``` ## Best Practices 1. **Always call `notifyAppReady()`**: When using auto-update, always call this method after your app initializes to prevent rollback. 2. **Handle failures gracefully**: Implement proper error handling for download and update failures. 3. **Provide user feedback**: Use the download progress event to show update progress to users. 4. **Clean up listeners**: Remove event listeners when they’re no longer needed to prevent memory leaks. 5. **Test update scenarios**: Test various update scenarios including failures, rollbacks, and major updates. # Known issues > Known issues with Capacitor and Capgo, and our updater, this page will help you understand the weird issue you have with our tool ## Ionic live reload * When you develop, if you use the Ionic live reload feature from the CLI, it will override the plugin, so you will never see your update. ## Quasar live reload * It uses the same system as ionic under the hood, so you will not see your updates. ## Updates fail * This usually happens when large updates (> 20mb) are pushed, a big percentage of users will not get the last version.\ In the past, users needed to keep the app open until the download was done, now we use background download, but it’s still limited to a few seconds. ## Android ### Cannot download We have seen some issues with devices in india, and got user on the call, made them try different DNS servers, and it worked. So if you have the issue, try to use a different DNS server like Cloudflare or Google DNS. Cloudflare: 1.1.1.1 and 1.0.0.1 Google DNS: 8.8.8.8 and 8.8.4.4 or dns.google [How to setup a preferred DNS server on Android? ](https://www.androidpolice.com/use-preferred-dns-server-android-tutorial/) ### Self Hosted When you are pushing a self-hosted update, be mindful you cannot use “HTTP” endpoint as it’s against the security policies of Android apps, if you still want to do it, follow this guide: [How to allow all Network connection types HTTP and HTTPS in Android (9) Pie? ](https://stackoverflow.com/a/51902630/5511370) ### Unzip Unzip issue: DEFLATED entries can have EXT descriptor If you zipped your bundle with something different than the CLI, the format or your zip could be incorrect, please use the CLI command `npx @capgo/cli zip BUNDLE_FOLDER`. This is a known issue of Java: [Unzip issue: DEFLATED entries can have EXT descriptor ](https://bugs.openjdk.org/browse/JDK-8143613) ### Clearfix issue * If you have issues with usesCleartextTraffic, it’s because the plugin follows the good practice recommended by sonar cloud, in 90% of the cases it will work just fine, but with some plugins that causes issues. To fix it, add in `android/app/src/main/AndroidManifest.xml` in the `` key : ```xml tools:replace="android:usesCleartextTraffic" xmlns:tools="http://schemas.android.com/tools" ``` ## IOS ### Privacy manifest Add the `NSPrivacyAccessedAPICategoryUserDefaults` dictionary key to your [Privacy Manifest](https://capacitorjs.com/docs/ios/privacy-manifest) (usually `ios/App/PrivacyInfo.xcprivacy`): ```xml NSPrivacyAccessedAPITypes NSPrivacyAccessedAPIType NSPrivacyAccessedAPICategoryUserDefaults NSPrivacyAccessedAPITypeReasons CA92.1 ``` We recommend to declare [`CA92.1`](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278401) as the reason for accessing the [`UserDefaults`](https://developer.apple.com/documentation/foundation/userdefaults) API. ### Network permissions When using local server for testing update, the app will ask for network permission, it’s a normal behavior, it’s not the case when you use a remote server. ## Both OS When doing manual mode updates, some events are not easy to catch, for example the update fail triggers just before your JS code reloads, so you will not be able to catch it. One alternative is to list the bundles and check error stats to know if the update fails. We need to find a better way to handle this in the future, but it’s not a priority, since auto mode is the recommended way to do update. PRs are welcome to help us improve this. ## CLI if your CLI has troubles doing anything, Check if **appId** and **appName** are present in your **capacitor.config.ts** Follow the guide of the official doc: [Capacitor Configuration ](https://capacitorjs.com/docs/config) # Using the capacitor updater with self-hosted capgo > How to use the capacitor updater with self-hosted Capgo, be fully autonomous with your own instance of Capgo ## What this tutorial will cover? This tutorial will show how to use capacitor updater in a dev environment with self hosted capgo ## Requirements 1. [Cloned capgo](https://github.com/Cap-go/capgo) ## Getting started To use the capacitor updater with self-hosted capgo edit the `capacitor.config.ts` from your app directory and set it like this: ```ts const config: CapacitorConfig = { appId: 'com.demo.app', appName: 'demoApp', webDir: 'dist', bundledWebRuntime: false, plugins: { CapacitorUpdater : { statsUrl: "https://localhost:54321/functions/v1/stats", channelUrl: "https://localhost:54321/functions/v1/channel_self", updateUrl: "https://localhost:54321/functions/v1/updates" }, }, }; ``` This will enable you to use local capgo in development. However, by default, this is not enough. > By default both IOS and Android expect you to use HTTPS, you need to use a tool like Ngrock or localcan to proxy your API in https. There is a way in Android to enable [plaintext communication](https://developer.android.com/topic/security/risks/cleartext). This can be achived by modifying [AndroidManifest.xml](https://github.com/Cap-go/capacitor-updater/blob/main/android/src/main/AndroidManifest.xml) and adding `android:usesCleartextTraffic="true"` in the `application` tag A full example of this change can be seen [here](https://gist.github.com/WcaleNieWolny/061a015acdebe35eaf3afd7030797701) There also could be a problem that prevents the android app from connecting. If you do not see any requests being send to edge functions run ```bash adb reverse tcp:54321 tcp:54321 ``` # Using the CLI with self-hosted capgo > This guide explains how to use the CLI with a self-hosted Capgo instance, enabling you to utilize Capgo tools on your own server instead of the cloud service. ## What this tutorial will cover? This tutorial will show how to use CLI in a dev environment with self hosted capgo ## Getting started To use the CLI with self-hosted capgo edit the `capacitor.config.ts` from your app directory and set it like this: ```ts const config: CapacitorConfig = { appId: 'com.demo.app', appName: 'demoApp', webDir: 'dist', bundledWebRuntime: false, plugins: { CapacitorUpdater : { localHost: "http://localhost:5173", localWebHost: "http://localhost:5173", localSupa: "http://localhost:54321", localSupaAnon: "see_notes", }, }, }; ``` Note: To get `localSupaAnon` please follow [this tutorial](/docs/plugin/self-hosted/local-dev/getting-started/) and copy the `anon key` into `localSupaAnon` # Contributing > A detailed guide on how to contribute to Capgo's open source projects, including the benefits of contributing, the steps involved in making contributions, and the resources available to assist contributors in the process ## Why contribute? First of all, thank you for considering contributing to capgo open source projects! It’s people like you that make capgo open source projects such great tools. Here are some reasons you might want to cinsder to contribute: * Contributing to capgo open source projects is a great way to earn some money from the [countless bounties](https://console.algora.io/org/Capgo) that are offered by the capgo team * Contributing to capgo open source projects is a great way to add a feature you would like to see * Contributing to capgo open source projects is a great way to fix a bug you encountered * [Capgo main’s license](https://github.com/Cap-go/capgo/blob/main/LICENSE) requires you to open source any changes you make to it. By contributing your code, you get to keep your changes open source and let others use it ## How to contribute * First of all, you need to fork the repository you want to contribute to * Second of all you need to commit and push your changes to that repository * Lastly, you need to open a pull request * That’s it! Now you just need to wait for the capgo team to review your PR ## Further documents to read * Capgo’s [CONTRIBUTING.MD](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTING.md) * Capgo’s [BOUNTY.md](https://github.com/Cap-go/capgo/blob/main/BOUNTY.md) # Getting started > This tutorial will show how to start the Supabase from scratch as well as start edge functions, to run Capgo on your own ## What this tutorial will cover? This tutorial will show how to start the supabase from scratch as well as start edge functions ## Requirements 1. Cloned [capgo](https://github.com/Cap-go/capgo) 2. [supabase](https://supabase.com/) ## Getting started To get started run ```bash supabase start ``` Next should see something like this: ```js Started supabase local development setup. API URL: http://localhost:54321 GraphQL URL: http://localhost:54321/graphql/v1 DB URL: postgresql://postgres:postgres@localhost:54322/postgres Studio URL: http://localhost:54323 Inbucket URL: http://localhost:54324 JWT secret: [truncated] anon key: supa_key_anon service_role key: supa_key_admin ``` Next open `configs.json` and set the following values: ```json { "base_domain": { "prod": "web.capgo.app", "development": "development.web.capgo.app", "local": "localhost:3332" }, "supa_anon": { "prod": "supa_key_anon", "development": "supa_key_anon", "local": "supa_key_anon" }, "supa_url": { "prod": "http://localhost:54321", "development": "http://localhost:54321", "local": "http://localhost:54321" } } ``` where `supa_key_anon` is the value from the previous step. Danger ⚠️ Do not commit `configs.json` into the remote repo Next, verify that you can go to [localhost:54323](http://localhost:54323/projects) and that the table `users` looks something like this ![](/supabase.webp) If it does start edge functions by running: ```bash supabase functions serve ``` and start fronend by running: ```bash bun run serve ``` # Placing CapacitorUpdater.notifyAppReady() call correctly > How to properly place the CapacitorUpdater.notifyAppReady() call in your app to ensure correct auto-update flow. The placement of the `CapacitorUpdater.notifyAppReady()` call is crucial for the correct auto-update flow. If not done correctly, the app will not be able to update to the latest version. Each version that does not call `notifyAppReady()` within 10 seconds will be marked as invalid and will be replaced by the previous valid version or the default (built-in) version. In this guide we will show you how to properly place the `notifyAppReady()` call in your app to ensure correct auto-update flow. ### `notifyAppReady()` Call Placement questionnaire 1. **What language/framework do you primarily use in your app?** ![JS + DOM API](/icons/js.svg) JS + DOM API ![TS + DOM API](/icons/ts.svg) TS + DOM API ![React](/icons/react.svg) React ![Angular](/icons/angular.svg) Angular ![Vue](/icons/vue.svg) Vue ![Svelte](/icons/svelte.svg) Svelte ![Qwik](/icons/qwik.svg) Qwik 2. **** 3. **** 4. **** Note If you cannot find your framework in the questionnaire, please don’t hesitate to ask on our [Discord](https://discord.capgo.app). # Auto Update > How to use the update endpoint of Capgo with the auto-update plugin in self-hosted mode, what they are used for and what to expect This documentation will explain how to run your auto-update server. ## Serve your bundle Make sure your bundle is served over HTTPS, and the server has the right CORS headers to allow the app to download the update. e.g. `https://myserver.com/app/updates/updates.json` If you’re unfamiliar with serving a bundle, we recommend you try Capgo Cloud or see an example here: [Serving a Bundle ](/docs/self-hosted/auto-update/update-endpoint) ## Configuration Add an `updateUrl` to your `capacitor.config.json`. ```json { "plugins": { "CapacitorUpdater": { "updateUrl": "https://myserver.com/app/updates/updates.json", } } } ``` Caution When you are pushing a self-hosted update, be mindful you cannot use “HTTP” endpoint as it’s against the security policies of Android apps, for testing purposes you can [allow it](https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted). ## Update API The plugin will do a POST call to your API each time the app is open, with this body: ```typescript interface AppInfos { "platform": "ios" | "android", "device_id": "UUID_of_device_unique_by_install", "app_id": "APPID_FROM_CAPACITOR_CONFIG", "custom_id": "your_custom_id_set_on_runtime", "plugin_version": "PLUGIN_VERSION", "version_build": "VERSION_NUMBER_FROM_NATIVE_CODE", "version_code": "VERSION_CODE_FROM_NATIVE_CODE", "version_name": "LAST_DOWNLOADER_VERSION" | "builtin" "version_os": "VERSION_OF_SYSYEM_OS", "is_emulator": boolean, "is_prod": boolean, } ``` The server API should respond, in JSON, to the capacitor-updater plugin. With this data if an update is necessary: ```json { "version": "1.2.3", "url": "https://myserver.com/app/updates/my-new-app-2.0.0.zip", "checksum": "sha256_checksum_of_bundle" } ``` In Auto-update mode the server should compare the versions and return the right one, if the URL key is present, the plugin starts the download process. If you add “message” and “error” key, the version will not be set, and the message will be displayed in logs instead. `version` key should be in [`semver`](https://semver.org/) format. The zip should have `index.html` as a file at the root, or only one folder at the root with `index.html` inside. You can use the command of the CLI to zip your bundle: Create a bundle with your files to serve from your server ```bash npx @capgo/cli bundle zip --path [/path/to/my/bundle] ``` ## Generating Bundle Checksum **Important:** You must use the Capgo CLI to create your bundle zip file. The Capgo plugin requires a specific zip format and structure that is only guaranteed when using the official CLI tool. Standard zip utilities may create incompatible archives. To generate the checksum for your bundle, use the Capgo CLI zip command with the `--json` flag: Create bundle with checksum information ```bash npx @capgo/cli bundle zip [appId] --json ``` This command will: * Create a properly formatted zip file compatible with the Capgo plugin * Generate the SHA256 checksum for integrity verification * Output bundle information in JSON format Example output: ```json { "version": "1.2.3", "checksum": "a1b2c3d4e5f6789...", "size": 1234567 } ``` Use the `checksum` value from this output in your API response to ensure the plugin can verify the bundle integrity before installation. # Encrypted Bundles > A comprehensive guide on utilizing the manual update plugin in a self-hosted environment, detailing the steps and processes involved in managing encrypted bundles for secure and efficient updates. ## End-to-end Encryption Starting with version 4.15.0 the plugin allows you to send encrypted updates. ### Step 1: Create a private key Create a private key ```bash npx @capgo/cli key create ``` ### Step 2: Create and zip your bundle Create bundle zip with checksum ```bash npx @capgo/cli bundle zip [appId] --key-v2 --json ``` The `--key-v2` flag uses the new encryption system with better checksums, and the `--json` flag will output the bundle information including the checksum that you’ll need for encryption. ### Step 3: Encrypt your bundle Encrypt bundled zip with checksum ```bash npx @capgo/cli encrypt [path/to/zip] [checksum] ``` The `checksum` parameter is the SHA256 checksum generated by the zip command in step 2. The encrypt command will return an `ivSessionKey` and generate an encrypted checksum.Remember to rename `ivSessionKey` key as `session_key` in the update payload. ### Step 4: Use in your update payload ```json { "version": "1.2.3", "url": "https://myserver.com/app/updates/my-new-app-2.0.0.zip", "session_key": "encrypted_session_key", "checksum": "encrypted_checksum_from_encrypt_command" } ``` The `session_key` is the `ivSessionKey` returned by the encrypt command, and the `checksum` is the encrypted checksum generated during encryption (not the original checksum from the zip command). Then your app will be able to use the private key to decrypt the `session_key` and use the decrypted `session_key` to decrypt the update. The encrypted checksum ensures bundle integrity verification. ## Learn More [End-to-End Encryption Guide ](https://capgo.app/blog/introducing-end-to-end-security-to-capacitor-updater-with-code-signing/)Deep dive into how Capgo's encryption system works with RSA + AES cryptography [Self-hosted Live Updates ](https://capgo.app/blog/self-hosted-live-updates/)Complete workflow for setting up self-hosted updates # Getting started > A comprehensive guide on setting up and managing your own auto-update server for seamless application updates and maintenance This documentation will explain how to run your own auto-update server. ## Introduction If you find this work helpful, please consider supporting my work by becoming a [Github sponsor](https://github.com/sponsors/riderx). I made a bet to open-source all the code I built here instead of paywalling it. By opening it up instead of fighting and hiding, I believe we can make the world a better place. Furthermore, I want to focus on Capgo tooling, and make it an open and transparent business. But to make it possible, it is necessary for all of us to do our part, including you 🥹. If Capgo doesn’t suit you, then pay your own price and [back a bootstrapped Maker](https://github.com/sponsors/riderx) on your terms. [Consider Contributing ](/docs/plugin/self-hosted/contributing/) ## Features parity If you choose to go with your own server, you will lose the 5-min setup flow.\ You need to implement all of these features yourself. | Features | Capgo | Self hosted | | ------------------------ | ----- | ----------- | | Updates | ✅ | 🚧 | | Auto revert | ✅ | 🚧 | | Email alerts on fail | ✅ | 🚧 | | Channels | ✅ | 🚧 | | Channels Override | ✅ | 🚧 | | Device Override | ✅ | 🚧 | | Channels Settings | ✅ | 🚧 | | Device Settings | ✅ | 🚧 | | Custom ID | ✅ | 🚧 | | Auto Set Channels | ✅ | 🚧 | | API Channels | ✅ | 🚧 | | Updates Statistics | ✅ | 🚧 | | Fail Download Statistics | ✅ | 🚧 | | App Usage Statistics | ✅ | 🚧 | | Update Encryption | ✅ | 🚧 | | Differential updates | ✅ | ❌ | Danger If you send a bad update to your users you can and will break their app. > Be mindful that you can’t use the Capgo cloud and your server at the same time. Danger The Over-the-Air (OTA) update feature is applicable only for modifications made to HTML, CSS, and JavaScript files. If you make any changes to the native code, such as updates to Capacitor plugins, it is mandatory to resubmit the application to the app store for approval. ## Choose between Auto and Manual In auto mode, part of the logic is handled by the Native code, updates are decided server side, this is more secure and allows fine grain updates, partial deployment to one device or group and more. In manual mode, all the logic is handled by the JS. [Auto Update ](/docs/plugin/self-hosted/auto-update/) [Manual ](/docs/plugin/self-hosted/manual-update/) ## Install Capacitor updater Install the Capacitor updater ```bash npm install @capgo/capacitor-updater npx cap sync ``` ## Prepare your bundle To send updates to your app, you need to zip it. The best way to be certain your zip is good is to use the Capgo CLI for zipping. Create a bundle with your files to serve from your server ```bash npx @capgo/cli@latest bundle zip ``` You will have to serve this zip from your server on your own. [Auto Update ](/docs/plugin/self-hosted/auto-update/) [Manual ](/docs/plugin/self-hosted/manual-update/) Note If this seems like a lot of work, try the trial Capgo Cloud. Note Differential update will not work in manual updates, but it can work in auto update, right now it’s not documented as it’s pretty complexe process # Channel API Endpoint > How to build channel management endpoints for self-hosted Capgo to handle device-channel assignments and channel queries Channels are a core mechanism for managing app updates in Capgo. In self-hosted mode, you need to implement channel endpoints to handle device assignments, channel queries, and channel management operations. ## Understanding Channels Channels allow you to: * **Control update distribution**: Assign different app versions to different user groups * **A/B testing**: Test new features with specific user segments * **Staged rollouts**: Gradually deploy updates to minimize risk * **Environment separation**: Separate development, staging, and production updates ## Configuration Configure the channel endpoint URL in your `capacitor.config.json`: ```json { "plugins": { "CapacitorUpdater": { "channelUrl": "https://myserver.com/api/channel_self" } } } ``` ## Channel Operations The plugin performs different channel operations that your endpoint needs to handle: ### 1. Get Channel (GET Request) When the plugin calls `getChannel()`, it sends a GET request to retrieve the device’s current channel assignment. #### Request Format ```typescript // GET /api/channel_self // Headers: { "Content-Type": "application/json" } // Query parameters or body: interface GetChannelRequest { device_id: string app_id: string platform: "ios" | "android" plugin_version: string version_build: string version_code: string version_name: string } ``` #### Response Format ```json { "status": "ok", "channel": "production", "allowSet": true, "message": "", "error": "" } ``` ### 2. Set Channel (POST Request) When the plugin calls `setChannel()`, it sends a POST request to assign the device to a specific channel. #### Request Format ```typescript // POST /api/channel_self interface SetChannelRequest { device_id: string app_id: string channel: string platform: "ios" | "android" plugin_version: string version_build: string version_code: string version_name: string } ``` #### Response Format ```json { "status": "ok", "message": "Device assigned to channel successfully", "error": "" } ``` ### 3. Unset Channel (DELETE Request) When the plugin calls `unsetChannel()`, it sends a DELETE request to remove the device’s channel assignment. #### Request Format ```typescript // DELETE /api/channel_self interface UnsetChannelRequest { device_id: string app_id: string platform: "ios" | "android" plugin_version: string version_build: string version_code: string version_name: string } ``` ## Implementation Example Here’s a JavaScript example of how to implement the channel endpoint: ```typescript interface ChannelRequest { device_id: string app_id: string channel?: string platform: "ios" | "android" plugin_version: string version_build: string version_code: string version_name: string } interface ChannelResponse { status: "ok" | "error" channel?: string allowSet?: boolean message?: string error?: string } export const handler = async (event) => { const method = event.httpMethod || event.method const body = JSON.parse(event.body || '{}') as ChannelRequest const { device_id, app_id, channel, platform } = body try { switch (method) { case 'GET': return await getDeviceChannel(device_id, app_id) case 'POST': return await setDeviceChannel(device_id, app_id, channel!, platform) case 'DELETE': return await unsetDeviceChannel(device_id, app_id) default: return { status: "error", error: "Method not allowed" } } } catch (error) { return { status: "error", error: error.message } } } async function getDeviceChannel(deviceId: string, appId: string): Promise { // Query your database for device channel assignment const assignment = await database.getDeviceChannel(deviceId, appId) if (assignment) { return { status: "ok", channel: assignment.channel, allowSet: assignment.allowSelfAssign } } // Return default channel if no assignment found return { status: "ok", channel: "production", // Your default channel allowSet: true } } async function setDeviceChannel( deviceId: string, appId: string, channel: string, platform: string ): Promise { // Validate channel exists and allows self-assignment const channelConfig = await database.getChannelConfig(channel, appId) if (!channelConfig) { return { status: "error", error: "Channel not found" } } if (!channelConfig.allowDeviceSelfSet) { return { status: "error", error: "Channel does not allow self-assignment" } } // Check platform restrictions if (platform === "ios" && !channelConfig.ios) { return { status: "error", error: "Channel not available for iOS" } } if (platform === "android" && !channelConfig.android) { return { status: "error", error: "Channel not available for Android" } } // Save the assignment await database.setDeviceChannel(deviceId, appId, channel) return { status: "ok", message: "Device assigned to channel successfully" } } async function unsetDeviceChannel(deviceId: string, appId: string): Promise { // Remove device channel assignment await database.removeDeviceChannel(deviceId, appId) return { status: "ok", message: "Device channel assignment removed" } } ``` ## Channel Configuration Your channel system should support these configuration options: ```typescript interface ChannelConfig { name: string appId: string // Platform targeting ios: boolean android: boolean // Device restrictions allowDeviceSelfSet: boolean // Allow setChannel() calls allowEmulator: boolean allowDev: boolean // Allow development builds // Update policies disableAutoUpdate: "major" | "minor" | "version_number" | "none" disableAutoUpdateUnderNative: boolean // Assignment isDefault: boolean // Default channel for new devices } ``` ## Database Schema Example You’ll need to store channel configurations and device assignments: ```sql -- Channels table CREATE TABLE channels ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, app_id VARCHAR(255) NOT NULL, ios BOOLEAN DEFAULT true, android BOOLEAN DEFAULT true, allow_device_self_set BOOLEAN DEFAULT false, allow_emulator BOOLEAN DEFAULT true, allow_dev BOOLEAN DEFAULT true, disable_auto_update VARCHAR(50) DEFAULT 'none', disable_auto_update_under_native BOOLEAN DEFAULT false, is_default BOOLEAN DEFAULT false, created_at TIMESTAMP DEFAULT NOW(), UNIQUE(name, app_id) ); -- Device channel assignments table CREATE TABLE device_channels ( id SERIAL PRIMARY KEY, device_id VARCHAR(255) NOT NULL, app_id VARCHAR(255) NOT NULL, channel_name VARCHAR(255) NOT NULL, assigned_at TIMESTAMP DEFAULT NOW(), UNIQUE(device_id, app_id) ); ``` ## Error Handling Handle common error scenarios: ```typescript // Channel not found { "status": "error", "error": "Channel 'beta' not found" } // Self-assignment not allowed { "status": "error", "error": "Channel does not allow device self-assignment" } // Platform not supported { "status": "error", "error": "Channel not available for this platform" } // Invalid request { "status": "error", "error": "Missing required field: device_id" } ``` ## Best Practices 1. **Security**: Validate all channel assignments against your business rules 2. **Logging**: Log all channel operations for auditing and debugging 3. **Performance**: Cache channel configurations to reduce database queries 4. **Validation**: Verify device\_id and app\_id authenticity 5. **Rate Limiting**: Implement rate limiting to prevent abuse ## Integration with Updates Channel assignments work together with your [Update API Endpoint](/docs/plugin/self-hosted/handling-updates/). When a device requests an update, check its channel assignment to determine which version to serve: ```typescript async function getUpdateForDevice(deviceId: string, appId: string) { // Get device's channel assignment const channelAssignment = await getDeviceChannel(deviceId, appId) const channel = channelAssignment.channel || 'production' // Get the version assigned to this channel const channelVersion = await getChannelVersion(channel, appId) return { version: channelVersion.version, url: channelVersion.url, checksum: channelVersion.checksum } } ``` This creates a complete self-hosted channel management system that gives you full control over how updates are distributed to your users. # Statistics API > How to use the statistics endpoint of Capgo with the auto-update plugin in self-hosted mode, what they are used for and what to expect ## Statistics API Starting from version 1.3.0 the update system is able to send stats! By default, all stats are sent to our server, to understand usage and research. Note No private data is sent for stats, only random UUID, version update, version native app, platform, action, and app ID. If you want to send this data to your server instead, change the config below: ```tsx // capacitor.config.json { "appId": "**.***.**", "appName": "Name", "plugins": { "CapacitorUpdater": { "statsUrl": "YOUR_URL" } } } ``` ## Data Structure What your server will receive is: ```tsx interface AppInfosStats { "action": "set", // can be set, delete, set_fail, reset, revert // Then it's the same info as update "app_id": "**.***.**", // app identifier in the store "device_id": "*******", // unique id per app install "platform": "ios", // or android "custom_id": "user_1", // represent your user "version_name": "1.2.3", // version of the web build "version_build": "1.2.0", // version of the native build "version_code": "120", // build number of the native build "version_os": "16", // OS version of the device "plugin_version": "4.0.0"// to make your api behave differently with different plugins "is_emulator": false, "is_prod": false, } ``` You can also totally disable it, with an empty string. Keep in mind, statistics are made private friendly and help me to understand how people use the plugin, to resolve issues and improve it. ## Implementation Example Here is an example of code in JavaScript to save the stats of the plugin: ```typescript interface AppInfos { version_name: string action: 'delete' | 'reset' | 'set' | 'set_fail' | 'update_fail' | 'windows_path_fail' | 'canonical_path_fail' | 'directory_path_fail' | 'unzip_fail' | 'low_mem_fail' | 'download_fail' | 'update_fail' | 'download_10' | 'download_20' | 'download_30' | 'download_40' | 'download_50' | 'download_60' | 'download_70' | 'download_80' | 'download_90' | 'download_complete' version_build: string version_code: string version_os: string plugin_version: string platform: string app_id: string device_id: string custom_id?: string is_prod?: boolean is_emulator?: boolean } export const handler: Handler = async (event) => { const body = JSON.parse(event.body || '{}') as AppInfos const { platform, app_id, action, version_code, version_os, device_id, version_name, version_build, plugin_version, } = body console.log('update asked', platform, app_id, action, version_os, version_code, device_id, version_name, version_build, plugin_version) // Save it in your database return { status: 'ok' } } ``` This endpoint should return a JSON: ```json { "status": "ok" } ``` ## Actions * **delete**: when a bundle is deleted locally * **reset**: when the app reset to the built-in bundle * **set**: when app sets a new bundle * **set\_fail**: when app couldn’t find the ID of the bundle set * **update\_fail**: send after the delay and `notifyAppReady` never called * **download\_fail**: when download never finished * **download\_complete**: When download finish * **download\_xx**: Send every 10% of download ex : download\_20, download\_70 * **update\_fail**: when the bundle fails to do `notifyAppReady` in the timeframe [Handling Updates ](/docs/plugin/self-hosted/handling-updates/) # Update API Endpoint > How to build your update server API endpoint to respond to Capgo plugin requests with proper bundle information and checksums Here is an example of code in JavaScript to send an update to the plugin ```typescript interface AppInfos { version_name: string version_build: string version_os: string custom_id?: string is_prod?: boolean is_emulator?: boolean plugin_version: string platform: string app_id: string device_id: string } export const handler: Handler = async (event) => { const body = JSON.parse(event.body || '{}') as AppInfos const { platform, app_id, version_os, device_id, version_name, version_build, plugin_version, } = body console.log('update asked', platform, app_id, version_os, device_id, version_name, version_build, plugin_version) if (version_name === '1.0.0') { return { version: '1.0.1', url: 'https://apiurl.com/mybuild_101.zip', checksum: 'sha256_checksum_of_bundle', } } else if (version_name === '1.0.1') { return { version: '1.0.2', url: 'https://apiurl.com/mybuild_102.zip', checksum: 'sha256_checksum_of_bundle', } } else { return { message: 'Error version not found' version: '', url: '', } } } ``` ## Response Format For **non-encrypted bundles**, your endpoint should return: ```json { "version": "1.0.2", "url": "https://apiurl.com/mybuild_102.zip", "checksum": "sha256_checksum_of_bundle" } ``` For **encrypted bundles**, you also need to include the session key: ```json { "version": "1.0.2", "url": "https://apiurl.com/mybuild_102.zip", "checksum": "encrypted_checksum_from_encrypt_command", "session_key": "ivSessionKey_from_encrypt_command" } ``` And if no update or error, add the `message` key and optionally an `error`: ```json { "message": "Version not found", "error": "The backend crashed", "version": "1.0.2", } ``` ## Field Descriptions * **`checksum`**: SHA256 hash of your bundle zip file for integrity verification * **`session_key`**: Required only for encrypted bundles - this is the `ivSessionKey` returned by the encrypt command * **`version`**: Version identifier in semver format * **`url`**: HTTPS URL where the bundle can be downloaded ## Bundle Creation To learn how to create compatible bundles and generate checksums, see the [Auto Update documentation](/docs/plugin/self-hosted/auto-update/#generating-bundle-checksum). For encrypted bundles, see the [Encrypted Bundles documentation](/docs/plugin/self-hosted/encrypted-bundles/) which explains the complete encryption workflow. # Manual Update > A detailed guide on utilizing the manual update plugin within a self-hosted environment, providing comprehensive instructions on configuration and usage to effectively manage updates without relying on automatic processes. ## Configuration Add this to your `capacitor.config.json`, to disable auto-update. ```tsx // capacitor.config.json { "appId": "**.***.**", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false, } } } ``` ## Usage You can use this example or re-create the logic in your app. Caution We are forcing the user to update the app with a static version declared in the code. This is not recommended, you should use a dynamic version from your server. Danger We are not doing any version checking, decryption or checksum validation in this example. You should do that on your own. ```tsx import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' let data = {version: ""} CapacitorUpdater.notifyAppReady() App.addListener('appStateChange', async(state) => { if (state.isActive) { // Do the download during user active app time to prevent failed download data = await CapacitorUpdater.download({ version: '0.0.4', url: 'https://github.com/Cap-go/demo-app/releases/download/0.0.4/dist.zip', }) } if (!state.isActive && data.version !== "") { // Do the switch when user leave app SplashScreen.show() try { await CapacitorUpdater.set(data) } catch (err) { console.log(err) SplashScreen.hide() // in case the set fail, otherwise the new app will have to hide it } } }) ``` Note If this seems like a lot of work consider trying [Capgo trial](https://capgo.app/register/). It will handle all of this for you. # Settings > All available settings for Capacitor Updater, all the configuration you can set in you capacitor config and what they used for To have more fine-grained control over the update system, you can configure it with these settings: Tip Any changes to these settings in capacitor.config file, require syncing the platform and releasing to the store for production apps to receive them. ## `appReadyTimeout` > Configure the number of milliseconds the native plugin should wait before considering an update ‘failed’. Only available for Android and iOS. Default: `10000` (10 seconds) capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 } } } ``` ## `responseTimeout` > Configure the number of milliseconds the native plugin should wait before considering API timeout. Only available for Android and iOS. Default: `20` (20 seconds) capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "responseTimeout": 10 // (10 seconds) } } } ``` ## `autoDeleteFailed` > Configure whether the plugin should automatically delete failed bundles. Only available for Android and iOS. Default: `true` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "autoDeleteFailed": false } } } ``` ## `autoDeletePrevious` > Configure whether the plugin should automatically delete previous bundles after a successful update. Only available for Android and iOS. Default: `true` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "autoDeletePrevious": false } } } ``` ## `autoUpdate` > Configure whether the plugin should use Auto Update via an update server. Only available for Android and iOS. Default: `true` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` ## `updateUrl` > Configure the URL / endpoint to which update checks are sent. Only available for Android and iOS. Default: `https://plugin.capgo.app/updates` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "updateUrl": "https://example.com/api/auto_update" } } } ``` ## `statsUrl` > Configure the URL / endpoint to which update statistics are sent. Only available for Android and iOS. Set to "" to disable stats reporting. Default: `https://plugin.capgo.app/stats` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "statsUrl": "https://example.com/api/stats" } } } ``` ## `publicKey` > Configure the public key for end to end live update encryption Version 2. Only available for Android and iOS. Default: `undefined` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "publicKey": "YOUR_PUBLIC_KEY" } } } ``` ## `directUpdate` > Configure when the plugin should direct install updates. Only for autoUpdate mode. Works well for apps less than 10MB and with uploads done using —partial flag. Zip or apps more than 10MB will be relatively slow for users to update. Options: * `false`: Never do direct updates (default behavior) * `'atInstall'`: Direct update only when app is installed/updated from store, otherwise use normal background update * `'always'`: Always do direct updates immediately when available * `true`: (deprecated) Same as “always” for backward compatibility Only available for Android and iOS. Default: `false` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": "atInstall" } } } ``` ## `resetWhenUpdate` > Automatically delete previous downloaded bundles when a newer native app bundle is installed to the device. Only available for Android and iOS. Default: `true` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "resetWhenUpdate": false } } } ``` ## `defaultChannel` > Set the default channel for the app in the config. Case sensitive. This setting will override the default channel set in the cloud, but will still respect overrides made in the cloud. Only available for Android and iOS. Default: `undefined` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "defaultChannel": "production" } } } ``` ## `appId` > Configure the app id for the app in the config. Only available for Android and iOS. Default: `undefined` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "appId": "com.example.app" } } } ``` ## `version` > Configure the current version of the app. This will be used for the first update request. If not set, the plugin will get the version from the native code. Only available for Android and iOS. Default: `undefined` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "version": "1.0.0" } } } ``` ## `channelUrl` > Configure the URL / endpoint for channel operations. Only available for Android and iOS. Default: `https://plugin.capgo.app/channel_self` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "channelUrl": "https://example.com/api/channel" } } } ``` ## `autoSplashscreen` > Automatically handle splashscreen hiding when using directUpdate. When enabled, the plugin will automatically hide the splashscreen after updates are applied or when no update is needed. This removes the need to manually listen for appReady events and call SplashScreen.hide(). Only works when directUpdate is set to “atInstall”, “always”, or true. Requires the @capacitor/splash-screen plugin to be installed and configured with launchAutoHide: false. Requires autoUpdate and directUpdate to be enabled. Only available for Android and iOS. Default: `false` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": "atInstall", "autoSplashscreen": true } } } ``` ## `periodCheckDelay` > Configure the delay period for period update check. The unit is in seconds. Cannot be less than 600 seconds (10 minutes). Only available for Android and iOS. Default: `600` (10 minutes) capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "periodCheckDelay": 600 // (10 minutes) } } } ``` ## `allowModifyUrl` > Allow the plugin to modify the updateUrl, statsUrl and channelUrl dynamically from the JavaScript side. Only available for Android and iOS. Default: `false` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "allowModifyUrl": true } } } ``` ## `keepUrlPathAfterReload` > Configure the plugin to keep the URL path after a reload. Caution When a reload is triggered, ‘window\.history’ will be cleared. Only available for Android and iOS. Default: `false` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "keepUrlPathAfterReload": true } } } ``` ## `disableJSLogging` > Disable the JavaScript logging of the plugin. If true, the plugin will not log to the JavaScript console. Only the native log will be done. Only available for Android and iOS. Default: `false` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "disableJSLogging": true } } } ``` ## `shakeMenu` > Enable shake gesture to show update menu for debugging/testing purposes. Only available for Android and iOS. Default: `false` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "shakeMenu": true } } } ``` ## Development Settings ### `localHost` > Configure the CLI to use a local server for testing or self-hosted update server. Default: `undefined` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "localHost": "http://localhost:5173" } } } ``` ### `localWebHost` > Configure the CLI to use a local server for testing or self-hosted update server. Default: `undefined` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "localWebHost": "http://localhost:5173" } } } ``` ### `localSupa` > Configure the CLI to use a local server for testing or self-hosted update server. Default: `undefined` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "localSupa": "http://localhost:54321" } } } ``` ### `localSupaAnon` > Configure the CLI to use a local server for testing. Default: `undefined` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "localSupaAnon": "YOUR_LOCAL_ANON_KEY" } } } ``` ### `localApi` > Configure the CLI to use a local api for testing. Default: `undefined` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "localApi": "http://localhost:54321/functions/v1" } } } ``` ### `localApiFiles` > Configure the CLI to use a local file api for testing. Default: `undefined` capacitor.config.json ```json { "plugins": { "CapacitorUpdater": { "localApiFiles": "http://localhost:54321/functions/v1/files" } } } ``` Tip There are additional settings available in the [Capgo web app](https://web.capgo.app/login) that can be configured per channel without requiring a native app release. # @capgo/capacitor-uploader > Upload files in the background with progress tracking, resumable uploads, and network-aware handling for Capacitor apps. Background uploads Continue uploads even when app is in background 🚀 Progress tracking Real-time upload progress with detailed statistics 📊 Resumable uploads Automatically resume interrupted uploads 🔄 Comprehensive Documentation Check the [Documentation](/docs/plugins/uploader/getting-started/) to master the plugin in just a few minutes. # Getting Started > Learn how to install and use the Background Uploader plugin for reliable file uploads in your Capacitor app. 1. **Install the package** * npm ```sh npm i @capgo/capacitor-uploader ``` * pnpm ```sh pnpm add @capgo/capacitor-uploader ``` * yarn ```sh yarn add @capgo/capacitor-uploader ``` * bun ```sh bun add @capgo/capacitor-uploader ``` 2. **Sync with native projects** * npm ```sh npx cap sync ``` * pnpm ```sh pnpm cap sync ``` * yarn ```sh yarn cap sync ``` * bun ```sh bunx cap sync ``` 3. **Configure permissions** ### iOS Add background modes to your `Info.plist`: ```xml UIBackgroundModes processing ``` ### Android Add permissions to your `AndroidManifest.xml`: ```xml ``` ## Usage Import the plugin and use its methods to upload files: ```typescript import { Uploader } from '@capgo/capacitor-uploader'; // Start an upload const startUpload = async () => { const upload = await Uploader.startUpload({ filePath: 'file:///path/to/your/file.jpg', serverUrl: 'https://your-server.com/upload', method: 'POST', headers: { 'Authorization': 'Bearer your-token' }, parameters: { 'userId': '12345', 'type': 'profile' }, notificationTitle: 'Uploading Photo' }); console.log('Upload ID:', upload.id); }; // Monitor upload progress const monitorProgress = async (uploadId: string) => { const listener = await Uploader.addListener( 'progressEvent', (progress) => { if (progress.id === uploadId) { console.log(`Progress: ${progress.progress}%`); console.log(`Bytes sent: ${progress.bytesSent}/${progress.bytesTotal}`); } } ); // Remember to remove listener when done // listener.remove(); }; // Handle upload completion const handleCompletion = async () => { const listener = await Uploader.addListener( 'completedEvent', (result) => { console.log('Upload completed:', result.id); console.log('Server response:', result.response); } ); }; // Handle upload errors const handleErrors = async () => { const listener = await Uploader.addListener( 'errorEvent', (error) => { console.error('Upload failed:', error.id); console.error('Error:', error.error); } ); }; // Cancel an upload const cancelUpload = async (uploadId: string) => { await Uploader.cancelUpload({ id: uploadId }); }; // Get all active uploads const getActiveUploads = async () => { const uploads = await Uploader.getUploads(); console.log('Active uploads:', uploads); }; ``` ## API Reference ### startUpload(options) Starts a new file upload. ```typescript interface UploadOptions { filePath: string; serverUrl: string; method?: 'POST' | 'PUT'; headers?: { [key: string]: string }; parameters?: { [key: string]: string }; notificationTitle?: string; notificationBody?: string; useUtf8Charset?: boolean; maxRetries?: number; } ``` ### cancelUpload(options) Cancels an ongoing upload. ```typescript interface CancelOptions { id: string; } ``` ### getUploads() Returns all active uploads. ### removeUpload(options) Removes an upload from the queue. ```typescript interface RemoveOptions { id: string; } ``` ## Events ### progressEvent Fired during upload progress. ```typescript interface ProgressEvent { id: string; progress: number; // 0-100 bytesSent: number; bytesTotal: number; } ``` ### completedEvent Fired when upload completes successfully. ```typescript interface CompletedEvent { id: string; response: string; statusCode: number; } ``` ### errorEvent Fired when upload fails. ```typescript interface ErrorEvent { id: string; error: string; statusCode?: number; } ``` ## Advanced Features ### Multipart Form Upload ```typescript const uploadWithFormData = async () => { const upload = await Uploader.startUpload({ filePath: 'file:///path/to/photo.jpg', serverUrl: 'https://api.example.com/upload', method: 'POST', parameters: { 'name': 'profile-photo', 'description': 'User profile photo' }, headers: { 'X-API-Key': 'your-api-key' } }); }; ``` ### Binary Upload ```typescript const uploadBinary = async () => { const upload = await Uploader.startUpload({ filePath: 'file:///path/to/data.bin', serverUrl: 'https://api.example.com/binary', method: 'PUT', headers: { 'Content-Type': 'application/octet-stream' } }); }; ``` ### Network-Aware Uploading ```typescript import { Network } from '@capacitor/network'; const smartUpload = async () => { const status = await Network.getStatus(); if (status.connectionType === 'wifi') { // Start large file uploads on WiFi await startLargeUpload(); } else if (status.connectionType === 'cellular') { // Queue for later or warn user console.log('Using cellular data'); } }; ``` ## Best Practices 1. **Handle all events** ```typescript const setupUploadHandlers = () => { Uploader.addListener('progressEvent', handleProgress); Uploader.addListener('completedEvent', handleCompleted); Uploader.addListener('errorEvent', handleError); }; ``` 2. **Clean up listeners** ```typescript const listeners: PluginListenerHandle[] = []; // Add listeners listeners.push(await Uploader.addListener(...)); // Clean up when done listeners.forEach(listener => listener.remove()); ``` 3. **Retry failed uploads** ```typescript const retryUpload = async (filePath: string, serverUrl: string) => { try { await Uploader.startUpload({ filePath, serverUrl, maxRetries: 3 }); } catch (error) { console.error('Upload failed after retries:', error); } }; ``` 4. **Show upload notifications** ```typescript await Uploader.startUpload({ filePath: 'file:///path/to/file', serverUrl: 'https://server.com/upload', notificationTitle: 'Uploading File', notificationBody: 'Your file is being uploaded...' }); ``` ## Platform Notes ### iOS * Uses `URLSession` for background uploads * Requires background processing capability * Uploads continue when app is suspended ### Android * Uses `WorkManager` for reliable uploads * Shows foreground service notification during uploads * Respects battery optimization settings # API Overview > Explore Capgo's public API for managing resources such as organizations, devices, channels, and bundles using RESTful HTTP methods and authentication. This is the documentation of the public API of Capgo cloud. The API allows you to programmatically manage your Capgo resources, including organizations, devices, channels, and bundles. It’s designed to be RESTful and uses standard HTTP methods. ## Authentication All API endpoints require authentication. To authenticate your requests, add your API key in the `authorization` header. Example: ```bash curl -H "authorization: your-api-key" https://api.capgo.app/organization/ ``` [Get API key ](https://web.capgo.app/dashboard/apikeys/)Generate your API key in the Capgo dashboard ## Rate Limiting The API implements rate limiting to ensure fair usage. Current limits are: * 100 requests per minute for standard accounts * 1000 requests per minute for enterprise accounts If you exceed these limits, you’ll receive a 429 (Too Many Requests) response. ## Response Format All responses are in JSON format. Successful responses typically include either a `data` object or a `status` field. Error responses include an `error` field with a description of what went wrong. Example success response: ```json { "status": "ok", "data": { ... } } ``` Example error response: ```json { "error": "Invalid API key", "status": "KO" } ``` ## Available Endpoints [Organizations ](/docs/public-api/organizations/)Create and manage organizations, update settings, and handle organization-level configurations [API Keys ](/docs/public-api/api-keys/)Generate, list, and revoke API keys for secure access to the Capgo API [Members ](/docs/public-api/members/)Manage organization members, roles, and permissions [Statistics ](/docs/public-api/statistics/)Access detailed analytics about app usage, storage, and bandwidth consumption [Channels ](/docs/public-api/channels/)Control app update channels, versions, and update policies [Devices ](/docs/public-api/devices/)Track and manage devices running your app, including version and channel assignments [Bundles ](/docs/public-api/bundles/)Handle app bundles, including uploading, listing, and managing versions ## Best Practices 1. **Error Handling**: Always check for error responses and handle them appropriately 2. **Rate Limiting**: Implement exponential backoff when hitting rate limits 3. **Caching**: Cache responses when appropriate to reduce API calls 4. **Versioning**: Keep track of API changes through our changelog # API Keys > Comprehensive documentation for API Keys endpoint, detailing authentication, permissions, and management within Capgo API API keys are used to authenticate requests to the Capgo API. Each key can have different permissions (modes) to control access levels. Keys are organization-specific and should be managed carefully as they grant access to your Capgo resources. ## Key Modes * **read**: Can only read data, no modifications allowed * **upload**: Can read, modify, and upload new bundles * **write**: Can read, modify data, and upload bundles * **all**: Full access to all operations Key modes follow a stepped/gradual schema. If you have an upload key, and then you create a write key, the write key will be able to do everything that the upload key could. Please take a look at the following diagram to better understand how API keys work. ![A diagram explaining how API key work](/capgo_apikeys_diagram.webp) ## Subkeys with Limited Rights You can create subkeys with limited access to specific apps or organizations. This is useful for restricting access to certain resources while still allowing operations on others. Use the `limited_to_apps` and `limited_to_orgs` parameters when creating a key to define these restrictions. ## Security Best Practices 1. **Principle of Least Privilege**: Always use the most restrictive mode that still allows your integration to function 2. **Regular Rotation**: Rotate your API keys periodically 3. **Secure Storage**: Store API keys securely and never commit them to version control 4. **Monitoring**: Monitor API key usage and revoke any compromised keys immediately 5. **Limited Subkeys**: Use subkeys with limited rights for specific integrations to minimize risk ## Endpoints ### GET `https://api.capgo.app/apikey/` Retrieve all API keys associated with your account. #### Response Type ```typescript interface ApiKey { created_at: string | null id: number key: string mode: 'read' | 'write' | 'upload' | 'all' name: string updated_at: string | null user_id: string limited_to_apps?: string[] limited_to_orgs?: string[] } ``` #### Example Request ```bash curl -H "authorization: your-api-key" https://api.capgo.app/apikey/ ``` #### Example Response ```json { "data": [ { "id": 1, "key": "ak_123...", "mode": "read", "name": "CI/CD Read Key", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z", "user_id": "user_123" }, { "id": 2, "key": "ak_456...", "mode": "upload", "name": "Deploy Bot", "created_at": "2024-01-02T00:00:00Z", "updated_at": "2024-01-02T00:00:00Z", "user_id": "user_123", "limited_to_apps": ["com.demo.app"] } ] } ``` ### POST `https://api.capgo.app/apikey/` Create a new API key for a specific organization. #### Query Parameters ```typescript interface ApiKeyCreate { name: string mode: 'read' | 'write' | 'upload' | 'all' limited_to_apps?: string[] limited_to_orgs?: string[] } ``` #### Example Request ```bash curl -X POST \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "name": "Limited Read Key", "mode": "read", "limited_to_apps": ["com.demo.app"] }' \ https://api.capgo.app/apikey/ ``` #### Example Response ```json { "apikey": { "id": 3, "key": "ak_789...", "mode": "read", "name": "Limited Read Key", "created_at": "2024-02-12T00:00:00Z", "user_id": "user_123", "limited_to_apps": ["com.demo.app"] } } ``` ### DELETE `https://api.capgo.app/apikey/:id/` Delete an existing API key. Use this to revoke access immediately. #### Parameters * `id`: The ID of the API key to delete (numeric identifier, not the key string itself) #### Example Request ```bash curl -X DELETE -H "authorization: your-api-key" https://api.capgo.app/apikey/1/ ``` #### Success Response ```json { "success": true } ``` ## Common Use Cases 1. **CI/CD Integration**: Create read-only keys for CI pipelines to check deployment status 2. **Deployment Automation**: Use upload mode keys for automated deployment scripts 3. **Monitoring Tools**: Use read mode keys for external monitoring integrations 4. **Admin Access**: Use all mode keys sparingly for administrative tools 5. **Limited Access**: Create subkeys with limited rights to specific apps or organizations for third-party integrations ## Error Handling Common error scenarios and their responses: ```json // Invalid mode { "error": "Invalid mode specified. Must be one of: read, write, upload, all", "status": "KO" } // Key not found { "error": "API key not found", "status": "KO" } // Permission denied { "error": "Insufficient permissions to manage API keys", "status": "KO" } ``` # Apps > Detailed documentation for the Apps endpoint, providing comprehensive insights into managing and interacting with Capacitor applications through Capgo's platform. Apps are the foundational entities in Capgo. Each app represents a unique Capacitor application that you can manage and update through the platform. The Apps API allows you to create, retrieve, update, and delete app configurations. ## Understanding Apps An app in Capgo represents your Capacitor application and includes: * **App ID**: Unique identifier for your application * **Name**: Human-readable name of your application * **Icons**: Visual identifiers for your app in the dashboard * **Configuration**: Settings that control how updates are delivered * **Ownership**: Organization and user access information * **Usage Statistics**: Metrics about installs and updates ## Best Practices 1. **Naming Convention**: Use clear, identifiable names for your apps 2. **Security**: Protect your API keys and access credentials 3. **Organization**: Group related apps under the same organization 4. **Monitoring**: Regularly check app statistics and performance 5. **Backup**: Maintain configuration backups for critical apps ## Endpoints ### GET `https://api.capgo.app/app/` Retrieve information about your apps. #### Query Parameters * `page`: Optional. Page number for pagination * `limit`: Optional. Number of results per page (default: 50) * `org_id`: Optional. Filter apps by organization ID. If not provided, returns apps from all organizations the user has access to For getting a specific app: * Use the app ID in the URL path: `https://api.capgo.app/app/:app_id` #### Response Type ```typescript interface App { app_id: string created_at: string | null default_upload_channel: string icon_url: string id: string | null last_version: string | null name: string | null owner_org: string retention: number transfer_history: Json[] | null updated_at: string | null user_id: string | null } ``` #### Example Request ```bash # Get all apps curl -H "authorization: your-api-key" \ "https://api.capgo.app/app/" # Get apps from a specific organization curl -H "authorization: your-api-key" \ "https://api.capgo.app/app/?org_id=046a36ac-e03c-4590-9257-bd6c9dba9ee8" # Get specific app curl -H "authorization: your-api-key" \ "https://api.capgo.app/app/com.demo.app" ``` #### Example Response ```json { "data": [ { "app_id": "com.demo.app", "created_at": "2024-01-01T00:00:00Z", "default_upload_channel": "dev", "icon_url": "https://example.com/icon.png", "id": "550e8400-e29b-41d4-a716-446655440000", "last_version": "1.0.0", "name": "Demo App", "owner_org": "046a36ac-e03c-4590-9257-bd6c9dba9ee8", "retention": 2592000, "transfer_history": null, "updated_at": "2024-01-01T00:00:00Z", "user_id": "6aa76066-55ef-4238-ade6-0b32334a4097" } ] } ``` ### POST `https://api.capgo.app/app/` Create a new app. #### Request Body ```typescript interface CreateApp { app_id: string name: string icon?: string owner_org: string } ``` #### Example Request ```bash # Create new app curl -X POST \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "name": "My New App", "app_id": "com.demo.myapp", // this id is unique in Capgo This cannot be reused by any account. "icon": "https://example.com/icon.png", "owner_org": "046a36ac-e03c-4590-9257-bd6c9dba9ee8" }' \ https://api.capgo.app/app/ ``` #### Success Response ```json { "app_id": "My New App", "created_at": "2024-01-01T00:00:00Z", "default_upload_channel": "dev", "icon_url": "https://example.com/icon.png", "id": "550e8400-e29b-41d4-a716-446655440000", "name": "My New App", "owner_org": "046a36ac-e03c-4590-9257-bd6c9dba9ee8", "retention": 2592000, "updated_at": "2024-01-01T00:00:00Z" } ``` ### PUT `https://api.capgo.app/app/:app_id` Update an existing app. The app ID is specified in the URL path. #### Request Body ```typescript interface UpdateApp { name?: string icon?: string retention?: number } ``` #### Example Request ```bash curl -X PUT \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "name": "Updated App Name", "icon": "https://example.com/updated-icon.png", "retention": 45 }' \ https://api.capgo.app/app/com.demo.app ``` #### Success Response ```json { "app_id": "com.demo.app", "created_at": "2024-01-01T00:00:00Z", "default_upload_channel": "dev", "icon_url": "https://example.com/updated-icon.png", "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Updated App Name", "owner_org": "046a36ac-e03c-4590-9257-bd6c9dba9ee8", "retention": 45, "updated_at": "2024-01-01T00:00:00Z" } ``` ### DELETE `https://api.capgo.app/app/:app_id` Delete an app and all associated resources. The app ID is specified in the URL path. Use with extreme caution as this action cannot be undone. #### Example Request ```bash curl -X DELETE \ -H "authorization: your-api-key" \ https://api.capgo.app/app/com.demo.app ``` #### Success Response ```json { "status": "ok" } ``` ## Error Handling Common error scenarios and their responses: ```json // App not found { "error": "App not found", "status": "KO" } // Duplicate custom ID { "error": "Custom ID already in use", "status": "KO" } // Invalid parameters { "error": "Invalid app configuration", "status": "KO" } // Permission denied { "error": "Insufficient permissions to manage app", "status": "KO" } // Organization access denied { "status": "You do not have access to this organization" } ``` ## Common Use Cases 1. **Create New App** ```typescript // Set up a new app { "name": "Production App", "owner_org": "046a36ac-e03c-4590-9257-bd6c9dba9ee8" } ``` 2. **Update App Configuration** ```typescript // Change app name and icon { "name": "Rebranded App Name", "icon": "https://example.com/new-icon.png" } ``` 3. **Set Retention Policy** ```typescript // Configure automatic bundle cleanup { "retention": 30 // Keep bundles for 30 days } ``` 4. **Get Apps by Organization** ```bash # List all apps in a specific organization curl -H "authorization: your-api-key" \ "https://api.capgo.app/app/?org_id=046a36ac-e03c-4590-9257-bd6c9dba9ee8" ``` ## Resource Management 1. **Storage Optimization**: Monitor storage usage and set appropriate retention policies 2. **Organization**: Group related apps under a single organization 3. **Access Control**: Manage which team members can modify app settings 4. **Backup Strategy**: Back up critical app configurations and settings # Bundles > Detailed guide for managing Capgo Bundles, covering listing, deleting, versioning, and storage optimization for app update packages. Bundles are the core update packages in Capgo. Each bundle contains the web assets (HTML, CSS, JS) that make up your app’s content. The Bundles API allows you to manage these update packages, including listing and deleting them. ## Understanding Bundles A bundle represents a specific version of your app’s web content and includes: * **Version**: Semantic version number of the bundle * **Checksum**: Unique hash to verify bundle integrity * **Storage Info**: Details about where and how the bundle is stored * **Native Requirements**: Minimum native app version requirements * **Metadata**: Creation time, ownership, and other tracking information ## Manual Bundle Creation (Without CLI) Here’s how to create and upload bundles manually without using the Capgo CLI: ### Step 1: Build Your App First, build your app’s web assets: ```bash npm run build ``` ### Step 2: Create Bundle Zip Using Same Packages as Capgo CLI **Important**: Use the exact same JavaScript packages that Capgo CLI uses internally to ensure compatibility. #### Install Required Packages ```bash npm install adm-zip @tomasklaen/checksum ``` #### Create Zip Bundle with JavaScript (Same as Capgo CLI) ```javascript const fs = require('node:fs'); const path = require('node:path'); const os = require('node:os'); const AdmZip = require('adm-zip'); const { checksum: getChecksum } = require('@tomasklaen/checksum'); // Exact same implementation as Capgo CLI function zipFileUnix(filePath) { const zip = new AdmZip(); zip.addLocalFolder(filePath); return zip.toBuffer(); } async function zipFileWindows(filePath) { console.log('Zipping file windows mode'); const zip = new AdmZip(); const addToZip = (folderPath, zipPath) => { const items = fs.readdirSync(folderPath); for (const item of items) { const itemPath = path.join(folderPath, item); const stats = fs.statSync(itemPath); if (stats.isFile()) { const fileContent = fs.readFileSync(itemPath); zip.addFile(path.join(zipPath, item).split(path.sep).join('/'), fileContent); } else if (stats.isDirectory()) { addToZip(itemPath, path.join(zipPath, item)); } } }; addToZip(filePath, ''); return zip.toBuffer(); } // Main zipFile function (exact same logic as CLI) async function zipFile(filePath) { if (os.platform() === 'win32') { return zipFileWindows(filePath); } else { return zipFileUnix(filePath); } } async function createBundle(inputPath, outputPath, version) { // Create zip using exact same method as Capgo CLI const zipped = await zipFile(inputPath); // Write to file fs.writeFileSync(outputPath, zipped); // Calculate checksum using exact same package as CLI const checksum = await getChecksum(zipped, 'sha256'); return { filename: path.basename(outputPath), version: version, size: zipped.length, checksum: checksum }; } // Usage async function main() { try { const result = await createBundle('./dist', './my-app-1.2.3.zip', '1.2.3'); console.log('Bundle info:', JSON.stringify(result, null, 2)); } catch (error) { console.error('Error creating bundle:', error); } } main(); ``` ### Step 3: Calculate SHA256 Checksum Using Same Package as CLI ```javascript const fs = require('node:fs'); const { checksum: getChecksum } = require('@tomasklaen/checksum'); async function calculateChecksum(filePath) { const fileBuffer = fs.readFileSync(filePath); // Use exact same package and method as Capgo CLI const checksum = await getChecksum(fileBuffer, 'sha256'); return checksum; } // Usage async function main() { const checksum = await calculateChecksum('./my-app-1.2.3.zip'); console.log('Checksum:', checksum); } main(); ``` ### Step 4: Upload Bundle to Your Storage Upload your zip file to any web-accessible storage: ```bash # Example: Upload to your server via scp scp my-app-1.2.3.zip user@your-server.com:/var/www/bundles/ # Example: Upload to S3 using AWS CLI aws s3 cp my-app-1.2.3.zip s3://your-bucket/bundles/ # Example: Upload via curl to a custom endpoint curl -X POST https://your-storage-api.com/upload \ -H "Authorization: Bearer YOUR_TOKEN" \ -F "file=@my-app-1.2.3.zip" ``` **Important**: Your bundle must be **publicly accessible** via HTTPS URL (no authentication required). Capgo’s servers need to download the bundle from this URL. Examples of valid public URLs: * `https://your-storage.com/bundles/my-app-1.2.3.zip` * `https://github.com/username/repo/releases/download/v1.2.3/bundle.zip` * `https://cdn.jsdelivr.net/gh/username/repo@v1.2.3/dist.zip` ### Step 5: Register Bundle with Capgo API Register the external bundle with Capgo using direct API calls: ```javascript async function registerWithCapgo(appId, version, bundleUrl, checksum, apiKey) { const fetch = require('node-fetch'); // Create bundle version const response = await fetch('https://api.capgo.app/bundle/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'authorization': apiKey }, body: JSON.stringify({ app_id: appId, version: version, external_url: bundleUrl, checksum: checksum }) }); if (!response.ok) { throw new Error(`Failed to create bundle: ${response.statusText}`); } const data = await response.json(); console.log('Bundle created:', data); return data; } ``` #### API Parameters | Parameter | Description | Required | | -------------- | ----------------------------------------------------------------------------------- | -------- | | `app_id` | Your app identifier | Yes | | `version` | Semantic version (e.g., “1.2.3”) | Yes | | `external_url` | **Publicly accessible** HTTPS URL where bundle can be downloaded (no auth required) | Yes | | `checksum` | SHA256 checksum of the zip file | Yes | ## Bundle Structure Requirements Your bundle zip must follow these requirements: 1. **Root Index File**: Must have `index.html` at the root level 2. **Capacitor Integration**: Must call `notifyAppReady()` in your app code 3. **Asset Paths**: Use relative paths for all assets ### Valid Bundle Structure ```plaintext bundle.zip ├── index.html ├── assets/ │ ├── app.js │ └── styles.css └── images/ ``` ## Complete Manual Workflow Example Simple Node.js script to zip, checksum, and upload to Capgo: ```javascript const fs = require('node:fs'); const os = require('node:os'); const AdmZip = require('adm-zip'); const { checksum: getChecksum } = require('@tomasklaen/checksum'); const fetch = require('node-fetch'); async function deployToCapgo() { const APP_ID = 'com.example.app'; const VERSION = '1.2.3'; const BUNDLE_URL = 'https://your-storage.com/bundles/app-1.2.3.zip'; const API_KEY = process.env.CAPGO_API_KEY; // 1. Create zip (same as Capgo CLI) const zip = new AdmZip(); zip.addLocalFolder('./dist'); const zipped = zip.toBuffer(); // 2. Calculate checksum (same as Capgo CLI) const checksum = await getChecksum(zipped, 'sha256'); console.log('Checksum:', checksum); // 3. Upload to your storage (replace with your upload logic) // fs.writeFileSync('./bundle.zip', zipped); // ... upload bundle.zip to your storage ... // 4. Register with Capgo API const response = await fetch('https://api.capgo.app/bundle/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'authorization': API_KEY }, body: JSON.stringify({ app_id: APP_ID, version: VERSION, external_url: BUNDLE_URL, checksum: checksum }) }); if (!response.ok) { throw new Error(`Failed: ${response.statusText}`); } console.log('Bundle registered with Capgo!'); } deployToCapgo().catch(console.error); ``` Install dependencies: ```bash npm install adm-zip @tomasklaen/checksum node-fetch ``` ## Checksum Verification ### JavaScript Checksum Calculation (Same as Capgo CLI) Use the exact same package and method that Capgo CLI uses internally: ```javascript const fs = require('node:fs'); const { checksum: getChecksum } = require('@tomasklaen/checksum'); async function calculateChecksum(filePath) { const fileBuffer = fs.readFileSync(filePath); // Use exact same package and method as Capgo CLI const checksum = await getChecksum(fileBuffer, 'sha256'); return checksum; } // Verify checksum matches async function verifyChecksum(filePath, expectedChecksum) { const actualChecksum = await calculateChecksum(filePath); const isValid = actualChecksum === expectedChecksum; console.log(`File: ${filePath}`); console.log(`Expected: ${expectedChecksum}`); console.log(`Actual: ${actualChecksum}`); console.log(`Valid: ${isValid}`); return isValid; } // Usage async function main() { const bundleChecksum = await calculateChecksum('./my-app-1.2.3.zip'); console.log('SHA256 Checksum:', bundleChecksum); } main(); ``` ### Checksum Importance * **Bundle Integrity**: Ensures the bundle hasn’t been corrupted during transfer * **API Verification**: Capgo verifies checksums before accepting bundles * **Plugin Verification**: The mobile plugin verifies checksums before applying updates ## Best Practices 1. **Version Management**: Use semantic versioning consistently 2. **Storage Optimization**: Remove unused bundles periodically 3. **Version Compatibility**: Set appropriate minimum native version requirements 4. **Backup Strategy**: Maintain backups of critical bundle versions ## Endpoints ### GET `https://api.capgo.app/bundle/` Retrieve bundle information. Returns 50 bundles per page. #### Query Parameters * `app_id`: Required. The ID of your app * `page`: Optional. Page number for pagination #### Response Type ```typescript interface Bundle { app_id: string bucket_id: string | null checksum: string | null created_at: string | null deleted: boolean external_url: string | null id: number minUpdateVersion: string | null name: string native_packages: Json[] | null owner_org: string r2_path: string | null session_key: string | null storage_provider: string updated_at: string | null user_id: string | null } ``` #### Example Request ```bash # Get all bundles curl -H "authorization: your-api-key" \ "https://api.capgo.app/bundle/?app_id=app_123" # Get next page curl -H "authorization: your-api-key" \ "https://api.capgo.app/bundle/?app_id=app_123&page=1" ``` #### Example Response ```json { "data": [ { "id": 1, "app_id": "app_123", "name": "1.0.0", "checksum": "abc123...", "minUpdateVersion": "1.0.0", "storage_provider": "r2", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z", "deleted": false, "owner_org": "org_123", "user_id": "user_123" } ] } ``` ### DELETE `https://api.capgo.app/bundle/` Delete one or all bundles for an app. Use with caution as this action cannot be undone. #### Query Parameters For deleting a specific bundle: ```typescript interface BundleDelete { app_id: string version: string } ``` For deleting all bundles: ```typescript interface BundleDeleteAll { app_id: string } ``` #### Example Requests ```bash # Delete specific bundle curl -X DELETE \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "app_id": "app_123", "version": "1.0.0" }' \ https://api.capgo.app/bundle/ # Delete all bundles curl -X DELETE \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "app_id": "app_123" }' \ https://api.capgo.app/bundle/ ``` #### Success Response ```json { "status": "ok" } ``` ### POST `https://api.capgo.app/bundle/` Create a new bundle with external URL. #### Request Body ```typescript interface CreateBundleBody { app_id: string version: string external_url: string // Must be publicly accessible HTTPS URL checksum: string } ``` #### Example Request ```bash curl -X POST \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "app_id": "com.example.app", "version": "1.2.3", "external_url": "https://your-storage.com/bundles/app-1.2.3.zip", "checksum": "a1b2c3d4e5f6789abcdef123456789abcdef123456789abcdef123456789abcd" }' \ https://api.capgo.app/bundle/ ``` #### Success Response ```json { "status": "ok" } ``` ### POST (Metadata) `https://api.capgo.app/bundle/metadata` Update bundle metadata such as link and comment information. #### Request Body ```typescript interface UpdateMetadataBody { app_id: string version_id: number link?: string comment?: string } ``` #### Example Request ```bash curl -X POST \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "app_id": "app_123", "version_id": 456, "link": "https://github.com/myorg/myapp/releases/tag/v1.0.0", "comment": "Fixed critical bug in authentication" }' \ https://api.capgo.app/bundle/metadata ``` #### Success Response ```json { "status": "success" } ``` ### PUT `https://api.capgo.app/bundle/` Set a bundle to a specific channel. This links a bundle version to a channel for distribution. #### Request Body ```typescript interface SetChannelBody { app_id: string version_id: number channel_id: number } ``` #### Example Request ```bash curl -X PUT \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "app_id": "app_123", "version_id": 456, "channel_id": 789 }' \ https://api.capgo.app/bundle/ ``` #### Success Response ```json { "status": "success", "message": "Bundle 1.0.0 set to channel production" } ``` ## Error Handling Common error scenarios and their responses: ```json // Bundle not found { "error": "Bundle not found", "status": "KO" } // Invalid version format { "error": "Invalid version format", "status": "KO" } // Storage error { "error": "Failed to delete bundle from storage", "status": "KO" } // Permission denied { "error": "Insufficient permissions to manage bundles", "status": "KO" } ``` ## Common Use Cases 1. **Cleanup Old Versions** ```typescript // Delete outdated beta versions { "app_id": "app_123", "version": "1.0.0-beta.1" } ``` 2. **App Reset** ```typescript // Remove all bundles to start fresh { "app_id": "app_123" } ``` ## Storage Considerations 1. **Retention Policy**: Define how long to keep old bundles 2. **Size Management**: Monitor bundle sizes and storage usage 3. **Backup Strategy**: Consider backing up critical versions 4. **Cost Optimization**: Remove unnecessary bundles to optimize storage costs # Channels > Guide to managing app update channels in Capgo, covering version control, platform targeting, and update policies. Channels are the core mechanism for managing app updates in Capgo. They allow you to control how and when your users receive updates, enabling features like A/B testing, staged rollouts, and platform-specific updates. ## Understanding Channels A channel represents a distribution track for your app updates. Each channel can be configured with specific rules and constraints: * **Version Control**: Specify which version users receive * **Platform Targeting**: Target specific platforms (iOS/Android) * **Update Policies**: Control how updates are delivered * **Device Restrictions**: Manage which devices can access updates ## Channel Configuration Options * **public**: Set as default channel for new devices * **disableAutoUpdateUnderNative**: Prevent updates when the device’s native app version is newer than the update version available in the channel (e.g., device is on version 1.2.3, but channel has 1.2.2) * **disableAutoUpdate**: Control update behavior (“major”, “minor”, “version\_number”, “none”) * **ios/android**: Enable/disable for specific platforms * **allow\_device\_self\_set**: Let devices choose their channel * **allow\_emulator**: Allow updates on emulator devices * **allow\_dev**: Allow updates on development builds ## Best Practices 1. **Testing Channel**: Maintain a testing channel for internal validation 2. **Staged Rollout**: Use multiple channels for gradual update deployment 3. **Platform Separation**: Create separate channels for iOS and Android when needed 4. **Version Control**: Use semantic versioning for clear update paths ## Endpoints ### POST `https://api.capgo.app/channel/` Create or update a channel configuration. #### Request Body ```typescript type disable_update = "major" | "minor" | "version_number" | "none" interface ChannelSet { app_id: string channel: string version?: string public?: boolean disableAutoUpdateUnderNative?: boolean disableAutoUpdate?: disable_update ios?: boolean android?: boolean allow_device_self_set?: boolean allow_emulator?: boolean allow_dev?: boolean } ``` #### Example Request ```bash curl -X POST \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "app_id": "app_123", "channel": "beta", "version": "1.2.0", "public": false, "disableAutoUpdate": "minor", "ios": true, "android": true, "allow_emulator": true }' \ https://api.capgo.app/channel/ ``` #### Success Response ```json { "status": "ok" } ``` ### GET `https://api.capgo.app/channel/` Retrieve channel information. Returns 50 channels per page. #### Query Parameters * `app_id`: Required. The ID of your app * `page`: Optional. Page number for pagination * `channel`: Optional. Specific channel name to retrieve #### Example Requests ```bash # Get all channels curl -H "authorization: your-api-key" \ "https://api.capgo.app/channel/?app_id=app_123" # Get specific channel curl -H "authorization: your-api-key" \ "https://api.capgo.app/channel/?app_id=app_123&channel=beta" # Get next page curl -H "authorization: your-api-key" \ "https://api.capgo.app/channel/?app_id=app_123&page=1" ``` #### Response Type ```typescript interface Channel { id: number; created_at: string; name: string; app_id: string; version: { id: number, name: string }; created_by: string; updated_at: string; public: boolean; disableAutoUpdateUnderNative: boolean; disableAutoUpdate: boolean; allow_emulator: boolean; allow_dev: boolean; } ``` #### Example Response ```json { "data": [ { "id": 1, "name": "production", "app_id": "app_123", "version": { "id": 1, "name": "1.0.0" }, "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z", "created_by": "user_123", "public": true, "disableAutoUpdateUnderNative": false, "disableAutoUpdate": false, "allow_emulator": false, "allow_dev": false } ] } ``` ### DELETE `https://api.capgo.app/channel/` Delete a channel. Note that this will affect all devices using this channel. #### Query Parameters ```typescript interface Channel { channel: string app_id: string } ``` #### Example Request ```bash curl -X DELETE \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "app_id": "app_123", "channel": "beta" }' \ https://api.capgo.app/channel/ ``` #### Success Response ```json { "status": "ok" } ``` ## Error Handling Common error scenarios and their responses: ```json // Channel not found { "error": "Channel not found", "status": "KO" } // Invalid version format { "error": "Invalid version format. Use semantic versioning", "status": "KO" } // Invalid update policy { "error": "Invalid disableAutoUpdate value", "status": "KO" } // Permission denied { "error": "Insufficient permissions to manage channels", "status": "KO" } ``` ## Common Use Cases 1. **Beta Testing** ```typescript { "app_id": "app_123", "channel": "beta", "version": "1.2.0-beta", "public": false, "allow_emulator": true, "allow_dev": true } ``` 2. **Production Rollout** ```typescript { "app_id": "app_123", "channel": "production", "version": "1.2.0", "public": true, "disableAutoUpdate": "minor" } ``` 3. **Platform-Specific Updates** ```typescript { "app_id": "app_123", "channel": "ios-hotfix", "version": "1.2.1", "ios": true, "android": false } ``` # Devices > Docs for managing devices via Capgo API, covering tracking, versioning, and channel assignments for app installations. Devices represent individual installations of your app that are managed by Capgo. The Devices API allows you to track and manage devices, including their versions, channels, and update status. ## Understanding Devices Each device has unique characteristics and states: * **Platform**: iOS or Android * **Version**: Current bundle version and native build version * **Environment**: Production or development, emulator or physical device * **Channel**: Current update channel assignment * **Custom ID**: Optional identifier for your own tracking purposes ## Best Practices 1. **Version Tracking**: Monitor device versions to ensure update adoption 2. **Channel Management**: Assign devices to appropriate channels based on testing needs 3. **Environment Awareness**: Handle different environments (prod/dev/emulator) appropriately 4. **Custom Identification**: Use custom IDs to integrate with your existing systems ## Endpoints ### POST `https://api.capgo.app/device/` Link a device to a specific version or channel. #### Request Body ```typescript interface DeviceLink { app_id: string device_id: string version_id?: string // version name channel?: string // channel name } ``` #### Example Request ```bash curl -X POST \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "app_id": "app_123", "device_id": "device_456", "channel": "beta" }' \ https://api.capgo.app/device/ ``` #### Success Response ```json { "status": "ok" } ``` ### GET `https://api.capgo.app/device/` Retrieve device information. Returns 50 devices per page. #### Query Parameters * `app_id`: Required. The ID of your app * `page`: Optional. Page number for pagination * `device_id`: Optional. Specific device ID to retrieve #### Example Requests ```bash # Get all devices curl -H "authorization: your-api-key" \ "https://api.capgo.app/device/?app_id=app_123" # Get specific device curl -H "authorization: your-api-key" \ "https://api.capgo.app/device/?app_id=app_123&device_id=device_456" # Get next page curl -H "authorization: your-api-key" \ "https://api.capgo.app/device/?app_id=app_123&page=1" ``` #### Response Type ```typescript interface Device { created_at?: string | undefined; updated_at?: string | undefined; device_id: string; custom_id: string; version: number; channel?: string; app_id: string; platform?: "ios" | "android" | undefined; plugin_version: string; os_version?: string | undefined; version_build: string; is_prod: boolean; is_emulator: boolean; } ``` #### Example Response ```json { "data": [ { "device_id": "device_456", "custom_id": "test-device-1", "version": 1, "app_id": "app_123", "platform": "ios", "plugin_version": "5.0.0", "os_version": "17.0", "version_build": "1", "is_prod": true, "is_emulator": false, "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" } ] } ``` ### DELETE `https://api.capgo.app/device/` Unlink a device from its channel and version override. This resets the device to use its default channel. #### Query Parameters ```typescript interface Device { device_id: string app_id: string } ``` #### Example Request ```bash curl -X DELETE \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "app_id": "app_123", "device_id": "device_456" }' \ https://api.capgo.app/device/ ``` #### Success Response ```json { "status": "ok" } ``` ## Error Handling Common error scenarios and their responses: ```json // Device not found { "error": "Device not found", "status": "KO" } // Invalid version { "error": "Version not found", "status": "KO" } // Invalid channel { "error": "Channel not found", "status": "KO" } // Permission denied { "error": "Insufficient permissions to manage devices", "status": "KO" } ``` ## Common Use Cases 1. **Beta Device Registration** ```typescript { "app_id": "app_123", "device_id": "device_456", "channel": "beta" } ``` 2. **Version Override** ```typescript { "app_id": "app_123", "device_id": "device_456", "version_id": "1.1.0" } ``` 3. **Reset to Default Channel** ```typescript // Use DELETE endpoint to remove overrides ``` ## Tips for Device Management 1. **Monitoring**: Regularly check device status and version distribution 2. **Testing**: Use custom IDs to identify test devices easily 3. **Troubleshooting**: Track device updates and channel assignments 4. **Version Control**: Monitor native app versions to ensure compatibility # Members > Comprehensive guide to managing organization members in Capgo, covering roles, permissions, and best practices for security and collaboration. Organization members are users who have access to your Capgo organization. Each member has a specific role that determines their permissions within the organization. Managing members effectively is crucial for maintaining security and collaboration in your team. ## Member Roles ### Regular Roles * **read**: Can view resources but cannot make changes * **upload**: Can upload new bundles and view resources * **write**: Can modify resources and upload bundles * **admin**: Can manage organization settings and members * **super\_admin**: Has full control over the organization ### Invite Roles * **invite\_read**: Pending invitation for read access * **invite\_upload**: Pending invitation for upload access * **invite\_write**: Pending invitation for write access * **invite\_admin**: Pending invitation for admin access * **invite\_super\_admin**: Pending invitation for super admin access ## Best Practices 1. **Role Assignment**: Follow the principle of least privilege when assigning roles 2. **Regular Audits**: Periodically review member access and remove unused accounts 3. **Onboarding**: Have a clear process for adding new members and assigning roles 4. **Offboarding**: Promptly remove access for members who leave the organization ## Endpoints ### POST `https://api.capgo.app/organization/members/` Add a new member to an organization or update an existing member’s role. Note that you can only invite users who already have a Capgo account - the email must correspond to an existing Capgo user. #### Request Body ```typescript interface MemberCreate { orgId: string email: string role: "read" | "upload" | "write" | "admin" | "super_admin" } ``` #### Example Request ```bash curl -X POST \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "orgId": "org_123", "email": "newmember@example.com", "role": "write" }' \ https://api.capgo.app/organization/members/ ``` #### Success Response ```json { "status": "OK", "data": { "uid": "user_789", "email": "newmember@example.com", "role": "invite_write", "image_url": null } } ``` Notes: * When adding a new member, they will receive an invitation email. Their role will be prefixed with “invite\_” until they accept the invitation. * The user must already have a Capgo account before they can be invited. If they don’t have an account, they should first create one at ### GET `https://api.capgo.app/organization/members/` Retrieve all members of an organization. #### Query Parameters ```typescript interface MemberQuery { orgId: string } ``` #### Response Type ```typescript interface Member { uid: string; email: string; image_url: string; role: "invite_read" | "invite_upload" | "invite_write" | "invite_admin" | "invite_super_admin" | "read" | "upload" | "write" | "admin" | "super_admin"; } ``` #### Example Request ```bash curl -H "authorization: your-api-key" \ "https://api.capgo.app/organization/members/?orgId=org_123" ``` #### Example Response ```json { "data": [ { "uid": "user_123", "email": "john@example.com", "image_url": "https://example.com/avatar.png", "role": "admin" }, { "uid": "user_456", "email": "jane@example.com", "image_url": "https://example.com/avatar2.png", "role": "write" }, { "uid": "user_789", "email": "bob@example.com", "image_url": null, "role": "invite_read" } ] } ``` ### DELETE `https://api.capgo.app/organization/members/` Remove a member from an organization. This will immediately revoke their access. #### Request Body ```typescript interface MemberDelete { orgId: string email: string } ``` #### Example Request ```bash curl -X DELETE \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "orgId": "org_123", "email": "user@example.com" }' \ https://api.capgo.app/organization/members/ ``` #### Success Response ```json { "status": "OK" } ``` ## Error Handling Common error scenarios and their responses: ```json // Member not found { "error": "Member not found", "status": "KO" } // Invalid role { "error": "Invalid role specified", "status": "KO" } // Permission denied { "error": "Insufficient permissions to manage members", "status": "KO" } // Cannot remove last admin { "error": "Cannot remove the last admin from the organization", "status": "KO" } // Invalid email { "error": "Invalid email format", "status": "KO" } // Member already exists { "error": "Member already exists in organization", "status": "KO" } ``` ## Common Use Cases 1. **Team Expansion**: Adding new team members with appropriate roles 2. **Access Control**: Managing member permissions as responsibilities change 3. **Security Audit**: Reviewing member list and roles periodically 4. **Team Restructuring**: Updating roles during organizational changes # Organizations > Guide to managing organizations in Capgo, covering creation, settings, updates, and retrieval of organization details. Organizations are the top-level entities in Capgo. They allow you to group apps, team members, and resources under a single umbrella. Each organization can have multiple members with different roles and permissions. ## Common Use Cases * Creating a new organization for your company * Managing organization settings * Updating organization information * Retrieving organization details ## Endpoints ### GET `https://api.capgo.app/organization/` Retrieve organization information. If `orgId` is provided in the parameters, returns a single organization. Otherwise, returns all accessible organizations. #### Query Parameters * `orgId` (optional): The ID of the specific organization to retrieve #### Response Type ```typescript interface Organization { id: string created_by: string created_at: string updated_at: string logo: string | null name: string management_email: string customer_id: string | null } ``` #### Example Request ```bash # Get all organizations curl -H "authorization: your-api-key" https://api.capgo.app/organization/ # Get specific organization curl -H "authorization: your-api-key" https://api.capgo.app/organization/?orgId=org_123 ``` #### Example Response ```json { "data": { "id": "org_123", "name": "My Company", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z", "logo": "https://example.com/logo.png", "management_email": "admin@example.com", "customer_id": "cus_123" } } ``` ### POST `https://api.capgo.app/organization/` Create a new organization. #### Request Body ```typescript interface OrganizationCreate { name: string } ``` #### Example Request ```bash curl -X POST \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "name": "New Organization" }' \ https://api.capgo.app/organization/ ``` #### Example Response ```json { "status": "Organization created", "id": "org_456" } ``` ### PUT `https://api.capgo.app/organization/` Update an existing organization. Requires admin role. #### Request Body ```typescript interface OrganizationUpdate { orgId: string logo?: string name?: string management_email?: string } ``` #### Example Request ```bash curl -X PUT \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "orgId": "org_123", "name": "New Company Name", "management_email": "newemail@example.com" }' \ https://api.capgo.app/organization/ ``` #### Example Response ```json { "status": "Organization updated", "data": { "id": "org_123", "name": "New Company Name", "management_email": "newemail@example.com" } } ``` ### DELETE `https://api.capgo.app/organization/` Delete an existing organization. Requires admin role. This action is irreversible and will remove all associated apps, versions, and resources. #### Query Parameters * `orgId`: The ID of the organization to delete #### Example Request ```bash curl -X DELETE \ -H "authorization: your-api-key" \ https://api.capgo.app/organization/?orgId=org_123 ``` #### Example Response ```json { "status": "Organization deleted", "id": "org_123" } ``` ## Error Handling Common error scenarios and their responses: ```json // Invalid API key { "error": "Invalid API key", "status": "KO" } // Missing required field { "error": "Name is required", "status": "KO" } // Insufficient permissions { "error": "Admin role required", "status": "KO" } ``` ## Best Practices 1. **Naming**: Use clear, descriptive names for organizations 2. **Roles**: Assign appropriate roles to team members 3. **Email**: Use a group email for management\_email to avoid issues with personal email changes 4. **Logo**: Host logos on a reliable CDN and use HTTPS URLs # Statistics > Detailed guide to Statistics API endpoints, providing insights into Monthly Active Users (MAU), storage, and bandwidth metrics for apps and organizations. The Statistics endpoints provide detailed analytics about your apps and organizations. You can track Monthly Active Users (MAU), storage usage, and bandwidth consumption across different time periods. This data is essential for monitoring app growth, resource usage, and planning capacity. ## Understanding the Metrics * **MAU (Monthly Active Users)**: Number of unique devices that accessed your app in the last 30 days * **Storage**: Total size of all bundles and resources stored in bytes * **Bandwidth**: Total data transfer for bundle downloads in bytes ## Best Practices 1. **Regular Monitoring**: Check statistics periodically to track growth and usage patterns 2. **Resource Planning**: Use storage and bandwidth metrics for capacity planning 3. **User Engagement**: Track MAU to understand user engagement trends 4. **Cost Management**: Monitor resource usage to optimize costs ## Endpoints ### GET /statistics/app/:app\_id/ Get statistics for a specific app. This endpoint is useful for monitoring individual app performance. #### Query Parameters ```typescript interface StatsQuery { from: Date // Start date for the statistics (format: YYYY-MM-DD) to: Date // End date for the statistics (format: YYYY-MM-DD) } ``` #### Example Request ```bash curl -H "authorization: your-api-key" \ "https://api.capgo.app/statistics/app/com.demo.app/?from=2024-01-01&to=2024-02-01" ``` #### Example Response ```json [ { "date": "2024-01-01", "mau": 1500, "storage": 536870912, // 512MB in bytes "bandwidth": 1073741824 // 1GB in bytes }, { "date": "2024-01-02", "mau": 1550, "storage": 537919488, // 513MB in bytes "bandwidth": 1074790400 // 1.01GB in bytes } ] ``` ### GET /statistics/org/:org\_id/ Get statistics for a specific organization. Useful for monitoring organization-level usage. #### Query Parameters ```typescript interface StatsQuery { from: Date // Start date for the statistics (format: YYYY-MM-DD) to: Date // End date for the statistics (format: YYYY-MM-DD) breakdown: boolean // default false, optional if true it return the breakdown by app noAccumulate: boolean // default false, optional if true it will not accumulate data and just return day by day result } ``` #### Example Request ```bash curl -H "authorization: your-api-key" \ "https://api.capgo.app/statistics/org/046a36ac-e03c-4590-9257-bd6c9dba9ee8/?from=2024-01-01&to=2024-02-01" ``` #### Example Response ```json [ { "date": "2024-01-01", "mau": 10000, "storage": 536870912, // 512MB in bytes "bandwidth": 1073741824 // 1GB in bytes }, { "date": "2024-01-02", "mau": 10200, "storage": 537919488, // 513MB in bytes "bandwidth": 1074790400 // 1.01GB in bytes } ] ``` ### GET /statistics/user/ Get aggregated statistics across all organizations you have access to. Perfect for overall usage monitoring. #### Query Parameters ```typescript interface StatsQuery { from: Date // Start date for the statistics (format: YYYY-MM-DD) to: Date // End date for the statistics (format: YYYY-MM-DD) } ``` #### Example Request ```bash curl -H "authorization: your-api-key" \ "https://api.capgo.app/statistics/user/?from=2024-01-01&to=2024-02-01" ``` #### Example Response ```json [ { "date": "2024-01-01", "mau": 25000, "storage": 1073741824, // 1GB in bytes "bandwidth": 2147483648 // 2GB in bytes }, { "date": "2024-01-02", "mau": 25500, "storage": 1074790400, // 1.01GB in bytes "bandwidth": 2148532224 // 2.01GB in bytes } ] ``` ### GET /statistics/app/:app\_id/bundle\_usage Get bundle usage statistics for a specific app, showing the distribution of versions among users over a specified period. #### Query Parameters ```typescript interface BundleUsageQuery { from: Date // Start date for the statistics (format: YYYY-MM-DD) to: Date // End date for the statistics (format: YYYY-MM-DD) } ``` #### Example Request ```bash curl -H "authorization: your-api-key" \ "https://api.capgo.app/statistics/app/com.demo.app/bundle_usage?from=2024-01-01&to=2024-02-01" ``` #### Example Response ```json { "labels": ["2024-01-01", "2024-01-02", "2024-01-03"], "datasets": [ { "label": "1.0.0", "data": [60.5, 58.2, 55.3] }, { "label": "1.0.1", "data": [39.5, 41.8, 44.7] } ] } ``` ## Error Handling Common error scenarios and their responses: ```json // Invalid body { "status": "Invalid body", "error": "Invalid date format or missing parameters" } // Permission denied { "status": "You can't access this app", "error": "Insufficient permissions to access statistics" } // Permission denied for organization { "status": "You can't access this organization", "error": "Insufficient permissions to access organization statistics" } // No organizations found for user statistics { "status": "No organizations found", "error": "No organizations found" } // Internal server error { "status": "Cannot get app statistics", "error": "Internal server error message" } ``` ## Common Use Cases 1. **Growth Tracking**: Monitor MAU growth over time 2. **Resource Optimization**: Track storage and bandwidth usage to optimize costs 3. **Capacity Planning**: Use trends to plan for future resource needs 4. **Usage Reports**: Generate periodic usage reports for stakeholders 5. **Version Distribution Analysis**: Understand how users are distributed across different app versions with bundle usage statistics ## Tips for Analysis 1. **Compare Periods**: Look at month-over-month or year-over-year trends 2. **Track Ratios**: Monitor bandwidth per user or storage per app 3. **Set Alerts**: Create alerts for unusual spikes in usage 4. **Regular Backups**: Export statistics regularly for historical analysis 5. **Version Adoption**: Use bundle usage to track adoption rates of new versions # Migrate from AppFlow to Capgo > Detailed walkthrough for moving an Ionic AppFlow project to Capgo. Each step maps to the standard AppFlow migration tasks so you can compare line by line—and see which ones Capgo already handles for you. > 🚦 Ionic announced that AppFlow’s commercial products—including Live Updates—are winding down. Existing projects can run until **31 December 2027**, but no new customers are accepted and no new features are planned. This guide walks you through the actions required to migrate to Capgo and highlights the native automation you gain. ## Migration overview Capgo handles channels, bundle retention, rollbacks, analytics, and CLI uploads for you. Migration boils down to installing the plugin, calling `CapacitorUpdater.notifyAppReady()`, and—if desired—configuring optional manual controls. The sections below walk through each task directly. ## Step 0 – Capture your current AppFlow setup * Note your AppFlow **App ID**, existing channels, and signing keys. * Export any bundle history you want to archive. * If you are using GitHub Actions or another CI provider, keep those pipelines—they will keep working with Capgo. ## Step 1 – Replace the AppFlow SDK with Capgo ```bash npm uninstall @capacitor/live-updates npm install @capgo/capacitor-updater npx cap sync ``` That’s it. Capgo bundles the native code for both iOS and Android; no extra JavaScript helpers are required. ## Step 2 – Minimal configuration (no manual fields) The existing configuration block is extensive. Capgo auto-detects your project and channels, so the minimal configuration is: capacitor.config.ts ```ts import { CapacitorConfig } from '@capacitor/cli' const config: CapacitorConfig = { plugins: { CapacitorUpdater: { autoUpdate: true, autoDeletePrevious: true, }, }, } export default config ``` ### Configuration quick reference | Ionic AppFlow setting | Capgo equivalent | Do you need to set it? | | ---------------------------- | ---------------------------------- | ----------------------------------------------------- | | `appId` | Managed in the Capgo dashboard | Automatically supplied when you create the project | | `channel` / `defaultChannel` | Channel rules in the dashboard/API | Optional override; defaults come from the server | | `autoUpdateMethod` | `autoUpdate: true` | Enabled by default | | `maxVersions` | Retention policy | Configured centrally (1 month default, 24 months max) | | `enabled` | Not required | Capgo toggles availability per channel | ## Step 3 – Call `notifyAppReady()` (the only required hook) In Ionic’s guide you wire `sync`, `download`, and `reload`, then hide the splash screen manually. Capgo performs those actions natively. You only need to confirm the app is ready: ```ts import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdater.notifyAppReady() ``` If the confirmation never arrives, Capgo rolls the bundle back automatically. **That’s it—Capgo handles the background checks, splash visibility, and rollbacks for you.** Optional: run logic before the splash screen hides ```ts import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' CapacitorUpdater.addListener('appReady', () => { // Log diagnostics or run custom code if needed SplashScreen.hide() }) CapacitorUpdater.notifyAppReady() ``` ## Step 4 – Update strategies translated AppFlow documents three strategies. Here is how they map to Capgo: ### Background (default) * **AppFlow**: configure `autoUpdateMethod = background`, call `sync()` manually. * **Capgo**: enabled by default. No JavaScript required. ### Always latest * **AppFlow**: add an `App.addListener('resume')` handler that downloads and reloads. * **Capgo**: auto-update runs on resume already. Add the handler only if you want a custom timing window. Optional: manual resume check ```ts import { App } from '@capacitor/app' import { CapacitorUpdater } from '@capgo/capacitor-updater' App.addListener('resume', async () => { const bundle = await CapacitorUpdater.download() if (bundle) { await CapacitorUpdater.set({ id: bundle.id }) } }) ``` ### Force update * **AppFlow**: prompt the user and call `reload()`. * **Capgo**: mark the bundle as “mandatory” in the dashboard, then listen for the `majorAvailable` event (emitted after `notifyAppReady()`) to prompt or force users inside your app. ## Step 5 – Mapping API calls | AppFlow method | Capgo equivalent | Do you need it? | | -------------------------- | ----------------------------- | ---------------------------------------------------------- | | `LiveUpdates.sync()` | Handled automatically | Capgo’s native auto-update runs without a manual sync call | | `LiveUpdates.download()` | `CapacitorUpdater.download()` | Optional for custom flows | | `LiveUpdates.reload()` | `CapacitorUpdater.set()` | Optional; dashboard toggles handle forced updates | | `LiveUpdates.getVersion()` | `CapacitorUpdater.current()` | Optional diagnostics | ## Step 6 – Deploy using the Capgo CLI or API Finish the migration by uploading bundles with the Capgo CLI or API. The workflow mirrors what you may have scripted before, but now includes native safeguards: ```bash capgo login # authenticate once capgo bundle upload \ --path dist \ --channel production # automatically tags platform/version ``` Capgo automatically: * Keeps device-level audit logs for every install. * Sends proactive emails when you approach plan limits. * Provides burst credits so you are never blocked mid-release. * Publishes latency metrics for 18 global regions at [status.capgo.app/history](https://status.capgo.app/history). ## Frequently asked questions ### Why is AppFlow shutting down live updates? Ionic is discontinuing commercial products, including AppFlow, to focus on their open-source framework. Existing customers can continue using live updates until **31 December 2027**, but no new features or customers are accepted. Capgo fills that gap with a dedicated native OTA platform. ### How long does migration take? Most teams complete the move in under a day. Concepts such as channels, deployments, and release rules map directly, and our team provides documentation plus hands-on support. In many cases you simply install the plugin, call `notifyAppReady()`, and upload your first bundle. ### Will we save money? Yes. AppFlow live updates start at **$499/mo**. Capgo starts at **$14/mo** with usage-based pricing that drops to roughly **$0.001 per MAU**. You also gain encryption, automatic rollbacks, and worldwide latency monitoring. ### When should we migrate? Because AppFlow is now in maintenance mode, migrating sooner gives you access to ongoing Capgo innovation. We recommend switching when it fits your release schedule. Our engineering team will help you plan the changeover so your CI/CD and deployments keep running. ## Need help? * Book a migration session: [cal.com/team/capgo/demo](https://cal.com/team/capgo/demo) * Join the community: [Capgo Discord](https://discord.gg/VCXxSVjefW) * Track issues / request features: [github.com/Cap-go/capacitor-updater](https://github.com/Cap-go/capacitor-updater) Capgo is engineered for enterprises that need native delta updates, encrypted bundles, and continuous innovation. Once you migrate you can delete the AppFlow glue code, rely on native automation, and keep shipping without interruption. # Migrate from Capawesome Cloud to Capgo > Step-by-step guide to move from Capawesome Cloud to Capgo while gaining native OTA safety, device-level observability, and full automation. > ⚡️ Capgo automates channels, bundle cleanup, rollbacks, analytics, and CLI uploads natively. Use this guide to perform the minimal steps required to migrate and optionally recreate any custom behaviour you still need. ## Overview 1. Gather your existing Capawesome Cloud configuration (App ID, channels, signing keys, CLI tokens) so you can archive or audit it later. 2. Install the Capgo plugin, remove the Capawesome SDK, and call `CapacitorUpdater.notifyAppReady()`. 3. Configure optional behaviour (manual downloads, pinning bundles, reloads) if you rely on those flows today. With Capgo you only need to install our plugin and call `CapacitorUpdater.notifyAppReady()`. Everything else—channels, bundle cleanup, rollbacks, analytics, and CLI automation—is handled natively. The sections below walk through each task directly. ## Before you start * Make sure your project is already using Capacitor 5 or later. * Install the Capgo CLI (`npm install -g @capgo/cli`) if you plan to push bundles from CI/CD. ## Step 1 – Install Capgo and remove the Capawesome SDK ```bash npm uninstall @capawesome/capacitor-live-update npm install @capgo/capacitor-updater npx cap sync ``` That is the only mandatory swap. Capgo’s native code ships with the plugin; no extra JavaScript helpers are required. ## Step 2 – Minimal configuration The previous setup required mapping dozens of options in `capacitor.config`. Capgo recognises your project automatically, so the minimal configuration looks like this: capacitor.config.ts ```ts import { CapacitorConfig } from '@capacitor/cli' const config: CapacitorConfig = { plugins: { CapacitorUpdater: { autoUpdate: true, autoDeletePrevious: true, periodCheckDelay: 10 * 60 * 1000, // optional: check every 10 minutes }, }, } export default config ``` Everything Capawesome lists as manual flags (`defaultChannel`, `autoDeleteBundles`, retention policies, etc.) is managed through the Capgo dashboard or API. You only need to override these keys if you want behaviour that differs from Capgo’s defaults. ### Configuration quick reference | Capawesome option | Capgo equivalent | Do you need to set it? | | ------------------------- | -------------------------------------------------------- | -------------------------------------------------------------- | | `appId` | Taken from the Capgo dashboard once you create a project | Only if you use multiple projects in one binary | | `defaultChannel` | Channel rules managed in the dashboard/API | Optional; most teams set this server-side | | `autoDeleteBundles` | `autoDeletePrevious: true` (default) | Already enabled | | `publicKey` | Managed in Capgo console | Only if you rotate keys manually | | `maxVersions` / retention | Bundle retention policy | Configured centrally in Capgo (1 month default, 24 months max) | ## Step 3 – Call `notifyAppReady()` (the only required hook) The old workflow introduced custom listeners (`checkForUpdates()`, `retryDownload()`, hiding the splash screen, etc.). Capgo performs those steps natively. The only API you must call is: ```ts import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdater.notifyAppReady() ``` This confirms the app booted successfully. If the confirmation never arrives, Capgo automatically rolls back the bundle—no extra JavaScript needed. **That’s it—Capgo handles background checks, splash visibility, and rollbacks natively.** Optional: run custom logic before the splash screen hides ```ts import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' CapacitorUpdater.addListener('appReady', () => { // Run diagnostics or logging if you need to SplashScreen.hide() }) CapacitorUpdater.notifyAppReady() ``` ## Step 4 – Map API calls (mostly optional) In Capgo you normally let the auto-updater run; manual APIs remain available if you want full control. | Capawesome Cloud | Capgo equivalent | Do you need it? | | -------------------------------- | ------------------------------ | ------------------------------------------------------------------- | | `LiveUpdate.fetchLatestBundle()` | `CapacitorUpdater.getLatest()` | Only when implementing your own download workflow | | `LiveUpdate.downloadBundle()` | `CapacitorUpdater.download()` | Optional: native auto-update already downloads | | `LiveUpdate.setNextBundle()` | `CapacitorUpdater.next()` | Optional: dashboard pins bundles automatically | | `LiveUpdate.reload()` | `CapacitorUpdater.reload()` | Optional; Capgo enforces mandatory bundles after `notifyAppReady()` | | `LiveUpdate.getCurrentBundle()` | `CapacitorUpdater.current()` | Optional diagnostics | If you stick with the native auto-update behaviour you can delete the Capawesome JavaScript entirely. ### Manual control examples **Download the latest bundle** Capgo ```ts import { CapacitorUpdater } from '@capgo/capacitor-updater' const downloadUpdate = async () => { const latest = await CapacitorUpdater.getLatest() if (latest?.url) { const bundle = await CapacitorUpdater.download({ url: latest.url, version: latest.version, }) console.log('Bundle downloaded', bundle?.id) } } ``` Capawesome Cloud ```ts import { LiveUpdate } from '@capawesome/capacitor-live-update' const downloadUpdate = async () => { const result = await LiveUpdate.fetchLatestBundle() if (result.downloadUrl) { await LiveUpdate.downloadBundle({ bundleId: result.bundleId, url: result.downloadUrl, }) console.log('Bundle downloaded') } } ``` **Set the next bundle** Capgo ```ts import { CapacitorUpdater } from '@capgo/capacitor-updater' const setNextBundle = async () => { await CapacitorUpdater.next({ id: 'bundle-id-123' }) } ``` Capawesome Cloud ```ts import { LiveUpdate } from '@capawesome/capacitor-live-update' const setNextBundle = async () => { await LiveUpdate.setNextBundle({ bundleId: 'bundle-id-123' }) } ``` **Apply the downloaded bundle immediately** Capgo ```ts import { CapacitorUpdater } from '@capgo/capacitor-updater' const applyUpdate = async () => { await CapacitorUpdater.reload() } ``` Capawesome Cloud ```ts import { LiveUpdate } from '@capawesome/capacitor-live-update' const applyUpdate = async () => { await LiveUpdate.reload() } ``` ## Step 5 – Update strategies: how Capgo handles them Capawesome documents three strategies. Here’s how they translate: ### Background updates * **Previous workflow**: configure in code and schedule downloads manually. * **Capgo**: enabled by default (`autoUpdate: true`). No additional code required. ### Always latest * **Previous workflow**: add an `App.resume` listener, call `download`, then `set`. * **Capgo**: background auto-update already performs the check after resume. You only need the manual listener if you want a custom interval. Optional: manual resume check ```ts import { App } from '@capacitor/app' import { CapacitorUpdater } from '@capgo/capacitor-updater' App.addListener('resume', async () => { const latest = await CapacitorUpdater.getLatest() if (latest?.url) { const downloaded = await CapacitorUpdater.download({ url: latest.url, version: latest.version, }) if (downloaded) { await CapacitorUpdater.next({ id: downloaded.id }) } } }) ``` ### Force update * **Previous workflow**: wire prompt logic and enforce reload. * **Capgo**: mark the bundle as “mandatory” in the dashboard, then listen for the `majorAvailable` event (emitted after `notifyAppReady()`) to require users to upgrade inside your app. ## Step 6 – Deploying bundles If you previously relied on `capawesome live-update deploy`, Capgo offers a similar CLI workflow, and you can also automate deployments entirely via API. ```bash # Authenticate once (stores a token in your CI environment) capgo login # Upload a new bundle (auto-detects platform/version) capgo bundle upload --path dist --channel production ``` Because Capgo tracks bundle health automatically, you also get: * Device-level audit logs for every install. * Automatic retention (one month by default) with configurable limits up to 24 months. * Real-time latency metrics at [status.capgo.app/history](https://status.capgo.app/history). ## Migration timeline * **Inventory & install**: 10 minutes (`npm install`, remove old plugin). * **Config & readiness**: 5 minutes (`notifyAppReady`). * **Sanity checks**: 15 minutes (optional manual tests or listeners). * **First deployment**: 10 minutes with Capgo CLI or CI integration. In practice teams finish in under an hour. If you provide Capawesome project details we can even import channels and device lists for you. ## Capgo support * **Migration concierge**: book a session at [cal.com/team/capgo/demo](https://cal.com/team/capgo/demo). * **Community**: join the [Capgo Discord](https://discord.gg/VCXxSVjefW). * **Issue tracker**: [github.com/Cap-go/capacitor-updater/issues](https://github.com/Cap-go/capacitor-updater/issues). Capgo is built for long-term reliability: native delta updates, encrypted bundles, automatic rollbacks, and analytics that do not require custom JavaScript. Once you migrate you can delete the maintenance-heavy glue and let the platform run updates automatically. # From V2 to V3 > A comprehensive guide on transitioning from version 2 to version 3 of Capgo updater, detailing the necessary steps and considerations for a successful upgrade process This documentation will explain how to upgrade to the version 3 of auto-update. ## First migrate to the last tooling: ```bash npm remove -g capgo npm remove capacitor-updater npm i @capgo/cli npm i @capgo/capacitor-updater@3 npx cap sync ``` ## Remove all your previous config: ```json { CapacitorUpdater: { autoUpdateURL: "https...", ... }, } ``` to only let this: ```json { "CapacitorUpdater": { "autoUpdate": true } } ``` > ⚠️ If you were using your server, with `autoUpdateURL`, I will upgrade this guide soon for you. Meanwhile, take a look at the new upload option `external` which allows you to send only the link of your zip, not the code in Capgo cloud. This has been made for companies with strict privacy policies. In external mode, the code will never land on Capgo server, we just store the URL and send it to the device, which will directly download it. In the standard way, the code is zipped and stored in our server, but we will never open it or use it either. ## What change All configurations become server-side for auto-update, to give you more control on how you send an update to users. That allows us to revert, even deploy just to one user with channels! These settings are added back to the web interface: * disable revert under native * disable update above major > ⚠️ They will become true by default for all channels This will also remove the need to update often the plugin, most updates will be done server side, and you will get it without any change in your side. > ⚠️ Reset when an update becomes the default, so if you prefer not to remove all download versions when updating from the store, do this: ```json { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } ``` ## Update your code Lastly, update all your imports in JS from: ```plaintext import { CapacitorUpdater } from 'capacitor-updater' ``` to ```plaintext import { CapacitorUpdater } from '@capgo/capacitor-updater' ``` Then build your code again `npm run build` and copy assets once more `npx cap copy`. You should be able now to test the last auto-update system Send your version with: ```plaintext npx @capgo/cli@latest bundle upload ``` instead of ```plaintext npx capgo upload ``` ## Future evolution For now only the first public channel is in use, in the future, public will change for multi public channels, if more than one is set. ## Common problems: * Build problem after upgrade: if you have already opened the source code of the plugin in Android studio or Xcode, sometimes the sync doesn’t remove them, that the cause of the issue. Open the native IDE and remove `capacitor-updater` by hands and do `npx cap sync` this should solve. # From V3 to V4 > How to upgrade from V3 to V4 of Capgo updater, undertsand what are the breaking changes and how to handle them ## Why this upgrade After many talk in the discord community with you. I discovered the manual mode was very too manual and not safe to use, for example, auto-revert was not possible, so if you failed update in manual the user have to remove the app and install back, what is terrible UX. Meanwhile, I took this as an opportunity to give more freedom to you, and remove all bad code I made. ## Install `npm i @capgo/capacitor-updater@4` ## Auto-update cloud If you use the basic example in your app, you are safe to migrate to the new version, enjoy! ## Auto-update self-hosted For you, still simple, the changes are: * The name of the setting from `autoUpdateUrl` in `updateUrl` * The Endpoint method changed from `GET` to POST ## Manual users For you, this is the most significant change, but for the best! You get tons of improvements, Read carefully. ## Changes * `autoUpdateUrl` becomes `updateUrl` since this setting can be used in manual mode now too * Delete of `cancelDelay` and `delayUpdate` in favor of `setDelay` * No more `versionName` in set * Change `version` key, who was returned in most function to object `BundleInfo` ```typescript interface BundleInfo { id: string; version: string; downloaded: string; status: 'success' | 'error' | 'pending' | 'downloading' } ``` * Renamed of misleading names now (even to explain cannot be clear, but at usage is easy to understand the new one): * what was called a `version` is now referring to a `bundle` * `id` refer to the old `version` who was a random string of 10 char, this `id` is the only trustable and unique way to access to your bundles, example `7Dfcd2RedN`. * `version` refer now to the `versionName` you choose for a bundle, example `1.0.0` * `updateUrl` move from `get` to `post`, since custom headers were a problem for some of you and post is more logical, all previous headers go to the body and prefix `cap_` disappear. * `versionName` method is deleted, in favor of `getId` * list returns now a list of `BundleInfo` * Rename `getId` in `getDeviceId` * `autoUpdate` becomes true by default, if you use Manual mode, set it to false. ## News * Method `getLatest`, this method allows you to get from your server set with `updateUrl` the last version available. * Method `setDelay` who take `{`kind`:` “background” | “kill” | “nativeVersion” | “date”, value? : string`}` as argument to set delay to different modes. * Method `next`, to set the version in next backgrounding, in opposite to `set` who do it instantly. * Method `isAutoUpdateEnabled`, to let you know if you are in auto-update context * Event `downloadComplete` when download reach 100% * Added mandatory field `version` in download method * `notifyAppReady` become mandatory in manual mode too, if not call after 10 sec the app reverts to past version. ## Contributors [@lincolnthree](https://github.com/lincolnthree/) Thank you so much for starting this work, it was impossible to make this update work without you. # From V4 to V5 > How to upgrade from V4 to V5, of Capgo updater what are the breaking change you should take care of, it's pretty simple ## Why this upgrade This major version is here to follow Capacitor major version First follow the migration guide of Capacitor: [https://capacitorjs.com/docs/updating/5-0](https://capacitorjs.com/docs/updating/5-0/) ## Install `npm i @capgo/capacitor-updater@5` `Then sync the native code update:` `npx cap sync` That it ! Pretty easy ! ## Manual mode If you were getting yourself the update with getLatest, there are a tiny change. Now if you are up-to-date already it will go into catch. Any response different than update available will do that. # From V5 to V6 > A detailed guide on transitioning from version 5 to version 6 of Capgo updater, outlining the necessary steps and considerations for a successful upgrade process, ensuring compatibility with the latest Capacitor features and improvements. ## Why this upgrade This major version is here to follow Capacitor major version First follow the migration guide of Capacitor: [https://capacitorjs.com/docs/updating/6-0](https://capacitorjs.com/docs/updating/6-0/) ## Install `npm i @capgo/capacitor-updater@6` `Then sync the native code update:` `npx cap sync` That it ! Pretty easy ! # From V6 to V7 > A detailed guide on transitioning from version 6 to version 7 of Capgo updater, outlining the necessary steps and considerations for a successful upgrade process, ensuring compatibility with the latest Capacitor features and improvements. ## Why this upgrade This major version is here to follow Capacitor major version First follow the migration guide of Capacitor: [https://capacitorjs.com/docs/updating/7-0](https://capacitorjs.com/docs/updating/7-0/) ## Install `npm i @capgo/capacitor-updater@7` `Then sync the native code update:` `npx cap sync` That it ! Pretty easy ! ## Encryption Migration If you’re using the `key-v1` encryption method, you’ll need to migrate to the new encryption system as `key-v1` is no longer supported in V7. \[\[memory:96112]] Follow the encryption migration guide here: [Encryption Migration Guide](/docs/cli/migrations/encryption/) ## Configuration Changes We recommend adding the following properties in your `capacitor.config` file: * `capacitorUpdater` * `appId` * `version` * `autoUpdate` These settings should help managed better the plugin’s and it’s behaviors. # Introduction > Introduction to the Capgo webapp, learn how to use the web app of Capgo, to manage your updates and understand what happen with it ## What is this? Capgo has an extensive webapp to help you manage your projects. This webapp is built with Vue.js and is open source. You can find the source code on [GitHub](https://github.com/Cap-go/capgo/tree/main/src/)\ The webapp is available [here](https://web.capgo.app/).\ This webapp allows you to [manage channels](/docs/webapp/channels/), [manage versions](/docs/webapp/bundles/), [manage devices](/docs/webapp/devices/), [inspect logs](/docs/webapp/logs/), [manage billing](/docs/webapp/settings/) and [manage your account](/docs/webapp/settings/). ## How do I use it? First, you need to create an account or log in. This is relatively simple and can be done by clicking the `Log in` button in the center of the screen. After you have logged in you will be redirected to the dashboard. This is the main page of the webapp. From here you can navigate to all the other pages. ![login page](/login.webp) ## Creating an account You have to click on the `Create a free account` in the bottom part of the login form. From then it will be as simple as filling a form and following the instructions. ![create account](/create-account.webp) # Api keys > How to manage api keys for Capgo cloud, learn what they use for, how to create, edit or roll them to ensure security with your account ## What can I do with the api keys? An API key can be regenerated, or removed or a new one can be added. ## How to see all api keys? You need to go to [API keys page](https://web.capgo.app/dashboard/apikeys/) and there you will see all your api keys. ## How to add a new api key? To add a new API key click on the little plus button ![add apikey](/apikeys-add.webp) and then select the permissions you want to give to the new API key. You can select: * Read - the API key will be able to read all the data * Upload - the API key will be able to upload new versions from the CLI and read * All - The API key will be able to do everything ![select perm](/apikeys-select-perm.webp) ## How to remove an api key? To remove an API key click on the little trash button. ![remove apikey](/apikeys-remove.webp) And then confirm removing the API key. ## How to regenerate an api key? To regenerate an API key click on the little refresh button. ![generate apikey](/apikeys-regenerate.webp) And then confirm regenerating the API key. # Bundles > Learn how to manage bundles in Capgo, What is a bundle how to manage it, there is mulple things you can do this them, they are the most important part of Capgo ## Show all bundles In Capgo, a bundle represents a specific version of your application’s code and assets, ready to be distributed to devices. First, let’s take a look at the bundles page. You can access it by [clicking on your app](/docs/webapp/main-page) and then [clicking on the bundles tab](/docs/webapp/main-app-page). ![bundle list](/bundles.webp) ## Delete a bundle They are two ways a bundle can be deleted: * Normally * Unsafely The Unsafe way of deleting a bundle was added into Capgo on August 12, 2024. The difference between the two ways is the ability to reuse the version number after the deletion. For example, if you delete a version `1.0.0` the normal way and later try to upload a `1.0.0` version, it will fail. If you delete this version via the unsafe delete, you will be able to upload a `1.0.0` version. Danger Deleting a version unsafely and re-uploading it is REALLY dangerous. It can cause all sorts of bugs and unpredictable behaviour in the plugin. It should NEVER be used for bundles that have been used in a public channel. It is for this reason that deleting a version unsafely requires “super\_admin” privileges ## Managing a specific bundle Once you see the list of all bundles click on the one you want to manage. After you do that you should see something like this: ![bundle info](/bundle-info.webp) Let’s go through all of the elements on this page. *** First you can see a `Channel`. This lets you know which channel this bundle is for. You can change the channel by clicking on it. Once you click on it you should see something like this: ![bundle change](/bundle-change.webp) **Set bundle to channel:** Assigns this bundle as the active version for a chosen channel. Devices subscribed to that channel will then receive this bundle. **Open channel:** Navigates you to the dedicated page for the channel currently associated with this bundle, where you can manage channel-specific settings. **Unlink bundle from channel:** Removes the association between this bundle and its current channel. This means devices on that channel will no longer receive this specific bundle (unless it’s re-linked or another bundle is set for that channel). The `Unlink bundle from channel` action only affects the association with the channel currently displayed for this bundle (e.g., “dev” in the screenshot). If this bundle is also active on other channels, those links will remain. You’ll need to manage unlinking from other channels separately, for example, by navigating to the respective channel’s configuration page. *** Next, you can see the `Size`. If you click on it you will be able to download this bundle. It should look something like this: ![download bundle](/download-bundle.webp) *** Finally, the **Devices** section lists all devices that are currently using this specific bundle version. This can be helpful for understanding the rollout status and impact of this bundle. # Channels > Channels are a way to manage your app's updates. Each channel can have one version. This allows you to have multiple versions of your app in production at the same time. ## How Capgo chooses a channel (precedence) When a device asks Capgo for an update, the channel it will use is decided in the following order (highest priority first): 1. **Forced device mapping**: If the device ID is explicitly forced to a channel (see the *Forced devices* list inside the channel settings), that channel always wins. 2. **Cloud override (created by `setChannel()` or Webapp action)**: Calling [`setChannel`](/docs/plugin/api/#setchannel) (or changing a device’s channel in the dashboard) writes a persistent override in the cloud tied to that device ID. That override is consulted after forced mapping but before any defaults. Re‑installing the app does **not** clear it; deleting the device entry does. 3. **Capacitor config `defaultChannel` (test build default)**: For internal / beta / test builds you can set `defaultChannel` (legacy key `channel`) in `capacitor.config.*` so test devices start on a pre-release channel (e.g. `beta`, `pr-123`). If absent, the device will proceed to the cloud default. Production builds usually leave this unset. 4. **Cloud Default Channel (primary strategy for \~99% of users)**: The main production channel virtually all real users land on. Any new device without a force, without an override, and without a config `defaultChannel` uses this. Changing it rolls out (or rolls back) for everyone in seconds—no new binary. Why the **cloud default** is the main path: * Instant rollout or rollback without rebuilding or re‑publishing native binaries. * One place to manage both iOS & Android behavior. * Safer: you can confirm bundles exist and settings are correct before switching default. * Auditable changes (team members can see who changed what in the UI / logs). Design principle: Layers above (force / override / config) are *exceptions* (debug single user, QA switching, test build defaults). Normal users flow to the cloud default. Changing the *cloud default* channel affects *new* normal devices that: * Are not forced * Do not already have a cloud override * Do not have an app-level `defaultChannel` defined If a test build ships with `defaultChannel: 'beta'` and you later change the cloud default to `production`, devices that started on `beta` via the config stay there until you: (a) override them with `setChannel()`, (b) force them, or (c) delete the device entry. Devices stay on their current channel unless you: * Force them to another channel. * Call `setChannel()` (creating/replacing the cloud override) or change it manually in the dashboard. * Remove / archive the channel they are on (then they will fall back through the precedence again at next check). If a channel is disabled for a platform (see iOS / Android toggles) and would otherwise have been selected, the selection skips it and falls back to the next rule. > Note: Setting `defaultChannel` means changing it requires a new binary; use it intentionally for test/QA, not for general production control. ### Capacitor config example capacitor.config.ts ```ts // Example: a TestFlight or internal QA build defaults to the beta channel. const config = { plugins: { Capgo: { defaultChannel: 'beta', // Test build default. Omit in production so users attach to cloud default. // legacy key: channel }, }, }; export default config; ``` If you later change the dashboard default to `production`, devices already on another channel (via config, override, or force) will NOT move automatically; only fresh devices (or those whose override/force you clear) pick it up. *** ## Managing channels First, let’s take a look at the channels page. You can access it by [clicking on your app](/docs/webapp/main-page) and then [clicking on the channels tab](/docs/webapp/main-app-page). ![channel list](/channels.webp) ## Creating a channel As you can see, there exists a plus button in the lower right corner. (`1` in the image) Clicking on it will open a modal where you can create a new channel. ![new channel](/new_channel_modal.webp) Then after you click on `Add` a new channel should appear in the list. ![after channel create](/post-channel-create.webp) ## What does misconfigured mean? Sometimes the configuration of a channel is not valid. In that case, you will get a big warning and the `Misconfigured` column will say `Yes` for one or more of the channels. You can learn more about it [here](/docs/cli/commands/#disable-updates-strategy) ## Deleting a channel Deleting a channel is straight forward. Just click on the trash icon and confirm the deletion. (`2` in the image) ## Managing a channel Clicking on the channel name will open a modal where you can manage the channel. (`3` in the image) This page should look something like this: ![manage channel](/manage_channel_main.webp) Let’s go through the different sections. First the `Bundle number` (`1` in the image). This is the current version for that channel. When asked to serve an update this channel will always attempt to respond with that version.\* \[^1] Clicking on it should take you to the [bundle](/docs/webapp/bundles/) page. Second the `Shared to` (`2` in the image) page. I recommend against ever using this. A new and better system is in the works. Now the forced devices (`3` in the image). This is a list of devices that will always get updates from this channel. This is useful for testing purposes. You can add force a device to a channel from the [devices](/docs/webapp/devices/) page. Lastly the settings (`4` in the image). This is where you can manage how the channels behave. After you click on it you should see something like this: ![setting of channel](/channel_settings.webp) The list of settings is long, but I will do my best to explain them all. *** First the `Default channel` **THIS IS PROBABLY THE MOST IMPORTANT ONE**.\ If a channel is marked as default, then it will be used as the default channel for all new devices.\ In different terms: If you have a new user Capgo will try to serve them the latest version of this default channel (unless the device is forced or has an override as described above). Only 1 channel can be set to default at a time. If you try to break this rule you will be asked to confirm your action. ![confirm make change](/confirm-make-default.webp) After you confirm the old default channel will be unmarked as default and the new one will be marked as default. *** Second the `IOS` setting. This is relatively simple. If this is false then IOS devices will not be allowed to download updates from this channel. Third is the `Android` setting. This is similar to `IOS`. If this is false then Android devices will not be allowed to download updates from this channel. Fourth is the `Disable auto downgrade under native` setting. If this is true then it will be impossible to downgrade from a native version. This means that if you have uploaded a `1.2.0` version to the app store or play store and try to set the channel version to `1.1.0` then the update (downgrade) will fail. Fifth is the `Disable auto update`. This setting is quite complex, and you can learn more about it [here](/docs/cli/commands/#disable-updates-strategy) As for `Allow development build`. If this is true then development builds will be allowed to download updates from this channel. If not then any update request that has the `prod` set to false will be rejected. This is mostly useful for testing purposes. Seventh is the `Allow Emulators`. If this is false then Capgo will disallow any update request that comes from an emulator. This is mostly useful for testing purposes. Eight is the `Allow devices to self associate`. If this is true then the [setChannel](/docs/plugin/api/#setchannel) method will be available. If this is set to false and you try to call the [setChannel](/docs/plugin/api/#setchannel) method with this channel then the call will fail. # Devices > A comprehensive guide on utilizing the devices page to manage and configure your devices effectively, including filtering options and detailed configuration settings for individual devices. ## Show the list of all devices First, let’s take a look at the devices page. You can access it by [clicking on your app](/docs/webapp/main-page) and then [clicking on the devices tab](/docs/webapp/main-app-page). ![devices list](/devices.webp) ## Show only developer devices You might want to show only the overwritten devices (Devices that have a [custom channel](/docs/plugin/api/#setchannel) or a custom version) To do that click on `Filters` and then on `Override`. It should look something like this: ![filter devices](/overwrite-filter.webp) ## Configuring a device To configure a specific device click on it in the table and then you should see something like this: ![show one device](/device-specific.webp) First the `Custom ID`. This is a very useful field that helps you connect the device to an ID you can recognize for your own users. Use it to easily identify which device belongs to which user. You can set it from the WebUI or from the device with `CapacitorUpdater.setCustomId({ customId: user });` Next the force version. If this is set then this device will **ALWAYS** receive this version. It takes precedence over the channel. Lastly the custom channel. If this is set then this device will not care about the public (default) channel and just use this one. # Logs > Understand and utilize the application logs of Capgo to diagnostics and track the action of your devices with the updates. ## Understanding Application Logs The Logs page provides a detailed history of update events and diagnostic information for your application. This is crucial for monitoring the update process, troubleshooting issues, and understanding how your devices interact with Capgo. You can access it by [clicking on your app](/docs/webapp/main-page) and then [clicking on the “Logs” tab (previously named “updates” in some older screenshots or documentation)](/docs/webapp/main-app-page). From there you should see a page similar to this, displaying a list of log entries: ![show logs](/logs.webp) Logs Page Overview Each log entry typically includes information such as the timestamp, the device ID, the log message or code, and the bundle version involved. ### Example Log Entries and Meanings Here are a few examples of common log codes you might encounter: * **`noNew`**: This indicates that the device checked for an update but already has the latest available version for its assigned channel. * **`get`**: Signifies that the device successfully received information to download a new bundle. * **`download_complete`**: Confirms that a new bundle has been successfully downloaded to the device. * **`set`**: Means a downloaded bundle has been successfully installed and set as the active version on the device. * **`update_fail`**: Indicates that a new bundle was installed, but the application failed to confirm its readiness (e.g., `notifyAppReady` was not called), leading to a rollback. These are just a few examples. For a comprehensive list of all possible log codes (both from the backend and the device) and their detailed explanations, please refer to our detailed debugging guide: ➡️ **[Full Log Code Reference and Debugging Guide](/docs/plugin/debugging/#understanding-cloud-logs)** ## Getting More Details About a Log If you click on a specific log entry, it will typically take you to the [device’s page](/docs/webapp/devices/). This allows you to see the full history for that particular device, which can be very helpful for diagnosing device-specific issues or understanding its update journey. # App Page > What does the app page of the Capgo webapp shows? And what you can do with it. ## What does the app page shows? First, let’s take a look at the main page of the app: In Capgo, an app represents your mobile application integrated with Capgo’s live update system. It allows you to manage updates, channels, and devices seamlessly. ![Main page screeshot](/main-app-page.webp) Let’s take a closer look at this. The main app page is divided into several key areas: 1. **Top Navigation Bar:** Provides access to different sections of your app management: * **Overview (1):** The current view, displaying key metrics and summaries. * **Information (2):** Displays your app’s core settings and details (see “App Information” section below). * **[Bundles (3)](/docs/webapp/bundles/):** Manage your app’s versions and releases. * **[Channels (4)](/docs/webapp/channels/):** Configure and manage different update channels (e.g., production, beta). * **[Devices (5)](/docs/webapp/devices/):** View and manage registered devices, including setting specific overrides. * **[Logs (6)](/docs/webapp/logs/):** Access detailed logs and error reports for your app. 2. **Statistics Display:** Visualizes important metrics for the last billing period (data reflects usage from your billing day, not the 1st of the month): * **Monthly Active Users (7):** Tracks the number of unique active users over time. * **Storage (8):** Shows the current storage consumption. * **Bandwidth (9):** Displays the bandwidth usage. * **Active Device by Bundle (10):** (Beta) Shows the distribution of active devices across different app bundles. 3. **Summary Cards:** Offers a quick overview of key counts: * **Channels (11):** Total number of configured channels. * **Bundles (12):** Total number of app bundles. * **Devices (13):** Total number of registered devices. * **Updates (14):** Total number of updates performed. ## App Information This section corresponds to the “Information” tab (2) in the top navigation bar. Here you can view and manage crucial details and settings for your application. ![App Information Page](/app_info.webp) App Information Page Here’s a breakdown of the available fields and actions: * **App Icon:** Displays your application’s icon. You can click the “Change” button to upload a new icon. * **App ID:** A unique identifier for your application within Capgo. This ID is not editable. * **App Name:** The display name for your application. You can modify this as needed. * **Default Upload Channel:** Specifies the default channel to which new bundles will be uploaded. You can click the edit icon to select a different default channel. * **Auto Delete Bundles Not Used (after x seconds):** This setting allows you to automatically delete old bundles that haven’t been used for a specified duration (in seconds). This helps manage storage and keep your bundle list clean. `2592000` seconds is equivalent to 30 days. * **Transfer the application to another organisation:** This section provides an option to initiate the transfer of your application to a different organization you are a part of. * **Delete App Button:** Permanently deletes your application from Capgo. This action is irreversible and will remove all associated data, bundles, channels, and devices. * **Update Button:** Saves any changes you’ve made to the editable fields on this page (e.g., App Name, Default Upload Channel, Auto Delete Bundles setting). # Home > What does the home page of the Capgo webapp shows? And what you can do with it. ## What does the main page shows? First, let’s take a look at the main page: ![Main page screeshot](/main-page.webp) Let’s start at the beginning. The first thing you see is the **stats**. It contains app-specific statistics. Those updates depend on the usage of the app The second thing you see is the list of all available apps. This will change depending on how many apps have you created. You can click on each app to see more details about it. The third thing you see is the **API keys** button. This button will take you to the [API keys](/docs/webapp/api-keys/) page. The next thing you see is the **test Capgo** button. This button will change depending on your first and second name and it will take you to the [settings](/docs/webapp/settings/) or support page. Lastly, you see a button to add another app. This button will take you to a page where you can add a new app to capgo. # Two-factor authentication > Managing two-factor authentication to better protect your capgo account. This doc will help you to make your account the most secure possible, and prevent bad actor sending unwanted bundle to your user ## What is 2FA? 2FA is a security measure designed to prevent a bad actor from taking over your capgo account.\ It achieves it by requiring an additional code. This code is stored on your mobile phone or a hardware 2FA key. It changes every 30 seconds, making it impossible to guess ## Requirements for this guide * An Android or IOS phone * Internet connection ## What will this guide cover? This guide will show how to setup 2FA using `Google Authenticator`. Other apps exist to serve a simular purpose, however I cannot cover the entire topic of 2FA in this guide. ## How to setup 2FA? First download the `Google Authenticator` app. If you are on Android,, you can download it from the [play store](https://play.google.com/store/apps/details/?id=com.google.android.apps.authenticator2). On IOS you can download it from the [App store](https://apps.apple.com/us/app/google-authenticator/id388497605/) Second, please go to [capgo’s account settings](https://web.capgo.app/dashboard/settings/account/). There you should see a green button that should look like this ![Button MFA](/button-mfa.webp) Click it, and once you do, a QR code should appear ![Enable MFA](/enable-mfa.webp) Danger ⚠️ Important Note:\ Never share this QR code with anyone, or you could get logged out of your account Next, please open the `Google Authenticator` on your phone. Once you do, follow these steps: Click the plus button ![MFA auth plus](/mfa-auth-plus.webp) After that, please click the camera button ![MFA scan QR](/mfa-scan-qr.webp) That will open the camera preview. Please scan the QR code shown on your PC. After you do that, you should see something like this: ![MFA final code](/mfa-final-code.webp) Then please go back to the PC and click the verify button ![Verify MFA](/enable-mfa-verify.webp) This will open a window to type our 2FA code. In my case, this code is `095101` but it will be different for you.\ After you type this code, please click on the `verify` button ![MFA verify code final](/mfa-verify-final-code.webp) If you entered the correct code and pressed `verify` you should see a pop-up like this ![MFA enabled](/mfa-enabled.webp) Congrats!\ You enabled 2FA authentication 🎉 ## How to login using 2FA Next time you login to your account, you will see a window like this ![MFA required](/mfa-required.webp) Please open the authenticator and copy your auth code ![MFA login](/mfa-login.webp) Danger ⚠️ Important Note:\ Press `verify` before the code refresh, otherwise the code will change, and the old one will no longer be valid Then input the code, into the login form and pres the `verify` ![MFA login](/mfa-final-login-verify.webp) If you entered the correct code you should see the capgo dashboard ## How to disable 2FA To disable 2FA please go to the [capgo’s account settings](https://web.capgo.app/dashboard/settings/account/). There you should see a red button that should look like this: ![MFA disable button](/mfa-disable-button.webp) Click it, and and you should see a screen like this ![MFA disabled](/mfa-disable-2.webp) Just press the `disable` button, and that’s it. # Organization system > A detailed guide on managing and organizing your teams and applications within your Capgo account, ensuring secure collaboration and efficient access control for all members involved. ## What is the organization system? The organization system is a system in capgo that allows you to securely share your apps with members of your team. ### Q: How can I access my organization’s info? In order to access your organization’s info, please go to [settings](/docs/webapp/settings/#how-to-get-to-the-settings-page) and then click on the `Organization settings` ![Org settings](/orgs-settings.webp) ### Q: How can I change the organization I am viewing? To view the settings of a different organization, please click on the organization selector near your name. ![Org selector](/org-selector.webp) If you cannot see this, then you are likely not on the settings page. ### Q: How can I see the members of my organization? Please click on the `members` ![Org Show members](/org-show-members.webp) ### Q: How can I invite a user to an organization? Please click on `Add member` ![Org add member](/orgs-add-member.webp) Then a pop-out will showup - please enter the user’s email address. ![Invite to org](/invite-to-org-email-enter.webp) Then click `invite`. Another popout will show up, this time asking you about the permission that the invited user should have. ![Select perm for org](/select-perm-orgs.webp) Here is a breakdown of all the permissions: | Permission | Read | Upload | Write | Admin | Super Admin | | -------------------------------- | ---- | ------ | ----- | ----- | ----------- | | Show app stats | ✅ | ✅ | ✅ | ✅ | ✅ | | Show app channels | ✅ | ✅ | ✅ | ✅ | ✅ | | Show devices | ✅ | ✅ | ✅ | ✅ | ✅ | | Show logs | ✅ | ✅ | ✅ | ✅ | ✅ | | Show bundles | ✅ | ✅ | ✅ | ✅ | ✅ | | Delete app | ❌ | ❌ | ❌ | ❌ | ✅ | | Delete channel | ❌ | ❌ | ❌ | ✅ | ✅ | | Delete version | ❌ | ❌ | ✅ | ✅ | ✅ | | Change org’s settings | ❌ | ❌ | ❌ | ✅ | ✅ | | Manage org users | ❌ | ❌ | ❌ | ✅ | ✅ | | Alter channel settings | ❌ | ❌ | ✅ | ✅ | ✅ | | Upload new version | ❌ | ✅ | ✅ | ✅ | ✅ | | Alter devices | ❌ | ❌ | ✅ | ✅ | ✅ | | Change channel’s current version | ❌ | ❌ | ✅ | ✅ | ✅ | | Create new channel | ❌ | ❌ | ❌ | ✅ | ✅ | | Alter version (metadata) | ❌ | ❌ | ✅ | ✅ | ✅ | | Manage billing | ❌ | ❌ | ❌ | ❌ | ✅ | | Delete a version unsafely | ❌ | ❌ | ❌ | ❌ | ✅ | ### Q: How is billing done within orgs? Anyone with a **super admin** permission can manage the billing for a given organization. Plans are linked to a organization and not to your personal account. Danger ⚠️ Buying a plan will ONLY affect the organizations that you have currently selected ### Q: Can I create more than one organization? No, not yet. # Payment system > Managing payments in your Capgo account. In this section we show you how to manage your Card and plan for Capgo ## What is this about? This page aims to answer some questions about the payment system in capgo. #### Q: How can I upgrade my capgo plan? A: You can upgrade your capgo plan by going to [the settings](/docs/webapp/settings/#how-to-get-to-the-settings-page) and clicking on the **Plans** button. ![Choose plan](/plans-button.webp) Then you can select the plan that best fits your needs and click on **Subscribe** ![Subscribe to plan](/plans-subscribe.webp) Then a stripe page will open up. There, you can enter your payment information. ![Stripe portal](/plans-stripe.webp) #### Q: Are payments secure? A: Yes, payments are fully managed by stripe. Capgo never gets access to your credit card details. Stripe takes security very seriously. [Learn more about stripe security policy](https://stripe.com/docs/security/) #### Q: Will capgo automatically upgrade my plan when I exceed the limit? A: No, capgo will never change your plan. #### Q: Will cagpo send me an email when my plan is near its limits? A: Yes, capgo will send you an email informing you about the usage. #### Q: Will the plan I purchase affect the organizations I am invited to? A: No, the plan will only affect the organization you have currently selected. Please refeer to [the organization documentation](/docs/webapp/organization-system/#q-how-is-billing-done-within-orgs). #### Q: What if I need a more tailored plan? A: [Please contact capgo’s support directly](/docs/getting-help#support-by-chat) #### Q: What is the refund policy for capgo? A: A refund policy can be found [here](https://capgo.app/return/) # Settings > How to change the user settings, manage your info, name and email change your picture and more from your Capgo account ## How to get to the settings page First click on **FIRS\_NAME SECOND\_NAME**. In my case this is **test Capgo**. In your case, this will be your first name and then your second name. Then click on **Settings**. ![open settings](/settings-go.webp) ## Changing the user settings To change any user setting you can just fill out the form in the account and then click on **Update**. ![save change in account](/account-save.webp) Then a confirmation should appear. ![acount updated](/account-updated.webp) ## Changing the password To change the password go to the settings page and click on **Password**. Then fill in the form and click on **Update**. ![update password](/update-passwd.webp) When the password does not follow the capgo password security rules then you will get an error message. ![wrong password](/passwd-error.webp) # Capgoへようこそ > Capgo es una plataforma de código abierto de actualizaciones en tiempo real para Capacitor y equipos de desarrollo móvil, que permite entregar actualizaciones a los usuarios en minutos en lugar de días El poder de la Actualización en Vivo Entrega de manera fluida actualizaciones de aplicaciones en vivo, correcciones críticas de errores, cambios de contenido, funciones beta y más para brindar a tus usuarios la mejor experiencia posible Fácil de integrar El plugin toma 3 pasos para integrarse en tu código base y te permite enviar actualizaciones a tus usuarios en cuestión de minutos en lugar de días Instalación Ejecuta `npx @capgo/cli@latest init [APIKEY]` para comenzar Documentación extensa Aprende en la [Documentación](/docs/getting-started/quickstart/) cómo dominar el plugin en 5 minutos con nuestro video de introducción # Comandos > Documentación CLI de Capgo ### Uso Todos los comandos deben ejecutarse en la carpeta de tu aplicación con el proyecto Capacitor iniciado correctamente [Capacitor Runtime nativo multiplataforma para aplicaciones web ](https://capacitorjs.com/docs/getting-started/) ### **Inicializar** `npx @capgo/cli@latest init [apikey]` Este método está aquí para guiarte paso a paso Agregará tu aplicación a Capgo Agregará el código a tu aplicación para validar la actualización Asimismo, construirá tu aplicación Además, subirá tu aplicación a Capgo Y te ayudará a verificar si la actualización funciona ### **Iniciar sesión** `npx @capgo/cli login [apikey]` Este método está aquí para recordar el `apikey` por ti Note usa `--apikey=********` en cualquier comando para sobrescribirlo **Opcionalmente puedes proporcionar:** `--local` Esto almacenará tu **apikey** en el repositorio local y lo ignorará en git ## **Doctor** `npx @capgo/cli doctor` Comando para verificar si estás actualizado con los paquetes de Capgo Este comando también será útil para reportar errores ## Aplicación ### **Agregar** `npx @capgo/cli app add [appId]` `[appId]` tu ID de aplicación, el formato `comtestapp` se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) > 💡 Todas las opciones se inferirán de tu configuración si no se proporcionan Opcionalmente, puedes proporcionar: * `--icon [/ruta/a/mi/icono]` para tener un icono personalizado mostrado en la aplicación web de Capgo * `--name [test]` para tener un nombre personalizado en la lista * `--apikey [key]` API key para vincular a tu cuenta * `--retention [retention]` período de retención del paquete de la aplicación en días, 0 por defecto = infinito Ejemplo de `capacitorconfigjson` para appId y AppName, el icono se busca en la carpeta de recursos ```json { "appId": "eeforgrcapacitor_go", "appName": "Capgo", "webDir": "dist" } ``` ### **Establecer** `npx @capgo/cli app set [appId]` `[appId]` es tu ID de aplicación, el formato se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) Opcionalmente, puedes proporcionar: * `--icon [/ruta/a/mi/icono]` para tener un icono personalizado mostrado en la aplicación web de Capgo * `--name [test]` para tener un nombre personalizado en la lista * `--retention [retention]` período de retención del paquete de la aplicación en días, 0 por defecto = infinito * `--apikey [key]` API key para vincular a tu cuenta ### **Listar** `npx @capgo/cli app list [appId]` `[appId]` tu ID de aplicación, el formato `comtestapp` se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) Opcionalmente, puedes proporcionar: * `--apikey [key]` API key para vincular a tu cuenta ### **Eliminar** `npx @capgo/cli app delete [appId]` `[appId]` tu ID de aplicación, el formato `comtestapp` se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) Opcionalmente, puedes proporcionar: * `--apikey [key]` API key para vincular a tu cuenta * `--bundle` con el número de versión solo eliminará esta versión ### Depurar `npx @capgo/cli app debug [appId]` `[appId]` tu ID de aplicación, el formato `comtestapp` se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) Opcionalmente, puedes proporcionar: * `--apikey [key]` API key para vincular a tu cuenta * `--device` con el dispositivo específico que deseas depurar ### Configuración `npx @capgo/cli app setting [path]` Editar la configuración de Capacitor `[path]` - ruta de la configuración que deseas cambiar Por ejemplo, para cambiar el `appId`, proporciona `appId` Si deseas deshabilitar la actualización automática en `capacitor-updater` proporciona `pluginsCapacitorUpdaterautoUpdate` ¡DEBES proporcionar `--string` o `--bool`! Opciones: * `--string ` - establece la configuración como una cadena * `--bool ` - establece la configuración como un booleano ## Paquete ### Subir `npx @capgo/cli bundle upload [appId]` `[appId]` es tu ID de aplicación, el formato se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) Opcionalmente, puedes proporcionar: * `--apikey ` API key para vincular a tu cuenta * `--path ` Ruta de la carpeta a subir * `--channel ` Canal para vincular * `--external ` Enlace a URL externa en lugar de subir a Capgo Cloud * `--iv-session-key ` Establecer la IV y clave de sesión para URL de paquete externo * `--s3-endpoint ` URL del endpoint S3 No funciona con carga Parcial u opción externa * `--s3-region ` Región para tu bucket S3 * `--s3-apikey ` API key para tu endpoint S3 * `--s3-apisecret ` API secret para tu endpoint S3 * `--s3-bucket-name ` Nombre para tu bucket AWS S3 * `--s3-port ` Puerto para tu endpoint S3 * `--no-s3-ssl` Deshabilitar SSL para carga S3 * `--key ` Ruta personalizada para clave de firma pública (sistema v1) * `--key-data ` Clave de firma pública (sistema v1) * `--key-v2 ` Ruta personalizada para clave de firma privada (sistema v2) * `--key-data-v2 ` Clave de firma privada (sistema v2) * `--bundle-url` Imprime la URL del paquete en stdout * `--no-key` Ignorar clave de firma y enviar actualización sin cifrar * `--no-code-check` Ignorar la verificación si notifyAppReady() es llamado en el código fuente y el índice presente en la carpeta raíz * `--display-iv-session` Mostrar en la consola la IV y clave de sesión usada para cifrar la actualización * `--bundle ` Número de versión del paquete a subir * `--min-update-version ` Versión mínima requerida para actualizar a esta versión Usado solo si la actualización automática está deshabilitada en los metadatos del canal * `--auto-min-update-version` Establecer la versión mínima de actualización basada en paquetes nativos * `--ignore-metadata-check` Ignora la verificación de metadatos (node\_modules) al subir * `--ignore-checksum-check` Ignora la verificación de suma de comprobación al subir * `--timeout ` Tiempo límite para el proceso de carga en segundos * `--partial` No sube archivos parciales a Capgo cloud * `--tus` Sube el paquete usando el protocolo tus * `--multipart` Usa protocolo multipart para subir datos a S3, Obsoleto, usa TUS en su lugar * `--encrypted-checksum ` Una suma de comprobación cifrada (firma) Usado solo al subir un paquete externo * `--package-json ` Una ruta a packagejson Útil para monorepos * `--auto-set-bundle` Establecer el paquete en capacitorconfigjson * `--node-modules ` Una lista de rutas a node\_modules Útil para monorepos (separado por comas ej: //node\_modules,/node\_modules) > ⭐️ La opción externa ayuda a desbloquear 2 casos: corporativos con preocupaciones de privacidad, no enviar el código a terceros y aplicaciones mayores a 200 MB Con esta configuración, Capgo solo almacena el enlace al zip y envía el enlace a todas las aplicaciones > 👀 Capgo cloud nunca mira lo que hay en el enlace (para la opción externa), o en el código cuando está almacenado > 🔑 Puedes agregar una segunda capa de seguridad usando cifrado, entonces Capgo no podrá ver ni modificar nada, se vuelve “sin confianza” Ejemplo de `packagejson` para versión ```json { "version": "102" } ``` > ⛔ La versión debe ser mayor que “000” > 💡 No olvides actualizar el número de versión cada vez que envíes uno, el número de versión no puede ser sobrescrito o reutilizado después de la eliminación por razones de seguridad ### **Listar** `npx @capgo/cli bundle list [appId]` `[appId]` tu ID de aplicación, el formato `comtestapp` se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) Opcionalmente, puedes proporcionar: * `--apikey [key]` API key para vincular a tu cuenta ### **Eliminar** `npx @capgo/cli bundle delete [appId]` `[appId]` tu ID de aplicación, el formato `comtestapp` se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) Opcionalmente, puedes proporcionar: * `--apikey [key]` API key para vincular a tu cuenta * `--bundle` con el número de versión solo eliminará esta versión ### Limpiar en un rango SemVer para una versión mayor a Cloud `npx @capgo/cli bundle cleanup [appId] --bundle=[majorVersion] --keep=[numberToKeep]` `[appId]` tu ID de aplicación, el formato `comtestapp` se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) Opcionalmente, puedes proporcionar: * `--apikey [key]` API key para vincular a tu cuenta * `--bundle [majorVersion]` una versión para la que deseas eliminar paquetes anteriores, mantendrá el último + `numberToKeep`\* `--keep [numberToKeep]` el número de paquetes que desea mantener (por defecto 4) Por ejemplo: Si tiene 10 versiones del 1001 al 10011, y utiliza `npx @capgo/cli cleanup [appId] --bundle=1000` eliminará del 1001 al 1006, 1007 hasta 10011 se mantendrán Si tiene 20 versiones en total, y no proporciona un número de bundle como este: `npx @capgo/cli cleanup [appId] --keep=2` Eliminará 18 versiones y mantendrá las últimas 2 > Este comando pedirá confirmación, muestra una tabla de lo que mantendrá y eliminará Note Este comando ignorará los bundles que actualmente estén en uso en cualquier canal ### **Encrypt** > **Advertencia**: Este comando está obsoleto y será eliminado en la próxima versión mayor. Por favor use el nuevo sistema de encriptación `npx @capgo/cli bundle encrypt [path/to/zip]` Este comando se usa cuando utiliza una fuente externa para almacenar su código o con fines de prueba Opcionalmente, puede proporcionar: `--key [/path/to/my/private_key]` la ruta de su clave privada `--key-data [privateKey]` los datos de la clave privada, si desea usarla en línea El comando imprimirá su `ivSessionKey` y generará un zip encriptado, para usarlo con el comando upload o decrypt ### **Encrypt V2** `npx @capgo/cli bundle encryptV2 [path/to/zip] [checksum]` Este comando se usa cuando utiliza una fuente externa para almacenar su código o con fines de prueba El checksum es el sha256 del bundle (generado por —key-v2), se usa para verificar la integridad del archivo después del descifrado Será encriptado con la clave privada y enviado junto con el bundle En la encriptación v2 el checksum se actualiza para convertirse en una “firma” del bundle Opcionalmente, puede proporcionar: `--key [/path/to/my/private_key]` la ruta de su clave privada `--key-data [privateKey]` los datos de la clave privada, si desea usarla en línea `--json` para mostrar la información como json El comando imprimirá su `ivSessionKey` y generará un zip encriptado, para usarlo con el comando upload o decrypt ### **Decrypt** `npx @capgo/cli bundle decrypt [path/to/zip] [ivSessionKey]` Opcionalmente, puede proporcionar: `--key [/path/to/my/private_key]` la ruta de su clave privada `--key-data [privateKey]` los datos de la clave privada, si desea usarla en línea Este comando se usa principalmente con fines de prueba, descifrará el zip e imprimirá la clave de sesión descifrada en base64 en la consola ### **Decrypt V2** `npx @capgo/cli bundle decryptV2 [path/to/zip] [ivSessionKey]` Opcionalmente, puede proporcionar: `--key [/path/to/my/private_key]` la ruta de su clave privada `--key-data [privateKey]` los datos de la clave privada, si desea usarla en línea Este comando se usa principalmente con fines de prueba, descifrará el zip e imprimirá la clave de sesión descifrada en base64 en la consola `--checksum [checksum]` el checksum del archivo, verificará el checksum después del descifrado ### **Zip** `npx @capgo/cli bundle zip [appId]` `[appId]` es su ID de aplicación, el formato se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) Opcionalmente, puede proporcionar: * `--path [/path/to/my/bundle]` para subir una carpeta específica * `--bundle [100]` para establecer el número de versión del bundle en el nombre del archivo * `--name [myapp]` para sobrescribir el nombre del archivo * `--json` para mostrar la información como json * `--no-code-check` para ignorar la verificación del código y enviar el bundle de todos modos * `--key-v2` para usar el nuevo sistema de encriptación Esto es necesario ya que el nuevo sistema de encriptación usa mejores checksums para verificar la integridad del archivo ### **Compatibility** `npx @capgo/cli bundle compatibility [appId] -c [channelId]` `[appId]` es su ID de aplicación, el formato se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) `[channelId]` el nombre de su nuevo canal Opcionalmente, puede proporcionar: * `--apikey [key]` Clave API para vincular a su cuenta * `--text` usar texto en lugar de emojis en la tabla * `--channel [channel]` el canal para verificar la compatibilidad * `--package-json ` Una ruta al packagejson Útil para monorepos * `--node-modules ` Una lista de rutas a node\_modules Útil para monorepos (separados por comas ej: //node\_modules,/node\_modules) ## Canal ### **Add** `npx @capgo/cli channel add [channelId] [appId]` `[channelId]` el nombre de su nuevo canal `[appId]` su ID de aplicación el formato `comtestapp` se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) ### **Delete** `npx @capgo/cli channel delete [channelId] [appId]` `[channelId]` el nombre del canal que desea eliminar `[appId]` su ID de aplicación el formato `comtestapp` se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) ### **List** `npx @capgo/cli channel list [appId]` `[appId]` su ID de aplicación el formato `comtestapp` se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) Opcionalmente, puede proporcionar: * `--apikey [key]` Clave API para vincular a su cuenta ### **Set** `npx @capgo/cli channel set [channelId] [appId]` `[appId]` es su ID de aplicación, el formato se explica [aquí](https://capacitorjs.com/docs/cli/commands/init/) Opcionalmente, puede proporcionar: * `--bundle [123]` su bundle de aplicación ya enviado a la nube, para vincularlo a un canal * `--latest` obtener la versión del bundle de `packagejson:version`, no se puede usar con `--bundle` * `--state [ normal | default ]` establece el estado del canal, puede ser `normal` o `default` Un canal debe ser `default` * `--downgrade` permite que el canal envíe versiones anteriores a los dispositivos * `--no-downgrade` impide que el canal envíe versiones anteriores a los dispositivos * `--upgrade` permite que el canal envíe actualizaciones (major) a los dispositivos * `--no-upgrade` impide que el canal envíe actualizaciones (major) a los dispositivos * `--ios` permite que el canal envíe versiones a dispositivos iOS * `--no-ios` impide que el canal envíe versiones a dispositivos iOS * `--android` permite que el canal envíe versiones a dispositivos Android * `--no-android` impide que el canal envíe versiones a dispositivos Android * `--self-assign` permite que los dispositivos se autoasignen a este canal * `--no-self-assign` impide que los dispositivos se autoasignen a este canal * `--disable-auto-update STRATEGY` Deshabilita la estrategia de actualización automática para este canal Las opciones posibles son: major, minor, metadata, none * `--apikey [key]` Clave API para vincular a su cuenta ## Estrategias para deshabilitar actualizaciones Hay varias formas de manejar la desactivación de actualizaciones para versiones muy antiguas\ Capgo no puede actualizar código nativo por lo que una actualización desde una versión con el código nativo antiguo a una versión con el código nativo actualizado no debería ser posible Hay varios modos de lograr esto Primero, la estrategia `major` Evita una actualización de `000` -> `100` El major es el número resaltado (**1**00 y **0**00)\ Segundo es la estrategia `minor` Evita una actualización de `000` -> `110` o una actualización de `110` a `120` **TENGA EN CUENTA** esta estrategia no evita una actualización de `010` -> `110` Tercero, la estrategia `patch` Se agregó a capgo como un modo muy estricto No se recomienda usarlo a menos que entienda completamente cómo funciona Para que acepte una actualización se deben cumplir las siguientes condiciones: * El major es el mismo entre la versión nueva y la antigua * El minor es el mismo entre la versión nueva y la antigua * El patch de la nueva versión es mayor que el patch de la versión antigua Aquí hay un ejemplo de en qué escenarios se permite o deniega la actualización * 00311 -> 00314 ✅ * 000 -> 00314 ✅ * 00316 -> 00314 ❌ * 01312 -> 00314 ❌ * 10312 -> 00314 ❌ Por último, la estrategia más complicada La estrategia `metadata`\ Primero debe saber que inicialmente después de habilitarla las actualizaciones **FALLARÁN** ya que el canal carece de los metadatos requeridos\ Si el canal carece de metadatos verá un mensaje como este: ![Cannot find metadata](/fail-metadata.webp) Si ve algo así, sabrá que tiene que ir al bundle actual del canal que está fallando y establecer los metadatos\ Primero, determine qué canal está fallando Puede hacerlo mirando la columna `misconfigured` ![Tabla mal configurada](/misconfigured-table.webp) Luego ve al canal fallido y haz clic en `Bundle number`. Esto te llevará a la página del paquete ![Localizar canal fallido](/fail-channel-show.webp) Una vez allí, completa el campo `Minimal update version`. Esto debe ser un [semver](https://devhintsio/semver/)\ Si el valor que ingresas no es un semver recibirás un error, pero si todo va correctamente deberías ver algo como esto: ![Establecer versión mínima](/set-min-update-version.webp) Ahora, probablemente no quieras establecer estos datos manualmente cada vez que actualices. Afortunadamente, la CLI evitará que envíes una actualización sin estos metadatos ![CLI falla sin metadatos](/cli-fail-no-metadata.webp) Para subir correctamente un paquete cuando usas la opción `metadata`, necesitas pasar el `--min-update-version` con el semver válido. Algo como esto: ![CLI subida con metadatos](/cli-upload-with-metadata.webp) El `--min-update-version` no es la ÚNICA forma de hacer compatibilidad También existe el `--auto-min-update-version`. Así es como funciona 1. Primero, revisa la versión actualmente subida al canal. Comprueba la compatibilidad igual que el comando `bundle compatibility` lo haría 2. Segundo, si la nueva versión es 100% compatible, reutiliza el `min_update_version` de la última versión en el canal Si no, entonces establece el `min_update_version` al número de paquete de la versión recién subida Siempre obtendrás información sobre cuál es el `min_update_version` cuando uses esta opción. Se verá algo como esto: ![Versión mínima de actualización](/min_update_version_info.webp) Si la nueva versión no es compatible, debería verse algo como esto ![Versión mínima de actualización no compatible](/min_update_version_not_compatible.webp) ## Cifrado de extremo a extremo (Sin confianza) Capgo soporta cifrado de extremo a extremo, esto significa que tu paquete (código) está cifrado antes de enviarse a la nube y descifrado en el dispositivo. Para ello, necesitas generar un par de claves RSA, puedes usar el siguiente comando para generarla El sistema de cifrado es una combinación de RSA y AES, la clave RSA se usa para cifrar la clave AES, y la clave AES se usa para cifrar el archivo Ver más abajo para más información sobre el sistema de cifrado ![Cómo funciona el cifrado](/crypto_explained.webp) Esquema de cifrado ### Crear clave para tu aplicación `npx @capgo/cli key create` Opcionalmente, puedes dar: `--force` para sobrescribir la clave existente. Este comando creará un par de claves en tu aplicación y te pedirá que guardes la clave privada en un lugar seguro. Se recomienda no hacer commit de la clave privada en git y no compartirla con nadie > Después de tu prueba local, elimina la clave del archivo de configuración y agrégala en el paso de CI con `key save` ### Guardar clave en la configuración de tu aplicación `npx @capgo/cli key save` Opcionalmente, puedes dar: `--key [/path/to/my/private_key]` la ruta de tu clave privada `--key-data [privateKey]` los datos de la clave privada, si quieres usarla en línea. Este comando es útil si seguiste la recomendación y no hiciste commit de la clave en tu aplicación y en la configuración ## Integración CI Para automatizar tu trabajo, te recomiendo hacer que GitHub action se encargue de enviar a nuestro servidor [Tutorial de GitHub action](https://capgo.app/blog/automatic-build-and-release-with-github-actions/) ## Nuestra aplicación demo [GitHub - Cap-go/demo-app](https://github.com/Cap-go/demo-app/) No olvides configurar la variable de entorno CI con tu clave API # CLI de 0.x a 1.x > Cómo actualizar de 0.x a 1.x No hay cambios significativos en la CLI El cambio disruptivo es principalmente el cambio de nombre del argumento `--version` a `--bundle` para evitar conflictos y seguir la nueva nomenclatura en todas partes # Encriptación > Cómo cifrar tus datos con el nuevo cifrado Esta documentación explicará cómo cifrar tus datos con el nuevo sistema de cifrado y eliminar el anterior Aprende más sobre el nuevo sistema de cifrado en el [blog post](/blog/introducing-end-to-end-security-to-capacitor-updater-with-code-signing) *** Primero, crea un nuevo par de claves con el siguiente comando: ```bash npx @capgo/cli key create ``` Este comando creará un nuevo par de claves en tu aplicación; es imperativo almacenar la clave privada en un lugar seguro. Nunca se debe confirmar la clave privada en el control de código fuente ni compartirla con terceros no confiables Este comando también eliminará la clave antigua de tu configuración de Capacitor, pero no eliminará los archivos de la clave antigua. El CLI los mantiene para permitirte continuar enviando actualizaciones en vivo para las aplicaciones que no han recibido una actualización de la tienda de aplicaciones y que todavía utilizan el plugin anterior. Esto facilita la migración Cuando la migración te pregunte “¿Quieres configurar el cifrado con el nuevo canal para admitir aplicaciones antiguas y facilitar la migración?”, por favor acepta. Esto agregará una nueva opción “defaultChannel” a tu configuración de Capacitor. Esto hará que tu aplicación use el canal “encryption\_v2”. Esto asegurará que el nuevo cifrado sea utilizado solo por aplicaciones que lo soporten. Las aplicaciones que no han recibido una actualización de la tienda de aplicaciones continuarán usando el canal predeterminado anterior *** Ahora, necesitas construir tu paquete JS y subirlo al nuevo canal. Por favor, ejecuta el siguiente comando: ```bash npx @capgo/cli bundle upload --channel encryption_v2 ``` *** Luego, ejecuta este comando para permitir que las aplicaciones se auto-asignen al canal “encryption\_v2” Caution Esto es necesario para que la nueva opción “defaultChannel” funcione ```bash npx @capgo/cli channel set encryption_v2 --self-assign ``` *** Ahora puedes ejecutar la aplicación; utilizará el nuevo sistema de cifrado Para subir el nuevo paquete JS al canal antiguo, solo necesitas ejecutar el siguiente comando: ```bash npx @capgo/cli bundle upload --channel production ``` *** No necesitas preocuparte por la configuración de Capacitor, nunca se sube a Capgo Cuando todos los usuarios hayan actualizado sus aplicaciones (puede tomar hasta 3/4 meses), puedes eliminar el “defaultChannel” de tu configuración de Capacitor Y luego, puedes eliminar el canal antiguo con el siguiente comando: ```bash npx @capgo/cli channel delete encryption_v2 ``` *** Después de eliminar el canal “encryption\_v2”, todas las aplicaciones que lo usen como predeterminado comenzarán a usar el canal “production” # Descripción general Use la función de Actualizaciones en Vivo de Capgo para actualizar los paquetes JavaScript de su aplicación de forma remota y en tiempo real. Envíe actualizaciones JS directamente a sus usuarios sin pasar por el proceso de revisión de la tienda de aplicaciones para corregir errores y lanzar nuevas funciones instantáneamente. Note Las Actualizaciones en Vivo están limitadas a cambios en los paquetes JavaScript. Si necesita actualizar código nativo, como agregar o eliminar un plugin o cambiar la configuración del proyecto nativo, deberá enviar una nueva compilación binaria nativa a las tiendas de aplicaciones. ## Cómo funcionan las Actualizaciones en Vivo El sistema de Actualización en Vivo de Capgo tiene dos componentes clave: 1. El SDK de Capgo, que instala en su aplicación. El SDK verifica las actualizaciones disponibles y las descarga en segundo plano. 2. Canales, que le permiten dirigir actualizaciones a grupos específicos de usuarios. Puede usar canales para gestionar diferentes pistas de lanzamiento, como `Production`, `Staging` y `Dev`. Cuando sube un nuevo paquete JS a Capgo y lo asigna a un canal, el SDK de Capgo en las aplicaciones configuradas para ese canal detectará la actualización y la descargará. La próxima vez que la aplicación se reinicie, se cargará el nuevo paquete. ## Primeros pasos Para comenzar a usar las Actualizaciones en Vivo, siga estos pasos: 1. Complete el [Inicio rápido de Capgo](/docs/getting-started/quickstart) para configurar su aplicación en Capgo e instalar el SDK de Capgo. 2. En el código de su aplicación, llame a `CapacitorUpdater.notifyAppReady()` después de que su aplicación haya terminado de inicializarse. Esto le indica al SDK de Capgo que su aplicación está lista para recibir actualizaciones. 3. Compile su paquete JS y súbalo a Capgo: ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. Abra su aplicación y espere a que se descargue la actualización. Puede verificar el estado con: ```shell npx @capgo/cli@latest app debug ``` 5. Una vez que se descargue la actualización, cierre y vuelva a abrir su aplicación para cargar el nuevo paquete. Consulte la guía [Implementación de Actualizaciones en Vivo](/docs/getting-started/deploy) para más detalles. ## La CLI de Capgo La CLI de Capgo es una herramienta poderosa que permite a los desarrolladores interactuar con los servicios de Capgo desde sus propios pipelines de CI/CD. Con la CLI, tiene control granular sobre cuándo se producen y despliegan las compilaciones, permitiéndole integrar Capgo en sus flujos de trabajo empresariales existentes. ### ¿Para qué sirve la CLI de Capgo? La CLI de Capgo está diseñada para desarrolladores y equipos que necesitan más control y flexibilidad en sus flujos de trabajo de actualización en vivo. Al usar la CLI en sus pipelines de CI/CD, puede: * Decidir exactamente cuándo construir y desplegar actualizaciones, en lugar de depender de la automatización integrada de Capgo * Insertar sus propios procesos, como firma de código, pruebas de QA o aprobaciones de gerentes, entre los pasos de compilación y despliegue * Integrar Capgo en sus herramientas y flujos de trabajo DevOps existentes ### Autenticación Para usar la CLI de Capgo, necesitará autenticarse con su clave API. Puede generar una clave API en la configuración de su cuenta de Capgo. Para iniciar sesión y almacenar de forma segura su clave API, ejecute: ```shell npx @capgo/cli@latest login [API_KEY] ``` Este comando se guardará para uso futuro. No necesitará proporcionar su clave API con cada comando después de iniciar sesión. ### Diferencias clave con otras herramientas CLI Si está familiarizado con otras herramientas CLI de actualización en vivo, hay algunas cosas clave que debe tener en cuenta sobre la CLI de Capgo: * Capgo utiliza una única CLI tanto para casos de uso de desarrollo como de CI/CD, ya que Capgo se centra únicamente en el conjunto de funciones de actualización en vivo * La CLI de Capgo no requiere un paso de instalación separado. Está incluida en el paquete `@capgo/cli` y se puede ejecutar directamente usando `npx` * La CLI de Capgo está diseñada específicamente para el flujo de trabajo de actualización en vivo, por lo que puede no incluir algunas características o comandos que se encuentran en herramientas CLI de propósito más general ## Siguientes pasos [ Canales](/docs/live-updates/channels/) [Aprenda cómo usar canales para gestionar diferentes pistas de lanzamiento y dirigir actualizaciones a usuarios específicos](/docs/live-updates/channels/) [ Reversiones](/docs/live-updates/rollbacks/) [Descubra cómo revertir a una versión anterior del paquete JS si una actualización causa problemas](/docs/live-updates/rollbacks/) [ Comportamiento de actualización](/docs/live-updates/update-behavior/) [Personalice cómo y cuándo se descargan y aplican las actualizaciones en su aplicación](/docs/live-updates/update-behavior/) [ Actualizaciones rápidas](/docs/live-updates/differentials/) [Aprenda cómo usar actualizaciones rápidas para acelerar el proceso de actualización](/docs/live-updates/differentials/) # 概要 > Documentación detallada para los comandos de la CLI de Capgo La CLI de Capgo proporciona un conjunto de comandos para gestionar tus aplicaciones y despliegues de Capgo. Esta referencia proporciona información detallada sobre cada comando disponible, incluyendo sus opciones y ejemplos de uso ## Comandos [ init](/docs/cli/reference/init/) [Inicializar una nueva aplicación de Capgo](/docs/cli/reference/init/) [ login](/login/) [Autenticarse con el servicio de Capgo](/login/) [ doctor](/docs/cli/reference/doctor/) [Verificar tu configuración de Capgo en busca de posibles problemas](/docs/cli/reference/doctor/) [ app](/docs/cli/reference/app/) [Gestionar tus aplicaciones de Capgo](/docs/cli/reference/app/) [ bundle](/docs/cli/reference/bundle/) [Gestionar tus paquetes de aplicaciones](/docs/cli/reference/bundle/) [ channel](/docs/cli/reference/channel/) [Gestionar tus canales de lanzamiento](/docs/cli/reference/channel/) [ key](/docs/cli/reference/key/) [Gestionar tus claves de firma de aplicaciones](/docs/cli/reference/key/) ## Integración CI Para automatizar tu trabajo, recomendamos usar GitHub Actions para enviar tus actualizaciones a Capgo. Consulta nuestro [tutorial de GitHub Actions](https://capgo.app/blog/automatic-build-and-release-with-github-actions/) para más información No olvides configurar las variables de entorno de tu CI con tu clave API de Capgo ## Aplicación Demo Para un ejemplo completo de una aplicación Capgo con integración CI, consulta nuestra [aplicación demo en GitHub](https://github.com/Cap-go/demo-app/) # cuenta El comando `account` te permite gestionar tu cuenta de Capgo ### id `npx @capgo/cli account id` Obtiene tu ID de cuenta Opciones: * `-a, --apikey `: Clave API para enlazar a tu cuenta # aplicación El comando `app` te permite gestionar tus aplicaciones de Capgo ### add `npx @capgo/cli app add [appId]` Agrega una nueva aplicación a tu cuenta de Capgo `[appId]` es el ID de tu aplicación en el formato `com.example.app`. Consulta la [documentación de Capacitor](https://capacitorjs.com/docs/cli/commands/init/) para más información > 💡 Todas las opciones se obtendrán de tu `capacitor.config.json` si no se proporcionan Opciones: * `--icon [path]`: Ruta a un ícono personalizado para mostrar en la aplicación web de Capgo * `--name [name]`: Nombre personalizado para mostrar en la lista de aplicaciones * `--apikey [key]`: Clave API para vincular a tu cuenta * `--retention [days]`: Período de retención para los paquetes de la aplicación en días (predeterminado: 0 = infinito) ### set `npx @capgo/cli app set [appId]` Actualiza una aplicación existente en tu cuenta de Capgo Opciones: * `--icon [path]`: Ruta a un ícono personalizado para mostrar en la aplicación web de Capgo * `--name [name]`: Nombre personalizado para mostrar en la lista de aplicaciones * `--retention [days]`: Período de retención para los paquetes de la aplicación en días (predeterminado: 0 = infinito) * `--apikey [key]`: Clave API para vincular a tu cuenta ### list `npx @capgo/cli app list [appId]` Lista todas las aplicaciones en tu cuenta de Capgo Opciones: * `--apikey [key]`: Clave API para vincular a tu cuenta ### delete `npx @capgo/cli app delete [appId]` Elimina una aplicación de tu cuenta de Capgo Opciones: * `--apikey [key]`: Clave API para vincular a tu cuenta * `--bundle`: Eliminar solo una versión específica del paquete ### debug `npx @capgo/cli app debug [appId]` Muestra información de depuración para una aplicación Opciones: * `--apikey [key]`: Clave API para vincular a tu cuenta * `--device`: Depurar un dispositivo específico ### setting `npx @capgo/cli app setting [path]` Edita la configuración de Capacitor para una aplicación `[path]` es la ruta a la configuración que deseas cambiar (por ejemplo, `appId` o `plugins.CapacitorUpdater.autoUpdate`) Debes proporcionar ya sea `--string` o `--bool`: * `--string `: Establece la configuración a un valor de cadena * `--bool `: Establece la configuración a un valor booleano # paquete El comando `bundle` te permite gestionar los paquetes de tu aplicación ### upload `npx @capgo/cli bundle upload [appId]` Sube un nuevo paquete para una aplicación Opciones: * `-a, --apikey `: Clave API para vincular a tu cuenta * `-p, --path `: Ruta a la carpeta a subir (por defecto el `webDir` en `capacitorconfig`) * `-c, --channel `: Canal al que vincular el paquete * `-e, --external `: Enlace a una URL externa en lugar de subir a Capgo Cloud * `--iv-session-key `: Establecer la IV y clave de sesión para una URL de paquete externo * `--s3-region `: Región para tu bucket S3 * `--s3-apikey `: Clave API para tu endpoint S3 * `--s3-apisecret `: Secreto API para tu endpoint S3 * `--s3-endpoint `: URL del endpoint S3 * `--s3-bucket-name `: Nombre de tu bucket S3 * `--s3-port `: Puerto para tu endpoint S3 * `--no-s3-ssl`: Deshabilitar SSL para subidas S3 * `--key `: Ruta personalizada para la clave de firma pública (sistema v1) * `--key-data `: Datos de la clave de firma pública (sistema v1) * `--key-v2 `: Ruta personalizada para la clave de firma privada (sistema v2) * `--key-data-v2 `: Datos de la clave de firma privada (sistema v2) * `--bundle-url`: Imprimir la URL del paquete en stdout * `--no-key`: Ignorar la clave de firma y enviar una actualización sin firmar * `--no-code-check`: Omitir la verificación de `notifyAppReady()` en el código fuente y `indexhtml` en la carpeta raíz * `--display-iv-session`: Mostrar la IV y clave de sesión usada para encriptar la actualización * `-b, --bundle `: Número de versión del paquete a subir * `--min-update-version `: Versión mínima de la app requerida para aplicar esta actualización (solo se usa si la auto-actualización está deshabilitada vía metadata) * `--auto-min-update-version`: Establecer automáticamente la versión mínima de actualización basada en versiones nativas del paquete * `--ignore-metadata-check`: Ignorar la verificación de metadata (node\_modules) al subir * `--ignore-checksum-check`: Ignorar la verificación del checksum al subir * `--timeout `: Tiempo límite para el proceso de subida en segundos * `--multipart`: Usar el protocolo multipart para subir datos a S3 (obsoleto, usar `--tus` en su lugar) * `--tus`: Subir el paquete usando el protocolo tus * `--tus-chunk-size `: Tamaño del chunk para la subida tus * `--partial`: Subir solo archivos modificados a Capgo Cloud * `--partial-only`: Subir solo archivos parciales a Capgo Cloud, omitiendo el archivo comprimido (útil para paquetes grandes) * `--encrypted-checksum `: Checksum encriptado (firma) para un paquete externo * `--auto-set-bundle`: Establecer automáticamente la versión del paquete en `capacitorconfigjson` * `--dry-upload`: Realizar una prueba de subida sin subir realmente los archivos (útil para pruebas) * `--package-json `: Lista separada por comas de rutas a archivos `packagejson` (útil para monorepos) * `--node-modules `: Lista separada por comas de rutas a directorios `node_modules` (útil para monorepos) * `--encrypt-partial`: Encriptar los archivos de actualización parcial * `--delete-linked-bundle-on-upload`: Eliminar el paquete actualmente vinculado en el canal destino antes de subir ### compatibility `npx @capgo/cli bundle compatibility [appId]` Verifica la compatibilidad de un paquete con un canal específico Opciones: * `-a, --apikey `: Clave API para vincular a tu cuenta * `-c, --channel `: Canal para verificar compatibilidad * `--text`: Mostrar resultados como texto en lugar de emojis * `--package-json `: Lista separada por comas de rutas a archivos `packagejson` (útil para monorepos) * `--node-modules `: Lista separada por comas de rutas a directorios `node_modules` (útil para monorepos) ### delete `npx @capgo/cli bundle delete [bundleId] [appId]` Elimina un paquete de una aplicación Opciones: * `-a, --apikey `: Clave API para vincular a tu cuenta ### list `npx @capgo/cli bundle list [appId]` Lista todos los paquetes de una aplicación Opciones: * `-a, --apikey `: Clave API para vincular a tu cuenta ### cleanup `npx @capgo/cli bundle cleanup [appId]` Limpia paquetes antiguos para una versión mayor, manteniendo el número especificado de paquetes más recientes Opciones: * `-b, --bundle `: Número de versión mayor para limpiar * `-a, --apikey `: Clave API para vincular a tu cuenta * `-k, --keep `: Número de paquetes a mantener (por defecto: 4) * `-f, --force`: Forzar eliminación sin confirmación ### decrypt `npx @capgo/cli bundle decrypt [zipPath] [sessionKey]` Desencripta un paquete zip firmado Opciones: * `--key `: Ruta personalizada para la clave de firma privada * `--key-data `: Datos de la clave de firma privada ### encrypt `npx @capgo/cli bundle encrypt [zipPath]` Encripta un paquete zip Opciones: * `--key `: Ruta personalizada para la clave de firma privada * `--key-data `: Datos de la clave de firma privada ### encryptV2 `npx @capgo/cli bundle encryptV2 [zipPath] [checksum]` Encripta un paquete zip usando el nuevo método de encriptación Opciones: * `--key `: Ruta personalizada para la clave de firma privada * `--key-data `: Datos de la clave de firma privada * `-j, --json`: Mostrar resultados como JSON ### decryptV2 `npx @capgo/cli bundle decryptV2 [zipPath] [checksum]` Desencripta un paquete zip usando el nuevo método de encriptación Opciones: * `--key `: Ruta personalizada para la clave de firma privada * `--key-data `: Datos de la clave de firma privada * `--checksum `: Checksum del paquete para verificar integridad ### zip `npx @capgo/cli bundle zip [appId]` Genera un archivo zip para un paquete Opciones: * `-p, --path `: Ruta a la carpeta a comprimir (por defecto el `webDir` en `capacitorconfig`) * `-b, --bundle `: Número de versión del paquete a usar en el nombre del archivo * `-n, --name `: Nombre personalizado para el zip * `-j, --json`: Mostrar resultados como JSON * `--no-code-check`: Omitir la verificación de `notifyAppReady()` en el código fuente y `indexhtml` en la carpeta raíz * `--key-v2`: Usar el nuevo método de encriptación (v2) * `--package-json `: Lista separada por comas de rutas a archivos `packagejson` (útil para monorepos) # canal El comando `channel` te permite gestionar tus canales de lanzamiento ### add `npx @capgo/cli channel add [channelId] [appId]` Crea un nuevo canal para una aplicación Opciones: * `-d, --default`: Establece el nuevo canal como canal predeterminado * `-a, --apikey `: Clave API para vincular a tu cuenta ### delete `npx @capgo/cli channel delete [channelId] [appId]` Elimina un canal de una aplicación Opciones: * `-a, --apikey `: Clave API para vincular a tu cuenta * `--delete-bundle`: Elimina el paquete asociado al canal ### list `npx @capgo/cli channel list [appId]` Lista todos los canales de una aplicación Opciones: * `-a, --apikey `: Clave API para vincular a tu cuenta ### currentBundle `npx @capgo/cli channel currentBundle [channel] [appId]` Obtiene el paquete actual para un canal específico Opciones: * `-c, --channel `: Canal del cual obtener el paquete actual * `-a, --apikey `: Clave API para vincular a tu cuenta * `--quiet`: Solo muestra la versión del paquete ### set `npx @capgo/cli channel set [channelId] [appId]` Establece las propiedades de un canal Opciones: * `-a, --apikey `: Clave API para vincular a tu cuenta * `-b, --bundle `: Número de versión del paquete a establecer para el canal * `-s, --state `: Establece el estado del canal (`default` o `normal`) * `--latest`: Usa la última versión de `packagejson` como versión del paquete * `--downgrade`: Permite degradar a versiones inferiores a la versión nativa * `--no-downgrade`: Deshabilita las degradaciones a versiones inferiores a la versión nativa * `--upgrade`: Permite actualizaciones a versiones superiores a la versión nativa * `--no-upgrade`: Deshabilita las actualizaciones a versiones superiores a la versión nativa * `--ios`: Permite enviar actualizaciones a dispositivos iOS * `--no-ios`: Deshabilita el envío de actualizaciones a dispositivos iOS * `--android`: Permite enviar actualizaciones a dispositivos Android * `--no-android`: Deshabilita el envío de actualizaciones a dispositivos Android * `--self-assign`: Permite que los dispositivos se auto-asignen a este canal * `--no-self-assign`: Deshabilita la auto-asignación de dispositivos a este canal * `--disable-auto-update `: Deshabilita la estrategia de actualización automática para este canal (opciones: `major`, `minor`, `metadata`, `patch`, `none`) * `--dev`: Permite enviar actualizaciones a dispositivos de desarrollo * `--no-dev`: Deshabilita el envío de actualizaciones a dispositivos de desarrollo * `--emulator`: Permite enviar actualizaciones a dispositivos emuladores * `--no-emulator`: Deshabilita el envío de actualizaciones a dispositivos emuladores * `--package-json `: Lista separada por comas de rutas a archivos `packagejson` (útil para monorepos) # médico `npx @capgo/cli doctor` Este comando verifica si estás usando la última versión de los paquetes de Capgo También es útil para reportar errores # iniciar `npx @capgo/cli@latest init [apikey]` Este comando te guía paso a paso para: * Agregar tu aplicación a Capgo * Agregar el código a tu aplicación para validar la actualización * Construir tu aplicación * Subir tu aplicación a Capgo * Ayudarte a verificar si la actualización funciona # llave El comando `key` te permite gestionar las claves de firma de tu aplicación ### save `npx @capgo/cli key save` Guarda una clave de cifrado codificada en base64 en la configuración de Capacitor (útil para CI) Opciones: * `-f, --force`: Forzar la generación de una nueva clave * `--key`: Ruta al archivo de clave para guardar en la configuración de Capacitor * `--key-data`: Datos de clave para guardar directamente en la configuración de Capacitor ### create `npx @capgo/cli key create` Crea una nueva clave de cifrado Opciones: * `-f, --force`: Forzar la generación de una nueva clave ### delete\_old `npx @capgo/cli key delete_old` Elimina la clave de cifrado antigua # iniciar sesión `npx @capgo/cli login [apikey]` Este comando almacena tu clave API de Capgo para uso futuro Note Puedes sobrescribir la clave API almacenada pasando `--apikey=` a cualquier comando Opciones: * `--local`: Almacena la clave API en el repositorio local y lo agrega a `gitignore` # FAQ (Tanya Jawab) > Preguntas frecuentes sobre Capgo Si tienes preguntas que no se hayan respondido aquí, ¡por favor pregunta! Puedes abrir un issue o preguntar en [Discord](https://discordcom/invite/VnYRvBfgA6) ### ¿Qué es “code push”? Code push, también conocido como “actualizaciones en el aire” (OTA) es un servicio en la nube que permite a los desarrolladores de Capacitor desplegar actualizaciones a sus aplicaciones en producción. Capgo actualmente funciona en Android y iOS y eventualmente funcionará en todas las plataformas donde funcione Capacitor. “Code Push” hace referencia al nombre de una función de despliegue utilizada por la comunidad de React Native de [Microsoft](https://appcenterms/) y [Expo](https://expodev/), ninguna de las cuales soporta Capacitor. ### ¿Cuál es la diferencia entre un bundle y un release? Usamos el término “release” para referirnos a la preparación de un binario para las tiendas de aplicaciones. Para poder generar un bundle posteriormente, Capgo necesita conocer el binario exacto que se envió a las tiendas. Usamos el término “bundle” para referirnos a un parche que puede aplicarse a un release para actualizarlo con nuevo código. El comando `npx @capgo/cli app update` se usa para generar un bundle desde tu código local nuevo que luego se envía a tus usuarios. ### ¿Cuál es la hoja de ruta? Nuestros tableros de proyecto son públicos y se encuentran en: [https://github.com/orgs/Cap-go/projects](https://github.com/orgs/Cap-go/projects/) Nuestro equipo también opera públicamente, así que puedes ver en qué estamos trabajando en cualquier momento. Estaremos encantados de responder cualquier pregunta que tengas sobre nuestra hoja de ruta o prioridades a través de issues de Github o [Discord](https://discordcom/invite/VnYRvBfgA6). ### ¿Puedo usar Capgo con mi equipo? ¡Sí! Todos los planes soportan desarrolladores ilimitados. Solo limitamos las métricas de la aplicación (MAU, almacenamiento y ancho de banda) para cada organización. Consulta [Teams](https://capgo.app/pricing/) para más información. ### ¿Capgo almacena mi código fuente? No. Los servidores de Capgo nunca ven tu código fuente. Cuando ejecutas `npx @capgo/cli app update`, la herramienta `npx @capgo/cli` solo sube el mismo código compilado que envías a las tiendas de aplicaciones. Si deseas seguridad adicional, puedes usar cifrado de Extremo a Extremo para cifrar tu bundle antes de subirlo a los servidores de Capgo. Consulta también nuestra política de privacidad: [https://capgo.app/privacy](https://capgo.app/privacy/) ### ¿Puedo usar Capgo desde mi sistema CI? Sí. Capgo está diseñado para ser usado desde sistemas CI. Hemos publicado una guía para [Android y Github Actions](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) y [IOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/), y para [Gitlab](https://capgo.app/blog/setup-ci-and-cd-gitlab/), otros sistemas CI deberían ser similares. No dudes en contactarnos a través de issues de GitHub o Discord si encuentras algún problema. ### ¿Cómo se relaciona esto con Firebase Remote Config o Launch Darkly? Code push permite agregar nuevo código / reemplazar código en el dispositivo. Firebase Remote Config y Launch Darkly son sistemas de configuración. Te permiten cambiar la configuración de tu aplicación sin tener que enviar una nueva versión. No están diseñados para reemplazar código. ### ¿Qué tamaño de huella de dependencias agrega esto? No lo he medido recientemente, pero espero que la biblioteca de code push agregue menos de un megabyte a las aplicaciones Capacitor. Conocemos formas de hacerlo más pequeño cuando eso se convierta en una prioridad. Si el tamaño es un bloqueador para ti, ¡háganoslo saber! ### ¿Funciona code push con aplicaciones grandes? Sí. No hay límite en el tamaño de la aplicación que puede actualizarse con code push. Como se menciona [abajo](https://capgo.app/docs/faq/#what-types-of-changes-does-capgo-code-push-support), Capgo puede cambiar cualquier código JS en tu aplicación sin importar el tamaño. Nota: Un tamaño mayor hace más difícil que los usuarios descarguen actualizaciones. Recomendamos mantener tu aplicación lo más pequeña posible. ### ¿Para qué puedo usar Capgo code push? Hemos visto varios usos, incluyendo: * Correcciones de emergencia para aplicaciones en producción * Envío de correcciones de errores a usuarios en versiones antiguas de tu aplicación * Envío constante (por ejemplo, cada hora) Ten en cuenta que la mayoría de las tiendas de aplicaciones prohíben enviar código que cambie el comportamiento de la aplicación de manera significativa. Consulta [abajo](https://capgo.app/docs/faq/#how-does-this-relate-to-the-appplay-store-review-process-or-policies) para más información. ### ¿Qué cuenta como un “MAU” para Capgo? Un MAU es un “Usuario Activo Mensual”. Contamos un MAU como cualquier dispositivo que haya contactado con nuestros servidores en los últimos 30 días. No contamos dispositivos que no hayan contactado con nuestros servidores en los últimos 30 días. Cada vez que un dispositivo instala tu aplicación nuevamente, se cuenta un nuevo MAU, esto sucede debido a las limitaciones de privacidad de la App Store. No podemos rastrear el mismo dispositivo si el usuario reinstala la aplicación. Durante el desarrollo, cada vez que reinstales la aplicación, se cuenta un nuevo MAU. Lo mismo para las descargas de testflight o cambio de canal en Android. Actualizar la aplicación no crea un nuevo ID de Dispositivo. > Recomendamos después de la primera configuración, deshabilitar los dispositivos de desarrollo y emuladores para reducir la cantidad de dispositivos duplicados. ### ¿Para qué no podemos usar Capgo code push? Como se mencionó arriba, Capgo no debe usarse para violar las políticas de las tiendas de aplicaciones. Consulta [abajo](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines) para más información. Además, Capgo no soporta cambiar código nativo (por ejemplo, Java/Kotlin en Android u Objective-C/Swift en iOS). La herramienta te advertirá durante un intento de actualización si has cambiado código nativo. ### ¿Capgo envía a las tiendas por mí? Actualmente Capgo no soporta el envío a las tiendas de aplicaciones en tu nombre. Tenemos planes de agregar esto en el futuro, pero por ahora necesitarás continuar usando tus procesos existentes para enviar a las tiendas de aplicaciones. Puedes usar nuestra [guía CI para Android](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) para automatizar este proceso y [guía CI para iOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) ### ¿Qué almacena Capgo en el disco y dónde? El actualizador de Capgo (incluido en tu aplicación cuando la compilas) almacena en caché el último bundle descargado en el único directorio que Capacitor permite cargar código. En Android, esto se encuentra en `/data/user/0/comexampleapp/code_cache/capgo_updater` aunque la base de esa ruta es proporcionada por el sistema Android y puede cambiar dinámicamente en tiempo de ejecución. En dispositivos iOS, los datos se almacenan en `Library/Application Support/capgo`. Las herramientas de línea de comandos de Capgo (por ejemplo`npx @capgo/cli app update`) se instalan en el disco en las cachés de npm, tus inicios de sesión se almacenan en el directorio home en `~/capgo` ### ¿Cómo se relaciona esto con Capacitor Hot Reload? El Hot reload de Capacitor es una función solo para desarrollo. Code push es para producción. Hot reload es una función de Capacitor que permite cambiar código en el dispositivo durante el desarrollo. Requiere construir la aplicación Capacitor con un proxy para conectarse a tu máquina local. Code push es una función que permite cambiar código en el dispositivo en producción. Usaremos diferentes técnicas para hacer esto posible dependiendo de la plataforma. ### ¿Qué tipos de cambios soporta el code push de Capgo? Capgo puede cambiar cualquier código JS en tu aplicación. Esto incluye código de la aplicación y código generado. También puedes actualizar dependencias en `package.json` siempre que no requieran cambios de código nativo. No tenemos planes de soportar cambios de código nativo (por ejemplo Java/Kotlin en Android u Objective-C/Swift en iOS), y la herramienta te advertirá si detecta que has cambiado código nativo ya que no se incluirá en el paquete. ### ¿Soporta Web? Code push no es necesario para web ya que la web ya funciona de esta manera. Cuando un usuario abre una aplicación web, descarga la última versión del servidor si es necesario. Si tienes un caso de uso para code push con web, ¡nos encantaría saberlo! ### ¿Funcionará en iOS, Android, Mac, Windows, Linux, etc? Sí. Hasta ahora nos hemos centrado en el soporte de Android e iOS, pero code push eventualmente funcionará en todas partes donde funcione Capacitor. Primero nos estamos asegurando de construir toda la infraestructura necesaria para proporcionar code push de manera confiable y segura antes de expandirnos a más plataformas. ### ¿Qué versiones de SO soporta Capgo? Capgo soporta las mismas versiones de Android que Capacitor. Capacitor actualmente soporta Android API nivel 22+ y iOS 13.0+: [https://capacitorjs.com/docs/main/reference/support-policy](https://capacitorjs.com/docs/main/reference/support-policy/) ### ¿Qué versiones de Capacitor soporta Capgo? Capgo actualmente solo soporta versiones estables recientes de Capacitor. Podríamos soportar versiones más antiguas de Capacitor también, simplemente no hemos construido la infraestructura necesaria para mantenerlo a lo largo del tiempo. Tenemos la intención de soportar más versiones de Capacitor en el futuro, incluyendo cualquier versión para nuestros clientes empresariales [https://github.com/Cap-go/capgo/issues/1100](https://github.com/Cap-go/capgo/issues/1100/) Capgo sigue las versiones estables y generalmente se actualiza dentro de las pocas horas de cualquier lanzamiento estable. Nuestro sistema para hacer estas actualizaciones está automatizado y toma unos minutos para ejecutarse. Luego hacemos un paso de verificación manual adicional antes de publicar en nuestros servidores. ### ¿Cómo se relaciona esto con el proceso de revisión o políticas de App/Play Store? Los desarrolladores están sujetos a sus acuerdos con los proveedores de las tiendas cuando eligen usar esas tiendas. Code push está diseñado para permitir a los desarrolladores actualizar sus aplicaciones y aún cumplir con las políticas de las tiendas en iOS y Android. Similar a la variedad de productos comerciales disponibles para hacerlo con React Native (por ejemplo [Microsoft](https://appcenter.ms/), [Expo](https://expo.dev/)) Microsoft también publica una guía sobre cómo su solución cumple con las tiendas de aplicaciones: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) Code push es una técnica ampliamente utilizada en las tiendas de aplicaciones. Todas las aplicaciones grandes que conozco usan code push. La política principal a tener en cuenta es no cambiar el comportamiento de la aplicación de manera significativa. Por favor, consulta [más abajo](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines) para más información. ### ¿Cumple Capgo con las directrices de Play Store? Sí. La Play Store ofrece dos restricciones relacionadas con las herramientas de actualización: 1. Las actualizaciones deben usar un intérprete o máquina virtual (Capgo usa la Máquina Virtual de Dart) [https://support.google.com/googleplay/android-developer/answer/9888379?hl=en](https://support.google.com/googleplay/android-developer/answer/9888379/?hl=en) ```plaintext Una aplicación distribuida a través de Google Play no puede modificarse, reemplazarse o actualizarse
usando cualquier método que no sea el mecanismo de actualización de Google Play. Del mismo modo, una aplicación
no puede descargar código ejecutable (como archivos dex, JAR, .so) de una
fuente que no sea Google Play. *Esta restricción no se aplica al código
que se ejecuta en una máquina virtual o un intérprete* donde cualquiera proporcione
acceso indirecto a las APIs de Android (como JavaScript en una webview o
navegador)

Las aplicaciones o código de terceros, como SDKs, con lenguajes interpretados (JavaScript,
Python, Lua, etc.) cargados en tiempo de ejecución (por ejemplo, no empaquetados con la
aplicación) no deben permitir posibles violaciones de las políticas de Google Play
``` 2. Los cambios en la aplicación no deben ser engañosos (por ejemplo, cambiar el propósito de la aplicación mediante actualización) [https://support.google.com/googleplay/android-developer/answer/9888077](https://support.google.com/googleplay/android-developer/answer/9888077/) Por favor, sé claro con tus usuarios sobre lo que estás proporcionando con tu aplicación y no violes sus expectativas con cambios significativos de comportamiento a través del uso de Capgo. Capgo está diseñado para ser compatible con las directrices de Play Store. Sin embargo, Capgo es una herramienta y, como cualquier herramienta, puede ser mal utilizada. El abuso deliberado de Capgo para violar las directrices de Play Store está en violación de los [Términos de Servicio](https://capgo.app/tos/) de Capgo y puede resultar en la terminación de tu cuenta. Finalmente, los servicios de code push son ampliamente utilizados en la industria (todas las aplicaciones grandes que conozco los usan) y hay múltiples otros servicios de code push disponibles públicamente (por ejemplo expo.dev & appcenter.ms). Este es un camino bien recorrido. Microsoft también publica una guía sobre cómo su biblioteca “codepush” de react native cumple con las tiendas de aplicaciones: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### ¿Cumple Capgo con las directrices de App Store? Sí. Similar a la Play Store, la App Store ofrece tanto restricciones técnicas como políticas. ```plaintext 3.2.2
el código interpretado puede descargarse en una Aplicación, pero solo mientras que
dicho código:
(a) no cambie el propósito principal de la Aplicación proporcionando
características o funcionalidades que sean inconsistentes con el propósito
previsto y anunciado de la Aplicación enviada a la App Store,
(b) no cree una tienda o punto de venta para otro código o aplicaciones, y
(c) no eluda la firma, el sandbox u otras características de seguridad del SO
Capgo utiliza un intérprete personalizado de Dart para cumplir con la restricción de solo intérprete para actualizaciones en iOS. Mientras tu aplicación no participe en comportamientos engañosos a través de actualizaciones (por ejemplo, cambiar el propósito de la aplicación mediante actualización), actualizar a través de Capgo (o cualquier otra solución de código push) es una práctica estándar de la industria y cumple con las pautas de la App Store. El abuso deliberado de Capgo para violar las pautas de la App Store está en violación de los [Términos de Servicio](https://capgo.app/tos/) de Capgo y puede resultar en la terminación de tu cuenta. Microsoft también publica una guía sobre cómo su biblioteca "codepush" de react native cumple con las tiendas de aplicaciones: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### ¿Puedo usar Capgo en mi país?[](https://capgo.app/docs/faq/#can-i-use-capgo-in-my-country "Direct link to Can I use Capgo in my country?") No hemos intentado restringir el acceso a Capgo desde ningún país. Reconocemos que algunos países tienen restricciones sobre qué URLs se pueden acceder desde dentro del país. Capgo actualmente utiliza Cloudflare Cloud para el alojamiento, incluyendo R2 Storage y Cloudflare workers. Las siguientes URLs son utilizadas por Capgo: - [https://apicapgo.app](https://apicapgo.app/) -- utilizado por las herramientas de línea de comandos `npx @capgo/cli` para interactuar con los servidores de Capgo, así como el actualizador de Capgo en los dispositivos de los usuarios para buscar actualizaciones - [https://*r2cloudflarestoragecom](https://*r2cloudflarestoragecom/) -- utilizado por la herramienta de línea de comandos `npx @capgo/cli` para subir y descargar paquetes Si todas esas URLs son accesibles desde tu país, entonces Capgo debería funcionar. Si tu región requiere bloquear el acceso a cualquiera de esas URLs, por favor háganoslo saber y podemos trabajar contigo para encontrar una solución. Los servidores proxy son una opción. ### ¿Puedo auto-alojar Capgo?[](https://capgo.app/docs/faq/#can-i-self-host-capgo "Direct link to Can I self-host Capgo?") Sí, puedes auto-alojar Capgo. La guía aún no está escrita, pero el código es de código abierto y está disponible en [https://github.com/cap-go/capgo](https://github.com/cap-go/capgo/) ### ¿El code push requiere internet para funcionar?[](https://capgo.app/docs/faq/#does-code-push-require-the-internet-to-work "Direct link to Does code push require the internet to work?") Sí. Se podría imaginar ejecutar un servidor para distribuir las actualizaciones separado de internet general, pero se requiere alguna forma de conectividad de red para transportar actualizaciones a los dispositivos. ### ¿Cómo afecta la falta de conectividad de red a Capgo?[](https://capgo.app/docs/faq/#how-is-capgo-affected-by-lack-of-network-connectivity "Direct link to How is Capgo affected by lack of network connectivity?") El actualizador de Capgo (incluido en tu aplicación cuando construyes tu app con Capgo) está diseñado para ser resiliente a problemas de conectividad de red. En el comportamiento de actualización predeterminado, cuando la aplicación se inicia, alerta al actualizador de Capgo, que genera un hilo separado para hacer una solicitud de red a los servidores de Capgo y solicitar una actualización. Intencionalmente usamos un hilo separado para evitar afectar o bloquear cualquier otra cosa que la aplicación pudiera estar haciendo. Si la solicitud de red falla o se agota el tiempo de espera, el actualizador simplemente intentará verificar nuevamente la próxima vez que se inicie la aplicación. Las herramientas de línea de comandos de Capgo (por ejemplo, `npx @capgo/cli app update`) requieren conectividad de red para funcionar. Si estás usando Capgo para distribuir tu aplicación, debes asegurarte de que tu sistema CI tenga conectividad de red. ### ¿Qué sucede si un usuario no actualiza durante mucho tiempo y se pierde una actualización?[](https://capgo.app/docs/faq/#what-happens-if-a-user-doesnt-update-for-a-long-time-and-misses-an-update "Direct link to What happens if a user doesn't update for a long time and misses an update?") Nuestra implementación siempre envía una actualización específicamente adaptada para el dispositivo que la solicita, actualizando siempre al solicitante a la última versión disponible. Por lo tanto, si un usuario no actualiza durante un tiempo, se "perderá" las actualizaciones intermedias. El servidor de actualización podría modificarse para admitir responder con la siguiente versión incremental o la última versión, dependiendo de las necesidades de tu aplicación. Por favor, háznos saber si los comportamientos de actualización alternativos son importantes para ti. ### ¿Cómo se relaciona Capgo con Capacitor?[](https://capgo.app/docs/faq/#how-does-capgo-relate-to-capacitor "Direct link to How does Capgo relate to Capacitor?") Capgo es un plugin para Capacitor que agrega code push. Capgo no es un reemplazo para Capacitor. Puedes continuar usando las herramientas de Capacitor que ya conoces y te gustan. Seguimos la última versión estable de Capacitor y actualizamos nuestro plugin de code push para que funcione con ella. ### ¿Cuándo ocurren las actualizaciones?[](https://capgo.app/docs/faq/#when-do-updates-happen "Direct link to When do updates happen?") Por defecto, el actualizador de Capgo busca actualizaciones al iniciar la aplicación. Se ejecuta en un hilo en segundo plano y no bloquea el hilo de la UI. Cualquier actualización se instalará mientras el usuario está usando la aplicación y se aplicará la próxima vez que se reinicie la aplicación. También es posible ejecutar el actualizador de Capgo manualmente usando [package:capgo\_code\_push](https://pubdev/packages/capgo_code_push/), a través del cual es posible activar actualizaciones en cualquier momento, incluso mediante una notificación push. El actualizador de Capgo está diseñado de tal manera que cuando la red no está disponible, o el servidor está caído o no es accesible, la aplicación continuará funcionando normalmente. Si alguna vez decides eliminar una actualización de nuestros servidores, todos tus clientes continuarán funcionando normalmente. Hemos agregado la capacidad de revertir parches. Lo más simple es simplemente adjuntar un paquete anterior a tu canal para deshacer. ### ¿Necesito mantener mi app\_id en secreto?[](https://capgo.app/docs/faq/#do-i-need-to-keep-my-app_id-secret "Direct link to Do I need to keep my app_id secret?") No. El `app_id` está incluido en tu aplicación y es seguro que sea público. Puedes registrarlo en el control de versiones (incluso públicamente) y no preocuparte de que alguien más lo acceda. Alguien que tenga tu `app_id` puede obtener la última versión de tu aplicación de los servidores de Capgo, pero no puede enviar actualizaciones a tu aplicación ni acceder a ningún otro aspecto de tu cuenta de Capgo. ### ¿Qué información se envía a los servidores de Capgo?[](https://capgo.app/docs/faq/#what-information-is-sent-to-capgo-servers "Direct link to What information is sent to Capgo servers?") Aunque Capgo se conecta a la red, no envía ninguna información personalmente identificable. Incluir Capgo no debería afectar tus declaraciones para la Play Store o App Store. Las solicitudes enviadas desde la aplicación a los servidores de Capgo incluyen: - app\_id (especificado en `capacitorconfigjson`) - channel (opcional en `capacitorconfigjson`) - release\_version (versionName de AndroidManifestxml o CFBundleShortVersionString de Infoplist o `capacitorconfigjson` si está configurado en [`CapacitorUpdaterversion`](/docs/plugin/settings/#version)) - version\_number (generado como parte de `npx @capgo/cli app update`) - os_version (por ejemplo '1121') - platform (por ejemplo 'android', necesario para enviar el parche correcto) Eso es todo. El código para esto está en `updater/library/src/networkrs` - device\_id (generado en el dispositivo en la primera ejecución, utilizado para eliminar duplicados de instalaciones por dispositivo y permitirnos cobrar según los usuarios instalados)usuarios activos mensuales), en lugar de parches totales o instalaciones totales de parches) - custom_id (opcional, establecido en tiempo de ejecución por el desarrollador, usado para vincular un dispositivo a un usuario en tu sistema) ### ¿Qué plataformas soporta Capgo? Actualmente, Capgo soporta iOS y Android. Ambos están listos para producción. El uso de Capgo para iOS o Android puede ser decisiones independientes. Puedes configurar en tu canal para distribuir a Android y una ipa construida para la App Store o viceversa. Capgo puede (relativamente fácil) ser adaptado para soportar escritorio o dispositivos embebidos. Si estos son importantes para ti, háganoslo saber. ### ¿Cómo interactúa Capgo con Play Testing Tracks o Apple TestFlight? Cada una de las tiendas de aplicaciones tiene mecanismos separados para distribuir aplicaciones a grupos limitados de usuarios (por ejemplo, "pruebas internas", "beta cerrada", etc.). Todos estos son mecanismos para segmentar a tus usuarios en grupos y distribuir versiones específicas de tus aplicaciones a cada uno. Desafortunadamente, no todos estos mecanismos permiten a terceros detectar cuándo las aplicaciones están instaladas en alguna Test Track específica o vía TestFlight. Por lo tanto, no tenemos visibilidad confiable sobre la composición de estos grupos, y no podemos controlar de manera confiable el acceso a los parches de Capgo basados en estos grupos [https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play](https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play/) [https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i](https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i/) Si deseas segmentar la disponibilidad del paquete Capgo, hay 4 opciones potenciales: 1. Usar canales separados para cada grupo. Este es el enfoque más directo, pero requiere que administres múltiples canales. Es posible que ya tengas canales de desarrollo y producción con diferente disponibilidad. Así puedes actualizar tus canales de desarrollo, verificarlos y luego actualizar separadamente tus canales de producción. Recomendamos usar ramas / etiquetas en tu control de versiones para ayudar a mantener un registro de las fuentes asociadas con cada versión. 2. Rastrear tu propio conjunto de usuarios inscritos, deshabilitar actualizaciones automáticas y activar actualizaciones solo para ciertos usuarios a través de package:capgo_code_push. Esto funciona hoy, pero requiere que administres tu propia lista de inscripción. 3. Capgo permite crear su propio mecanismo de inscripción por dispositivo (similar a Test Tracks o TestFlight, solo que agnóstico a la plataforma). Esto permite que tu equipo de QA opte por recibir paquetes antes de que sean promovidos al público general. 4. Capgo tiene despliegues basados en porcentajes. Esto no te permite elegir a qué dispositivos enviar, pero puede ayudarte a desplegar incrementalmente y revertir ante cualquier problema. ## Facturación ### ¿Cómo actualizo o bajo de categoría mi plan? Puedes actualizar o bajar de categoría tu plan en cualquier momento en tu panel de control: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### ¿Cuándo se reinicia mi período de facturación? Los períodos de facturación se reinician automáticamente cada mes en el mes que te suscribiste por primera vez a Capgo. Por ejemplo, si te suscribiste el día 15 del mes, tu período de facturación se reiniciará el 15 de cada mes. ### ¿Cómo cancelo mi suscripción? Puedes cancelar tu suscripción en cualquier momento en tu panel de control: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### ¿Puedo pagar por un año por adelantado? Sí, puedes hacerlo en cualquier momento en tu panel de control: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Estadísticas y análisis Las estadísticas en tu panel de control se actualizan cada medianoche UTC. Las estadísticas se calculan basándose en el número de [MAU](https://capgo.app/docs/faq/#what-is-the-difference-between-a-bundle-and-a-release) que se han instalado en tus dispositivos. # Cómo se genera el ID del dispositivo El ID del dispositivo se genera en el dispositivo en la primera ejecución, y se usa para eliminar duplicados de instalaciones por dispositivo y permitirnos cobrar basándonos en usuarios instalados (por ejemplo, usuarios activos mensuales), en lugar de parches totales o instalaciones totales de parches. MAU es una mejor solución que el número de instalaciones para fijar el precio de Capgo, ya que es más preciso y refleja el costo real de Capgo por dispositivo. Por razones de privacidad, no podemos rastrear el mismo dispositivo si el usuario reinstala la aplicación. Las reglas de privacidad son impuestas por Apple y Google, y no por Capgo. El ID del dispositivo no aparecerá en tu lista de dispositivos hasta que reciban su primer parche instalado. # ¿Por qué mi número de dispositivos es diferente a mi MAU? Actualmente, la lista de dispositivos no se actualiza tan frecuentemente como el MAU. La lista de dispositivos se actualiza solo cuando un dispositivo instala una actualización. Mientras que el MAU se actualiza en cada inicio de la aplicación. Esta es una limitación actual de la plataforma. Nuestra plataforma de Analytics no soporta actualizaciones en bruto por lo que usamos una base de datos convencional para la lista de Dispositivos. Para limitar el número de consultas a la base de datos, solo actualizamos las filas en la actualización de la aplicación. Esta limitación será eliminada en el futuro. # ¿Cómo tener diferentes actualizaciones por plataforma? Puedes crear un canal para cada plataforma y deshabilitar las actualizaciones específicas de plataforma en cada canal. En el canal ios deshabilita las actualizaciones de android y en el canal android deshabilita las actualizaciones de ios. Luego sube un paquete a cada canal para tener diferentes actualizaciones para cada plataforma. Si necesitas tener la misma actualización para ambas plataformas, puedes vincular un paquete a múltiples canales. No es necesario duplicar el paquete. ``` # Tech Support für Capgo > Cómo obtener soporte técnico para capgo ## Soporte por Discord Capgo tiene un [servidor de Discord](https://discordcom/invite/VnYRvBfgA6) oficial. Obtener soporte técnico allí es probablemente una de las formas más rápidas de obtener una respuesta. Aquí hay un curso rápido: 1. * ve al canal `questions` ![Ask on discord](/discord-questions.webp) 2. * crea tu hilo ![Create a question on discord](/discord-newquestion.webp) 3. * Describe tu problema y selecciona las etiquetas relevantes ![Create a post on discord](/discord-new-post.webp) 4. * Comparte tu ID de cuenta segura (opcional) Esto permitirá al personal de Capgo revisar tu cuenta. Compartir este ID es seguro, ya que fue diseñado para ser compartido públicamente. Para compartirlo, por favor ve a la [configuración de Capgo](https://web.capgo.app/dashboard/settings/account/). Allí, haz clic en `copy account id` ![Share your id without leaking your info](/share-secure-id.webp) Esto copiará el ID seguro de la cuenta al portapapeles. Por favor, incluye eso en tu publicación de Discord. ## Soporte por correo electrónico Esta es la forma más lenta de obtener soporte. Por favor, utiliza primero el servidor de Discord. Si necesitas contactarnos por correo electrónico, por favor envía un correo a # Ajouter une App > Agregar una aplicación a tu cuenta de Capgo e instalar plugins en la aplicación ## Introducción a Capgo [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## Las actualizaciones en vivo están a 3 pasos ### Configuración guiada 1. Crea tu cuenta en ![captura de pantalla del registro](/signup.webp "captura de pantalla del registro") 2. Usa los comandos de inicialización para comenzar ```bash npx @capgo/cli@latest init [APIKEY] ``` Se te presentará una serie de preguntas. Proporciona las respuestas necesarias para completar la configuración automatizada Tip Siguiendo estos pasos, estarás listo en poco tiempo. Si necesitas ayuda adicional durante el proceso, nuestro equipo de soporte está [aquí para ayudarte](https://support.capgo.app) ¡Feliz incorporación! 3. Despliega una actualización en vivo [Despliega una actualización en vivo ](/docs/getting-started/deploy/)Aprende cómo desplegar una actualización en vivo en tu aplicación ### Configuración manual En caso de que el comando init no funcione para ti, puedes agregar una aplicación manualmente 1. Conecta el CLI a tu cuenta: ```bash npx @capgo/cli@latest login [APIKEY] ``` 2. Agrega la aplicación a tu cuenta con este comando: ```bash npx @capgo/cli@latest app add [APP_NAME] ``` 3. Instala el plugin en tu aplicación: ```json { "plugins": { CapacitorUpdater: { "appId": "Your appID", "autoUpdate": true, "version": "1.0.0" } } } ``` 4. Llama al método init lo antes posible en tu aplicación: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; CapacitorUpdater.notifyAppReady(); ``` 5. Despliega una actualización en vivo [Despliega una actualización en vivo ](/docs/getting-started/deploy/)Aprende cómo desplegar una actualización en vivo en tu aplicación # Integración de CI/CD La integración de Capgo en tu pipeline de CI/CD te permite automatizar completamente el proceso de construcción y despliegue de actualizaciones para tu aplicación. Al aprovechar la CLI de Capgo y semantic-release, puedes asegurar despliegues consistentes y confiables, y habilitar iteraciones rápidas. ## Beneficios de la Integración CI/CD * **Automatización**: Sin más pasos manuales o margen para errores humanos. Todo tu proceso de construcción, pruebas y despliegue puede ser automatizado de principio a fin. * **Consistencia**: Cada despliegue sigue el mismo conjunto de pasos, asegurando un proceso predecible y repetible. Esto es especialmente valioso cuando tienes múltiples miembros del equipo contribuyendo código. * **Iteraciones más rápidas**: Con despliegues automatizados, puedes publicar actualizaciones con más frecuencia y con confianza. Sin más esperas por aprobaciones manuales de QA o lanzamientos. ## CLI de Capgo La CLI de Capgo es la clave para integrar Capgo en tu flujo de trabajo CI/CD. Proporciona comandos para subir nuevas versiones de paquetes, gestionar canales y más. El comando más importante para la integración CI/CD es `upload`: ```shell npx @capgo/cli@latest bundle upload --channel=Production --apikey YOUR_API_KEY ``` Este comando sube la construcción web actual al canal especificado. Normalmente ejecutarás esto como el último paso en tu pipeline CI/CD, después de que tu construcción web se haya completado exitosamente. ## Configurando Capgo en tu Pipeline CI/CD Aunque los pasos exactos variarán dependiendo de tu herramienta CI/CD elegida, el proceso general para integrar Capgo se ve así: 1. **Generar una clave API**: Inicia sesión en el panel de control de Capgo y crea una nueva clave API. Esta clave se usará para autenticar la CLI en tu entorno CI/CD. ¡Mantenla secreta y nunca la comprometas en tu repositorio! 2. **Configurar el comando `upload`**: Agrega un paso a tu configuración CI/CD que ejecute el comando `upload` con los argumentos apropiados: upload.yml ```yaml - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secrets.CAPGO_API_KEY }} ``` Reemplaza `Production` con el canal al que quieres desplegar, y `${{ secrets.CAPGO_API_KEY }}` con la variable de entorno que contiene tu clave API. 3. **Agregar el paso `upload` después de tu construcción web**: Asegúrate de que el paso `upload` venga después de que tu construcción web se haya completado exitosamente. Esto asegura que siempre estés desplegando tu código más reciente. Aquí hay un ejemplo de configuración para GitHub Actions: upload.yml ```yaml name: Deploy to Capgo on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v4 with: node-version: 18 - run: npm ci - run: npm run build - run: npm install -g @capgo/cli - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secrets.CAPGO_API_KEY }} ``` ## Integración con Semantic-release Semantic-release es una poderosa herramienta para automatizar la gestión de versiones y generar notas de lanzamiento. Al integrar semantic-release con Capgo, puedes incrementar automáticamente la versión de tu aplicación y generar registros de cambios con cada despliegue. Aquí hay un archivo de configuración `releaserc` de ejemplo para semantic-release: ```json { "branches": [ "main", { "name": "beta", "prerelease": true } ], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", [ "@semantic-release/exec", { "publishCmd": "npx @capgo/cli@latest bundle upload --channel=${nextRelease.channel} --apikey YOUR_API_KEY --partial" } ], [ "@semantic-release/git", { "assets": ["CHANGELOG.md", "package.json"], "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" } ] ] } ``` Esta configuración hace lo siguiente: 1. Analiza los mensajes de commit para determinar el siguiente número de versión, siguiendo la especificación de Conventional Commits 2. Genera notas de lanzamiento basadas en los commits desde el último lanzamiento 3. Actualiza el archivo `CHANGELOG.md` con las nuevas notas de lanzamiento 4. Ejecuta el comando `upload` de la CLI de Capgo, pasando el nuevo número de versión y usando la bandera `--partial` para actualizaciones diferenciales 5. Compromete el `CHANGELOG.md` actualizado, `package.json` y cualquier otro archivo cambiado de vuelta al repositorio Para usar semantic-release con Capgo, simplemente agrega un paso a tu configuración CI/CD que ejecute `npx semantic-release`. Asegúrate de que este paso venga después de tu construcción web y antes del paso `upload` de Capgo. ## Solución de Problemas Si encuentras problemas con tu integración CI/CD de Capgo, aquí hay algunas cosas que verificar: * **Clave API**: Asegúrate de que tu clave API sea válida y tenga los permisos necesarios. Si usas una variable de entorno, verifica que esté configurada correctamente. * **Versión de CLI**: Asegúrate de estar usando la última versión de la CLI de Capgo. Las versiones antiguas pueden tener problemas de compatibilidad o carecer de ciertas características. * **Artefactos de construcción**: Confirma que tu construcción web esté generando los archivos de salida esperados. La CLI de Capgo necesita una construcción web válida para crear un paquete. * **Conectividad de red**: Verifica que tu entorno CI/CD tenga acceso de red a los servidores de Capgo. Los problemas de firewall o proxy pueden a veces interferir con el comando `upload`. Si aún tienes problemas, contacta al soporte de Capgo para asistencia. Pueden ayudar a solucionar cualquier problema con tu configuración específica. ## Conclusión Integrar Capgo en tu pipeline CI/CD y aprovechar semantic-release para la gestión de versiones puede agilizar enormemente tu flujo de trabajo de desarrollo. Al automatizar tus despliegues y versionado, puedes publicar actualizaciones más rápido y con más confianza. La CLI de Capgo y semantic-release proporcionan una poderosa combinación para lograr lanzamientos completamente automatizados de principio a fin. Con un poco de configuración, puedes tener un proceso de despliegue robusto y confiable que te permite enfocarte en construir grandes características en lugar de preocuparte por pasos de lanzamiento manuales. Para más detalles sobre los comandos y opciones de la CLI de Capgo, consulta la [referencia CLI](/docs/cli/overview). Y para una inmersión más profunda en la configuración de semantic-release, consulta la [documentación de semantic-release](https://github.com/semantic-release/semantic-release). ¡Feliz despliegue! # Implementar una Actualización en Vivo Utilice la función de Actualizaciones en Vivo de Capgo para actualizar la interfaz de usuario y la lógica de negocio de su aplicación de forma remota y en tiempo real. Envíe actualizaciones del paquete JS directamente a sus usuarios sin pasar por la tienda de aplicaciones para corregir errores y lanzar nuevas funciones al instante. Esta guía asume que ha completado el [Inicio Rápido de Capgo](/docs/getting-started/quickstart) y ya ha: 1. Instalado el SDK `@capgo/capacitor-updater` en su aplicación Capacitor 2. Configurado su ID de aplicación y canal de actualización en `capacitor.config.ts` 3. Añadido en su código el método `CapacitorUpdater.notifyAppReady()` Si aún no ha completado estos pasos, por favor regrese y complete primero el inicio rápido [Añadir una aplicación ](/docs/getting-started/add-an-app/)Añada una aplicación a su cuenta Capgo e instale el plugin en su aplicación ## Subiendo un Paquete Con el SDK de Capgo instalado y configurado, está listo para subir su primer paquete de actualización en vivo: 1. Compile sus activos web: ```shell npm run build ``` 2. Suba el paquete a Capgo: * Consola ```shell npx @capgo/cli@latest bundle upload --channel=Production ``` * Github Actions github/workflows/build\_and\_deploy.yml ```yml name: Build source code and send to Capgo concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true on: push: branches: - main jobs: deploy_to_capgo: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v5 - uses: actions/setup-node@v4 with: node-version: 18 - name: Install dependencies run: npm install - name: Build run: npm run build - name: Deploy to Capgo run: bunx @capgo/cli@latest bundle upload -a ${{ secrets.CAPGO_TOKEN }} --channel ${{ env.CHANNEL }} env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} ``` * Gitlab gitlab-ci.yml ```yml stages: - build build: stage: build image: node:18 cache: - key: files: - package-lock.json paths: - node_modules/ script: - npm install - npm run build - npx @capgo/cli@latest bundle upload -a $CAPGO_TOKEN --channel $CAPGO_CHANNEL artifacts: paths: - node_modules/ - dist/ only: - master ``` Esto subirá una nueva versión del paquete al canal especificado en el comando ### Solución de problemas de carga Si su carga falla, verifique: * Su ID de aplicación en `capacitor.config.ts` coincide con su aplicación en el panel de Capgo * Está ejecutando el comando de carga desde la raíz de su proyecto Capacitor * Sus activos web están compilados y actualizados Si aún tiene problemas, vaya a la sección de [Solución de problemas](/docs/getting-started/troubleshooting/) ## Recibiendo una Actualización en un Dispositivo Una vez que su paquete esté subido, puede probar la actualización en vivo en un dispositivo: 1. Sincronice su aplicación con el dispositivo: ```shell npx cap sync ios ``` 2. Abra otra terminal y ejecute el siguiente comando para verificar el estado de la actualización: ```shell npx @capgo/cli@latest app debug ``` 3. Ejecute su aplicación localmente: ```shell npx cap run ios ``` O abra el proyecto iOS/Android en Xcode/Android Studio y realice una ejecución nativa 4. Mantenga la aplicación abierta durante unos 30 segundos para permitir que la actualización se descargue en segundo plano 5. Los registros tardarán unos segundos en actualizarse y mostrar el estado de la actualización 6. Cierre y vuelva a abrir la aplicación. ¡Debería ver su actualización en vivo aplicada! Consulte el [Inicio Rápido de Capgo](/docs/getting-started/quickstart#receiving-a-live-update-on-a-device) para más detalles sobre cómo probar actualizaciones en vivo ## Siguientes Pasos ¡Felicitaciones por implementar su primera actualización en vivo con Capgo! 🎉 Para aprender más, revise el resto de la [documentación de Actualizaciones en Vivo de Capgo](/docs/live-updates). Algunos temas clave para revisar a continuación: * [Direccionamiento de Actualizaciones con Canales](/docs/live-updates/channels) * [Personalización del Comportamiento de Actualización](/docs/live-updates/update-behavior) * [Reversiones de Actualizaciones en Vivo](/docs/live-updates/rollbacks) # Descripción General El tutorial de inicio rápido te guiará a través de los conceptos clave de Capgo. Los conceptos que se explorarán incluyen: 1. Agregar una aplicación a tu cuenta de Capgo 2. Integrar Capgo con tu CI/CD 3. Activar la carga de paquetes en Capgo al enviar commits 4. Configurar y personalizar la publicación de paquetes de Capgo 5. Configurar tu aplicación para habilitar actualizaciones en vivo a través de Capgo 6. Implementar actualizaciones en vivo en tu aplicación desde Capgo Simplemente sigue la guía paso a paso, o navega directamente a la documentación del componente que te interese [ Comenzar el Tutorial](/docs/getting-started/add-an-app/) [¡Sigue el tutorial de inicio rápido y comienza a usar Capgo en poco tiempo!](/docs/getting-started/add-an-app/) [ Fácil de integrar](/docs/getting-started/deploy/) [Integra Capgo con tu CI/CD y activa cargas de paquetes en Capgo al enviar commits](/docs/getting-started/deploy/) [ Documentación de Actualización en Vivo](/docs/live-updates/) [Actualiza tu aplicación remotamente en tiempo real sin demoras de la tienda de aplicaciones](/docs/live-updates/) [ Solución de Problemas](/docs/getting-started/troubleshooting) [Problemas comunes y cómo resolverlos](/docs/getting-started/troubleshooting) Tip La función de actualización Over-the-Air (OTA) solo es aplicable para modificaciones realizadas en archivos HTML, CSS y JavaScript Si realizas cambios en el código nativo, como actualizaciones de plugins de Capacitor, es obligatorio volver a enviar la aplicación a la tienda de aplicaciones para su aprobación ## Únete a la Comunidad de Discord [¡Únete al Servidor de Discord de Capacitor-updater!](https://discordcom/invite/VnYRvBfgA6) ## Mantenimiento | Versión del plugin | Compatibilidad con Capacitor | Mantenimiento | | ------------------ | ---------------------------- | --------------------------------------------------------------------- | | v6\*\* | v6\*\* | ✅ | | v5\*\* | v5\*\* | Solo errores críticos | | v4\*\* | v4\*\* | ⚠️ Obsoleto | | v3\*\* | v3\*\* | ⚠️ Obsoleto | | > 7 | v4\*\* | ⚠️ Obsoleto, nuestro CI se volvió loco y aumentó demasiadas versiones | ## Cumplimiento de las Directrices de las Tiendas Google Play de Android y App Store de iOS tienen directrices correspondientes con reglas que debes conocer antes de integrar la solución Capacitor-updater en tu aplicación ### Google Play El tercer párrafo del tema [Abuso de Dispositivos y Red](https://supportgooglecom/googleplay/android-developer/answer/9888379/?hl=en) describe que está restringida la actualización del código fuente por cualquier método que no sea el mecanismo de actualización de Google Play. Pero esta restricción no se aplica a la actualización de paquetes javascript > Esta restricción no se aplica al código que se ejecuta en una máquina virtual y tiene acceso limitado a las API de Android (como JavaScript en un webview o navegador) Esto permite completamente Capacitor-updater ya que solo actualiza los paquetes JS y no actualizará código nativo ### App Store El párrafo **332**, desde 2015 en el [Acuerdo de Licencia del Programa de Desarrollador de Apple](https://developer.apple.com/programs/ios/information/) permite completamente realizar actualizaciones over-the-air de JavaScript y activos - y en su última versión (20170605) [descargable aquí](https://developer.apple.com/terms/) esta normativa es incluso más amplia: > El código interpretado puede descargarse en una Aplicación solo mientras dicho código: (a) no cambie el propósito principal de la Aplicación proporcionando características o funcionalidades que sean inconsistentes con el propósito previsto y anunciado de la Aplicación tal como se envió a la App Store, (b) no cree una tienda o punto de venta para otro código o aplicaciones, y (c) no eluda la firma, el sandbox u otras características de seguridad del SO Capacitor-updater te permite seguir estas reglas en total cumplimiento siempre que la actualización que envíes no se desvíe significativamente de la intención original de tu producto aprobada por la App Store Para mantener aún más el cumplimiento de las directrices de Apple, sugerimos que las aplicaciones distribuidas en la App Store no habiliten el escenario de `Actualización forzada`, ya que en las [Directrices de Revisión de la App Store](https://developer.apple.com/app-store/review/guidelines/) se establece que: > Las aplicaciones no deben forzar a los usuarios a calificar la aplicación, revisar la aplicación, descargar otras aplicaciones u otras acciones similares para acceder a la funcionalidad, contenido o uso de la aplicación Esto no es un problema para el comportamiento predeterminado de actualización en segundo plano, ya que no forzará al usuario a aplicar la nueva versión hasta la próxima vez que cierre la aplicación, pero al menos debes ser consciente de ese rol si decides mostrarlo ## Código abierto El plugin está bajo la Licencia LGPL-30 y el back-end está bajo la Licencia AGPL-30 > 💡 LGPL-30 significa que si alguien modifica el código del plugin, es obligatorio publicarlo, en código abierto con la misma licencia. Si usas el código sin modificación, eso no te concierne. Para más detalles, consulta el problema a continuación, revisa el enlace 👇 [¿Licenciamiento? ](https://github.com/Cap-go/capacitor-updater/issues/7) [Prueba GPTS Capgo para obtener ayuda en lugar de leer la documentación ](https://chatopenaicom/g/g-3dMwHbF2w-capgo-doc-gpt) > Puedes incluirlo en tu aplicación sin preocupaciones ## Notas Finales Si autohostas y encuentras útil esta herramienta, considera apoyar mi trabajo convirtiéndote en un [patrocinador de GitHub](https://github.com/sponsors/riderx/) Aposté por hacer código abierto todo el código que construí aquí en lugar de ponerlo detrás de un muro de pago. Al abrirlo en lugar de luchar y ocultarlo, creo que podemos hacer del mundo un lugar mejor Para hacer esto posible, es necesario que todos hagamos nuestra parte, incluyéndote a ti 🥹 Si Capgo cloud no satisface tus necesidades, puedes respaldar a un creador independiente [aquí](https://github.com/sponsors/riderx/) en tus propios términos ## Matemáticas Simples El precio del plan básico: $14\*12 = $168 al año Mientras que el promedio dev/hora = $60 Eso significa que 3 horas perdidas de tiempo de desarrollo en autohospedaje te permiten pagar un año completo, si gastas más de 3 horas estás perdiendo dinero ^^ # Resolución de problemas Aquí están algunos problemas comunes que puedes encontrar mientras usas Capgo y cómo resolverlos ### Fallos en la subida Si la subida de tu bundle falla, verifica: * Tu ID de app en `capacitorconfigts` coincide con tu app en el panel de Capgo * Estás ejecutando el comando de subida desde la raíz de tu proyecto Capacitor * Tus assets web están compilados y actualizados #### Opciones avanzadas de subida La CLI de Capgo proporciona algunas banderas adicionales para ayudar con problemas comunes de subida: * `--tus`: Usa el [protocolo de subida reanudable tus](https://tusio/) para subidas más confiables de bundles grandes o en conexiones de red deficientes. Si tu bundle es mayor a 10MB o tienes una conexión inestable, considera usar `--tus`: ```shell npx @capgo/cli@latest bundle upload --tus ``` * `--package-json` y `--node-modules`: Le indica a Capgo dónde encontrar tu `packagejson` raíz y `node_modules` si tu app usa una estructura no estándar como un monorepo o espacio de trabajo npm. Pasa la ruta al `packagejson` raíz y la ruta de `--node-modules`: ```shell npx @capgo/cli@latest bundle upload --package-json=path/to/packagejson --node-modules=path/to/node_modules ``` Capgo necesita esta información para empaquetar correctamente las dependencias de tu app Puedes combinar estas banderas con otras opciones como `--channel` según sea necesario. Consulta la [documentación de la CLI de Capgo](/docs/cli/overview/) para ver todos los detalles sobre las opciones de subida disponibles Si sigues teniendo problemas con las subidas, contacta al [soporte de Capgo](https://support.capgo.app) para más ayuda ### Depurando Actualizaciones Si estás encontrando problemas con las actualizaciones en vivo, el comando debug de Capgo es una herramienta útil para solucionar problemas. Para usarlo: 1. Ejecuta el siguiente comando en el directorio de tu proyecto: ```shell npx @capgo/cli@latest app debug ``` 2. Inicia tu app en un dispositivo o emulador y realiza la acción que debería activar una actualización (ej. reabrir la app después de subir un nuevo bundle) 3. Observa la salida del comando debug. Registrará información sobre el proceso de actualización, incluyendo: * Cuándo la app busca una actualización * Si se encuentra una actualización y qué versión es * Progreso de descarga e instalación de la actualización * Cualquier error que ocurra durante el proceso de actualización 4. Usa los registros de depuración para identificar dónde está ocurriendo el problema. Por ejemplo: * Si no se encuentra actualización, verifica que tu bundle se subió correctamente y que la app está configurada para usar el canal correcto * Si la actualización se descarga pero no se instala, asegúrate de haber llamado `CapacitorUpdater.notifyAppReady()` y que la app se cerró y reabrió completamente * Si ves un mensaje de error, busca ese error específico en la documentación de Capgo o contacta al soporte para obtener ayuda El comando debug es especialmente útil para identificar problemas con el proceso de descarga e instalación de actualizaciones. Si los registros muestran que se encontró la versión de actualización esperada pero no se aplicó finalmente, enfoca tu solución de problemas en los pasos posteriores a la descarga ### Depuración con Registros Nativos Además del comando debug de Capgo, los registros nativos en Android e iOS pueden proporcionar información valiosa para solucionar problemas, especialmente para problemas en el lado nativo del proceso de actualización #### Registros de Android Para acceder a los registros de Android: 1. Conecta tu dispositivo o inicia tu emulador 2. Abre Android Studio y selecciona “View > Tool Windows > Logcat” 3. En la ventana Logcat, filtra los registros solo para el proceso de tu app seleccionándolo del menú desplegable en la parte superior 4. Busca cualquier línea que incluya `Capgo` para encontrar los registros del SDK Alternativamente, puedes usar el comando `adb logcat` y grep para `Capgo` para filtrar los registros El SDK de Capgo registrará eventos clave durante el proceso de actualización, como: * Cuándo se inicia una verificación de actualización * Si se encuentra una actualización y qué versión es * Cuándo comienza y termina la descarga de la actualización * Cuándo se activa la instalación de la actualización * Cualquier error que ocurra durante los pasos de actualización nativos Los problemas comunes específicos de Android que podrías ver en los registros incluyen: * Problemas de conectividad de red que impiden la descarga de la actualización * Errores de permisos de archivo al guardar o leer el bundle de actualización * Espacio de almacenamiento insuficiente para el bundle de actualización * Fallo al reiniciar la app después de que se instala la actualización #### Registros de iOS Para acceder a los registros de iOS: 1. Conecta tu dispositivo o inicia tu simulador 2. Abre Xcode y ve a “Window > Devices and Simulators” 3. Selecciona tu dispositivo y haz clic en “Open Console” 4. En la salida de la consola, busca cualquier línea que incluya `Capgo` para encontrar los registros del SDK También puedes usar el comando `log stream` en la terminal y grep para `Capgo` para filtrar los registros Similar a Android, el SDK de Capgo registrará eventos clave del lado de iOS: * Inicio y resultado de la verificación de actualización * Inicio, progreso y finalización de la descarga * Activación y resultado de la instalación * Cualquier error durante el proceso de actualización nativo Los problemas específicos de iOS que puedes identificar en los registros incluyen: * Problemas con certificados SSL al descargar la actualización * Seguridad de transporte de la app bloqueando la descarga de actualización * Espacio de almacenamiento insuficiente para el bundle de actualización * Fallo al extraer o aplicar correctamente el bundle de actualización En ambas plataformas, los registros nativos proporcionan una vista de más bajo nivel del proceso de actualización, con más detalles sobre la implementación nativa. Son especialmente útiles para identificar problemas que ocurren fuera de la capa JavaScript de Capgo Cuando solucionas un problema complicado de actualización en vivo, es una buena idea capturar tanto los registros de depuración de Capgo como los registros nativos para tener una imagen completa de lo que está sucediendo. Los dos registros juntos te darán la mejor oportunidad de identificar y resolver el problema ### Actualizaciones que no se aplican Si has subido un bundle pero no ves los cambios en tu dispositivo: * Asegúrate de haber llamado `CapacitorUpdater.notifyAppReady()` en el código de tu app como se muestra en la [guía rápida](/docs/getting-started/quickstart) * Verifica que tu dispositivo esté conectado a internet y que los registros de depuración de Capgo muestren que la actualización se descargó * Intenta cerrar completamente y reabrir la app, ya que las actualizaciones solo se aplican en un inicio nuevo * Busca cualquier error en los registros nativos que pueda indicar un problema al aplicar la actualización Consulta la guía de [implementación de actualizaciones en vivo](/docs/getting-started/deploy) para más detalles sobre el proceso de actualización. Si sigues atascado, usa el comando `npx @capgo/cli@latest app debug` y los registros nativos para obtener más visibilidad de lo que está sucediendo ## Instalación del SDK Si tienes problemas instalando el SDK de Capgo, asegúrate de que: * Tu app está usando una versión compatible de Capacitor (4.0 o más nueva) * Has seguido los pasos de la [guía rápida](/docs/getting-started/quickstart) en orden, incluyendo sincronizar tu app después de instalar el SDK ## Integración CI/CD Para problemas con la activación de subidas de Capgo desde tu pipeline CI/CD: * Verifica que tu token de autenticación de Capgo esté configurado correctamente * Asegúrate de ejecutar el comando de subida después de que tus assets web estén compilados * Verifica que el comando de subida esté usando el nombre de canal correcto para tu entorno objetivo Consulta la documentación de [integración CI/CD](/docs/getting-started/cicd-integration) para más consejos de solución de problemas. También puedes usar el comando `npx @capgo/cli@latest app debug` para confirmar si tu app está recibiendo las actualizaciones activadas por CI/CD # Cara Melakukan > Cómo usar Capgo, tutoriales, consejos y trucos [Cómo funciona la versión en Capgo ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [Cómo lanzar una versión mayor en Capgo ](https://capgo.app/blog/how-to-release-major-version-in-capgo/)capgo.app [Cómo enviar una actualización específica a un usuario o grupo ](https://capgo.app/blog/how-to-send-specific-version-to-users/)capgo.app ## CI / CD [Construcción y lanzamiento automático con GitHub Actions ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [Gestionar construcciones de desarrollo y producción con GitHub Actions ](https://capgo.app/blog/automatic-build-and-release-with-github-actions/)capgo.app ## Contribuir [Contribuir al código abierto de Capgo ](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTINGmd)githubcom # Visión General Utiliza la función de Actualizaciones en Vivo de Capgo para actualizar los paquetes JavaScript de tu aplicación de forma remota y en tiempo real. Envía actualizaciones JS directamente a tus usuarios sin pasar por el proceso de revisión de la tienda de aplicaciones para corregir errores y lanzar nuevas funciones instantáneamente. Note Las Actualizaciones en Vivo están limitadas a cambios en el paquete JavaScript. Si necesitas actualizar código nativo, como agregar o eliminar un plugin o cambiar la configuración del proyecto nativo, necesitarás enviar una nueva compilación binaria nativa a las tiendas de aplicaciones. ## Cómo funcionan las Actualizaciones en Vivo El sistema de Actualización en Vivo de Capgo tiene dos componentes clave: 1. El SDK de Capgo, que instalas en tu aplicación. El SDK verifica las actualizaciones disponibles y las descarga en segundo plano. 2. Canales, que te permiten dirigir actualizaciones a grupos específicos de usuarios. Puedes usar canales para gestionar diferentes pistas de lanzamiento, como `Production`, `Staging` y `Dev`. Cuando subes un nuevo paquete JS a Capgo y lo asignas a un canal, el SDK de Capgo en las aplicaciones configuradas para ese canal detectará la actualización y la descargará. La próxima vez que la aplicación se reinicie, se cargará el nuevo paquete. ## Primeros Pasos Para comenzar a usar las Actualizaciones en Vivo, sigue estos pasos: 1. Completa el [Inicio Rápido de Capgo](/docs/getting-started/quickstart) para configurar tu aplicación en Capgo e instalar el SDK de Capgo 2. En el código de tu aplicación, llama a `CapacitorUpdaternotifyAppReady()` después de que tu aplicación haya terminado de inicializarse. Esto le indica al SDK de Capgo que tu aplicación está lista para recibir actualizaciones 3. Construye tu paquete JS y súbelo a Capgo: ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. Abre tu aplicación y espera a que se descargue la actualización. Puedes verificar el estado con: ```shell npx @capgo/cli@latest app debug ``` 5. Una vez que se descargue la actualización, cierra y vuelve a abrir tu aplicación para cargar el nuevo paquete Consulta la guía [Implementando Actualizaciones en Vivo](/docs/getting-started/deploy) para más detalles ## Siguientes Pasos [ Canales](/docs/live-updates/channels/) [Aprende cómo usar canales para gestionar diferentes pistas de lanzamiento y dirigir actualizaciones a usuarios específicos](/docs/live-updates/channels/) [ Reversiones](/docs/live-updates/rollbacks/) [Descubre cómo revertir a una versión anterior del paquete JS si una actualización causa problemas](/docs/live-updates/rollbacks/) [ Comportamiento de Actualización](/docs/live-updates/update-behavior/) [Personaliza cómo y cuándo se descargan y aplican las actualizaciones en tu aplicación](/docs/live-updates/update-behavior/) [ Actualizaciones Rápidas](/docs/live-updates/differentials/) [Aprende cómo usar actualizaciones rápidas para acelerar el proceso de actualización](/docs/live-updates/differentials/) # Canales Un canal de Actualización en Vivo apunta a una compilación específica del bundle JS de tu aplicación que se compartirá con cualquier dispositivo configurado para escuchar ese canal para actualizaciones. Cuando [instalas el SDK de Actualizaciones en Vivo de Capgo](/docs/getting-started/quickstart/) en tu aplicación, cualquier binario nativo configurado para ese canal verificará las actualizaciones disponibles cada vez que se inicie la aplicación. Puedes cambiar la compilación a la que apunta un canal en cualquier momento y también puedes revertir a compilaciones anteriores si es necesario. ## Configurando un Canal Cada aplicación viene con un canal predeterminado llamado “Production” que no se puede eliminar. Para añadir nuevos canales: 1. Ve a la sección “Channels” del panel de control de Capgo 2. Haz clic en el botón “New Channel” 3. Ingresa un nombre para el canal y haz clic en “Create” Los nombres de los canales pueden ser cualquier cosa que desees. Una estrategia común es hacer coincidir los canales con tus etapas de desarrollo, como: * `Development` - para probar actualizaciones en vivo en dispositivos locales o emuladores * `QA` - para que tu equipo de QA verifique las actualizaciones antes de un lanzamiento más amplio * `Staging` - para pruebas finales en un entorno similar a producción * `Production` - para la versión de tu aplicación que los usuarios finales reciben de las tiendas de aplicaciones ## Configurando el Canal en Tu Aplicación Con tus canales creados, necesitas configurar tu aplicación para escuchar el canal apropiado. En este ejemplo, usaremos el canal `Development` Abre tu archivo `capacitor.config.ts` (o `capacitor.config.json`). En la sección `plugins`, establece la propiedad `channel` del plugin `CapacitorUpdater` con el nombre de tu canal deseado: ```ts import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { defaultChannel: 'Development', }, }, }; ``` Luego, compila tu aplicación web y ejecuta `npx cap sync` para copiar el archivo de configuración actualizado a tus proyectos iOS y Android. Si te saltas este paso de sincronización, tus proyectos nativos continuarán usando el canal que tenían configurado previamente. Caution La propiedad `defaultChannel` siempre anulará el canal predeterminado en la nube. Pero aún puedes forzar el deviceId a un canal en la nube. ## Asignando un Bundle a un Canal Para desplegar una actualización en vivo, necesitas subir una nueva compilación del bundle JS y asignarla a un canal. Puedes hacer esto en un solo paso con el CLI de Capgo: ```shell npx @capgo/cli@latest bundle upload --channel=Development ``` Esto subirá tus activos web compilados y establecerá el nuevo bundle como la compilación activa para el canal `Development`. Cualquier aplicación configurada para escuchar ese canal recibirá la actualización la próxima vez que busque una. También puedes asignar compilaciones a canales desde la sección “Bundles” del panel de control de Capgo. Haz clic en el ícono de menú junto a una compilación y selecciona “Assign to Channel” para elegir el canal para esa compilación. ## Versionado de Bundles y Canales Es importante notar que los bundles en Capgo son globales para tu aplicación, no específicos para canales individuales. El mismo bundle puede ser asignado a múltiples canales. Al versionar tus bundles, recomendamos usar versionado semántico [semver](https://semver.org/) con identificadores de prelanzamiento para compilaciones específicas de canal. Por ejemplo, una versión beta podría versionarse como `1.2.3-beta.1`. Este enfoque tiene varios beneficios: * Comunica claramente la relación entre compilaciones. `1.2.3-beta.1` es obviamente un prelanzamiento de `1.2.3` * Permite reutilizar números de versión entre canales, reduciendo la confusión * Habilita rutas claras de reversión. Si necesitas revertir desde `1.2.3`, sabes que `1.2.2` es la versión estable anterior Aquí hay un ejemplo de cómo podrías alinear tus versiones de bundle con una configuración típica de canal: * Canal `Development`: `1.2.3-dev.1`, `1.2.3-dev.2`, etc. * Canal `QA`: `1.2.3-qa.1`, `1.2.3-qa.2`, etc. * Canal `Staging`: `1.2.3-rc.1`, `1.2.3-rc.2`, etc. * Canal `Production`: `1.2.3`, `1.2.4`, etc. Usar semver con identificadores de prelanzamiento es un enfoque recomendado, pero no estrictamente requerido. La clave es encontrar un esquema de versionado que comunique claramente las relaciones entre tus compilaciones y se alinee con el proceso de desarrollo de tu equipo. ## Revirtiendo una Actualización en Vivo Si despliegas una actualización en vivo que introduce un error o que necesita ser revertida por otros motivos, puedes fácilmente volver a una compilación anterior. Desde la sección “Channels” del panel de control: 1. Haz clic en el nombre del canal que quieres revertir 2. Encuentra la compilación a la que quieres revertir y haz clic en el ícono de corona ![Revertir compilación](/select_bundle.webp) 3. Confirma la acción La compilación seleccionada se convertirá inmediatamente en la compilación activa para ese canal nuevamente. Las aplicaciones recibirán la versión revertida la próxima vez que busquen una actualización. ## Automatizando Despliegues Para flujos de trabajo más avanzados, puedes automatizar tus despliegues de actualizaciones en vivo como parte de tu pipeline CI/CD. Al integrar Capgo en tu proceso de compilación, puedes subir automáticamente nuevos bundles y asignarlos a canales cuando hagas push a ciertas ramas o crees nuevos lanzamientos. Consulta la documentación de [Integración CI/CD](/docs/getting-started/cicd-integration/) para aprender más sobre la automatización de actualizaciones en vivo de Capgo. ## Desplegando a un Dispositivo Ahora que entiendes los canales, estás listo para comenzar a desplegar actualizaciones en vivo a dispositivos reales. El proceso básico es: 1. Instalar el SDK de Capgo en tu aplicación 2. Configurar la aplicación para escuchar tu canal deseado 3. Subir una compilación y asignarla a ese canal 4. ¡Iniciar la aplicación y esperar la actualización! Para una guía más detallada, consulta la guía de [Desplegando Actualizaciones en Vivo](/docs/getting-started/deploy/). ¡Felices actualizaciones! # Actualizaciones rápidas El sistema de Actualización en Vivo de Capgo puede entregar actualizaciones más rápido y de manera más eficiente enviando solo los archivos modificados, en lugar del paquete JS completo Esto es especialmente beneficioso para usuarios con conexiones de red más lentas o limitadas, ya que minimiza la cantidad de datos que necesitan descargar Un segundo beneficio es cuando la aplicación tiene recursos grandes que cambian raramente, como imágenes o videos, en comparación con archivos JS comprimidos que se descargarán solo una vez ## Cómo Funcionan las Actualizaciones Diferenciales Las actualizaciones diferenciales en Capgo son manejadas por el plugin de Capgo instalado en tu aplicación. Cuando subes una nueva versión de tu aplicación usando la bandera `--partial`, Capgo hace lo siguiente: 1. Cada archivo en tu compilación se sube individualmente 2. Se generan checksums para cada archivo 3. Se crea un nuevo manifiesto json, listando todos los archivos y sus checksums 4. Este manifiesto se sube a la base de datos de Capgo Cuando un dispositivo ejecutando tu aplicación busca actualizaciones, el plugin de Capgo recibe el nuevo manifiesto del servidor. Compara este manifiesto con el que tiene actualmente, identificando qué archivos han cambiado basándose en los checksums y rutas de archivos El plugin entonces descarga solo los archivos modificados, en lugar del paquete JS completo. Reconstruye la nueva versión de la aplicación combinando estos archivos descargados con los archivos sin cambios que ya tiene Manifiesto En caso de actualizaciones diferenciales, el dispositivo almacena todos los archivos descargados en un caché común, Capgo nunca lo limpiará pero el sistema operativo puede hacerlo en cualquier momento ## Habilitando Actualizaciones Diferenciales Para habilitar actualizaciones diferenciales para tu aplicación Capgo, simplemente usa la bandera `--partial` cuando subas una nueva versión: ## Forzando Actualizaciones Diferenciales Si deseas asegurar que todas las subidas sean actualizaciones diferenciales y prevenir cualquier subida accidental del paquete completo, puedes usar la bandera `--partial-only`: ```shell npx @capgo/cli@latest bundle upload --partial-only ``` Cuando se usa `--partial-only`, Capgo solo subirá archivos individuales y generará un manifiesto. Cualquier dispositivo que no soporte parcial no podrá descargar la actualización Podrías querer usar `--partial-only` si: * Siempre quieres usar actualizaciones diferenciales y nunca permitir subidas de paquetes completos * Estás configurando un pipeline CI/CD y quieres asegurar que todas las subidas automatizadas sean diferenciales * Tu aplicación es grande y el ancho de banda está limitado, por lo que necesitas minimizar los tamaños de subida/descarga Si necesitas hacer una subida de paquete completo mientras `--partial-only` está configurado, simplemente ejecuta el comando de subida sin `--partial-only`. Esto anulará la configuración para esa única subida, permitiéndote enviar un paquete completo cuando sea necesario ## Solución de Problemas Si las actualizaciones diferenciales no parecen estar funcionando (es decir, los dispositivos siempre están descargando el paquete JS completo incluso para cambios pequeños), verifica que: * Estés usando la bandera `--partial` cada vez que subes una nueva versión * Si usas `--partial-only`, asegúrate de no haber omitido accidentalmente la bandera `--partial` * Tu dispositivo esté ejecutando la última versión del plugin de Capgo * Tu dispositivo tenga una conexión de red estable y pueda alcanzar los servidores de Capgo También puedes usar la aplicación web de Capgo para verificar los detalles de tu última subida: 1. Ve a la [webapp](https://app.capgo.io) 2. Haz clic en tu aplicación 3. Haz clic en el número de bundles de la barra de estadísticas 4. Selecciona el último bundle 5. Verifica el campo `Partial` ![bundle type](/bundle_type.webp) Si continúas teniendo problemas, por favor contacta al soporte de Capgo para más asistencia. Ellos pueden revisar los registros del servidor para confirmar que tus subidas parciales están siendo procesadas correctamente y que los dispositivos están recibiendo los manifiestos actualizados ¡Eso es todo! La bandera `--partial` le dice a Capgo que realice las subidas de archivos individuales y la generación de manifiestos necesarios para las actualizaciones diferenciales Ten en cuenta que necesitas usar `--partial` cada vez que subas una nueva versión que quieras que se entregue como una actualización diferencial. Si omites la bandera, Capgo subirá el paquete JS completo como un solo archivo, y los dispositivos descargarán el paquete completo incluso si solo una pequeña parte ha cambiado # Rollbacks Si bien las actualizaciones en vivo de Capgo te permiten entregar rápidamente mejoras y correcciones a tus usuarios, puede haber situaciones donde necesites revertir a una versión anterior de tu aplicación. Quizás una nueva actualización introdujo un problema crítico inesperado, o tal vez quieras revertir un cambio específico mientras trabajas en una solución. Capgo proporciona varias formas de gestionar las compilaciones de un canal y controlar la versión de tu aplicación que reciben los usuarios. ## Revertir a un Bundle Anterior Cada vez que subes una nueva compilación y la asignas a un canal, Capgo mantiene un historial de esas compilaciones. Si necesitas revertir una actualización específica, puedes seleccionar una de estas compilaciones anteriores para volver a implementarla en el canal. Para revertir a una compilación anterior: 1. Inicia sesión en el [Panel de Control de Capgo](https://app.capgo.io) 2. Navega a la sección “Canales” 3. Haz clic en el nombre del canal que quieres revertir 4. Encuentra la compilación a la que quieres revertir en el historial de compilaciones del canal 5. Haz clic en el ícono de corona junto a esa compilación para convertirla en la compilación activa del canal ![Opciones de gestión de canal](/select_bundle.webp) 6. Confirma que deseas revertir a esta compilación Note Revertir a una compilación anterior solo afecta al canal seleccionado. Si tienes múltiples canales (ej. Producción, Staging, etc.), necesitarás repetir el proceso de reversión para cada canal afectado. Después de revertir, los dispositivos configurados para escuchar el canal actualizado recibirán la compilación anterior la próxima vez que busquen actualizaciones. La compilación revertida será tratada como una nueva actualización, por lo que se aplicarán las condiciones y el flujo de actualización habituales. ## Desvincular un Canal Si deseas detener temporalmente las actualizaciones en un canal mientras investigas un problema, puedes desvincular el canal de su compilación actual. Para desvincular un canal: 1. Navega al canal en el Panel de Control de Capgo 2. Haz clic en el botón “Desvincular” junto a la compilación actual 3. Confirma que deseas desvincular el canal Una vez que un canal está desvinculado, no distribuirá nuevas actualizaciones. Los dispositivos configurados en ese canal permanecerán en su compilación actual hasta que el canal se vincule nuevamente a una compilación. Esto es útil si has identificado un problema con una actualización pero aún no estás seguro a qué compilación quieres revertir. Desvincular el canal te da tiempo para investigar sin enviar más actualizaciones. ## Forzar el Bundle Incorporado En situaciones más graves, es posible que desees revertir todos los dispositivos en un canal a la compilación web que se incluyó originalmente en el binario nativo de tu aplicación. Esto se conoce como el “bundle incorporado”. Para forzar el bundle incorporado en un canal: 1. Navega al canal en el Panel de Control de Capgo 2. Haz clic en el botón “Bundle Incorporado” 3. Confirma que deseas forzar el bundle incorporado Cuando fuerzas el bundle incorporado, todos los dispositivos configurados en ese canal volverán a la compilación web original empaquetada en su próxima verificación de actualización. Esto sucede independientemente de la compilación en la que se encuentren actualmente. Esta es una opción de reversión más agresiva que revertir a una compilación anterior específica, ya que descarta todas las actualizaciones en vivo lanzadas desde que la aplicación se publicó por última vez en las tiendas de aplicaciones. Caution Ten cuidado al forzar el bundle incorporado, ya que afectará a todos los dispositivos en el canal. Asegúrate de haber considerado el impacto y tener un plan para avanzar antes de tomar esta acción. ## Monitoreo y Respuesta a Problemas Para detectar problemas rápidamente y minimizar el impacto de actualizaciones problemáticas, es importante tener un plan para monitorear tus lanzamientos y responder a los problemas. Algunas estrategias incluyen: * Monitorear reportes de fallos y retroalimentación de usuarios inmediatamente después de lanzar una actualización * Usar despliegues graduales o un sistema de canales escalonado para probar actualizaciones en un grupo más pequeño antes del lanzamiento general * Tener un proceso de decisión claro sobre cuándo revertir, desvincular o forzar el bundle incorporado, y quién tiene la autoridad para hacerlo * Comunicar a los usuarios sobre el problema y la resolución, cuando sea apropiado Al combinar un monitoreo cuidadoso con la capacidad de gestionar rápidamente las actualizaciones problemáticas, puedes ofrecer una experiencia de aplicación que mejora continuamente mientras minimizas las interrupciones para tus usuarios. # Comportamiento de Actualización Cuando lanzas una actualización de tu aplicación Capgo, probablemente quieres que tus usuarios reciban esa actualización lo antes posible. Pero también no quieres interrumpir su experiencia forzándolos a esperar una descarga o reiniciar la aplicación en medio de una sesión. El comportamiento de actualización de Capgo está diseñado para lograr un equilibrio entre entregar actualizaciones rápidamente y minimizar la interrupción para tus usuarios. ## Flujo de Actualización Predeterminado Por defecto, así es como Capgo maneja las actualizaciones de la aplicación: 1. Al iniciar la aplicación, el plugin de Capgo verifica si hay una nueva actualización disponible 2. Si se encuentra una actualización, se descarga en segundo plano mientras el usuario continúa usando la versión actual de la aplicación 3. Una vez que se completa la descarga, Capgo espera a que el usuario envíe la aplicación a segundo plano o la cierre por completo 4. Cuando el usuario vuelva a iniciar la aplicación, estará ejecutando la versión actualizada Este flujo asegura que los usuarios siempre estén ejecutando la última versión de tu aplicación, sin ser interrumpidos por avisos de actualización o forzados a esperar descargas. Tip Capgo también busca actualizaciones cuando la aplicación se reanuda desde segundo plano, por lo que los usuarios recibirán actualizaciones incluso si no cierran completamente la aplicación ## ¿Por qué Este Enfoque? Aplicar actualizaciones en un evento de segundo plano o cierre tiene varios beneficios clave para la experiencia del usuario: * Los usuarios no son interrumpidos por avisos de actualización ni forzados a esperar descargas en medio de una sesión * Las actualizaciones se aplican sin problemas entre sesiones, por lo que la experiencia de iniciar la aplicación siempre es nueva * Puedes entregar actualizaciones frecuentemente sin preocuparte por interrumpir a los usuarios activos La principal desventaja es que si un usuario envía a segundo plano y reanuda rápidamente tu aplicación, puede perder cualquier estado no guardado ya que la actualización se aplicó entre esas acciones. Para mitigar esto, recomendamos: * Guardar el estado frecuentemente y restaurarlo correctamente cuando la aplicación se reanude * Evitar actualizaciones muy frecuentes que modifiquen grandes partes del estado de la aplicación * Considerar personalizar el comportamiento de actualización para flujos sensibles (ver abajo) ## Personalizando Cuándo se Aplican las Actualizaciones En algunos casos, es posible que desees más control sobre exactamente cuándo se aplica una actualización. Por ejemplo, podrías querer asegurarte de que un usuario complete un flujo en progreso antes de actualizar, o coordinar una actualización de la aplicación con un cambio del lado del servidor. Capgo proporciona una función `setDelay` que te permite especificar condiciones que deben cumplirse antes de que se instale una actualización: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; await CapacitorUpdater.setMultiDelay({ delayConditions: [ { kind: 'date', value: '2023-06-01T00:00:00.000Z', }, { kind: 'background', value: '60000', }, ], }); ``` Este ejemplo retrasaría la instalación de una actualización hasta después del 1 de junio de 2023 Y la aplicación haya estado en segundo plano durante al menos 60 segundos. Las condiciones de retraso disponibles son: * `date`: Esperar hasta después de una fecha/hora específica para aplicar la actualización * `background`: Esperar una duración mínima después de que la aplicación esté en segundo plano para aplicar la actualización * `nativeVersion`: Esperar a que se instale un binario nativo con una versión mínima antes de aplicar la actualización * `kill`: Esperar hasta el próximo evento de cierre de la aplicación para aplicar la actualización Puedes mezclar y combinar estas condiciones para controlar precisamente cuándo se instala una actualización. Danger Ten en cuenta que la condición `kill` actualmente activa la actualización después del primer evento de cierre, no el próximo evento de segundo plano como las otras condiciones. Esta inconsistencia se corregirá en una versión futura ## Aplicando Actualizaciones Inmediatamente Para actualizaciones críticas o aplicaciones con estado muy simple, es posible que desees aplicar una actualización tan pronto como se descargue, sin esperar un evento de segundo plano o cierre. Capgo admite esto a través de la opción de configuración `directUpdate`. `directUpdate` se establece en tu archivo `capacitor.config.ts`, no en código JavaScript: ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: true, keepUrlPathAfterReload: true, }, }, }; export default config; ``` Con `directUpdate` habilitado, Capgo aplicará inmediatamente una actualización tan pronto como se complete la descarga, incluso si el usuario está usando activamente la aplicación. Ten en cuenta que debido a que `directUpdate` es una configuración nativa, requiere un manejo adicional en tu código JavaScript. Cuando uses `directUpdate`, necesitas escuchar el evento `appReady` y ocultar la pantalla de inicio de tu aplicación en respuesta: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater'; import { SplashScreen } from '@capacitor/splash-screen'; CapacitorUpdater.addListener('appReady', () => { // Ocultar pantalla de inicio SplashScreen.hide(); }); CapacitorUpdater.notifyAppReady(); ``` El evento `appReady` se dispara una vez que la aplicación ha terminado de inicializarse y aplicar cualquier actualización pendiente. Este es el punto en el que es seguro mostrar la interfaz de usuario de tu aplicación, ya que asegura que el usuario verá la última versión. Además de manejar el evento `appReady`, recomendamos establecer la opción de configuración `keepUrlPathAfterReload` en `true` cuando se use `directUpdate`. Esto preserva la ruta URL actual cuando la aplicación se recarga debido a una actualización, ayudando a mantener la ubicación del usuario en la aplicación y reduciendo la desorientación. Si no manejas el evento `appReady` y estableces `keepUrlPathAfterReload` cuando uses `directUpdate`, el usuario puede ver brevemente una versión obsoleta de la aplicación, ser llevado de vuelta a la ruta inicial, o ver un parpadeo mientras se aplica la actualización. Usar `directUpdate` puede ser útil para entregar correcciones de errores críticos o parches de seguridad, pero viene con algunos compromisos: * El usuario puede ver un breve parpadeo o estado de carga mientras se aplica la actualización si no manejas correctamente el evento `appReady` * Si la actualización modifica el estado o la interfaz de usuario de la aplicación, el usuario puede ver un cambio disruptivo en medio de una sesión * La ubicación del usuario en la aplicación puede perderse si `keepUrlPathAfterReload` no está establecido, potencialmente desorientándolo * Necesitarás manejar cuidadosamente el guardado y restauración del estado para asegurar una transición suave Si habilitas `directUpdate`, recomendamos: * Manejar el evento `appReady` para controlar cuándo se muestra la interfaz de usuario de tu aplicación * Establecer `keepUrlPathAfterReload` en `true` para preservar la ubicación del usuario en la aplicación * Guardar y restaurar el estado de la aplicación según sea necesario para evitar perder el progreso del usuario * Probar exhaustivamente el comportamiento de actualización de tu aplicación para asegurar que no haya transiciones bruscas, pérdida de estado o cambios de ubicación desorientadores En la mayoría de los casos, el comportamiento de actualización predeterminado proporciona el mejor equilibrio entre entregar actualizaciones rápidamente y minimizar la interrupción. Pero para aplicaciones con necesidades específicas, Capgo proporciona la flexibilidad para personalizar cuándo y cómo se aplican las actualizaciones. # Funzioni e impostazioni > Todos los métodos y configuraciones disponibles del plugin # Configuración del Plugin Updater Consulta el [Readme](https://github.com/Cap-go/capacitor-updater) de Github para más información CapacitorUpdater puede configurarse con estas opciones: | Propiedad | Tipo | Descripción | Valor predeterminado | Desde | | ------------------------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | ----- | | **`appReadyTimeout`** | `number` | Configura el número de milisegundos que el plugin nativo debe esperar antes de considerar una actualización como ‘fallida’. Solo disponible para Android e iOS | `10000 // (10 segundos)` | | | **`responseTimeout`** | `number` | Configura el número de milisegundos que el plugin nativo debe esperar antes de considerar un tiempo de espera de la API. Solo disponible para Android e iOS | `20 // (20 segundos)` | | | **`autoDeleteFailed`** | `boolean` | Configura si el plugin debe eliminar automáticamente los paquetes fallidos. Solo disponible para Android e iOS | `true` | | | **`autoDeletePrevious`** | `boolean` | Configura si el plugin debe eliminar automáticamente los paquetes anteriores después de una actualización exitosa. Solo disponible para Android e iOS | `true` | | | **`autoUpdate`** | `boolean` | Configura si el plugin debe usar actualización automática a través de un servidor de actualizaciones. Solo disponible para Android e iOS | `true` | | | **`resetWhenUpdate`** | `boolean` | Elimina automáticamente los paquetes descargados anteriormente cuando se instala un nuevo paquete nativo en el dispositivo. Solo disponible para Android e iOS | `true` | | | **`updateUrl`** | `string` | Configura la URL / punto final al que se envían las comprobaciones de actualización. Solo disponible para Android e iOS | `https://plugin.capgo.app/updates` | | | **`channelUrl`** | `string` | Configura la URL / punto final para operaciones de canal. Solo disponible para Android e iOS | `https://plugin.capgo.app/channel_self` | | | **`statsUrl`** | `string` | Configura la URL / punto final al que se envían las estadísticas de actualización. Solo disponible para Android e iOS. Establecer como "" para deshabilitar el reporte de estadísticas | `https://plugin.capgo.app/stats` | | | **`privateKey`** | `string` | Configura la clave privada para el cifrado de actualizaciones en vivo de extremo a extremo. Solo disponible para Android e iOS. Obsoleto en la versión 620, será eliminado en la versión 700 | `undefined` | | | **`publicKey`** | `string` | Configura la clave pública para el cifrado de actualizaciones en vivo de extremo a extremo Versión 2. Solo disponible para Android e iOS | `undefined` | 620 | | **`version`** | `string` | Configura la versión actual de la aplicación. Se usará para la primera solicitud de actualización. Si no se establece, el plugin obtendrá la versión del código nativo. Solo para Android e iOS | `undefined` | 41748 | | **`directUpdate`** | `boolean` | Hace que el plugin instale directamente la actualización cuando la aplicación se acaba de actualizar/instalar. Solo para modo autoUpdate. Solo disponible para Android e iOS | `undefined` | 510 | | **`periodCheckDelay`** | `number` | Configura el período de retraso para la comprobación periódica de actualizaciones en segundos. Solo disponible para Android e iOS. No puede ser menor a 600 segundos (10 minutos) | `600 // (10 minutos)` | | | **`localS3`** | `boolean` | Configura el CLI para usar un servidor local para pruebas o servidor de actualizaciones autohospedado | `undefined` | 41748 | | **`localHost`** | `string` | Configura el CLI para usar un servidor local para pruebas o servidor de actualizaciones autohospedado | `undefined` | 41748 | | **`localWebHost`** | `string` | Configura el CLI para usar un servidor local para pruebas o servidor de actualizaciones autohospedado | `undefined` | 41748 | | **`localSupa`** | `string` | Configura el CLI para usar un servidor local para pruebas o servidor de actualizaciones autohospedado | `undefined` | 41748 | | **`localSupaAnon`** | `string` | Configura el CLI para usar un servidor local para pruebas | `undefined` | 41748 | | **`localApi`** | `string` | Configura el CLI para usar una API local para pruebas | `undefined` | 633 | | **`localApiFiles`** | `string` | Configura el CLI para usar una API de archivos local para pruebas | `undefined` | 633 | | **`allowModifyUrl`** | `boolean` | Permite que el plugin modifique updateUrl, statsUrl y channelUrl dinámicamente desde el lado JavaScript | `false` | 540 | | **`defaultChannel`** | `string` | Establece el canal predeterminado para la aplicación en la configuraciónTraducción al español: | | | ```plaintext | undefined | 550 | ``` \| **`appId`** | `string` | Configura el id de la aplicación en la configuración | `undefined` | 600 | | **`keepUrlPathAfterReload`** | `boolean` | Configura el plugin para mantener la ruta URL después de una recarga ADVERTENCIA: Cuando se activa una recarga, ‘windowhistory’ se borrará | `false` | 680 | ## Ejemplos En `capacitorconfigjson`: ```json { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 // (1 segundo), "responseTimeout": 10 // (10 segundos), "autoDeleteFailed": false, "autoDeletePrevious": false, "autoUpdate": false, "resetWhenUpdate": false, "updateUrl": https://examplecom/api/auto_update, "channelUrl": https://examplecom/api/channel, "statsUrl": https://examplecom/api/stats, "privateKey": undefined, "publicKey": undefined, "version": undefined, "directUpdate": undefined, "periodCheckDelay": undefined, "localS3": undefined, "localHost": undefined, "localWebHost": undefined, "localSupa": undefined, "localSupaAnon": undefined, "localApi": undefined, "localApiFiles": undefined, "allowModifyUrl": undefined, "defaultChannel": undefined, "appId": undefined, "keepUrlPathAfterReload": undefined } } } ``` En `capacitorconfigts`: ```ts /// import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { appReadyTimeout: 1000 // (1 segundo), responseTimeout: 10 // (10 segundos), autoDeleteFailed: false, autoDeletePrevious: false, autoUpdate: false, resetWhenUpdate: false, updateUrl: https://examplecom/api/auto_update, channelUrl: https://examplecom/api/channel, statsUrl: https://examplecom/api/stats, privateKey: undefined, publicKey: undefined, version: undefined, directUpdate: undefined, periodCheckDelay: undefined, localS3: undefined, localHost: undefined, localWebHost: undefined, localSupa: undefined, localSupaAnon: undefined, localApi: undefined, localApiFiles: undefined, allowModifyUrl: undefined, defaultChannel: undefined, appId: undefined, keepUrlPathAfterReload: undefined, }, }, }; export default config; ``` * [`notifyAppReady()`](#notifyappready) * [`setUpdateUrl()`](#setupdateurl) * [`setStatsUrl()`](#setstatsurl) * [`setChannelUrl()`](#setchannelurl) * [`download()`](#download) * [`next()`](#next) * [`set()`](#set) * [`delete()`](#delete) * [`list()`](#list) * [`reset()`](#reset) * [`current()`](#current) * [`reload()`](#reload) * [`setMultiDelay()`](#setmultidelay) * [`cancelDelay()`](#canceldelay) * [`getLatest()`](#getlatest) * [`setChannel()`](#setchannel) * [`unsetChannel()`](#unsetchannel) * [`getChannel()`](#getchannel) * [`setCustomId()`](#setcustomid) * [`getBuiltinVersion()`](#getbuiltinversion) * [`getDeviceId()`](#getdeviceid) * [`getPluginVersion()`](#getpluginversion) * [`isAutoUpdateEnabled()`](#isautoupdateenabled) * [`removeAllListeners()`](#removealllisteners) * [`addListener('download', )`](#addlistenerdownload-) * [`addListener('noNeedUpdate', )`](#addlistenernoneedupdate-) * [`addListener('updateAvailable', )`](#addlistenerupdateavailable-) * [`addListener('downloadComplete', )`](#addlistenerdownloadcomplete-) * [`addListener('majorAvailable', )`](#addlistenermajoravailable-) * [`addListener('updateFailed', )`](#addlistenerupdatefailed-) * [`addListener('downloadFailed', )`](#addlistenerdownloadfailed-) * [`addListener('appReloaded', )`](#addlistenerappreloaded-) * [`addListener('appReady', )`](#addlistenerappready-) * [`isAutoUpdateAvailable()`](#isautoupdateavailable) * [`getNextBundle()`](#getnextbundle) * [Interfaces](#interfaces) * [Type Aliases](#type-aliases) # Métodos ## notifyAppReady() ```typescript notifyAppReady() => Promise ``` Notifica a Capacitor Updater que el paquete actual está funcionando (se producirá un rollback si este método no se llama en cada inicio de la aplicación) Por defecto, este método debe llamarse en los primeros 10 segundos después del inicio de la aplicación, de lo contrario se producirá un rollback Cambia este comportamiento con {@link appReadyTimeout} **Devuelve:** `Promise` *** ## setUpdateUrl() ```typescript setUpdateUrl(options: UpdateUrl) => Promise ``` Establece la updateUrl para la aplicación, esta se usará para buscar actualizaciones | Param | Type | Descripción | | ------------- | ----------- | -------------------------------------------------- | | **`options`** | `UpdateUrl` | contiene la URL a usar para buscar actualizaciones | **Desde:** 540 *** ## setStatsUrl() ```typescript setStatsUrl(options: StatsUrl) => Promise ``` Establece la statsUrl para la aplicación, esta se usará para enviar estadísticas. Pasar una cadena vacía deshabilitará la recopilación de estadísticas | Param | Type | Descripción | | ------------- | ---------- | ----------------------------------------------- | | **`options`** | `StatsUrl` | contiene la URL a usar para enviar estadísticas | **Desde:** 540 *** ## setChannelUrl() ```typescript setChannelUrl(options: ChannelUrl) => Promise ``` Establece la channelUrl para la aplicación, esta se usará para establecer el canal | Param | Type | Descripción | | ------------- | ------------ | ----------------------------------------------- | | **`options`** | `ChannelUrl` | contiene la URL a usar para establecer el canal | **Desde:** 540 *** ## download() ```typescript download(options: DownloadOptions) => Promise ``` Descarga un nuevo paquete desde la URL proporcionada, debe ser un archivo zip, con archivos dentro o con un id único dentro con todos tus archivos | Param | Type | Descripción | | ------------- | ----------------- | -------------------------------------------------------------------------------------- | | **`options`** | `DownloadOptions` | Las {@link [DownloadOptions](#downloadoptions)} para descargar un nuevo zip de paquete | **Devuelve:** `Promise` *** ## next() ```typescript next(options: BundleId) => Promise ``` Establece el siguiente paquete que se usará cuando la aplicación sea recargada| Param | Type | Description | | ------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | Contiene el ID del siguiente Bundle a establecer en el próximo inicio de la aplicación {@link [BundleInfoid](#bundleinfo)} | **Returns:** `Promise` *** ## set() ```typescript set(options: BundleId) => Promise ``` Establece el bundle actual e inmediatamente recarga la aplicación | Param | Type | Description | | ------------- | ---------- | --------------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | Un objeto {@link [BundleId](#bundleid)} que contiene el nuevo ID de bundle a establecer como actual | *** ## delete() ```typescript delete(options: BundleId) => Promise ``` Elimina el bundle especificado del almacenamiento nativo de la aplicación. Use con {@link list} para obtener los IDs de Bundle almacenados | Param | Type | Description | | ------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | Un objeto {@link [BundleId](#bundleid)} que contiene el ID del bundle a eliminar (nota, este es el ID del bundle, NO el nombre de la versión) | *** ## list() ```typescript list(options?: ListOptions | undefined) => Promise ``` Obtiene todos los bundles descargados localmente en tu aplicación | Param | Type | Description | | ------------- | ------------- | ----------------------------------------------------------- | | **`options`** | `ListOptions` | Las {@link [ListOptions](#listoptions)} para listar bundles | **Returns:** `Promise` *** ## reset() ```typescript reset(options?: ResetOptions | undefined) => Promise ``` Restablece la aplicación al bundle `builtin` (el enviado a Apple App Store / Google Play Store) o al último bundle cargado exitosamente | Param | Type | Description | | ------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **`options`** | `ResetOptions` | Contiene {@link [ResetOptionstoLastSuccessful](#resetoptions)}, `true` restablece al bundle incorporado y `false` restablecerá al último bundle cargado exitosamente | *** ## current() ```typescript current() => Promise ``` Obtiene el bundle actual, si no hay ninguno establecido retorna `builtin`. currentNative es el bundle original instalado en el dispositivo **Returns:** `Promise` *** ## reload() ```typescript reload() => Promise ``` Recarga la vista *** ## setMultiDelay() ```typescript setMultiDelay(options: MultiDelayConditions) => Promise ``` Establece un array {@link [DelayCondition](#delaycondition)} que contiene condiciones que el Plugin usará para retrasar la actualización Después de que todas las condiciones se cumplan, el proceso de actualización comenzará nuevamente como de costumbre, por lo que la actualización se instalará después de poner en segundo plano o matar la aplicación Para el tipo `date`, el valor debe ser una cadena de fecha iso8601 Para el tipo `background`, el valor debe ser un número en milisegundos Para el tipo `nativeVersion`, el valor debe ser el número de versión Para el tipo `kill`, el valor no se utiliza La función tiene un comportamiento inconsistente; la opción kill activa la actualización después del primer cierre y no después del siguiente segundo plano como otras opciones. Esto se corregirá en una versión mayor futura | Param | Type | Description | | ------------- | ---------------------- | --------------------------------------------------------------------------------------------------- | | **`options`** | `MultiDelayConditions` | Contiene el array {@link [MultiDelayConditions](#multidelayconditions)} de condiciones a establecer | **Since:** 430 *** ## cancelDelay() ```typescript cancelDelay() => Promise ``` Cancela una {@link [DelayCondition](#delaycondition)} para procesar una actualización inmediatamente **Since:** 400 *** ## getLatest() ```typescript getLatest(options?: GetLatestOptions | undefined) => Promise ``` Obtiene el último bundle disponible desde la URL de actualización | Param | Type | | ------------- | ------------------ | | **`options`** | `GetLatestOptions` | **Returns:** `Promise` **Since:** 400 *** ## setChannel() ```typescript setChannel(options: SetChannelOptions) => Promise ``` Establece el canal para este dispositivo. El canal debe permitir la autoasignación para que esto funcione No use este método para establecer el canal al inicio cuando `autoUpdate` está habilitado en la {@link PluginsConfig} Este método es para establecer el canal después de que la aplicación esté lista Este método envía al backend de Capgo una solicitud para vincular el ID del dispositivo al canal. Capgo puede aceptar o rechazar dependiendo de la configuración de tu canal | Param | Type | Description | | ------------- | ------------------- | ------------------------------------------------------------------------ | | **`options`** | `SetChannelOptions` | Es el canal {@link [SetChannelOptions](#setchanneloptions)} a establecer | **Returns:** `Promise` **Since:** 470 *** ## unsetChannel() ```typescript unsetChannel(options: UnsetChannelOptions) => Promise ``` Desestablece el canal para este dispositivoEl dispositivo volverá entonces al canal predeterminado | Param | Type | | ------------- | --------------------- | | **`options`** | `UnsetChannelOptions` | **Since:** 470 *** ## getChannel() ```typescript getChannel() => Promise ``` Obtener el canal para este dispositivo **Returns:** `Promise` **Since:** 480 *** ## setCustomId() ```typescript setCustomId(options: SetCustomIdOptions) => Promise ``` Establecer un ID personalizado para este dispositivo | Param | Type | Description | | ------------- | -------------------- | ----------------------------------------------------------------------------- | | **`options`** | `SetCustomIdOptions` | es el {@link [SetCustomIdOptions](#setcustomidoptions)} customId a establecer | **Since:** 490 *** ## getBuiltinVersion() ```typescript getBuiltinVersion() => Promise ``` Obtener la versión nativa de la app o la versión incorporada si está configurada **Returns:** `Promise` **Since:** 520 *** ## getDeviceId() ```typescript getDeviceId() => Promise ``` Obtener ID único usado para identificar el dispositivo (enviado al servidor de actualización automática) **Returns:** `Promise` *** ## getPluginVersion() ```typescript getPluginVersion() => Promise ``` Obtener la versión nativa del plugin Capacitor Updater (enviada al servidor de actualización automática) **Returns:** `Promise` *** ## isAutoUpdateEnabled() ```typescript isAutoUpdateEnabled() => Promise ``` Obtener el estado de la configuración de actualización automática **Returns:** `Promise` *** ## removeAllListeners() ```typescript removeAllListeners() => Promise ``` Eliminar todos los listeners de este plugin **Since:** 100 *** ## addListener(‘download’, ) ```typescript addListener(eventName: 'download', listenerFunc: (state: DownloadEvent) => void) => Promise ``` Escuchar el evento de descarga de bundle en la App. Se activa cuando comienza una descarga, durante la descarga y cuando finaliza | Param | Type | | ------------------ | -------------------------------- | | **`eventName`** | `’download’` | | **`listenerFunc`** | `(state: DownloadEvent) => void` | **Returns:** `Promise` **Since:** 2011 *** ## addListener(‘noNeedUpdate’, ) ```typescript addListener(eventName: 'noNeedUpdate', listenerFunc: (state: NoNeedEvent) => void) => Promise ``` Escuchar el evento de no necesidad de actualización, útil cuando deseas forzar la comprobación cada vez que se inicia la app | Param | Type | | ------------------ | ------------------------------ | | **`eventName`** | `’noNeedUpdate’` | | **`listenerFunc`** | `(state: NoNeedEvent) => void` | **Returns:** `Promise` **Since:** 400 *** ## addListener(‘updateAvailable’, ) ```typescript addListener(eventName: 'updateAvailable', listenerFunc: (state: UpdateAvailableEvent) => void) => Promise ``` Escuchar el evento de actualización disponible, útil cuando deseas forzar la comprobación cada vez que se inicia la app | Param | Type | | ------------------ | --------------------------------------- | | **`eventName`** | `’updateAvailable’` | | **`listenerFunc`** | `(state: UpdateAvailableEvent) => void` | **Returns:** `Promise` **Since:** 400 *** ## addListener(‘downloadComplete’, ) ```typescript addListener(eventName: 'downloadComplete', listenerFunc: (state: DownloadCompleteEvent) => void) => Promise ``` Escuchar eventos de descarga completada | Param | Type | | ------------------ | ---------------------------------------- | | **`eventName`** | `’downloadComplete’` | | **`listenerFunc`** | `(state: DownloadCompleteEvent) => void` | **Returns:** `Promise` **Since:** 400 *** ## addListener(‘majorAvailable’, ) ```typescript addListener(eventName: 'majorAvailable', listenerFunc: (state: MajorAvailableEvent) => void) => Promise ``` Escuchar el evento de actualización Mayor en la App, te permite saber cuándo una actualización mayor está bloqueada por la configuración disableAutoUpdateBreaking | Param | Type | | ------------------ | -------------------------------------- | | **`eventName`** | `’majorAvailable’` | | **`listenerFunc`** | `(state: MajorAvailableEvent) => void` | **Returns:** `Promise` **Since:** 230 *** ## addListener(‘updateFailed’, ) ```typescript addListener(eventName: 'updateFailed', listenerFunc: (state: UpdateFailedEvent) => void) => Promise ``` Escuchar el evento de fallo de actualización en la App, te permite saber cuándo una actualización ha fallado al instalarse en el próximo inicio de la app | Param | Type | | ------------------ | ------------------------------------ | | **`eventName`** | `’updateFailed’` | | **`listenerFunc`** | `(state: UpdateFailedEvent) => void` | **Returns:** `Promise` **Since:** 230 *** ## addListener(‘downloadFailed’,\`\`\`typescript addListener(eventName: ‘downloadFailed’, listenerFunc: (state: DownloadFailedEvent) => void) => Promise ````plaintext Escuchar el evento de fallo de descarga en la App, te permite saber cuando ha fallado la descarga de un paquete | Param | Tipo | | ------------------ | --------------------------------------------------------------------------------------- | | **`eventName`** | 'downloadFailed' | | **`listenerFunc`** | (state: DownloadFailedEvent) => void | **Devuelve:** Promise<PluginListenerHandle> **Desde:** 400 -------------------- ## addListener('appReloaded', ) ```typescript addListener(eventName: 'appReloaded', listenerFunc: () => void) => Promise ```` Escuchar el evento de recarga en la App, te permite saber cuando se ha producido una recarga | Param | Tipo | | ------------------ | --------------- | | **`eventName`** | `’appReloaded’` | | **`listenerFunc`** | `() => void` | **Devuelve:** `Promise` **Desde:** 430 *** ## addListener(‘appReady’, ) ```typescript addListener(eventName: 'appReady', listenerFunc: (state: AppReadyEvent) => void) => Promise ``` Escuchar el evento de app lista en la App, te permite saber cuando la app está lista para usarse | Param | Tipo | | ------------------ | -------------------------------- | | **`eventName`** | `’appReady’` | | **`listenerFunc`** | `(state: AppReadyEvent) => void` | **Devuelve:** `Promise` **Desde:** 510 *** ## isAutoUpdateAvailable() ```typescript isAutoUpdateAvailable() => Promise ``` Obtener si la actualización automática está disponible (no deshabilitada por serverUrl) **Devuelve:** `Promise` *** ## getNextBundle() ```typescript getNextBundle() => Promise ``` Obtener el siguiente paquete que será utilizado cuando la app se recargue Devuelve null si no hay un siguiente paquete establecido **Devuelve:** `Promise` **Desde:** 680 *** ## Interfaces ### AppReadyResult | Prop | Tipo | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | ### BundleInfo | Prop | Tipo | | ---------------- | -------------- | | **`id`** | `string` | | **`version`** | `string` | | **`downloaded`** | `string` | | **`checksum`** | `string` | | **`status`** | `BundleStatus` | ### UpdateUrl | Prop | Tipo | | --------- | -------- | | **`url`** | `string` | ### StatsUrl | Prop | Tipo | | --------- | -------- | | **`url`** | `string` | ### ChannelUrl | Prop | Tipo | | --------- | -------- | | **`url`** | `string` | ### DownloadOptions | Prop | Tipo | Descripción | Por defecto | Desde | | ---------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ----- | | **`url`** | `string` | La URL del archivo zip del paquete (ej: distzip) a descargar (Puede ser cualquier URL Ej: Amazon S3, un tag de GitHub, cualquier otro lugar donde hayas alojado tu paquete) | | | | **`version`** | `string` | El código/nombre de versión de este paquete/versión | | | | **`sessionKey`** | `string` | La clave de sesión para la actualización | `undefined` | 400 | | **`checksum`** | `string` | El checksum para la actualización | `undefined` | 400 | ### BundleId | Prop | Tipo | | -------- | -------- | | **`id`** | `string` | ### BundleListResult | Prop | Tipo | | ------------- | -------------- | | **`bundles`** | `BundleInfo[]` | ### ListOptions | Prop | Tipo | Descripción | Por defecto | Desde | | --------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | ----- | | **`raw`** | `boolean` | Si devolver la lista cruda de paquetes o el manifiesto. Si es true, la lista intentará leer la base de datos interna en lugar de los archivos en disco | `false` | 6140 | ### ResetOptions | Prop | Tipo | | ---------------------- | --------- | | **`toLastSuccessful`** | `boolean` | ### CurrentBundleResult | Prop | Tipo | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | | **`native`** | `string` | ### MultiDelayConditions | Prop | Tipo | | --------------------- | ------------------ | | **`delayConditions`** | `DelayCondition[]` | ### DelayCondition | Prop | Tipo | Descripción | | ----------- | ---------------- | -------------------------------------------------- | | **`kind`** | `DelayUntilNext` | Establecer condiciones de retraso en setMultiDelay | | **`value`** | `string` | | ### LatestVersion | Prop | Tipo | Descripción | Desde | | ---------------- | ----------------- | ------------------------------ | ----- | | **`version`** | `string` | Resultado del método getLatest | 400 | | **`checksum`** | `string` | | 6 | | **`major`** | `boolean` | | | | **`message`** | `string` | | | | **`sessionKey`** | `string` | | | | **`error`** | `string` | | | | **`old`** | `string` | | | | **`url`** | `string` | | | | **`manifest`** | `ManifestEntry[]` | | 61 | ### ManifestEntry | Prop | Type | | ------------------ | ---------------- | | **`file_name`** | `string \| null` | | **`file_hash`** | `string \| null` | | **`download_url`** | `string \| null` | ### GetLatestOptions | Prop | Type | Description | Default | Since | | ------------- | -------- | ----------------------------------------------------------------------------------------------------- | ----------- | ----- | | **`channel`** | `string` | El canal para obtener la última versión. El canal debe permitir ‘self\_assign’ para que esto funcione | `undefined` | 680 | ### ChannelRes | Prop | Type | Description | Since | | ------------- | -------- | ----------------------------------- | ----- | | **`status`** | `string` | Estado actual del canal establecido | 470 | | **`error`** | `string` | | | | **`message`** | `string` | | | ### SetChannelOptions | Prop | Type | | ----------------------- | --------- | | **`channel`** | `string` | | **`triggerAutoUpdate`** | `boolean` | ### UnsetChannelOptions | Prop | Type | | ----------------------- | --------- | | **`triggerAutoUpdate`** | `boolean` | ### GetChannelRes | Prop | Type | Description | Since | | -------------- | --------- | -------------------------------- | ----- | | **`channel`** | `string` | Estado actual del canal obtenido | 480 | | **`error`** | `string` | | | | **`message`** | `string` | | | | **`status`** | `string` | | | | **`allowSet`** | `boolean` | | | ### SetCustomIdOptions | Prop | Type | | -------------- | -------- | | **`customId`** | `string` | ### BuiltinVersion | Prop | Type | | ------------- | -------- | | **`version`** | `string` | ### DeviceId | Prop | Type | | -------------- | -------- | | **`deviceId`** | `string` | ### PluginVersion | Prop | Type | | ------------- | -------- | | **`version`** | `string` | ### AutoUpdateEnabled | Prop | Type | | ------------- | --------- | | **`enabled`** | `boolean` | ### PluginListenerHandle | Prop | Type | | ------------ | --------------------- | | **`remove`** | `() => Promise` | ### DownloadEvent | Prop | Type | Description | Since | | ------------- | ------------ | ------------------------------------------- | ----- | | **`percent`** | `number` | Estado actual de la descarga, entre 0 y 100 | 400 | | **`bundle`** | `BundleInfo` | | | ### NoNeedEvent | Prop | Type | Description | Since | | ------------ | ------------ | ------------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Estado actual de la descarga, entre 0 y 100 | 400 | ### UpdateAvailableEvent | Prop | Type | Description | Since | | ------------ | ------------ | ------------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Estado actual de la descarga, entre 0 y 100 | 400 | ### DownloadCompleteEvent | Prop | Type | Description | Since | | ------------ | ------------ | ------------------------------------------------------ | ----- | | **`bundle`** | `BundleInfo` | Se emite cuando hay una nueva actualización disponible | 400 | ### MajorAvailableEvent | Prop | Type | Description | Since | | ------------- | -------- | --------------------------------------------------------- | ----- | | **`version`** | `string` | Se emite cuando hay un nuevo paquete principal disponible | 400 | ### UpdateFailedEvent | Prop | Type | Description | Since | | ------------ | ------------ | ----------------------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Se emite cuando una actualización falla al instalarse | 400 | ### DownloadFailedEvent | Prop | Type | Description | Since | | ------------- | -------- | ---------------------------------- | ----- | | **`version`** | `string` | Se emite cuando falla una descarga | 400 | ### AppReadyEvent | Prop | Type | Description | Since | | ------------ | ------------ | -------------------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Se emite cuando la aplicación está lista para usar | 520 | | **`status`** | `string` | | | ### AutoUpdateAvailable | Prop | Type | | --------------- | --------- | | **`available`** | `boolean` | ## Type Aliases ### BundleStatus `‘success’ | ‘error’ | ‘pending’ | ‘downloading’` ### DelayUntilNext `‘background’ | ‘kill’ | ‘nativeVersion’ | ‘date’` # Auto actualización > Cómo utilizar la actualización automática con capacitor-updater Este modo permite a los desarrolladores utilizar capacitor-updater con modo de actualización automática y enviar actualizaciones a través de canales Capgo o equivalentes ### Prerrequisitos Asegúrate de que la versión de tu aplicación use antes de usar la actualización automática de Capgo Esta es la convención que utiliza para gestionar versiones en Capgo Hay dos formas de establecer la versión en tu aplicación: Nueva forma: Usa el campo `version` en tu archivo `capacitor.config.json` ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true, // Habilitar actualización automática, true por defecto "appId": "com.example.app", // Usado para identificar la app en el servidor "version": "1.0.0" // Usado para verificar actualizaciones } } } ``` Estas opciones serán utilizadas por el plugin para verificar actualizaciones y por la CLI para subir la versión Forma antigua: En 3 archivos en tu proyecto: * `package.json` en **version** * `android/app/build.gradle` en **versionName** * `ios/App/App.xcodeproj/project.pbxproj` en **CURRENT\_PROJECT\_VERSION** ### Tutoriales Configura tu app en 5 minutos [Actualiza tus apps de capacitor sin problemas usando capacitor updater](https://capgo.app/blog/update-your-capacitor-apps-seamlessly-using-capacitor-updater) Configura tu CI en 5 minutos [Construcción y publicación automática con GitHub actions](https://capgo.app/blog/automatic-build-and-release-with-github-actions) ### Instalación ```bash npm install @capgo/capacitor-updater npx cap sync ``` ### Introducción Haz clic en [registro](https://capgo.app) para crear tu cuenta El servidor te permite gestionar canales, versiones y mucho más `autoUpdate` utilizará datos de `capacitor.config` para identificar el servidor Capgo Note Aún puedes usar Capgo Cloud sin enviar tu código a nuestro servidor si tu empresa no lo permite #### Validar versión Cuando la actualización automática está configurada, debes notificar desde JS que tu app está activa y lista Esto se puede hacer llamando `notifyAppReady` dentro de tu app Hazlo tan pronto como sea posible ```ts import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdater.notifyAppReady() ``` #### Flujo de usuario * El usuario abre la app, la app consulta al servidor por actualizaciones, si se encuentra alguna se descargará en segundo plano * El usuario sale de la app, la nueva versión se establece como activa * El usuario abre la app nuevamente, cargamos la nueva versión activa y la establecemos como predeterminada * Si se llama a `notifyAppReady()`, cuando el usuario sale de la app, la versión anterior se elimina * El usuario continúa el flujo normal de la app hasta el siguiente ciclo de actualización Danger ⚠️ No llamar a `notifyAppReady()` en tu app, hará que la versión actual se marque como inválida y volverá al último paquete válido o al original #### Flujo de desarrollo Cuando desarrolles nuevas funciones, asegúrate de bloquear `autoUpdate`, ya que capgo sobrescribirá constantemente tu trabajo con el último paquete de actualización Establece `autoUpdate` en false en tu configuración Si por alguna razón te quedas atascado en una actualización, puedes eliminar la app y reinstalarla Asegúrate de establecer `autoUpdate` en false en tu configuración antes de hacerlo Y luego compílala nuevamente con Xcode o Android studio Para subir la versión en cada commit configura CI/CD con esta guía [Construcción y publicación automática con GitHub actions](https://capgo.app/blog/automatic-build-and-release-with-github-actions) #### Evento Major Available Cuando `disableAutoUpdateBreaking` está establecido en true, puedes escuchar el evento para saber cuándo la app rechaza hacer una actualización mayor ```jsx import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdater.addListener('majorAvailable', (info: any) => { console.log('majorAvailable was fired', info.version) }) ``` # チャネルシステム > Cómo utilizar el sistema de canales con capacitor-updater Capgo y capacitor-updater vienen con un poderoso sistema de canales ## Qué puedes hacer con los canales: * Asociar dispositivos a canales para desarrollo, pruebas beta * Usar un canal por rama de desarrollo y permitir que tu equipo se auto-asigne desde el teléfono para pruebas ## Asignando dispositivos a un canal: * Hacer el canal predeterminado, cada vez que un nuevo dispositivo solicite una actualización a Capgo este canal responderá * Enviar el **deviceId** (con el método [**getDeviceId**](/docs/plugin/api#getdeviceid)) a tu backend y asignarlo con la API pública de Capgo * Hacer el canal auto-asignable (con el método [**setChannel**](/docs/plugin/api#setchannel)), y dejar que el dispositivo se suscriba al canal (con o sin interacción del usuario) con el método `setChannel` del plugin * Usar la opción `defaultChannel` en la [configuración](/docs/plugin/settings#defaultchannel) para establecer el canal predeterminado para todos los dispositivos con esta configuración del plugin Note También puedes asignar un dispositivo directamente a un paquete ## Opciones de canal ![](/channel_setting_1.webp) Detalles de cada opción: | Opción | Descripción | | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------- | | **Deshabilitar auto degradación bajo nativo** | No enviar una actualización si la versión nativa de la app es mayor que la del canal | | **Deshabilitar auto actualización sobre major** | No enviar una actualización si la versión nativa de la app es menor que un Major (**1**23) del canal | | **Deshabilitar auto actualización sobre minor** | No enviar una actualización si la versión nativa de la app es menor que un minor (1**2**3) del canal | | **Permitir auto-asignación del dispositivo** | Permitir que un dispositivo use el método `setChannel` para este canal | | **IOS** | Permitir que dispositivos iOS descarguen actualizaciones de este canal | | **Android** | Permitir que dispositivos Android descarguen actualizaciones de este canal | | **Permitir Emulador** | Permitir que los emuladores reciban actualizaciones de este canal | | **Permitir compilación de desarrollo** | Permitir que las compilaciones de desarrollo reciban actualizaciones de este canal | Note Capgo realiza algunos filtrados automáticos por ti. Si tienes un CI/CD configurado para enviar tu versión a Google Play, Google Play ejecutará tu app cada vez en más de 20 dispositivos reales. Durante las primeras 4 horas de un nuevo paquete, bloquearemos las IPs del centro de datos de Google para evitar que se contabilicen en tus estadísticas Note Capgo **no** cuenta los emuladores y compilaciones de desarrollo en tu uso, pero ten en cuenta que no puedes tener más del 3% de ellos, o tu cuenta será bloqueada hasta que lo soluciones # はじめに > Instala el plugin en tu app ## Introducción a Capgo [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## Las actualizaciones en vivo están a 3 pasos de distancia ### Crea tu cuenta Visita nuestra página de registro en ![captura de pantalla de incorporación](/onboard.webp "captura de pantalla de incorporación") ### Instala Capgo con la CLI Usa los comandos mágicos para comenzar ```bash npx @capgo/cli@latest init [APIKEY] ``` Este comando te guiará a través del proceso de configuración ### Simplemente sigue las indicaciones En la CLI, se te presentarán una serie de preguntas. Proporciona las respuestas necesarias para completar la configuración automatizada Tip Siguiendo estos pasos, estarás listo en poco tiempo. Si necesitas ayuda adicional durante el proceso, nuestro equipo de soporte está aquí para ayudarte. ¡Feliz incorporación! ### ¡Disfruta la magia de Capgo! Prueba tu aplicación y aprende más adelante cómo usar las funciones avanzadas de Capgo # Actualización híbrida > Métodos de actualización para actualizaciones automáticas Al enviar actualizaciones a tu usuario, tienes varias formas de manejar el ciclo de actualización según consideres conveniente antes de aplicarlas: * Actualización silenciosa * Escuchar el evento `updateAvailable` * Mostrar una ventana modal o retrasar actualizaciones ## Actualización silenciosa Puedes forzar que ocurra un ciclo de actualización en cada inicio de la aplicación configurando `directUpdate` como `true`, esto activará el ciclo de actualización como de costumbre sin la interacción del usuario ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "directUpdate": true, }, "SplashScreen": { "launchAutoHide": false, } } } ``` Y luego en tu aplicación, debes ocultar la pantalla de inicio cuando recibas el evento `appReady`: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' CapacitorUpdateraddListener('appReady', () => { // Hide splash SplashScreenhide() }) CapacitorUpdaternotifyAppReady() ``` ## Forzar actualización Agrega un listener al evento `updateAvailable` y luego muestra una alerta para informar al usuario que la aplicación se actualizará: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { Dialog } from '@capacitor/dialog' CapacitorUpdateraddListener('updateAvailable', async (res) => { try { await Dialogalert({ title: 'Actualización Disponible', message: `La versión ${resbundleversion} está disponible. La aplicación se actualizará ahora`, }) CapacitorUpdaterset(resbundle) } catch (error) { consolelog(error) } }) CapacitorUpdaternotifyAppReady() ``` ## Actualización modal También puedes dejar que el usuario decida mostrando un diálogo para preguntarles si desean actualizar: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { Dialog } from '@capacitor/dialog' CapacitorUpdateraddListener('updateAvailable', async (res) => { try { const { value } = await Dialogconfirm({ title: 'Actualización Disponible', message: `La versión ${resbundleversion} está disponible. ¿Te gustaría actualizar ahora?`, }) if (value) CapacitorUpdaterset(resbundle) } catch (error) { consolelog(error) } }) CapacitorUpdaternotifyAppReady() ``` # Actualización Manual > Cómo gestionar las actualizaciones de aplicaciones Si deseas gestionar por ti mismo cuándo se aplican las actualizaciones, utiliza el modo manual con Capgo cloud Esto es lo que necesitas hacer, configura tu cuenta como se explica en Comenzar [Comenzar ](/docs/getting-started/quickstart/) #### Configuración Desactiva la actualización automática en tu `capacitor.config.json` ```tsx // capacitor.config.json { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` Luego agrega la lógica para manejar las actualizaciones por ti mismo\ Aquí hay un ejemplo de cómo puedes hacerlo: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater' import type { BundleInfo } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' CapacitorUpdater.notifyAppReady() let data: BundleInfo | null = null App.addListener('appStateChange', async (state: any) => { console.log('appStateChange', state) if (state.isActive) { console.log('getLatest') // Realiza la descarga durante el tiempo activo de la aplicación para evitar descargas fallidas const latest = await CapacitorUpdater.getLatest() console.log('latest', latest) if (latest.url) { data = await CapacitorUpdater.download(latest) console.log('download', data) } } if (!state.isActive && data) { console.log('set') // Realiza el cambio cuando el usuario abandona la aplicación o cuando lo desees SplashScreen.show() try { await CapacitorUpdater.set({ id: data.id }) } catch (err) { console.log(err) SplashScreen.hide() // en caso de que falle el set, de lo contrario la nueva aplicación tendrá que ocultarlo } } }) ``` Documentación de todas las API disponibles en el plugin: [Métodos ](/docs/plugin/api/) Hay algunos casos de uso en los que puedes permitir que los usuarios se suscriban a canales y prueben diferentes versiones:\ # Cordova > ¿Estará capacitor-updater disponible en Cordova? Te has estado preguntando si este plugin estará disponible alguna vez para Cordova He comenzado un repositorio de I+D para eso, pero es una gran cantidad de trabajo ## Problemas Sé que puedo hacerlo pero para eso, tengo que leer todo el código base de Cordova como lo hice para Capacitor, para entender cómo hacerlo funcionar La versión de Android es más fácil de hacer ya que ambos usan Java, pero iOS necesita una reescritura completa porque Swift todavía no está bien soportado en Cordova ## Solución Mientras tanto, esto es lo que puedes hacer: * [Apóyame](https://github.com/sponsors/riderx) en GitHub y puedo darle prioridad a eso. Esto necesitará al menos 1 mes de trabajo * Contrátame como Consultor, solía ayudar a grandes empresas a migrar a Capacitor, normalmente toma \~10-20 días, y el [beneficio](https://ionicio/resources/articles/capacitor-vs-cordova-modern-hybrid-app-development) es enorme para el equipo # Depuración > Cómo depurar tu aplicación ## Entendiendo los registros en la nube: ### Enviados desde el backend | código | Descripción | | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **InvalidIp** | El usuario está ubicado en un centro de datos de Google y la actualización tiene menos de 4 horas. Esto se hace para evitar que los dispositivos de los bots de Google se cuenten como dispositivos en tu cuenta | | **needPlanUpgrade** (anteriormente **needUpgrade**) | Indica que has alcanzado el límite de tu plan, y el dispositivo no recibirá actualizaciones hasta que actualices o hasta el próximo mes | | **noNew** | El dispositivo tiene la última versión disponible | | **disablePlatformIos** | El dispositivo está en la plataforma iOS, pero está deshabilitado en la configuración del canal | | **disablePlatformAndroid** | El dispositivo está en la plataforma Android, pero está deshabilitado en la configuración del canal | | **disableAutoUpdate** | ”major" | | **disableAutoUpdateUnderNative** | El dispositivo tiene la versión (`123`), y el canal tiene una actualización (`122`) por debajo de la versión del dispositivo para enviar, pero está deshabilitado en la configuración del canal | | **disableDevBuild** | El dispositivo tiene una compilación de desarrollo, pero está deshabilitado en la configuración del canal | | **disableEmulator** | El dispositivo es un emulador, pero está deshabilitado en la configuración del canal | ### Enviados desde el dispositivo | código | Descripción | | ------------------------- | ------------------------------------------------------------------------------------ | | **get** | La información para descargar la nueva versión ha sido enviada al dispositivo | | **delete** | Un paquete ha sido eliminado en el dispositivo | | **set** | Un paquete ha sido establecido en el dispositivo | | **set\_fail** | El paquete falló al establecerse | | **reset** | El dispositivo se reinició al paquete `builtin` | | **download\_XX** | Un nuevo paquete ha sido descargado - progreso indicado por XX% (incrementos de 10%) | | **download\_complete** | La descarga del nuevo paquete ha finalizado | | **download\_fail** | El nuevo paquete falló al descargar | | **update\_fail** | El nuevo paquete ha sido instalado pero falló al llamar a `notifyAppReady` | | **checksum\_fail** | El nuevo paquete falló al validar el checksum | | **windows\_path\_fail** | El zip tiene archivos que contienen rutas de Windows que son ilegales | | **canonical\_path\_fail** | La ruta de los archivos no es canónica | | **directory\_path\_fail** | Hay un error en la ruta de los archivos zip | | **unzip\_fail** | La descompresión falló | | **low\_mem\_fail** | La descarga falló debido a memoria baja en el dispositivo | ### Estado del paquete * `SUCCESS`: instalación del paquete completada * `ERROR`: instalación o descarga fallida * `PENDING`: Descarga completada, pendiente de liberación * `DELETED`: Paquete eliminado, aún se muestra para estadísticas * `DOWNLOADING`: Actualmente descargando un paquete ## Entendiendo los registros del dispositivo: ### Comando de depuración: Hay un comando de depuración para usuarios de Capgo cloud ```bash npx @capgo/cli@latest app debug ``` Esto te permitirá verificar todos los eventos que ocurren en la aplicación y encontrar una solución si las actualizaciones no ocurren ### IOS para encontrar tus registros en Xcode [Getting the Device Log in Xcode ](https://intercomhelp/deploygate/en/articles/4682692-getting-the-device-log-in-xcode) ### Android: para encontrar tus registros en Android studio [View logs with Logcat ](https://developerandroidcom/studio/debug/am-logcat) ### Explicaciones de Registros * `Failed to download from` **=>** igual que **download\_fail** * `notifyAppReady was not called, roll back current bundle` => igual que **update\_fail** ## Encontrando el paquete descargado en tu dispositivo ### iOS Para depurar en iOS, necesitas volcar la aplicación en tu computadora, puedes hacerlo así: Xcode tiene una función incorporada para inspeccionar el sistema de archivos de aplicaciones instaladas por desarrolladores en un dispositivo iOS Para lograr esto: * Conecta tu dispositivo a tu Mac y selecciona Window > Devices en la barra de menú de Xcode * Selecciona tu dispositivo en el panel izquierdo bajo la sección Devices * Esto mostrará una lista de aplicaciones instaladas por desarrolladores para ese dispositivo * Selecciona la aplicación que deseas inspeccionar y luego selecciona el ícono de engranaje cerca de la parte inferior de la pantalla * Aquí puedes ver el sistema de archivos actual seleccionando Show Container o descargar una instantánea del mismo Seleccionar Download Container descargará y exportará una instantánea del sistema de archivos como un archivo xcappdata que puedes navegar Haz clic derecho en este archivo y selecciona Show Package Contents para abrir la carpeta Abre la carpeta App Data, y ahora deberías ver algunas carpetas como Documents, Library, tmp, etc ![image](/ios_debug_update_1.webp) Luego encontrarás una versión en 2 carpetas: `library/NoCloud/ionic_built_snapshots` es necesario después del reinicio de la aplicación y `documents/versions` para recarga en caliente ### Android Para depurar en Android, necesitas acceder al dispositivo desde Android Studio: * Haz clic en View > Tool Windows > Device File Explorer o haz clic en el botón Device File Explorer en la barra de herramientas para abrir el Device File Explorer * Selecciona un dispositivo de la lista desplegable * Abre la ruta **data/data/APP\_NAME/** donde **APP\_NAME es el ID de tu aplicación** ![image](/android_debug_update.webp) Luego encuentra la carpeta `versions` para ver todas las versiones ¿Sabías que? En Android, todas las versiones se almacenan en una carpeta, a diferencia de iOS donde tiene que duplicarse en dos ubicaciones ## Entendiendo los registros de fallos de producción en iOS [How to review your app's crash logs ](https://developer.apple.com/news/?id=nra79npr) # Nuxt 2 > Cómo instalar el plugin en Nuxt 2 # Instalar en Nuxt 2 Crea un archivo de plugin `capacitor-updaterjs` en el directorio `plugins` ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' export default ({ app }) => { if (processclient) { windowonNuxtReady(() => { CapacitorUpdaternotifyAppReady() }) } } ``` Esto cargará el plugin del lado del cliente y notificará a la aplicación que está lista para recibir actualizaciones # Problemas conocidos > Problemas conocidos con Capacitor y CapGo ## Recarga en vivo de Ionic * Cuando desarrolles, si usas la función de recarga en vivo de Ionic desde la CLI, anulará el plugin, por lo que nunca verás tu actualización ## Recarga en vivo de Quasar * Utiliza el mismo sistema que Ionic internamente, por lo que no verás tus actualizaciones ## Fallos en actualizaciones * Esto suele ocurrir cuando se envían grandes actualizaciones (> 20mb), un gran porcentaje de usuarios no obtendrá la última versión En el pasado, los usuarios necesitaban mantener la aplicación abierta hasta que la descarga se completara, ahora usamos descarga en segundo plano, pero aún está limitada a unos pocos segundos ## Android ### No se puede descargar Hemos visto algunos problemas con dispositivos en India, y al contactar con usuarios, les hicimos probar diferentes servidores DNS, y funcionó Así que si tienes el problema, intenta usar un servidor DNS diferente como Cloudflare o Google DNS Cloudflare: 1111 y 1001 Google DNS: 8888 y 8844 o dnsgoogle [¿Cómo configurar un servidor DNS preferido en Android? ](https://wwwandroidpolicecom/use-preferred-dns-server-android-tutorial/) ### Auto-alojado Cuando estás enviando una actualización auto-alojada, ten en cuenta que no puedes usar endpoints “HTTP” ya que va contra las políticas de seguridad de las aplicaciones Android, si aún quieres hacerlo, sigue esta guía: [¿Cómo permitir todos los tipos de conexión de red HTTP y HTTPS en Android (9) Pie? ](https://stackoverflow.com/a/51902630/5511370) ### Descompresión Problema de descompresión: Las entradas DEFLATED pueden tener descriptor EXT Si comprimiste tu paquete con algo diferente a la CLI, el formato de tu zip podría ser incorrecto, por favor usa el comando CLI `npx @capgo/cli zip BUNDLE_FOLDER` Este es un problema conocido de Java: [Problema de descompresión: Las entradas DEFLATED pueden tener descriptor EXT ](https://bugsopenjdkorg/browse/JDK-8143613) ### Problema de Clearfix * Si tienes problemas con usesCleartextTraffic, es porque el plugin sigue las buenas prácticas recomendadas por sonar cloud, en el 90% de los casos funcionará bien, pero con algunos plugins causa problemas Para solucionarlo, agrega en `android/app/src/main/AndroidManifestxml` en la clave ``: ```xml tools:replace="android:usesCleartextTraffic" xmlns:tools="http://schemasandroidcom/tools" ``` ## iOS ### Manifiesto de privacidad Agrega la clave de diccionario `NSPrivacyAccessedAPICategoryUserDefaults` a tu [Manifiesto de Privacidad](https://capacitorjs.com/docs/ios/privacy-manifest) (normalmente `ios/App/PrivacyInfoxcprivacy`): ```xml NSPrivacyAccessedAPITypes NSPrivacyAccessedAPIType NSPrivacyAccessedAPICategoryUserDefaults NSPrivacyAccessedAPITypeReasons CA921 ``` Recomendamos declarar [`CA921`](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278401) como razón para acceder a la API [`UserDefaults`](https://developer.apple.com/documentation/foundation/userdefaults) ### Permisos de red Cuando uses un servidor local para probar actualizaciones, la aplicación pedirá permisos de red, es un comportamiento normal, no sucede cuando usas un servidor remoto ## Ambos sistemas operativos Cuando se realizan actualizaciones en modo manual, algunos eventos no son fáciles de capturar, por ejemplo, el fallo de actualización se dispara justo antes de que tu código JS se recargue, por lo que no podrás capturarlo Una alternativa es listar los paquetes y verificar las estadísticas de error para saber si la actualización falló Necesitamos encontrar una mejor manera de manejar esto en el futuro, pero no es una prioridad, ya que el modo automático es la forma recomendada de hacer actualizaciones Los PRs son bienvenidos para ayudarnos a mejorar esto ## CLI si tu CLI tiene problemas haciendo cualquier cosa, Verifica si **appId** y **appName** están presentes en tu **capacitorconfigts** Sigue la guía de la documentación oficial: [Configuración de Capacitor ](https://capacitorjs.com/docs/config) # Visión General > Explicación de los dos enfoques diferentes ### Modo Cloud (Recomendado) El Modo Cloud es nuestra opción recomendada para una gestión de actualizaciones sin complicaciones. El backend de Capgo se encarga de toda la lógica de actualización, tomando decisiones sobre las actualizaciones del lado del servidor para una mejor seguridad y control. Este modo se centra en la facilidad de uso: una vez configurado, funciona sin problemas por sí solo, ofreciendo funciones avanzadas como estadísticas y canales. También se puede configurar en modo manual, lo que te da más control, permitiéndote decidir cuándo actualizar usando tu código JavaScript. El backend sigue gestionando qué se actualiza. Este modo comparte muchos beneficios con el Modo Auto, especialmente en seguridad y funciones avanzadas, pero añade la flexibilidad de programar las actualizaciones tú mismo. ### Modo Auto-Hospedado El Modo Auto-Hospedado es para aquellos que quieren manejar toda la lógica de actualización en su propio servidor. Ofrece completa autonomía pero requiere un servidor separado y más trabajo para gestionar las actualizaciones y los requisitos del servidor. El Modo Manual Auto-Hospedado combina control y autonomía. Tú decides cuándo actualizar a través de JavaScript, pero tu servidor maneja qué se actualiza. Es un poco complejo ya que estás incluyendo código de actualización en las actualizaciones. Note Si eliges auto-hospedar te perderás todas las excelentes funciones que ofrece Capgo cloud como: reversiones automáticas, alertas por correo electrónico, canales, estadísticas, cifrado y más Danger Si envías una actualización defectuosa a tus usuarios puedes y vas a romper su aplicación # Actualización Automática > Cómo usar el plugin de actualización automática en modo auto-alojado Esta documentación explicará cómo ejecutar tu servidor de actualización automática ## Servir tu paquete Asegúrate de que tu paquete se sirva a través de HTTPS, y que el servidor tenga los encabezados CORS correctos para permitir que la aplicación descargue la actualización ej. `https://myservercom/app/updates/updatesjson` Si no estás familiarizado con servir un paquete, te recomendamos que pruebes Capgo Cloud o veas un ejemplo aquí: [Servir un Paquete ](/docs/self-hosted/auto-update/update-endpoint) ## Configuración Añade una `updateUrl` a tu `capacitorconfigjson` ```json { "plugins": { "CapacitorUpdater": { "updateUrl": "https://myservercom/app/updates/updatesjson", } } } ``` Caution Cuando estés publicando una actualización auto-alojada, ten en cuenta que no puedes usar endpoints “HTTP” ya que va en contra de las políticas de seguridad de las aplicaciones Android, para fines de prueba puedes [permitirlo](https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted) ## API de Actualización El plugin realizará una llamada POST a tu API cada vez que se abra la aplicación, con este cuerpo: ```typescript interface AppInfos { "platform": "ios" | "android", "device_id": "UUID_of_device_unique_by_install", "app_id": "APPID_FROM_CAPACITOR_CONFIG", "custom_id": "your_custom_id_set_on_runtime", "plugin_version": "PLUGIN_VERSION", "version_build": "VERSION_NUMBER_FROM_NATIVE_CODE", "version_code": "VERSION_CODE_FROM_NATIVE_CODE", "version_name": "LAST_DOWNLOADER_VERSION" | "builtin" "version_os": "VERSION_OF_SYSYEM_OS", "is_emulator": boolean, "is_prod": boolean, } ``` El servidor API debe responder, en JSON, al plugin capacitor-updater con estos datos si una actualización es necesaria: ```json { "version": "123", "url": "https://myservercom/app/updates/my-new-app-200zip" } ``` En modo de actualización automática, el servidor debe comparar las versiones y devolver la correcta, si la clave URL está presente, el plugin inicia el proceso de descarga Si agregas las claves “message” y “error”, la versión no se establecerá y el mensaje se mostrará en los registros en su lugar La clave `version` debe estar en formato [`semver`](https://semverorg/) El zip debe tener `indexhtml` como archivo en la raíz, o solo una carpeta en la raíz con `indexhtml` dentro Puedes usar el comando de la CLI para comprimir tu paquete: Crear un paquete con tus archivos para servir desde tu servidor ```bash npx @capgo/cli bundle zip --path [/path/to/my/bundle] ``` # Contribuer > Contribuir a los proyectos de código abierto de capgo ## ¿Por qué contribuir? En primer lugar, ¡gracias por considerar contribuir a los proyectos de código abierto de capgo! Es gente como tú la que hace que los proyectos de código abierto de capgo sean herramientas tan excelentes. Aquí hay algunas razones por las que podrías considerar contribuir: * Contribuir a los proyectos de código abierto de capgo es una excelente manera de ganar dinero con las [numerosas recompensas](https://consolealgoraio/org/Capgo) que ofrece el equipo de capgo * Contribuir a los proyectos de código abierto de capgo es una excelente manera de agregar una función que te gustaría ver * Contribuir a los proyectos de código abierto de capgo es una excelente manera de corregir un error que encontraste * [La licencia principal de Capgo](https://github.com/Cap-go/capgo/blob/main/LICENSE) requiere que hagas de código abierto cualquier cambio que realices. Al contribuir con tu código, mantienes tus cambios en código abierto y permites que otros lo utilicen ## Cómo contribuir * En primer lugar, necesitas hacer un fork del repositorio al que quieres contribuir * En segundo lugar, necesitas confirmar y enviar tus cambios a ese repositorio * Por último, necesitas abrir una solicitud de extracción (pull request) * ¡Eso es todo! Ahora solo necesitas esperar a que el equipo de capgo revise tu PR ## Documentos adicionales para leer * [CONTRIBUTINGMD](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTINGmd) de Capgo * [BOUNTYmd](https://github.com/Cap-go/capgo/blob/main/BOUNTYmd) de Capgo # Bundle crittografati > Cómo usar el plugin de actualización manual en modo autohospedado ## Cifrado de extremo a extremo A partir de la versión 4150, el plugin permite enviar actualizaciones cifradas. Para comenzar, crea una clave privada Create a private key ```bash npx @capgo/cli key create ``` Luego cifra tu archivo zip Encrypt bundled zip ```bash npx @capgo/cli encrypt [path/to/zip] ``` El comando te mostrará un `ivSessionKey` que debe enviarse con la carga útil de tu actualización en la clave `session_key` ```json { "version": "123", "url": "https://myservercom/app/updates/my-new-app-200zip", "session_key": "encrypted_session_key", } ``` Entonces tu aplicación podrá usar la clave privada para descifrar el `session_key` y usar el `session_key` descifrado para descifrar la actualización Aprende más sobre esto aquí: [Actualizaciones en vivo auto-alojadas ](https://capgo.app/blog/self-hosted-live-updates/) # Primeros pasos > Cómo ejecutar tu propio servidor de actualización automática Esta documentación explicará cómo ejecutar tu propio servidor de actualización automática ## Introducción Si encuentras útil este trabajo, considera apoyar mi trabajo convirtiéndote en [patrocinador de Github](https://github.com/sponsors/riderx) Aposté por hacer de código abierto todo el código que construí aquí en lugar de ponerlo detrás de un muro de pago. Al abrirlo en lugar de luchar y ocultarlo, creo que podemos hacer del mundo un mejor lugar Además, quiero centrarme en las herramientas de Capgo y hacer que sea un negocio abierto y transparente Pero para hacerlo posible, es necesario que todos hagamos nuestra parte, incluyéndote a ti 🥹 Si Capgo no te conviene, entonces paga tu propio precio y [apoya a un Creador independiente](https://github.com/sponsors/riderx) en tus términos [Considera Contribuir ](/docs/plugin/self-hosted/contributing/) ## Paridad de características Si eliges usar tu propio servidor, perderás el flujo de configuración de 5 minutos\ Necesitarás implementar todas estas características por tu cuenta | Características | Capgo | Auto alojado | | ------------------------ | ----- | ------------ | | Actualizaciones | ✅ | 🚧 | | Auto reversión | ✅ | 🚧 | | Alertas por email | ✅ | 🚧 | | Canales | ✅ | 🚧 | | Anulación de canales | ✅ | 🚧 | | Anulación de dispositivo | ✅ | 🚧 | | Ajustes de canales | ✅ | 🚧 | | Ajustes de dispositivo | ✅ | 🚧 | | ID personalizado | ✅ | 🚧 | | Auto configurar canales | ✅ | 🚧 | | API de canales | ✅ | 🚧 | | Estadísticas de actualiz | ✅ | 🚧 | | Estadísticas de fallos | ✅ | 🚧 | | Estadísticas de uso | ✅ | 🚧 | | Cifrado de actualización | ✅ | 🚧 | Danger Si envías una actualización incorrecta a tus usuarios, puedes y romperás su aplicación > Ten en cuenta que no puedes usar la nube Capgo y tu servidor al mismo tiempo Danger La función de actualización Over-the-Air (OTA) solo es aplicable para modificaciones realizadas en archivos HTML, CSS y JavaScript Si realizas cambios en el código nativo, como actualizaciones de plugins de Capacitor, es obligatorio volver a enviar la aplicación a la tienda de aplicaciones para su aprobación ## Elige entre Auto y Manual En modo automático, parte de la lógica es manejada por el código nativo, las actualizaciones se deciden del lado del servidor, esto es más seguro y permite actualizaciones detalladas, despliegue parcial a un dispositivo o grupo y más En modo manual, toda la lógica es manejada por JS [Actualización Automática ](/docs/plugin/self-hosted/auto-update/) [Manual ](/docs/plugin/self-hosted/manual-update/) ## Instalar Capacitor updater Instalar el actualizador de Capacitor ```bash npm install @capgo/capacitor-updater npx cap sync ``` ## Prepara tu paquete Para enviar actualizaciones a tu aplicación, necesitas comprimirla en zip La mejor manera de asegurarte de que tu zip es correcto es usar el CLI de Capgo para comprimir Crear un paquete con tus archivos para servir desde tu servidor ```bash npx @capgo/cli@latest bundle zip ``` Tendrás que servir este zip desde tu servidor por tu cuenta [Actualización Automática ](/docs/plugin/self-hosted/auto-update/) [Manual ](/docs/plugin/self-hosted/manual-update/) Note Si esto parece mucho trabajo, prueba la versión de prueba de Capgo Cloud # 통계 처리 > Cómo crear un endpoint de estadísticas autohospedado Aquí hay un ejemplo de código en JavaScript para guardar las estadísticas del plugin ```typescript interface AppInfos { version_name: string action: 'delete' | 'reset' | 'set' | 'set_fail' | 'update_fail' | 'windows_path_fail' | 'canonical_path_fail' | 'directory_path_fail' | 'unzip_fail' | 'low_mem_fail' | 'download_fail' | 'update_fail' | 'download_10' | 'download_20' | 'download_30' | 'download_40' | 'download_50' | 'download_60' | 'download_70' | 'download_80' | 'download_90' | 'download_complete' version_build: string version_code: string version_os: string plugin_version: string platform: string app_id: string device_id: string custom_id?: string is_prod?: boolean is_emulator?: boolean } export const handler: Handler = async (event) => { const body = JSONparse(eventbody || '{}') as AppInfos const { platform, app_id, action, version_code, version_os, device_id, version_name, version_build, plugin_version, } = body consolelog('update asked', platform, app_id, action, version_os, version_code, device_id, version_name, version_build, plugin_version) // Guárdalo en tu base de datos return { status: 'ok' } } ``` Este endpoint debe devolver un JSON: ```json { "status": "ok" } ``` ## Acciones: * **delete**: cuando un paquete se elimina localmente * **reset**: cuando la aplicación se restablece al paquete incorporado * **set**: cuando la aplicación establece un nuevo paquete * **set\_fail**: cuando la aplicación no pudo encontrar el ID del paquete establecido * **update\_fail**: enviado después del retraso y `notifyAppReady` nunca fue llamado * **download\_fail**: cuando la descarga nunca terminó * **download\_complete:** Cuando la descarga finaliza * **download\_xx:** Enviado cada 10% de descarga ej: download\_20, download\_70 * **update\_fail:** cuando el paquete falla al ejecutar `notifyAppReady` en el plazo establecido # Manejo de Actualizaciones > Uso del complemento Auto Update en modo autohospedado Aquí hay un ejemplo de código en JavaScript para enviar una actualización al plugin ```typescript interface AppInfos { version_name: string version_build: string version_os: string custom_id?: string is_prod?: boolean is_emulator?: boolean plugin_version: string platform: string app_id: string device_id: string } export const handler: Handler = async (event) => { const body = JSONparse(eventbody || '{}') as AppInfos const { platform, app_id, version_os, device_id, version_name, version_build, plugin_version, } = body consolelog('update asked', platform, app_id, version_os, device_id, version_name, version_build, plugin_version) if (version_name === '100') { return { version: '101', url: 'https://apiurlcom/mybuild_101zip', } } else if (version_name === '101') { return { version: '102', url: 'https://apiurlcom/mybuild_102zip', } } else { return { message: 'Error version not found' version: '', url: '', } } } ``` Este endpoint debería devolver un JSON: ```json { "version": "102", "url": "https://apiurlcom/mybuild_102zip" } ``` Y si no hay actualización o hay un error, agregar la clave `message` y opcionalmente un `error` ```json { "message": "Version not found", "error": "The backend crashed", "version": "102", "url": "https://apiurlcom/mybuild_102zip" } ``` # Mise à jour manuelle > Cómo utilizar el plugin de actualización manual en modo autohospedado ## Configuración Añade esto a tu `capacitorconfigjson`, para deshabilitar la actualización automática ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false, } } } ``` ## Uso Puedes usar este ejemplo o recrear la lógica en tu aplicación Caution Estamos forzando al usuario a actualizar la aplicación con una versión estática declarada en el código. Esto no es recomendable, deberías usar una versión dinámica desde tu servidor Danger No estamos realizando ninguna verificación de versión, descifrado o validación de suma de comprobación en este ejemplo. Deberías hacer esto por tu cuenta ```tsx import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' let data = {version: ""} CapacitorUpdaternotifyAppReady() AppaddListener('appStateChange', async(state) => { if (stateisActive) { // Do the download during user active app time to prevent failed download data = await CapacitorUpdaterdownload({ version: '004', url: 'https://github.com/Cap-go/demo-app/releases/download/004/distzip', }) } if (!stateisActive && dataversion !== "") { // Do the switch when user leave app SplashScreenshow() try { await CapacitorUpdaterset(data) } catch (err) { consolelog(err) SplashScreenhide() // in case the set fail, otherwise the new app will have to hide it } } }) ``` Note Si esto parece mucho trabajo, considera probar [Capgo trial](https://capgo.app/register/) que manejará todo esto por ti # Ajustes > Todas las configuraciones disponibles para Capacitor Updater Para tener un control más preciso sobre el sistema de actualización, puedes configurarlo con estos ajustes: ## `appReadyTimeout` > Configura el número de milisegundos que el plugin nativo debe esperar antes de considerar una actualización como ‘fallida’ Solo disponible para Android e iOS Predeterminado: `10000` (10 segundos) ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 } } } ``` ## `responseTimeout` > Configura el número de milisegundos que el plugin nativo debe esperar antes de considerar un tiempo de espera de la API Solo disponible para Android e iOS Predeterminado: `20` (20 segundos) ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "responseTimeout": 1000 } } } ``` ## `autoDeleteFailed` > Configura si el plugin debe eliminar automáticamente los paquetes fallidos Solo disponible para Android e iOS Predeterminado: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoDeleteFailed": false } } } ``` ## `autoDeletePrevious` > Configura si el plugin debe eliminar automáticamente los paquetes anteriores después de una actualización exitosa Solo disponible para Android e iOS Predeterminado: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoDeletePrevious": false } } } ``` ## `autoUpdate` > Configura si el plugin debe usar la Actualización Automática a través de un servidor de actualización Solo disponible para Android e iOS Predeterminado: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` ## `updateUrl` > Configura la URL / endpoint al que se envían las comprobaciones de actualización Solo disponible para Android e iOS Predeterminado: `https://apicapgo.app/updates` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "updateUrl": "https://examplecom/api/updates" } } } ``` ## `statsUrl` > Configura la URL / endpoint al que se envían las estadísticas de actualización Solo disponible para Android e iOS. Establece como "" para deshabilitar el reporte de estadísticas Predeterminado: `https://apicapgo.app/stats` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "statsUrl": "https://examplecom/api/stats" } } } ``` ## `privateKey` > Configura la clave privada para el cifrado de actualizaciones en vivo de extremo a extremo Solo disponible para Android e iOS Crea la clave privada con el comando `npx @capgo/cli key create` Predeterminado: `undefined` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "privateKey": "YOUR_KEY" } } } ``` ## `directUpdate` > Hace que el plugin instale directamente la actualización cuando la aplicación se acaba de actualizar/instalar. Solo aplicable para el modo autoUpdate Solo disponible para Android e iOS Predeterminado: `undefined` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": true } } } ``` ## `resetWhenUpdate` Note Cuando ocurre una actualización de la tienda, deshabilita el reinicio forzado a la versión nativa Hay muchas más configuraciones disponibles solo en la [aplicación web](https://web.capgo.app/login) Para configurar el plugin, usa estos ajustes: ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } } ``` ## `directUpdate` Hace que el plugin instale directamente la actualización cuando la aplicación se acaba de actualizar/instalar. Solo aplicable para el modo autoUpdate Caution Esta configuración requiere que ocultes la aplicación del usuario mientras se instala la actualización. De lo contrario, la aplicación se reiniciará mientras el usuario está navegando ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": true } } } ``` ## `defaultChannel` Establece el canal predeterminado para la aplicación. Esto anulará cualquier otro canal establecido en Capgo si el canal permite sobrescribir ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "defaultChannel": "production" } } } ``` ## `appId` Establece el appId para la aplicación. Esto anulará cualquier otra forma de obtener el appId. Esto es útil cuando quieres tener un appId diferente en Capgo y en tu código nativo Note Esta es la nueva forma de establecer el appId. La forma antigua sigue y seguirá siendo compatible ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "AppId": "comexampleapp" } } } ``` ## `version` Establece la versión para la aplicación. Esto anulará cualquier otra forma de obtener la versión. Esto es útil cuando quieres tener una versión diferente en Capgo y en tu código nativo Note Esta es la nueva forma de establecer la versión. La forma antigua sigue y seguirá siendo compatible ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "version": "123" } } } ``` # 統計情報 API > Cómo usar el plugin de actualización automática en modo auto-hospedado ## API de Estadísticas ¡A partir de la versión 130, el sistema de actualización puede enviar estadísticas! Por defecto, todas las estadísticas se envían a nuestro servidor, para entender el uso e investigar Note No se envían datos privados para las estadísticas, solo UUID aleatorio, actualización de versión, versión de la aplicación nativa, plataforma, acción e ID de la aplicación Si deseas enviar estos datos a tu servidor en su lugar, cambia la configuración a continuación: ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "statsUrl": "TU_URL" } } } ``` Lo que tu servidor recibirá es: ```tsx interface AppInfosStats { "action": "set", // puede ser set, delete, set_fail, reset, revert // Luego es la misma información que la actualización "app_id": "*******", // identificador de la app en la tienda "device_id": "*******", // id único por instalación de app "platform": "ios", // o android "custom_id": "user_1", // representa tu usuario "version_name": "123", // versión del build web "version_build": "120", // versión del build nativo "version_code": "120", // número de build de la versión nativa "version_os": "16", // versión del SO del dispositivo "plugin_version": "400"// para que tu api se comporte diferente con diferentes plugins "is_emulator": false, "is_prod": false, } ``` También puedes desactivarlo completamente, con una cadena vacía. Ten en cuenta que las estadísticas están hechas de manera amigable con la privacidad y me ayudan a entender cómo la gente usa el plugin, para resolver problemas y mejorarlo [Manejo de Actualizaciones ](/docs/plugin/self-hosted/handling-updates/) # Migrar de AppFlow a Capgo > Guía completa para migrar tu aplicación de Ionic AppFlow a Capgo ## Referencia de Configuración de AppFlow Antes de migrar, anota tu configuración actual de AppFlow en `capacitor.config.ts`: ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { LiveUpdates: { appId: 'your-app-id', channel: 'Production', autoUpdateMethod: 'background', // o 'always latest', 'force update' maxVersions: 2 } } }; ``` Esta configuración te ayudará a mapear las características de AppFlow a sus equivalentes en Capgo. ## ¿Por qué migrar a Capgo? Con el anuncio del cierre de Ionic AppFlow, migrar a Capgo ofrece una transición perfecta para tu flujo de trabajo de desarrollo de aplicaciones móviles. Capgo ofrece características mejoradas, mejor rendimiento y ahorros significativos en costos mientras mantiene toda la funcionalidad crítica que necesitas. ### Beneficios Principales * Entrega de actualizaciones más rápida (< 1 minuto vs 10 minutos) * Precios más asequibles ($14/mes vs $499/mes) * Cifrado de extremo a extremo incluido en todos los planes * Mayor control sobre los canales de actualización * Opciones completas de integración CI/CD ## Pasos de Migración ### 1. Migración de Actualizaciones en Vivo #### Eliminar Dependencias Anteriores ```bash npm uninstall @ionic/appflow # Eliminar configuraciones específicas de AppFlow de capacitor.config.json ``` #### Instalar Capgo ```bash npm install @capgo/capacitor-updater npx cap sync ``` #### Actualizar Configuración Agrega la configuración de Capgo a tu `capacitor.config.json`: ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true } } } ``` ### 2. Migración CI/CD Capgo ofrece opciones flexibles de CI/CD: #### Opción 1: Usa tu CI/CD Existente Sigue nuestros tutoriales detallados para configurar CI/CD con plataformas populares: * [Configuración de Build iOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) * [Configuración de Build Android](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) * [Integración con GitHub Actions](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) #### Opción 2: CI/CD Gestionado Deja que nosotros manejemos tu configuración CI/CD con nuestro [servicio gestionado](https://cal.com/team/capgo/mobile-ci-cd-done-for-you). ### 3. Configuración de Canales 1. Crear canales en el dashboard de Capgo: ```bash npx @capgo/cli channel create production npx @capgo/cli channel create staging ``` 2. Configurar ajustes de canales: ```bash # Configurar canal de producción npx @capgo/cli channel update production --no-downgrade --no-upgrade # Configurar canal de staging npx @capgo/cli channel update staging ``` ### 4. Prueba de la Migración 1. **Probar Actualizaciones en Vivo** ```bash # Crear y subir un bundle de prueba npx @capgo/cli bundle create --channel staging ``` 2. **Verificar Recepción de Actualizaciones** * Instalar la aplicación en un dispositivo de prueba * Verificar que las actualizaciones se reciben correctamente * Verificar el proceso de instalación de actualizaciones * Probar la funcionalidad de recuperación 3. **Validar Pipeline CI/CD** * Realizar un commit de prueba * Verificar proceso de build * Comprobar despliegue automático * Confirmar asignación de canales ## Solución de Problemas ### Problemas Comunes #### Actualizaciones No Recibidas * Verificar configuración de canales * Revisar logs del dispositivo * Asegurar conectividad de red adecuada * Validar formato de versión del bundle #### Problemas de Pipeline de Build * Verificar configuración de GitHub Actions * Comprobar certificados de firma * Validar variables de entorno * Revisar logs de build #### Conflictos de Versión * Verificar numeración de versiones * Comprobar restricciones de canales * Revisar condiciones de actualización ## Siguientes Pasos 1. [Crear una cuenta Capgo](/register/) 2. Seguir nuestra [guía de inicio rápido](/docs/getting-started/quickstart/) 3. Configurar [integración CI/CD](/docs/getting-started/cicd-integration/) 4. Configurar [actualizaciones en vivo](/docs/live-updates/) Para equipos empresariales que requieren soporte dedicado durante la migración, [programa una llamada con nuestro equipo](https://cal.com/team/capgo/capgo-enterprise-inquiry). Recuerda probar exhaustivamente en un entorno de staging antes de desplegar a producción. Nuestro equipo de soporte está disponible para ayudarte si encuentras algún problema durante la migración. # V2에서 V3로 > Cómo actualizar de V2 a V3 Esta documentación explicará cómo actualizar a la versión 3 de auto-update ## Primero migrar a las últimas herramientas: ```bash npm remove -g capgo npm remove capacitor-updater npm i @capgo/cli npm i @capgo/capacitor-updater@3 npx cap sync ``` ## Eliminar toda tu configuración anterior: ```json { CapacitorUpdater: { autoUpdateURL: "https", }, } ``` para dejar solo esto: ```json { "CapacitorUpdater": { "autoUpdate": true } } ``` > ⚠️ Si estabas usando tu servidor con `autoUpdateURL`, actualizaré esta guía pronto. Mientras tanto, echa un vistazo a la nueva opción de carga `external` que te permite enviar solo el enlace de tu zip, no el código en Capgo cloud. Esto se ha hecho para empresas con políticas de privacidad estrictas. En modo externo, el código nunca llegará al servidor de Capgo, solo almacenamos la URL y la enviamos al dispositivo, que la descargará directamente. En la forma estándar, el código se comprime y se almacena en nuestro servidor, pero nunca lo abriremos ni lo usaremos tampoco. ## Qué cambia Todas las configuraciones se vuelven del lado del servidor para auto-update, para darte más control sobre cómo envías una actualización a los usuarios Esto nos permite revertir, incluso desplegar solo a un usuario con canales. Estas configuraciones se agregan de nuevo a la interfaz web: * deshabilitar revertir bajo nativo * deshabilitar actualización por encima de major > ⚠️ Se volverán verdaderos por defecto para todos los canales Esto también eliminará la necesidad de actualizar frecuentemente el plugin, la mayoría de las actualizaciones se realizarán del lado del servidor, y las obtendrás sin ningún cambio de tu parte > ⚠️ Reinicio cuando una actualización se convierte en predeterminada, así que si prefieres no eliminar todas las versiones descargadas al actualizar desde la tienda, haz esto: ```json { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } ``` ## Actualiza tu código Por último, actualiza todas tus importaciones en JS de: ```plaintext import { CapacitorUpdater } from 'capacitor-updater' ``` a ```plaintext import { CapacitorUpdater } from '@capgo/capacitor-updater' ``` Luego compila tu código nuevamente `npm run build` y copia los assets una vez más `npx cap copy` Ahora deberías poder probar el último sistema de auto-update Envía tu versión con: ```plaintext npx @capgo/cli@latest bundle upload ``` en lugar de ```plaintext npx capgo upload ``` ## Evolución futura Por ahora solo se usa el primer canal público, en el futuro, público cambiará para múltiples canales públicos, si se configura más de uno ## Problemas comunes: * Problema de compilación después de actualizar: si ya has abierto el código fuente del plugin en Android Studio o Xcode, a veces la sincronización no los elimina, esa es la causa del problema. Abre el IDE nativo y elimina `capacitor-updater` manualmente y haz `npx cap sync`, esto debería resolverlo # Von V3 zu V4 > Cómo actualizar de V3 a V4 ## Por qué esta actualización Después de muchas conversaciones en la comunidad de Discord con ustedes, descubrí que el modo manual era demasiado manual y no seguro de usar, por ejemplo, la auto-reversión no era posible, por lo que si fallaba la actualización en manual el usuario tenía que eliminar la aplicación y volver a instalarla, lo cual es una terrible experiencia de usuario Mientras tanto, tomé esto como una oportunidad para darles más libertad y eliminar todo el código malo que hice ## Instalación `npm i @capgo/capacitor-updater@4` ## Auto-actualización en la nube Si usas el ejemplo básico en tu aplicación, es seguro migrar a la nueva versión, ¡disfrútalo! ## Auto-actualización auto-alojada Para ti, sigue siendo simple, los cambios son: * El nombre de la configuración de `autoUpdateUrl` a `updateUrl` * El método del endpoint cambió de `GET` a POST ## Usuarios manuales Para ti, este es el cambio más significativo, ¡pero para mejor! Obtienes toneladas de mejoras, lee cuidadosamente ## Cambios * `autoUpdateUrl` se convierte en `updateUrl` ya que esta configuración puede usarse en modo manual ahora también * Eliminación de `cancelDelay` y `delayUpdate` en favor de `setDelay` * Ya no hay `versionName` en set * Cambio de la clave `version`, que se devolvía en la mayoría de funciones al objeto `BundleInfo` ```typescript interface BundleInfo { id: string; version: string; downloaded: string; status: 'success' | 'error' | 'pending' | 'downloading' } ``` * Renombrado de nombres confusos ahora (incluso para explicar no puede ser claro, pero en el uso es fácil entender el nuevo): * lo que se llamaba `version` ahora se refiere a un `bundle` * `id` se refiere a la antigua `version` que era una cadena aleatoria de 10 caracteres, este `id` es la única forma confiable y única de acceder a tus bundles, ejemplo `7Dfcd2RedN` * `version` se refiere ahora al `versionName` que eliges para un bundle, ejemplo `100` * `updateUrl` cambia de `get` a `post`, ya que los encabezados personalizados eran un problema para algunos de ustedes y post es más lógico, todos los encabezados anteriores van al cuerpo y el prefijo `cap_` desaparece * el método `versionName` se elimina, en favor de `getId` * list ahora devuelve una lista de `BundleInfo` * Renombrado `getId` a `getDeviceId` * `autoUpdate` se vuelve verdadero por defecto, si usas el modo Manual, establécelo en falso ## Novedades * Método `getLatest`, este método te permite obtener de tu servidor configurado con `updateUrl` la última versión disponible * Método `setDelay` que toma `{kind: "background" | "kill" | "nativeVersion" | "date", value?: string}` como argumento para establecer el retraso en diferentes modos * Método `next`, para establecer la versión en el próximo paso a segundo plano, en oposición a `set` que lo hace instantáneamente * Método `isAutoUpdateEnabled`, para que sepas si estás en un contexto de auto-actualización * Evento `downloadComplete` cuando la descarga alcanza el 100% * Campo obligatorio añadido `version` en el método download * `notifyAppReady` se vuelve obligatorio en modo manual también, si no se llama después de 10 segundos la aplicación vuelve a la versión anterior ## Contribuidores [@lincolnthree](https://github.com/lincolnthree/) Muchas gracias por iniciar este trabajo, era imposible hacer que esta actualización funcionara sin ti # Dari V4 ke V5 > Cómo actualizar de V4 a V5 ## Por qué esta actualización Esta versión principal está aquí para seguir la versión principal de Capacitor Primero sigue la guía de migración de Capacitor: [https://capacitorjs.com/docs/updating/5-0](https://capacitorjs.com/docs/updating/5-0/) ## Instalación `npm i @capgo/capacitor-updater@5` `Luego sincroniza la actualización del código nativo:` `npx cap sync` ¡Eso es todo! ¡Bastante fácil! ## Modo manual Si estabas obteniendo la actualización por ti mismo con getLatest, hay un pequeño cambio Ahora si ya estás actualizado, entrará en catch Cualquier respuesta diferente a actualización disponible hará eso # De V5 a V6 > Cómo actualizar de V5 a V6 ## Por qué esta actualización Esta versión mayor está aquí para seguir la versión mayor de Capacitor Primero sigue la guía de migración de Capacitor: [https://capacitorjs.com/docs/updating/6-0](https://capacitorjs.com/docs/updating/6-0/) ## Instalación `npm i @capgo/capacitor-updater@6` `Luego sincroniza la actualización del código nativo:` `npx cap sync` ¡Eso es todo! ¡Bastante fácil! # イントロダクション > Introducción a la aplicación web Cagpo ## ¿Qué es esto? Cagpo tiene una extensa aplicación web para ayudarte a gestionar tus proyectos. Esta aplicación web está construida con Vuejs y es de código abierto. Puedes encontrar el código fuente en [GitHub](https://github.com/Cap-go/capgo/tree/main/src/)\ La aplicación web está disponible [aquí](https://web.capgo.app/)\ Esta aplicación web te permite [gestionar canales](/docs/webapp/channels/), [gestionar versiones](/docs/webapp/bundles/), [gestionar dispositivos](/docs/webapp/devices/), [inspeccionar registros](/docs/webapp/logs/), [gestionar facturación](/docs/webapp/settings/) y [gestionar tu cuenta](/docs/webapp/settings/) ## ¿Cómo lo uso? Primero, necesitas crear una cuenta o iniciar sesión. Esto es relativamente simple y se puede hacer haciendo clic en el botón `Iniciar sesión` en el centro de la pantalla. Después de iniciar sesión, serás redirigido al panel de control. Esta es la página principal de la aplicación web. Desde aquí puedes navegar a todas las demás páginas. ![login page](/login.webp) ## Creando una cuenta Tienes que hacer clic en `Crear una cuenta gratuita` en la parte inferior del formulario de inicio de sesión. A partir de ahí será tan simple como llenar un formulario y seguir las instrucciones. ![create account](/create-account.webp) # Gestione delle chiavi api > Cómo gestionar las claves de API ## ¿Qué puedo hacer con las claves api? Una clave API puede ser regenerada, eliminada o se puede añadir una nueva ## ¿Cómo ver todas las claves api? Necesitas ir a la [página de claves API](https://web.capgo.app/dashboard/apikeys/) y allí verás todas tus claves api ## ¿Cómo añadir una nueva clave api? Para añadir una nueva clave API haz clic en el pequeño botón más ![add apikey](/apikeys-add.webp) y luego selecciona los permisos que quieres dar a la nueva clave API. Puedes seleccionar: * Lectura - la clave API podrá leer todos los datos * Subir - la clave API podrá subir nuevas versiones desde la CLI y leer * Todo - La clave API podrá hacer todo ![select perm](/apikeys-select-perm.webp) ## ¿Cómo eliminar una clave api? Para eliminar una clave API haz clic en el pequeño botón de papelera ![remove apikey](/apikeys-remove.webp) Y luego confirma la eliminación de la clave API ## ¿Cómo regenerar una clave api? Para regenerar una clave API haz clic en el pequeño botón de actualización ![generate apikey](/apikeys-regenerate.webp) Y luego confirma la regeneración de la clave API # Bundles > Aprende cómo gestionar bundles ## Mostrar todos los paquetes Primero, echemos un vistazo a la página de paquetes. Puedes acceder a ella [haciendo clic en tu aplicación](/docs/webapp/main-page) y luego [haciendo clic en la pestaña de paquetes](/docs/webapp/main-app-page) ![bundle list](/bundles.webp) ## Eliminar un paquete Hay dos formas de eliminar un paquete: * Normalmente * De forma insegura La forma insegura de eliminar un paquete se agregó a Capgo el 12 de agosto de 2024 La diferencia entre las dos formas es la capacidad de reutilizar el número de versión después de la eliminación Por ejemplo, si eliminas una versión `100` de la forma normal y luego intentas subir una versión `100`, fallará Si eliminas esta versión a través del borrado inseguro, podrás subir una versión `100` Danger Eliminar una versión de forma insegura y volver a subirla es REALMENTE peligroso Puede causar todo tipo de errores y comportamientos impredecibles en el plugin NUNCA se debe usar para paquetes que se hayan utilizado en un canal público Por esta razón, eliminar una versión de forma insegura requiere privilegios de “super\_admin” ## Gestionar un paquete específico Una vez que veas la lista de todos los paquetes, haz clic en el que deseas gestionar. Después de hacerlo, deberías ver algo como esto: ![bundle info](/bundle-info.webp) Veamos todos los elementos de esta página *** Primero puedes ver un `Canal`. Esto te permite saber para qué canal es este paquete. Puedes cambiar el canal haciendo clic en él Una vez que hagas clic en él, deberías ver algo como esto: ![bundle change](/bundle-change.webp) `Establecer paquete al canal` te permitirá vincular este paquete como predeterminado para cualquier canal\ `Abrir canal` abrirá la página del canal para el canal al que pertenece este paquete\ `Desvincular paquete del canal` desvinculará este paquete del canal al que pertenece (**ADVERTENCIA**: Si el paquete está vinculado a más de 1 canal, no se te dará la opción de qué canal desvincular) *** A continuación, puedes ver el `Tamaño`. Si haces clic en él, podrás descargar este paquete Debería verse algo así: ![download bundle](/download-bundle.webp) *** Por último, está la sección de `Dispositivos`. Puedes ver todos los dispositivos que usan esta versión allí # 채널 > Los canales son una forma de gestionar las actualizaciones de tu aplicación. Puedes tener múltiples canales y cada canal puede tener múltiples versiones. Esto te permite tener múltiples versiones de tu aplicación en producción al mismo tiempo. ## Gestión de canales Primero, echemos un vistazo a la página de canales. Puedes acceder a ella [haciendo clic en tu aplicación](/docs/webapp/main-page) y luego [haciendo clic en la pestaña de canales](/docs/webapp/main-app-page) ![channel list](/channels.webp) ## Crear un canal Como puedes ver, existe un botón más en la esquina inferior derecha (`1` en la imagen). Al hacer clic en él se abrirá un modal donde puedes crear un nuevo canal ![new channel](/new_channel_modal.webp) Después de hacer clic en `Añadir` un nuevo canal debería aparecer en la lista ![after channel create](/post-channel-create.webp) ## ¿Qué significa mal configurado? A veces la configuración de un canal no es válida. En ese caso, recibirás una advertencia grande y la columna `Mal configurado` dirá `Sí` para uno o más de los canales. Puedes aprender más sobre esto [aquí](/docs/cli/commands/#disable-updates-strategy) ## Eliminar un canal Eliminar un canal es sencillo. Solo haz clic en el ícono de la papelera y confirma la eliminación (`2` en la imagen) ## Gestionar un canal Hacer clic en el nombre del canal abrirá un modal donde puedes gestionar el canal (`3` en la imagen) Esta página debería verse algo así: ![manage channel](/manage_channel_main.webp) Veamos las diferentes secciones Primero el `Número de paquete` (`1` en la imagen). Esta es la versión actual para ese canal. Cuando se solicite servir una actualización, este canal siempre intentará responder con esa versión\* \[^1] Al hacer clic en él deberías ir a la página de [paquetes](/docs/webapp/bundles/) Segundo la página `Compartido con` (`2` en la imagen). Recomiendo no usar esto nunca. Un sistema nuevo y mejor está en desarrollo Ahora los dispositivos forzados (`3` en la imagen). Esta es una lista de dispositivos que siempre obtendrán actualizaciones de este canal. Esto es útil para propósitos de prueba. Puedes forzar un dispositivo a un canal desde la página de [dispositivos](/docs/webapp/devices/) Por último la configuración (`4` en la imagen). Aquí es donde puedes gestionar cómo se comportan los canales Después de hacer clic en él deberías ver algo como esto: ![setting of channel](/channel_settings.webp) La lista de configuraciones es larga, pero haré mi mejor esfuerzo para explicarlas todas *** Primero el `Canal predeterminado` **ESTA ES PROBABLEMENTE LA MÁS IMPORTANTE**\ Si un canal está marcado como predeterminado, entonces se usará como el canal predeterminado para todos los dispositivos nuevos\ En otros términos: Si tienes un nuevo usuario, capgo intentará servirle la última versión de este canal predeterminado Solo 1 canal puede ser establecido como predeterminado a la vez. Si intentas romper esta regla se te pedirá confirmar tu acción ![confirm make change](/confirm-make-default.webp) Después de confirmar, el antiguo canal predeterminado se desmarcará como predeterminado y el nuevo será marcado como predeterminado *** Segundo la configuración de `IOS`. Esto es relativamente simple. Si es falso, entonces los dispositivos IOS no podrán descargar actualizaciones de este canal Tercero es la configuración de `Android`. Esto es similar a `IOS`. Si es falso, entonces los dispositivos Android no podrán descargar actualizaciones de este canal Cuarto es la configuración `Deshabilitar auto degradación bajo nativo`. Si esto es verdadero entonces será imposible degradar desde una versión nativa. Esto significa que si has subido una versión `120` a la App Store o Play Store e intentas establecer la versión del canal a `110` entonces la actualización (degradación) fallará Quinto es `Deshabilitar auto actualización`. Esta configuración es bastante compleja, y puedes aprender más sobre ella [aquí](/docs/cli/commands/#disable-updates-strategy) En cuanto a `Permitir compilación de desarrollo`. Si esto es verdadero entonces las compilaciones de desarrollo podrán descargar actualizaciones de este canal. Si no, entonces cualquier solicitud de actualización que tenga el `prod` establecido en falso será rechazada. Esto es principalmente útil para propósitos de prueba Séptimo es `Permitir Emuladores`. Si esto es falso entonces capgo rechazará cualquier solicitud de actualización que provenga de un emulador. Esto es principalmente útil para propósitos de prueba Octavo es `Permitir que los dispositivos se auto asocien`. Si esto es verdadero entonces el método [setChannel](/docs/plugin/api/#setchannel) estará disponible. Si esto está establecido en falso e intentas llamar al método [setChannel](/docs/plugin/api/#setchannel) con este canal entonces la llamada fallará # Geräte > Cómo usar la página de dispositivos ## Mostrar la lista de todos los dispositivos Primero, echemos un vistazo a la página de dispositivos. Puedes acceder a ella [haciendo clic en tu aplicación](/docs/webapp/main-page) y luego [haciendo clic en la pestaña de dispositivos](/docs/webapp/main-app-page) ![devices list](/devices.webp) ## Mostrar solo dispositivos de desarrollo Es posible que desees mostrar solo los dispositivos sobrescritos (Dispositivos que tienen un [canal personalizado](/docs/plugin/api/#setchannel) o una versión personalizada) Para hacer esto, haz clic en `Filtros` y luego en `Sobrescribir`. Debería verse algo así: ![filter devices](/overwrite-filter.webp) ## Configurando un dispositivo Para configurar un dispositivo específico, haz clic en él en la tabla y deberías ver algo como esto: ![show one device](/device-specific.webp) Primero, el `ID Personalizado`. Esto no es realmente útil y por ahora no hace nada. Puedes ignorarlo Siguiente, la versión forzada. Si esto está configurado, este dispositivo recibirá **SIEMPRE** esta versión. Tiene prioridad sobre el canal Por último, el canal personalizado. Si esto está configurado, este dispositivo no se preocupará por el canal público (predeterminado) y simplemente usará este # 로그 > Aprende cómo usar la página de registros ## Mostrar todos los registros Primero, echemos un vistazo a la página de registros. Puedes acceder a ella [haciendo clic en tu aplicación](/docs/webapp/main-page) y luego [haciendo clic en la pestaña de actualizaciones](/docs/webapp/main-app-page) Desde allí deberías ver una página como esta: ![show logs](/logs.webp) ## Obtener más detalles sobre un registro Si haces clic en un registro, te llevará a una [página de dispositivos](/docs/webapp/devices/) # Página principal de la aplicación > ¿Qué se muestra en la página principal? ## ¿Qué muestra la página principal? Primero, echemos un vistazo a la página principal de la aplicación: ![Main page screeshot](/main-app-page.webp) Veamos esto más detalladamente Primero las estadísticas. Las estadísticas están siendo reelaboradas por lo que no pueden ser documentadas en este momento. Agregaremos una sección de estadísticas cuando estén completamente operativas. Segundo, echemos un vistazo a todos los menús disponibles y lo que hacen ![Multiple sections screeshot](/app-multiple-sections.webp) El primer botón te llevará a la página de [canales](/docs/webapp/channels/). Puedes crear/eliminar/configurar los canales de la aplicación allí\ El segundo botón te llevará a la página de [paquetes](/docs/webapp/bundles/). Puedes ver todas las versiones de la aplicación allí El segundo botón te llevará a la página de [dispositivos](/docs/webapp/devices/). Puedes ver todos los dispositivos allí. También puedes establecer sobreescrituras específicas de dispositivos desde allí El segundo botón te llevará a la página de [actualizaciones](/docs/webapp/logs/). Puedes ver las estadísticas detalladas (registros) y errores que tu aplicación está experimentando desde allí # Página principal > Esta página describe la página principal de la aplicación web ## ¿Qué muestra la página principal? Primero, echemos un vistazo a la página principal: ![Main page screeshot](/main-page.webp) Empecemos por el principio. Lo primero que ves son las **estadísticas**. Contiene estadísticas específicas de la aplicación. Estas actualizaciones dependen del uso de la aplicación. Lo segundo que ves es la lista de todas las aplicaciones disponibles. Esto cambiará dependiendo de cuántas aplicaciones hayas creado. Puedes hacer clic en cada aplicación para ver más detalles sobre ella. Lo tercero que ves es el botón de **claves API**. Este botón te llevará a la página de [claves API](/docs/webapp/api-keys/). Lo siguiente que ves es el botón **test Capgo**. Este botón cambiará dependiendo de tu nombre y apellido y te llevará a la página de [configuración](/docs/webapp/settings/) o soporte. Por último, ves un botón para agregar otra aplicación. Este botón te llevará a una página donde puedes agregar una nueva aplicación a Capgo. # 2단계 인증 > Gestión de la autenticación de dos factores para proteger mejor tu cuenta de capgo ## ¿Qué es 2FA? 2FA es una medida de seguridad diseñada para evitar que un actor malicioso tome el control de tu cuenta de capgo\ Lo logra requiriendo un código adicional. Este código se almacena en tu teléfono móvil o en una llave de hardware 2FA. Cambia cada 30 segundos, haciendo imposible adivinarlo ## Requisitos para esta guía * Un teléfono Android o iOS * Conexión a Internet ## ¿Qué cubrirá esta guía? Esta guía mostrará cómo configurar 2FA usando `Google Authenticator`. Existen otras aplicaciones que sirven para un propósito similar, sin embargo, no puedo cubrir todo el tema de 2FA en esta guía ## ¿Cómo configurar 2FA? Primero descarga la aplicación `Google Authenticator`. Si estás en Android, puedes descargarla desde la [play store](https://play.google.com/store/apps/details/?id=comgoogleandroidappsauthenticator2). En iOS puedes descargarla desde la [App store](https://appsapplecom/us/app/google-authenticator/id388497605/) Segundo, por favor ve a la [configuración de cuenta de capgo](https://web.capgo.app/dashboard/settings/account/). Allí deberías ver un botón verde que debería verse así: ![Button MFA](/button-mfa.webp) Haz clic en él, y una vez que lo hagas, debería aparecer un código QR ![Enable MFA](/enable-mfa.webp) Danger ⚠️ Nota Importante:\ Nunca compartas este código QR con nadie, o podrías perder el acceso a tu cuenta A continuación, abre `Google Authenticator` en tu teléfono. Una vez que lo hagas, sigue estos pasos: Haz clic en el botón más ![MFA auth plus](/mfa-auth-plus.webp) Después de eso, haz clic en el botón de la cámara ![MFA scan QR](/mfa-scan-qr.webp) Eso abrirá la vista previa de la cámara. Por favor escanea el código QR mostrado en tu PC. Después de hacer eso, deberías ver algo como esto: ![MFA final code](/mfa-final-code.webp) Luego regresa a la PC y haz clic en el botón verificar ![Verify MFA](/enable-mfa-verify.webp) Esto abrirá una ventana para escribir nuestro código 2FA. En mi caso, este código es `095101` pero será diferente para ti\ Después de escribir este código, haz clic en el botón `verificar` ![MFA verify code final](/mfa-verify-final-code.webp) Si ingresaste el código correcto y presionaste `verificar` deberías ver una ventana emergente como esta ![MFA enabled](/mfa-enabled.webp) ¡Felicitaciones!\ Has habilitado la autenticación 2FA 🎉 ## Cómo iniciar sesión usando 2FA La próxima vez que inicies sesión en tu cuenta, verás una ventana como esta ![MFA required](/mfa-required.webp) Por favor abre el autenticador y copia tu código de autenticación ![MFA login](/mfa-login.webp) Danger ⚠️ Nota Importante:\ Presiona `verificar` antes de que el código se actualice, de lo contrario el código cambiará y el anterior ya no será válido Luego ingresa el código en el formulario de inicio de sesión y presiona `verificar` ![MFA login](/mfa-final-login-verify.webp) Si ingresaste el código correcto, deberías ver el panel de control de capgo ## Cómo deshabilitar 2FA Para deshabilitar 2FA, por favor ve a la [configuración de cuenta de capgo](https://web.capgo.app/dashboard/settings/account/). Allí deberías ver un botón rojo que debería verse así: ![MFA disable button](/mfa-disable-button.webp) Haz clic en él, y deberías ver una pantalla como esta ![MFA disabled](/mfa-disable-2.webp) Solo presiona el botón `deshabilitar`, y eso es todo # Organisationssystem > Gestión de organizaciones en tu cuenta de capgo ## ¿Qué es el sistema de organización? El sistema de organización es un sistema en capgo que te permite compartir de forma segura tus aplicaciones con miembros de tu equipo ### P: ¿Cómo puedo acceder a la información de mi organización? Para acceder a la información de tu organización, por favor ve a [configuración](/docs/webapp/settings/#how-to-get-to-the-settings-page) y luego haz clic en `Configuración de la Organización` ![Org settings](/orgs-settings.webp) ### P: ¿Cómo puedo cambiar la organización que estoy viendo? Para ver la configuración de una organización diferente, por favor haz clic en el selector de organización cerca de tu nombre ![Org selector](/org-selector.webp) Si no puedes ver esto, probablemente no estés en la página de configuración ### P: ¿Cómo puedo ver los miembros de mi organización? Por favor haz clic en `miembros` ![Org Show members](/org-show-members.webp) ### P: ¿Cómo puedo invitar a un usuario a una organización? Por favor haz clic en `Añadir miembro` ![Org add member](/orgs-add-member.webp) Entonces aparecerá una ventana emergente - por favor ingresa la dirección de correo electrónico del usuario ![Invite to org](/invite-to-org-email-enter.webp) Luego haz clic en `invitar` Aparecerá otra ventana emergente, esta vez preguntando sobre los permisos que debería tener el usuario invitado ![Select perm for org](/select-perm-orgs.webp) Aquí hay un desglose de todos los permisos: | Permiso | Lectura | Subir | Escritura | Admin | Super Admin | | -------------------------------- | ------- | ----- | --------- | ----- | ----------- | | Ver estadísticas de la app | ✅ | ✅ | ✅ | ✅ | ✅ | | Ver canales de la app | ✅ | ✅ | ✅ | ✅ | ✅ | | Ver dispositivos | ✅ | ✅ | ✅ | ✅ | ✅ | | Ver registros | ✅ | ✅ | ✅ | ✅ | ✅ | | Ver paquetes | ✅ | ✅ | ✅ | ✅ | ✅ | | Eliminar app | ❌ | ❌ | ❌ | ❌ | ✅ | | Eliminar canal | ❌ | ❌ | ❌ | ✅ | ✅ | | Eliminar versión | ❌ | ❌ | ✅ | ✅ | ✅ | | Cambiar configuración de org | ❌ | ❌ | ❌ | ✅ | ✅ | | Gestionar usuarios de org | ❌ | ❌ | ❌ | ✅ | ✅ | | Modificar config. de canales | ❌ | ❌ | ✅ | ✅ | ✅ | | Subir nueva versión | ❌ | ✅ | ✅ | ✅ | ✅ | | Modificar dispositivos | ❌ | ❌ | ✅ | ✅ | ✅ | | Cambiar versión actual del canal | ❌ | ❌ | ✅ | ✅ | ✅ | | Crear nuevo canal | ❌ | ❌ | ❌ | ✅ | ✅ | | Modificar versión (metadatos) | ❌ | ❌ | ✅ | ✅ | ✅ | | Gestionar facturación | ❌ | ❌ | ❌ | ❌ | ✅ | | Eliminar versión inseguramente | ❌ | ❌ | ❌ | ❌ | ✅ | ### P: ¿Cómo se maneja la facturación dentro de las organizaciones? Cualquier persona con permiso de **super admin** puede gestionar la facturación de una organización dada Los planes están vinculados a una organización y no a tu cuenta personal Danger ⚠️ Comprar un plan SOLO afectará a las organizaciones que tienes seleccionadas actualmente ### P: ¿Puedo crear más de una organización? No, aún no # Sistem pembayaran > Administración de pagos en tu cuenta capgo. ## ¿De qué trata esto? Esta página pretende responder algunas preguntas sobre el sistema de pago en capgo #### P: ¿Cómo puedo actualizar mi plan de capgo? R: Puedes actualizar tu plan de capgo yendo a [la configuración](/docs/webapp/settings/#how-to-get-to-the-settings-page) y haciendo clic en el botón **Planes** ![Choose plan](/plans-button.webp) Luego puedes seleccionar el plan que mejor se adapte a tus necesidades y hacer clic en **Suscribirse** ![Subscribe to plan](/plans-subscribe.webp) Entonces se abrirá una página de stripe. Allí, puedes ingresar tu información de pago ![Stripe portal](/plans-stripe.webp) #### P: ¿Son seguros los pagos? R: Sí, los pagos son completamente gestionados por stripe. Capgo nunca tiene acceso a los detalles de tu tarjeta de crédito. Stripe toma la seguridad muy en serio [Aprende más sobre la política de seguridad de stripe](https://stripecom/docs/security/) #### P: ¿Capgo actualizará automáticamente mi plan cuando exceda el límite? R: No, capgo nunca cambiará tu plan #### P: ¿Capgo me enviará un correo electrónico cuando mi plan esté cerca de sus límites? R: Sí, capgo te enviará un correo electrónico informándote sobre el uso #### P: ¿El plan que compre afectará a las organizaciones a las que estoy invitado? R: No, el plan solo afectará a la organización que tienes seleccionada actualmente Por favor, consulta [la documentación de la organización](/docs/webapp/organization-system/#q-how-is-billing-done-within-orgs) #### P: ¿Qué sucede si necesito un plan más personalizado? R: [Por favor contacta directamente con el soporte de capgo](/docs/getting-help#support-by-chat) #### P: ¿Cuál es la política de reembolso de capgo? R: Puedes encontrar la política de reembolso [aquí](https://capgo.app/return/) # Pengaturan > Cómo cambiar la configuración del usuario ## Cómo llegar a la página de configuración Primero haga clic en **NOMBRE APELLIDO** En mi caso es **test Capgo** En tu caso, será tu nombre y luego tu apellido. Luego haz clic en **Configuración** ![open settings](/settings-go.webp) ## Cambiar la configuración del usuario Para cambiar cualquier configuración de usuario, simplemente complete el formulario en la cuenta y luego haga clic en **Actualizar** ![save change in account](/account-save.webp) Luego debería aparecer una confirmación ![acount updated](/account-updated.webp) ## Cambiar la contraseña Para cambiar la contraseña, ve a la página de configuración y haz clic en **Contraseña**. Luego completa el formulario y haz clic en **Actualizar** ![update password](/update-passwd.webp) Cuando la contraseña no sigue las reglas de seguridad de contraseñas de Capgo, recibirás un mensaje de error ![wrong password](/passwd-error.webp) # Selamat datang di Capgo > Capgo est une plateforme open source de mises à jour en direct pour Capacitor et les équipes de développement mobile qui vous permet de fournir des mises à jour en direct à vos utilisateurs en quelques minutes, et non en quelques jours La puissance de Live Update Livrez de manière transparente des mises à jour d’applications en direct, des corrections de bugs critiques, des changements de contenu, des fonctionnalités bêta et plus encore pour offrir à vos utilisateurs la meilleure expérience possible Facile à intégrer Le plugin prend 3 étapes pour s’intégrer dans votre code et vous permet d’envoyer des mises à jour à vos utilisateurs en quelques minutes au lieu de jours ! Installation Exécutez `npx @capgo/cli@latest init [APIKEY]` pour commencer Documentation complète Apprenez dans la [Documentation](/docs/getting-started/quickstart/) comment maîtriser le plugin en 5 minutes avec notre vidéo d’intégration # Commandes > Documentation Capgo CLI ### Utilisation Toutes les commandes doivent être exécutées dans votre dossier d’application avec un projet Capacitor correctement initialisé [Capacitor Runtime natif multiplateforme pour les applications web ](https://capacitorjs.com/docs/getting-started/) ### **Init** `npx @capgo/cli@latest init [apikey]` Cette méthode est là pour vous guider étape par étape Elle ajoutera votre application à Capgo Elle ajoutera le code à votre application pour valider la mise à jour De même, elle construira votre application De plus, elle téléversera votre application vers Capgo Et elle vous aidera à vérifier si la mise à jour fonctionne ### **Connexion** `npx @capgo/cli login [apikey]` Cette méthode est là pour mémoriser votre `apikey` Note utilisez `--apikey=********` dans n’importe quelle commande pour la remplacer **En option, vous pouvez donner :** `--local` Cela stockera votre **apikey** dans le dépôt local et l’ignorera dans git ## **Doctor** `npx @capgo/cli doctor` Commande pour vérifier si vous êtes à jour avec les paquets Capgo Cette commande sera également utile pour les rapports de bugs ## Application ### **Ajouter** `npx @capgo/cli app add [appId]` `[appId]` votre ID d’application, le format `comtestapp` est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) > 💡 Toutes les options seront devinées dans votre configuration si non fournies En option, vous pouvez donner : * `--icon [/chemin/vers/mon/icone]` pour avoir une icône personnalisée affichée dans l’application web Capgo * `--name [test]` pour avoir un nom personnalisé dans la liste * `--apikey [clé]` Clé API pour lier à votre compte * `--retention [retention]` période de rétention du bundle d’application en jours, 0 par défaut = infini Exemple de `capacitorconfigjson` pour appId et AppName, l’icône est devinée dans le dossier resources ```json { "appId": "eeforgrcapacitor_go", "appName": "Capgo", "webDir": "dist" } ``` ### **Définir** `npx @capgo/cli app set [appId]` `[appId]` est votre ID d’application, le format est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) En option, vous pouvez donner : * `--icon [/chemin/vers/mon/icone]` pour avoir une icône personnalisée affichée dans l’application web Capgo * `--name [test]` pour avoir un nom personnalisé dans la liste * `--retention [retention]` période de rétention du bundle d’application en jours, 0 par défaut = infini * `--apikey [clé]` Clé API pour lier à votre compte ### **Liste** `npx @capgo/cli app list [appId]` `[appId]` votre ID d’application, le format `comtestapp` est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) En option, vous pouvez donner : * `--apikey [clé]` Clé API pour lier à votre compte ### **Supprimer** `npx @capgo/cli app delete [appId]` `[appId]` votre ID d’application, le format `comtestapp` est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) En option, vous pouvez donner : * `--apikey [clé]` Clé API pour lier à votre compte * `--bundle` avec le numéro de version supprimera uniquement cette version ### Debug `npx @capgo/cli app debug [appId]` `[appId]` votre ID d’application, le format `comtestapp` est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) En option, vous pouvez donner : * `--apikey [clé]` Clé API pour lier à votre compte * `--device` avec l’appareil spécifique que vous souhaitez déboguer ### Paramètres `npx @capgo/cli app setting [chemin]` Modifier la configuration Capacitor `[chemin]` - chemin du paramètre que vous souhaitez modifier Par exemple, pour changer l’`appId`, fournissez `appId` Si vous souhaitez désactiver la mise à jour automatique dans `capacitor-updater` fournissez `pluginsCapacitorUpdaterautoUpdate` Vous DEVEZ fournir soit `--string` soit `--bool` ! Options : * `--string ` - définit le paramètre comme une chaîne * `--bool ` - définit le paramètre comme un booléen ## Bundle ### Téléverser `npx @capgo/cli bundle upload [appId]` `[appId]` est votre ID d’application, le format est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) En option, vous pouvez donner : * `--apikey ` Clé API pour lier à votre compte * `--path ` Chemin du dossier à téléverser * `--channel ` Canal à lier * `--external ` Lien vers une URL externe au lieu de téléverser vers Capgo Cloud * `--iv-session-key ` Définir l’IV et la clé de session pour l’URL du bundle externe * `--s3-endpoint ` URL du point de terminaison S3 Ne fonctionne pas avec le téléversement partiel ou l’option externe * `--s3-region ` Région pour votre bucket S3 * `--s3-apikey ` Clé API pour votre point de terminaison S3 * `--s3-apisecret ` Secret API pour votre point de terminaison S3 * `--s3-bucket-name ` Nom pour votre bucket AWS S3 * `--s3-port ` Port pour votre point de terminaison S3 * `--no-s3-ssl` Désactiver SSL pour le téléversement S3 * `--key ` Chemin personnalisé pour la clé de signature publique (système v1) * `--key-data ` Clé de signature publique (système v1) * `--key-v2 ` Chemin personnalisé pour la clé de signature privée (système v2) * `--key-data-v2 ` Clé de signature privée (système v2) * `--bundle-url` Affiche l’URL du bundle dans stdout * `--no-key` Ignorer la clé de signature et envoyer une mise à jour en clair * `--no-code-check` Ignorer la vérification si notifyAppReady() est appelé dans le code source et index présent dans le dossier racine * `--display-iv-session` Afficher dans la console l’IV et la clé de session utilisés pour chiffrer la mise à jour * `--bundle ` Numéro de version du bundle à téléverser * `--min-update-version ` Version minimale requise pour mettre à jour vers cette version Utilisé uniquement si la désactivation de la mise à jour automatique est définie sur metadata dans le canal * `--auto-min-update-version` Définir la version minimale de mise à jour basée sur les paquets natifs * `--ignore-metadata-check` Ignore la vérification des métadonnées (node\_modules) lors du téléversement * `--ignore-checksum-check` Ignore la vérification du checksum lors du téléversement * `--timeout ` Délai d’attente pour le processus de téléversement en secondes * `--partial` Ne téléverse pas les fichiers partiels vers Capgo cloud * `--tus` Téléverse le bundle en utilisant le protocole tus * `--multipart` Utilise le protocole multipart pour téléverser les données vers S3, Déprécié, utilisez TUS à la place * `--encrypted-checksum ` Un checksum chiffré (signature) Utilisé uniquement lors du téléversement d’un bundle externe * `--package-json ` Un chemin vers packagejson Utile pour les monorepos * `--auto-set-bundle` Définir le bundle dans capacitorconfigjson * `--node-modules ` Une liste de chemins vers node\_modules Utile pour les monorepos (séparés par des virgules ex : //node\_modules,/node\_modules) > ⭐️ L’option externe aide à débloquer 2 cas : entreprise avec des préoccupations de confidentialité, ne pas envoyer le code à un tiers et application plus grande que 200 MB Avec ce paramètre, Capgo stocke uniquement le lien vers le zip et envoie le lien à toutes les applications > 👀 Capgo cloud ne regarde jamais ce qu’il y a dans le lien (pour l’option externe), ou dans le code lorsqu’il est stocké > 🔑 Vous pouvez ajouter une deuxième couche de sécurité en utilisant le chiffrement, alors Capgo ne pourra pas regarder ou modifier quoi que ce soit, cela devient “trustless” Exemple de `packagejson` pour la version ```json { "version": "102" } ``` > ⛔ La version doit être supérieure à “000” > 💡 N’oubliez pas de mettre à jour le numéro de version à chaque fois que vous en envoyez un, le numéro de version ne peut pas être écrasé ou réutilisé après suppression pour des raisons de sécurité ### **Liste** `npx @capgo/cli bundle list [appId]` `[appId]` votre ID d’application, le format `comtestapp` est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) En option, vous pouvez donner : * `--apikey [clé]` Clé API pour lier à votre compte ### **Supprimer** `npx @capgo/cli bundle delete [appId]` `[appId]` votre ID d’application, le format `comtestapp` est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) En option, vous pouvez donner : * `--apikey [clé]` Clé API pour lier à votre compte * `--bundle` avec le numéro de version supprimera uniquement cette version ### Nettoyage dans une plage SemVer pour une version majeure vers Cloud `npx @capgo/cli bundle cleanup [appId] --bundle=[versionMajeure] --keep=[nombreÀGarder]` `[appId]` votre ID d’application, le format `comtestapp` est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) En option, vous pouvez donner : * `--apikey [clé]` Clé API pour lier à votre compte * `--bundle [versionMajeure]` une version pour laquelle vous souhaitez supprimer les paquets précédents, il gardera le dernier + `nombreÀGarder`Je traduis le texte en français tout en gardant les éléments techniques inchangés : * `--keep [numberToKeep]` le nombre de paquets que vous souhaitez conserver (par défaut 4) Par exemple : Si vous avez 10 versions de 1001 à 10011, et que vous utilisez `npx @capgo/cli cleanup [appId] --bundle=1000`, cela supprimera de 1001 à 1006, 1007 jusqu’à 10011 seront conservés Si vous avez 20 versions au total, et que vous ne fournissez pas de numéro de bundle comme ceci : `npx @capgo/cli cleanup [appId] --keep=2`, cela supprimera 18 versions et conservera les 2 dernières > Cette commande demandera une confirmation, elle affiche un tableau de ce qui sera conservé et supprimé Note Cette commande ignorera les bundles qui sont actuellement utilisés dans n’importe quel canal ### **Encrypt** > **Attention** : Cette commande est dépréciée et sera supprimée dans la prochaine version majeure. Veuillez utiliser le nouveau système de chiffrement `npx @capgo/cli bundle encrypt [path/to/zip]` Cette commande est utilisée lorsque vous utilisez une source externe pour stocker votre code ou à des fins de test En option, vous pouvez donner : `--key [/path/to/my/private_key]` le chemin de votre clé privée `--key-data [privateKey]` les données de la clé privée, si vous voulez l’utiliser en ligne La commande affichera votre `ivSessionKey` et générera un zip chiffré, à utiliser avec la commande upload ou decrypt ### **Encrypt V2** `npx @capgo/cli bundle encryptV2 [path/to/zip] [checksum]` Cette commande est utilisée lorsque vous utilisez une source externe pour stocker votre code ou à des fins de test Le checksum est le sha256 du bundle (généré par —key-v2), il est utilisé pour vérifier l’intégrité du fichier après le déchiffrement Il sera chiffré avec la clé privée et envoyé avec le bundle Dans le chiffrement v2, le checksum est amélioré pour devenir une “signature” du bundle En option, vous pouvez donner : `--key [/path/to/my/private_key]` le chemin de votre clé privée `--key-data [privateKey]` les données de la clé privée, si vous voulez l’utiliser en ligne `--json` pour afficher les informations en json La commande affichera votre `ivSessionKey` et générera un zip chiffré, à utiliser avec la commande upload ou decrypt ### **Decrypt** `npx @capgo/cli bundle decrypt [path/to/zip] [ivSessionKey]` En option, vous pouvez donner : `--key [/path/to/my/private_key]` le chemin de votre clé privée `--key-data [privateKey]` les données de la clé privée, si vous voulez l’utiliser en ligne Cette commande est principalement utilisée à des fins de test, elle déchiffrera le zip et affichera la clé de session déchiffrée en base64 dans la console ### **Decrypt V2** `npx @capgo/cli bundle decryptV2 [path/to/zip] [ivSessionKey]` En option, vous pouvez donner : `--key [/path/to/my/private_key]` le chemin de votre clé privée `--key-data [privateKey]` les données de la clé privée, si vous voulez l’utiliser en ligne Cette commande est principalement utilisée à des fins de test, elle déchiffrera le zip et affichera la clé de session déchiffrée en base64 dans la console `--checksum [checksum]` le checksum du fichier, il vérifiera le checksum après le déchiffrement ### **Zip** `npx @capgo/cli bundle zip [appId]` `[appId]` est votre ID d’application, le format est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) En option, vous pouvez donner : * `--path [/path/to/my/bundle]` pour télécharger un dossier spécifique * `--bundle [100]` pour définir le numéro de version du bundle dans le nom du fichier * `--name [myapp]` pour remplacer le nom du fichier * `--json` pour afficher les informations en json * `--no-code-check` pour ignorer la vérification du code et envoyer le bundle quand même * `--key-v2` pour utiliser le nouveau système de chiffrement Ceci est requis car le nouveau système de chiffrement utilise de meilleurs checksums pour vérifier l’intégrité du fichier ### **Compatibility** `npx @capgo/cli bundle compatibility [appId] -c [channelId]` `[appId]` est votre ID d’application, le format est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) `[channelId]` le nom de votre nouveau canal En option, vous pouvez donner : * `--apikey [key]` Clé API pour lier à votre compte * `--text` utiliser du texte au lieu d’emojis dans le tableau * `--channel [channel]` le canal pour vérifier la compatibilité * `--package-json ` Un chemin vers packagejson Utile pour les monorepos * `--node-modules ` Une liste de chemins vers node\_modules Utile pour les monorepos (séparés par des virgules ex : //node\_modules,/node\_modules) ## Channel ### **Add** `npx @capgo/cli channel add [channelId] [appId]` `[channelId]` le nom de votre nouveau canal `[appId]` votre ID d’application le format `comtestapp` est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) ### **Delete** `npx @capgo/cli channel delete [channelId] [appId]` `[channelId]` le nom du canal que vous souhaitez supprimer `[appId]` votre ID d’application le format `comtestapp` est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) ### **List** `npx @capgo/cli channel list [appId]` `[appId]` votre ID d’application le format `comtestapp` est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) En option, vous pouvez donner : * `--apikey [key]` Clé API pour lier à votre compte ### **Set** `npx @capgo/cli channel set [channelId] [appId]` `[appId]` est votre ID d’application, le format est expliqué [ici](https://capacitorjs.com/docs/cli/commands/init/) En option, vous pouvez donner : * `--bundle [123]` votre bundle d’application déjà envoyé au cloud, pour le lier à un canal * `--latest` obtenir la version du bundle depuis `packagejson:version`, ne peut pas être utilisé avec `--bundle` * `--state [ normal | default ]` définir l’état du canal, peut être `normal` ou `default` Un canal doit être `default` * `--downgrade` permet au canal d’envoyer des versions inférieures aux appareils * `--no-downgrade` interdit au canal d’envoyer des versions inférieures aux appareils * `--upgrade` permet au canal d’envoyer des mises à niveau (majeures) aux appareils * `--no-upgrade` interdit au canal d’envoyer des mises à niveau (majeures) aux appareils * `--ios` permet au canal d’envoyer des versions aux appareils iOS * `--no-ios` interdit au canal d’envoyer des versions aux appareils iOS * `--android` permet au canal d’envoyer des versions aux appareils Android * `--no-android` interdit au canal d’envoyer des versions aux appareils Android * `--self-assign` permet aux appareils de s’auto-assigner à ce canal * `--no-self-assign` interdit aux appareils de s’auto-assigner à ce canal * `--disable-auto-update STRATEGY` Désactive la stratégie de mise à jour automatique pour ce canal Les options possibles sont : major, minor, metadata, none * `--apikey [key]` Clé API pour lier à votre compte ## Stratégies de désactivation des mises à jour Il existe plusieurs façons de gérer la désactivation des mises à jour pour les versions trop anciennes\ Capgo ne peut pas mettre à jour le code natif, donc une mise à jour d’une version avec l’ancien code natif vers une version avec le code natif mis à jour ne devrait pas être possible Il existe plusieurs façons d’y parvenir Premièrement, la stratégie `major` Elle empêche une mise à jour de `000` -> `100` Le major est le numéro en surbrillance (**1**00 et **0**00)\ Deuxièmement, la stratégie `minor` Elle empêche une mise à jour de `000` -> `110` ou une mise à jour de `110` vers `120` **ATTENTION** cette stratégie n’empêche pas une mise à jour de `010` -> `110` Troisièmement, la stratégie `patch` Elle a été ajoutée dans capgo comme un mode très strict Il n’est pas recommandé de l’utiliser sauf si vous comprenez parfaitement son fonctionnement Pour qu’une mise à jour soit acceptée, les conditions suivantes doivent être remplies : * Le major est le même entre la nouvelle et l’ancienne version * Le minor est le même entre la nouvelle et l’ancienne version * Le patch de la nouvelle version est supérieur au patch de l’ancienne version Voici un exemple des scénarios où la mise à jour est autorisée ou refusée * 00311 -> 00314 ✅ * 000 -> 00314 ✅ * 00316 -> 00314 ❌ * 01312 -> 00314 ❌ * 10312 -> 00314 ❌ Enfin, la stratégie la plus complexe La stratégie `metadata`\ D’abord, vous devez savoir qu’initialement après l’avoir activée, les mises à jour **ÉCHOUERONT** car le canal manque des métadonnées requises\ Si le canal manque de métadonnées, vous verrez un message comme celui-ci : ![Impossible de trouver les métadonnées](/fail-metadata.webp) Si vous voyez quelque chose comme ceci, vous savez que vous devez aller au bundle actuel pour le canal défaillant et définir les métadonnées\ Tout d’abord, déterminez quel canal échoue Vous pouvez le faire en regardant la colonne `misconfigured` ![Misconfigured table](/misconfigured-table.webp) Ensuite, allez dans le canal défaillant et cliquez sur `Bundle number`. Cela devrait vous amener à la page du bundle. ![Locate failing channel](/fail-channel-show.webp) Une fois là, remplissez le champ `Minimal update version`. Ce doit être un [semver](https://devhintsio/semver/)\ Si la valeur que vous passez n’est pas un semver, vous obtiendrez une erreur, mais si tout se passe correctement, vous devriez voir quelque chose comme ceci : ![Set min version](/set-min-update-version.webp) Maintenant, vous ne voulez probablement pas définir ces données manuellement à chaque mise à jour. Heureusement, le CLI vous empêchera d’envoyer une mise à jour sans ces métadonnées. ![CLI fail no metadata](/cli-fail-no-metadata.webp) Pour télécharger correctement un bundle en utilisant l’option `metadata`, vous devez passer le `--min-update-version` avec un semver valide. Quelque chose comme ceci : ![CLI upload with metadata](/cli-upload-with-metadata.webp) Le `--min-update-version` n’est pas la SEULE façon de gérer la compatibilité. Il existe aussi le `--auto-min-update-version`. Voici comment il fonctionne : 1. Il examine d’abord la version actuellement téléchargée sur le canal. Il vérifie la compatibilité comme le ferait la commande `bundle compatibility`. 2. Si la nouvelle version est 100% compatible, il réutilise le `min_update_version` de la dernière version du canal. Si non, il définit le `min_update_version` sur le numéro de bundle de la version nouvellement téléchargée. Vous obtiendrez toujours une information sur le `min_update_version` lors de l’utilisation de cette option. Cela ressemblera à quelque chose comme ceci : ![Min update version](/min_update_version_info.webp) Si la nouvelle version n’est pas compatible, cela devrait ressembler à ceci : ![Min update version not compatible](/min_update_version_not_compatible.webp) ## Chiffrement de bout en bout (Sans confiance) Capgo prend en charge le chiffrement de bout en bout, ce qui signifie que votre bundle (code) est chiffré avant d’être envoyé au cloud et déchiffré sur l’appareil. Pour cela, vous devez générer une paire de clés RSA, vous pouvez utiliser la commande suivante pour la générer. Le système de chiffrement est une combinaison de RSA et AES, la clé RSA est utilisée pour chiffrer la clé AES, et la clé AES est utilisée pour chiffrer le fichier. Voir ci-dessous pour plus d’informations sur le système de chiffrement ![How crypto works](/crypto_explained.webp) Schéma de chiffrement ### Créer une clé pour votre application `npx @capgo/cli key create` En option, vous pouvez donner : `--force` pour écraser la clé existante. Cette commande créera pour vous une paire de clés dans votre application, et vous demandera de sauvegarder la clé privée dans un endroit sûr. Il est recommandé de ne pas commiter la clé privée sur git, et de ne pas la partager avec qui que ce soit. > Après votre test local, supprimez la clé du fichier de configuration et ajoutez-la à l’étape CI avec `key save` ### Sauvegarder la clé dans la configuration de votre application `npx @capgo/cli key save` En option, vous pouvez donner : `--key [/path/to/my/private_key]` le chemin de votre clé privée `--key-data [privateKey]` les données de la clé privée, si vous voulez l’utiliser en ligne. Cette commande est utile si vous avez suivi la recommandation et n’avez pas commité la clé dans votre application et dans la configuration. ## Intégration CI Pour automatiser votre travail, je vous recommande de faire faire le travail d’envoi vers notre serveur par GitHub action. [Tutoriel GitHub action](https://capgo.app/blog/automatic-build-and-release-with-github-actions/) ## Notre application de démonstration [GitHub - Cap-go/demo-app](https://github.com/Cap-go/demo-app/) N’oubliez pas de configurer la variable d’environnement CI avec votre clé API # CLI de 0.x a 1.x > Comment passer de la version 0.x à 1.x Il n’y a pas de changements significatifs dans la CLI Le changement majeur concerne principalement le renommage de l’argument `--version` en `--bundle` pour éviter les conflits et suivre la nouvelle nomenclature partout # Chiffrement > Comment chiffrer vos données avec le nouveau chiffrement Cette documentation expliquera comment chiffrer vos données avec le nouveau système de chiffrement et supprimer l’ancien En savoir plus sur le nouveau système de chiffrement dans le [blog post](/blog/introducing-end-to-end-security-to-capacitor-updater-with-code-signing) *** Tout d’abord, créez une nouvelle paire de clés avec la commande suivante : ```bash npx @capgo/cli key create ``` Cette commande créera une nouvelle paire de clés dans votre application ; il est impératif de stocker la clé privée dans un endroit sûr. Il ne faut jamais soumettre la clé privée au contrôle de source ni la partager avec une partie non fiable. Cette commande supprimera également l’ancienne clé de votre configuration Capacitor, mais elle ne supprimera pas les anciens fichiers de clés. Le CLI les conserve pour vous permettre de continuer à envoyer des mises à jour en direct pour les applications qui n’ont pas reçu de mise à jour de l’app store et qui utilisent toujours l’ancien plugin. Cela facilite la migration. Lorsque la migration vous demande “Voulez-vous configurer le chiffrement avec le nouveau canal afin de prendre en charge les anciennes applications et faciliter la migration ?”, veuillez accepter. Cela ajoutera une nouvelle option “defaultChannel” à votre configuration Capacitor. Cela fera en sorte que votre application utilise le canal “encryption\_v2”. Cela garantira que le nouveau chiffrement n’est utilisé que par les applications qui le prennent en charge. Les applications qui n’ont pas reçu de mise à jour de l’app store continueront à utiliser le canal par défaut précédent. *** Maintenant, vous devez construire votre bundle JS et le télécharger vers le nouveau canal. Veuillez exécuter la commande suivante : ```bash npx @capgo/cli bundle upload --channel encryption_v2 ``` *** Ensuite, exécutez cette commande pour permettre aux applications de s’auto-assigner au canal “encryption\_v2” Caution Ceci est nécessaire pour que la nouvelle option “defaultChannel” fonctionne ```bash npx @capgo/cli channel set encryption_v2 --self-assign ``` *** Vous pouvez maintenant exécuter l’application ; elle utilisera le nouveau système de chiffrement. Pour télécharger le nouveau bundle JS vers l’ancien canal, il vous suffit d’exécuter la commande suivante : ```bash npx @capgo/cli bundle upload --channel production ``` *** Vous n’avez pas besoin de vous soucier de la configuration Capacitor, elle n’est jamais téléchargée vers Capgo. Lorsque tous les utilisateurs auront mis à jour leurs applications (cela peut prendre jusqu’à 3/4 mois), vous pourrez supprimer le “defaultChannel” de votre configuration Capacitor. Et ensuite, vous pourrez supprimer l’ancien canal avec la commande suivante : ```bash npx @capgo/cli channel delete encryption_v2 ``` *** Après avoir supprimé le canal “encryption\_v2”, toutes les applications qui l’utilisent comme canal par défaut commenceront à utiliser le canal “production”. # Aperçu Utilisez la fonctionnalité Live Updates de Capgo pour mettre à jour les bundles JavaScript de votre application à distance, en temps réel. Poussez les mises à jour JS directement vers vos utilisateurs sans passer par le processus de révision de l’app store pour corriger instantanément les bugs et déployer de nouvelles fonctionnalités. Note Les Live Updates sont limitées aux modifications des bundles JavaScript. Si vous devez mettre à jour du code natif, comme l’ajout ou la suppression d’un plugin ou la modification de la configuration native du projet, vous devrez soumettre une nouvelle version binaire native aux app stores. ## Comment fonctionnent les Live Updates Le système Live Update de Capgo comporte deux composants clés : 1. Le SDK Capgo, que vous installez dans votre application. Le SDK vérifie les mises à jour disponibles et les télécharge en arrière-plan. 2. Les canaux, qui vous permettent de cibler des mises à jour vers des groupes spécifiques d’utilisateurs. Vous pouvez utiliser les canaux pour gérer différentes versions, comme `Production`, `Staging` et `Dev`. Lorsque vous téléchargez un nouveau bundle JS sur Capgo et l’assignez à un canal, le SDK Capgo dans les applications configurées pour ce canal détectera la mise à jour et la téléchargera. Au prochain redémarrage de l’application, le nouveau bundle sera chargé. ## Démarrage Pour commencer à utiliser Live Updates, suivez ces étapes : 1. Complétez le [Démarrage rapide Capgo](/docs/getting-started/quickstart) pour configurer votre application dans Capgo et installer le SDK Capgo. 2. Dans votre code d’application, appelez `CapacitorUpdater.notifyAppReady()` après l’initialisation de votre application. Cela indique au SDK Capgo que votre application est prête à recevoir des mises à jour. 3. Construisez votre bundle JS et téléchargez-le sur Capgo : ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. Ouvrez votre application et attendez que la mise à jour se télécharge. Vous pouvez vérifier le statut avec : ```shell npx @capgo/cli@latest app debug ``` 5. Une fois la mise à jour téléchargée, fermez et rouvrez votre application pour charger le nouveau bundle. Consultez le guide [Déploiement des Live Updates](/docs/getting-started/deploy) pour plus de détails. ## Le CLI Capgo Le CLI Capgo est un outil puissant qui permet aux développeurs d’interagir avec les services de Capgo depuis leurs propres pipelines CI/CD. Avec le CLI, vous avez un contrôle précis sur le moment où les builds sont produits et déployés, vous permettant d’intégrer Capgo dans vos workflows d’entreprise existants. ### À quoi sert le CLI Capgo ? Le CLI Capgo est conçu pour les développeurs et les équipes qui ont besoin de plus de contrôle et de flexibilité dans leurs workflows de mise à jour en direct. En utilisant le CLI dans vos pipelines CI/CD, vous pouvez : * Décider exactement quand construire et déployer les mises à jour, plutôt que de vous fier à l’automatisation intégrée de Capgo * Insérer vos propres processus, comme la signature de code, les tests QA ou les approbations des gestionnaires, entre les étapes de build et de déploiement * Intégrer Capgo dans vos outils et workflows DevOps existants ### Authentification Pour utiliser le CLI Capgo, vous devrez vous authentifier avec votre clé API. Vous pouvez générer une clé API dans les paramètres de votre compte Capgo. Pour vous connecter et stocker en toute sécurité votre clé API, exécutez : ```shell npx @capgo/cli@latest login [API_KEY] ``` Cette commande sera alors sauvegardée pour une utilisation future. Vous n’aurez pas besoin de fournir votre clé API à chaque commande après vous être connecté. ### Différences clés avec les autres outils CLI Si vous êtes familier avec d’autres outils CLI de mise à jour en direct, il y a quelques points clés à noter concernant le CLI de Capgo : * Capgo utilise un seul CLI pour les cas d’utilisation de développement et de CI/CD, car Capgo se concentre uniquement sur l’ensemble des fonctionnalités de mise à jour en direct * Le CLI Capgo ne nécessite pas d’étape d’installation séparée. Il est intégré au package `@capgo/cli` et peut être exécuté directement en utilisant `npx` * Le CLI de Capgo est conçu spécifiquement pour le workflow de mise à jour en direct, il peut donc ne pas inclure certaines fonctionnalités ou commandes présentes dans des outils CLI plus généralistes ## Prochaines étapes [ Canaux](/docs/live-updates/channels/) [Apprenez à utiliser les canaux pour gérer différentes versions et cibler les mises à jour vers des utilisateurs spécifiques](/docs/live-updates/channels/) [ Retours en arrière](/docs/live-updates/rollbacks/) [Découvrez comment revenir à une version précédente du bundle JS si une mise à jour cause des problèmes](/docs/live-updates/rollbacks/) [ Comportement des mises à jour](/docs/live-updates/update-behavior/) [Personnalisez comment et quand les mises à jour sont téléchargées et appliquées dans votre application](/docs/live-updates/update-behavior/) [ Mises à jour rapides](/docs/live-updates/differentials/) [Apprenez à utiliser les mises à jour rapides pour accélérer le processus de mise à jour](/docs/live-updates/differentials/) # Gambaran Umum > Documentation détaillée des commandes CLI de Capgo Le CLI Capgo fournit un ensemble de commandes pour gérer vos applications et déploiements Capgo. Cette référence fournit des informations détaillées sur chaque commande disponible, y compris ses options et exemples d’utilisation ## Commandes [ init](/docs/cli/reference/init/) [Initialiser une nouvelle application Capgo](/docs/cli/reference/init/) [ login](/login/) [S’authentifier auprès du service Capgo](/login/) [ doctor](/docs/cli/reference/doctor/) [Vérifier votre configuration Capgo pour d’éventuels problèmes](/docs/cli/reference/doctor/) [ app](/docs/cli/reference/app/) [Gérer vos applications Capgo](/docs/cli/reference/app/) [ bundle](/docs/cli/reference/bundle/) [Gérer vos bundles d’applications](/docs/cli/reference/bundle/) [ channel](/docs/cli/reference/channel/) [Gérer vos canaux de diffusion](/docs/cli/reference/channel/) [ key](/docs/cli/reference/key/) [Gérer vos clés de signature d’application](/docs/cli/reference/key/) ## Intégration CI Pour automatiser votre travail, nous recommandons d’utiliser GitHub Actions pour pousser vos mises à jour vers Capgo. Consultez notre [tutoriel GitHub Actions](https://capgo.app/blog/automatic-build-and-release-with-github-actions/) pour plus d’informations N’oubliez pas de configurer les variables d’environnement de votre CI avec votre clé API Capgo ## Application de démonstration Pour un exemple complet d’une application Capgo avec intégration CI, consultez notre [application de démonstration sur GitHub](https://github.com/Cap-go/demo-app/) # compte La commande `account` vous permet de gérer votre compte Capgo ### id `npx @capgo/cli account id` Obtient votre ID de compte Options : * `-a, --apikey ` : Clé API à lier à votre compte # application La commande `app` vous permet de gérer vos applications Capgo ### add `npx @capgo/cli app add [appId]` Ajoute une nouvelle application à votre compte Capgo `[appId]` est l’ID de votre application au format `comexampleapp`. Consultez la [documentation Capacitor](https://capacitorjs.com/docs/cli/commands/init/) pour plus d’informations > 💡 Toutes les options seront devinées à partir de votre `capacitorconfigjson` si elles ne sont pas fournies Options : * `--icon [path]` : Chemin vers une icône personnalisée à afficher dans l’application web Capgo * `--name [name]` : Nom personnalisé à afficher dans la liste des applications * `--apikey [key]` : Clé API pour lier à votre compte * `--retention [days]` : Période de rétention des bundles d’applications en jours (par défaut : 0 = infini) ### set `npx @capgo/cli app set [appId]` Met à jour une application existante dans votre compte Capgo Options : * `--icon [path]` : Chemin vers une icône personnalisée à afficher dans l’application web Capgo * `--name [name]` : Nom personnalisé à afficher dans la liste des applications * `--retention [days]` : Période de rétention des bundles d’applications en jours (par défaut : 0 = infini) * `--apikey [key]` : Clé API pour lier à votre compte ### list `npx @capgo/cli app list [appId]` Liste toutes les applications de votre compte Capgo Options : * `--apikey [key]` : Clé API pour lier à votre compte ### delete `npx @capgo/cli app delete [appId]` Supprime une application de votre compte Capgo Options : * `--apikey [key]` : Clé API pour lier à votre compte * `--bundle` : Supprime uniquement une version spécifique du bundle ### debug `npx @capgo/cli app debug [appId]` Affiche les informations de débogage pour une application Options : * `--apikey [key]` : Clé API pour lier à votre compte * `--device` : Débogue un appareil spécifique ### setting `npx @capgo/cli app setting [path]` Modifie la configuration Capacitor pour une application `[path]` est le chemin vers le paramètre que vous souhaitez modifier (par exemple, `appId` ou `pluginsCapacitorUpdaterautoUpdate`) Vous devez fournir soit `--string` soit `--bool` : * `--string ` : Définit le paramètre sur une valeur de type chaîne * `--bool ` : Définit le paramètre sur une valeur booléenne # lot La commande `bundle` vous permet de gérer vos bundles d’application ### upload `npx @capgo/cli bundle upload [appId]` Téléverse un nouveau bundle pour une application Options : * `-a, --apikey ` : Clé API pour lier à votre compte * `-p, --path ` : Chemin vers le dossier à téléverser (par défaut le `webDir` dans `capacitorconfig`) * `-c, --channel ` : Canal auquel lier le bundle * `-e, --external ` : Lien vers une URL externe au lieu de téléverser vers Capgo Cloud * `--iv-session-key ` : Définir la clé IV et de session pour une URL de bundle externe * `--s3-region ` : Région pour votre bucket S3 * `--s3-apikey ` : Clé API pour votre endpoint S3 * `--s3-apisecret ` : Secret API pour votre endpoint S3 * `--s3-endpoint ` : URL de l’endpoint S3 * `--s3-bucket-name ` : Nom de votre bucket S3 * `--s3-port ` : Port pour votre endpoint S3 * `--no-s3-ssl` : Désactiver SSL pour les téléversements S3 * `--key ` : Chemin personnalisé pour la clé de signature publique (système v1) * `--key-data ` : Données de la clé de signature publique (système v1) * `--key-v2 ` : Chemin personnalisé pour la clé de signature privée (système v2) * `--key-data-v2 ` : Données de la clé de signature privée (système v2) * `--bundle-url` : Afficher l’URL du bundle dans stdout * `--no-key` : Ignorer la clé de signature et envoyer une mise à jour non signée * `--no-code-check` : Ignorer la vérification de `notifyAppReady()` dans le code source et `indexhtml` dans le dossier racine * `--display-iv-session` : Afficher la clé IV et de session utilisée pour chiffrer la mise à jour * `-b, --bundle ` : Numéro de version du bundle à téléverser * `--min-update-version ` : Version minimale de l’app requise pour appliquer cette mise à jour (utilisé uniquement si la mise à jour auto est désactivée via les métadonnées) * `--auto-min-update-version` : Définir automatiquement la version minimale de mise à jour basée sur les versions natives * `--ignore-metadata-check` : Ignorer la vérification des métadonnées (node\_modules) lors du téléversement * `--ignore-checksum-check` : Ignorer la vérification du checksum lors du téléversement * `--timeout ` : Délai d’expiration du processus de téléversement en secondes * `--multipart` : Utiliser le protocole multipart pour téléverser les données vers S3 (déprécié, utilisez `--tus` à la place) * `--tus` : Téléverser le bundle en utilisant le protocole tus * `--tus-chunk-size ` : Taille des chunks pour le téléversement tus * `--partial` : Téléverser uniquement les fichiers modifiés vers Capgo Cloud * `--partial-only` : Téléverser uniquement les fichiers partiels vers Capgo Cloud, en ignorant le fichier zippé (utile pour les gros bundles) * `--encrypted-checksum ` : Checksum chiffré (signature) pour un bundle externe * `--auto-set-bundle` : Définir automatiquement la version du bundle dans `capacitorconfigjson` * `--dry-upload` : Effectuer une simulation du processus de téléversement sans réellement téléverser les fichiers (utile pour les tests) * `--package-json ` : Liste de chemins vers les fichiers `packagejson` séparés par des virgules (utile pour les monorepos) * `--node-modules ` : Liste de chemins vers les répertoires `node_modules` séparés par des virgules (utile pour les monorepos) * `--encrypt-partial` : Chiffrer les fichiers de mise à jour partielle * `--delete-linked-bundle-on-upload` : Supprimer le bundle actuellement lié dans le canal cible avant le téléversement ### compatibility `npx @capgo/cli bundle compatibility [appId]` Vérifie la compatibilité d’un bundle avec un canal spécifique Options : * `-a, --apikey ` : Clé API pour lier à votre compte * `-c, --channel ` : Canal à vérifier pour la compatibilité * `--text` : Afficher les résultats en texte au lieu d’emoji * `--package-json ` : Liste de chemins vers les fichiers `packagejson` séparés par des virgules (utile pour les monorepos) * `--node-modules ` : Liste de chemins vers les répertoires `node_modules` séparés par des virgules (utile pour les monorepos) ### delete `npx @capgo/cli bundle delete [bundleId] [appId]` Supprime un bundle d’une application Options : * `-a, --apikey ` : Clé API pour lier à votre compte ### list `npx @capgo/cli bundle list [appId]` Liste tous les bundles d’une application Options : * `-a, --apikey ` : Clé API pour lier à votre compte ### cleanup `npx @capgo/cli bundle cleanup [appId]` Nettoie les anciens bundles d’une version majeure, en conservant le nombre spécifié des bundles les plus récents Options : * `-b, --bundle ` : Numéro de version majeure à nettoyer * `-a, --apikey ` : Clé API pour lier à votre compte * `-k, --keep ` : Nombre de bundles à conserver (par défaut : 4) * `-f, --force` : Forcer la suppression sans confirmation ### decrypt `npx @capgo/cli bundle decrypt [zipPath] [sessionKey]` Déchiffre un bundle zip signé Options : * `--key ` : Chemin personnalisé pour la clé de signature privée * `--key-data ` : Données de la clé de signature privée ### encrypt `npx @capgo/cli bundle encrypt [zipPath]` Chiffre un bundle zip Options : * `--key ` : Chemin personnalisé pour la clé de signature privée * `--key-data ` : Données de la clé de signature privée ### encryptV2 `npx @capgo/cli bundle encryptV2 [zipPath] [checksum]` Chiffre un bundle zip en utilisant la nouvelle méthode de chiffrement Options : * `--key ` : Chemin personnalisé pour la clé de signature privée * `--key-data ` : Données de la clé de signature privée * `-j, --json` : Afficher les résultats en JSON ### decryptV2 `npx @capgo/cli bundle decryptV2 [zipPath] [checksum]` Déchiffre un bundle zip en utilisant la nouvelle méthode de chiffrement Options : * `--key ` : Chemin personnalisé pour la clé de signature privée * `--key-data ` : Données de la clé de signature privée * `--checksum ` : Checksum du bundle pour vérifier l’intégrité ### zip `npx @capgo/cli bundle zip [appId]` Génère un fichier zip pour un bundle Options : * `-p, --path ` : Chemin vers le dossier à zipper (par défaut le `webDir` dans `capacitorconfig`) * `-b, --bundle ` : Numéro de version du bundle à utiliser dans le nom de fichier * `-n, --name ` : Nom de fichier personnalisé pour le zip * `-j, --json` : Afficher les résultats en JSON * `--no-code-check` : Ignorer la vérification de `notifyAppReady()` dans le code source et `indexhtml` dans le dossier racine * `--key-v2` : Utiliser la nouvelle méthode de chiffrement (v2) * `--package-json ` : Liste de chemins vers les fichiers `packagejson` séparés par des virgules (utile pour les monorepos) # chaîne La commande `channel` vous permet de gérer vos canaux de diffusion ### add `npx @capgo/cli channel add [channelId] [appId]` Crée un nouveau canal pour une application Options : * `-d, --default` : Définir le nouveau canal comme canal par défaut * `-a, --apikey ` : Clé API pour lier à votre compte ### delete `npx @capgo/cli channel delete [channelId] [appId]` Supprime un canal d’une application Options : * `-a, --apikey ` : Clé API pour lier à votre compte * `--delete-bundle` : Supprime le bundle associé au canal ### list `npx @capgo/cli channel list [appId]` Liste tous les canaux d’une application Options : * `-a, --apikey ` : Clé API pour lier à votre compte ### currentBundle `npx @capgo/cli channel currentBundle [channel] [appId]` Obtient le bundle actuel pour un canal spécifique Options : * `-c, --channel ` : Canal pour obtenir le bundle actuel * `-a, --apikey ` : Clé API pour lier à votre compte * `--quiet` : Affiche uniquement la version du bundle ### set `npx @capgo/cli channel set [channelId] [appId]` Définit les propriétés d’un canal Options : * `-a, --apikey ` : Clé API pour lier à votre compte * `-b, --bundle ` : Numéro de version du bundle à définir pour le canal * `-s, --state ` : Définit l’état du canal (`default` ou `normal`) * `--latest` : Utilise la dernière version de `packagejson` comme version du bundle * `--downgrade` : Autorise les rétrogradations vers des versions inférieures à la version native * `--no-downgrade` : Désactive les rétrogradations vers des versions inférieures à la version native * `--upgrade` : Autorise les mises à niveau vers des versions supérieures à la version native * `--no-upgrade` : Désactive les mises à niveau vers des versions supérieures à la version native * `--ios` : Autorise l’envoi de mises à jour aux appareils iOS * `--no-ios` : Désactive l’envoi de mises à jour aux appareils iOS * `--android` : Autorise l’envoi de mises à jour aux appareils Android * `--no-android` : Désactive l’envoi de mises à jour aux appareils Android * `--self-assign` : Autorise les appareils à s’auto-assigner à ce canal * `--no-self-assign` : Désactive l’auto-assignation des appareils à ce canal * `--disable-auto-update ` : Désactive la stratégie de mise à jour automatique pour ce canal (options : `major`, `minor`, `metadata`, `patch`, `none`) * `--dev` : Autorise l’envoi de mises à jour aux appareils de développement * `--no-dev` : Désactive l’envoi de mises à jour aux appareils de développement * `--emulator` : Autorise l’envoi de mises à jour aux émulateurs * `--no-emulator` : Désactive l’envoi de mises à jour aux émulateurs * `--package-json ` : Liste de chemins vers les fichiers `packagejson` séparés par des virgules (utile pour les monorepos) # médecin `npx @capgo/cli doctor` Cette commande vérifie si vous utilisez la dernière version des packages Capgo Elle est également utile pour le signalement de bugs # initialiser `npx @capgo/cli@latest init [apikey]` Cette commande vous guide étape par étape pour : * Ajouter votre application à Capgo * Ajouter le code à votre application pour valider la mise à jour * Construire votre application * Téléverser votre application sur Capgo * Vous aider à vérifier si la mise à jour fonctionne # clé La commande `key` vous permet de gérer les clés de signature de votre application ### save `npx @capgo/cli key save` Enregistre une clé de chiffrement encodée en base64 dans la configuration Capacitor (utile pour CI) Options : * `-f, --force` : Force la génération d’une nouvelle clé * `--key` : Chemin vers le fichier de clé à enregistrer dans la configuration Capacitor * `--key-data` : Données de clé à enregistrer directement dans la configuration Capacitor ### create `npx @capgo/cli key create` Crée une nouvelle clé de chiffrement Options : * `-f, --force` : Force la génération d’une nouvelle clé ### delete\_old `npx @capgo/cli key delete_old` Supprime l’ancienne clé de chiffrement # connexion `npx @capgo/cli login [apikey]` Cette commande stocke votre clé API Capgo pour une utilisation ultérieure Note Vous pouvez remplacer la clé API stockée en passant `--apikey=` à n’importe quelle commande Options: * `--local`: Stocke la clé API dans le dépôt local et l’ajoute à `gitignore` # FAQ > Questions fréquentes sur Capgo Si vous avez des questions qui n’ont pas été répondues ici, n’hésitez pas à les poser ! Vous pouvez créer une issue ou demander sur [Discord](https://discordcom/invite/VnYRvBfgA6) ### Qu’est-ce que le “code push” ?[](https://capgo.app/docs/#what-is-code-push "Lien direct vers Qu'est-ce que le \"code push\" ?") Le code push, également appelé “mises à jour en direct” (OTA), est un service cloud permettant aux développeurs Capacitor de déployer des mises à jour sur leurs applications en production. Capgo fonctionne actuellement sur Android et iOS et fonctionnera à terme partout où Capacitor fonctionne. “Code Push” fait référence au nom d’une fonctionnalité de déploiement utilisée par la communauté React Native de [Microsoft](https://appcenterms/) et [Expo](https://expodev/), qui ne prennent pas en charge Capacitor. ### Quelle est la différence entre un bundle et une release ?[](https://capgo.app/docs/faq/#what-is-the-difference-between-a-bundle-and-a-release "Lien direct vers Quelle est la différence entre un bundle et une release ?") Nous utilisons le terme “release” pour désigner la préparation d’un binaire pour les app stores. Pour générer ultérieurement un bundle, Capgo doit connaître le binaire exact qui a été envoyé aux app stores. Nous utilisons le terme “bundle” pour désigner un patch qui peut être appliqué à une release pour la mettre à jour avec du nouveau code. La commande `npx @capgo/cli app update` est utilisée pour générer un bundle à partir de votre nouveau code local qui est ensuite envoyé à vos utilisateurs. ### Quelle est la feuille de route ?[](https://capgo.app/docs/faq/#what-is-the-roadmap "Lien direct vers Quelle est la feuille de route ?") Nos tableaux de projet sont publics et disponibles sur : [https://github.com/orgs/Cap-go/projects](https://github.com/orgs/Cap-go/projects/) Notre équipe opère également en public, vous pouvez donc voir ce sur quoi nous travaillons à tout moment. Nous sommes heureux de répondre à toutes vos questions concernant notre feuille de route ou nos priorités via les issues Github ou [Discord](https://discordcom/invite/VnYRvBfgA6). ### Puis-je utiliser Capgo avec mon équipe ?[](https://capgo.app/docs/faq/#can-i-use-capgo-with-my-team "Lien direct vers Puis-je utiliser Capgo avec mon équipe ?") Oui ! Tous les plans supportent un nombre illimité de développeurs. Nous limitons uniquement les métriques d’application (MAU, stockage et bande passante) pour chaque organisation. Voir [Teams](https://capgo.app/pricing/) pour plus d’informations. ### Est-ce que Capgo stocke mon code source ?[](https://capgo.app/docs/faq/#does-capgo-store-my-source-code "Lien direct vers Est-ce que Capgo stocke mon code source ?") Non. Les serveurs Capgo ne voient jamais votre code source. Lorsque vous exécutez `npx @capgo/cli app update`, l’outil `npx @capgo/cli` ne télécharge que le code compilé que vous envoyez aux app stores. Si vous souhaitez une sécurité supplémentaire, vous pouvez utiliser le chiffrement de bout en bout pour chiffrer votre bundle avant de le télécharger sur les serveurs Capgo. Voir aussi notre politique de confidentialité : [https://capgo.app/privacy](https://capgo.app/privacy/) ### Puis-je utiliser Capgo depuis mon système CI ?[](https://capgo.app/docs/faq/#can-i-use-capgo-from-my-ci-system "Lien direct vers Puis-je utiliser Capgo depuis mon système CI ?") Oui. Capgo est conçu pour être utilisé depuis des systèmes CI. Nous avons publié un guide pour [Android et Github Actions](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) et [IOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/), Et pour [Gitlab](https://capgo.app/blog/setup-ci-and-cd-gitlab/), les autres systèmes CI devraient être similaires. N’hésitez pas à nous contacter via les issues GitHub ou Discord si vous rencontrez des problèmes. ### Quel est le rapport avec Firebase Remote Config ou Launch Darkly ?[](https://capgo.app/docs/faq/#how-does-this-relate-to-firebase-remote-config-or-launch-darkly "Lien direct vers Quel est le rapport avec Firebase Remote Config ou Launch Darkly ?") Le code push permet d’ajouter du nouveau code / remplacer du code sur l’appareil. Firebase Remote Config et Launch Darkly sont tous deux des systèmes de configuration. Ils vous permettent de modifier la configuration de votre application sans avoir à expédier une nouvelle version. Ils ne sont pas destinés à remplacer du code. ### Quelle est l’empreinte des dépendances ajoutées ?[](https://capgo.app/docs/faq/#how-big-of-a-dependency-footprint-does-this-add "Lien direct vers Quelle est l'empreinte des dépendances ajoutées ?") Je n’ai pas mesuré récemment, mais je m’attends à ce que la bibliothèque de code push ajoute moins d’un mégaoctet aux applications Capacitor. Nous connaissons des moyens de réduire cette taille lorsque cela deviendra une priorité. Si la taille est un blocage pour vous, faites-le nous savoir ! ### Le code push fonctionne-t-il avec les grandes applications ?[](https://capgo.app/docs/faq/#does-code-push-work-with-large-applications "Lien direct vers Le code push fonctionne-t-il avec les grandes applications ?") Oui. Il n’y a pas de limite sur la taille de l’application qui peut être mise à jour avec le code push. Comme indiqué [ci-dessous](https://capgo.app/docs/faq/#what-types-of-changes-does-capgo-code-push-support), Capgo peut modifier n’importe quel code JS dans votre application quelle que soit sa taille. À noter : Une taille plus importante rend plus difficile le téléchargement des mises à jour pour les utilisateurs. Nous recommandons de garder votre application aussi légère que possible. ### À quoi puis-je utiliser le code push de Capgo ?[](https://capgo.app/docs/faq/#what-can-i-use-capgo-code-push-for "Lien direct vers À quoi puis-je utiliser le code push de Capgo ?") Nous avons vu diverses utilisations, notamment : * Correctifs d’urgence pour les applications en production * Envoi de corrections de bugs aux utilisateurs sur les anciennes versions de votre application * Livraison constante (par exemple toutes les heures) Notez que la plupart des app stores interdisent l’envoi de code qui modifie significativement le comportement de l’application. Veuillez consulter [ci-dessous](https://capgo.app/docs/faq/#how-does-this-relate-to-the-appplay-store-review-process-or-policies) pour plus d’informations. ### Qu’est-ce qui compte comme un “MAU” pour Capgo ?[](https://capgo.app/docs/faq/#what-counts-as-a-mau-for-capgo "Lien direct vers Qu'est-ce qui compte comme un \"MAU\" pour Capgo ?") Un MAU est un “Utilisateur Actif Mensuel”. Nous comptons un MAU comme tout appareil qui a contacté nos serveurs au cours des 30 derniers jours. Nous ne comptons pas les appareils qui n’ont pas contacté nos serveurs au cours des 30 derniers jours. Chaque fois qu’un appareil installe à nouveau votre application, un nouveau MAU est compté, cela se produit en raison des limitations de confidentialité de l’App Store. Nous ne pouvons pas suivre le même appareil si l’utilisateur réinstalle l’application. Pendant le développement, chaque fois que vous réinstallez l’application, un nouveau MAU est compté. Il en va de même pour les téléchargements Testflight ou le changement de canal sur Android. La mise à jour de l’application ne crée pas un nouvel ID d’appareil. > Nous recommandons après la première configuration de désactiver les appareils de développement et l’émulateur pour réduire le nombre d’appareils dupliqués. ### Que ne pouvons-nous pas faire avec le code push de Capgo ?[](https://capgo.app/docs/faq/#what-cant-we-use-capgo-code-push-for "Lien direct vers Que ne pouvons-nous pas faire avec le code push de Capgo ?") Comme mentionné ci-dessus, Capgo ne doit pas être utilisé pour violer les politiques des app stores. Veuillez consulter [ci-dessous](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines) pour plus d’informations. De plus, Capgo ne prend pas en charge la modification du code natif (par exemple Java/Kotlin sur Android ou Objective-C/Swift sur iOS). L’outil vous avertira lors d’une tentative de mise à jour si vous avez modifié du code natif. ### Est-ce que Capgo soumet aux stores pour moi ?[](https://capgo.app/docs/faq/#does-capgo-submit-to-the-stores-for-me "Lien direct vers Est-ce que Capgo soumet aux stores pour moi ?") Capgo ne prend actuellement pas en charge la soumission aux app stores en votre nom. Nous prévoyons d’ajouter cette fonctionnalité à l’avenir, mais pour l’instant, vous devrez continuer à utiliser vos processus existants pour soumettre aux app stores. Vous pouvez utiliser notre [guide CI Android](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) pour automatiser ce processus et [guide CI iOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/). ### Que stocke Capgo sur le disque et où ?[](https://capgo.app/docs/faq/#what-does-capgo-store-on-disk-and-where "Lien direct vers Que stocke Capgo sur le disque et où ?") Le système de mise à jour Capgo (inclus dans votre application lors de la compilation) met en cache le dernier bundle téléchargé dans le seul répertoire que Capacitor autorise pour charger du code. Sur Android, il est situé dans `/data/user/0/comexampleapp/code_cache/capgo_updater` bien que le début de ce chemin soit fourni par le système Android et puisse changer dynamiquement lors de l’exécution. Sur les appareils iOS, les données sont stockées sous `Library/Application Support/capgo`. Les outils en ligne de commande Capgo (par exemple`npx @capgo/cli app update`) sont installés sur le disque dans les caches npm, vos identifiants sont stockés dans votre répertoire personnel dans `~/capgo` ### Quel est le rapport avec le Hot Reload de Capacitor? Le Hot reload de Capacitor est une fonctionnalité uniquement pour le développement. Code push est pour la production. Le Hot reload est une fonctionnalité de Capacitor qui permet de modifier le code sur l’appareil pendant le développement. Il nécessite de construire l’application Capacitor avec un proxy pour se connecter à votre machine locale. Code push est une fonctionnalité qui permet de modifier le code sur l’appareil en production. Nous utiliserons différentes techniques pour rendre cela possible selon la plateforme. ### Quels types de modifications le code push de Capgo prend-il en charge? Capgo peut modifier n’importe quel code JS dans votre application. Cela inclut le code de l’application et le code généré. Vous pouvez également mettre à jour les dépendances dans `packages.json` tant qu’elles ne nécessitent pas de modifications du code natif. Nous n’avons pas prévu de prendre en charge la modification du code natif (par exemple Java/Kotlin sur Android ou Objective-C/Swift sur iOS), et l’outil vous avertira s’il détecte que vous avez modifié du code natif car il ne sera pas inclus dans le bundle. ### Est-ce que cela prend en charge le Web? Le code push n’est pas nécessaire pour le web car le web fonctionne déjà de cette façon. Lorsqu’un utilisateur ouvre une application web, il télécharge la dernière version depuis le serveur si nécessaire. Si vous avez un cas d’utilisation pour le code push avec le web, nous aimerions le savoir ! ### Est-ce que cela fonctionnera sur iOS, Android, Mac, Windows, Linux, etc? Oui. Jusqu’à présent, nous nous sommes concentrés sur le support Android et iOS, mais le code push fonctionnera partout où Capacitor fonctionne. Nous nous assurons d’avoir construit toute l’infrastructure nécessaire pour fournir le code push de manière fiable et sûre avant de l’étendre à d’autres plateformes. ### Quelles versions d’OS Capgo prend-il en charge? Capgo prend en charge les mêmes versions d’Android que Capacitor. Capacitor prend actuellement en charge Android API niveau 22+ et iOS 13.0+ : [https://capacitorjs.com/docs/main/reference/support-policy](https://capacitorjs.com/docs/main/reference/support-policy/) ### Quelles versions de Capacitor Capgo prend-il en charge? Capgo ne prend actuellement en charge que les versions stables récentes de Capacitor. Nous pourrions prendre en charge des versions plus anciennes de Capacitor également, nous n’avons simplement pas construit l’infrastructure nécessaire pour maintenir cela dans le temps. Nous avons l’intention de prendre en charge plus de versions de Capacitor à l’avenir, y compris n’importe quelle version pour nos clients entreprise [https://github.com/Cap-go/capgo/issues/1100](https://github.com/Cap-go/capgo/issues/1100/) Capgo suit la version stable de Flutter et se met généralement à jour dans les quelques heures suivant une version stable. Notre système pour effectuer ces mises à jour est automatisé et prend quelques minutes à s’exécuter. Nous effectuons ensuite une étape de vérification manuelle supplémentaire avant la publication sur nos serveurs. ### Quel est le rapport avec le processus de révision ou les politiques de l’App/Play Store? Les développeurs sont liés par leurs accords avec les fournisseurs de magasins lorsqu’ils choisissent d’utiliser ces magasins. Code push est conçu pour permettre aux développeurs de mettre à jour leurs applications tout en respectant les politiques des magasins sur iOS et Android. Similaire à la variété de produits commerciaux disponibles pour le faire avec React Native (par exemple [Microsoft](https://appcenter.ms/), [Expo](https://expo.dev/)) Microsoft publie également un guide sur la façon dont leur solution est conforme aux magasins d’applications : [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) Code push est une technique largement utilisée dans les magasins d’applications. Toutes les grandes applications que je connais utilisent le code push. La principale politique à connaître est de ne pas modifier le comportement de l’application de manière significative. Veuillez voir [ci-dessous](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines) pour plus d’informations. ### Est-ce que Capgo est conforme aux directives du Play Store? Oui. Le Play Store impose deux restrictions concernant les outils de mise à jour : 1. Les mises à jour doivent utiliser un interpréteur ou une machine virtuelle (Capgo utilise la Machine Virtuelle Dart) [https://support.google.com/googleplay/android-developer/answer/9888379?hl=en](https://support.google.com/googleplay/android-developer/answer/9888379/?hl=en) ```plaintext Une application distribuée via Google Play ne peut pas se modifier, se remplacer ou se mettre à jour
en utilisant une méthode autre que le mécanisme de mise à jour de Google Play. De même, une application
ne peut pas télécharger de code exécutable (comme des fichiers dex, JAR, so) depuis une
source autre que Google Play. *Cette restriction ne s'applique pas au code
qui s'exécute dans une machine virtuelle ou un interpréteur* où l'un ou l'autre fournit
un accès indirect aux API Android (comme JavaScript dans une webview ou
navigateur)

Les applications ou le code tiers, comme les SDK, avec des langages interprétés (JavaScript,
Python, Lua, etc.) chargés à l'exécution (par exemple, non inclus dans
l'application) ne doivent pas permettre de violations potentielles des politiques de Google Play
``` 2. Les modifications apportées à l’application ne doivent pas être trompeuses (par exemple, changer le but de l’application via une mise à jour) [https://support.google.com/googleplay/android-developer/answer/9888077](https://support.google.com/googleplay/android-developer/answer/9888077/) Veuillez être clair avec vos utilisateurs sur ce que vous fournissez avec votre application et ne pas violer leurs attentes avec des changements comportementaux significatifs via l’utilisation de Capgo. Capgo est conçu pour être compatible avec les directives du Play Store. Cependant, Capgo est un outil, et comme tout outil, il peut être abusé. Abuser délibérément de Capgo pour violer les directives du Play Store est en violation des [Conditions d’utilisation](https://capgo.app/tos/) de Capgo et peut entraîner la résiliation de votre compte. Enfin, les services de code push sont largement utilisés dans l’industrie (toutes les grandes applications que je connais les utilisent) et il existe plusieurs autres services de code push publiquement disponibles (par exemple expo.dev & appcenter.ms). C’est un chemin bien tracé. Microsoft publie également un guide sur la façon dont leur bibliothèque “codepush” pour react native est conforme aux magasins d’applications : [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### Est-ce que Capgo est conforme aux directives de l’App Store? Oui. Similaire au Play Store, l’App Store propose des restrictions techniques et politiques. ````plaintext 3.2.2
```Le code interprété peut être téléchargé dans une Application uniquement si
ce code :
(a) ne change pas l'objectif principal de l'Application en fournissant
des fonctionnalités qui ne sont pas cohérentes avec l'objectif prévu et
annoncé de l'Application telle que soumise à l'App Store,
(b) ne crée pas de magasin ou de vitrine pour d'autres codes ou applications, et
(c) ne contourne pas la signature, le bac à sable ou d'autres fonctionnalités de sécurité du système d'exploitation
Capgo utilise un interpréteur Dart personnalisé pour se conformer à la restriction interpréteur-uniquement pour les mises à jour sur iOS. Tant que votre application n'adopte pas un comportement trompeur via les mises à jour (par exemple, changer l'objectif de l'application via la mise à jour), la mise à jour via Capgo (ou toute autre solution de code push) est une pratique standard de l'industrie et conforme aux directives de l'App Store. L'utilisation abusive délibérée de Capgo pour violer les directives de l'App Store est une violation des [Conditions d'utilisation](https://capgo.app/tos/) de Capgo et peut entraîner la résiliation de votre compte. Microsoft publie également un guide sur la façon dont leur bibliothèque react native "codepush" est conforme aux app stores : [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### Puis-je utiliser Capgo dans mon pays ?[](https://capgo.app/docs/faq/#can-i-use-capgo-in-my-country "Lien direct vers Puis-je utiliser Capgo dans mon pays ?") Nous n'avons pas tenté de restreindre l'accès à Capgo depuis aucun pays. Nous reconnaissons que certains pays ont des restrictions sur les URLs accessibles depuis leur territoire. Capgo utilise actuellement Cloudflare Cloud pour l'hébergement, y compris R2 Storage et Cloudflare workers. Les URLs suivantes sont utilisées par Capgo : - [https://apicapgo.app](https://apicapgo.app/) -- utilisé par les outils en ligne de commande `npx @capgo/cli` pour interagir avec les serveurs Capgo ainsi que le système de mise à jour Capgo sur les appareils des utilisateurs pour vérifier les mises à jour - [https://*r2cloudflarestoragecom](https://*r2cloudflarestoragecom/) -- utilisé par l'outil en ligne de commande `npx @capgo/cli` pour télécharger et téléverser les bundles Si toutes ces URLs sont accessibles depuis votre pays, alors Capgo devrait fonctionner. Si votre région nécessite de bloquer l'accès à l'une de ces URLs, veuillez nous en informer et nous pourrons travailler avec vous pour trouver une solution. Les serveurs proxy sont une option. ### Puis-je auto-héberger Capgo ?[](https://capgo.app/docs/faq/#can-i-self-host-capgo "Lien direct vers Puis-je auto-héberger Capgo ?") Oui, vous pouvez auto-héberger Capgo. Le guide n'est pas encore écrit, mais le code est open source et disponible sur [https://github.com/cap-go/capgo](https://github.com/cap-go/capgo/) ### Le code push nécessite-t-il Internet pour fonctionner ?[](https://capgo.app/docs/faq/#does-code-push-require-the-internet-to-work "Lien direct vers Le code push nécessite-t-il Internet pour fonctionner ?") Oui. On pourrait imaginer faire fonctionner un serveur pour distribuer les mises à jour séparément d'Internet, mais une forme de connectivité réseau est nécessaire pour transporter les mises à jour vers les appareils. ### Comment Capgo est-il affecté par le manque de connectivité réseau ?[](https://capgo.app/docs/faq/#how-is-capgo-affected-by-lack-of-network-connectivity "Lien direct vers Comment Capgo est-il affecté par le manque de connectivité réseau ?") Le système de mise à jour Capgo (inclus dans votre application lorsque vous compilez votre app avec Capgo) est conçu pour être résilient aux problèmes de connectivité réseau. Dans le comportement de mise à jour par défaut, lorsque l'application démarre, elle alerte le système de mise à jour Capgo, qui lance un thread séparé pour faire une requête réseau aux serveurs Capgo et demander une mise à jour. Nous utilisons intentionnellement un thread séparé pour éviter d'affecter ou de bloquer toute autre chose que l'application pourrait faire. Si la requête réseau échoue ou expire, le système de mise à jour essaiera simplement de vérifier à nouveau au prochain lancement de l'application. Les outils en ligne de commande Capgo (par exemple `npx @capgo/cli app update`) nécessitent une connectivité réseau pour fonctionner. Si vous utilisez Capgo pour distribuer votre application, vous devez vous assurer que votre système CI dispose d'une connectivité réseau. ### Que se passe-t-il si un utilisateur ne met pas à jour pendant longtemps et manque une mise à jour ?[](https://capgo.app/docs/faq/#what-happens-if-a-user-doesnt-update-for-a-long-time-and-misses-an-update "Lien direct vers Que se passe-t-il si un utilisateur ne met pas à jour pendant longtemps et manque une mise à jour ?") Notre implémentation envoie toujours une mise à jour spécifiquement adaptée à l'appareil qui la demande, mettant à jour le demandeur toujours vers la dernière version disponible. Ainsi, si un utilisateur ne met pas à jour pendant un certain temps, il "manquera" les mises à jour intermédiaires. Le serveur de mise à jour pourrait être modifié pour prendre en charge la réponse avec soit la prochaine version incrémentielle, soit la dernière version selon les besoins de votre application. Veuillez nous informer si des comportements de mise à jour alternatifs sont importants pour vous. ### Quel est le rapport entre Capgo et Capacitor ?[](https://capgo.app/docs/faq/#how-does-capgo-relate-to-capacitor "Lien direct vers Quel est le rapport entre Capgo et Capacitor ?") Capgo est un plugin pour Capacitor qui ajoute le code push. Capgo n'est pas un remplacement pour Capacitor. Vous pouvez continuer à utiliser les outils Capacitor que vous connaissez et appréciez déjà. Nous suivons la dernière version stable de Capacitor et mettons à jour notre plugin de code push pour qu'il fonctionne avec elle. ### Quand les mises à jour se produisent-elles ?[](https://capgo.app/docs/faq/#when-do-updates-happen "Lien direct vers Quand les mises à jour se produisent-elles ?") Par défaut, le système de mise à jour Capgo vérifie les mises à jour au démarrage de l'application. Il s'exécute sur un thread en arrière-plan et ne bloque pas le thread UI. Toutes les mises à jour seront installées pendant que l'utilisateur utilise l'application et seront appliquées au prochain redémarrage de l'application. Il est également possible d'exécuter le système de mise à jour Capgo manuellement en utilisant [package:capgo_code_push](https://pubdev/packages/capgo_code_push/), à travers lequel il est possible de déclencher des mises à jour à tout moment, y compris via une notification push. Le système de mise à jour Capgo est conçu de telle sorte que lorsque le réseau n'est pas disponible, ou que le serveur est en panne ou autrement inaccessible, l'application continuera à fonctionner normalement. Si vous choisissez un jour de supprimer une mise à jour de nos serveurs, tous vos clients continueront à fonctionner normalement. Nous avons ajouté la possibilité de revenir en arrière sur les correctifs. La chose la plus simple est simplement d'attacher un bundle précédent à votre canal pour annuler. ### Dois-je garder mon app_id secret ?[](https://capgo.app/docs/faq/#do-i-need-to-keep-my-app_id-secret "Lien direct vers Dois-je garder mon app_id secret ?") Non. L'`app_id` est inclus dans votre application et peut être public en toute sécurité. Vous pouvez le versionner (même publiquement) et ne pas vous inquiéter que quelqu'un d'autre y accède. Quelqu'un qui a votre `app_id` peut récupérer la dernière version de votre application depuis les serveurs Capgo, mais ne peut pas pousser de mises à jour vers votre application ou accéder à tout autre aspect de votre compte Capgo. ### Quelles informations sont envoyées aux serveurs Capgo ?[](https://capgo.app/docs/faq/#what-information-is-sent-to-capgo-servers "Lien direct vers Quelles informations sont envoyées aux serveurs Capgo ?") Bien que Capgo se connecte au réseau, il n'envoie aucune information personnellement identifiable. L'inclusion de Capgo ne devrait pas affecter vos déclarations pour le Play Store ou l'App Store. Les requêtes envoyées depuis l'application aux serveurs Capgo incluent : - app_id (spécifié dans `capacitorconfigjson`) - channel (optionnel dans `capacitorconfigjson`) - release_version (versionName depuis AndroidManifestxml ou CFBundleShortVersionString depuis Infoplist ou `capacitorconfigjson` si défini dans [`CapacitorUpdaterversion`](/docs/plugin/settings/#version)) - version_number (généré dans le cadre de `npx @capgo/cli app update`) - os_version (par exemple '1121') - platform (par exemple 'android', nécessaire pour envoyer le bon correctif) C'est tout. Le code pour cela se trouve dans `updater/library/src/networkrs` - device_id (généré sur l'appareil lors de la première exécution, utilisé pour dédupliquer les installations par appareil et nous permettre de facturer en fonction des utilisateurs installés)utilisateurs actifs mensuels), plutôt que le nombre total de correctifs ou d'installations de correctifs) - custom_id (optionnel, défini lors de l'exécution par le développeur, utilisé pour lier un appareil à un utilisateur dans votre système) ### Quelles plateformes Capgo prend-il en charge ? Actuellement, Capgo prend en charge iOS et Android. Les deux sont prêts pour la production. L'utilisation de Capgo pour iOS ou Android peut être décidée indépendamment. Vous pouvez configurer votre canal pour déployer sur Android et un ipa construit pour l'App Store ou vice versa. Capgo peut (relativement facilement) être adapté pour prendre en charge les cibles desktop ou embarquées. Si celles-ci sont importantes pour vous, faites-le nous savoir. ### Comment Capgo interagit-il avec les Play Testing Tracks ou Apple TestFlight ? Chacun des app stores dispose de mécanismes séparés pour distribuer des applications à des groupes limités d'utilisateurs (par exemple "test interne", "bêta fermée", etc.). Ce sont tous des mécanismes pour segmenter vos utilisateurs en groupes et distribuer des versions spécifiques de vos applications à chacun. Malheureusement, ces mécanismes ne permettent pas tous aux tiers de détecter quand les applications sont installées dans une Test Track spécifique ou via TestFlight. Ainsi, nous n'avons pas une visibilité fiable sur la composition de ces groupes et ne pouvons pas restreindre de manière fiable l'accès aux correctifs Capgo basés sur ces groupes. [https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play](https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play/) [https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i](https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i/) Si vous souhaitez segmenter la disponibilité du bundle Capgo, il existe 4 options potentielles : 1. Utiliser un canal séparé pour chaque groupe. C'est l'approche la plus simple, mais nécessite de gérer plusieurs canaux. Vous avez peut-être déjà des canaux de dev et de prod avec différentes disponibilités. Vous pouvez ainsi mettre à jour vos canaux de dev, les vérifier puis mettre à jour séparément vos canaux de prod. Nous recommandons d'utiliser des branches / tags dans votre contrôle de version pour garder une trace des sources associées à chaque version. 2. Suivre votre propre ensemble d'utilisateurs inscrits, désactiver les mises à jour automatiques et déclencher les mises à jour uniquement pour certains utilisateurs via package:capgo_code_push. Cela fonctionne aujourd'hui, mais nécessite de gérer votre propre liste d'inscription. 3. Capgo permet de créer son propre mécanisme d'inscription par appareil (similaire à Test Tracks ou TestFlight, mais agnostique de la plateforme). Cela permet à votre équipe QA de s'inscrire aux bundles avant qu'ils ne soient promus au grand public. 4. Capgo propose des déploiements basés sur le pourcentage. Cela ne vous permet pas de choisir quels appareils envoyer, mais peut vous aider à déployer progressivement et à revenir en arrière à la vue de tout problème. ## Facturation ### Comment puis-je améliorer ou rétrograder mon forfait ? Vous pouvez améliorer ou rétrograder votre forfait à tout moment dans votre tableau de bord : [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Quand ma période de facturation est-elle réinitialisée ? Les périodes de facturation sont réinitialisées automatiquement chaque mois le mois où vous vous êtes abonné à Capgo. Par exemple, si vous vous êtes abonné le 15 du mois, votre période de facturation sera réinitialisée le 15 de chaque mois. ### Comment puis-je annuler mon abonnement ? Vous pouvez annuler votre abonnement à tout moment dans votre tableau de bord : [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Puis-je payer pour une année à l'avance ? Oui, vous pouvez le faire à tout moment dans votre tableau de bord : [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Statistiques et analyses Les statistiques dans votre tableau de bord sont mises à jour chaque minuit UTC. Les statistiques sont calculées sur la base du nombre de [MAU](https://capgo.app/docs/faq/#what-is-the-difference-between-a-bundle-and-a-release) qui ont été installés sur vos appareils. # Comment l'ID de l'appareil est-il généré L'ID de l'appareil est généré sur l'appareil lors de la première exécution, et est utilisé pour dédupliquer les installations par appareil et nous permettre de facturer en fonction des utilisateurs installés (par exemple, les utilisateurs actifs mensuels), plutôt que le nombre total de correctifs ou d'installations de correctifs. MAU est une meilleure solution que le nombre d'installations pour tarifer Capgo, car il est plus précis et reflète le coût réel de Capgo par appareil. Pour des raisons de confidentialité, nous ne pouvons pas suivre le même appareil si l'utilisateur réinstalle l'application. Les règles de confidentialité sont imposées par Apple et Google, et ne sont pas imposées par Capgo. L'ID de l'appareil ne sera pas répertorié dans votre liste d'appareils tant qu'ils n'auront pas reçu leur premier correctif installé. # Pourquoi mon nombre d'appareils est-il différent de mon MAU ? Actuellement, la liste des appareils n'est pas mise à jour aussi souvent que le MAU. La liste des appareils est mise à jour uniquement lorsqu'un appareil installe une mise à jour. Alors que le MAU est mis à jour à chaque lancement d'application. C'est une limitation actuelle de la plateforme. Notre plateforme d'analyse ne prend pas en charge les mises à jour brutes, nous utilisons donc une base de données conventionnelle pour la liste des appareils. Pour limiter le nombre de requêtes de base de données, nous mettons à jour les lignes uniquement lors de la mise à jour de l'application. Cette limitation sera supprimée à l'avenir. # Comment avoir différentes mises à jour par plateforme ? Vous pouvez créer un canal pour chaque plateforme et désactiver les mises à jour spécifiques à la plateforme dans chaque canal. Sur le canal iOS, désactivez les mises à jour Android et sur le canal Android, désactivez les mises à jour iOS. Ensuite, téléchargez un bundle sur chaque canal pour avoir différentes mises à jour pour chaque plateforme. Si vous avez besoin d'avoir la même mise à jour pour les deux plateformes, vous pouvez lier un bundle à plusieurs canaux. Pas besoin de dupliquer le bundle. ```` # Support technique pour capgo > Comment obtenir de l'aide pour capgo ## Support par Discord Capgo dispose d’un [serveur Discord](https://discordcom/invite/VnYRvBfgA6) officiel. Obtenir une assistance technique là-bas est probablement l’un des moyens les plus rapides d’obtenir une réponse. Voici un guide rapide : 1. * rendez-vous sur le canal `questions` ![Ask on discord](/discord-questions.webp) 2. * créez votre fil de discussion ![Create a question on discord](/discord-newquestion.webp) 3. * Décrivez votre problème et sélectionnez les tags pertinents ![Create a post on discord](/discord-new-post.webp) 4. * Partagez votre identifiant de compte sécurisé (optionnel) Cela permettra à l’équipe de Capgo d’examiner votre compte. Le partage de cet identifiant est sûr, car il a été conçu pour être partagé publiquement. Pour le partager, rendez-vous dans les [paramètres de Capgo](https://web.capgo.app/dashboard/settings/account/). Cliquez ensuite sur `copy account id` ![Share your id without leaking your info](/share-secure-id.webp) Cela copiera l’identifiant de compte sécurisé dans le presse-papiers. Veuillez inclure cet identifiant dans votre message Discord. ## Support par email C’est le moyen le plus lent d’obtenir de l’aide. Veuillez d’abord utiliser le serveur Discord. Si vous devez nous contacter par email, veuillez envoyer un message à # Ajouter une App > Ajoutez une application à votre compte Capgo et installez des plugins dans l'application ## Introduction à Capgo [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## Les mises à jour en direct en 3 étapes ### Configuration guidée 1. Créez votre compte sur ![capture d'écran d'inscription](/signup.webp "capture d'écran d'inscription") 2. Utilisez la commande Init pour commencer ```bash npx @capgo/cli@latest init [APIKEY] ``` Une série de questions vous sera présentée. Fournissez les réponses nécessaires pour compléter la configuration automatisée Tip En suivant ces étapes, vous serez opérationnel en un rien de temps. Si vous avez besoin d’aide pendant le processus, notre équipe de support est [là pour vous aider](https://support.capgo.app) Bon démarrage ! 3. Déployez une mise à jour en direct [Déployer une mise à jour en direct ](/docs/getting-started/deploy/)Apprenez comment déployer une mise à jour en direct pour votre application ### Configuration manuelle Si la commande init ne fonctionne pas pour vous, vous pouvez ajouter une application manuellement 1. Connectez le CLI à votre compte : ```bash npx @capgo/cli@latest login [APIKEY] ``` 2. Ajoutez l’application à votre compte avec cette commande : ```bash npx @capgo/cli@latest app add [APP_NAME] ``` 3. Installez le plugin dans votre application : ```json { "plugins": { CapacitorUpdater: { "appId": "Your appID", "autoUpdate": true, "version": "1.0.0" } } } ``` 4. Appelez la méthode init le plus tôt possible dans votre application : ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; CapacitorUpdater.notifyAppReady(); ``` 5. Déployez une mise à jour en direct [Déployer une mise à jour en direct ](/docs/getting-started/deploy/)Apprenez comment déployer une mise à jour en direct pour votre application # Intégration CI/CD L’intégration de Capgo dans votre pipeline CI/CD vous permet d’automatiser complètement le processus de construction et de déploiement des mises à jour de votre application. En utilisant le CLI Capgo et semantic-release, vous pouvez garantir des déploiements cohérents et fiables et permettre une itération rapide. ## Avantages de l’intégration CI/CD * **Automatisation** : Plus d’étapes manuelles ni de place pour l’erreur humaine. Tout votre processus de construction, de test et de déploiement peut être automatisé de bout en bout. * **Cohérence** : Chaque déploiement suit le même ensemble d’étapes, garantissant un processus prévisible et reproductible. C’est particulièrement précieux lorsque vous avez plusieurs membres d’équipe qui contribuent au code. * **Itérations plus rapides** : Avec les déploiements automatisés, vous pouvez livrer des mises à jour plus fréquemment et en toute confiance. Plus besoin d’attendre l’approbation manuelle de l’AQ ou des versions. ## CLI Capgo Le CLI Capgo est la clé pour intégrer Capgo dans votre workflow CI/CD. Il fournit des commandes pour pousser de nouvelles versions de bundles, gérer les canaux, et plus encore. La commande la plus importante pour l’intégration CI/CD est `upload` : ```shell npx @capgo/cli@latest bundle upload --channel=Production --apikey YOUR_API_KEY ``` Cette commande télécharge la construction web actuelle vers le canal spécifié. Vous l’exécuterez généralement comme dernière étape de votre pipeline CI/CD, après que votre construction web s’est terminée avec succès. ## Configuration de Capgo dans votre pipeline CI/CD Bien que les étapes exactes varient selon votre outil CI/CD, le processus général d’intégration de Capgo ressemble à ceci : 1. **Générer une clé API** : Connectez-vous au tableau de bord Capgo et créez une nouvelle clé API. Cette clé sera utilisée pour authentifier le CLI dans votre environnement CI/CD. Gardez-la secrète et ne la committez jamais dans votre dépôt ! 2. **Configurer la commande `upload`** : Ajoutez une étape à votre configuration CI/CD qui exécute la commande `upload` avec les arguments appropriés : upload.yml ```yaml - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secrets.CAPGO_API_KEY }} ``` \n Remplacez `Production` par le canal vers lequel vous souhaitez déployer, et `${{ secrets.CAPGO_API_KEY }}` par la variable d’environnement contenant votre clé API. 3. **Ajouter l’étape `upload` après votre construction web** : Assurez-vous que l’étape `upload` vient après que votre construction web s’est terminée avec succès. Cela garantit que vous déployez toujours votre code le plus récent.\n Voici un exemple de configuration pour GitHub Actions :\n upload.yml ```yaml name: Deploy to Capgo on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v4 with: node-version: 18 - run: npm ci - run: npm run build - run: npm install -g @capgo/cli - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secrets.CAPGO_API_KEY }} ``` ## Intégration de Semantic-release Semantic-release est un outil puissant pour automatiser la gestion des versions et générer des notes de version. En intégrant semantic-release avec Capgo, vous pouvez automatiquement incrémenter la version de votre application et générer des journaux de modifications à chaque déploiement. Voici un exemple de fichier de configuration `releaserc` pour semantic-release : ```json { "branches": [ "main", { "name": "beta", "prerelease": true } ], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", [ "@semantic-release/exec", { "publishCmd": "npx @capgo/cli@latest bundle upload --channel=${nextRelease.channel} --apikey YOUR_API_KEY --partial" } ], [ "@semantic-release/git", { "assets": ["CHANGELOG.md", "package.json"], "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" } ] ] } ``` Cette configuration fait ce qui suit : 1. Analyse les messages de commit pour déterminer le prochain numéro de version, suivant la spécification Conventional Commits 2. Génère des notes de version basées sur les commits depuis la dernière version 3. Met à jour le fichier `CHANGELOG.md` avec les nouvelles notes de version 4. Exécute la commande `upload` du CLI Capgo, en passant le nouveau numéro de version et en utilisant le flag `--partial` pour les mises à jour différentielles 5. Commit les fichiers `CHANGELOG.md`, `package.json` et tout autre fichier modifié dans le dépôt Pour utiliser semantic-release avec Capgo, ajoutez simplement une étape à votre configuration CI/CD qui exécute `npx semantic-release`. Assurez-vous que cette étape vient après votre construction web et avant l’étape `upload` de Capgo. ## Dépannage Si vous rencontrez des problèmes avec votre intégration CI/CD Capgo, voici quelques points à vérifier : * **Clé API** : Assurez-vous que votre clé API est valide et dispose des permissions nécessaires. Si vous utilisez une variable d’environnement, vérifiez qu’elle est correctement définie. * **Version du CLI** : Assurez-vous d’utiliser la dernière version du CLI Capgo. Les anciennes versions peuvent avoir des problèmes de compatibilité ou manquer certaines fonctionnalités. * **Artefacts de construction** : Confirmez que votre construction web génère les fichiers de sortie attendus. Le CLI Capgo a besoin d’une construction web valide pour créer un bundle. * **Connectivité réseau** : Vérifiez que votre environnement CI/CD a accès au réseau des serveurs Capgo. Les problèmes de pare-feu ou de proxy peuvent parfois interférer avec la commande `upload`. Si vous rencontrez toujours des difficultés, contactez le support Capgo. Ils peuvent vous aider à résoudre les problèmes liés à votre configuration spécifique. ## Conclusion L’intégration de Capgo dans votre pipeline CI/CD et l’utilisation de semantic-release pour la gestion des versions peuvent grandement simplifier votre flux de travail de développement. En automatisant vos déploiements et votre versionnement, vous pouvez livrer des mises à jour plus rapidement et avec plus de confiance. Le CLI Capgo et semantic-release offrent une combinaison puissante pour obtenir des versions entièrement automatisées de bout en bout. Avec un peu de configuration, vous pouvez avoir un processus de déploiement robuste et fiable qui vous permet de vous concentrer sur la création de nouvelles fonctionnalités plutôt que de vous soucier des étapes manuelles de publication. Pour plus de détails sur les commandes et options du CLI Capgo, consultez la [référence CLI](/docs/cli/overview). Et pour une plongée plus approfondie dans la configuration de semantic-release, consultez la [documentation semantic-release](https://github.com/semantic-release/semantic-release). Bon déploiement ! # Déployer une mise à jour en direct Utilisez la fonctionnalité Live Updates de Capgo pour mettre à jour l’interface utilisateur et la logique métier de votre application à distance, en temps réel. Envoyez des mises à jour du bundle JS directement à vos utilisateurs sans passer par l’app store pour corriger instantanément les bugs et déployer de nouvelles fonctionnalités. Ce guide suppose que vous avez terminé le [Démarrage rapide Capgo](/docs/getting-started/quickstart) et que vous avez déjà : 1. Installé le SDK `@capgo/capacitor-updater` dans votre application Capacitor 2. Configuré votre ID d’application et le canal de mise à jour dans `capacitor.config.ts` 3. Ajouté dans votre code la méthode `CapacitorUpdater.notifyAppReady()` Si vous n’avez pas encore effectué ces étapes, veuillez revenir en arrière et compléter d’abord le démarrage rapide. [Ajouter une application ](/docs/getting-started/add-an-app/)Ajoutez une application à votre compte Capgo et installez le plugin dans votre application ## Téléversement d’un Bundle Une fois le SDK Capgo installé et configuré, vous êtes prêt à téléverser votre premier bundle de mise à jour en direct : 1. Construisez vos assets web : ```shell npm run build ``` 2. Téléversez le bundle vers Capgo : * Console ```shell npx @capgo/cli@latest bundle upload --channel=Production ``` * Github Actions github/workflows/build\_and\_deploy.yml ```yml name: Build source code and send to Capgo concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true on: push: branches: - main jobs: deploy_to_capgo: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v5 - uses: actions/setup-node@v4 with: node-version: 18 - name: Install dependencies run: npm install - name: Build run: npm run build - name: Deploy to Capgo run: bunx @capgo/cli@latest bundle upload -a ${{ secrets.CAPGO_TOKEN }} --channel ${{ env.CHANNEL }} env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} ``` * Gitlab gitlab-ci.yml ```yml stages: - build build: stage: build image: node:18 cache: - key: files: - package-lock.json paths: - node_modules/ script: - npm install - npm run build - npx @capgo/cli@latest bundle upload -a $CAPGO_TOKEN --channel $CAPGO_CHANNEL artifacts: paths: - node_modules/ - dist/ only: - master ``` Cela téléversera une nouvelle version du bundle vers le canal spécifié dans la commande. ### Dépannage des téléversements Si votre téléversement échoue, vérifiez : * Que votre ID d’application dans `capacitor.config.ts` correspond à votre application dans le tableau de bord Capgo * Que vous exécutez la commande de téléversement depuis la racine de votre projet Capacitor * Que vos assets web sont construits et à jour Si vous rencontrez toujours des problèmes, consultez la section [Dépannage](/docs/getting-started/troubleshooting/) ## Réception d’une mise à jour sur un appareil Une fois votre bundle téléversé, vous pouvez tester la mise à jour en direct sur un appareil : 1. Synchronisez votre application avec l’appareil : ```shell npx cap sync ios ``` 2. Ouvrez un autre terminal et exécutez la commande suivante pour vérifier l’état de la mise à jour : ```shell npx @capgo/cli@latest app debug ``` 3. Exécutez votre application localement : ```shell npx cap run ios ``` Ou ouvrez le projet iOS/Android dans Xcode/Android Studio et effectuez une exécution native 4. Gardez l’application ouverte pendant environ 30 secondes pour permettre à la mise à jour de se télécharger en arrière-plan 5. Les logs prendront quelques secondes pour se mettre à jour et afficher l’état de la mise à jour 6. Fermez et rouvrez l’application. Vous devriez voir votre mise à jour en direct appliquée ! Référez-vous au [Démarrage rapide Capgo](/docs/getting-started/quickstart#receiving-a-live-update-on-a-device) pour plus de détails sur les tests des mises à jour en direct ## Prochaines étapes Félicitations pour avoir déployé votre première mise à jour en direct avec Capgo ! 🎉 Pour en savoir plus, consultez le reste de la [documentation Live Updates de Capgo](/docs/live-updates). Quelques sujets clés à découvrir ensuite : * [Ciblage des mises à jour avec les canaux](/docs/live-updates/channels) * [Personnalisation du comportement des mises à jour](/docs/live-updates/update-behavior) * [Retours en arrière des mises à jour en direct](/docs/live-updates/rollbacks) # Aperçu Le tutoriel de démarrage rapide vous guidera à travers les concepts clés de Capgo ! Les concepts qui seront explorés incluent : 1. Ajouter une application à votre compte Capgo 2. Intégrer Capgo à votre CI/CD 3. Déclencher le téléchargement des bundles sur Capgo en poussant des commits 4. Configurer et personnaliser la publication des bundles Capgo 5. Configurer votre application pour activer les mises à jour en direct via Capgo 6. Déployer des mises à jour en direct sur votre application depuis Capgo Suivez simplement le guide étape par étape, ou naviguez directement vers la documentation du composant qui vous intéresse [ Commencer le tutoriel](/docs/getting-started/add-an-app/) [Suivez le tutoriel de démarrage rapide et lancez-vous avec Capgo en un rien de temps !](/docs/getting-started/add-an-app/) [ Facile à intégrer](/docs/getting-started/deploy/) [Intégrez Capgo à votre CI/CD et déclenchez des téléchargements de bundles sur Capgo en poussant des commits](/docs/getting-started/deploy/) [ Documentation des mises à jour en direct](/docs/live-updates/) [Mettez à jour votre application à distance en temps réel sans délais de l’App Store](/docs/live-updates/) [ Dépannage](/docs/getting-started/troubleshooting) [Problèmes courants et comment les résoudre](/docs/getting-started/troubleshooting) Tip La fonction de mise à jour Over-the-Air (OTA) ne s’applique qu’aux modifications apportées aux fichiers HTML, CSS et JavaScript Si vous apportez des modifications au code natif, comme des mises à jour des plugins Capacitor, il est obligatoire de soumettre à nouveau l’application à l’App Store pour approbation ## Rejoindre la communauté Discord [Rejoignez le serveur Discord Capacitor-updater !](https://discordcom/invite/VnYRvBfgA6) ## Maintenance | Version du plugin | Compatibilité Capacitor | Maintenance | | ----------------- | ----------------------- | -------------------------------------------------------------------- | | v6\*\* | v6\*\* | ✅ | | v5\*\* | v5\*\* | Bugs critiques uniquement | | v4\*\* | v4\*\* | ⚠️ Déprécié | | v3\*\* | v3\*\* | ⚠️ Déprécié | | > 7 | v4\*\* | ⚠️ Déprécié, notre CI est devenu fou et a trop augmenté les versions | ## Conformité aux directives des stores Google Play Android et l’App Store iOS ont des directives correspondantes avec des règles dont vous devez être conscient avant d’intégrer la solution Capacitor-updater dans votre application ### Google Play Le troisième paragraphe du sujet [Abus des appareils et du réseau](https://supportgooglecom/googleplay/android-developer/answer/9888379/?hl=en) décrit que la mise à jour du code source par toute méthode autre que le mécanisme de mise à jour de Google Play est limitée, mais cette restriction ne s’applique pas à la mise à jour des bundles JavaScript > Cette restriction ne s’applique pas au code qui s’exécute dans une machine virtuelle et a un accès limité aux API Android (comme JavaScript dans une webview ou un navigateur) Cela permet totalement Capacitor-updater car il met uniquement à jour les bundles JS et ne mettra pas à jour le code natif ### App Store Le paragraphe **332** depuis 2015 de l’[accord de licence du programme pour développeurs Apple](https://developer.apple.com/programs/ios/information/) autorise pleinement l’exécution de mises à jour over-the-air de JavaScript et des assets - et dans sa dernière version (20170605) [téléchargeable ici](https://developer.apple.com/terms/) cette règle est encore plus large : > Le code interprété peut être téléchargé dans une Application tant que ce code : (a) ne modifie pas l’objectif principal de l’Application en fournissant des fonctionnalités qui ne correspondent pas à l’objectif prévu et annoncé de l’Application telle que soumise à l’App Store, (b) ne crée pas de magasin ou de vitrine pour d’autres codes ou applications, et (c) ne contourne pas la signature, le bac à sable ou d’autres fonctionnalités de sécurité du système d’exploitation Capacitor-updater vous permet de suivre ces règles en totale conformité tant que la mise à jour que vous poussez ne dévie pas significativement votre produit de son intention originale approuvée par l’App Store Pour rester davantage en conformité avec les directives d’Apple, nous suggérons que les applications distribuées sur l’App Store n’activent pas le scénario de “Mise à jour forcée”, car les [directives d’examen de l’App Store](https://developer.apple.com/app-store/review/guidelines/) stipulent que : > Les applications ne doivent pas forcer les utilisateurs à noter l’application, à l’évaluer, à télécharger d’autres applications ou à effectuer d’autres actions similaires pour accéder aux fonctionnalités, au contenu ou à l’utilisation de l’application Ce n’est pas un problème pour le comportement par défaut de la mise à jour en arrière-plan, car elle ne forcera pas l’utilisateur à appliquer la nouvelle version jusqu’à la prochaine fois qu’il fermera l’application, mais vous devez au moins être conscient de ce rôle si vous décidez de l’afficher ## Open source Le plugin est sous licence LGPL-30 et le back-end est sous licence AGPL-30 > 💡 LGPL-30 signifie que si quelqu’un modifie le code du plugin, il est obligatoire de le publier en open-source avec la même licence. Si vous utilisez le code sans modification, cela ne vous concerne pas. Voir le problème ci-dessous pour plus de détails, consultez le lien 👇 [Licences ? ](https://github.com/Cap-go/capacitor-updater/issues/7) [Essayez GPTS Capgo pour obtenir de l'aide au lieu de lire la documentation ](https://chatopenaicom/g/g-3dMwHbF2w-capgo-doc-gpt) > Vous pouvez l’inclure dans votre application sans vous inquiéter ## Notes finales Si vous auto-hébergez et trouvez cet outil utile, veuillez envisager de soutenir mon travail en devenant un [sponsor GitHub](https://github.com/sponsors/riderx/) J’ai fait le pari d’open-sourcer tout le code que j’ai construit ici au lieu de le mettre derrière un paywall. En l’ouvrant au lieu de lutter et de le cacher, je crois que nous pouvons rendre le monde meilleur Pour rendre cela possible, il est nécessaire que nous fassions tous notre part, y compris vous 🥹 Si Capgo cloud ne répond pas à vos besoins, vous pouvez soutenir un créateur bootstrappé [ici](https://github.com/sponsors/riderx/) selon vos conditions ## Mathématiques simples Le prix du plan de base : 14$ \* 12 = 168$ par an Tandis que le coût moyen dev/heure = 60$ Cela signifie que 3 heures perdues de temps de développement sur l’auto-hébergement vous permettent de payer une année entière, si vous passez plus de 3 heures vous perdez de l’argent ^^ # Dépannage Voici quelques problèmes courants que vous pourriez rencontrer en utilisant Capgo et comment les résoudre ### Échecs de téléchargement Si le téléchargement de votre bundle échoue, vérifiez : * L’ID de votre application dans `capacitor.config.ts` correspond à votre application dans le tableau de bord Capgo * Vous exécutez la commande de téléchargement depuis la racine de votre projet Capacitor * Vos ressources web sont construites et à jour #### Options avancées de téléchargement La CLI Capgo fournit des options supplémentaires pour aider avec les problèmes courants de téléchargement : * `--tus` : Utilise le [protocole de téléchargement reprise tus](https://tus.io/) pour des téléchargements plus fiables de gros bundles ou sur des connexions réseau instables. Si votre bundle fait plus de 10 Mo ou si votre connexion est instable, envisagez d’utiliser `--tus` : ```shell npx @capgo/cli@latest bundle upload --tus ``` * `--package-json` et `--node-modules` : Indique à Capgo où trouver votre `package.json` racine et `node_modules` si votre application utilise une structure non standard comme un monorepo ou un espace de travail npm. Passez le chemin vers le `package.json` racine et le chemin `--node-modules` : ```shell npx @capgo/cli@latest bundle upload --package-json=path/to/package.json --node-modules=path/to/node_modules ``` Capgo a besoin de ces informations pour regrouper correctement les dépendances de votre application Vous pouvez combiner ces options avec d’autres comme `--channel` selon vos besoins. Consultez la [documentation CLI Capgo](/docs/cli/overview/) pour tous les détails sur les options de téléchargement disponibles Si vous rencontrez toujours des problèmes avec les téléchargements, contactez le [support Capgo](https://support.capgo.app) pour obtenir de l’aide ### Débogage des mises à jour Si vous rencontrez des problèmes avec les mises à jour en direct, la commande debug de Capgo est un outil utile pour le dépannage. Pour l’utiliser : 1. Exécutez la commande suivante dans votre répertoire de projet : ```shell npx @capgo/cli@latest app debug ``` 2. Lancez votre application sur un appareil ou un émulateur et effectuez l’action qui devrait déclencher une mise à jour (par exemple, rouvrir l’application après avoir téléchargé un nouveau bundle) 3. Observez la sortie de la commande debug. Elle enregistrera des informations sur le processus de mise à jour, notamment : * Quand l’application vérifie une mise à jour * Si une mise à jour est trouvée et quelle version elle est * La progression du téléchargement et de l’installation de la mise à jour * Toutes les erreurs qui surviennent pendant le processus de mise à jour 4. Utilisez les journaux de débogage pour identifier où se produit le problème. Par exemple : * Si aucune mise à jour n’est trouvée, vérifiez que votre bundle a été téléchargé avec succès et que l’application est configurée pour utiliser le bon canal * Si la mise à jour se télécharge mais ne s’installe pas, assurez-vous d’avoir appelé `CapacitorUpdater.notifyAppReady()` et que l’application a été complètement fermée et rouverte * Si vous voyez un message d’erreur, recherchez cette erreur spécifique dans la documentation Capgo ou contactez le support pour obtenir de l’aide La commande debug est particulièrement utile pour identifier les problèmes avec le processus de téléchargement et d’installation des mises à jour. Si les journaux montrent que la version de mise à jour attendue a été trouvée mais n’a pas été appliquée, concentrez votre dépannage sur les étapes après le téléchargement ### Débogage avec les journaux natifs En plus de la commande debug de Capgo, les journaux natifs sur Android et iOS peuvent fournir des informations de dépannage précieuses, en particulier pour les problèmes côté natif du processus de mise à jour #### Journaux Android Pour accéder aux journaux Android : 1. Connectez votre appareil ou démarrez votre émulateur 2. Ouvrez Android Studio et sélectionnez “View > Tool Windows > Logcat” 3. Dans la fenêtre Logcat, filtrez les journaux pour n’afficher que le processus de votre application en le sélectionnant dans le menu déroulant en haut 4. Recherchez les lignes contenant “Capgo” pour trouver les journaux du SDK Alternativement, vous pouvez utiliser la commande `adb logcat` et grep pour “Capgo” pour filtrer les journaux Le SDK Capgo enregistrera les événements clés pendant le processus de mise à jour, tels que : * Quand une vérification de mise à jour est initiée * Si une mise à jour est trouvée et quelle version elle est * Quand le téléchargement de la mise à jour commence et se termine * Quand l’installation de la mise à jour est déclenchée * Toutes les erreurs qui surviennent pendant les étapes de mise à jour natives Les problèmes courants spécifiques à Android que vous pourriez voir dans les journaux incluent : * Problèmes de connectivité réseau empêchant le téléchargement de la mise à jour * Erreurs de permissions de fichiers lors de l’enregistrement ou de la lecture du bundle de mise à jour * Espace de stockage insuffisant pour le bundle de mise à jour * Échec du redémarrage de l’application après l’installation de la mise à jour #### Journaux iOS Pour accéder aux journaux iOS : 1. Connectez votre appareil ou démarrez votre simulateur 2. Ouvrez Xcode et allez dans “Window > Devices and Simulators” 3. Sélectionnez votre appareil et cliquez sur “Open Console” 4. Dans la sortie console, recherchez les lignes contenant “Capgo” pour trouver les journaux du SDK Vous pouvez également utiliser la commande `log stream` dans le terminal et grep pour “Capgo” pour filtrer les journaux Comme pour Android, le SDK Capgo enregistrera les événements clés côté iOS : * Initiation et résultat de la vérification de mise à jour * Début, progression et fin du téléchargement * Déclenchement et résultat de l’installation * Toutes les erreurs pendant le processus de mise à jour natif Les problèmes spécifiques à iOS que vous pourriez identifier dans les journaux incluent : * Problèmes de certificat SSL lors du téléchargement de la mise à jour * Sécurité du transport de l’application bloquant le téléchargement de la mise à jour * Espace de stockage insuffisant pour le bundle de mise à jour * Échec de l’extraction ou de l’application correcte du bundle de mise à jour Sur les deux plateformes, les journaux natifs fournissent une vue plus détaillée du processus de mise à jour, avec plus de détails sur l’implémentation native. Ils sont particulièrement utiles pour identifier les problèmes qui se produisent en dehors de la couche JavaScript de Capgo Lors du dépannage d’un problème complexe de mise à jour en direct, il est recommandé de capturer à la fois les journaux de débogage Capgo et les journaux natifs pour avoir une vision complète de ce qui se passe. Les deux journaux ensemble vous donneront la meilleure chance d’identifier et de résoudre le problème ### Mises à jour non appliquées Si vous avez téléchargé un bundle mais ne voyez pas les changements sur votre appareil : * Assurez-vous d’avoir appelé `CapacitorUpdater.notifyAppReady()` dans votre code d’application comme indiqué dans le [guide de démarrage rapide](/docs/getting-started/quickstart) * Vérifiez que votre appareil est connecté à Internet et que les journaux de débogage Capgo montrent que la mise à jour a été téléchargée * Essayez de fermer complètement et de rouvrir l’application, car les mises à jour ne sont appliquées que lors d’un nouveau lancement * Recherchez des erreurs dans les journaux natifs qui pourraient indiquer un problème lors de l’application de la mise à jour Consultez le guide [déploiement des mises à jour en direct](/docs/getting-started/deploy) pour plus de détails sur le processus de mise à jour. Si vous êtes toujours bloqué, utilisez la commande `npx @capgo/cli@latest app debug` et les journaux natifs pour avoir plus de visibilité sur ce qui se passe ## Installation du SDK Si vous rencontrez des problèmes lors de l’installation du SDK Capgo, assurez-vous que : * Votre application utilise une version supportée de Capacitor (4.0 ou plus récente) * Vous avez suivi les étapes du [guide de démarrage rapide](/docs/getting-started/quickstart) dans l’ordre, y compris la synchronisation de votre application après l’installation du SDK ## Intégration CI/CD Pour les problèmes de déclenchement des téléchargements Capgo depuis votre pipeline CI/CD : * Vérifiez que votre jeton d’authentification Capgo est correctement configuré * Assurez-vous d’exécuter la commande de téléchargement après la construction de vos ressources web * Vérifiez que la commande de téléchargement utilise le bon nom de canal pour votre environnement cible Consultez la documentation [intégration CI/CD](/docs/getting-started/cicd-integration) pour plus de conseils de dépannage. Vous pouvez également utiliser la commande `npx @capgo/cli@latest app debug` pour confirmer si vos mises à jour déclenchées par CI/CD sont bien reçues par l’application # Comment faire > Comment utiliser Capgo, tutoriels, astuces et conseils [Comment fonctionne la gestion des versions dans Capgo ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [Comment publier une version majeure dans Capgo ](https://capgo.app/blog/how-to-release-major-version-in-capgo/)capgo.app [Comment envoyer une mise à jour spécifique à un utilisateur ou à un groupe ](https://capgo.app/blog/how-to-send-specific-version-to-users/)capgo.app ## CI / CD [Construction et publication automatiques avec GitHub Actions ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [Gérer les versions de développement et de production avec GitHub Actions ](https://capgo.app/blog/automatic-build-and-release-with-github-actions/)capgo.app ## Contribution [Contribuer à l'open source de Capgo ](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTINGmd)githubcom # Vue d'ensemble Utilisez la fonctionnalité Live Updates de Capgo pour mettre à jour les bundles JavaScript de votre application à distance, en temps réel. Envoyez les mises à jour JS directement à vos utilisateurs sans passer par le processus de révision de l’app store pour corriger instantanément les bugs et déployer de nouvelles fonctionnalités. Note Les Live Updates sont limitées aux modifications des bundles JavaScript. Si vous devez mettre à jour du code natif, comme l’ajout ou la suppression d’un plugin ou la modification de la configuration du projet natif, vous devrez soumettre une nouvelle version binaire native aux app stores. ## Comment fonctionnent les Live Updates Le système Live Update de Capgo comporte deux composants clés : 1. Le SDK Capgo, que vous installez dans votre application. Le SDK vérifie les mises à jour disponibles et les télécharge en arrière-plan. 2. Les canaux, qui vous permettent de cibler des mises à jour pour des groupes spécifiques d’utilisateurs. Vous pouvez utiliser les canaux pour gérer différentes pistes de publication, comme `Production`, `Staging` et `Dev`. Lorsque vous téléchargez un nouveau bundle JS sur Capgo et l’assignez à un canal, le SDK Capgo dans les applications configurées pour ce canal détectera la mise à jour et la téléchargera. La prochaine fois que l’application redémarre, le nouveau bundle sera chargé. ## Pour commencer Pour commencer à utiliser Live Updates, suivez ces étapes : 1. Complétez le [Démarrage rapide Capgo](/docs/getting-started/quickstart) pour configurer votre application dans Capgo et installer le SDK Capgo 2. Dans votre code d’application, appelez `CapacitorUpdaternotifyAppReady()` après l’initialisation de votre application. Cela indique au SDK Capgo que votre application est prête à recevoir des mises à jour 3. Construisez votre bundle JS et téléchargez-le sur Capgo : ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. Ouvrez votre application et attendez que la mise à jour se télécharge. Vous pouvez vérifier le statut avec : ```shell npx @capgo/cli@latest app debug ``` 5. Une fois la mise à jour téléchargée, fermez et rouvrez votre application pour charger le nouveau bundle Consultez le guide [Déploiement des Live Updates](/docs/getting-started/deploy) pour plus de détails ## Prochaines étapes [ Canaux](/docs/live-updates/channels/) [Apprenez à utiliser les canaux pour gérer différentes pistes de publication et cibler les mises à jour pour des utilisateurs spécifiques](/docs/live-updates/channels/) [ Retours en arrière](/docs/live-updates/rollbacks/) [Découvrez comment revenir à une version précédente du bundle JS si une mise à jour cause des problèmes](/docs/live-updates/rollbacks/) [ Comportement des mises à jour](/docs/live-updates/update-behavior/) [Personnalisez comment et quand les mises à jour sont téléchargées et appliquées dans votre application](/docs/live-updates/update-behavior/) [ Mises à jour rapides](/docs/live-updates/differentials/) [Apprenez à utiliser les mises à jour rapides pour accélérer le processus de mise à jour](/docs/live-updates/differentials/) # Canaux Un canal de mise à jour en direct pointe vers une build JS spécifique de votre application qui sera partagée avec tous les appareils configurés pour écouter ce canal pour les mises à jour. Lorsque vous [installez le SDK Capgo Live Updates](/docs/getting-started/quickstart/) dans votre application, tout binaire natif configuré sur ce canal vérifiera les mises à jour disponibles à chaque lancement de l’application. Vous pouvez modifier la build vers laquelle pointe un canal à tout moment et revenir aux builds précédentes si nécessaire. ## Configuration d’un Canal Chaque application dispose d’un canal par défaut appelé “Production” qui ne peut pas être supprimé. Pour ajouter de nouveaux canaux : 1. Allez dans la section “Canaux” du tableau de bord Capgo 2. Cliquez sur le bouton “Nouveau Canal” 3. Saisissez un nom pour le canal et cliquez sur “Créer” Les noms des canaux peuvent être ce que vous voulez. Une stratégie courante consiste à faire correspondre les canaux à vos étapes de développement, comme : * `Development` - pour tester les mises à jour en direct sur les appareils locaux ou les émulateurs * `QA` - pour que votre équipe QA vérifie les mises à jour avant une diffusion plus large * `Staging` - pour les tests finaux dans un environnement similaire à la production * `Production` - pour la version de votre application que les utilisateurs finaux reçoivent des stores ## Configuration du Canal dans Votre Application Avec vos canaux créés, vous devez configurer votre application pour écouter le canal approprié. Dans cet exemple, nous utiliserons le canal `Development`. Ouvrez votre fichier `capacitor.config.ts` (ou `capacitor.config.json`). Dans la section `plugins`, définissez la propriété `channel` du plugin `CapacitorUpdater` avec le nom de votre canal souhaité : ```ts import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { defaultChannel: 'Development', }, }, }; ``` Ensuite, construisez votre application web et exécutez `npx cap sync` pour copier le fichier de configuration mis à jour vers vos projets iOS et Android. Si vous sautez cette étape de synchronisation, vos projets natifs continueront d’utiliser le canal pour lequel ils étaient précédemment configurés. Caution La propriété `defaultChannel` remplacera toujours le canal par défaut du cloud. Mais vous pouvez toujours forcer le deviceId vers un canal dans le Cloud. ## Attribution d’un Bundle à un Canal Pour déployer une mise à jour en direct, vous devez télécharger une nouvelle build JS et l’attribuer à un canal. Vous pouvez le faire en une seule étape avec le CLI Capgo : ```shell npx @capgo/cli@latest bundle upload --channel=Development ``` Cela téléchargera vos ressources web construites et définira le nouveau bundle comme build active pour le canal `Development`. Toutes les applications configurées pour écouter ce canal recevront la mise à jour la prochaine fois qu’elles en vérifieront une. Vous pouvez également attribuer des builds aux canaux depuis la section “Bundles” du tableau de bord Capgo. Cliquez sur l’icône de menu à côté d’une build et sélectionnez “Attribuer au Canal” pour choisir le canal pour cette build. ## Versionnement des Bundles et Canaux Il est important de noter que les bundles dans Capgo sont globaux à votre application, et non spécifiques à des canaux individuels. Le même bundle peut être attribué à plusieurs canaux. Pour le versionnement de vos bundles, nous recommandons d’utiliser le versionnement sémantique [semver](https://semver.org/) avec des identifiants de pré-version pour les builds spécifiques aux canaux. Par exemple, une version bêta pourrait être versionnée comme `1.2.3-beta.1`. Cette approche présente plusieurs avantages : * Elle communique clairement la relation entre les builds. `1.2.3-beta.1` est évidemment une pré-version de `1.2.3` * Elle permet de réutiliser les numéros de version entre les canaux, réduisant la confusion * Elle permet des chemins de retour en arrière clairs. Si vous devez revenir de `1.2.3`, vous savez que `1.2.2` est la version stable précédente Voici un exemple de comment vous pourriez aligner vos versions de bundle avec une configuration typique de canal : * Canal `Development` : `1.2.3-dev.1`, `1.2.3-dev.2`, etc. * Canal `QA` : `1.2.3-qa.1`, `1.2.3-qa.2`, etc. * Canal `Staging` : `1.2.3-rc.1`, `1.2.3-rc.2`, etc. * Canal `Production` : `1.2.3`, `1.2.4`, etc. ## Retour en Arrière d’une Mise à Jour en Direct Si vous déployez une mise à jour en direct qui introduit un bug ou qui doit être annulée pour une autre raison, vous pouvez facilement revenir à une build précédente. Depuis la section “Canaux” du tableau de bord : 1. Cliquez sur le nom du canal que vous souhaitez restaurer 2. Trouvez la build vers laquelle vous voulez revenir et cliquez sur l’icône de couronne ![Retour à une build](/select_bundle.webp) 3. Confirmez l’action La build sélectionnée deviendra immédiatement la build active pour ce canal. Les applications recevront la version restaurée la prochaine fois qu’elles vérifieront une mise à jour. ## Automatisation des Déploiements Pour des flux de travail plus avancés, vous pouvez automatiser vos déploiements de mises à jour en direct dans le cadre de votre pipeline CI/CD. En intégrant Capgo dans votre processus de build, vous pouvez automatiquement télécharger de nouveaux bundles et les attribuer à des canaux chaque fois que vous poussez vers certaines branches ou créez de nouvelles versions. Consultez la documentation [Intégration CI/CD](/docs/getting-started/cicd-integration/) pour en savoir plus sur l’automatisation des mises à jour en direct Capgo. ## Déploiement vers un Appareil Maintenant que vous comprenez les canaux, vous êtes prêt à commencer à déployer des mises à jour en direct sur des appareils réels. Le processus de base est : 1. Installez le SDK Capgo dans votre application 2. Configurez l’application pour écouter votre canal souhaité 3. Téléchargez une build et attribuez-la à ce canal 4. Lancez l’application et attendez la mise à jour ! Pour un guide plus détaillé, consultez le guide [Déploiement des Mises à Jour en Direct](/docs/getting-started/deploy/). Bonnes mises à jour ! # Mises à jour rapides Le système Live Update de Capgo peut livrer les mises à jour plus rapidement et plus efficacement en n’envoyant que les fichiers modifiés, plutôt que l’ensemble du bundle JS Ceci est particulièrement bénéfique pour les utilisateurs ayant des connexions réseau plus lentes ou limitées, car cela minimise la quantité de données à télécharger Un second avantage est lorsque l’application contient de gros fichiers qui changent rarement, comme des images ou des vidéos, comparé aux fichiers JS compressés, ils ne seront téléchargés qu’une seule fois ## Comment fonctionnent les mises à jour différentielles Les mises à jour différentielles dans Capgo sont gérées par le plugin Capgo installé dans votre application. Lorsque vous téléchargez une nouvelle version de votre application en utilisant le flag `--partial`, Capgo effectue les actions suivantes : 1. Chaque fichier de votre build est téléchargé individuellement 2. Des sommes de contrôle sont générées pour chaque fichier 3. Un nouveau manifeste json est créé, listant tous les fichiers et leurs sommes de contrôle 4. Ce manifeste est téléchargé dans la base de données Capgo Lorsqu’un appareil exécutant votre application vérifie les mises à jour, le plugin Capgo reçoit le nouveau manifeste du serveur. Il compare ce manifeste à celui qu’il possède actuellement, identifiant quels fichiers ont changé en se basant sur les sommes de contrôle et les chemins des fichiers Le plugin ne télécharge ensuite que les fichiers modifiés, plutôt que l’ensemble du bundle JS. Il reconstruit la nouvelle version de l’application en combinant ces fichiers téléchargés avec les fichiers inchangés qu’il possède déjà Manifeste Dans le cas des mises à jour différentielles, l’appareil stocke tous les fichiers téléchargés dans un cache commun, Capgo ne le nettoiera jamais mais le système d’exploitation peut le faire à tout moment ## Activer les mises à jour différentielles Pour activer les mises à jour différentielles pour votre application Capgo, utilisez simplement le flag `--partial` lors du téléchargement d’une nouvelle version : ## Imposer les mises à jour différentielles Si vous souhaitez vous assurer que tous les téléchargements sont des mises à jour différentielles et empêcher tout téléchargement accidentel de bundle complet, vous pouvez utiliser le flag `--partial-only` : ```shell npx @capgo/cli@latest bundle upload --partial-only ``` Lorsque `--partial-only` est utilisé, Capgo ne téléchargera que des fichiers individuels et générera un manifeste. Tout appareil qui ne prend pas en charge le partiel ne pourra pas télécharger la mise à jour Vous pourriez vouloir utiliser `--partial-only` si : * Vous voulez toujours utiliser des mises à jour différentielles et ne jamais autoriser les téléchargements de bundle complet * Vous configurez un pipeline CI/CD et voulez vous assurer que tous les téléchargements automatisés sont différentiels * Votre application est volumineuse et la bande passante est limitée, vous devez donc minimiser les tailles de téléchargement/upload Si vous devez faire un téléchargement de bundle complet alors que `--partial-only` est défini, exécutez simplement la commande de téléchargement sans `--partial-only`. Cela ignorera le paramètre pour ce téléchargement unique, vous permettant de pousser un bundle complet si nécessaire ## Dépannage Si les mises à jour différentielles ne semblent pas fonctionner (c’est-à-dire que les appareils téléchargent toujours le bundle JS complet même pour de petits changements), vérifiez que : * Vous utilisez le flag `--partial` à chaque fois que vous téléchargez une nouvelle version * Si vous utilisez `--partial-only`, assurez-vous de ne pas avoir oublié le flag `--partial` * Votre appareil exécute la dernière version du plugin Capgo * Votre appareil a une connexion réseau stable et peut atteindre les serveurs Capgo Vous pouvez également utiliser l’application web Capgo pour vérifier les détails de votre dernier téléchargement : 1. Allez sur [webapp](https://app.capgo.io) 2. Cliquez sur votre application 3. Cliquez sur le nombre de bundles dans la barre de statistiques 4. Sélectionnez le dernier bundle 5. Vérifiez le champ `Partial` ![bundle type](/bundle_type.webp) Si vous continuez à avoir des problèmes, veuillez contacter le support Capgo pour une assistance supplémentaire. Ils peuvent vérifier les logs du serveur pour confirmer que vos téléchargements partiels sont traités correctement et que les appareils reçoivent les manifestes mis à jour C’est tout ! Le flag `--partial` indique à Capgo d’effectuer les téléchargements de fichiers individuels et la génération de manifeste nécessaires pour les mises à jour différentielles Notez que vous devez utiliser `--partial` chaque fois que vous téléchargez une nouvelle version que vous souhaitez livrer comme mise à jour différentielle. Si vous omettez le flag, Capgo téléchargera l’ensemble du bundle JS comme un seul fichier, et les appareils téléchargeront le bundle complet même si seule une petite partie a changé # Retours en arrière Bien que les mises à jour en direct de Capgo vous permettent de livrer rapidement des améliorations et des corrections à vos utilisateurs, il peut y avoir des situations où vous devez revenir à une version précédente de votre application. Peut-être qu’une nouvelle mise à jour a introduit un problème critique inattendu, ou peut-être que vous souhaitez annuler une modification spécifique pendant que vous travaillez sur une correction. Capgo propose plusieurs façons de gérer les builds d’un canal et de contrôler la version de votre application que les utilisateurs reçoivent. ## Retour à un Bundle précédent Chaque fois que vous téléchargez un nouveau build et l’attribuez à un canal, Capgo conserve un historique de ces builds. Si vous devez annuler une mise à jour spécifique, vous pouvez sélectionner l’un de ces builds précédents pour le redéployer sur le canal. Pour revenir à un build précédent : 1. Connectez-vous au [Tableau de bord Capgo](https://app.capgo.io) 2. Accédez à la section “Canaux” 3. Cliquez sur le nom du canal que vous souhaitez restaurer 4. Trouvez le build auquel vous souhaitez revenir dans l’historique des builds du canal 5. Cliquez sur l’icône de couronne à côté de ce build pour en faire le build actif du canal ![Options de gestion des canaux](/select_bundle.webp) 6. Confirmez que vous souhaitez revenir à ce build Note Le retour à un build précédent n’affecte que le canal sélectionné. Si vous avez plusieurs canaux (par exemple Production, Staging, etc.), vous devrez répéter le processus de restauration pour chaque canal concerné. Après le retour en arrière, les appareils configurés pour écouter le canal mis à jour recevront le build précédent la prochaine fois qu’ils vérifieront les mises à jour. Le build restauré sera traité comme une nouvelle mise à jour, donc le flux et les conditions habituels de mise à jour s’appliquent. ## Délier un Canal Si vous souhaitez suspendre temporairement les mises à jour sur un canal pendant que vous enquêtez sur un problème, vous pouvez délier le canal de son build actuel. Pour délier un canal : 1. Accédez au canal dans le Tableau de bord Capgo 2. Cliquez sur le bouton “Délier” à côté du build actuel 3. Confirmez que vous souhaitez délier le canal Une fois qu’un canal est délié, il ne distribuera plus de nouvelles mises à jour. Les appareils configurés sur ce canal resteront sur leur build actuel jusqu’à ce que le canal soit à nouveau lié à un build. C’est utile si vous avez identifié un problème avec une mise à jour mais n’êtes pas encore sûr du build auquel vous souhaitez revenir. Délier le canal vous donne le temps d’enquêter sans pousser d’autres mises à jour. ## Forcer le Bundle Intégré Dans des situations plus graves, vous pourriez vouloir ramener tous les appareils d’un canal au build web qui était initialement packagé avec le binaire natif de votre application. C’est ce qu’on appelle le “bundle intégré”. Pour forcer le bundle intégré sur un canal : 1. Accédez au canal dans le Tableau de bord Capgo 2. Cliquez sur le bouton “Bundle Intégré” 3. Confirmez que vous voulez forcer le bundle intégré Lorsque vous forcez le bundle intégré, tous les appareils configurés sur ce canal reviendront au build web d’origine packagé lors de leur prochaine vérification de mise à jour. Cela se produit indépendamment du build sur lequel ils se trouvent actuellement. C’est une option de retour en arrière plus agressive que de revenir à un build précédent spécifique, car elle supprime toutes les mises à jour en direct publiées depuis la dernière publication de l’application sur les stores. Caution Soyez prudent lorsque vous forcez le bundle intégré, car cela affectera tous les appareils sur le canal. Assurez-vous d’avoir considéré l’impact et d’avoir un plan pour avancer avant de prendre cette action. ## Surveillance et Réponse aux Problèmes Pour détecter rapidement les problèmes et minimiser l’impact des mises à jour problématiques, il est important d’avoir un plan pour surveiller vos versions et répondre aux problèmes. Quelques stratégies incluent : * Surveiller les rapports de crash et les retours utilisateurs immédiatement après la publication d’une mise à jour * Utiliser des déploiements progressifs ou un système de canaux échelonnés pour tester les mises à jour sur un groupe plus restreint avant une diffusion large * Avoir un processus de décision clair pour déterminer quand revenir en arrière, délier ou forcer le bundle intégré, et qui a l’autorité pour le faire * Communiquer aux utilisateurs sur le problème et la résolution, si approprié En combinant une surveillance attentive avec la capacité de gérer rapidement les mises à jour problématiques, vous pouvez offrir une expérience d’application en amélioration continue tout en minimisant les perturbations pour vos utilisateurs. # Comportement de la mise à jour Lorsque vous publiez une mise à jour de votre application Capgo, vous voulez probablement que vos utilisateurs la reçoivent le plus rapidement possible. Mais vous ne voulez pas non plus perturber leur expérience en les forçant à attendre un téléchargement ou à redémarrer l’application au milieu d’une session. Le comportement de mise à jour de Capgo est conçu pour trouver un équilibre entre la livraison rapide des mises à jour et la minimisation des perturbations pour vos utilisateurs. ## Flux de mise à jour par défaut Par défaut, voici comment Capgo gère les mises à jour d’applications : 1. Au lancement de l’application, le plugin Capgo vérifie si une nouvelle mise à jour est disponible 2. Si une mise à jour est trouvée, elle est téléchargée en arrière-plan pendant que l’utilisateur continue d’utiliser la version actuelle de l’application 3. Une fois le téléchargement terminé, Capgo attend que l’utilisateur mette l’application en arrière-plan ou la ferme complètement 4. Lorsque l’utilisateur relance l’application, il exécutera la version mise à jour Ce flux garantit que les utilisateurs utilisent toujours la dernière version de votre application, sans jamais être interrompus par des invites de mise à jour ou forcés d’attendre des téléchargements. Tip Capgo vérifie également les mises à jour lorsque l’application reprend depuis l’arrière-plan, ainsi les utilisateurs recevront les mises à jour même s’ils ne quittent pas complètement l’application ## Pourquoi cette approche ? L’application des mises à jour lors d’un événement d’arrière-plan ou de fermeture présente plusieurs avantages clés pour l’expérience utilisateur : * Les utilisateurs ne sont pas interrompus par des invites de mise à jour ou forcés d’attendre des téléchargements au milieu d’une session * Les mises à jour sont appliquées de manière transparente entre les sessions, ainsi l’expérience de lancement de l’application est toujours nouvelle * Vous pouvez livrer des mises à jour fréquemment sans vous soucier de perturber les utilisateurs actifs Le principal inconvénient est que si un utilisateur met en arrière-plan et reprend rapidement votre application, il peut perdre tout état non sauvegardé puisque la mise à jour a été appliquée entre ces actions. Pour atténuer cela, nous recommandons : * Sauvegarder l’état fréquemment et le restaurer gracieusement lorsque l’application reprend * Éviter les mises à jour très fréquentes qui modifient de grandes parties de l’état de l’application * Envisager de personnaliser le comportement de mise à jour pour les flux sensibles (voir ci-dessous) ## Personnalisation du moment d’application des mises à jour Dans certains cas, vous pouvez vouloir plus de contrôle sur le moment exact où une mise à jour est appliquée. Par exemple, vous pourriez vouloir vous assurer qu’un utilisateur termine un flux en cours avant la mise à jour, ou coordonner une mise à jour d’application avec un changement côté serveur. Capgo fournit une fonction `setDelay` qui vous permet de spécifier les conditions qui doivent être remplies avant qu’une mise à jour ne soit installée : ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; await CapacitorUpdater.setMultiDelay({ delayConditions: [ { kind: 'date', value: '2023-06-01T00:00:00.000Z', }, { kind: 'background', value: '60000', }, ], }); ``` Cet exemple retarderait l’installation d’une mise à jour jusqu’après le 1er juin 2023 ET que l’application ait été en arrière-plan pendant au moins 60 secondes. Les conditions de délai disponibles sont : * `date` : Attendre jusqu’après une date/heure spécifique pour appliquer la mise à jour * `background` : Attendre une durée minimale après la mise en arrière-plan de l’application pour appliquer la mise à jour * `nativeVersion` : Attendre qu’un binaire natif avec une version minimale soit installé avant d’appliquer la mise à jour * `kill` : Attendre jusqu’au prochain événement de fermeture de l’application pour appliquer la mise à jour Vous pouvez mélanger ces conditions pour contrôler précisément quand une mise à jour est installée. Danger Notez que la condition `kill` déclenche actuellement la mise à jour après le premier événement de fermeture, et non le prochain événement d’arrière-plan comme les autres conditions. Cette incohérence sera corrigée dans une future version ## Application immédiate des mises à jour Pour les mises à jour critiques ou les applications avec un état très simple, vous pouvez vouloir appliquer une mise à jour dès qu’elle est téléchargée, sans attendre un événement d’arrière-plan ou de fermeture. Capgo prend en charge cela via l’option de configuration `directUpdate`. `directUpdate` est défini dans votre fichier `capacitor.config.ts`, pas dans le code JavaScript : ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: true, keepUrlPathAfterReload: true, }, }, }; export default config; ``` Avec `directUpdate` activé, Capgo appliquera immédiatement une mise à jour dès que le téléchargement est terminé, même si l’utilisateur utilise activement l’application. Notez que comme `directUpdate` est une configuration native, elle nécessite une gestion supplémentaire dans votre code JavaScript. Lors de l’utilisation de `directUpdate`, vous devez écouter l’événement `appReady` et masquer l’écran de démarrage de votre application en réponse : ```js import { CapacitorUpdater } from '@capgo/capacitor-updater'; import { SplashScreen } from '@capacitor/splash-screen'; CapacitorUpdater.addListener('appReady', () => { // Masquer l'écran de démarrage SplashScreen.hide(); }); CapacitorUpdater.notifyAppReady(); ``` L’événement `appReady` se déclenche une fois que l’application a terminé l’initialisation et l’application des mises à jour en attente. C’est le moment où il est sûr d’afficher l’interface utilisateur de votre application, car cela garantit que l’utilisateur verra la dernière version. En plus de gérer l’événement `appReady`, nous recommandons de définir l’option de configuration `keepUrlPathAfterReload` sur `true` lors de l’utilisation de `directUpdate`. Cela préserve le chemin URL actuel lorsque l’application est rechargée en raison d’une mise à jour, aidant à maintenir la position de l’utilisateur dans l’application et réduisant la désorientation. Si vous ne gérez pas l’événement `appReady` et ne définissez pas `keepUrlPathAfterReload` lors de l’utilisation de `directUpdate`, l’utilisateur peut brièvement voir une version obsolète de l’application, être ramené à la route initiale, ou voir un scintillement lors de l’application de la mise à jour. L’utilisation de `directUpdate` peut être utile pour livrer des corrections de bugs critiques ou des correctifs de sécurité, mais elle présente certains compromis : * L’utilisateur peut voir un bref scintillement ou état de chargement lors de l’application de la mise à jour si vous ne gérez pas correctement l’événement `appReady` * Si la mise à jour modifie l’état ou l’interface utilisateur de l’application, l’utilisateur peut voir un changement perturbateur au milieu d’une session * La position de l’utilisateur dans l’application peut être perdue si `keepUrlPathAfterReload` n’est pas défini, ce qui peut le désorienter * Vous devrez gérer soigneusement la sauvegarde et la restauration de l’état pour assurer une transition fluide Si vous activez `directUpdate`, nous recommandons : * Gérer l’événement `appReady` pour contrôler quand l’interface utilisateur de votre application est affichée * Définir `keepUrlPathAfterReload` sur `true` pour préserver la position de l’utilisateur dans l’application * Sauvegarder et restaurer l’état de l’application selon les besoins pour éviter de perdre la progression de l’utilisateur * Tester minutieusement le comportement de mise à jour de votre application pour s’assurer qu’il n’y a pas de transitions brusques, d’états perdus ou de changements de position désorientants Dans la plupart des cas, le comportement de mise à jour par défaut offre le meilleur équilibre entre la livraison rapide des mises à jour et la minimisation des perturbations. Mais pour les applications ayant des besoins spécifiques, Capgo offre la flexibilité de personnaliser quand et comment les mises à jour sont appliquées. # Fonctions et paramètres > Les méthodes et configurations disponibles du plugin # Configuration du Plugin Updater Voir le [Readme](https://github.com/Cap-go/capacitor-updater) Github pour plus d’informations CapacitorUpdater peut être configuré avec ces options : | Prop | Type | Description | Par défaut | Depuis | | ------------------------ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | ------ | | **`appReadyTimeout`** | `number` | Configure le nombre de millisecondes pendant lesquelles le plugin natif doit attendre avant de considérer une mise à jour comme ‘échouée’ Disponible uniquement pour Android et iOS | `10000 // (10 secondes)` | | | **`responseTimeout`** | `number` | Configure le nombre de millisecondes pendant lesquelles le plugin natif doit attendre avant de considérer l’API comme expirée Disponible uniquement pour Android et iOS | `20 // (20 secondes)` | | | **`autoDeleteFailed`** | `boolean` | Configure si le plugin doit automatiquement supprimer les bundles échoués Disponible uniquement pour Android et iOS | `true` | | | **`autoDeletePrevious`** | `boolean` | Configure si le plugin doit automatiquement supprimer les bundles précédents après une mise à jour réussie Disponible uniquement pour Android et iOS | `true` | | | **`autoUpdate`** | `boolean` | Configure si le plugin doit utiliser la mise à jour automatique via un serveur de mise à jour Disponible uniquement pour Android et iOS | `true` | | | **`resetWhenUpdate`** | `boolean` | Supprime automatiquement les bundles précédemment téléchargés lors de l’installation d’une nouvelle version native de l’application Disponible uniquement pour Android et iOS | `true` | | | **`updateUrl`** | `string` | Configure l’URL / point de terminaison vers lequel les vérifications de mise à jour sont envoyées Disponible uniquement pour Android et iOS | `https://plugin.capgo.app/updates` | | | **`channelUrl`** | `string` | Configure l’URL / point de terminaison pour les opérations de canal Disponible uniquement pour Android et iOS | `https://plugin.capgo.app/channel_self` | | | **`statsUrl`** | `string` | Configure l’URL / point de terminaison vers lequel les statistiques de mise à jour sont envoyées Disponible uniquement pour Android et iOS Mettre à "" pour désactiver les rapports stats | `https://plugin.capgo.app/stats` | | | **`privateKey`** | `string` | Configure la clé privée pour le chiffrement de bout en bout des mises à jour en direct Disponible uniquement pour Android et iOS Déprécié en version 620, sera supprimé en version 700 | `undefined` | | | **`publicKey`** | `string` | Configure la clé publique pour le chiffrement de bout en bout des mises à jour en direct Version 2 Disponible uniquement pour Android et iOS | `undefined` | 620 | | **`version`** | `string` | Configure la version actuelle de l’application Sera utilisé pour la première demande de mise à jour Si non défini, le plugin obtiendra la version du code natif Disponible pour Android/iOS | `undefined` | 41748 | | **`directUpdate`** | `boolean` | Fait installer directement la mise à jour par le plugin lorsque l’application vient d’être mise à jour/installée Uniquement pour le mode autoUpdate Android et iOS uniquement | `undefined` | 510 | | **`periodCheckDelay`** | `number` | Configure le délai de vérification périodique des mises à jour en secondes Disponible uniquement pour Android et iOS Ne peut pas être inférieur à 600 secondes (10 minutes) | `600 // (10 minutes)` | | | **`localS3`** | `boolean` | Configure le CLI pour utiliser un serveur local pour les tests ou un serveur de mise à jour auto-hébergé | `undefined` | 41748 | | **`localHost`** | `string` | Configure le CLI pour utiliser un serveur local pour les tests ou un serveur de mise à jour auto-hébergé | `undefined` | 41748 | | **`localWebHost`** | `string` | Configure le CLI pour utiliser un serveur local pour les tests ou un serveur de mise à jour auto-hébergé | `undefined` | 41748 | | **`localSupa`** | `string` | Configure le CLI pour utiliser un serveur local pour les tests ou un serveur de mise à jour auto-hébergé | `undefined` | 41748 | | **`localSupaAnon`** | `string` | Configure le CLI pour utiliser un serveur local pour les tests | `undefined` | 41748 | | **`localApi`** | `string` | Configure le CLI pour utiliser une API locale pour les tests | `undefined` | 633 | | **`localApiFiles`** | `string` | Configure le CLI pour utiliser une API de fichiers locale pour les tests | `undefined` | 633 | | **`allowModifyUrl`** | `boolean` | Permet au plugin de modifier dynamiquement updateUrl, statsUrl et channelUrl depuis le côté JavaScript | `false` | 540 | | **`defaultChannel`** | `string` | Définit le canal par défaut pour l’application dans la configurationVoici la traduction en français : | | | \| `undefined` | 550 | | **`appId`** | `string` | Configurer l’identifiant de l’application dans la configuration | `undefined` | 600 | | **`keepUrlPathAfterReload`** | `boolean` | Configurer le plugin pour conserver le chemin URL après un rechargement ATTENTION : Lorsqu’un rechargement est déclenché, ‘windowhistory’ sera effacé | `false` | 680 | ## Exemples Dans `capacitorconfigjson` : ```json { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 // (1 seconde), "responseTimeout": 10 // (10 secondes), "autoDeleteFailed": false, "autoDeletePrevious": false, "autoUpdate": false, "resetWhenUpdate": false, "updateUrl": https://examplecom/api/auto_update, "channelUrl": https://examplecom/api/channel, "statsUrl": https://examplecom/api/stats, "privateKey": undefined, "publicKey": undefined, "version": undefined, "directUpdate": undefined, "periodCheckDelay": undefined, "localS3": undefined, "localHost": undefined, "localWebHost": undefined, "localSupa": undefined, "localSupaAnon": undefined, "localApi": undefined, "localApiFiles": undefined, "allowModifyUrl": undefined, "defaultChannel": undefined, "appId": undefined, "keepUrlPathAfterReload": undefined } } } ``` Dans `capacitorconfigts` : ```ts /// import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { appReadyTimeout: 1000 // (1 seconde), responseTimeout: 10 // (10 secondes), autoDeleteFailed: false, autoDeletePrevious: false, autoUpdate: false, resetWhenUpdate: false, updateUrl: https://examplecom/api/auto_update, channelUrl: https://examplecom/api/channel, statsUrl: https://examplecom/api/stats, privateKey: undefined, publicKey: undefined, version: undefined, directUpdate: undefined, periodCheckDelay: undefined, localS3: undefined, localHost: undefined, localWebHost: undefined, localSupa: undefined, localSupaAnon: undefined, localApi: undefined, localApiFiles: undefined, allowModifyUrl: undefined, defaultChannel: undefined, appId: undefined, keepUrlPathAfterReload: undefined, }, }, }; export default config; ``` * [`notifyAppReady()`](#notifyappready) * [`setUpdateUrl()`](#setupdateurl) * [`setStatsUrl()`](#setstatsurl) * [`setChannelUrl()`](#setchannelurl) * [`download()`](#download) * [`next()`](#next) * [`set()`](#set) * [`delete()`](#delete) * [`list()`](#list) * [`reset()`](#reset) * [`current()`](#current) * [`reload()`](#reload) * [`setMultiDelay()`](#setmultidelay) * [`cancelDelay()`](#canceldelay) * [`getLatest()`](#getlatest) * [`setChannel()`](#setchannel) * [`unsetChannel()`](#unsetchannel) * [`getChannel()`](#getchannel) * [`setCustomId()`](#setcustomid) * [`getBuiltinVersion()`](#getbuiltinversion) * [`getDeviceId()`](#getdeviceid) * [`getPluginVersion()`](#getpluginversion) * [`isAutoUpdateEnabled()`](#isautoupdateenabled) * [`removeAllListeners()`](#removealllisteners) * [`addListener('download', )`](#addlistenerdownload-) * [`addListener('noNeedUpdate', )`](#addlistenernoneedupdate-) * [`addListener('updateAvailable', )`](#addlistenerupdateavailable-) * [`addListener('downloadComplete', )`](#addlistenerdownloadcomplete-) * [`addListener('majorAvailable', )`](#addlistenermajoravailable-) * [`addListener('updateFailed', )`](#addlistenerupdatefailed-) * [`addListener('downloadFailed', )`](#addlistenerdownloadfailed-) * [`addListener('appReloaded', )`](#addlistenerappreloaded-) * [`addListener('appReady', )`](#addlistenerappready-) * [`isAutoUpdateAvailable()`](#isautoupdateavailable) * [`getNextBundle()`](#getnextbundle) * [Interfaces](#interfaces) * [Type Aliases](#type-aliases) # Méthodes ## notifyAppReady() ```typescript notifyAppReady() => Promise ``` Notifier Capacitor Updater que le bundle actuel fonctionne (un retour en arrière se produira si cette méthode n’est pas appelée à chaque lancement de l’application) Par défaut, cette méthode doit être appelée dans les 10 premières secondes après le lancement de l’application, sinon un retour en arrière se produira Modifiez ce comportement avec {@link appReadyTimeout} **Retourne:** `Promise` *** ## setUpdateUrl() ```typescript setUpdateUrl(options: UpdateUrl) => Promise ``` Définir l’updateUrl pour l’application, elle sera utilisée pour vérifier les mises à jour | Param | Type | Description | | ------------- | ----------- | -------------------------------------------------------- | | **`options`** | `UpdateUrl` | contient l’URL à utiliser pour vérifier les mises à jour | **Depuis:** 540 *** ## setStatsUrl() ```typescript setStatsUrl(options: StatsUrl) => Promise ``` Définir la statsUrl pour l’application, elle sera utilisée pour envoyer des statistiques. Passer une chaîne vide désactivera la collecte de statistiques | Param | Type | Description | | ------------- | ---------- | ------------------------------------------------------- | | **`options`** | `StatsUrl` | contient l’URL à utiliser pour envoyer les statistiques | **Depuis:** 540 *** ## setChannelUrl() ```typescript setChannelUrl(options: ChannelUrl) => Promise ``` Définir la channelUrl pour l’application, elle sera utilisée pour définir le canal | Param | Type | Description | | ------------- | ------------ | ----------------------------------------------- | | **`options`** | `ChannelUrl` | contient l’URL à utiliser pour définir le canal | **Depuis:** 540 *** ## download() ```typescript download(options: DownloadOptions) => Promise ``` Télécharger un nouveau bundle depuis l’URL fournie, il doit être un fichier zip, avec des fichiers à l’intérieur ou avec un identifiant unique à l’intérieur avec tous vos fichiers | Param | Type | Description | | ------------- | ----------------- | -------------------------------------------------------------------------------------- | | **`options`** | `DownloadOptions` | Les {@link [DownloadOptions](#downloadoptions)} pour télécharger un nouveau bundle zip | **Retourne:** `Promise` *** ## next() ```typescript next(options: BundleId) => Promise ``` Définir le prochain bundle à utiliser lorsque l’application sera rechargée| Param | Type | Description | | ------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | Contient l’ID du prochain Bundle à définir lors du prochain lancement de l’application {@link [BundleInfoid](#bundleinfo)} | **Returns:** `Promise` *** ## set() ```typescript set(options: BundleId) => Promise ``` Définit le bundle actuel et recharge immédiatement l’application | Param | Type | Description | | ------------- | ---------- | -------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | Un objet {@link [BundleId](#bundleid)} contenant le nouveau bundle id à définir comme actuel | *** ## delete() ```typescript delete(options: BundleId) => Promise ``` Supprime le bundle spécifié du stockage natif de l’application. Utiliser avec {@link list} pour obtenir les ID des Bundles stockés | Param | Type | Description | | ------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | Un objet {@link [BundleId](#bundleid)} contenant l’ID d’un bundle à supprimer (noter que c’est l’id du bundle, PAS le nom de la version) | *** ## list() ```typescript list(options?: ListOptions | undefined) => Promise ``` Obtenir tous les bundles téléchargés localement dans votre application | Param | Type | Description | | ------------- | ------------- | --------------------------------------------------------------- | | **`options`** | `ListOptions` | Les {@link [ListOptions](#listoptions)} pour lister les bundles | **Returns:** `Promise` *** ## reset() ```typescript reset(options?: ResetOptions | undefined) => Promise ``` Réinitialiser l’application au bundle ‘builtin’ (celui envoyé à l’Apple App Store / Google Play Store) ou au dernier bundle chargé avec succès | Param | Type | Description | | ------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **`options`** | `ResetOptions` | Contenant {@link [ResetOptionstoLastSuccessful](#resetoptions)}, `true` réinitialise au bundle intégré et `false` réinitialisera au dernier bundle chargé avec succès | *** ## current() ```typescript current() => Promise ``` Obtenir le bundle actuel, si aucun n’est défini, renvoie ‘builtin’. currentNative est le bundle d’origine installé sur l’appareil **Returns:** `Promise` *** ## reload() ```typescript reload() => Promise ``` Recharger la vue *** ## setMultiDelay() ```typescript setMultiDelay(options: MultiDelayConditions) => Promise ``` Définit un tableau {@link [DelayCondition](#delaycondition)} contenant les conditions que le Plugin utilisera pour retarder la mise à jour. Une fois toutes les conditions remplies, le processus de mise à jour redémarrera comme d’habitude, la mise à jour sera donc installée après une mise en arrière-plan ou l’arrêt de l’application. Pour le type ‘date’, la valeur doit être une chaîne de date iso8601. Pour le type ‘background’, la valeur doit être un nombre en millisecondes. Pour le type ‘nativeVersion’, la valeur doit être le numéro de version. Pour le type ‘kill’, la valeur n’est pas utilisée. La fonction a un comportement incohérent, l’option kill déclenche la mise à jour après le premier arrêt et non après la prochaine mise en arrière-plan comme les autres options. Cela sera corrigé dans une future version majeure. | Param | Type | Description | | ------------- | ---------------------- | --------------------------------------------------------------------------------------------------- | | **`options`** | `MultiDelayConditions` | Contenant le tableau {@link [MultiDelayConditions](#multidelayconditions)} des conditions à définir | **Since:** 430 *** ## cancelDelay() ```typescript cancelDelay() => Promise ``` Annule une {@link [DelayCondition](#delaycondition)} pour traiter une mise à jour immédiatement **Since:** 400 *** ## getLatest() ```typescript getLatest(options?: GetLatestOptions | undefined) => Promise ``` Obtenir le dernier bundle disponible depuis l’URL de mise à jour | Param | Type | | ------------- | ------------------ | | **`options`** | `GetLatestOptions` | **Returns:** `Promise` **Since:** 400 *** ## setChannel() ```typescript setChannel(options: SetChannelOptions) => Promise ``` Définit le canal pour cet appareil. Le canal doit autoriser l’auto-attribution pour que cela fonctionne. N’utilisez pas cette méthode pour définir le canal au démarrage lorsque `autoUpdate` est activé dans {@link PluginsConfig}. Cette méthode sert à définir le canal après que l’application est prête. Cette méthode envoie au backend Capgo une requête pour lier l’ID de l’appareil au canal. Capgo peut accepter ou refuser selon les paramètres de votre canal. | Param | Type | Description | | ------------- | ------------------- | ---------------------------------------------------------------------- | | **`options`** | `SetChannelOptions` | Est le canal {@link [SetChannelOptions](#setchanneloptions)} à définir | **Returns:** `Promise` **Since:** 470 *** ## unsetChannel() ```typescript unsetChannel(options: UnsetChannelOptions) => Promise ``` Désactive le canal pour cet appareilL’appareil reviendra ensuite au canal par défaut | Param | Type | | ------------- | --------------------- | | **`options`** | `UnsetChannelOptions` | **Since:** 470 *** ## getChannel() ```typescript getChannel() => Promise ``` Obtenir le canal pour cet appareil **Returns:** `Promise` **Since:** 480 *** ## setCustomId() ```typescript setCustomId(options: SetCustomIdOptions) => Promise ``` Définir un ID personnalisé pour cet appareil | Param | Type | Description | | ------------- | -------------------- | --------------------------------------------------------------------------- | | **`options`** | `SetCustomIdOptions` | est le {@link [SetCustomIdOptions](#setcustomidoptions)} customId à définir | **Since:** 490 *** ## getBuiltinVersion() ```typescript getBuiltinVersion() => Promise ``` Obtenir la version de l’application native ou la version intégrée si définie dans la configuration **Returns:** `Promise` **Since:** 520 *** ## getDeviceId() ```typescript getDeviceId() => Promise ``` Obtenir l’ID unique utilisé pour identifier l’appareil (envoyé au serveur de mise à jour automatique) **Returns:** `Promise` *** ## getPluginVersion() ```typescript getPluginVersion() => Promise ``` Obtenir la version native du plugin Capacitor Updater (envoyée au serveur de mise à jour automatique) **Returns:** `Promise` *** ## isAutoUpdateEnabled() ```typescript isAutoUpdateEnabled() => Promise ``` Obtenir l’état de la configuration de mise à jour automatique **Returns:** `Promise` *** ## removeAllListeners() ```typescript removeAllListeners() => Promise ``` Supprimer tous les écouteurs pour ce plugin **Since:** 100 *** ## addListener(‘download’, ) ```typescript addListener(eventName: 'download', listenerFunc: (state: DownloadEvent) => void) => Promise ``` Écouter l’événement de téléchargement du bundle dans l’application. Se déclenche une fois qu’un téléchargement a commencé, pendant le téléchargement et une fois terminé | Param | Type | | ------------------ | -------------------------------- | | **`eventName`** | `’download’` | | **`listenerFunc`** | `(state: DownloadEvent) => void` | **Returns:** `Promise` **Since:** 2011 *** ## addListener(‘noNeedUpdate’, ) ```typescript addListener(eventName: 'noNeedUpdate', listenerFunc: (state: NoNeedEvent) => void) => Promise ``` Écouter l’événement indiquant qu’aucune mise à jour n’est nécessaire, utile lorsque vous voulez forcer la vérification à chaque lancement de l’application | Param | Type | | ------------------ | ------------------------------ | | **`eventName`** | `’noNeedUpdate’` | | **`listenerFunc`** | `(state: NoNeedEvent) => void` | **Returns:** `Promise` **Since:** 400 *** ## addListener(‘updateAvailable’, ) ```typescript addListener(eventName: 'updateAvailable', listenerFunc: (state: UpdateAvailableEvent) => void) => Promise ``` Écouter l’événement de mise à jour disponible, utile lorsque vous voulez forcer la vérification à chaque lancement de l’application | Param | Type | | ------------------ | --------------------------------------- | | **`eventName`** | `’updateAvailable’` | | **`listenerFunc`** | `(state: UpdateAvailableEvent) => void` | **Returns:** `Promise` **Since:** 400 *** ## addListener(‘downloadComplete’, ) ```typescript addListener(eventName: 'downloadComplete', listenerFunc: (state: DownloadCompleteEvent) => void) => Promise ``` Écouter les événements downloadComplete | Param | Type | | ------------------ | ---------------------------------------- | | **`eventName`** | `’downloadComplete’` | | **`listenerFunc`** | `(state: DownloadCompleteEvent) => void` | **Returns:** `Promise` **Since:** 400 *** ## addListener(‘majorAvailable’, ) ```typescript addListener(eventName: 'majorAvailable', listenerFunc: (state: MajorAvailableEvent) => void) => Promise ``` Écouter l’événement de mise à jour majeure dans l’application, vous informe quand une mise à jour majeure est bloquée par le paramètre disableAutoUpdateBreaking | Param | Type | | ------------------ | -------------------------------------- | | **`eventName`** | `’majorAvailable’` | | **`listenerFunc`** | `(state: MajorAvailableEvent) => void` | **Returns:** `Promise` **Since:** 230 *** ## addListener(‘updateFailed’, ) ```typescript addListener(eventName: 'updateFailed', listenerFunc: (state: UpdateFailedEvent) => void) => Promise ``` Écouter l’événement d’échec de mise à jour dans l’application, vous informe quand une mise à jour n’a pas pu être installée au prochain démarrage de l’application | Param | Type | | ------------------ | ------------------------------------ | | **`eventName`** | `’updateFailed’` | | **`listenerFunc`** | `(state: UpdateFailedEvent) => void` | **Returns:** `Promise` **Since:** 230 *** ## addListener(‘downloadFailed’,\`\`\`typescript addListener(eventName: ‘downloadFailed’, listenerFunc: (state: DownloadFailedEvent) => void) => Promise ````plaintext Écouter l'événement d'échec de téléchargement dans l'application, vous informe lorsqu'un téléchargement de bundle a échoué | Param | Type | |----------|-------------| | **`eventName`** | 'downloadFailed' | | **`listenerFunc`** | (state: DownloadFailedEvent) => void | **Returns:** Promise<PluginListenerHandle> **Since:** 400 -------------------- ## addListener('appReloaded', ) ```typescript addListener(eventName: 'appReloaded', listenerFunc: () => void) => Promise ```` Écouter l’événement de rechargement dans l’application, vous informe lorsqu’un rechargement s’est produit | Param | Type | | ------------------ | --------------- | | **`eventName`** | `’appReloaded’` | | **`listenerFunc`** | `() => void` | **Returns:** `Promise` **Since:** 430 *** ## addListener(‘appReady’, ) ```typescript addListener(eventName: 'appReady', listenerFunc: (state: AppReadyEvent) => void) => Promise ``` Écouter l’événement “app ready” dans l’application, vous informe lorsque l’application est prête à être utilisée | Param | Type | | ------------------ | -------------------------------- | | **`eventName`** | `’appReady’` | | **`listenerFunc`** | `(state: AppReadyEvent) => void` | **Returns:** `Promise` **Since:** 510 *** ## isAutoUpdateAvailable() ```typescript isAutoUpdateAvailable() => Promise ``` Vérifier si la mise à jour automatique est disponible (non désactivée par serverUrl) **Returns:** `Promise` *** ## getNextBundle() ```typescript getNextBundle() => Promise ``` Obtenir le prochain bundle qui sera utilisé lors du rechargement de l’application Renvoie null si aucun prochain bundle n’est défini **Returns:** `Promise` **Since:** 680 *** ## Interfaces ### AppReadyResult | Prop | Type | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | ### BundleInfo | Prop | Type | | ---------------- | -------------- | | **`id`** | `string` | | **`version`** | `string` | | **`downloaded`** | `string` | | **`checksum`** | `string` | | **`status`** | `BundleStatus` | ### UpdateUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### StatsUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### ChannelUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### DownloadOptions | Prop | Type | Description | Default | Since | | ---------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ----- | | **`url`** | `string` | L’URL du fichier zip du bundle (par exemple : distzip) à télécharger (Cela peut être n’importe quelle URL, par exemple : Amazon S3, un tag GitHub, tout autre endroit où vous avez hébergé votre bundle) | | | | **`version`** | `string` | Le code/nom de version de ce bundle/version | | | | **`sessionKey`** | `string` | La clé de session pour la mise à jour | `undefined` | 400 | | **`checksum`** | `string` | La somme de contrôle pour la mise à jour | `undefined` | 400 | ### BundleId | Prop | Type | | -------- | -------- | | **`id`** | `string` | ### BundleListResult | Prop | Type | | ------------- | -------------- | | **`bundles`** | `BundleInfo[]` | ### ListOptions | Prop | Type | Description | Default | Since | | --------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ----- | | **`raw`** | `boolean` | Indique s’il faut renvoyer la liste brute des bundles ou le manifeste. Si vrai, la liste tentera de lire la base de données interne au lieu des fichiers sur le disque | `false` | 6140 | ### ResetOptions | Prop | Type | | ---------------------- | --------- | | **`toLastSuccessful`** | `boolean` | ### CurrentBundleResult | Prop | Type | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | | **`native`** | `string` | ### MultiDelayConditions | Prop | Type | | --------------------- | ------------------ | | **`delayConditions`** | `DelayCondition[]` | ### DelayCondition | Prop | Type | Description | | ----------- | ---------------- | ----------------------------------------------------- | | **`kind`** | `DelayUntilNext` | Configurer les conditions de délai dans setMultiDelay | | **`value`** | `string` | | ### LatestVersion | Prop | Type | Description | Since | | ---------------- | ----------------- | -------------------------------- | ----- | | **`version`** | `string` | Résultat de la méthode getLatest | 40 | | **`major`** | `boolean` | | | | **`message`** | `string` | | | | **`sessionKey`** | `string` | | | | **`error`** | `string` | | | | **`old`** | `string` | | | | **`url`** | `string` | | | | **`manifest`** | `ManifestEntry[]` | | 61 | ### ManifestEntry | Prop | Type | | ------------------ | ---------------- | | **`file_name`** | `string \| null` | | **`file_hash`** | `string \| null` | | **`download_url`** | `string \| null` | ### GetLatestOptions | Prop | Type | Description | Default | Since | | ------------- | -------- | -------------------------------------------------------------------------------------------------- | ----------- | ----- | | **`channel`** | `string` | Le canal pour obtenir la dernière version. Le canal doit autoriser ‘self\_assign’ pour fonctionner | `undefined` | 680 | ### ChannelRes | Prop | Type | Description | Since | | ------------- | -------- | --------------------------- | ----- | | **`status`** | `string` | État actuel du canal défini | 470 | | **`error`** | `string` | | | | **`message`** | `string` | | | ### SetChannelOptions | Prop | Type | | ----------------------- | --------- | | **`channel`** | `string` | | **`triggerAutoUpdate`** | `boolean` | ### UnsetChannelOptions | Prop | Type | | ----------------------- | --------- | | **`triggerAutoUpdate`** | `boolean` | ### GetChannelRes | Prop | Type | Description | Since | | -------------- | --------- | ----------------------------------- | ----- | | **`channel`** | `string` | État actuel de l’obtention du canal | 480 | | **`error`** | `string` | | | | **`message`** | `string` | | | | **`status`** | `string` | | | | **`allowSet`** | `boolean` | | | ### SetCustomIdOptions | Prop | Type | | -------------- | -------- | | **`customId`** | `string` | ### BuiltinVersion | Prop | Type | | ------------- | -------- | | **`version`** | `string` | ### DeviceId | Prop | Type | | -------------- | -------- | | **`deviceId`** | `string` | ### PluginVersion | Prop | Type | | ------------- | -------- | | **`version`** | `string` | ### AutoUpdateEnabled | Prop | Type | | ------------- | --------- | | **`enabled`** | `boolean` | ### PluginListenerHandle | Prop | Type | | ------------ | --------------------- | | **`remove`** | `() => Promise` | ### DownloadEvent | Prop | Type | Description | Since | | ------------- | ------------ | --------------------------------------------- | ----- | | **`percent`** | `number` | État actuel du téléchargement, entre 0 et 100 | 400 | | **`bundle`** | `BundleInfo` | | | ### NoNeedEvent | Prop | Type | Description | Since | | ------------ | ------------ | --------------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | État actuel du téléchargement, entre 0 et 100 | 400 | ### UpdateAvailableEvent | Prop | Type | Description | Since | | ------------ | ------------ | --------------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | État actuel du téléchargement, entre 0 et 100 | 400 | ### DownloadCompleteEvent | Prop | Type | Description | Since | | ------------ | ------------ | -------------------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Émis quand une nouvelle mise à jour est disponible | 400 | ### MajorAvailableEvent | Prop | Type | Description | Since | | ------------- | -------- | ------------------------------------------------------ | ----- | | **`version`** | `string` | Émis quand une nouvelle version majeure est disponible | 400 | ### UpdateFailedEvent | Prop | Type | Description | Since | | ------------ | ------------ | ---------------------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Émis quand une mise à jour a échoué à l’installation | 400 | ### DownloadFailedEvent | Prop | Type | Description | Since | | ------------- | -------- | ----------------------------------- | ----- | | **`version`** | `string` | Émis quand un téléchargement échoue | 400 | ### AppReadyEvent | Prop | Type | Description | Since | | ------------ | ------------ | -------------------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Émis quand l’application est prête à être utilisée | 520 | | **`status`** | `string` | | | ### AutoUpdateAvailable | Prop | Type | | --------------- | --------- | | **`available`** | `boolean` | ## Type Aliases ### BundleStatus `‘success’ | ‘error’ | ‘pending’ | ‘downloading’` ### DelayUntilNext `‘background’ | ‘kill’ | ‘nativeVersion’ | ‘date’` # Mise à jour automatique > Comment utiliser la mise à jour automatique avec capacitor-updater Ce mode permet aux développeurs d’utiliser capacitor-updater en mode auto-update et de pousser des mises à jour via les canaux Capgo ou équivalent ### Prérequis Assurez-vous que la version de votre application utilise avant d’utiliser l’auto-update de Capgo C’est la convention utilisée pour gérer les versions dans Capgo Il existe deux façons de définir la version dans votre application : Nouvelle méthode : Utilisez le champ `version` dans votre fichier `capacitorconfigjson` ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true, // Active l'auto-update, true par défaut "appId": "comexampleapp", // Utilisé pour identifier l'application sur le serveur "version": "100" // Utilisé pour vérifier les mises à jour } } } ``` Ces options seront utilisées par le plugin pour vérifier les mises à jour et par le CLI pour télécharger la version Ancienne méthode : Dans 3 fichiers de votre projet : * `packagejson` dans **version** * `android/app/buildgradle` dans **versionName** * `ios/App/Appxcodeproj/projectpbxproj` dans **CURRENT\_PROJECT\_VERSION** ### Tutoriels Configurez votre application en 5 minutes [Mettez à jour vos applications Capacitor en toute transparence avec capacitor updater](https://capgo.app/blog/update-your-capacitor-apps-seamlessly-using-capacitor-updater) Configurez votre CI en 5 minutes [Build et déploiement automatiques avec GitHub actions](https://capgo.app/blog/automatic-build-and-release-with-github-actions) ### Installation ```bash npm install @capgo/capacitor-updater npx cap sync ``` ### Introduction Cliquez sur [register](https://capgo.app) pour créer votre compte Le serveur vous permet de gérer les canaux, les versions et bien plus encore `autoUpdate` utilisera les données de `capacitorconfig` pour identifier le serveur Capgo Note Vous pouvez toujours utiliser Capgo Cloud sans envoyer votre code à notre serveur si cela n’est pas autorisé par votre entreprise #### Valider la version Lorsque l’auto-update est configuré, vous devez notifier depuis JS que votre application est active et prête Cela peut être fait en appelant `notifyAppReady` dans votre application Faites-le le plus tôt possible ```ts import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdaternotifyAppReady() ``` #### Flux utilisateur 1. L’utilisateur ouvre l’application, l’application interroge le serveur pour vérifier les mises à jour, si des mises à jour sont trouvées, elles seront téléchargées en arrière-plan 2. L’utilisateur quitte l’application, la nouvelle version est définie comme active 3. L’utilisateur ouvre à nouveau l’application, nous chargeons la nouvelle version active et la définissons par défaut 4. Si `notifyAppReady()` est appelé, lorsque l’utilisateur quitte l’application, l’ancienne version est supprimée 5. L’utilisateur continue le flux normal de l’application jusqu’au prochain cycle de mise à jour Danger ⚠️ Ne pas appeler `notifyAppReady()` dans votre application marquera la version actuelle comme invalide et reviendra au bundle précédent valide ou d’origine #### Flux de développement Lorsque vous développez de nouvelles fonctionnalités, assurez-vous de bloquer `autoUpdate`, car capgo écrasera constamment votre travail avec le dernier bundle de mise à jour Définissez `autoUpdate` sur false dans votre configuration Si pour une raison quelconque vous êtes bloqué sur une mise à jour, vous pouvez supprimer l’application et la réinstaller Assurez-vous de définir `autoUpdate` sur false dans votre configuration avant de le faire Puis reconstruisez-la avec Xcode ou Android Studio Pour télécharger la version à chaque commit, configurez CI/CD avec ce guide [Build et déploiement automatiques avec GitHub actions](https://capgo.app/blog/automatic-build-and-release-with-github-actions) #### Événement Major Available Lorsque `disableAutoUpdateBreaking` est défini sur true, vous pouvez écouter l’événement pour savoir quand l’application refuse de faire une mise à jour majeure ```jsx import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdateraddListener('majorAvailable', (info: any) => { consolelog('majorAvailable was fired', infoversion) }) ``` # Système de canaux > Comment utiliser le système de canaux avec capacitor-updater Capgo et capacitor-updater sont livrés avec un puissant système de canaux ## Ce que vous pouvez faire avec les canaux : * Associer des appareils à un canal pour le développement, les tests bêta * Utiliser un canal par branche de développement et laisser votre équipe s’auto-assigner depuis le téléphone pour tester ## Assigner des appareils à un canal : * Définir le canal par défaut, chaque fois qu’un nouvel appareil demande une mise à jour à Capgo, ce canal répondra * Envoyer le **deviceId** (avec la méthode [**getDeviceId**](/docs/plugin/api#getdeviceid)) à votre backend et l’assigner avec l’API publique Capgo * Rendre le canal auto-assignable (avec la méthode [**setChannel**](/docs/plugin/api#setchannel)), et laisser l’appareil s’abonner au canal (avec ou sans interaction utilisateur) avec la méthode `setChannel` du plugin * Utiliser l’option `defaultChannel` dans la [configuration](/docs/plugin/settings#defaultchannel) pour définir le canal par défaut pour tous les appareils avec cette configuration du plugin Note Vous pouvez également assigner un appareil directement à un bundle ## Options du canal ![](/channel_setting_1.webp) Détails de chaque option : | Option | Description | | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | **Désactiver le déclassement automatique sous natif** | N’envoie pas de mise à jour si la version native de l’application est supérieure à celle du canal | | **Désactiver la mise à niveau automatique au-dessus de la majeure** | N’envoie pas de mise à jour si la version native de l’application est inférieure à une Majeure (**1**23) de celle du canal | | **Désactiver la mise à niveau automatique au-dessus de la mineure** | N’envoie pas de mise à jour si la version native de l’application est inférieure à une mineure (1**2**3) de celle du canal | | **Permettre à l’appareil de s’auto-assigner** | Permet à un appareil d’utiliser la méthode `setChannel` pour ce canal | | **IOS** | Permet aux appareils iOS de télécharger des mises à jour depuis ce canal | | **Android** | Permet aux appareils Android de télécharger des mises à jour depuis ce canal | | **Autoriser l’émulateur** | Permet aux émulateurs de recevoir des mises à jour depuis ce canal | | **Autoriser les builds de développement** | Permet aux builds de développement de recevoir des mises à jour depuis ce canal | Note Capgo effectue automatiquement certains filtrages pour vous. Si vous avez un CI/CD configuré pour envoyer votre version sur Google Play, Google Play exécutera votre application à chaque fois sur plus de 20 appareils réels. Pendant les 4 premières heures d’un nouveau bundle, nous bloquerons les IPs des centres de données Google pour éviter qu’elles ne soient comptabilisées dans vos statistiques Note Capgo **ne compte pas** les émulateurs et les builds de développement dans votre utilisation, mais gardez à l’esprit que vous ne pouvez pas en avoir plus de 3%, sinon votre compte sera verrouillé jusqu’à ce que vous corrigiez cela # Pour commencer > Installe le plugin dans ton application ## Introduction à Capgo [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## Les mises à jour en direct sont à 3 étapes ### Créez votre compte Visitez notre page d’inscription sur ![onboarding screenshot](/onboard.webp "onboarding screenshot") ### Installez Capgo avec le CLI Utilisez les commandes magiques pour commencer ```bash npx @capgo/cli@latest init [APIKEY] ``` Cette commande vous guidera à travers le processus d’installation ### Suivez simplement les instructions Dans le CLI, une série de questions vous sera présentée. Fournissez les réponses nécessaires pour compléter la configuration automatisée Tip En suivant ces étapes, vous serez opérationnel en un rien de temps. Si vous avez besoin d’aide pendant le processus, notre équipe de support est là pour vous aider. Bon démarrage ! ### Profitez de la magie de Capgo ! Testez votre application et découvrez plus tard comment utiliser les fonctionnalités avancées de Capgo # Mise à jour hybride > Méthode de mise à jour pour les mises à jour automatiques Lors de la mise à jour de votre application, vous disposez de plusieurs façons de gérer le cycle de mise à jour comme vous le souhaitez avant de les appliquer * Mise à jour silencieuse * Écouter l’événement `updateAvailable` * Afficher une fenêtre modale ou retarder les mises à jour ## Mise à jour silencieuse Vous pouvez forcer un cycle de mise à jour à chaque démarrage de l’application en définissant `directUpdate` sur `true`, cela déclenchera le cycle de mise à jour comme d’habitude sans l’interaction de l’utilisateur ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "directUpdate": true, }, "SplashScreen": { "launchAutoHide": false, } } } ``` Ensuite dans votre application, vous devez masquer l’écran de démarrage lorsque vous recevez l’événement `appReady` : ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' CapacitorUpdateraddListener('appReady', () => { // Hide splash SplashScreenhide() }) CapacitorUpdaternotifyAppReady() ``` ## Forcer la mise à jour Ajoutez un écouteur à l’événement `updateAvailable` puis affichez une alerte pour informer l’utilisateur que l’application va se mettre à jour : ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { Dialog } from '@capacitor/dialog' CapacitorUpdateraddListener('updateAvailable', async (res) => { try { await Dialogalert({ title: 'Mise à jour disponible', message: `La version ${resbundleversion} est disponible. L'application va se mettre à jour maintenant`, }) CapacitorUpdaterset(resbundle) } catch (error) { consolelog(error) } }) CapacitorUpdaternotifyAppReady() ``` ## Mise à jour modale Vous pouvez également laisser l’utilisateur décider en affichant une boîte de dialogue pour lui demander de mettre à jour : ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { Dialog } from '@capacitor/dialog' CapacitorUpdateraddListener('updateAvailable', async (res) => { try { const { value } = await Dialogconfirm({ title: 'Mise à jour disponible', message: `La version ${resbundleversion} est disponible. Voulez-vous mettre à jour maintenant ?`, }) if (value) CapacitorUpdaterset(resbundle) } catch (error) { consolelog(error) } }) CapacitorUpdaternotifyAppReady() ``` # Mise à jour manuelle > Comment gérer les mises à jour d'applications Si vous souhaitez gérer vous-même l’application des mises à jour, utilisez le mode manuel avec Capgo cloud Voici ce que vous devez faire, configurez votre compte comme expliqué dans la section Démarrage [Démarrage ](/docs/getting-started/quickstart/) #### Configuration Désactivez la mise à jour automatique dans votre `capacitor.config.json` ```tsx // capacitor.config.json { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` Ensuite, ajoutez la logique pour gérer les mises à jour vous-même\ Voici un exemple de la façon dont vous pouvez le faire : ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater' import type { BundleInfo } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' CapacitorUpdater.notifyAppReady() let data: BundleInfo | null = null App.addListener('appStateChange', async (state: any) => { console.log('appStateChange', state) if (state.isActive) { console.log('getLatest') // Effectuez le téléchargement pendant que l'application est active pour éviter les échecs de téléchargement const latest = await CapacitorUpdater.getLatest() console.log('latest', latest) if (latest.url) { data = await CapacitorUpdater.download(latest) console.log('download', data) } } if (!state.isActive && data) { console.log('set') // Effectuez le changement lorsque l'utilisateur quitte l'application ou quand vous le souhaitez SplashScreen.show() try { await CapacitorUpdater.set({ id: data.id }) } catch (err) { console.log(err) SplashScreen.hide() // en cas d'échec du set, sinon la nouvelle application devra le cacher } } }) ``` Documentation de toutes les API disponibles dans le plugin : [Méthodes ](/docs/plugin/api/) Il existe certains cas d’utilisation où vous pouvez permettre aux utilisateurs de s’abonner à des canaux et d’essayer différentes versions :\ # Cordova > Capacitor-updater sera-t-il disponible pour Cordova ? Vous vous demandiez si ce plugin sera un jour disponible pour Cordova J’ai commencé un dépôt de R\&D pour cela, mais c’est une énorme quantité de travail ## Problèmes Je sais que je peux le faire mais pour cela, je dois lire tout le code de Cordova comme je l’ai fait pour Capacitor, pour comprendre comment le faire fonctionner La version Android est plus facile à réaliser puisque les deux utilisent Java, mais iOS nécessite une réécriture complète car Swift n’est toujours pas bien pris en charge dans Cordova ## Solution En attendant, voici ce que vous pouvez faire : * [Soutenez-moi](https://github.com/sponsors/riderx) sur GitHub et je peux prioriser cela. Cela nécessitera au moins 1 mois de travail * Engagez-moi comme Consultant, j’ai l’habitude d’aider les grandes entreprises à migrer vers Capacitor, cela prend généralement \~10-20 jours, et le [bénéfice](https://ionicio/resources/articles/capacitor-vs-cordova-modern-hybrid-app-development) est énorme pour l’équipe # デバッグ > Comment déboguer votre app ## Comprendre les journaux cloud : ### Envoyé depuis le backend | code | Description | | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **InvalidIp** | L’utilisateur est situé dans un centre de données Google et la mise à jour date de moins de 4 heures. Ceci est fait pour empêcher les appareils des bots Google d’être comptés comme des appareils dans votre compte | | **needPlanUpgrade** (précédemment **needUpgrade**) | Indique que vous avez atteint la limite de votre forfait, et l’appareil ne recevra pas de mises à jour jusqu’à ce que vous effectuiez une mise à niveau ou jusqu’au mois prochain | | **noNew** | L’appareil dispose de la dernière version disponible | | **disablePlatformIos** | L’appareil est sur la plateforme iOS, mais celle-ci est désactivée dans les paramètres du canal | | **disablePlatformAndroid** | L’appareil est sur la plateforme Android, mais celle-ci est désactivée dans les paramètres du canal | | **disableAutoUpdate** | ”major" | | **disableAutoUpdateUnderNative** | L’appareil a la version (`123`), et le canal a une mise à jour (`122`) sous la version de l’appareil à envoyer, mais c’est désactivé dans les paramètres du canal | | **disableDevBuild** | L’appareil a une version de développement, mais celle-ci est désactivée dans les paramètres du canal | | **disableEmulator** | L’appareil est un émulateur, mais celui-ci est désactivé dans les paramètres du canal | ### Envoyé depuis l’appareil | code | Description | | ------------------------- | ------------------------------------------------------------------------------------- | | **get** | Les informations pour télécharger la nouvelle version ont été envoyées à l’appareil | | **delete** | Un bundle a été supprimé sur l’appareil | | **set** | Un bundle a été défini sur l’appareil | | **set\_fail** | Le bundle n’a pas pu être défini | | **reset** | L’appareil est revenu au bundle `builtin` | | **download\_XX** | Un nouveau bundle a été téléchargé - progression indiquée par XX% (incréments de 10%) | | **download\_complete** | Le nouveau bundle a terminé le téléchargement | | **download\_fail** | Le nouveau bundle n’a pas pu être téléchargé | | **update\_fail** | Le nouveau bundle a été installé mais n’a pas réussi à appeler `notifyAppReady` | | **checksum\_fail** | Le nouveau bundle n’a pas réussi à valider le checksum | | **windows\_path\_fail** | Le zip contient des fichiers avec des chemins Windows illégaux | | **canonical\_path\_fail** | Le chemin des fichiers n’est pas canonique | | **directory\_path\_fail** | Il y a une erreur dans le chemin des fichiers zip | | **unzip\_fail** | La décompression a échoué | | **low\_mem\_fail** | Le téléchargement a échoué en raison d’une mémoire insuffisante sur l’appareil | ### Statut du bundle * `SUCCESS` : installation du bundle terminée * `ERROR` : installation ou téléchargement échoué * `PENDING` : Téléchargement terminé, en attente de publication * `DELETED` : Bundle supprimé, toujours présent pour les statistiques * `DOWNLOADING` : Téléchargement d’un bundle en cours ## Comprendre les journaux de l’appareil : ### Commande de débogage : Il existe une commande de débogage pour les utilisateurs de Capgo cloud ```bash npx @capgo/cli@latest app debug ``` Cela vous permettra de vérifier tous les événements se produisant dans l’application et de trouver une solution si les mises à jour ne se produisent pas ### IOS pour trouver vos journaux sur Xcode [Obtenir le journal de l'appareil dans Xcode ](https://intercomhelp/deploygate/en/articles/4682692-getting-the-device-log-in-xcode) ### Android : pour trouver vos journaux sur Android studio [Voir les journaux avec Logcat ](https://developerandroidcom/studio/debug/am-logcat) ### Explications des journaux * `Failed to download from` **=>** identique à **download\_fail** * `notifyAppReady was not called, roll back current bundle` => identique à **update\_fail** ## Trouver le bundle téléchargé dans votre appareil ### iOS Pour déboguer sur iOS, vous devez extraire l’application sur votre ordinateur, vous pouvez le faire comme ceci : Xcode dispose d’une fonctionnalité intégrée pour inspecter le système de fichiers des applications installées par les développeurs sur un appareil iOS Pour y parvenir : 1. Connectez votre appareil à votre Mac et sélectionnez Window > Devices dans la barre de menu Xcode 2. Sélectionnez votre appareil dans le volet gauche sous la section Devices 3. Cela affichera une liste des applications installées par les développeurs pour cet appareil 4. Sélectionnez l’application que vous souhaitez inspecter puis sélectionnez l’icône d’engrenage près du bas de l’écran 5. Ici vous pouvez voir le système de fichiers actuel en sélectionnant Show Container ou télécharger un instantané Sélectionner Download Container téléchargera et exportera un instantané du système de fichiers sous forme de fichier xcappdata que vous pourrez parcourir Faites un clic droit sur ce fichier et sélectionnez Show Package Contents pour ouvrir le dossier Ouvrez le dossier App Data, et vous devriez maintenant voir quelques dossiers comme Documents, Library, tmp, etc ![image](/ios_debug_update_1.webp) Ensuite, vous trouverez une version dans 2 dossiers : `library/NoCloud/ionic_built_snapshots` est nécessaire après le redémarrage de l’application et `documents/versions` pour le rechargement à chaud ### Android Pour déboguer sur Android, vous devez accéder à l’appareil depuis Android Studio : 1. Cliquez sur View > Tool Windows > Device File Explorer ou cliquez sur le bouton Device File Explorer dans la barre d’outils pour ouvrir l’explorateur de fichiers de l’appareil 2. Sélectionnez un appareil dans la liste déroulante 3. Ouvrez le chemin **data/data/APP\_NAME/** où **APP\_NAME est l’ID de votre application** ![image](/android_debug_update.webp) Puis trouvez le dossier `versions` pour voir toutes les versions Le saviez-vous ? Sur Android, toutes les versions sont stockées dans un seul dossier, contrairement à iOS où elles doivent être dupliquées dans deux emplacements ## Comprendre les journaux de crash iOS en production [Comment examiner les journaux de crash de votre application ](https://developer.apple.com/news/?id=nra79npr) # Nuxt 2 > Comment installer le plugin dans Nuxt 2 # Installation dans Nuxt 2 Créez un fichier plugin `capacitor-updaterjs` dans le répertoire `plugins` ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' export default ({ app }) => { if (processclient) { windowonNuxtReady(() => { CapacitorUpdaternotifyAppReady() }) } } ``` Cela chargera le plugin côté client et notifiera l’application qu’elle est prête à recevoir des mises à jour # Problèmes connus > Problèmes connus avec Capacitor et CapGo ## Rechargement en direct Ionic * Lorsque vous développez, si vous utilisez la fonction de rechargement en direct d’Ionic depuis la CLI, elle remplacera le plugin, vous ne verrez donc jamais vos mises à jour ## Rechargement en direct Quasar * Il utilise le même système qu’Ionic en interne, vous ne verrez donc pas vos mises à jour ## Échecs des mises à jour * Cela se produit généralement lorsque de grandes mises à jour (> 20 Mo) sont envoyées, un grand pourcentage d’utilisateurs n’obtiendra pas la dernière version Auparavant, les utilisateurs devaient garder l’application ouverte jusqu’à la fin du téléchargement, maintenant nous utilisons le téléchargement en arrière-plan, mais c’est toujours limité à quelques secondes ## Android ### Impossible de télécharger Nous avons constaté des problèmes avec des appareils en Inde, et après avoir contacté les utilisateurs, leur avoir fait essayer différents serveurs DNS, cela a fonctionné Donc si vous rencontrez ce problème, essayez d’utiliser un autre serveur DNS comme Cloudflare ou Google DNS Cloudflare : 1111 et 1001 Google DNS : 8888 et 8844 ou dnsgoogle [Comment configurer un serveur DNS préféré sur Android ? ](https://wwwandroidpolicecom/use-preferred-dns-server-android-tutorial/) ### Auto-hébergé Lorsque vous poussez une mise à jour auto-hébergée, gardez à l’esprit que vous ne pouvez pas utiliser un point de terminaison “HTTP” car cela va à l’encontre des politiques de sécurité des applications Android, si vous souhaitez toujours le faire, suivez ce guide : [Comment autoriser tous les types de connexion réseau HTTP et HTTPS dans Android (9) Pie ? ](https://stackoverflow.com/a/51902630/5511370) ### Décompression Problème de décompression : Les entrées DEFLATED peuvent avoir un descripteur EXT Si vous avez compressé votre bundle avec autre chose que la CLI, le format de votre zip pourrait être incorrect, veuillez utiliser la commande CLI `npx @capgo/cli zip BUNDLE_FOLDER` C’est un problème connu de Java : [Problème de décompression : Les entrées DEFLATED peuvent avoir un descripteur EXT ](https://bugsopenjdkorg/browse/JDK-8143613) ### Problème Clearfix * Si vous avez des problèmes avec usesCleartextTraffic, c’est parce que le plugin suit les bonnes pratiques recommandées par sonar cloud, dans 90% des cas cela fonctionnera très bien, mais avec certains plugins cela cause des problèmes Pour résoudre ce problème, ajoutez dans `android/app/src/main/AndroidManifestxml` dans la clé `` : ```xml tools:replace="android:usesCleartextTraffic" xmlns:tools="http://schemasandroidcom/tools" ``` ## iOS ### Manifeste de confidentialité Ajoutez la clé de dictionnaire `NSPrivacyAccessedAPICategoryUserDefaults` à votre [Manifeste de confidentialité](https://capacitorjs.com/docs/ios/privacy-manifest) (généralement `ios/App/PrivacyInfoxcprivacy`) : ```xml NSPrivacyAccessedAPITypes NSPrivacyAccessedAPIType NSPrivacyAccessedAPICategoryUserDefaults NSPrivacyAccessedAPITypeReasons CA921 ``` Nous recommandons de déclarer [`CA921`](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278401) comme raison d’accès à l’API [`UserDefaults`](https://developer.apple.com/documentation/foundation/userdefaults) ### Permissions réseau Lors de l’utilisation d’un serveur local pour tester la mise à jour, l’application demandera la permission réseau, c’est un comportement normal, ce n’est pas le cas lorsque vous utilisez un serveur distant ## Les deux OS Lors des mises à jour en mode manuel, certains événements ne sont pas faciles à capturer, par exemple l’échec de mise à jour se déclenche juste avant que votre code JS ne se recharge, vous ne pourrez donc pas le capturer Une alternative est de lister les bundles et de vérifier les statistiques d’erreur pour savoir si la mise à jour échoue Nous devons trouver une meilleure façon de gérer cela à l’avenir, mais ce n’est pas une priorité, puisque le mode auto est la façon recommandée de faire les mises à jour Les PRs sont les bienvenues pour nous aider à améliorer cela ## CLI si votre CLI a des problèmes pour faire quoi que ce soit, Vérifiez si **appId** et **appName** sont présents dans votre **capacitorconfigts** Suivez le guide de la documentation officielle : [Configuration Capacitor ](https://capacitorjs.com/docs/config) # Vue d'ensemble > Explication des deux approches ### Mode Cloud (Recommandé) Le Mode Cloud est notre choix recommandé pour une gestion sans tracas des mises à jour. Le backend de Capgo gère toute la logique de mise à jour, prenant les décisions côté serveur pour une meilleure sécurité et un meilleur contrôle. Ce mode est axé sur la facilité d’utilisation : une fois configuré, il fonctionne de manière autonome, offrant des fonctionnalités avancées comme les statistiques et les canaux. Il peut également être configuré en mode manuel pour vous donner plus de contrôle, vous permettant de décider quand mettre à jour en utilisant votre code JavaScript. Le backend gère toujours ce qui est mis à jour. Ce mode partage de nombreux avantages avec le Mode Auto, particulièrement en termes de sécurité et de fonctionnalités avancées, mais ajoute la flexibilité de programmer vous-même les mises à jour. ### Mode Auto-hébergé Le Mode Auto Auto-hébergé est destiné à ceux qui souhaitent gérer toute la logique de mise à jour sur leur propre serveur. Il offre une autonomie complète mais nécessite un serveur distinct et plus de travail pour gérer les mises à jour et les exigences serveur. Le Mode Manuel Auto-hébergé combine contrôle et autonomie. Vous décidez quand mettre à jour via JavaScript, mais votre serveur gère ce qui est mis à jour. C’est un peu complexe car vous incluez le code de mise à jour dans les mises à jour. Note Si vous choisissez l’auto-hébergement, vous passez à côté de toutes les excellentes fonctionnalités que le cloud capgo offre comme : les retours automatiques, les alertes par email, les canaux, les statistiques, le chiffrement et plus encore Danger Si vous envoyez une mauvaise mise à jour à vos utilisateurs, vous pouvez et allez casser leur application # Auto Update > Comment utiliser le plugin auto-update en mode auto-hébergé Cette documentation expliquera comment exécuter votre serveur de mise à jour automatique ## Servir votre bundle Assurez-vous que votre bundle est servi via HTTPS, et que le serveur dispose des en-têtes CORS appropriés pour permettre à l’application de télécharger la mise à jour par exemple `https://myservercom/app/updates/updatesjson` Si vous n’êtes pas familier avec la distribution d’un bundle, nous vous recommandons d’essayer Capgo Cloud ou de voir un exemple ici : [Distribution d'un Bundle ](/docs/self-hosted/auto-update/update-endpoint) ## Configuration Ajoutez une `updateUrl` à votre `capacitorconfigjson` ```json { "plugins": { "CapacitorUpdater": { "updateUrl": "https://myservercom/app/updates/updatesjson", } } } ``` Caution Lorsque vous publiez une mise à jour auto-hébergée, gardez à l’esprit que vous ne pouvez pas utiliser un point de terminaison “HTTP” car cela va à l’encontre des politiques de sécurité des applications Android. Pour les tests, vous pouvez [l’autoriser](https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted) ## API de mise à jour Le plugin effectuera un appel POST vers votre API chaque fois que l’application est ouverte, avec ce corps : ```typescript interface AppInfos { "platform": "ios" | "android", "device_id": "UUID_of_device_unique_by_install", "app_id": "APPID_FROM_CAPACITOR_CONFIG", "custom_id": "your_custom_id_set_on_runtime", "plugin_version": "PLUGIN_VERSION", "version_build": "VERSION_NUMBER_FROM_NATIVE_CODE", "version_code": "VERSION_CODE_FROM_NATIVE_CODE", "version_name": "LAST_DOWNLOADER_VERSION" | "builtin" "version_os": "VERSION_OF_SYSYEM_OS", "is_emulator": boolean, "is_prod": boolean, } ``` Le serveur API doit répondre, en JSON, au plugin capacitor-updater avec ces données si une mise à jour est nécessaire : ```json { "version": "123", "url": "https://myservercom/app/updates/my-new-app-200zip" } ``` En mode de mise à jour automatique, le serveur doit comparer les versions et renvoyer la bonne. Si la clé URL est présente, le plugin commence le processus de téléchargement Si vous ajoutez les clés “message” et “error”, la version ne sera pas définie, et le message sera affiché dans les logs à la place La clé `version` doit être au format [`semver`](https://semverorg/) Le zip doit avoir `indexhtml` comme fichier à la racine, ou un seul dossier à la racine avec `indexhtml` à l’intérieur Vous pouvez utiliser la commande du CLI pour zipper votre bundle : Créer un bundle avec vos fichiers à servir depuis votre serveur ```bash npx @capgo/cli bundle zip --path [/path/to/my/bundle] ``` # Contribuer > Contribuer au projet open source capgo ## Pourquoi contribuer ? Tout d’abord, merci d’envisager de contribuer aux projets open source de capgo ! C’est grâce à des personnes comme vous que les projets open source de capgo deviennent d’excellents outils. Voici quelques raisons pour lesquelles vous pourriez vouloir contribuer : * Contribuer aux projets open source de capgo est un excellent moyen de gagner de l’argent grâce aux [nombreuses primes](https://consolealgoraio/org/Capgo) offertes par l’équipe capgo * Contribuer aux projets open source de capgo est un excellent moyen d’ajouter une fonctionnalité que vous souhaitez voir * Contribuer aux projets open source de capgo est un excellent moyen de corriger un bug que vous avez rencontré * [La licence principale de Capgo](https://github.com/Cap-go/capgo/blob/main/LICENSE) vous oblige à ouvrir le code source de toute modification que vous y apportez. En contribuant votre code, vous gardez vos modifications open source et permettez aux autres de l’utiliser ## Comment contribuer * Tout d’abord, vous devez forker le dépôt auquel vous souhaitez contribuer * Ensuite, vous devez valider et pousser vos modifications vers ce dépôt * Enfin, vous devez ouvrir une pull request * C’est tout ! Maintenant, il vous suffit d’attendre que l’équipe capgo examine votre PR ## Documents à lire * [CONTRIBUTINGMD](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTINGmd) de Capgo * [BOUNTYmd](https://github.com/Cap-go/capgo/blob/main/BOUNTYmd) de Capgo # Paquets chiffrés > Comment utiliser le plugin de mise à jour manuelle en mode auto-hébergé ## Chiffrement de bout en bout À partir de la version 4150, le plugin permet d’envoyer des mises à jour chiffrées Pour commencer, créez une clé privée Create a private key ```bash npx @capgo/cli key create ``` Ensuite, chiffrez votre zip Encrypt bundled zip ```bash npx @capgo/cli encrypt [path/to/zip] ``` La commande vous imprimera un `ivSessionKey` qui doit être envoyé avec votre payload de mise à jour dans la clé `session_key` ```json { "version": "123", "url": "https://myservercom/app/updates/my-new-app-200zip", "session_key": "encrypted_session_key", } ``` Ensuite, votre application pourra utiliser la clé privée pour déchiffrer la `session_key` et utiliser la `session_key` déchiffrée pour déchiffrer la mise à jour En savoir plus ici : [Mises à jour en direct auto-hébergées ](https://capgo.app/blog/self-hosted-live-updates/) # Commencer > Comment exécuter votre propre serveur de mise à jour automatique Cette documentation expliquera comment exécuter votre propre serveur de mise à jour automatique ## Introduction Si vous trouvez ce travail utile, merci d’envisager de soutenir mon travail en devenant un [sponsor Github](https://github.com/sponsors/riderx) J’ai fait le pari d’ouvrir le code source de tout ce que j’ai construit ici au lieu de le mettre derrière un paywall. En l’ouvrant au lieu de le cacher, je crois que nous pouvons rendre le monde meilleur De plus, je veux me concentrer sur les outils Capgo, et en faire une entreprise ouverte et transparente Mais pour que cela soit possible, il est nécessaire que chacun d’entre nous fasse sa part, y compris vous 🥹 Si Capgo ne vous convient pas, alors fixez votre propre prix et [soutenez un créateur indépendant](https://github.com/sponsors/riderx) selon vos conditions [Envisager de Contribuer ](/docs/plugin/self-hosted/contributing/) ## Parité des fonctionnalités Si vous choisissez d’utiliser votre propre serveur, vous perdrez le flux de configuration en 5 minutes\ Vous devrez implémenter toutes ces fonctionnalités vous-même | Fonctionnalités | Capgo | Auto-hébergé | | ----------------------------------------- | ----- | ------------ | | Mises à jour | ✅ | 🚧 | | Retour auto | ✅ | 🚧 | | Alertes email en cas d’échec | ✅ | 🚧 | | Canaux | ✅ | 🚧 | | Remplacement de canaux | ✅ | 🚧 | | Remplacement d’appareil | ✅ | 🚧 | | Paramètres des canaux | ✅ | 🚧 | | Paramètres d’appareil | ✅ | 🚧 | | ID personnalisé | ✅ | 🚧 | | Configuration auto des canaux | ✅ | 🚧 | | API des canaux | ✅ | 🚧 | | Statistiques des mises à jour | ✅ | 🚧 | | Statistiques des échecs de téléchargement | ✅ | 🚧 | | Statistiques d’utilisation | ✅ | 🚧 | | Chiffrement des mises à jour | ✅ | 🚧 | Danger Si vous envoyez une mauvaise mise à jour à vos utilisateurs, vous pouvez et allez casser leur application > Gardez à l’esprit que vous ne pouvez pas utiliser le cloud Capgo et votre serveur en même temps Danger La fonction de mise à jour Over-the-Air (OTA) ne s’applique qu’aux modifications apportées aux fichiers HTML, CSS et JavaScript Si vous apportez des modifications au code natif, comme des mises à jour des plugins Capacitor, il est obligatoire de soumettre à nouveau l’application à l’app store pour approbation ## Choisir entre Auto et Manuel En mode auto, une partie de la logique est gérée par le code natif, les mises à jour sont décidées côté serveur, c’est plus sécurisé et permet des mises à jour précises, un déploiement partiel sur un appareil ou un groupe et plus encore En mode manuel, toute la logique est gérée par le JS [Mise à jour automatique ](/docs/plugin/self-hosted/auto-update/) [Manuel ](/docs/plugin/self-hosted/manual-update/) ## Installer Capacitor updater Installer le Capacitor updater ```bash npm install @capgo/capacitor-updater npx cap sync ``` ## Préparer votre bundle Pour envoyer des mises à jour à votre application, vous devez la zipper La meilleure façon d’être certain que votre zip est bon est d’utiliser le CLI Capgo pour le zipping Créer un bundle avec vos fichiers à servir depuis votre serveur ```bash npx @capgo/cli@latest bundle zip ``` Vous devrez servir ce zip depuis votre serveur par vos propres moyens [Mise à jour automatique ](/docs/plugin/self-hosted/auto-update/) [Manuel ](/docs/plugin/self-hosted/manual-update/) Note Si cela semble beaucoup de travail, essayez l’essai gratuit de Capgo Cloud # Gestion des statistiques > Créer un endpoint de statistiques auto-hébergé Voici un exemple de code en JavaScript pour sauvegarder les statistiques du plugin ```typescript interface AppInfos { version_name: string action: 'delete' | 'reset' | 'set' | 'set_fail' | 'update_fail' | 'windows_path_fail' | 'canonical_path_fail' | 'directory_path_fail' | 'unzip_fail' | 'low_mem_fail' | 'download_fail' | 'update_fail' | 'download_10' | 'download_20' | 'download_30' | 'download_40' | 'download_50' | 'download_60' | 'download_70' | 'download_80' | 'download_90' | 'download_complete' version_build: string version_code: string version_os: string plugin_version: string platform: string app_id: string device_id: string custom_id?: string is_prod?: boolean is_emulator?: boolean } export const handler: Handler = async (event) => { const body = JSONparse(eventbody || '{}') as AppInfos const { platform, app_id, action, version_code, version_os, device_id, version_name, version_build, plugin_version, } = body consolelog('update asked', platform, app_id, action, version_os, version_code, device_id, version_name, version_build, plugin_version) // Sauvegardez-le dans votre base de données return { status: 'ok' } } ``` Ce point de terminaison doit retourner un JSON : ```json { "status": "ok" } ``` ## Actions : * **delete** : quand un bundle est supprimé localement * **reset** : quand l’application revient au bundle intégré * **set** : quand l’application configure un nouveau bundle * **set\_fail** : quand l’application ne trouve pas l’ID du bundle configuré * **update\_fail** : envoyé après le délai et `notifyAppReady` n’a jamais été appelé * **download\_fail** : quand le téléchargement n’est jamais terminé * **download\_complete:** Quand le téléchargement se termine * **download\_xx:** Envoyé tous les 10% du téléchargement ex : download\_20, download\_70 * **update\_fail:** quand le bundle ne parvient pas à exécuter `notifyAppReady` dans le délai imparti # Gestion des mises à jour > Comment utiliser le plugin de mise à jour automatique en mode auto-hébergé Voici un exemple de code en JavaScript pour envoyer une mise à jour au plugin ```typescript interface AppInfos { version_name: string version_build: string version_os: string custom_id?: string is_prod?: boolean is_emulator?: boolean plugin_version: string platform: string app_id: string device_id: string } export const handler: Handler = async (event) => { const body = JSONparse(eventbody || '{}') as AppInfos const { platform, app_id, version_os, device_id, version_name, version_build, plugin_version, } = body consolelog('update asked', platform, app_id, version_os, device_id, version_name, version_build, plugin_version) if (version_name === '100') { return { version: '101', url: 'https://apiurlcom/mybuild_101zip', } } else if (version_name === '101') { return { version: '102', url: 'https://apiurlcom/mybuild_102zip', } } else { return { message: 'Error version not found' version: '', url: '', } } } ``` Ce point de terminaison doit renvoyer un JSON : ```json { "version": "102", "url": "https://apiurlcom/mybuild_102zip" } ``` Et s’il n’y a pas de mise à jour ou en cas d’erreur, ajoutez la clé `message` et éventuellement une `error` ```json { "message": "Version non trouvée", "error": "Le backend a planté", "version": "102", "url": "https://apiurlcom/mybuild_102zip" } ``` # 수동 업데이트 > Comment utiliser le plugin de mise à jour manuelle en mode auto-hébergé ## Configuration Ajoutez ceci à votre `capacitorconfigjson`, pour désactiver la mise à jour automatique ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false, } } } ``` ## Utilisation Vous pouvez utiliser cet exemple ou recréer la logique dans votre application Caution Nous forçons l’utilisateur à mettre à jour l’application avec une version statique déclarée dans le code. Ce n’est pas recommandé, vous devriez utiliser une version dynamique depuis votre serveur Danger Nous ne faisons aucune vérification de version, de décryptage ou de validation de somme de contrôle dans cet exemple. Vous devriez le faire vous-même ```tsx import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' let data = {version: ""} CapacitorUpdaternotifyAppReady() AppaddListener('appStateChange', async(state) => { if (stateisActive) { // Do the download during user active app time to prevent failed download data = await CapacitorUpdaterdownload({ version: '004', url: 'https://github.com/Cap-go/demo-app/releases/download/004/distzip', }) } if (!stateisActive && dataversion !== "") { // Do the switch when user leave app SplashScreenshow() try { await CapacitorUpdaterset(data) } catch (err) { consolelog(err) SplashScreenhide() // in case the set fail, otherwise the new app will have to hide it } } }) ``` Note Si cela semble être beaucoup de travail, envisagez d’essayer [l’essai Capgo](https://capgo.app/register/). Il gérera tout cela pour vous # 설정 > Tous les paramètres disponibles pour Capacitor Updater Pour avoir un contrôle plus précis sur le système de mise à jour, vous pouvez le configurer avec ces paramètres : ## `appReadyTimeout` > Configure le nombre de millisecondes pendant lesquelles le plugin natif doit attendre avant de considérer qu’une mise à jour a ‘échoué’ Disponible uniquement pour Android et iOS Par défaut : `10000` (10 secondes) ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 } } } ``` ## `responseTimeout` > Configure le nombre de millisecondes pendant lesquelles le plugin natif doit attendre avant de considérer un délai d’expiration de l’API Disponible uniquement pour Android et iOS Par défaut : `20` (20 secondes) ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "responseTimeout": 1000 } } } ``` ## `autoDeleteFailed` > Configure si le plugin doit automatiquement supprimer les bundles ayant échoué Disponible uniquement pour Android et iOS Par défaut : `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoDeleteFailed": false } } } ``` ## `autoDeletePrevious` > Configure si le plugin doit automatiquement supprimer les bundles précédents après une mise à jour réussie Disponible uniquement pour Android et iOS Par défaut : `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoDeletePrevious": false } } } ``` ## `autoUpdate` > Configure si le plugin doit utiliser la mise à jour automatique via un serveur de mise à jour Disponible uniquement pour Android et iOS Par défaut : `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` ## `updateUrl` > Configure l’URL / point de terminaison vers lequel les vérifications de mise à jour sont envoyées Disponible uniquement pour Android et iOS Par défaut : `https://apicapgo.app/updates` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "updateUrl": "https://examplecom/api/updates" } } } ``` ## `statsUrl` > Configure l’URL / point de terminaison vers lequel les statistiques de mise à jour sont envoyées Disponible uniquement pour Android et iOS. Définissez à "" pour désactiver les rapports de statistiques Par défaut : `https://apicapgo.app/stats` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "statsUrl": "https://examplecom/api/stats" } } } ``` ## `privateKey` > Configure la clé privée pour le chiffrement de bout en bout des mises à jour en direct Disponible uniquement pour Android et iOS Créez la clé privée avec la commande `npx @capgo/cli key create` Par défaut : `undefined` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "privateKey": "YOUR_KEY" } } } ``` ## `directUpdate` > Fait que le plugin installe directement la mise à jour lorsque l’application vient d’être mise à jour/installée. Applicable uniquement pour le mode autoUpdate Disponible uniquement pour Android et iOS Par défaut : `undefined` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": true } } } ``` ## `resetWhenUpdate` Note Lorsqu’une mise à jour du store se produit, désactive la réinitialisation forcée vers la version native Il existe beaucoup plus de paramètres disponibles uniquement sur l’[application web](https://web.capgo.app/login) Pour configurer le plugin, utilisez ces paramètres : ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } } ``` ## `directUpdate` Fait que le plugin installe directement la mise à jour lorsque l’application vient d’être mise à jour/installée. Applicable uniquement pour le mode autoUpdate Caution Ce paramètre nécessite que vous masquiez l’application à l’utilisateur pendant l’installation de la mise à jour. Sinon, l’application se réinitialisera pendant que l’utilisateur navigue ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": true } } } ``` ## `defaultChannel` Définit le canal par défaut pour l’application. Cela remplacera tout autre canal défini dans Capgo si le canal permet l’écrasement ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "defaultChannel": "production" } } } ``` ## `appId` Définit l’appId pour l’application. Cela remplacera toute autre façon d’obtenir l’appId. C’est utile lorsque vous voulez avoir un appId différent dans Capgo et dans votre code natif Note C’est la nouvelle façon de définir l’appId. L’ancienne méthode est toujours et restera prise en charge ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "AppId": "comexampleapp" } } } ``` ## `version` Définit la version pour l’application. Cela remplacera toute autre façon d’obtenir la version. C’est utile lorsque vous voulez avoir une version différente dans Capgo et dans votre code natif Note C’est la nouvelle façon de définir la version. L’ancienne méthode est toujours et restera prise en charge ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "version": "123" } } } ``` # API Statistiche > Comment utiliser le plugin d'auto-mise à jour en mode auto-hébergé ## API de Statistiques À partir de la version 130, le système de mise à jour peut envoyer des statistiques ! Par défaut, toutes les statistiques sont envoyées à notre serveur pour comprendre l’utilisation et la recherche Note Aucune donnée privée n’est envoyée pour les statistiques, uniquement un UUID aléatoire, la mise à jour de version, la version de l’application native, la plateforme, l’action et l’ID de l’application Si vous souhaitez envoyer ces données à votre serveur à la place, modifiez la configuration ci-dessous : ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "statsUrl": "VOTRE_URL" } } } ``` Ce que votre serveur recevra : ```tsx interface AppInfosStats { "action": "set", // peut être set, delete, set_fail, reset, revert // Ensuite, ce sont les mêmes informations que la mise à jour "app_id": "*******", // identifiant de l'application dans le store "device_id": "*******", // id unique par installation d'application "platform": "ios", // ou android "custom_id": "user_1", // représente votre utilisateur "version_name": "123", // version du build web "version_build": "120", // version du build natif "version_code": "120", // numéro de build de la version native "version_os": "16", // version OS de l'appareil "plugin_version": "400"// pour faire réagir votre api différemment selon les plugins "is_emulator": false, "is_prod": false, } ``` Vous pouvez également le désactiver complètement avec une chaîne vide. Gardez à l’esprit que les statistiques sont conçues de manière respectueuse de la vie privée et m’aident à comprendre comment les gens utilisent le plugin, pour résoudre les problèmes et l’améliorer [Gestion des Mises à Jour ](/docs/plugin/self-hosted/handling-updates/) # Migration d'AppFlow vers Capgo > Guide complet pour migrer votre application d'Ionic AppFlow vers Capgo ## Référence de Configuration AppFlow Avant la migration, notez votre configuration AppFlow actuelle dans `capacitor.config.ts` : ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { LiveUpdates: { appId: 'your-app-id', channel: 'Production', autoUpdateMethod: 'background', // ou 'always latest', 'force update' maxVersions: 2 } } }; ``` Cette configuration vous aidera à mapper les fonctionnalités d’AppFlow vers leurs équivalents Capgo. ## Stratégies de Mise à Jour ### Mises à Jour en Arrière-plan (Par Défaut) Si vous utilisez les mises à jour en arrière-plan d’AppFlow : ```typescript // Équivalent Capgo dans capacitor.config.ts { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: false, autoDeletePrevious: true } } } ``` ### Mises à Jour Forcées Si vous utilisez la stratégie de mise à jour forcée d’AppFlow : ```typescript // Équivalent Capgo dans capacitor.config.ts { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: true, keepUrlPathAfterReload: true } } } // Code JavaScript requis import { CapacitorUpdater } from '@capgo/capacitor-updater'; import { SplashScreen } from '@capacitor/splash-screen'; CapacitorUpdater.addListener('appReady', () => { SplashScreen.hide(); }); CapacitorUpdater.notifyAppReady(); ``` ### Toujours la Dernière Version Si vous utilisez la stratégie “always latest” d’AppFlow, implémentez avec Capgo : ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; import { App } from '@capacitor/app'; async function setupAlwaysLatest() { App.addListener('resume', async () => { const result = await CapacitorUpdater.download({ url: 'your-update-url' }); if (result) { await CapacitorUpdater.set({ id: result.id }); } }); } ``` ## Migration des Méthodes API | Méthode AppFlow | Équivalent Capgo | Notes | | --------------- | ---------------- | --------------------------------------- | | `sync()` | `download()` | Télécharge les nouvelles mises à jour | | `reload()` | `set()` | Applique les mises à jour immédiatement | | `setConfig()` | `setChannel()` | Met à jour la configuration du canal | ### Exemple de Migration ```typescript // Code AppFlow import * as LiveUpdates from '@capacitor/live-updates'; const result = await LiveUpdates.sync(); if (result.activeApplicationPathChanged) { await LiveUpdates.reload(); } // Équivalent Capgo import { CapacitorUpdater } from '@capgo/capacitor-updater'; const bundle = await CapacitorUpdater.download({ url: 'your-update-url' }); if (bundle) { await CapacitorUpdater.set({ id: bundle.id }); } ``` ## Pourquoi migrer vers Capgo ? Suite à l’annonce concernant Ionic AppFlow, la migration vers Capgo offre une transition fluide pour votre processus de développement d’applications mobiles. Capgo propose des fonctionnalités améliorées, de meilleures performances et des économies significatives tout en maintenant toutes les fonctionnalités essentielles. ### Avantages Principaux * Livraison des mises à jour plus rapide (< 1 minute contre 10 minutes) * Tarification plus abordable (14$/mois contre 499$/mois) * Chiffrement de bout en bout inclus dans tous les plans * Meilleur contrôle des canaux de mise à jour * Options complètes d’intégration CI/CD ## Étapes de Migration ### 1. Migration des Mises à Jour #### Retirer les Dépendances ```bash npm uninstall @ionic/appflow # Retirer les configurations spécifiques à AppFlow de capacitor.config.json ``` #### Installer Capgo ```bash npm install @capgo/capacitor-updater npx cap sync ``` #### Mettre à Jour la Configuration Ajoutez la configuration Capgo à votre `capacitor.config.json` : ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true } } } ``` ### 2. Migration CI/CD Capgo offre des options flexibles : #### Option 1 : Utiliser votre CI/CD Existant Suivez nos tutoriels détaillés : * [Configuration iOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) * [Configuration Android](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) * [Intégration GitHub Actions](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) #### Option 2 : Service CI/CD Utilisez notre [service géré](https://cal.com/team/capgo/mobile-ci-cd-done-for-you). ### 3. Configuration des Canaux 1. Créer des canaux dans le tableau de bord Capgo : ```bash npx @capgo/cli channel create production npx @capgo/cli channel create staging ``` 2. Configurer les paramètres : ```bash # Canal de production npx @capgo/cli channel update production --no-downgrade --no-upgrade # Canal de staging npx @capgo/cli channel update staging ``` ### 4. Tests de Migration 1. **Tester les Mises à Jour** ```bash # Créer un bundle de test npx @capgo/cli bundle create --channel staging ``` 2. **Vérification** * Installer l’application sur un appareil de test * Vérifier la réception des mises à jour * Tester le processus d’installation * Valider la récupération ## Résolution des Problèmes ### Problèmes Fréquents #### Mises à Jour Non Reçues * Vérifier la configuration des canaux * Consulter les journaux * Vérifier la connectivité réseau * Valider les versions ## Prochaines Étapes 1. [Créer un compte Capgo](/register/) 2. [Guide de démarrage](/docs/getting-started/quickstart/) 3. [Intégration CI/CD](/docs/getting-started/cicd-integration/) 4. [Configuration des mises à jour](/docs/live-updates/) Pour les équipes nécessitant un support dédié, [contactez notre équipe](https://cal.com/team/capgo/capgo-enterprise-inquiry). # V2에서 V3로 > Comment passer de la V2 à la V3 Cette documentation expliquera comment mettre à niveau vers la version 3 de l’auto-update ## D’abord migrer vers les derniers outils : ```bash npm remove -g capgo npm remove capacitor-updater npm i @capgo/cli npm i @capgo/capacitor-updater@3 npx cap sync ``` ## Supprimez toute votre configuration précédente : ```json { CapacitorUpdater: { autoUpdateURL: "https", }, } ``` pour ne laisser que ceci : ```json { "CapacitorUpdater": { "autoUpdate": true } } ``` > ⚠️ Si vous utilisiez votre serveur avec `autoUpdateURL`, je mettrai à jour ce guide prochentiellement pour vous. En attendant, jetez un œil à la nouvelle option de téléchargement `external` qui vous permet d’envoyer uniquement le lien de votre zip, pas le code dans Capgo cloud. Cela a été conçu pour les entreprises ayant des politiques de confidentialité strictes. En mode externe, le code n’arrivera jamais sur le serveur Capgo, nous stockons uniquement l’URL et l’envoyons à l’appareil, qui le téléchargera directement. De manière standard, le code est compressé et stocké dans notre serveur, mais nous ne l’ouvrirons ni ne l’utiliserons jamais. ## Ce qui change Toutes les configurations deviennent côté serveur pour l’auto-update, pour vous donner plus de contrôle sur la façon dont vous envoyez une mise à jour aux utilisateurs Cela nous permet de revenir en arrière, même de déployer pour un seul utilisateur avec des canaux ! Ces paramètres sont ajoutés dans l’interface web : * désactiver le retour en arrière sous la version native * désactiver la mise à jour au-dessus de la version majeure > ⚠️ Ils deviendront vrais par défaut pour tous les canaux Cela supprimera également la nécessité de mettre à jour souvent le plugin, la plupart des mises à jour seront effectuées côté serveur, et vous les obtiendrez sans aucun changement de votre côté > ⚠️ Réinitialisation lorsqu’une mise à jour devient la valeur par défaut, donc si vous préférez ne pas supprimer toutes les versions téléchargées lors de la mise à jour depuis le store, faites ceci : ```json { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } ``` ## Mettez à jour votre code Enfin, mettez à jour tous vos imports en JS de : ```plaintext import { CapacitorUpdater } from 'capacitor-updater' ``` à ```plaintext import { CapacitorUpdater } from '@capgo/capacitor-updater' ``` Puis reconstruisez votre code `npm run build` et copiez les assets une fois de plus `npx cap copy` Vous devriez maintenant pouvoir tester le dernier système d’auto-update Envoyez votre version avec : ```plaintext npx @capgo/cli@latest bundle upload ``` au lieu de ```plaintext npx capgo upload ``` ## Évolutions futures Pour l’instant, seul le premier canal public est utilisé, à l’avenir, public changera pour plusieurs canaux publics, si plus d’un est défini ## Problèmes courants : * Problème de build après la mise à niveau : si vous avez déjà ouvert le code source du plugin dans Android Studio ou Xcode, parfois la synchronisation ne les supprime pas, c’est la cause du problème. Ouvrez l’IDE natif et supprimez `capacitor-updater` manuellement et faites `npx cap sync`, cela devrait résoudre le problème # V3 から V4 へ > Comment mettre à niveau de V3 vers V4 ## Pourquoi cette mise à niveau Après de nombreuses discussions avec vous dans la communauté Discord, j’ai découvert que le mode manuel était trop manuel et pas sûr à utiliser. Par exemple, la restauration automatique n’était pas possible, donc si la mise à jour échouait en manuel, l’utilisateur devait supprimer l’application et la réinstaller, ce qui est une terrible expérience utilisateur. Entre-temps, j’ai pris cela comme une opportunité pour vous donner plus de liberté et supprimer tout le mauvais code que j’ai fait. ## Installation `npm i @capgo/capacitor-updater@4` ## Mise à jour automatique cloud Si vous utilisez l’exemple de base dans votre application, vous pouvez migrer en toute sécurité vers la nouvelle version, profitez-en ! ## Mise à jour automatique auto-hébergée Pour vous, c’est toujours simple, les changements sont : * Le nom du paramètre de `autoUpdateUrl` devient `updateUrl` * La méthode de l’endpoint est passée de `GET` à `POST` ## Utilisateurs manuels Pour vous, c’est le changement le plus important, mais pour le meilleur ! Vous obtenez des tonnes d’améliorations, lisez attentivement. ## Changements * `autoUpdateUrl` devient `updateUrl` puisque ce paramètre peut être utilisé en mode manuel maintenant aussi * Suppression de `cancelDelay` et `delayUpdate` en faveur de `setDelay` * Plus de `versionName` dans set * Changement de la clé `version`, qui était retournée dans la plupart des fonctions vers l’objet `BundleInfo` ```typescript interface BundleInfo { id: string; version: string; downloaded: string; status: 'success' | 'error' | 'pending' | 'downloading' } ``` * Renommage des noms trompeurs maintenant (même à expliquer ça ne peut pas être clair, mais à l’usage il est facile de comprendre le nouveau) : * ce qui était appelé `version` fait maintenant référence à un `bundle` * `id` fait référence à l’ancienne `version` qui était une chaîne aléatoire de 10 caractères, cet `id` est la seule façon fiable et unique d’accéder à vos bundles, exemple `7Dfcd2RedN` * `version` fait maintenant référence au `versionName` que vous choisissez pour un bundle, exemple `100` * `updateUrl` passe de `get` à `post`, puisque les en-têtes personnalisés étaient un problème pour certains d’entre vous et post est plus logique, tous les en-têtes précédents vont dans le corps et le préfixe `cap_` disparaît * La méthode `versionName` est supprimée, en faveur de `getId` * list retourne maintenant une liste de `BundleInfo` * Renommage de `getId` en `getDeviceId` * `autoUpdate` devient true par défaut, si vous utilisez le mode Manuel, mettez-le à false ## Nouveautés * Méthode `getLatest`, cette méthode vous permet d’obtenir de votre serveur défini avec `updateUrl` la dernière version disponible * Méthode `setDelay` qui prend `{kind: "background" | "kill" | "nativeVersion" | "date", value?: string}` comme argument pour définir le délai pour différents modes * Méthode `next`, pour définir la version au prochain passage en arrière-plan, à l’opposé de `set` qui le fait instantanément * Méthode `isAutoUpdateEnabled`, pour vous permettre de savoir si vous êtes dans un contexte de mise à jour automatique * Événement `downloadComplete` lorsque le téléchargement atteint 100% * Ajout du champ obligatoire `version` dans la méthode download * `notifyAppReady` devient obligatoire en mode manuel aussi, si non appelé après 10 secondes l’application revient à la version précédente ## Contributeurs [@lincolnthree](https://github.com/lincolnthree/) Merci beaucoup d’avoir commencé ce travail, il était impossible de faire fonctionner cette mise à jour sans vous # Dari V4 ke V5 > Comment passer de la V4 à la V5 ## Pourquoi cette mise à niveau Cette version majeure est là pour suivre la version majeure de Capacitor Suivez d’abord le guide de migration de Capacitor: [https://capacitorjs.com/docs/updating/5-0](https://capacitorjs.com/docs/updating/5-0/) ## Installation `npm i @capgo/capacitor-updater@5` `Puis synchronisez la mise à jour du code natif :` `npx cap sync` C’est tout ! Plutôt facile ! ## Mode manuel Si vous obteniez vous-même la mise à jour avec getLatest, il y a un petit changement Maintenant, si vous êtes déjà à jour, cela ira dans le catch Toute réponse différente de la mise à jour disponible fera cela # De V5 à V6 > Comment mettre à jour de V5 à V6 ## Pourquoi cette mise à niveau Cette version majeure est là pour suivre la version majeure de Capacitor Suivez d’abord le guide de migration de Capacitor : [https://capacitorjs.com/docs/updating/6-0](https://capacitorjs.com/docs/updating/6-0/) ## Installation `npm i @capgo/capacitor-updater@6` `Puis synchronisez la mise à jour du code natif :` `npx cap sync` C’est tout ! Assez simple ! # Introduction > Introduction à l'application web Cagpo ## Qu’est-ce que c’est ? Cagpo dispose d’une application web complète pour vous aider à gérer vos projets. Cette application web est construite avec Vuejs et est open source. Vous pouvez trouver le code source sur [GitHub](https://github.com/Cap-go/capgo/tree/main/src/)\ L’application web est disponible [ici](https://web.capgo.app/)\ Cette application web vous permet de [gérer les canaux](/docs/webapp/channels/), [gérer les versions](/docs/webapp/bundles/), [gérer les appareils](/docs/webapp/devices/), [inspecter les logs](/docs/webapp/logs/), [gérer la facturation](/docs/webapp/settings/) et [gérer votre compte](/docs/webapp/settings/) ## Comment l’utiliser ? Tout d’abord, vous devez créer un compte ou vous connecter. C’est relativement simple et peut être fait en cliquant sur le bouton `Se connecter` au centre de l’écran. Après vous être connecté, vous serez redirigé vers le tableau de bord. C’est la page principale de l’application web. De là, vous pouvez naviguer vers toutes les autres pages. ![login page](/login.webp) ## Créer un compte Vous devez cliquer sur `Créer un compte gratuit` dans la partie inférieure du formulaire de connexion. À partir de là, il suffira de remplir un formulaire et de suivre les instructions. ![create account](/create-account.webp) # Gestione delle chiavi api > Gestion des clés API ## Que puis-je faire avec les clés api ? Une clé API peut être régénérée, supprimée ou une nouvelle peut être ajoutée ## Comment voir toutes les clés api ? Vous devez aller sur la [page des clés API](https://web.capgo.app/dashboard/apikeys/) et là vous verrez toutes vos clés api ## Comment ajouter une nouvelle clé api ? Pour ajouter une nouvelle clé API, cliquez sur le petit bouton plus ![add apikey](/apikeys-add.webp) puis sélectionnez les permissions que vous souhaitez donner à la nouvelle clé API. Vous pouvez sélectionner : * Lecture - la clé API pourra lire toutes les données * Upload - la clé API pourra télécharger de nouvelles versions depuis la CLI et lire * Tout - La clé API pourra tout faire ![select perm](/apikeys-select-perm.webp) ## Comment supprimer une clé api ? Pour supprimer une clé API, cliquez sur le petit bouton corbeille ![remove apikey](/apikeys-remove.webp) Puis confirmez la suppression de la clé API ## Comment régénérer une clé api ? Pour régénérer une clé API, cliquez sur le petit bouton rafraîchir ![generate apikey](/apikeys-regenerate.webp) Puis confirmez la régénération de la clé API # 번들 > Découvrez comment gérer les bundles ## Afficher tous les bundles Tout d’abord, jetons un coup d’œil à la page des bundles. Vous pouvez y accéder en [cliquant sur votre application](/docs/webapp/main-page) puis en [cliquant sur l’onglet bundles](/docs/webapp/main-app-page) ![bundle list](/bundles.webp) ## Supprimer un bundle Il existe deux façons de supprimer un bundle : * Normalement * De manière non sécurisée La suppression non sécurisée d’un bundle a été ajoutée à Capgo le 12 août 2024 La différence entre les deux méthodes réside dans la possibilité de réutiliser le numéro de version après la suppression Par exemple, si vous supprimez une version `100` de manière normale et que vous essayez plus tard de télécharger une version `100`, cela échouera Si vous supprimez cette version via la suppression non sécurisée, vous pourrez télécharger une version `100` Danger Supprimer une version de manière non sécurisée et la retélécharger est VRAIMENT dangereux Cela peut causer toutes sortes de bugs et de comportements imprévisibles dans le plugin Cela ne devrait JAMAIS être utilisé pour des bundles qui ont été utilisés dans un canal public C’est pour cette raison que la suppression non sécurisée d’une version nécessite des privilèges “super\_admin” ## Gérer un bundle spécifique Une fois que vous voyez la liste de tous les bundles, cliquez sur celui que vous souhaitez gérer. Après cela, vous devriez voir quelque chose comme ceci : ![bundle info](/bundle-info.webp) Passons en revue tous les éléments de cette page *** Tout d’abord, vous pouvez voir un `Canal`. Cela vous indique pour quel canal ce bundle est destiné. Vous pouvez changer le canal en cliquant dessus Une fois que vous cliquez dessus, vous devriez voir quelque chose comme ceci : ![bundle change](/bundle-change.webp) `Définir le bundle pour le canal` vous permettra de lier ce bundle comme bundle par défaut pour n’importe quel canal\ `Ouvrir le canal` ouvrira la page du canal pour lequel ce bundle est destiné\ `Délier le bundle du canal` déliera ce bundle du canal auquel il est destiné (**ATTENTION** : Si le bundle est lié à plus d’un canal, vous n’aurez pas d’option pour choisir quel canal délier) *** Ensuite, vous pouvez voir la `Taille`. Si vous cliquez dessus, vous pourrez télécharger ce bundle Cela devrait ressembler à quelque chose comme ceci : ![download bundle](/download-bundle.webp) *** Enfin, il y a la section `Appareils`. Vous pouvez voir tous les appareils utilisant cette version ici # Canaux > Les canaux sont un moyen de gérer les mises à jour de votre application. Vous pouvez avoir plusieurs canaux et chaque canal peut avoir plusieurs versions. Cela vous permet d'avoir plusieurs versions de votre application en production en même temps. ## Gestion des canaux Tout d’abord, examinons la page des canaux. Vous pouvez y accéder en [cliquant sur votre application](/docs/webapp/main-page) puis en [cliquant sur l’onglet canaux](/docs/webapp/main-app-page) ![channel list](/channels.webp) ## Créer un canal Comme vous pouvez le voir, il existe un bouton plus dans le coin inférieur droit (`1` sur l’image). Cliquer dessus ouvrira une fenêtre modale où vous pourrez créer un nouveau canal ![new channel](/new_channel_modal.webp) Ensuite, après avoir cliqué sur `Ajouter`, un nouveau canal devrait apparaître dans la liste ![after channel create](/post-channel-create.webp) ## Que signifie mal configuré ? Parfois, la configuration d’un canal n’est pas valide. Dans ce cas, vous obtiendrez un gros avertissement et la colonne `Mal configuré` indiquera `Oui` pour un ou plusieurs canaux. Vous pouvez en savoir plus à ce sujet [ici](/docs/cli/commands/#disable-updates-strategy) ## Supprimer un canal Supprimer un canal est simple. Cliquez simplement sur l’icône de la corbeille et confirmez la suppression (`2` sur l’image) ## Gérer un canal Cliquer sur le nom du canal ouvrira une fenêtre modale où vous pourrez gérer le canal (`3` sur l’image) Cette page devrait ressembler à ceci : ![manage channel](/manage_channel_main.webp) Passons en revue les différentes sections D’abord le `Numéro de bundle` (`1` sur l’image). C’est la version actuelle pour ce canal. Lorsqu’on lui demande de servir une mise à jour, ce canal tentera toujours de répondre avec cette version\* \[^1] Cliquer dessus devrait vous amener à la page des [bundles](/docs/webapp/bundles/) Deuxièmement, la page `Partagé à` (`2` sur l’image). Je déconseille de l’utiliser. Un nouveau et meilleur système est en cours de développement Maintenant les appareils forcés (`3` sur l’image). C’est une liste d’appareils qui recevront toujours les mises à jour de ce canal. C’est utile à des fins de test. Vous pouvez forcer un appareil à un canal depuis la page des [appareils](/docs/webapp/devices/) Enfin les paramètres (`4` sur l’image). C’est ici que vous pouvez gérer comment les canaux se comportent Après avoir cliqué dessus, vous devriez voir quelque chose comme ceci : ![setting of channel](/channel_settings.webp) La liste des paramètres est longue, mais je vais faire de mon mieux pour tous les expliquer *** Premièrement le `Canal par défaut` **C’EST PROBABLEMENT LE PLUS IMPORTANT**\ Si un canal est marqué comme par défaut, il sera utilisé comme canal par défaut pour tous les nouveaux appareils\ En d’autres termes : Si vous avez un nouvel utilisateur, capgo essaiera de lui servir la dernière version de ce canal par défaut Un seul canal peut être défini par défaut à la fois. Si vous essayez d’enfreindre cette règle, il vous sera demandé de confirmer votre action ![confirm make change](/confirm-make-default.webp) Après confirmation, l’ancien canal par défaut ne sera plus marqué comme par défaut et le nouveau le sera *** Deuxièmement le paramètre `IOS`. C’est relativement simple. Si c’est faux, alors les appareils IOS ne seront pas autorisés à télécharger des mises à jour depuis ce canal Troisièmement le paramètre `Android`. C’est similaire à `IOS`. Si c’est faux, alors les appareils Android ne seront pas autorisés à télécharger des mises à jour depuis ce canal Quatrièmement le paramètre `Désactiver la rétrogradation automatique sous la version native`. Si c’est vrai, alors il sera impossible de rétrograder depuis une version native. Cela signifie que si vous avez téléchargé une version `120` sur l’App Store ou le Play Store et essayez de définir la version du canal à `110`, alors la mise à jour (rétrogradation) échouera Cinquièmement `Désactiver la mise à jour automatique`. Ce paramètre est assez complexe, et vous pouvez en savoir plus à ce sujet [ici](/docs/cli/commands/#disable-updates-strategy) Quant à `Autoriser les builds de développement`. Si c’est vrai, alors les builds de développement seront autorisés à télécharger des mises à jour depuis ce canal. Sinon, toute demande de mise à jour avec `prod` défini sur faux sera rejetée. C’est principalement utile à des fins de test Septièmement `Autoriser les émulateurs`. Si c’est faux, alors capgo refusera toute demande de mise à jour provenant d’un émulateur. C’est principalement utile à des fins de test Huitièmement `Autoriser l'auto-association des appareils`. Si c’est vrai, alors la méthode [setChannel](/docs/plugin/api/#setchannel) sera disponible. Si c’est défini sur faux et que vous essayez d’appeler la méthode [setChannel](/docs/plugin/api/#setchannel) avec ce canal, alors l’appel échouera # デバイス > Comment utiliser la page Device ## Afficher la liste de tous les appareils Tout d’abord, examinons la page des appareils. Vous pouvez y accéder en [cliquant sur votre application](/docs/webapp/main-page) puis en [cliquant sur l’onglet appareils](/docs/webapp/main-app-page) ![devices list](/devices.webp) ## Afficher uniquement les appareils développeur Vous pourriez vouloir afficher uniquement les appareils modifiés (Appareils qui ont un [canal personnalisé](/docs/plugin/api/#setchannel) ou une version personnalisée) Pour cela, cliquez sur `Filtres` puis sur `Remplacer`. Cela devrait ressembler à ceci : ![filter devices](/overwrite-filter.webp) ## Configuration d’un appareil Pour configurer un appareil spécifique, cliquez dessus dans le tableau et vous devriez voir quelque chose comme ceci : ![show one device](/device-specific.webp) D’abord l’`ID personnalisé`. Ce n’est pas vraiment utile, et pour l’instant cela ne fait rien. Vous pouvez l’ignorer Ensuite la version forcée. Si celle-ci est définie, alors cet appareil recevra **TOUJOURS** cette version. Elle prime sur le canal Enfin, le canal personnalisé. S’il est défini, alors cet appareil ne tiendra pas compte du canal public (par défaut) et utilisera uniquement celui-ci # Journaux > Découvrez la page des logs ## Afficher tous les journaux Tout d’abord, jetons un coup d’œil à la page des journaux. Vous pouvez y accéder en [cliquant sur votre application](/docs/webapp/main-page) puis en [cliquant sur l’onglet mises à jour](/docs/webapp/main-app-page) À partir de là, vous devriez voir une page comme celle-ci : ![show logs](/logs.webp) ## Obtenir plus de détails sur un journal Si vous cliquez sur un journal, vous serez dirigé vers une [page des appareils](/docs/webapp/devices/) # 메인 앱 페이지 > Qu'est-ce qui est affiché sur la page principale ? ## Que montre la page principale ? Tout d’abord, jetons un coup d’œil à la page principale de l’application : ![Main page screeshot](/main-app-page.webp) Examinons cela de plus près Premièrement, les statistiques. Les statistiques sont en cours de refonte, elles ne peuvent donc pas être documentées pour le moment. Nous ajouterons une section statistiques lorsqu’elles seront pleinement opérationnelles. Deuxièmement, examinons tous les menus disponibles et leur fonction ![Multiple sections screeshot](/app-multiple-sections.webp) Le premier bouton vous mènera à la page des [canaux](/docs/webapp/channels/). Vous pouvez y créer/supprimer/configurer les canaux de l’application\ Le deuxième bouton vous mènera à la page des [bundles](/docs/webapp/bundles/). Vous pouvez y voir toutes les versions de l’application Le deuxième bouton vous mènera à la page des [appareils](/docs/webapp/devices/). Vous pouvez y voir tous les appareils. Vous pouvez également définir des remplacements spécifiques aux appareils à partir de là Le deuxième bouton vous mènera à la page des [mises à jour](/docs/webapp/logs/). Vous pouvez y voir les statistiques détaillées (logs) et les erreurs que votre application rencontre # Page principale > Cette page explique la page principale de l'application web ## Que montre la page principale ? Tout d’abord, jetons un coup d’œil à la page principale : ![Capture d'écran de la page principale](/main-page.webp) Commençons par le début. La première chose que vous voyez est les **statistiques**. Elles contiennent des statistiques spécifiques à l’application. Ces mises à jour dépendent de l’utilisation de l’application. La deuxième chose que vous voyez est la liste de toutes les applications disponibles. Cela changera en fonction du nombre d’applications que vous avez créées. Vous pouvez cliquer sur chaque application pour voir plus de détails à son sujet. La troisième chose que vous voyez est le bouton **Clés API**. Ce bouton vous mènera à la page des [clés API](/docs/webapp/api-keys/). Ensuite, vous voyez le bouton **tester Capgo**. Ce bouton changera en fonction de vos nom et prénom et vous mènera à la page des [paramètres](/docs/webapp/settings/) ou du support. Enfin, vous voyez un bouton pour ajouter une autre application. Ce bouton vous mènera à une page où vous pourrez ajouter une nouvelle application à Capgo. # Authentification à deux facteurs > Gérez l'authentification à deux facteurs pour mieux protéger votre compte Capgo. ## Qu’est-ce que la 2FA ? La 2FA est une mesure de sécurité conçue pour empêcher un acteur malveillant de prendre le contrôle de votre compte capgo\ Elle y parvient en exigeant un code supplémentaire. Ce code est stocké sur votre téléphone portable ou une clé matérielle 2FA. Il change toutes les 30 secondes, ce qui le rend impossible à deviner. ## Prérequis pour ce guide * Un téléphone Android ou iOS * Une connexion Internet ## Que couvre ce guide ? Ce guide vous montrera comment configurer la 2FA en utilisant `Google Authenticator`. D’autres applications existent pour servir un but similaire, cependant je ne peux pas couvrir l’ensemble du sujet de la 2FA dans ce guide. ## Comment configurer la 2FA ? Premièrement, téléchargez l’application `Google Authenticator`. Si vous êtes sur Android, vous pouvez la télécharger depuis le [play store](https://play.google.com/store/apps/details/?id=comgoogleandroidappsauthenticator2). Sur iOS, vous pouvez la télécharger depuis l’[App store](https://appsapplecom/us/app/google-authenticator/id388497605/) Deuxièmement, rendez-vous sur les [paramètres du compte capgo](https://web.capgo.app/dashboard/settings/account/). Vous devriez y voir un bouton vert qui ressemble à ceci : ![Button MFA](/button-mfa.webp) Cliquez dessus, et un QR code devrait apparaître ![Enable MFA](/enable-mfa.webp) Danger ⚠️ Note Importante :\ Ne partagez jamais ce QR code avec qui que ce soit, ou vous pourriez être déconnecté de votre compte Ensuite, ouvrez `Google Authenticator` sur votre téléphone. Une fois fait, suivez ces étapes : Cliquez sur le bouton plus ![MFA auth plus](/mfa-auth-plus.webp) Après cela, cliquez sur le bouton appareil photo ![MFA scan QR](/mfa-scan-qr.webp) Cela ouvrira l’aperçu de la caméra. Veuillez scanner le QR code affiché sur votre PC. Après l’avoir fait, vous devriez voir quelque chose comme ceci : ![MFA final code](/mfa-final-code.webp) Ensuite, retournez sur le PC et cliquez sur le bouton vérifier ![Verify MFA](/enable-mfa-verify.webp) Cela ouvrira une fenêtre pour taper votre code 2FA. Dans mon cas, ce code est `095101` mais il sera différent pour vous\ Après avoir tapé ce code, cliquez sur le bouton `vérifier` ![MFA verify code final](/mfa-verify-final-code.webp) Si vous avez entré le bon code et appuyé sur `vérifier`, vous devriez voir une fenêtre comme celle-ci ![MFA enabled](/mfa-enabled.webp) Félicitations !\ Vous avez activé l’authentification 2FA 🎉 ## Comment se connecter avec la 2FA La prochaine fois que vous vous connecterez à votre compte, vous verrez une fenêtre comme celle-ci ![MFA required](/mfa-required.webp) Veuillez ouvrir l’authentificateur et copier votre code d’authentification ![MFA login](/mfa-login.webp) Danger ⚠️ Note Importante :\ Appuyez sur `vérifier` avant que le code ne se rafraîchisse, sinon le code changera et l’ancien ne sera plus valide Ensuite, saisissez le code dans le formulaire de connexion et appuyez sur `vérifier` ![MFA login](/mfa-final-login-verify.webp) Si vous avez entré le bon code, vous devriez voir le tableau de bord capgo ## Comment désactiver la 2FA Pour désactiver la 2FA, rendez-vous sur les [paramètres du compte capgo](https://web.capgo.app/dashboard/settings/account/). Vous devriez y voir un bouton rouge qui ressemble à ceci : ![MFA disable button](/mfa-disable-button.webp) Cliquez dessus, et vous devriez voir un écran comme celui-ci ![MFA disabled](/mfa-disable-2.webp) Appuyez simplement sur le bouton `désactiver`, et c’est tout # 조직 시스템 > Gestion des organisations dans votre compte capgo. ## Qu’est-ce que le système d’organisation ? Le système d’organisation est un système dans capgo qui vous permet de partager en toute sécurité vos applications avec les membres de votre équipe ### Q : Comment puis-je accéder aux informations de mon organisation ? Pour accéder aux informations de votre organisation, veuillez aller dans les [paramètres](/docs/webapp/settings/#how-to-get-to-the-settings-page) puis cliquez sur `Paramètres de l'organisation` ![Org settings](/orgs-settings.webp) ### Q : Comment puis-je changer l’organisation que je visualise ? Pour voir les paramètres d’une autre organisation, veuillez cliquer sur le sélecteur d’organisation près de votre nom ![Org selector](/org-selector.webp) Si vous ne voyez pas cela, vous n’êtes probablement pas sur la page des paramètres ### Q : Comment puis-je voir les membres de mon organisation ? Veuillez cliquer sur `membres` ![Org Show members](/org-show-members.webp) ### Q : Comment puis-je inviter un utilisateur dans une organisation ? Veuillez cliquer sur `Ajouter un membre` ![Org add member](/orgs-add-member.webp) Une fenêtre pop-up apparaîtra - veuillez entrer l’adresse e-mail de l’utilisateur ![Invite to org](/invite-to-org-email-enter.webp) Puis cliquez sur `inviter` Une autre fenêtre pop-up apparaîtra, cette fois-ci vous demandant les permissions que l’utilisateur invité devrait avoir ![Select perm for org](/select-perm-orgs.webp) Voici une répartition de toutes les permissions : | Permission | Lecture | Télécharger | Écriture | Admin | Super Admin | | --------------------------------- | ------- | ----------- | -------- | ----- | ----------- | | Afficher les statistiques d’app | ✅ | ✅ | ✅ | ✅ | ✅ | | Afficher les canaux d’app | ✅ | ✅ | ✅ | ✅ | ✅ | | Afficher les appareils | ✅ | ✅ | ✅ | ✅ | ✅ | | Afficher les logs | ✅ | ✅ | ✅ | ✅ | ✅ | | Afficher les bundles | ✅ | ✅ | ✅ | ✅ | ✅ | | Supprimer l’app | ❌ | ❌ | ❌ | ❌ | ✅ | | Supprimer le canal | ❌ | ❌ | ❌ | ✅ | ✅ | | Supprimer la version | ❌ | ❌ | ✅ | ✅ | ✅ | | Modifier les paramètres de l’org | ❌ | ❌ | ❌ | ✅ | ✅ | | Gérer les utilisateurs de l’org | ❌ | ❌ | ❌ | ✅ | ✅ | | Modifier les paramètres du canal | ❌ | ❌ | ✅ | ✅ | ✅ | | Télécharger nouvelle version | ❌ | ✅ | ✅ | ✅ | ✅ | | Modifier les appareils | ❌ | ❌ | ✅ | ✅ | ✅ | | Changer version actuelle du canal | ❌ | ❌ | ✅ | ✅ | ✅ | | Créer nouveau canal | ❌ | ❌ | ❌ | ✅ | ✅ | | Modifier version (métadonnées) | ❌ | ❌ | ✅ | ✅ | ✅ | | Gérer la facturation | ❌ | ❌ | ❌ | ❌ | ✅ | | Supprimer version sans sécurité | ❌ | ❌ | ❌ | ❌ | ✅ | ### Q : Comment fonctionne la facturation au sein des organisations ? Toute personne ayant une permission de **super admin** peut gérer la facturation pour une organisation donnée Les plans sont liés à une organisation et non à votre compte personnel Danger ⚠️ L’achat d’un plan n’affectera QUE les organisations que vous avez actuellement sélectionnées ### Q : Puis-je créer plus d’une organisation ? Non, pas encore # Système de paiement > Gestion des paiements dans votre compte capgo. ## De quoi s’agit-il ? Cette page vise à répondre à certaines questions concernant le système de paiement dans capgo #### Q : Comment puis-je mettre à niveau mon forfait capgo ? A : Vous pouvez mettre à niveau votre forfait capgo en allant dans [les paramètres](/docs/webapp/settings/#how-to-get-to-the-settings-page) et en cliquant sur le bouton **Plans** ![Choose plan](/plans-button.webp) Ensuite, vous pouvez sélectionner le forfait qui correspond le mieux à vos besoins et cliquer sur **S’abonner** ![Subscribe to plan](/plans-subscribe.webp) Une page stripe s’ouvrira alors. Là, vous pourrez saisir vos informations de paiement ![Stripe portal](/plans-stripe.webp) #### Q : Les paiements sont-ils sécurisés ? A : Oui, les paiements sont entièrement gérés par stripe. Capgo n’a jamais accès aux détails de votre carte bancaire. Stripe prend la sécurité très au sérieux. [En savoir plus sur la politique de sécurité de stripe](https://stripecom/docs/security/) #### Q : Est-ce que capgo mettra automatiquement à niveau mon forfait lorsque je dépasserai la limite ? A : Non, capgo ne changera jamais votre forfait #### Q : Est-ce que capgo m’enverra un e-mail lorsque mon forfait approche de ses limites ? A : Oui, capgo vous enverra un e-mail vous informant de l’utilisation #### Q : Est-ce que le forfait que j’achète affectera les organisations auxquelles je suis invité ? A : Non, le forfait n’affectera que l’organisation que vous avez actuellement sélectionnée Veuillez vous référer à [la documentation sur l’organisation](/docs/webapp/organization-system/#q-how-is-billing-done-within-orgs) #### Q : Que faire si j’ai besoin d’un forfait plus personnalisé ? A : [Veuillez contacter directement le support de capgo](/docs/getting-help#support-by-chat) #### Q : Quelle est la politique de remboursement de capgo ? A : Une politique de remboursement est disponible [ici](https://capgo.app/return/) # Paramètres > Comment modifier les paramètres utilisateur ## Comment accéder à la page des paramètres Cliquez d’abord sur **PRÉNOM NOM** Dans mon cas, c’est **test Capgo** Dans votre cas, ce sera votre prénom puis votre nom Ensuite, cliquez sur **Paramètres** ![open settings](/settings-go.webp) ## Modification des paramètres utilisateur Pour modifier un paramètre utilisateur, il suffit de remplir le formulaire dans le compte puis de cliquer sur **Mettre à jour** ![save change in account](/account-save.webp) Une confirmation devrait alors apparaître ![acount updated](/account-updated.webp) ## Modification du mot de passe Pour changer le mot de passe, allez dans la page des paramètres et cliquez sur **Mot de passe** Puis remplissez le formulaire et cliquez sur **Mettre à jour** ![update password](/update-passwd.webp) Lorsque le mot de passe ne respecte pas les règles de sécurité de Capgo, vous recevrez un message d’erreur ![wrong password](/passwd-error.webp) # Capgoへようこそ > Capgo es una plataforma de código abierto de actualizaciones en tiempo real para Capacitor y equipos de desarrollo móvil, que permite entregar actualizaciones a los usuarios en minutos en lugar de días Kekuatan Live Update Kirimkan pembaruan aplikasi secara langsung, perbaikan bug penting, perubahan konten, fitur beta, dan lainnya untuk memberikan pengalaman terbaik bagi pengguna Anda Mudah diintegrasikan Plugin ini hanya membutuhkan 3 langkah untuk diintegrasikan ke dalam kode Anda dan memungkinkan Anda mengirim pembaruan ke pengguna dalam hitungan menit, bukan hari! Instalasi Jalankan `npx @capgo/cli@latest init [APIKEY]` untuk memulai Dokumentasi lengkap Pelajari di [Dokumentasi](/docs/getting-started/quickstart/) cara menguasai plugin dalam 5 menit dengan video onboarding kami # Perintah > Dokumentasi Capgo CLI ### Penggunaan Semua perintah harus dijalankan di folder aplikasi Anda dengan proyek Capacitor yang sudah disiapkan dengan benar [Capacitor Cross-platform native runtime for web apps ](https://capacitorjs.com/docs/getting-started/) ### **Init** `npx @capgo/cli@latest init [apikey]` Metode ini ada untuk membimbing Anda langkah demi langkah Ini akan menambahkan aplikasi Anda ke Capgo Ini akan menambahkan kode ke aplikasi Anda untuk memvalidasi pembaruan Demikian juga, ini akan membangun aplikasi Anda Selanjutnya, ini akan mengunggah aplikasi Anda ke Capgo Dan ini akan membantu Anda untuk memeriksa apakah pembaruan berfungsi ### **Login** `npx @capgo/cli login [apikey]` Metode ini ada untuk mengingat `apikey` untuk Anda Note gunakan `--apikey=********` di perintah manapun untuk menimpanya **Secara opsional Anda dapat memberikan:** `--local` Ini akan menyimpan **apikey** Anda di repo lokal dan git akan mengabaikannya ## **Doctor** `npx @capgo/cli doctor` Perintah untuk memeriksa apakah Anda sudah up-to-date dengan paket Capgo Perintah ini juga akan berguna untuk laporan bug ## Aplikasi ### **Add** `npx @capgo/cli app add [appId]` `[appId]` ID aplikasi Anda dengan format `comtestapp` dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) > 💡 Semua opsi akan ditebak dalam konfigurasi Anda jika tidak disediakan Secara opsional, Anda dapat memberikan: * `--icon [/path/to/my/icon]` untuk memiliki ikon khusus yang ditampilkan di aplikasi web Capgo * `--name [test]` untuk memiliki nama khusus dalam daftar * `--apikey [key]` API key untuk menghubungkan ke akun Anda * `--retention [retention]` periode retensi bundle aplikasi dalam hari, 0 secara default = tak terbatas Contoh `capacitorconfigjson` untuk appId dan AppName, ikon ditebak di folder resources ```json { "appId": "eeforgrcapacitor_go", "appName": "Capgo", "webDir": "dist" } ``` ### **Set** `npx @capgo/cli app set [appId]` `[appId]` adalah ID aplikasi Anda, formatnya dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) Secara opsional, Anda dapat memberikan: * `--icon [/path/to/my/icon]` untuk memiliki ikon khusus yang ditampilkan di aplikasi web Capgo * `--name [test]` untuk memiliki nama khusus dalam daftar * `--retention [retention]` periode retensi bundle aplikasi dalam hari, 0 secara default = tak terbatas * `--apikey [key]` API key untuk menghubungkan ke akun Anda ### **List** `npx @capgo/cli app list [appId]` `[appId]` ID aplikasi Anda dengan format `comtestapp` dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) Secara opsional, Anda dapat memberikan: * `--apikey [key]` API key untuk menghubungkan ke akun Anda ### **Delete** `npx @capgo/cli app delete [appId]` `[appId]` ID aplikasi Anda dengan format `comtestapp` dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) Secara opsional, Anda dapat memberikan: * `--apikey [key]` API key untuk menghubungkan ke akun Anda * `--bundle` dengan nomor versi hanya akan menghapus versi ini ### Debug `npx @capgo/cli app debug [appId]` `[appId]` ID aplikasi Anda dengan format `comtestapp` dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) Secara opsional, Anda dapat memberikan: * `--apikey [key]` API key untuk menghubungkan ke akun Anda * `--device` dengan perangkat spesifik yang ingin Anda debug ### Setting `npx @capgo/cli app setting [path]` Edit konfigurasi Capacitor `[path]` - path dari pengaturan yang ingin Anda ubah. Misalnya, untuk mengubah `appId`, berikan `appId` Jika Anda ingin menonaktifkan pembaruan otomatis di `capacitor-updater` berikan `pluginsCapacitorUpdaterautoUpdate` Anda HARUS memberikan `--string` atau `--bool`! Opsi: * `--string ` - mengatur pengaturan ke string * `--bool ` - mengatur pengaturan ke boolean ## Bundle ### Upload `npx @capgo/cli bundle upload [appId]` `[appId]` adalah ID aplikasi Anda, formatnya dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) Secara opsional, Anda dapat memberikan: * `--apikey ` API key untuk menghubungkan ke akun Anda * `--path ` Path folder yang akan diunggah * `--channel ` Channel yang akan dihubungkan * `--external ` Link ke URL eksternal alih-alih mengunggah ke Capgo Cloud * `--iv-session-key ` Atur IV dan kunci sesi untuk URL bundle eksternal * `--s3-endpoint ` URL endpoint S3 Tidak bekerja dengan unggahan Parsial, atau opsi eksternal * `--s3-region ` Region untuk bucket S3 Anda * `--s3-apikey ` API key untuk endpoint S3 Anda * `--s3-apisecret ` API secret untuk endpoint S3 Anda * `--s3-bucket-name ` Nama untuk bucket AWS S3 Anda * `--s3-port ` Port untuk endpoint S3 Anda * `--no-s3-ssl` Nonaktifkan SSL untuk unggahan S3 * `--key ` Path kustom untuk kunci penandatanganan publik (sistem v1) * `--key-data ` Kunci penandatanganan publik (sistem v1) * `--key-v2 ` Path kustom untuk kunci penandatanganan privat (sistem v2) * `--key-data-v2 ` Kunci penandatanganan privat (sistem v2) * `--bundle-url` Mencetak URL bundle ke stdout * `--no-key` Abaikan kunci penandatanganan dan kirim pembaruan yang jelas * `--no-code-check` Abaikan pemeriksaan apakah notifyAppReady() dipanggil dalam kode sumber dan indeks ada di folder root * `--display-iv-session` Tampilkan di konsol IV dan kunci sesi yang digunakan untuk mengenkripsi pembaruan * `--bundle ` Nomor versi bundle yang akan diunggah * `--min-update-version ` Versi minimal yang diperlukan untuk memperbarui ke versi ini Hanya digunakan jika nonaktifkan pembaruan otomatis diatur ke metadata di channel * `--auto-min-update-version` Atur versi pembaruan minimal berdasarkan paket native * `--ignore-metadata-check` Mengabaikan pemeriksaan metadata (node\_modules) saat mengunggah * `--ignore-checksum-check` Mengabaikan pemeriksaan checksum saat mengunggah * `--timeout ` Batas waktu untuk proses unggah dalam detik * `--partial` Tidak mengunggah file parsial ke cloud Capgo * `--tus` Unggah bundle menggunakan protokol tus * `--multipart` Menggunakan protokol multipart untuk mengunggah data ke S3, Tidak direkomendasikan, gunakan TUS sebagai gantinya * `--encrypted-checksum ` Checksum terenkripsi (tanda tangan) Hanya digunakan saat mengunggah bundle eksternal * `--package-json ` Path ke packagejson Berguna untuk monorepos * `--auto-set-bundle` Atur bundle di capacitorconfigjson * `--node-modules ` Daftar path ke node\_modules Berguna untuk monorepos (dipisahkan koma mis: //node\_modules,/node\_modules) > ⭐️ Opsi eksternal membantu membuka 2 kasus: korporat dengan masalah privasi, jangan kirim kode ke pihak ketiga dan aplikasi lebih besar dari 200 MB Dengan pengaturan ini, Capgo hanya menyimpan tautan ke zip dan mengirim tautan ke semua aplikasi > 👀 Cloud Capgo tidak pernah melihat apa yang ada di link (untuk opsi eksternal), atau di kode ketika disimpan > 🔑 Anda dapat menambahkan lapisan keamanan kedua dengan menggunakan enkripsi, maka Capgo tidak akan dapat melihat atau memodifikasi apa pun, menjadi “trustless” Contoh `packagejson` untuk versi ```json { "version": "102" } ``` > ⛔ Versi harus lebih besar dari “000” > 💡 Jangan lupa untuk memperbarui nomor versi setiap kali Anda mengirim, nomor versi tidak dapat ditimpa, atau digunakan kembali setelah penghapusan karena alasan keamanan ### **List** `npx @capgo/cli bundle list [appId]` `[appId]` ID aplikasi Anda dengan format `comtestapp` dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) Secara opsional, Anda dapat memberikan: * `--apikey [key]` API key untuk menghubungkan ke akun Anda ### **Delete** `npx @capgo/cli bundle delete [appId]` `[appId]` ID aplikasi Anda dengan format `comtestapp` dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) Secara opsional, Anda dapat memberikan: * `--apikey [key]` API key untuk menghubungkan ke akun Anda * `--bundle` dengan nomor versi hanya akan menghapus versi ini ### Cleanup dalam rentang SemVer untuk versi major ke Cloud `npx @capgo/cli bundle cleanup [appId] --bundle=[majorVersion] --keep=[numberToKeep]` `[appId]` ID aplikasi Anda dengan format `comtestapp` dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) Secara opsional, Anda dapat memberikan: * `--apikey [key]` API key untuk menghubungkan ke akun Anda * `--bundle [majorVersion]` versi yang ingin Anda hapus paket sebelumnya, ini akan menyimpan yang terakhir + `numberToKeep`\* `--keep [numberToKeep]` jumlah paket yang ingin Anda simpan (default 4) Contoh: Jika Anda memiliki 10 versi dari 1001 hingga 10011, dan Anda menggunakan `npx @capgo/cli cleanup [appId] --bundle=1000` maka akan menghapus 1001 hingga 1006, 1007 sampai 10011 akan disimpan Jika Anda memiliki total 20 versi, dan Anda tidak menyertakan nomor bundle seperti ini: `npx @capgo/cli cleanup [appId] --keep=2` Ini akan menghapus 18 versi, dan menyimpan 2 yang terakhir > Perintah ini akan meminta konfirmasi, menampilkan tabel apa yang akan disimpan dan dihapus Note Perintah ini akan mengabaikan bundle yang sedang digunakan di channel manapun ### **Encrypt** > **Peringatan**: Perintah ini sudah usang dan akan dihapus di rilis mayor berikutnya. Silakan gunakan sistem enkripsi yang baru `npx @capgo/cli bundle encrypt [path/to/zip]` Perintah ini digunakan ketika Anda menggunakan sumber eksternal untuk menyimpan kode Anda atau untuk tujuan pengujian Secara opsional, Anda dapat memberikan: `--key [/path/to/my/private_key]` path dari private key Anda `--key-data [privateKey]` data private key, jika Anda ingin menggunakan secara inline Perintah akan mencetak `ivSessionKey` Anda dan menghasilkan zip terenkripsi, untuk digunakan dengan perintah upload atau decrypt ### **Encrypt V2** `npx @capgo/cli bundle encryptV2 [path/to/zip] [checksum]` Perintah ini digunakan ketika Anda menggunakan sumber eksternal untuk menyimpan kode Anda atau untuk tujuan pengujian Checksum adalah sha256 dari bundle (dihasilkan oleh —key-v2), digunakan untuk memverifikasi integritas file setelah dekripsi Ini akan dienkripsi dengan private key dan dikirim bersama dengan bundle Dalam enkripsi v2 checksum ditingkatkan menjadi “signature” dari bundle Secara opsional, Anda dapat memberikan: `--key [/path/to/my/private_key]` path dari private key Anda `--key-data [privateKey]` data private key, jika Anda ingin menggunakan secara inline `--json` untuk menampilkan info sebagai json Perintah akan mencetak `ivSessionKey` Anda dan menghasilkan zip terenkripsi, untuk digunakan dengan perintah upload atau decrypt ### **Decrypt** `npx @capgo/cli bundle decrypt [path/to/zip] [ivSessionKey]` Secara opsional, Anda dapat memberikan: `--key [/path/to/my/private_key]` path dari private key Anda `--key-data [privateKey]` data private key, jika Anda ingin menggunakan secara inline Perintah ini terutama digunakan untuk tujuan pengujian, akan mendekripsi zip dan mencetak session key terdekripsi base64 di konsol ### **Decrypt V2** `npx @capgo/cli bundle decryptV2 [path/to/zip] [ivSessionKey]` Secara opsional, Anda dapat memberikan: `--key [/path/to/my/private_key]` path dari private key Anda `--key-data [privateKey]` data private key, jika Anda ingin menggunakan secara inline Perintah ini terutama digunakan untuk tujuan pengujian, akan mendekripsi zip dan mencetak session key terdekripsi base64 di konsol `--checksum [checksum]` checksum dari file, akan memverifikasi checksum setelah dekripsi ### **Zip** `npx @capgo/cli bundle zip [appId]` `[appId]` adalah ID aplikasi Anda, formatnya dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) Secara opsional, Anda dapat memberikan: * `--path [/path/to/my/bundle]` untuk mengunggah folder tertentu * `--bundle [100]` untuk mengatur nomor versi bundle dari nama file * `--name [myapp]` untuk mengganti nama file * `--json` untuk menampilkan info sebagai json * `--no-code-check` untuk mengabaikan pemeriksaan kode dan mengirim bundle * `--key-v2` untuk menggunakan sistem enkripsi baru Ini diperlukan karena sistem enkripsi baru menggunakan checksum yang lebih baik untuk memverifikasi integritas file ### **Compatibility** `npx @capgo/cli bundle compatibility [appId] -c [channelId]` `[appId]` adalah ID aplikasi Anda, formatnya dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) `[channelId]` nama channel baru Anda Secara opsional, Anda dapat memberikan: * `--apikey [key]` API key untuk menghubungkan ke akun Anda * `--text` gunakan teks alih-alih emoji dalam tabel * `--channel [channel]` channel untuk memeriksa kompatibilitas * `--package-json ` Path ke packagejson Berguna untuk monorepos * `--node-modules ` Daftar path ke node\_modules Berguna untuk monorepos (dipisahkan koma mis: //node\_modules,/node\_modules) ## Channel ### **Add** `npx @capgo/cli channel add [channelId] [appId]` `[channelId]` nama channel baru Anda `[appId]` ID aplikasi Anda dengan format `comtestapp` dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) ### **Delete** `npx @capgo/cli channel delete [channelId] [appId]` `[channelId]` nama channel yang ingin Anda hapus `[appId]` ID aplikasi Anda dengan format `comtestapp` dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) ### **List** `npx @capgo/cli channel list [appId]` `[appId]` ID aplikasi Anda dengan format `comtestapp` dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) Secara opsional, Anda dapat memberikan: * `--apikey [key]` API key untuk menghubungkan ke akun Anda ### **Set** `npx @capgo/cli channel set [channelId] [appId]` `[appId]` adalah ID aplikasi Anda, formatnya dijelaskan [di sini](https://capacitorjs.com/docs/cli/commands/init/) Secara opsional, Anda dapat memberikan: * `--bundle [123]` bundle aplikasi Anda yang sudah dikirim ke cloud, untuk menghubungkannya ke channel * `--latest` mengambil versi bundle dari `packagejson:version`, tidak dapat digunakan dengan `--bundle` * `--state [ normal | default ]` mengatur status channel, bisa `normal` atau `default` Satu channel harus `default` * `--downgrade` mengizinkan channel untuk mengirim versi downgrade ke perangkat * `--no-downgrade` melarang channel untuk mengirim versi downgrade ke perangkat * `--upgrade` mengizinkan channel untuk mengirim upgrade (major) versi ke perangkat * `--no-upgrade` melarang channel untuk mengirim upgrade (major) versi ke perangkat * `--ios` mengizinkan channel untuk mengirim versi ke perangkat iOS * `--no-ios` melarang channel untuk mengirim versi ke perangkat iOS * `--android` mengizinkan channel untuk mengirim versi ke perangkat android * `--no-android` melarang channel untuk mengirim versi ke perangkat android * `--self-assign` mengizinkan perangkat untuk menetapkan diri ke channel ini * `--no-self-assign` melarang perangkat untuk menetapkan diri ke channel ini * `--disable-auto-update STRATEGY` Menonaktifkan strategi pembaruan otomatis untuk channel ini Opsi yang mungkin adalah: major, minor, metadata, none * `--apikey [key]` API key untuk menghubungkan ke akun Anda ## Strategi menonaktifkan pembaruan Ada beberapa cara untuk menangani penonaktifan pembaruan untuk versi yang terlalu lama\ Capgo tidak dapat memperbarui kode native sehingga pembaruan dari versi dengan kode native lama ke versi dengan kode native yang diperbarui seharusnya tidak mungkin Ada beberapa cara untuk mencapai itu Pertama, strategi `major` Ini mencegah pembaruan dari `000` -> `100` Major adalah angka yang disorot (**1**00 dan **0**00)\ Kedua adalah strategi `minor` Ini mencegah pembaruan dari `000` -> `110` atau pembaruan dari `110` ke `120` **PERHATIAN** strategi ini tidak mencegah pembaruan dari `010` -> `110` Ketiga, strategi `patch` Ini ditambahkan ke capgo sebagai mode yang sangat ketat Tidak direkomendasikan untuk digunakan kecuali Anda benar-benar memahami cara kerjanya Agar dapat menerima pembaruan kondisi berikut harus dipenuhi: * Major sama antara versi baru dan lama * Minor sama antara versi baru dan lama * Patch dari versi baru lebih besar dari patch versi lama Berikut contoh skenario di mana pembaruan diizinkan atau ditolak * 00311 -> 00314 ✅ * 000 -> 00314 ✅ * 00316 -> 00314 ❌ * 01312 -> 00314 ❌ * 10312 -> 00314 ❌ Terakhir strategi yang paling rumit Strategi `metadata`\ Pertama Anda perlu tahu bahwa awalnya setelah Anda mengaktifkannya pembaruan **AKAN** gagal karena channel tidak memiliki metadata yang diperlukan\ Jika channel tidak memiliki metadata Anda akan melihat pesan seperti ini: ![Cannot find metadata](/fail-metadata.webp) Jika Anda melihat sesuatu seperti ini, Anda tahu bahwa Anda harus pergi ke bundle saat ini untuk channel yang gagal dan mengatur metadata\ Pertama, cari tahu channel mana yang gagal Anda dapat melakukannya dengan melihat kolom `misconfigured` ![Misconfigured table](/misconfigured-table.webp) Kemudian pergi ke channel yang gagal dan klik pada `Bundle number`. Ini akan membawa Anda ke halaman bundle ![Locate failing channel](/fail-channel-show.webp) Setelah itu isi field `Minimal update version`. Ini harus berupa [semver](https://devhints.io/semver/)\ Jika nilai yang Anda masukkan bukan semver, Anda akan mendapat error, tetapi jika semua berjalan dengan benar Anda akan melihat sesuatu seperti ini: ![Set min version](/set-min-update-version.webp) Sekarang, Anda mungkin tidak ingin mengatur data ini secara manual setiap kali Anda memperbarui. Untungnya, CLI akan mencegah Anda mengirim pembaruan tanpa metadata ini ![CLI fail no metadata](/cli-fail-no-metadata.webp) Untuk mengunggah bundle dengan benar saat menggunakan opsi `metadata`, Anda perlu memberikan `--min-update-version` dengan semver yang valid. Seperti ini: ![CLI upload with metadata](/cli-upload-with-metadata.webp) `--min-update-version` bukan satu-satunya cara untuk melakukan kompatibilitas. Ada juga `--auto-min-update-version`. Berikut cara kerjanya: Pertama, melihat versi yang saat ini diunggah ke channel. Memeriksa kompatibilitas sama seperti perintah `bundle compatibility`. Kedua, jika versi baru 100% kompatibel, akan menggunakan kembali `min_update_version` dari versi terbaru di channel. Jika tidak, maka akan mengatur `min_update_version` ke nomor bundle versi yang baru diunggah. Anda akan selalu mendapatkan informasi tentang `min_update_version` saat menggunakan opsi ini. Tampilannya akan seperti ini: ![Min update version](/min_update_version_info.webp) Jika versi baru tidak kompatibel, tampilannya akan seperti ini: ![Min update version not compatible](/min_update_version_not_compatible.webp) ## Enkripsi End-to-End (Trustless) Capgo mendukung enkripsi end-to-end, ini berarti bundle (kode) Anda dienkripsi sebelum dikirim ke cloud dan didekripsi di perangkat. Untuk itu, Anda perlu menghasilkan pasangan kunci RSA, Anda dapat menggunakan perintah berikut untuk menghasilkannya. Sistem enkripsi adalah kombinasi RSA dan AES, kunci RSA digunakan untuk mengenkripsi kunci AES, dan kunci AES digunakan untuk mengenkripsi file. Lihat di bawah untuk informasi lebih lanjut tentang sistem enkripsi. ![How crypto works](/crypto_explained.webp) Skema enkripsi ### Membuat kunci untuk aplikasi Anda `npx @capgo/cli key create` Secara opsional, Anda dapat memberikan: `--force` untuk menimpa kunci yang ada. Perintah ini akan membuat pasangan kunci di aplikasi Anda, dan akan meminta Anda untuk menyimpan kunci privat di tempat yang aman. Disarankan untuk tidak melakukan git commit kunci privat, dan tidak membagikannya dengan siapa pun. > Setelah pengujian lokal Anda, hapus kunci dari file konfigurasi dan tambahkan pada langkah CI dengan `key save` ### Menyimpan kunci dalam konfigurasi aplikasi Anda `npx @capgo/cli key save` Secara opsional, Anda dapat memberikan: `--key [/path/to/my/private_key]` path kunci privat Anda `--key-data [privateKey]` data kunci privat, jika Anda ingin menggunakan inline. Perintah ini berguna jika Anda mengikuti rekomendasi dan tidak melakukan commit kunci di aplikasi Anda, dan dalam konfigurasi. ## Integrasi CI Untuk mengotomatiskan pekerjaan Anda, saya sarankan Anda membuat GitHub action melakukan pekerjaan mengirim ke server kami. [Tutorial GitHub action](https://capgo.app/blog/automatic-build-and-release-with-github-actions/) ## Aplikasi demo kami [GitHub - Cap-go/demo-app](https://github.com/Cap-go/demo-app/) Jangan lupa untuk mengkonfigurasi variabel env CI dengan API key Anda # CLI Dari 0.x ke 1.x > Cara Melakukan Peningkatan dari 0.x ke 1.x Tidak ada perubahan signifikan pada CLI Perubahan yang memutus kompatibilitas terutama pada penamaan ulang argumen `--version` menjadi `--bundle` untuk menghindari konflik, dan mengikuti penamaan baru di mana saja # Crittografia > Cara mengenkripsi data Anda dengan enkripsi baru Dokumentasi ini akan menjelaskan cara mengenkripsi data Anda dengan sistem enkripsi baru dan menghapus yang lama Pelajari lebih lanjut tentang sistem enkripsi baru di [blog post](/blog/introducing-end-to-end-security-to-capacitor-updater-with-code-signing) *** Pertama, buat pasangan kunci baru dengan perintah berikut: ```bash npx @capgo/cli key create ``` Perintah ini akan membuat pasangan kunci baru di aplikasi Anda; sangat penting untuk menyimpan kunci pribadi di tempat yang aman. Jangan pernah menyimpan kunci pribadi ke kontrol sumber atau membagikannya dengan pihak yang tidak terpercaya Perintah ini juga akan menghapus kunci lama dari konfigurasi Capacitor Anda, tetapi tidak akan menghapus file kunci lama. CLI menyimpannya agar Anda dapat terus mengirim pembaruan langsung untuk aplikasi yang belum menerima pembaruan app store dan masih menggunakan plugin lama. Ini memfasilitasi proses migrasi Ketika Anda ditanya oleh migrasi, “Apakah Anda ingin mengatur enkripsi dengan channel baru untuk mendukung aplikasi lama dan memfasilitasi migrasi?”, silakan setuju. Ini akan menambahkan opsi “defaultChannel” baru ke konfigurasi Capacitor Anda. Ini akan membuat aplikasi Anda menggunakan channel “encryption\_v2”. Ini akan memastikan bahwa enkripsi baru hanya digunakan oleh aplikasi yang mendukungnya. Aplikasi yang belum menerima pembaruan app store akan terus menggunakan channel default sebelumnya *** Sekarang, Anda perlu membangun bundle JS Anda dan mengunggahnya ke channel baru. Silakan jalankan perintah berikut: ```bash npx @capgo/cli bundle upload --channel encryption_v2 ``` *** Kemudian, jalankan perintah ini untuk mengizinkan aplikasi melakukan self-assign ke channel “encryption\_v2” Caution Ini diperlukan agar opsi “defaultChannel” baru dapat berfungsi ```bash npx @capgo/cli channel set encryption_v2 --self-assign ``` *** Anda sekarang dapat menjalankan aplikasi; aplikasi akan menggunakan sistem enkripsi baru Untuk mengunggah bundle JS baru ke channel lama, Anda hanya perlu menjalankan perintah berikut: ```bash npx @capgo/cli bundle upload --channel production ``` *** Anda tidak perlu khawatir tentang konfigurasi Capacitor, karena tidak pernah diunggah ke Capgo Ketika semua pengguna telah memperbarui aplikasi mereka (bisa memakan waktu hingga 3/4 bulan), Anda dapat menghapus “defaultChannel” dari konfigurasi Capacitor Anda Dan kemudian, Anda dapat menghapus channel lama dengan perintah berikut: ```bash npx @capgo/cli channel delete encryption_v2 ``` *** Setelah menghapus channel “encryption\_v2”, semua aplikasi yang menggunakannya sebagai default akan mulai menggunakan channel “production” # Ringkasan Gunakan fitur Live Updates Capgo untuk memperbarui bundel JavaScript aplikasi Anda secara jarak jauh dan real-time. Push pembaruan JS langsung ke pengguna Anda tanpa melalui proses review app store untuk segera memperbaiki bug dan merilis fitur baru. Note Live Updates terbatas pada perubahan bundel JavaScript. Jika Anda perlu memperbarui kode native, seperti menambah atau menghapus plugin atau mengubah konfigurasi proyek native, Anda perlu mengirimkan build binary native baru ke app store. ## Cara Kerja Live Updates Sistem Live Update Capgo memiliki dua komponen utama: 1. SDK Capgo, yang Anda instal di aplikasi Anda. SDK memeriksa pembaruan yang tersedia dan mengunduhnya di latar belakang. 2. Channel, yang memungkinkan Anda menargetkan pembaruan ke grup pengguna tertentu. Anda dapat menggunakan channel untuk mengelola jalur rilis yang berbeda, seperti `Production`, `Staging`, dan `Dev`. Ketika Anda mengunggah bundel JS baru ke Capgo dan menetapkannya ke channel, SDK Capgo di aplikasi yang dikonfigurasi untuk channel tersebut akan mendeteksi pembaruan dan mengunduhnya. Saat aplikasi dimulai ulang berikutnya, bundel baru akan dimuat. ## Memulai Untuk mulai menggunakan Live Updates, ikuti langkah-langkah berikut: 1. Selesaikan [Capgo Quickstart](/docs/getting-started/quickstart) untuk menyiapkan aplikasi Anda di Capgo dan menginstal SDK Capgo. 2. Dalam kode aplikasi Anda, panggil `CapacitorUpdater.notifyAppReady()` setelah aplikasi Anda selesai menginisialisasi. Ini memberi tahu SDK Capgo bahwa aplikasi Anda siap menerima pembaruan. 3. Build bundel JS Anda dan unggah ke Capgo: ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. Buka aplikasi Anda dan tunggu pembaruan diunduh. Anda dapat memeriksa statusnya dengan: ```shell npx @capgo/cli@latest app debug ``` 5. Setelah pembaruan diunduh, tutup dan buka kembali aplikasi Anda untuk memuat bundel baru. Lihat panduan [Deploying Live Updates](/docs/getting-started/deploy) untuk detail lebih lanjut. ## CLI Capgo CLI Capgo adalah alat yang kuat yang memungkinkan pengembang berinteraksi dengan layanan Capgo dari pipeline CI/CD mereka sendiri. Dengan CLI, Anda memiliki kontrol detail kapan build diproduksi dan dideploy, memungkinkan Anda mengintegrasikan Capgo ke dalam alur kerja enterprise yang ada. ### Untuk Apa CLI Capgo? CLI Capgo dirancang untuk pengembang dan tim yang membutuhkan lebih banyak kontrol dan fleksibilitas dalam alur kerja pembaruan langsung mereka. Dengan menggunakan CLI dalam pipeline CI/CD Anda, Anda dapat: * Menentukan kapan tepatnya untuk membangun dan mendeploy pembaruan, daripada mengandalkan otomatisasi bawaan Capgo * Menyisipkan proses Anda sendiri, seperti penandatanganan kode, pengujian QA, atau persetujuan manajer, antara langkah build dan deploy * Mengintegrasikan Capgo ke dalam alat dan alur kerja DevOps Anda yang ada ### Autentikasi Untuk menggunakan CLI Capgo, Anda perlu mengautentikasi dengan kunci API Anda. Anda dapat menghasilkan kunci API di pengaturan akun Capgo Anda. Untuk masuk dan menyimpan kunci API Anda dengan aman, jalankan: ```shell npx @capgo/cli@latest login [API_KEY] ``` Perintah ini kemudian akan disimpan untuk penggunaan di masa mendatang. Anda tidak perlu menyediakan kunci API Anda setiap kali menjalankan perintah setelah masuk. ### Perbedaan Utama dari CLI Lainnya Jika Anda familiar dengan alat CLI pembaruan langsung lainnya, ada beberapa hal penting yang perlu diperhatikan tentang CLI Capgo: * Capgo menggunakan satu CLI untuk kasus penggunaan pengembangan dan CI/CD, karena Capgo hanya fokus pada fitur pembaruan langsung * CLI Capgo tidak memerlukan langkah instalasi terpisah. Ini dibundel dengan paket `@capgo/cli` dan dapat dijalankan langsung menggunakan `npx` * CLI Capgo dirancang khusus untuk alur kerja pembaruan langsung, jadi mungkin tidak menyertakan beberapa fitur atau perintah yang ditemukan di alat CLI yang lebih umum ## Langkah Selanjutnya [ Channel](/docs/live-updates/channels/) [Pelajari cara menggunakan channel untuk mengelola jalur rilis yang berbeda dan menargetkan pembaruan ke pengguna tertentu](/docs/live-updates/channels/) [ Rollback](/docs/live-updates/rollbacks/) [Temukan cara untuk kembali ke versi bundel JS sebelumnya jika pembaruan menyebabkan masalah](/docs/live-updates/rollbacks/) [ Perilaku Pembaruan](/docs/live-updates/update-behavior/) [Sesuaikan bagaimana dan kapan pembaruan diunduh dan diterapkan di aplikasi Anda](/docs/live-updates/update-behavior/) [ Pembaruan Cepat](/docs/live-updates/differentials/) [Pelajari cara menggunakan pembaruan cepat untuk mempercepat proses pembaruan](/docs/live-updates/differentials/) # Gambaran Umum > Dokumentasi Detail untuk Perintah CLI Capgo CLI Capgo menyediakan serangkaian perintah untuk mengelola aplikasi dan deployment Capgo Anda. Referensi ini memberikan informasi detail tentang setiap perintah yang tersedia, termasuk opsi dan contoh penggunaannya. ## Perintah [ init](/docs/cli/reference/init/) [Inisialisasi aplikasi Capgo baru](/docs/cli/reference/init/) [ login](/login/) [Autentikasi dengan layanan Capgo](/login/) [ doctor](/docs/cli/reference/doctor/) [Periksa pengaturan Capgo Anda untuk potensi masalah](/docs/cli/reference/doctor/) [ app](/docs/cli/reference/app/) [Kelola aplikasi Capgo Anda](/docs/cli/reference/app/) [ bundle](/docs/cli/reference/bundle/) [Kelola bundle aplikasi Anda](/docs/cli/reference/bundle/) [ channel](/docs/cli/reference/channel/) [Kelola channel rilis Anda](/docs/cli/reference/channel/) [ key](/docs/cli/reference/key/) [Kelola kunci penandatanganan aplikasi Anda](/docs/cli/reference/key/) ## Integrasi CI Untuk mengotomatiskan pekerjaan Anda, kami merekomendasikan menggunakan GitHub Actions untuk mendorong pembaruan Anda ke Capgo. Lihat [tutorial GitHub Actions](https://capgo.app/blog/automatic-build-and-release-with-github-actions/) kami untuk informasi lebih lanjut. Jangan lupa untuk mengonfigurasi variabel lingkungan CI Anda dengan kunci API Capgo Anda. ## Aplikasi Demo Untuk contoh lengkap aplikasi Capgo dengan integrasi CI, lihat [aplikasi demo kami di GitHub](https://github.com/Cap-go/demo-app/) # akun Perintah `account` memungkinkan Anda mengelola akun Capgo Anda ### id `npx @capgo/cli account id` Mendapatkan ID akun Anda Pilihan: * `-a, --apikey `: API key untuk menghubungkan ke akun Anda # aplikasi Perintah `app` memungkinkan Anda mengelola aplikasi Capgo Anda ### add `npx @capgo/cli app add [appId]` Menambahkan aplikasi baru ke akun Capgo Anda `[appId]` adalah ID aplikasi Anda dalam format `com.example.app`. Lihat [Dokumentasi Capacitor](https://capacitorjs.com/docs/cli/commands/init/) untuk informasi lebih lanjut > 💡 Semua opsi akan ditebak dari `capacitor.config.json` Anda jika tidak disediakan Opsi: * `--icon [path]`: Path ke ikon kustom untuk ditampilkan di aplikasi web Capgo * `--name [name]`: Nama kustom untuk ditampilkan dalam daftar aplikasi * `--apikey [key]`: Kunci API untuk menghubungkan ke akun Anda * `--retention [days]`: Periode penyimpanan untuk bundle aplikasi dalam hari (default: 0 = tak terbatas) ### set `npx @capgo/cli app set [appId]` Memperbarui aplikasi yang ada di akun Capgo Anda Opsi: * `--icon [path]`: Path ke ikon kustom untuk ditampilkan di aplikasi web Capgo * `--name [name]`: Nama kustom untuk ditampilkan dalam daftar aplikasi * `--retention [days]`: Periode penyimpanan untuk bundle aplikasi dalam hari (default: 0 = tak terbatas) * `--apikey [key]`: Kunci API untuk menghubungkan ke akun Anda ### list `npx @capgo/cli app list [appId]` Menampilkan semua aplikasi di akun Capgo Anda Opsi: * `--apikey [key]`: Kunci API untuk menghubungkan ke akun Anda ### delete `npx @capgo/cli app delete [appId]` Menghapus aplikasi dari akun Capgo Anda Opsi: * `--apikey [key]`: Kunci API untuk menghubungkan ke akun Anda * `--bundle`: Hapus hanya versi bundle tertentu ### debug `npx @capgo/cli app debug [appId]` Menampilkan informasi debug untuk aplikasi Opsi: * `--apikey [key]`: Kunci API untuk menghubungkan ke akun Anda * `--device`: Debug perangkat tertentu ### setting `npx @capgo/cli app setting [path]` Mengedit konfigurasi Capacitor untuk aplikasi `[path]` adalah path ke pengaturan yang ingin Anda ubah (misalnya, `appId` atau `plugins.CapacitorUpdater.autoUpdate`) Anda harus menyediakan `--string` atau `--bool`: * `--string `: Atur pengaturan ke nilai string * `--bool `: Atur pengaturan ke nilai boolean # bundel Perintah `bundle` memungkinkan Anda mengelola bundel aplikasi Anda ### upload `npx @capgo/cli bundle upload [appId]` Mengunggah bundel baru untuk aplikasi Opsi: * `-a, --apikey `: Kunci API untuk menghubungkan ke akun Anda * `-p, --path `: Path ke folder yang akan diunggah (default ke `webDir` di `capacitorconfig`) * `-c, --channel `: Channel untuk menghubungkan bundel * `-e, --external `: Link ke URL eksternal daripada mengunggah ke Capgo Cloud * `--iv-session-key `: Tetapkan IV dan kunci sesi untuk URL bundel eksternal * `--s3-region `: Region untuk bucket S3 Anda * `--s3-apikey `: Kunci API untuk endpoint S3 Anda * `--s3-apisecret `: Secret API untuk endpoint S3 Anda * `--s3-endpoint `: URL endpoint S3 * `--s3-bucket-name `: Nama bucket S3 Anda * `--s3-port `: Port untuk endpoint S3 Anda * `--no-s3-ssl`: Nonaktifkan SSL untuk unggahan S3 * `--key `: Path kustom untuk kunci penandatanganan publik (sistem v1) * `--key-data `: Data kunci penandatanganan publik (sistem v1) * `--key-v2 `: Path kustom untuk kunci penandatanganan privat (sistem v2) * `--key-data-v2 `: Data kunci penandatanganan privat (sistem v2) * `--bundle-url`: Cetak URL bundel ke stdout * `--no-key`: Abaikan kunci penandatanganan dan kirim pembaruan tanpa tanda tangan * `--no-code-check`: Lewati pemeriksaan `notifyAppReady()` dalam kode sumber dan `indexhtml` di folder root * `--display-iv-session`: Tampilkan IV dan kunci sesi yang digunakan untuk mengenkripsi pembaruan * `-b, --bundle `: Nomor versi bundel yang akan diunggah * `--min-update-version `: Versi aplikasi minimum yang diperlukan untuk menerapkan pembaruan ini (hanya digunakan jika pembaruan otomatis dinonaktifkan melalui metadata) * `--auto-min-update-version`: Secara otomatis menetapkan versi pembaruan minimum berdasarkan versi paket native * `--ignore-metadata-check`: Abaikan pemeriksaan metadata (node\_modules) saat mengunggah * `--ignore-checksum-check`: Abaikan pemeriksaan checksum saat mengunggah * `--timeout `: Batas waktu untuk proses unggah dalam detik * `--multipart`: Gunakan protokol multipart untuk mengunggah data ke S3 (tidak direkomendasikan, gunakan `--tus` sebagai gantinya) * `--tus`: Unggah bundel menggunakan protokol tus * `--tus-chunk-size `: Ukuran chunk untuk unggahan tus * `--partial`: Unggah hanya file yang berubah ke Capgo Cloud * `--partial-only`: Unggah hanya file parsial ke Capgo Cloud, melewati file zip (berguna untuk bundel besar) * `--encrypted-checksum `: Checksum terenkripsi (tanda tangan) untuk bundel eksternal * `--auto-set-bundle`: Secara otomatis menetapkan versi bundel di `capacitorconfigjson` * `--dry-upload`: Lakukan simulasi proses unggah tanpa benar-benar mengunggah file (berguna untuk pengujian) * `--package-json `: Daftar path ke file `packagejson` yang dipisahkan koma (berguna untuk monorepo) * `--node-modules `: Daftar path ke direktori `node_modules` yang dipisahkan koma (berguna untuk monorepo) * `--encrypt-partial`: Enkripsi file pembaruan parsial * `--delete-linked-bundle-on-upload`: Hapus bundel yang saat ini terhubung di channel target sebelum mengunggah ### compatibility `npx @capgo/cli bundle compatibility [appId]` Memeriksa kompatibilitas bundel dengan channel tertentu Opsi: * `-a, --apikey `: Kunci API untuk menghubungkan ke akun Anda * `-c, --channel `: Channel untuk memeriksa kompatibilitas * `--text`: Tampilkan hasil sebagai teks alih-alih emoji * `--package-json `: Daftar path ke file `packagejson` yang dipisahkan koma (berguna untuk monorepo) * `--node-modules `: Daftar path ke direktori `node_modules` yang dipisahkan koma (berguna untuk monorepo) ### delete `npx @capgo/cli bundle delete [bundleId] [appId]` Menghapus bundel dari aplikasi Opsi: * `-a, --apikey `: Kunci API untuk menghubungkan ke akun Anda ### list `npx @capgo/cli bundle list [appId]` Menampilkan semua bundel untuk aplikasi Opsi: * `-a, --apikey `: Kunci API untuk menghubungkan ke akun Anda ### cleanup `npx @capgo/cli bundle cleanup [appId]` Membersihkan bundel lama untuk versi major, menyimpan jumlah bundel terbaru yang ditentukan Opsi: * `-b, --bundle `: Nomor versi major yang akan dibersihkan * `-a, --apikey `: Kunci API untuk menghubungkan ke akun Anda * `-k, --keep `: Jumlah bundel yang akan disimpan (default: 4) * `-f, --force`: Paksa penghapusan tanpa konfirmasi ### decrypt `npx @capgo/cli bundle decrypt [zipPath] [sessionKey]` Mendekripsi bundel zip yang ditandatangani Opsi: * `--key `: Path kustom untuk kunci penandatanganan privat * `--key-data `: Data kunci penandatanganan privat ### encrypt `npx @capgo/cli bundle encrypt [zipPath]` Mengenkripsi bundel zip Opsi: * `--key `: Path kustom untuk kunci penandatanganan privat * `--key-data `: Data kunci penandatanganan privat ### encryptV2 `npx @capgo/cli bundle encryptV2 [zipPath] [checksum]` Mengenkripsi bundel zip menggunakan metode enkripsi baru Opsi: * `--key `: Path kustom untuk kunci penandatanganan privat * `--key-data `: Data kunci penandatanganan privat * `-j, --json`: Tampilkan hasil sebagai JSON ### decryptV2 `npx @capgo/cli bundle decryptV2 [zipPath] [checksum]` Mendekripsi bundel zip menggunakan metode enkripsi baru Opsi: * `--key `: Path kustom untuk kunci penandatanganan privat * `--key-data `: Data kunci penandatanganan privat * `--checksum `: Checksum bundel untuk memverifikasi integritas ### zip `npx @capgo/cli bundle zip [appId]` Menghasilkan file zip untuk bundel Opsi: * `-p, --path `: Path ke folder yang akan di-zip (default ke `webDir` di `capacitorconfig`) * `-b, --bundle `: Nomor versi bundel yang akan digunakan dalam nama file * `-n, --name `: Nama file kustom untuk zip * `-j, --json`: Tampilkan hasil sebagai JSON * `--no-code-check`: Lewati pemeriksaan `notifyAppReady()` dalam kode sumber dan `indexhtml` di folder root * `--key-v2`: Gunakan metode enkripsi baru (v2) * `--package-json `: Daftar path ke file `packagejson` yang dipisahkan koma (berguna untuk monorepo) # saluran Perintah `channel` memungkinkan Anda mengelola kanal rilis Anda ### add `npx @capgo/cli channel add [channelId] [appId]` Membuat kanal baru untuk aplikasi Opsi: * `-d, --default`: Atur kanal baru sebagai kanal default * `-a, --apikey `: Kunci API untuk menghubungkan ke akun Anda ### delete `npx @capgo/cli channel delete [channelId] [appId]` Menghapus kanal dari aplikasi Opsi: * `-a, --apikey `: Kunci API untuk menghubungkan ke akun Anda * `--delete-bundle`: Hapus bundle yang terkait dengan kanal ### list `npx @capgo/cli channel list [appId]` Menampilkan semua kanal untuk aplikasi Opsi: * `-a, --apikey `: Kunci API untuk menghubungkan ke akun Anda ### currentBundle `npx @capgo/cli channel currentBundle [channel] [appId]` Mendapatkan bundle saat ini untuk kanal tertentu Opsi: * `-c, --channel `: Kanal untuk mendapatkan bundle saat ini * `-a, --apikey `: Kunci API untuk menghubungkan ke akun Anda * `--quiet`: Hanya menampilkan versi bundle ### set `npx @capgo/cli channel set [channelId] [appId]` Mengatur properti kanal Opsi: * `-a, --apikey `: Kunci API untuk menghubungkan ke akun Anda * `-b, --bundle `: Nomor versi bundle untuk diatur ke kanal * `-s, --state `: Atur status kanal (`default` atau `normal`) * `--latest`: Gunakan versi terbaru dari `packagejson` sebagai versi bundle * `--downgrade`: Izinkan penurunan versi di bawah versi asli * `--no-downgrade`: Nonaktifkan penurunan versi di bawah versi asli * `--upgrade`: Izinkan peningkatan versi di atas versi asli * `--no-upgrade`: Nonaktifkan peningkatan versi di atas versi asli * `--ios`: Izinkan pengiriman pembaruan ke perangkat iOS * `--no-ios`: Nonaktifkan pengiriman pembaruan ke perangkat iOS * `--android`: Izinkan pengiriman pembaruan ke perangkat Android * `--no-android`: Nonaktifkan pengiriman pembaruan ke perangkat Android * `--self-assign`: Izinkan perangkat untuk mengatur diri sendiri ke kanal ini * `--no-self-assign`: Nonaktifkan pengaturan diri perangkat ke kanal ini * `--disable-auto-update `: Nonaktifkan strategi pembaruan otomatis untuk kanal ini (opsi: `major`, `minor`, `metadata`, `patch`, `none`) * `--dev`: Izinkan pengiriman pembaruan ke perangkat pengembangan * `--no-dev`: Nonaktifkan pengiriman pembaruan ke perangkat pengembangan * `--emulator`: Izinkan pengiriman pembaruan ke perangkat emulator * `--no-emulator`: Nonaktifkan pengiriman pembaruan ke perangkat emulator * `--package-json `: Daftar path ke file `packagejson` yang dipisahkan koma (berguna untuk monorepo) # dokter `npx @capgo/cli doctor` Perintah ini memeriksa apakah Anda menggunakan versi terbaru dari paket-paket Capgo Ini juga berguna untuk pelaporan bug # init `npx @capgo/cli@latest init [apikey]` Perintah ini akan memandu Anda langkah demi langkah untuk: * Menambahkan aplikasi Anda ke Capgo * Menambahkan kode ke aplikasi Anda untuk memvalidasi pembaruan * Membangun aplikasi Anda * Mengunggah aplikasi Anda ke Capgo * Membantu Anda memeriksa apakah pembaruan berfungsi # kunci Perintah `key` memungkinkan Anda mengelola kunci penandatanganan aplikasi Anda ### save `npx @capgo/cli key save` Menyimpan kunci enkripsi yang dikodekan base64 ke konfigurasi Capacitor (berguna untuk CI) Options: * `-f, --force`: Memaksa pembuatan kunci baru * `--key`: Path ke file kunci yang akan disimpan dalam konfigurasi Capacitor * `--key-data`: Data kunci yang akan disimpan langsung dalam konfigurasi Capacitor ### create `npx @capgo/cli key create` Membuat kunci enkripsi baru Options: * `-f, --force`: Memaksa pembuatan kunci baru ### delete\_old `npx @capgo/cli key delete_old` Menghapus kunci enkripsi lama # masuk `npx @capgo/cli login [apikey]` Perintah ini menyimpan kunci API Capgo Anda untuk penggunaan di masa mendatang Note Anda dapat mengganti kunci API yang tersimpan dengan menambahkan `--apikey=` ke perintah apapun Opsi: * `--local`: Menyimpan kunci API di repo lokal dan menambahkannya ke `gitignore` # FAQ (Tanya Jawab) > FAQ Seputar Capgo Jika Anda memiliki pertanyaan yang belum terjawab di sini, silakan bertanya! Baik dengan membuat issue atau bertanya di [Discord](https://discordcom/invite/VnYRvBfgA6) ### Apa itu “code push”?[](https://capgo.app/docs/#what-is-code-push "Direct link to What is \"code push\"?") Code push, juga dikenal sebagai “over the air updates” (OTA) adalah layanan cloud yang memungkinkan pengembang Capacitor untuk menerapkan pembaruan ke aplikasi mereka dalam produksi. Capgo saat ini berfungsi di Android dan iOS dan nantinya akan berfungsi di mana pun Capacitor bekerja. “Code Push” adalah referensi untuk nama fitur deploy yang digunakan oleh komunitas React Native dari [Microsoft](https://appcenterms/) dan [Expo](https://expodev/), yang keduanya tidak mendukung Capacitor. ### Apa perbedaan antara bundle dan release?[](https://capgo.app/docs/faq/#what-is-the-difference-between-a-bundle-and-a-release "Direct link to What is the difference between a bundle and a release?") Kami menggunakan istilah “release” untuk menyiapkan binary untuk app store. Agar nantinya dapat menghasilkan bundle, Capgo perlu mengetahui binary yang persis yang dikirim ke app store. Kami menggunakan istilah “bundle” untuk patch yang dapat diterapkan ke release untuk memperbarui kode baru. Perintah `npx @capgo/cli app update` digunakan untuk menghasilkan bundle dari kode lokal baru Anda yang kemudian dikirim ke pengguna Anda. ### Apa roadmap-nya?[](https://capgo.app/docs/faq/#what-is-the-roadmap "Direct link to What is the roadmap?") Papan proyek kami juga bersifat publik dan dapat ditemukan di: [https://github.com/orgs/Cap-go/projects](https://github.com/orgs/Cap-go/projects/) Tim kami juga beroperasi secara publik, jadi Anda dapat melihat apa yang sedang kami kerjakan setiap saat. Kami senang menjawab pertanyaan apa pun yang Anda miliki tentang roadmap atau prioritas kami melalui Github issues atau [Discord](https://discordcom/invite/VnYRvBfgA6). ### Bisakah saya menggunakan Capgo dengan tim saya?[](https://capgo.app/docs/faq/#can-i-use-capgo-with-my-team "Direct link to Can I use Capgo with my team?") Ya! Semua paket mendukung pengembang tanpa batas. Kami hanya membatasi metrik aplikasi (MAU, penyimpanan dan bandwidth) untuk setiap organisasi. Lihat [Teams](https://capgo.app/pricing/) untuk informasi lebih lanjut. ### Apakah Capgo menyimpan kode sumber saya?[](https://capgo.app/docs/faq/#does-capgo-store-my-source-code "Direct link to Does Capgo store my source code?") Tidak. Server Capgo tidak pernah melihat kode sumber Anda. Ketika Anda menjalankan `npx @capgo/cli app update`, alat `npx @capgo/cli` hanya mengunggah kode yang sama yang dikompilasi yang Anda kirim ke app store. Jika Anda menginginkan keamanan tambahan, Anda dapat menggunakan enkripsi End to End untuk mengenkripsi bundle Anda sebelum mengunggahnya ke server Capgo. Lihat juga kebijakan privasi kami: [https://capgo.app/privacy](https://capgo.app/privacy/) ### Bisakah saya menggunakan Capgo dari sistem CI saya?[](https://capgo.app/docs/faq/#can-i-use-capgo-from-my-ci-system "Direct link to Can I use Capgo from my CI system?") Ya. Capgo dimaksudkan untuk digunakan dari sistem CI. Kami telah menerbitkan panduan untuk [Android dan Github Actions](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) dan [IOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/), Dan untuk [Gitlab](https://capgo.app/blog/setup-ci-and-cd-gitlab/), sistem CI lainnya seharusnya serupa. Jangan ragu untuk menghubungi kami melalui GitHub issues atau Discord jika Anda mengalami masalah. ### Bagaimana hubungannya dengan Firebase Remote Config atau Launch Darkly?[](https://capgo.app/docs/faq/#how-does-this-relate-to-firebase-remote-config-or-launch-darkly "Direct link to How does this relate to Firebase Remote Config or Launch Darkly?") Code push memungkinkan menambahkan kode baru / mengganti kode pada perangkat. Firebase Remote Config dan Launch Darkly keduanya adalah sistem konfigurasi. Mereka memungkinkan Anda untuk mengubah konfigurasi aplikasi Anda tanpa harus mengirim versi baru. Mereka tidak dimaksudkan untuk mengganti kode. ### Seberapa besar jejak dependensi yang ditambahkannya?[](https://capgo.app/docs/faq/#how-big-of-a-dependency-footprint-does-this-add "Direct link to How big of a dependency footprint does this add?") Saya belum mengukur baru-baru ini, tetapi saya memperkirakan library code push akan menambah kurang dari satu megabyte ke aplikasi Capacitor. Kami tahu cara untuk membuatnya lebih kecil ketika itu menjadi prioritas. Jika ukuran menjadi penghalang bagi Anda, beri tahu kami! ### Apakah code push bekerja dengan aplikasi besar?[](https://capgo.app/docs/faq/#does-code-push-work-with-large-applications "Direct link to Does code push work with large applications?") Ya. Tidak ada batasan ukuran aplikasi yang dapat diperbarui dengan code push. Seperti disebutkan [di bawah](https://capgo.app/docs/faq/#what-types-of-changes-does-capgo-code-push-support), Capgo dapat mengubah kode JS apa pun dalam aplikasi Anda tanpa memandang ukuran. Perlu diperhatikan: Ukuran yang lebih besar membuat lebih sulit bagi pengguna untuk mengunduh pembaruan. Kami menyarankan untuk menjaga aplikasi Anda sekecil mungkin. ### Untuk apa saya bisa menggunakan Capgo code push?[](https://capgo.app/docs/faq/#what-can-i-use-capgo-code-push-for "Direct link to What can I use Capgo code push for?") Kami telah melihat berbagai penggunaan, termasuk: * Perbaikan darurat untuk aplikasi produksi * Mengirim perbaikan bug ke pengguna pada versi lama aplikasi Anda * Pengiriman konstan (misalnya setiap jam) Perhatikan bahwa sebagian besar app store melarang pengiriman kode yang mengubah perilaku aplikasi secara signifikan. Silakan lihat [di bawah](https://capgo.app/docs/faq/#how-does-this-relate-to-the-appplay-store-review-process-or-policies) untuk informasi lebih lanjut. ### Apa yang dihitung sebagai “MAU” untuk Capgo?[](https://capgo.app/docs/faq/#what-counts-as-a-mau-for-capgo "Direct link to What counts as a \"MAU\" for Capgo?") MAU adalah “Monthly Active User”. Kami menghitung MAU sebagai perangkat yang telah menghubungi server kami dalam 30 hari terakhir. Kami tidak menghitung perangkat yang tidak menghubungi server kami dalam 30 hari terakhir. Setiap kali perangkat menginstal ulang aplikasi Anda, MAU baru dihitung, ini terjadi karena batasan privasi Apple Store. Kami tidak dapat melacak perangkat yang sama jika pengguna menginstal ulang aplikasi. Selama pengembangan, setiap kali Anda menginstal ulang aplikasi, MAU baru dihitung. Sama untuk unduhan testflight atau perpindahan channel di Android. Memperbarui aplikasi tidak membuat ID Perangkat baru. > Kami menyarankan setelah pengaturan pertama, untuk menonaktifkan perangkat dev dan emulator untuk mengurangi jumlah perangkat duplikat. ### Apa yang tidak bisa kita gunakan Capgo code push untuk?[](https://capgo.app/docs/faq/#what-cant-we-use-capgo-code-push-for "Direct link to What can't we use Capgo code push for?") Seperti di atas, Capgo tidak boleh digunakan untuk melanggar kebijakan app store. Silakan lihat [di bawah](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines) untuk informasi lebih lanjut. Juga Capgo tidak mendukung perubahan kode native (misalnya Java/Kotlin di Android atau Objective-C/Swift di iOS). Alat akan memperingatkan Anda selama percobaan pembaruan jika Anda telah mengubah kode native. ### Apakah Capgo mengirimkan ke store untuk saya?[](https://capgo.app/docs/faq/#does-capgo-submit-to-the-stores-for-me "Direct link to Does Capgo submit to the stores for me?") Capgo saat ini tidak mendukung pengiriman ke app store atas nama Anda. Kami memiliki rencana untuk menambahkan ini di masa depan, tetapi untuk saat ini Anda perlu terus menggunakan proses yang ada untuk mengirim ke app store. Anda dapat menggunakan [panduan CI Android](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) kami untuk mengotomatiskan proses ini dan [panduan CI iOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/). ### Apa yang disimpan Capgo di disk dan di mana?[](https://capgo.app/docs/faq/#what-does-capgo-store-on-disk-and-where "Direct link to What does Capgo store on disk and where?") Updater Capgo (termasuk dalam aplikasi Anda ketika Anda membangun aplikasi Anda) menyimpan bundle terakhir yang diunduh dalam satu-satunya direktori yang diizinkan capacitor untuk memuat kode. Di Android, ini terletak di `/data/user/0/comexampleapp/code_cache/capgo_updater` meskipun bagian awal dari path itu disediakan oleh sistem Android dan dapat berubah secara dinamis saat runtime. Pada perangkat iOS, data disimpan di bawah `Library/Application Support/capgo`. Alat baris perintah Capgo (misalnya`npx @capgo/cli app update`) diinstal pada disk di cache npm, login Anda disimpan di direktori home Anda di `~/capgo` ### Bagaimana hubungannya dengan Hot Reload Capacitor?[](https://capgo.app/docs/faq/#how-does-this-relate-to-capacitor-hot-reload "Direct link to How does this relate to Capacitor Hot Reload?") Hot reload Capacitor hanya fitur pada saat pengembangan. Code push adalah untuk produksi. Hot reload adalah fitur Capacitor yang memungkinkan Anda mengubah kode pada perangkat selama pengembangan. Ini membutuhkan build aplikasi Capacitor dengan proxy untuk terhubung ke mesin lokal Anda. Code push adalah fitur yang memungkinkan Anda mengubah kode pada perangkat dalam produksi. Kami akan menggunakan berbagai teknik berbeda untuk membuatnya mungkin tergantung platformnya. ### Perubahan jenis apa yang didukung code push Capgo?[](https://capgo.app/docs/faq/#what-types-of-changes-does-capgo-code-push-support "Direct link to What types of changes does Capgo code push support?") Capgo dapat mengubah kode JS apapun dalam aplikasi Anda. Ini termasuk kode aplikasi dan kode yang dihasilkan. Anda juga dapat memperbarui dependensi di `packages.json` selama tidak memerlukan perubahan kode native. Kami tidak berencana untuk mendukung perubahan kode native (misalnya Java/Kotlin di Android atau Objective-C/Swift di iOS), dan tool akan memperingatkan jika mendeteksi Anda telah mengubah kode native karena tidak akan dimasukkan dalam bundle. ### Apakah mendukung Web?[](https://capgo.app/docs/faq/#does-this-support-web "Direct link to Does this support Flutter Web?") Code push tidak diperlukan untuk web karena web sudah bekerja dengan cara ini. Ketika pengguna membuka aplikasi web, ia mengunduh versi terbaru dari server jika dibutuhkan. Jika Anda memiliki use case untuk code push dengan web, kami ingin mengetahuinya! ### Apakah akan berfungsi di iOS, Android, Mac, Windows, Linux, dll?[](https://capgo.app/docs/faq/#will-this-work-on-ios-android-mac-windows-linux-etc "Direct link to Will this work on iOS, Android, Mac, Windows, Linux, etc?") Ya. Sejauh ini kami fokus pada dukungan Android dan iOS, tapi code push pada akhirnya akan bekerja di mana saja Capacitor bekerja. Kami memastikan telah membangun semua infrastruktur yang diperlukan untuk menyediakan code push secara andal dan aman terlebih dahulu sebelum memperluas ke platform lain. ### Versi OS apa yang didukung Capgo?[](https://capgo.app/docs/faq/#what-os-versions-does-capgo-support "Direct link to What OS versions does Capgo support?") Capgo mendukung versi Android yang sama dengan yang didukung Capacitor. Capacitor saat ini mendukung Android API level 22+ dan iOS 13.0+: [https://capacitorjs.com/docs/main/reference/support-policy](https://capacitorjs.com/docs/main/reference/support-policy/) ### Versi Capacitor apa yang didukung Capgo?[](https://capgo.app/docs/faq/#what-versions-of-flutter-does-capgo-support "Direct link to What versions of Flutter does Capgo support?") Capgo saat ini hanya mendukung versi stabil terbaru dari Capacitor. Kami dapat mendukung versi Capacitor yang lebih lama juga, kami hanya belum membangun infrastruktur yang diperlukan untuk mempertahankannya seiring waktu. Kami bermaksud untuk mendukung lebih banyak versi Capacitor di masa depan, termasuk versi apapun untuk pelanggan enterprise kami [https://github.com/Cap-go/capgo/issues/1100](https://github.com/Cap-go/capgo/issues/1100/) Capgo mengikuti Flutter stabil dan umumnya diperbarui dalam beberapa jam setelah rilis stabil. Sistem kami untuk melakukan pembaruan ini otomatis dan membutuhkan beberapa menit untuk dijalankan. Kami kemudian melakukan langkah verifikasi manual tambahan sebelum mempublikasikan ke server kami. ### Bagaimana hubungannya dengan proses review atau kebijakan App/Play Store?[](https://capgo.app/docs/faq/#how-does-this-relate-to-the-appplay-store-review-process-or-policies "Direct link to How does this relate to the App/Play Store review process or policies?") Pengembang terikat dengan perjanjian mereka dengan penyedia toko saat memilih untuk menggunakan toko tersebut. Code push dirancang untuk memungkinkan pengembang memperbarui aplikasi mereka dan tetap mematuhi kebijakan toko di iOS dan Android. Mirip dengan berbagai produk komersial yang tersedia untuk melakukannya dengan React Native (misalnya [Microsoft](https://appcenter.ms/), [Expo](https://expo.dev/)) Microsoft juga menerbitkan panduan tentang bagaimana solusi mereka mematuhi app store: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) Code push adalah teknik yang banyak digunakan di seluruh app store. Semua aplikasi besar yang saya ketahui menggunakan code push. Kebijakan utama yang perlu diperhatikan adalah tidak mengubah perilaku aplikasi secara signifikan. Silakan lihat [di bawah](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines) untuk informasi lebih lanjut. ### Apakah Capgo mematuhi pedoman Play Store?[](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines "Direct link to Does Capgo comply with Play Store guidelines?") Ya. Play Store menawarkan dua pembatasan terkait alat pembaruan: 1. Pembaruan harus menggunakan interpreter atau mesin virtual (Capgo menggunakan Dart Virtual Machine) [https://support.google.com/googleplay/android-developer/answer/9888379?hl=en](https://support.google.com/googleplay/android-developer/answer/9888379/?hl=en) ```plaintext Aplikasi yang didistribusikan melalui Google Play tidak boleh memodifikasi, mengganti, atau memperbarui dirinya sendiri
menggunakan metode selain mekanisme pembaruan Google Play. Demikian juga, aplikasi
tidak boleh mengunduh kode yang dapat dieksekusi (seperti file dex, JAR, so) dari
sumber selain Google Play. *Pembatasan ini tidak berlaku untuk kode
yang berjalan di mesin virtual atau interpreter* di mana keduanya menyediakan
akses tidak langsung ke API Android (seperti JavaScript di webview atau
browser)

Aplikasi atau kode pihak ketiga, seperti SDK, dengan bahasa yang diinterpretasikan (JavaScript,
Python, Lua, dll) yang dimuat saat runtime (misalnya, tidak dikemas dengan
aplikasi) tidak boleh mengizinkan potensi pelanggaran kebijakan Google Play
``` 2. Perubahan pada aplikasi tidak boleh menipu (misalnya mengubah tujuan aplikasi melalui pembaruan) [https://support.google.com/googleplay/android-developer/answer/9888077](https://support.google.com/googleplay/android-developer/answer/9888077/) Harap jelaskan kepada pengguna Anda tentang apa yang Anda sediakan dengan aplikasi Anda dan jangan melanggar ekspektasi mereka dengan perubahan perilaku yang signifikan melalui penggunaan Capgo. Capgo dirancang untuk kompatibel dengan pedoman Play Store. Namun Capgo adalah alat, dan seperti alat lainnya, dapat disalahgunakan. Sengaja menyalahgunakan Capgo untuk melanggar pedoman Play Store adalah pelanggaran [Ketentuan Layanan](https://capgo.app/tos/) Capgo dan dapat mengakibatkan pemutusan akun Anda. Akhirnya, layanan code push banyak digunakan di industri (semua aplikasi besar yang saya ketahui menggunakannya) dan ada beberapa layanan code push lain yang tersedia untuk umum (misalnya expo.dev & appcenter.ms). Ini adalah jalan yang sudah banyak dilalui. Microsoft juga menerbitkan panduan tentang bagaimana library “codepush” react native mereka mematuhi app store: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### Apakah Capgo mematuhi pedoman App Store?[](https://capgo.app/docs/faq/#does-capgo-comply-with-app-store-guidelines "Direct link to Does Capgo comply with App Store guidelines?") Ya. Mirip dengan Play Store, App Store menawarkan pembatasan teknis dan kebijakan ```plaintext 3.2.2
kode yang diinterpretasikan dapat diunduh ke Aplikasi hanya selama
kode tersebut:
(a) tidak mengubah tujuan utama Aplikasi dengan menyediakan
fitur atau fungsionalitas yang tidak sesuai dengan tujuan yang dimaksudkan dan
diiklankan dari Aplikasi sebagaimana yang diserahkan ke App Store,
(b) tidak membuat toko atau storefront untuk kode atau aplikasi lain, dan
(c) tidak memotong signing, sandbox, atau fitur keamanan lain dari OS
Capgo menggunakan interpreter Dart khusus untuk mematuhi pembatasan interpreter-only untuk pembaruan di iOS. Selama aplikasi Anda tidak melakukan perilaku yang menipu melalui pembaruan (misalnya mengubah tujuan aplikasi melalui pembaruan), memperbarui melalui Capgo (atau solusi code push lainnya) adalah praktik standar industri dan mematuhi pedoman App Store. Penyalahgunaan Capgo secara sengaja untuk melanggar pedoman App Store adalah pelanggaran [Ketentuan Layanan](https://capgo.app/tos/) Capgo dan dapat mengakibatkan penutupan akun Anda. Microsoft juga menerbitkan panduan tentang bagaimana pustaka "codepush" react native mereka mematuhi app store: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### Bisakah saya menggunakan Capgo di negara saya?[](https://capgo.app/docs/faq/#can-i-use-capgo-in-my-country "Link langsung ke Bisakah saya menggunakan Capgo di negara saya?") Kami tidak membatasi akses ke Capgo dari negara manapun. Kami menyadari bahwa beberapa negara memiliki pembatasan URL yang dapat diakses dari dalam negara. Capgo saat ini menggunakan Cloudflare Cloud untuk hosting, termasuk R2 Storage dan Cloudflare workers. URL berikut digunakan oleh Capgo: - [https://apicapgo.app](https://apicapgo.app/) -- digunakan oleh alat baris perintah `npx @capgo/cli` untuk berinteraksi dengan server Capgo serta pembaruan Capgo pada perangkat pengguna untuk memeriksa pembaruan - [https://*r2cloudflarestoragecom](https://*r2cloudflarestoragecom/) -- digunakan oleh alat baris perintah `npx @capgo/cli` untuk mengunggah dan mengunduh bundle Jika semua URL tersebut dapat diakses dari negara Anda, maka Capgo seharusnya berfungsi. Jika wilayah Anda mengharuskan memblokir akses ke URL tersebut, silakan beri tahu kami dan kami dapat bekerja sama untuk menemukan solusi. Server proxy adalah salah satu pilihannya. ### Bisakah saya menghosting Capgo sendiri?[](https://capgo.app/docs/faq/#can-i-self-host-capgo "Link langsung ke Bisakah saya menghosting Capgo sendiri?") Ya, Anda dapat menghosting Capgo sendiri. Panduannya belum ditulis, tetapi kodenya bersifat open source dan tersedia di [https://github.com/cap-go/capgo](https://github.com/cap-go/capgo/) ### Apakah code push memerlukan internet untuk bekerja?[](https://capgo.app/docs/faq/#does-code-push-require-the-internet-to-work "Link langsung ke Apakah code push memerlukan internet untuk bekerja?") Ya. Seseorang bisa membayangkan menjalankan server untuk mendistribusikan pembaruan secara terpisah dari internet umum, tetapi beberapa bentuk konektivitas jaringan diperlukan untuk mentransfer pembaruan ke perangkat. ### Bagaimana Capgo terpengaruh oleh kurangnya konektivitas jaringan?[](https://capgo.app/docs/faq/#how-is-capgo-affected-by-lack-of-network-connectivity "Link langsung ke Bagaimana Capgo terpengaruh oleh kurangnya konektivitas jaringan?") Pembaruan Capgo (termasuk dalam aplikasi Anda saat Anda membangun aplikasi dengan Capgo) dirancang untuk tahan terhadap masalah konektivitas jaringan. Dalam perilaku pembaruan default, ketika aplikasi diluncurkan, ia memberi tahu pembaruan Capgo, yang memunculkan thread terpisah untuk membuat permintaan jaringan ke server Capgo dan meminta pembaruan. Kami sengaja menggunakan thread terpisah untuk menghindari mempengaruhi pemblokiran hal lain yang mungkin dilakukan aplikasi. Jika permintaan jaringan gagal atau timeout, pembaruan akan mencoba memeriksa lagi saat aplikasi diluncurkan berikutnya. Alat baris perintah Capgo (misalnya `npx @capgo/cli app update`) memerlukan konektivitas jaringan untuk berfungsi. Jika Anda menggunakan Capgo untuk mendistribusikan aplikasi Anda, Anda harus memastikan bahwa sistem CI Anda memiliki konektivitas jaringan. ### Apa yang terjadi jika pengguna tidak memperbarui untuk waktu yang lama dan melewatkan pembaruan?[](https://capgo.app/docs/faq/#what-happens-if-a-user-doesnt-update-for-a-long-time-and-misses-an-update "Link langsung ke Apa yang terjadi jika pengguna tidak memperbarui untuk waktu yang lama dan melewatkan pembaruan?") Implementasi kami selalu mengirim pembaruan yang disesuaikan khusus untuk perangkat yang memintanya, selalu memperbarui peminta ke versi terbaru yang tersedia. Jadi jika pengguna tidak memperbarui untuk sementara waktu, mereka akan "melewatkan" pembaruan perantara. Server pembaruan dapat diubah untuk mendukung respons baik dengan versi inkremental berikutnya atau versi terbaru tergantung pada kebutuhan aplikasi Anda. Silakan beri tahu kami jika perilaku pembaruan alternatif penting bagi Anda. ### Bagaimana hubungan Capgo dengan Capacitor?[](https://capgo.app/docs/faq/#how-does-capgo-relate-to-capacitor "Link langsung ke Bagaimana hubungan Capgo dengan Capacitor?") Capgo adalah plugin untuk Capacitor yang menambahkan code push. Capgo bukan pengganti Capacitor. Anda dapat terus menggunakan alat Capacitor yang sudah Anda kenal dan sukai. Kami melacak rilis stabil terbaru dari Capacitor dan memperbarui plugin code push kami agar berfungsi dengannya. ### Kapan pembaruan terjadi?[](https://capgo.app/docs/faq/#when-do-updates-happen "Link langsung ke Kapan pembaruan terjadi?") Secara default, pembaruan Capgo memeriksa pembaruan saat aplikasi dimulai. Ini berjalan di thread latar belakang dan tidak memblokir thread UI. Setiap pembaruan akan dipasang saat pengguna menggunakan aplikasi dan akan diterapkan saat aplikasi dimulai ulang berikutnya. Dimungkinkan juga untuk menjalankan pembaruan Capgo secara manual menggunakan [package:capgo_code_push](https://pubdev/packages/capgo_code_push/), yang memungkinkan untuk memicu pembaruan kapan saja, termasuk melalui notifikasi push. Pembaruan Capgo dirancang sedemikian rupa sehingga ketika jaringan tidak tersedia, atau server down atau tidak dapat dijangkau, aplikasi akan terus berjalan normal. Jika Anda memilih untuk menghapus pembaruan dari server kami, semua klien Anda akan terus berjalan normal. Kami telah menambahkan kemampuan untuk melakukan rollback patch. Hal paling sederhana adalah dengan melampirkan bundle sebelumnya ke channel Anda untuk membatalkan. ### Apakah saya perlu menjaga kerahasiaan app_id saya?[](https://capgo.app/docs/faq/#do-i-need-to-keep-my-app_id-secret "Link langsung ke Apakah saya perlu menjaga kerahasiaan app_id saya?") Tidak. `app_id` disertakan dalam aplikasi Anda dan aman untuk dipublikasikan. Anda dapat memeriksakannya ke kontrol versi (bahkan secara publik) dan tidak perlu khawatir orang lain mengaksesnya. Seseorang yang memiliki `app_id` Anda dapat mengambil versi terbaru aplikasi Anda dari server Capgo, tetapi mereka tidak dapat mendorong pembaruan ke aplikasi Anda atau mengakses aspek lain dari akun Capgo Anda. ### Informasi apa yang dikirim ke server Capgo?[](https://capgo.app/docs/faq/#what-information-is-sent-to-capgo-servers "Link langsung ke Informasi apa yang dikirim ke server Capgo?") Meskipun Capgo terhubung ke jaringan, ia tidak mengirimkan informasi yang dapat diidentifikasi secara pribadi. Menyertakan Capgo seharusnya tidak mempengaruhi deklarasi Anda untuk Play Store atau App Store. Permintaan yang dikirim dari aplikasi ke server Capgo mencakup: - app_id (ditentukan dalam `capacitorconfigjson`) - channel (opsional dalam `capacitorconfigjson`) - release_version (versionName dari AndroidManifestxml atau CFBundleShortVersionString dari Infoplist atau `capacitorconfigjson` jika diatur dalam [`CapacitorUpdaterversion`](/docs/plugin/settings/#version)) - version_number (dihasilkan sebagai bagian dari `npx @capgo/cli app update`) - os_version (misalnya '1121') - platform (misalnya 'android', diperlukan untuk mengirimkan patch yang tepat) Itu saja. Kode untuk ini ada di `updater/library/src/networkrs` - device_id (dibuat di perangkat saat pertama kali dijalankan, digunakan untuk menghilangkan duplikasi instalasi per-perangkat dan memungkinkan kami mengenakan biaya berdasarkan pengguna yang diinstal)pengguna aktif bulanan), daripada total patch atau total instalasi patch) - custom\_id (opsional, diatur saat runtime oleh pengembang, digunakan agar Anda dapat menghubungkan perangkat ke pengguna dalam sistem Anda) ### Platform apa saja yang didukung Capgo?[](https://capgo.app/docs/faq/#what-platforms-does-capgo-support "Direct link to What platforms does Capgo support?") Saat ini, Capgo mendukung iOS dan Android. Keduanya sudah siap untuk produksi. Penggunaan Capgo untuk iOS atau Android dapat menjadi keputusan independen. Anda dapat mengatur di channel Anda untuk mengirim ke Android dan ipa yang dibuat ke App Store atau sebaliknya. Capgo dapat (dengan relatif mudah) dibuat untuk mendukung target desktop atau embedded. Jika hal tersebut penting bagi Anda, silakan beri tahu kami. ### Bagaimana Capgo berinteraksi dengan Play Testing Tracks atau Apple TestFlight?[](https://capgo.app/docs/faq/#how-does-capgo-interact-with-play-testing-tracks-or-apple-testflight "Direct link to How does Capgo interact with Play Testing Tracks or Apple TestFlight?") Masing-masing app store memiliki mekanisme terpisah untuk mendistribusikan aplikasi ke kelompok pengguna terbatas (mis. "pengujian internal", "beta tertutup", dll). Semua ini adalah mekanisme untuk membagi pengguna Anda menjadi kelompok-kelompok dan mendistribusikan versi aplikasi tertentu ke masing-masing. Sayangnya, tidak semua mekanisme ini memungkinkan pihak ke-3 mendeteksi kapan aplikasi diinstal di Test Track tertentu atau melalui TestFlight. Dengan demikian, kami tidak memiliki visibilitas yang dapat diandalkan ke komposisi kelompok-kelompok ini, dan tidak dapat membatasi akses ke patch Capgo berdasarkan kelompok-kelompok ini. [https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play](https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play/) [https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i](https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i/) Jika Anda ingin membagi ketersediaan bundle Capgo, ada 4 opsi potensial: 1. Gunakan channel terpisah untuk setiap kelompok. Ini adalah pendekatan yang paling langsung, tapi memerlukan Anda mengelola beberapa channel. Anda mungkin sudah memiliki channel dev dan prod dengan ketersediaan berbeda. Anda dapat memperbarui channel dev Anda, memverifikasinya dan kemudian memperbarui channel prod Anda secara terpisah. Kami merekomendasikan menggunakan branch/tag dalam version control untuk membantu melacak sumber yang terkait dengan setiap rilis. 2. Lacak set pengguna opt-in Anda sendiri, nonaktifkan pembaruan otomatis, dan picu pembaruan hanya untuk pengguna tertentu melalui package:capgo\_code\_push. Ini berfungsi saat ini, tapi memerlukan Anda mengelola daftar opt-in Anda sendiri. 3. Capgo memungkinkan membuat mekanisme opt-in sendiri berdasarkan perangkat (mirip dengan Test Tracks atau TestFlight, hanya agnostik platform). Ini memungkinkan tim QA Anda untuk opt-in ke bundle sebelum dipromosikan ke publik. 4. Capgo memiliki rollout berbasis persentase. Ini tidak membiarkan Anda memilih perangkat mana yang akan dikirim, tapi dapat membantu Anda melakukan rollout secara bertahap dan rollback saat melihat masalah. ## Penagihan[](https://capgo.app/docs/faq/#billing "Direct link to Billing") ### Bagaimana cara meningkatkan atau menurunkan paket saya?[](https://capgo.app/docs/faq/#how-do-i-upgrade-or-downgrade-my-plan "Direct link to How do I upgrade or downgrade my plan?") Anda dapat meningkatkan atau menurunkan paket Anda kapan saja di dashboard Anda: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Kapan periode penagihan saya direset?[](https://capgo.app/docs/faq/#when-does-my-billing-period-reset "Direct link to When does my billing period reset?") Periode penagihan direset secara otomatis setiap bulan pada bulan Anda pertama kali berlangganan Capgo. Misalnya, jika Anda berlangganan pada tanggal 15 bulan ini, periode penagihan Anda akan direset pada tanggal 15 setiap bulan. ### Bagaimana cara membatalkan langganan saya?[](https://capgo.app/docs/faq/#how-do-i-cancel-my-subscription "Direct link to How do I cancel my subscription?") Anda dapat membatalkan langganan Anda kapan saja di dashboard Anda: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Bisakah saya membayar untuk satu tahun di muka?[](https://capgo.app/docs/faq/#can-i-pay-for-a-year-in-advance "Direct link to Can I pay for a year in advance?") Ya, Anda bisa kapan saja di dashboard Anda: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Statistik dan analitik[](https://capgo.app/docs/faq/#stats-and-analytics "Direct link to Stats and analytics") Statistik di dashboard Anda diperbarui setiap tengah malam UTC. Statistik dihitung berdasarkan jumlah [MAU](https://capgo.app/docs/faq/#what-is-the-difference-between-a-bundle-and-a-release "Direct link to What is the difference between a bundle and a release?") yang telah diinstal di perangkat Anda. # Bagaimana ID perangkat dibuat[](https://capgo.app/docs/faq/#how-device-id-is-generated "Direct link to How device ID is generated") ID perangkat dibuat di perangkat pada penggunaan pertama, dan digunakan untuk menghilangkan duplikasi instalasi per-perangkat dan memungkinkan kami menagih berdasarkan pengguna yang terinstal (mis. pengguna aktif bulanan), daripada total patch atau total instalasi patch. MAU adalah solusi yang lebih baik daripada jumlah instalasi untuk harga Capgo, karena lebih akurat dan mencerminkan biaya aktual Capgo per perangkat. Untuk alasan privasi, kami tidak dapat melacak perangkat yang sama jika pengguna menginstal ulang aplikasi. Aturan privasi diberlakukan oleh Apple dan Google, dan tidak diberlakukan oleh Capgo. ID Perangkat tidak akan terdaftar dalam daftar perangkat Anda sampai mereka mendapatkan patch pertama yang diinstal. # Mengapa jumlah perangkat saya berbeda dengan MAU saya?[](https://capgo.app/docs/faq/#why-my-device-number-is-different-than-my-mau "Direct link to Why my device number is different than my MAU?") Saat ini, daftar perangkat tidak diperbarui sesering MAU. Daftar perangkat hanya diperbarui ketika perangkat menginstal pembaruan. Sementara MAU diperbarui pada setiap peluncuran aplikasi. Ini adalah keterbatasan platform saat ini. Platform Analitik kami tidak mendukung pembaruan mentah sehingga kami menggunakan database konvensional untuk daftar Perangkat. Untuk membatasi jumlah query database, kami hanya memperbarui baris saat pembaruan aplikasi. Keterbatasan ini akan dihapus di masa depan. # Bagaimana cara memiliki pembaruan berbeda berdasarkan platform?[](https://capgo.app/docs/faq/#how-to-have-different-update-by-platform "Direct link to How to have different update by platform?") Anda dapat membuat channel untuk setiap platform dan menonaktifkan pembaruan khusus platform di setiap channel. Pada channel ios nonaktifkan pembaruan android dan pada channel android nonaktifkan pembaruan ios. Kemudian unggah bundle ke setiap channel untuk memiliki pembaruan berbeda untuk setiap platform. Jika Anda perlu memiliki pembaruan yang sama untuk kedua platform, Anda dapat menghubungkan satu bundle ke beberapa channel. Tidak perlu menduplikasi bundle. ``` # Dukungan teknis untuk capgo > Cara Mendapatkan Bantuan untuk Capgo ## Dukungan melalui discord Capgo memiliki [server discord](https://discordcom/invite/VnYRvBfgA6) resmi. Mendapatkan dukungan teknis di sana mungkin adalah salah satu cara tercepat untuk mendapatkan respons. Berikut adalah panduan singkatnya: 1. pergi ke channel `questions` ![Ask on discord](/discord-questions.webp) 2. buat thread anda ![Create a question on discord](/discord-newquestion.webp) 3. Jelaskan masalah anda dan pilih tag yang relevan ![Create a post on discord](/discord-new-post.webp) 4. Bagikan id akun aman anda (opsional) Ini akan memungkinkan staf capgo untuk melihat akun anda. Berbagi id ini aman, karena memang dirancang untuk dibagikan secara publik. Untuk membagikannya, silakan pergi ke [pengaturan capgo](https://web.capgo.app/dashboard/settings/account/) Di sana silakan klik `copy account id` ![Share your id without leaking your info](/share-secure-id.webp) Ini akan menyalin id akun aman ke clipboard. Mohon sertakan id tersebut dalam postingan discord anda. ## Dukungan melalui email Ini adalah cara paling lambat untuk mendapatkan dukungan. Mohon gunakan server discord terlebih dahulu. Jika anda perlu menghubungi kami melalui email, silakan kirim email ke # Ajouter une App > Tambahkan aplikasi ke akun Capgo dan instal plugin ke aplikasi tersebut ## Pengenalan Capgo [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## Live update hanya 3 langkah ### Panduan setup 1. Buat akun Anda di ![signup screenshot](/signup.webp "signup screenshot") 2. Gunakan perintah Init untuk memulai ```bash npx @capgo/cli@latest init [APIKEY] ``` Anda akan diberikan beberapa pertanyaan. Berikan jawaban yang diperlukan untuk menyelesaikan setup otomatis Tip Dengan mengikuti langkah-langkah ini, Anda akan siap menggunakan dalam waktu singkat. Jika Anda membutuhkan bantuan selama proses, tim support kami [siap membantu](https://support.capgo.app) Selamat mencoba! 3. Deploy live update [Deploy live update ](/docs/getting-started/deploy/)Pelajari cara deploy live update ke aplikasi Anda ### Setup manual Jika perintah init tidak berhasil, Anda dapat menambahkan aplikasi secara manual 1. Hubungkan CLI ke akun Anda: ```bash npx @capgo/cli@latest login [APIKEY] ``` 2. Tambahkan aplikasi ke akun Anda dengan perintah ini: ```bash npx @capgo/cli@latest app add [APP_NAME] ``` 3. Pasang plugin di aplikasi Anda: ```json { "plugins": { CapacitorUpdater: { "appId": "Your appID", "autoUpdate": true, "version": "1.0.0" } } } ``` 4. Panggil metode init sedini mungkin di aplikasi Anda: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; CapacitorUpdater.notifyAppReady(); ``` 5. Deploy live update [Deploy live update ](/docs/getting-started/deploy/)Pelajari cara deploy live update ke aplikasi Anda # Integrasi CI/CD Mengintegrasikan Capgo ke dalam pipeline CI/CD Anda memungkinkan untuk mengotomatisasi sepenuhnya proses pembuatan dan penerapan pembaruan ke aplikasi Anda. Dengan memanfaatkan CLI Capgo dan semantic-release, Anda dapat memastikan penerapan yang konsisten, handal dan memungkinkan iterasi yang cepat. ## Manfaat Integrasi CI/CD * **Otomatisasi**: Tidak ada lagi langkah manual atau ruang untuk kesalahan manusia. Seluruh proses build, test, dan deployment Anda dapat diotomatisasi dari awal hingga akhir. * **Konsistensi**: Setiap penerapan mengikuti langkah-langkah yang sama, memastikan proses yang dapat diprediksi dan diulang. Ini sangat berharga ketika Anda memiliki beberapa anggota tim yang berkontribusi kode. * **Iterasi lebih cepat**: Dengan penerapan otomatis, Anda dapat mengirim pembaruan lebih sering dan dengan percaya diri. Tidak perlu lagi menunggu QA manual atau persetujuan rilis. ## CLI Capgo CLI Capgo adalah kunci untuk mengintegrasikan Capgo ke dalam alur kerja CI/CD Anda. Ini menyediakan perintah untuk mendorong versi bundle baru, mengelola channel, dan banyak lagi. Perintah yang paling penting untuk integrasi CI/CD adalah `upload`: ```shell npx @capgo/cli@latest bundle upload --channel=Production --apikey YOUR_API_KEY ``` Perintah ini mengunggah build web saat ini ke channel yang ditentukan. Anda biasanya akan menjalankan ini sebagai langkah terakhir dalam pipeline CI/CD Anda, setelah build web Anda berhasil diselesaikan. ## Menyiapkan Capgo dalam Pipeline CI/CD Anda Meskipun langkah-langkah pastinya akan bervariasi tergantung pada pilihan alat CI/CD Anda, proses umum untuk mengintegrasikan Capgo terlihat seperti ini: 1. **Buat API key**: Masuk ke dashboard Capgo dan buat API key baru. Kunci ini akan digunakan untuk mengautentikasi CLI di lingkungan CI/CD Anda. Jaga kerahasiaannya dan jangan pernah menyimpannya di repositori Anda! 2. **Konfigurasi perintah `upload`**: Tambahkan langkah ke konfigurasi CI/CD Anda yang menjalankan perintah `upload` dengan argumen yang sesuai: upload.yml ```yaml - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secrets.CAPGO_API_KEY }} ``` \n Ganti `Production` dengan channel yang ingin Anda terapkan, dan `${{ secrets.CAPGO_API_KEY }}` dengan variabel lingkungan yang menyimpan API key Anda. 3. **Tambahkan langkah `upload` setelah build web Anda**: Pastikan bahwa langkah `upload` datang setelah build web Anda berhasil diselesaikan. Ini memastikan Anda selalu menerapkan kode terbaru Anda.\n Berikut contoh konfigurasi untuk GitHub Actions:\n upload.yml ```yaml name: Deploy to Capgo on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v4 with: node-version: 18 - run: npm ci - run: npm run build - run: npm install -g @capgo/cli - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secrets.CAPGO_API_KEY }} ``` ## Integrasi Semantic-release Semantic-release adalah alat yang kuat untuk mengotomatisasi manajemen versi dan menghasilkan catatan rilis. Dengan mengintegrasikan semantic-release dengan Capgo, Anda dapat secara otomatis menambah versi aplikasi Anda dan menghasilkan changelog dengan setiap penerapan. Berikut contoh file konfigurasi `releaserc` untuk semantic-release: ```json { "branches": [ "main", { "name": "beta", "prerelease": true } ], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", [ "@semantic-release/exec", { "publishCmd": "npx @capgo/cli@latest bundle upload --channel=${nextRelease.channel} --apikey YOUR_API_KEY --partial" } ], [ "@semantic-release/git", { "assets": ["CHANGELOG.md", "package.json"], "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" } ] ] } ``` Konfigurasi ini melakukan hal berikut: 1. Menganalisis pesan commit untuk menentukan nomor versi berikutnya, mengikuti spesifikasi Conventional Commits 2. Menghasilkan catatan rilis berdasarkan commit sejak rilis terakhir 3. Memperbarui file `CHANGELOG.md` dengan catatan rilis baru 4. Menjalankan perintah `upload` CLI Capgo, meneruskan nomor versi baru dan menggunakan flag `--partial` untuk pembaruan diferensial 5. Melakukan commit file `CHANGELOG.md`, `package.json`, dan file lain yang berubah kembali ke repositori Untuk menggunakan semantic-release dengan Capgo, cukup tambahkan langkah ke konfigurasi CI/CD Anda yang menjalankan `npx semantic-release`. Pastikan langkah ini datang setelah build web Anda dan sebelum langkah `upload` Capgo. ## Pemecahan Masalah Jika Anda mengalami masalah dengan integrasi CI/CD Capgo Anda, berikut beberapa hal yang perlu diperiksa: * **API key**: Pastikan API key Anda valid dan memiliki izin yang diperlukan. Jika menggunakan variabel lingkungan, periksa kembali bahwa itu diatur dengan benar. * **Versi CLI**: Pastikan Anda menggunakan versi terbaru dari CLI Capgo. Versi lama mungkin memiliki masalah kompatibilitas atau kurang fitur tertentu. * **Artefak build**: Konfirmasikan bahwa build web Anda menghasilkan file output yang diharapkan. CLI Capgo membutuhkan build web yang valid untuk membuat bundle. * **Konektivitas jaringan**: Periksa bahwa lingkungan CI/CD Anda memiliki akses jaringan ke server Capgo. Masalah firewall atau proxy terkadang dapat mengganggu perintah `upload`. Jika Anda masih mengalami masalah, hubungi dukungan Capgo untuk bantuan. Mereka dapat membantu memecahkan masalah dengan pengaturan spesifik Anda. ## Kesimpulan Mengintegrasikan Capgo ke dalam pipeline CI/CD Anda dan memanfaatkan semantic-release untuk manajemen versi dapat sangat menyederhanakan alur kerja pengembangan Anda. Dengan mengotomatisasi penerapan dan versi, Anda dapat mengirim pembaruan lebih cepat dan dengan lebih percaya diri. CLI Capgo dan semantic-release menyediakan kombinasi yang kuat untuk mencapai rilis yang sepenuhnya otomatis, end-to-end. Dengan sedikit konfigurasi, Anda dapat memiliki proses penerapan yang kuat dan andal yang memungkinkan Anda fokus pada membangun fitur hebat daripada khawatir tentang langkah-langkah rilis manual. Untuk detail lebih lanjut tentang perintah dan opsi CLI Capgo, lihat [referensi CLI](/docs/cli/overview). Dan untuk pendalaman lebih lanjut tentang konfigurasi semantic-release, lihat [dokumentasi semantic-release](https://github.com/semantic-release/semantic-release). Selamat menerapkan! # Menerapkan Live Update Gunakan fitur Live Updates Capgo untuk memperbarui UI dan logika bisnis aplikasi Anda dari jarak jauh secara real-time. Push pembaruan bundle JS langsung ke pengguna Anda tanpa melalui app store untuk segera memperbaiki bug dan mengirim fitur baru. Panduan ini mengasumsikan Anda telah menyelesaikan [Capgo Quickstart](/docs/getting-started/quickstart) dan telah: 1. Menginstal SDK `@capgo/capacitor-updater` di aplikasi Capacitor Anda 2. Mengkonfigurasi ID aplikasi dan channel pembaruan di `capacitor.config.ts` 3. Menambahkan method `CapacitorUpdater.notifyAppReady()` dalam kode Anda Jika Anda belum melakukan langkah-langkah tersebut, silakan kembali dan selesaikan quickstart terlebih dahulu [Tambah aplikasi ](/docs/getting-started/add-an-app/)Tambahkan aplikasi ke akun Capgo Anda, dan instal plugin di aplikasi Anda ## Mengunggah Bundle Dengan SDK Capgo telah terinstal dan terkonfigurasi, Anda siap untuk mengunggah bundle pembaruan live pertama Anda: 1. Build aset web Anda: ```shell npm run build ``` 2. Unggah bundle ke Capgo: * Console ```shell npx @capgo/cli@latest bundle upload --channel=Production ``` * Github Actions github/workflows/build\_and\_deploy.yml ```yml name: Build source code and send to Capgo concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true on: push: branches: - main jobs: deploy_to_capgo: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v5 - uses: actions/setup-node@v4 with: node-version: 18 - name: Install dependencies run: npm install - name: Build run: npm run build - name: Deploy to Capgo run: bunx @capgo/cli@latest bundle upload -a ${{ secrets.CAPGO_TOKEN }} --channel ${{ env.CHANNEL }} env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} ``` * Gitlab gitlab-ci.yml ```yml stages: - build build: stage: build image: node:18 cache: - key: files: - package-lock.json paths: - node_modules/ script: - npm install - npm run build - npx @capgo/cli@latest bundle upload -a $CAPGO_TOKEN --channel $CAPGO_CHANNEL artifacts: paths: - node_modules/ - dist/ only: - master ``` Ini akan mengunggah versi bundle baru ke channel yang ditentukan dalam perintah ### Pemecahan Masalah Unggahan Jika unggahan Anda gagal, periksa kembali: * ID aplikasi Anda di `capacitor.config.ts` cocok dengan aplikasi Anda di dashboard Capgo * Anda menjalankan perintah unggah dari root proyek Capacitor Anda * Aset web Anda telah di-build dan terbaru Jika Anda masih mengalami masalah, kunjungi bagian [Pemecahan Masalah](/docs/getting-started/troubleshooting/) ## Menerima Pembaruan di Perangkat Setelah bundle Anda diunggah, Anda dapat menguji pembaruan live di perangkat: 1. Sinkronkan aplikasi Anda ke perangkat: ```shell npx cap sync ios ``` 2. Buka terminal lain dan jalankan perintah berikut untuk memeriksa status pembaruan: ```shell npx @capgo/cli@latest app debug ``` 3. Jalankan aplikasi Anda secara lokal: ```shell npx cap run ios ``` Atau buka proyek iOS/Android di Xcode/Android Studio dan lakukan native run 4. Biarkan aplikasi terbuka selama sekitar 30 detik untuk memungkinkan pembaruan diunduh di latar belakang 5. Log akan membutuhkan beberapa detik untuk memperbarui dan menampilkan status pembaruan 6. Tutup dan buka kembali aplikasi. Anda seharusnya melihat pembaruan live Anda diterapkan! Lihat kembali [Capgo Quickstart](/docs/getting-started/quickstart#receiving-a-live-update-on-a-device) untuk detail lebih lanjut tentang pengujian pembaruan live ## Langkah Selanjutnya Selamat atas penerapan pembaruan live pertama Anda dengan Capgo! 🎉 Untuk mempelajari lebih lanjut, tinjau dokumentasi [Capgo Live Updates](/docs/live-updates) lainnya. Beberapa topik penting untuk diperiksa selanjutnya: * [Menargetkan Pembaruan dengan Channel](/docs/live-updates/channels) * [Menyesuaikan Perilaku Pembaruan](/docs/live-updates/update-behavior) * [Rollback Pembaruan Live](/docs/live-updates/rollbacks) # Ikhtisar Tutorial quickstart akan memandu Anda melalui konsep-konsep utama Capgo! Konsep yang akan dibahas meliputi: 1. Menambahkan aplikasi ke akun Capgo Anda 2. Mengintegrasikan Capgo dengan CI/CD Anda 3. Memicu upload bundle di Capgo dengan mendorong commit 4. Mengkonfigurasi dan menyesuaikan publikasi bundle Capgo 5. Menyiapkan aplikasi Anda untuk mengaktifkan pembaruan langsung melalui Capgo 6. Menerapkan pembaruan langsung ke aplikasi Anda dari Capgo Cukup ikuti panduan langkah demi langkah, atau navigasi langsung ke dokumentasi untuk komponen yang menarik bagi Anda [ Mulai Tutorial](/docs/getting-started/add-an-app/) [Ikuti tutorial quickstart dan mulai menggunakan Capgo dalam waktu singkat!](/docs/getting-started/add-an-app/) [ Mudah diintegrasikan](/docs/getting-started/deploy/) [Integrasikan Capgo dengan CI/CD Anda dan picu upload bundle di Capgo dengan mendorong commit](/docs/getting-started/deploy/) [ Dokumentasi Pembaruan Langsung](/docs/live-updates/) [Perbarui aplikasi Anda dari jarak jauh secara real-time tanpa penundaan app store](/docs/live-updates/) [ Pemecahan Masalah](/docs/getting-started/troubleshooting) [Masalah umum dan cara mengatasinya](/docs/getting-started/troubleshooting) Tip Fitur pembaruan Over-the-Air (OTA) hanya berlaku untuk modifikasi yang dilakukan pada file HTML, CSS, dan JavaScript Jika Anda melakukan perubahan pada kode native, seperti pembaruan plugin Capacitor, wajib untuk mengirimkan ulang aplikasi ke app store untuk persetujuan ## Bergabung dengan Komunitas Discord [Bergabung dengan Server Discord Capacitor-updater!](https://discordcom/invite/VnYRvBfgA6) ## Pemeliharaan | Versi Plugin | Kompatibilitas Capacitor | Dipelihara | | ------------ | ------------------------ | ----------------------------------------------------------------- | | v6\*\* | v6\*\* | ✅ | | v5\*\* | v5\*\* | Hanya bug kritis | | v4\*\* | v4\*\* | ⚠️ Usang | | v3\*\* | v3\*\* | ⚠️ Usang | | > 7 | v4\*\* | ⚠️ Usang, CI kami menjadi gila dan terlalu banyak menaikkan versi | ## Kepatuhan Pedoman Toko Android Google Play dan iOS App Store memiliki pedoman terkait yang memiliki aturan yang harus Anda ketahui sebelum mengintegrasikan solusi Capacitor-updater dalam aplikasi Anda ### Google play Paragraf ketiga dari topik [Penyalahgunaan Perangkat dan Jaringan](https://supportgooglecom/googleplay/android-developer/answer/9888379/?hl=en) menjelaskan bahwa memperbarui kode sumber dengan metode apa pun selain mekanisme pembaruan Google Play dibatasi Namun pembatasan ini tidak berlaku untuk memperbarui bundle javascript > Pembatasan ini tidak berlaku untuk kode yang berjalan di mesin virtual dan memiliki akses terbatas ke API Android (seperti JavaScript di webview atau browser) Itu sepenuhnya memperbolehkan Capacitor-updater karena hanya memperbarui bundle JS dan tidak akan memperbarui kode native ### App Store Paragraf **332**, sejak tahun 2015 [Perjanjian Lisensi Program Pengembang Apple](https://developer.apple.com/programs/ios/information/) sepenuhnya mengizinkan melakukan pembaruan over-the-air untuk JavaScript dan aset - dan dalam versi terbarunya (20170605) [dapat diunduh di sini](https://developer.apple.com/terms/) aturan ini bahkan lebih luas: > Kode yang diinterpretasikan dapat diunduh ke Aplikasi tetapi hanya selama kode tersebut: (a) tidak mengubah tujuan utama Aplikasi dengan menyediakan fitur atau fungsionalitas yang tidak konsisten dengan tujuan yang dimaksudkan dan diiklankan dari Aplikasi sebagaimana yang diserahkan ke App Store, (b) tidak membuat toko atau storefront untuk kode atau aplikasi lain, dan (c) tidak memotong penandatanganan, sandbox, atau fitur keamanan lain dari OS Capacitor-updater memungkinkan Anda mengikuti aturan-aturan ini dengan kepatuhan penuh selama pembaruan yang Anda dorong tidak secara signifikan menyimpang dari tujuan awal produk Anda yang disetujui App Store Untuk tetap mematuhi pedoman Apple, kami menyarankan agar aplikasi yang didistribusikan App Store tidak mengaktifkan skenario ‘Pembaruan paksa’, karena dalam [Pedoman Peninjauan App Store](https://developer.apple.com/app-store/review/guidelines/) menyatakan bahwa: > Aplikasi tidak boleh memaksa pengguna untuk menilai aplikasi, mengulas aplikasi, mengunduh aplikasi lain, atau tindakan serupa lainnya untuk mengakses fungsionalitas, konten, atau penggunaan aplikasi Ini bukan masalah untuk perilaku default pembaruan latar belakang, karena tidak akan memaksa pengguna untuk menerapkan versi baru sampai mereka menutup aplikasi lain kali, tetapi setidaknya Anda harus mengetahui peran itu jika Anda memutuskan untuk menampilkannya ## Open source Plugin ini berada di bawah Lisensi LGPL-30 dan back-end berada di bawah Lisensi AGPL-30 > 💡 LGPL-30 berarti jika seseorang memodifikasi kode plugin, wajib untuk mempublikasikannya, dalam open-source dengan lisensi yang sama Jika Anda menggunakan kode tanpa modifikasi, itu tidak menyangkut Anda Lihat masalah di bawah untuk detail lebih lanjut klik tautan 👇 [Lisensi? ](https://github.com/Cap-go/capacitor-updater/issues/7) [Coba GPTS Capgo untuk Mendapatkan bantuan daripada membaca dokumen ](https://chatopenaicom/g/g-3dMwHbF2w-capgo-doc-gpt) > Anda dapat menyertakannya dalam aplikasi Anda tanpa khawatir ## Catatan Akhir Jika Anda self-host dan merasa alat ini berguna, silakan pertimbangkan untuk mendukung pekerjaan saya dengan menjadi [sponsor GitHub](https://github.com/sponsors/riderx/) Saya membuat taruhan untuk open-source semua kode yang saya bangun di sini alih-alih memasang paywall Dengan membukanya alih-alih melawan dan menyembunyikan, saya percaya kita dapat membuat dunia menjadi tempat yang lebih baik Untuk mewujudkan ini, kita semua perlu melakukan bagian kita, termasuk Anda 🥹 Jika Capgo cloud tidak memenuhi kebutuhan Anda, Anda dapat mendukung Maker bootstrapped [di sini](https://github.com/sponsors/riderx/) dengan syarat Anda sendiri ## Matematika Sederhana Harga paket dasar: $14\*12 = $168 setahun Sementara rata-rata dev/jam = $60 Itu berarti bahwa 3 jam terbuang waktu dev pada self-host memungkinkan Anda membayar untuk seluruh tahun, jika Anda menghabiskan lebih dari 3 jam Anda kehilangan uang ^^ # Pemecahan Masalah Berikut adalah beberapa masalah umum yang mungkin Anda temui saat menggunakan Capgo dan cara mengatasinya ### Kegagalan upload Jika upload bundle Anda gagal, periksa kembali: * ID aplikasi di `capacitor.config.ts` sesuai dengan aplikasi Anda di dashboard Capgo * Anda menjalankan perintah upload dari root proyek Capacitor Anda * Asset web Anda sudah di-build dan terbaru #### Opsi upload lanjutan CLI Capgo menyediakan beberapa flag tambahan untuk membantu masalah upload yang umum: * `--tus`: Menggunakan [protokol upload yang dapat dilanjutkan tus](https://tus.io/) untuk upload bundle besar atau koneksi jaringan yang buruk yang lebih handal. Jika bundle Anda lebih dari 10MB atau Anda memiliki koneksi yang tidak stabil, pertimbangkan menggunakan `--tus`: ```shell npx @capgo/cli@latest bundle upload --tus ``` * `--package-json` dan `--node-modules`: Memberi tahu Capgo di mana menemukan root `package.json` dan `node_modules` jika aplikasi Anda menggunakan struktur non-standar seperti monorepo atau workspace npm. Berikan path ke root `package.json` dan path `--node_modules`: ```shell npx @capgo/cli@latest bundle upload --package-json=path/to/package.json --node_modules=path/to/node_modules ``` Capgo membutuhkan informasi ini untuk membundle dependensi aplikasi Anda dengan benar Anda dapat menggabungkan flag-flag ini dengan opsi lain seperti `--channel` sesuai kebutuhan. Lihat [dokumentasi CLI Capgo](/docs/cli/overview/) untuk detail lengkap tentang opsi upload yang tersedia Jika Anda masih mengalami masalah dengan upload, hubungi [dukungan Capgo](https://support.capgo.app) untuk bantuan lebih lanjut ### Debug Update Jika Anda mengalami masalah dengan pembaruan langsung, perintah debug Capgo adalah alat yang membantu untuk troubleshooting. Cara menggunakannya: 1. Jalankan perintah berikut di direktori proyek Anda: ```shell npx @capgo/cli@latest app debug ``` 2. Jalankan aplikasi Anda di perangkat atau emulator dan lakukan tindakan yang seharusnya memicu pembaruan (misal membuka kembali aplikasi setelah mengunggah bundle baru) 3. Perhatikan output dari perintah debug. Ini akan mencatat informasi tentang proses pembaruan, termasuk: * Ketika aplikasi memeriksa pembaruan * Jika pembaruan ditemukan dan versi apa * Progres unduhan dan instalasi pembaruan * Kesalahan yang terjadi selama proses pembaruan 4. Gunakan log debug untuk mengidentifikasi di mana masalah terjadi. Contohnya: * Jika tidak ada pembaruan yang ditemukan, periksa kembali apakah bundle Anda berhasil diunggah dan aplikasi dikonfigurasi untuk menggunakan channel yang benar * Jika pembaruan terunduh tapi tidak terinstal, pastikan Anda telah memanggil `CapacitorUpdater.notifyAppReady()` dan aplikasi benar-benar ditutup dan dibuka kembali * Jika Anda melihat pesan error, cari error tersebut di dokumentasi Capgo atau hubungi dukungan untuk bantuan Perintah debug sangat berguna untuk mengidentifikasi masalah dengan proses unduhan dan instalasi pembaruan. Jika log menunjukkan versi pembaruan yang diharapkan ditemukan tetapi akhirnya tidak diterapkan, fokuskan troubleshooting Anda pada langkah-langkah setelah unduhan ### Debug dengan Log Native Selain perintah debug Capgo, log native di Android dan iOS dapat memberikan informasi troubleshooting yang berharga, terutama untuk masalah di sisi native dari proses pembaruan #### Log Android Untuk mengakses log Android: 1. Hubungkan perangkat Anda atau mulai emulator 2. Buka Android Studio dan pilih “View > Tool Windows > Logcat” 3. Di jendela Logcat, filter log ke proses aplikasi Anda dengan memilihnya dari dropdown di atas 4. Cari baris yang menyertakan `Capgo` untuk menemukan log SDK Atau, Anda dapat menggunakan perintah `adb logcat` dan grep untuk `Capgo` untuk memfilter log SDK Capgo akan mencatat kejadian-kejadian penting selama proses pembaruan, seperti: * Ketika pemeriksaan pembaruan dimulai * Jika pembaruan ditemukan dan versi apa * Ketika unduhan pembaruan dimulai dan selesai * Ketika instalasi pembaruan dipicu * Kesalahan yang terjadi selama langkah pembaruan native Masalah khusus Android yang mungkin Anda lihat di log termasuk: * Masalah konektivitas jaringan yang mencegah unduhan pembaruan * Error izin file saat menyimpan atau membaca bundle pembaruan * Ruang penyimpanan tidak cukup untuk bundle pembaruan * Kegagalan memulai ulang aplikasi setelah pembaruan diinstal #### Log iOS Untuk mengakses log iOS: 1. Hubungkan perangkat Anda atau mulai simulator 2. Buka Xcode dan pergi ke “Window > Devices and Simulators” 3. Pilih perangkat Anda dan klik “Open Console” 4. Di output konsol, cari baris yang menyertakan `Capgo` untuk menemukan log SDK Anda juga dapat menggunakan perintah `log stream` di terminal dan grep untuk `Capgo` untuk memfilter log Mirip dengan Android, SDK Capgo akan mencatat kejadian-kejadian penting di sisi iOS: * Inisiasi dan hasil pemeriksaan pembaruan * Mulai, progres, dan selesainya unduhan * Pemicu dan hasil instalasi * Kesalahan selama proses pembaruan native Masalah khusus iOS yang dapat Anda identifikasi dalam log termasuk: * Masalah sertifikat SSL saat mengunduh pembaruan * App transport security memblokir unduhan pembaruan * Ruang penyimpanan tidak cukup untuk bundle pembaruan * Kegagalan untuk mengekstrak atau menerapkan bundle pembaruan dengan benar Pada kedua platform, log native memberikan tampilan proses pembaruan yang lebih detail, dengan rincian lebih lanjut tentang implementasi native. Log ini sangat berguna untuk mengidentifikasi masalah yang terjadi di luar lapisan JavaScript Capgo Saat troubleshooting masalah pembaruan langsung yang rumit, sebaiknya mengambil log debug Capgo dan log native untuk gambaran komprehensif tentang apa yang terjadi. Kedua log bersama akan memberi Anda peluang terbaik untuk mengidentifikasi dan menyelesaikan masalah ### Pembaruan tidak diterapkan Jika Anda telah mengunggah bundle tetapi tidak melihat perubahan di perangkat Anda: * Pastikan Anda telah memanggil `CapacitorUpdater.notifyAppReady()` dalam kode aplikasi Anda seperti yang ditunjukkan di [quickstart](/docs/getting-started/quickstart) * Periksa bahwa perangkat Anda terhubung ke internet dan log debug Capgo menunjukkan pembaruan telah diunduh * Coba tutup sepenuhnya dan buka kembali aplikasi, karena pembaruan hanya diterapkan saat peluncuran baru * Cari error di log native yang mungkin menunjukkan masalah dalam menerapkan pembaruan Lihat panduan [menerapkan pembaruan langsung](/docs/getting-started/deploy) untuk detail lebih lanjut tentang proses pembaruan. Jika Anda masih mengalami kesulitan, gunakan perintah `npx @capgo/cli@latest app debug` dan log native untuk mendapatkan visibilitas lebih tentang apa yang terjadi ## Instalasi SDK Jika Anda mengalami masalah menginstal SDK Capgo, pastikan: * Aplikasi Anda menggunakan versi Capacitor yang didukung (4.0 atau lebih baru) * Anda telah mengikuti langkah-langkah [quickstart](/docs/getting-started/quickstart) secara berurutan, termasuk sinkronisasi aplikasi Anda setelah menginstal SDK ## Integrasi CI/CD Untuk masalah dengan memicu upload Capgo dari pipeline CI/CD Anda: * Periksa kembali token autentikasi Capgo Anda telah diatur dengan benar * Pastikan Anda menjalankan perintah upload setelah asset web Anda di-build * Periksa bahwa perintah upload menggunakan nama channel yang benar untuk environment target Anda Lihat dokumentasi [integrasi CI/CD](/docs/getting-started/cicd-integration) untuk tips troubleshooting lebih lanjut. Anda juga dapat menggunakan perintah `npx @capgo/cli@latest app debug` untuk mengkonfirmasi apakah pembaruan yang dipicu CI/CD diterima oleh aplikasi # Cara Melakukan > Cara menggunakan Capgo, tutorial, trik dan tips [Bagaimana versi bekerja di Capgo ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [Cara merilis versi major di Capgo ](https://capgo.app/blog/how-to-release-major-version-in-capgo/)capgo.app [Cara mengirim pembaruan spesifik ke satu pengguna atau grup ](https://capgo.app/blog/how-to-send-specific-version-to-users/)capgo.app ## CI / CD [Build dan rilis otomatis dengan GitHub Actions ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [Mengelola build pengembangan dan produksi dengan GitHub Actions ](https://capgo.app/blog/automatic-build-and-release-with-github-actions/)capgo.app ## Berkontribusi [Berkontribusi pada open source Capgo ](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTINGmd)githubcom # Gambaran Umum Gunakan fitur Live Updates Capgo untuk memperbarui bundel JavaScript aplikasi Anda secara jarak jauh dan real-time. Kirim pembaruan JS langsung ke pengguna Anda tanpa melalui proses review app store untuk segera memperbaiki bug dan mengirim fitur baru. Note Live Updates terbatas pada perubahan bundel JavaScript. Jika Anda perlu memperbarui kode native, seperti menambah atau menghapus plugin atau mengubah konfigurasi proyek native, Anda perlu mengirimkan build binary native baru ke app store. ## Cara Kerja Live Updates Sistem Live Update Capgo memiliki dua komponen utama: 1. SDK Capgo, yang Anda instal di aplikasi Anda. SDK memeriksa pembaruan yang tersedia dan mengunduhnya di latar belakang. 2. Channel, yang memungkinkan Anda menargetkan pembaruan ke grup pengguna tertentu. Anda dapat menggunakan channel untuk mengelola jalur rilis yang berbeda, seperti `Production`, `Staging`, dan `Dev`. Ketika Anda mengunggah bundel JS baru ke Capgo dan menetapkannya ke channel, SDK Capgo di aplikasi yang dikonfigurasi untuk channel tersebut akan mendeteksi pembaruan dan mengunduhnya. Saat aplikasi dimulai ulang berikutnya, bundel baru akan dimuat. ## Memulai Untuk mulai menggunakan Live Updates, ikuti langkah-langkah berikut: 1. Selesaikan [Capgo Quickstart](/docs/getting-started/quickstart) untuk menyiapkan aplikasi Anda di Capgo dan menginstal SDK Capgo 2. Dalam kode aplikasi Anda, panggil `CapacitorUpdaternotifyAppReady()` setelah aplikasi Anda selesai diinisialisasi. Ini memberi tahu SDK Capgo bahwa aplikasi Anda siap menerima pembaruan 3. Build bundel JS Anda dan unggah ke Capgo: ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. Buka aplikasi Anda dan tunggu pembaruan diunduh. Anda dapat memeriksa statusnya dengan: ```shell npx @capgo/cli@latest app debug ``` 5. Setelah pembaruan diunduh, tutup dan buka kembali aplikasi Anda untuk memuat bundel baru Lihat panduan [Deploying Live Updates](/docs/getting-started/deploy) untuk detail lebih lanjut ## Langkah Selanjutnya [ Channel](/docs/live-updates/channels/) [Pelajari cara menggunakan channel untuk mengelola jalur rilis yang berbeda dan menargetkan pembaruan ke pengguna tertentu](/docs/live-updates/channels/) [ Rollback](/docs/live-updates/rollbacks/) [Temukan cara kembali ke versi bundel JS sebelumnya jika pembaruan menyebabkan masalah](/docs/live-updates/rollbacks/) [ Perilaku Pembaruan](/docs/live-updates/update-behavior/) [Sesuaikan bagaimana dan kapan pembaruan diunduh dan diterapkan di aplikasi Anda](/docs/live-updates/update-behavior/) [ Pembaruan Cepat](/docs/live-updates/differentials/) [Pelajari cara menggunakan pembaruan cepat untuk mempercepat proses pembaruan](/docs/live-updates/differentials/) # Saluran Channel Live Update mengarah ke build bundle JS tertentu dari aplikasi Anda yang akan dibagikan dengan perangkat yang dikonfigurasi untuk mendengarkan channel tersebut untuk pembaruan. Ketika Anda [menginstal Capgo Live Updates SDK](/docs/getting-started/quickstart/) di aplikasi Anda, setiap binary native yang dikonfigurasi ke channel tersebut akan memeriksa pembaruan yang tersedia setiap kali aplikasi diluncurkan. Anda dapat mengubah build yang ditunjuk channel kapan saja dan juga dapat kembali ke build sebelumnya jika diperlukan. ## Menyiapkan Channel Setiap aplikasi dilengkapi dengan channel default bernama “Production” yang tidak dapat dihapus. Untuk menambahkan channel baru: 1. Buka bagian “Channels” di dashboard Capgo 2. Klik tombol “New Channel” 3. Masukkan nama untuk channel dan klik “Create” Nama channel bisa apa saja yang Anda inginkan. Strategi yang umum adalah menyesuaikan channel dengan tahap pengembangan Anda, seperti: * `Development` - untuk menguji live update di perangkat lokal atau emulator * `QA` - untuk tim QA Anda memverifikasi pembaruan sebelum rilis yang lebih luas * `Staging` - untuk pengujian akhir di lingkungan seperti produksi * `Production` - untuk versi aplikasi Anda yang diterima pengguna akhir dari app store ## Mengkonfigurasi Channel di Aplikasi Anda Dengan channel Anda yang telah dibuat, Anda perlu mengkonfigurasi aplikasi untuk mendengarkan channel yang sesuai. Dalam contoh ini, kita akan menggunakan channel `Development` Buka file `capacitor.config.ts` (atau `capacitor.config.json`) Anda. Di bagian `plugins`, atur properti `channel` dari plugin `CapacitorUpdater` ke nama channel yang Anda inginkan: ```ts import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { defaultChannel: 'Development', }, }, }; ``` Selanjutnya, build aplikasi web Anda dan jalankan `npx cap sync` untuk menyalin file konfigurasi yang diperbarui ke proyek iOS dan Android Anda. Jika Anda melewatkan langkah sinkronisasi ini, proyek native Anda akan terus menggunakan channel yang sebelumnya dikonfigurasi. Caution Properti `defaultChannel` akan selalu menimpa channel default cloud. Tapi Anda masih dapat memaksa deviceId ke channel di Cloud ## Menetapkan Bundle ke Channel Untuk menerapkan live update, Anda perlu mengunggah build bundle JS baru dan menetapkannya ke channel. Anda dapat melakukan ini dalam satu langkah dengan Capgo CLI: ```shell npx @capgo/cli@latest bundle upload --channel=Development ``` Ini akan mengunggah aset web yang telah di-build dan menetapkan bundle baru sebagai build aktif untuk channel `Development`. Setiap aplikasi yang dikonfigurasi untuk mendengarkan channel tersebut akan menerima pembaruan saat mereka memeriksa pembaruan berikutnya. Anda juga dapat menetapkan build ke channel dari bagian “Bundles” di dashboard Capgo. Klik ikon menu di sebelah build dan pilih “Assign to Channel” untuk memilih channel untuk build tersebut. ## Versi Bundle dan Channel Penting untuk dicatat bahwa bundle di Capgo bersifat global untuk aplikasi Anda, tidak spesifik untuk channel individual. Bundle yang sama dapat ditetapkan ke beberapa channel. Saat memversikan bundle Anda, kami merekomendasikan menggunakan semantic versioning [semver](https://semver.org/) dengan pengidentifikasi pre-release untuk build khusus channel. Misalnya, rilis beta mungkin diversion sebagai `123-beta1`. Pendekatan ini memiliki beberapa keuntungan: * Dengan jelas mengkomunikasikan hubungan antara build. `123-beta1` jelas merupakan pre-release dari `123` * Memungkinkan penggunaan kembali nomor versi di beberapa channel, mengurangi kebingungan * Memungkinkan jalur rollback yang jelas. Jika Anda perlu melakukan rollback dari `123`, Anda tahu `122` adalah rilis stabil sebelumnya Berikut contoh bagaimana Anda mungkin menyelaraskan versi bundle Anda dengan pengaturan channel yang umum: * Channel `Development`: `123-dev1`, `123-dev2`, dll * Channel `QA`: `123-qa1`, `123-qa2`, dll * Channel `Staging`: `123-rc1`, `123-rc2`, dll * Channel `Production`: `123`, `124`, dll Menggunakan semver dengan pengidentifikasi pre-release adalah pendekatan yang direkomendasikan, tetapi tidak wajib. Yang terpenting adalah menemukan skema versioning yang dengan jelas mengkomunikasikan hubungan antara build Anda dan selaras dengan proses pengembangan tim Anda. ## Melakukan Rollback Live Update Jika Anda menerapkan live update yang memperkenalkan bug atau perlu dikembalikan karena alasan lain, Anda dapat dengan mudah kembali ke build sebelumnya. Dari bagian “Channels” di dashboard: 1. Klik nama channel yang ingin Anda rollback 2. Temukan build yang ingin Anda kembalikan dan klik ikon mahkota ![Rollback build](/select_bundle.webp) 3. Konfirmasi tindakan Build yang dipilih akan segera menjadi build aktif untuk channel tersebut lagi. Aplikasi akan menerima versi yang di-rollback saat mereka memeriksa pembaruan berikutnya. ## Mengotomatisasi Deployment Untuk alur kerja yang lebih canggih, Anda dapat mengotomatisasi deployment live update Anda sebagai bagian dari pipeline CI/CD Anda. Dengan mengintegrasikan Capgo ke dalam proses build Anda, Anda dapat secara otomatis mengunggah bundle baru dan menetapkannya ke channel setiap kali Anda push ke branch tertentu atau membuat rilis baru. Lihat dokumen [Integrasi CI/CD](/docs/getting-started/cicd-integration/) untuk mempelajari lebih lanjut tentang mengotomatisasi live update Capgo. ## Menerapkan ke Perangkat Sekarang setelah Anda memahami channel, Anda siap untuk mulai menerapkan live update ke perangkat nyata. Proses dasarnya adalah: 1. Instal SDK Capgo di aplikasi Anda 2. Konfigurasi aplikasi untuk mendengarkan channel yang Anda inginkan 3. Unggah build dan tetapkan ke channel tersebut 4. Luncurkan aplikasi dan tunggu pembaruannya! Untuk panduan yang lebih detail, lihat panduan [Menerapkan Live Update](/docs/getting-started/deploy/). Selamat memperbarui! # Update cepat Sistem Live Update Capgo dapat mengirimkan pembaruan lebih cepat dan lebih efisien dengan hanya mengirim file yang berubah, bukan seluruh bundle JS Ini sangat bermanfaat bagi pengguna dengan koneksi jaringan yang lebih lambat atau terbatas, karena meminimalkan jumlah data yang perlu diunduh Manfaat kedua adalah ketika aplikasi memiliki aset besar yang jarang berubah, seperti gambar atau video, dibandingkan dengan file JS terkompresi yang hanya akan diunduh sekali ## Cara Kerja Pembaruan Diferensial Pembaruan diferensial di Capgo ditangani oleh plugin Capgo yang terpasang di aplikasi Anda. Saat Anda mengunggah versi baru aplikasi menggunakan flag `--partial`, Capgo melakukan hal berikut: 1. Setiap file dalam build Anda diunggah secara individual 2. Checksum dibuat untuk setiap file 3. Manifest json baru dibuat, mendaftar semua file dan checksumnya 4. Manifest ini diunggah ke database Capgo Ketika perangkat yang menjalankan aplikasi Anda memeriksa pembaruan, plugin Capgo menerima manifest baru dari server. Ia membandingkan manifest ini dengan yang dimilikinya saat ini, mengidentifikasi file mana yang telah berubah berdasarkan checksum dan jalur file Plugin kemudian hanya mengunduh file yang berubah, bukan seluruh bundle JS. Ia merekonstruksi versi baru aplikasi dengan menggabungkan file yang diunduh dengan file yang tidak berubah yang sudah dimilikinya Manifest Dalam kasus pembaruan diferensial, perangkat menyimpan semua file yang diunduh dalam cache umum, Capgo tidak akan pernah membersihkannya tetapi OS dapat melakukannya kapan saja ## Mengaktifkan Pembaruan Diferensial Untuk mengaktifkan pembaruan diferensial untuk aplikasi Capgo Anda, cukup gunakan flag `--partial` saat mengunggah versi baru: ## Menegakkan Pembaruan Diferensial Jika Anda ingin memastikan bahwa semua unggahan adalah pembaruan diferensial dan mencegah unggahan bundle penuh yang tidak disengaja, Anda dapat menggunakan flag `--partial-only`: ```shell npx @capgo/cli@latest bundle upload --partial-only ``` Ketika `--partial-only` digunakan, Capgo hanya akan mengunggah file individual dan menghasilkan manifest. Perangkat yang tidak mendukung partial tidak akan dapat mengunduh pembaruan Anda mungkin ingin menggunakan `--partial-only` jika: * Anda selalu ingin menggunakan pembaruan diferensial dan tidak pernah ingin mengizinkan unggahan bundle penuh * Anda sedang menyiapkan pipeline CI/CD dan ingin memastikan semua unggahan otomatis bersifat diferensial * Aplikasi Anda besar dan bandwidth terbatas, sehingga Anda perlu meminimalkan ukuran unggah/unduh Jika Anda perlu melakukan unggahan bundle penuh saat `--partial-only` diatur, cukup jalankan perintah unggah tanpa `--partial-only`. Ini akan menimpa pengaturan untuk unggahan tunggal tersebut, memungkinkan Anda untuk mendorong bundle lengkap saat diperlukan ## Pemecahan Masalah Jika pembaruan diferensial tidak tampak berfungsi (yaitu perangkat selalu mengunduh bundle JS penuh bahkan untuk perubahan kecil), periksa kembali bahwa: * Anda menggunakan flag `--partial` setiap kali mengunggah versi baru * Jika menggunakan `--partial-only`, pastikan Anda tidak secara tidak sengaja menghilangkan flag `--partial` * Perangkat Anda menjalankan versi terbaru plugin Capgo * Perangkat Anda memiliki koneksi jaringan yang stabil dan dapat mencapai server Capgo Anda juga dapat menggunakan webapp Capgo untuk memeriksa detail unggahan terakhir Anda: 1. Buka [webapp](https://app.capgo.io) 2. Klik pada aplikasi Anda 3. Klik pada jumlah bundles di bar statistik 4. Pilih bundle terakhir 5. Periksa kolom `Partial` ![bundle type](/bundle_type.webp) Jika Anda terus mengalami masalah, silakan hubungi dukungan Capgo untuk bantuan lebih lanjut. Mereka dapat memeriksa log server untuk memastikan bahwa unggahan parsial Anda diproses dengan benar dan perangkat menerima manifest yang diperbarui Itu saja! Flag `--partial` memberi tahu Capgo untuk melakukan unggahan file individual dan pembuatan manifest yang diperlukan untuk pembaruan diferensial Perhatikan bahwa Anda perlu menggunakan `--partial` setiap kali Anda mengunggah versi baru yang ingin Anda kirimkan sebagai pembaruan diferensial. Jika Anda menghilangkan flag, Capgo akan mengunggah seluruh bundle JS sebagai satu file, dan perangkat akan mengunduh seluruh bundle bahkan jika hanya sebagian kecil yang berubah # Rollback Meskipun pembaruan langsung Capgo memungkinkan Anda untuk dengan cepat memberikan peningkatan dan perbaikan kepada pengguna, mungkin ada situasi di mana Anda perlu kembali ke versi sebelumnya dari aplikasi Anda. Mungkin pembaruan baru memunculkan masalah kritis yang tidak terduga, atau mungkin Anda ingin mengembalikan perubahan tertentu sambil mengerjakan perbaikan. Capgo menyediakan beberapa cara untuk mengelola build channel dan mengontrol versi aplikasi yang diterima pengguna. ## Kembali ke Bundle Sebelumnya Setiap kali Anda mengunggah build baru dan menetapkannya ke channel, Capgo menyimpan riwayat build tersebut. Jika Anda perlu mengembalikan pembaruan tertentu, Anda dapat memilih salah satu build sebelumnya untuk dideploy ulang ke channel. Untuk kembali ke build sebelumnya: 1. Masuk ke [Capgo Dashboard](https://app.capgo.io) 2. Navigasi ke bagian “Channels” 3. Klik nama channel yang ingin Anda kembalikan 4. Temukan build yang ingin Anda kembalikan di riwayat build channel 5. Klik ikon mahkota di sebelah build tersebut untuk menjadikannya build aktif untuk channel ![Channel management options](/select_bundle.webp) 6. Konfirmasi bahwa Anda ingin kembali ke build ini Note Kembali ke build sebelumnya hanya mempengaruhi channel yang dipilih. Jika Anda memiliki beberapa channel (misalnya Production, Staging, dll), Anda perlu mengulangi proses pengembalian untuk setiap channel yang terdampak. Setelah kembali, perangkat yang dikonfigurasi untuk mendengarkan channel yang diperbarui akan menerima build sebelumnya saat mereka memeriksa pembaruan berikutnya. Build yang dikembalikan akan diperlakukan sebagai pembaruan baru, sehingga alur dan kondisi pembaruan biasa berlaku. ## Memutuskan Tautan Channel Jika Anda ingin menghentikan sementara pembaruan pada channel saat menyelidiki masalah, Anda dapat memutuskan tautan channel dari build saat ini. Untuk memutuskan tautan channel: 1. Navigasi ke channel di Capgo Dashboard 2. Klik tombol “Unlink” di sebelah build saat ini 3. Konfirmasi bahwa Anda ingin memutuskan tautan channel Setelah channel diputus tautannya, tidak akan mendistribusikan pembaruan baru. Perangkat yang dikonfigurasi ke channel tersebut akan tetap pada build mereka saat ini sampai channel ditautkan kembali ke build. Ini berguna jika Anda telah mengidentifikasi masalah dengan pembaruan tetapi belum yakin build mana yang ingin Anda kembalikan. Memutuskan tautan channel memberi Anda waktu untuk menyelidiki tanpa mengirimkan pembaruan lebih lanjut. ## Memaksakan Bundle Bawaan Dalam situasi yang lebih serius, Anda mungkin ingin mengembalikan semua perangkat pada channel kembali ke build web yang awalnya dikemas dengan binary native aplikasi Anda. Ini dikenal sebagai “bundle bawaan”. Untuk memaksakan bundle bawaan pada channel: 1. Navigasi ke channel di Capgo Dashboard 2. Klik tombol “Built-in Bundle” 3. Konfirmasi bahwa Anda ingin memaksakan bundle bawaan Ketika Anda memaksakan bundle bawaan, semua perangkat yang dikonfigurasi ke channel tersebut akan kembali ke build web kemasan asli pada pemeriksaan pembaruan berikutnya. Ini terjadi terlepas dari build mana yang sedang mereka gunakan. Ini adalah opsi pengembalian yang lebih agresif daripada kembali ke build sebelumnya tertentu, karena menghapus semua pembaruan langsung yang dirilis sejak aplikasi terakhir diterbitkan ke app store. Caution Berhati-hatilah saat memaksakan bundle bawaan, karena akan mempengaruhi semua perangkat pada channel. Pastikan Anda telah mempertimbangkan dampaknya dan memiliki rencana untuk melanjutkan sebelum mengambil tindakan ini. ## Memantau dan Menanggapi Masalah Untuk menangkap masalah dengan cepat dan meminimalkan dampak pembaruan bermasalah, penting untuk memiliki rencana untuk memantau rilis Anda dan menanggapi masalah. Beberapa strategi meliputi: * Memantau laporan crash dan umpan balik pengguna segera setelah merilis pembaruan * Menggunakan peluncuran bertahap atau sistem channel bertahap untuk menguji pembaruan pada kelompok yang lebih kecil sebelum rilis luas * Memiliki proses keputusan yang jelas untuk kapan harus kembali, memutuskan tautan, atau memaksakan bundle bawaan, dan siapa yang memiliki wewenang untuk melakukannya * Berkomunikasi dengan pengguna tentang masalah dan penyelesaiannya, jika sesuai Dengan menggabungkan pemantauan yang cermat dengan kemampuan untuk dengan cepat mengelola pembaruan bermasalah, Anda dapat memberikan pengalaman aplikasi yang terus meningkat sambil meminimalkan gangguan bagi pengguna Anda. # Perilaku Pembaruan Ketika Anda merilis pembaruan untuk aplikasi Capgo, Anda mungkin ingin pengguna menerima pembaruan tersebut secepat mungkin. Namun Anda juga tidak ingin mengganggu pengalaman mereka dengan memaksa menunggu unduhan atau memulai ulang aplikasi di tengah sesi. Perilaku pembaruan Capgo dirancang untuk menyeimbangkan antara memberikan pembaruan dengan cepat dan meminimalkan gangguan bagi pengguna Anda. ## Alur Pembaruan Default Secara default, berikut cara Capgo menangani pembaruan aplikasi: 1. Saat aplikasi diluncurkan, plugin Capgo memeriksa apakah ada pembaruan baru yang tersedia 2. Jika ditemukan pembaruan, pembaruan akan diunduh di latar belakang sementara pengguna terus menggunakan versi saat ini dari aplikasi 3. Setelah unduhan selesai, Capgo menunggu pengguna menutup aplikasi ke latar belakang atau menutupnya sepenuhnya 4. Ketika pengguna membuka aplikasi berikutnya, mereka akan menjalankan versi yang diperbarui Alur ini memastikan pengguna selalu menjalankan versi terbaru dari aplikasi Anda, tanpa pernah terganggu oleh permintaan pembaruan atau dipaksa menunggu unduhan. Tip Capgo juga memeriksa pembaruan ketika aplikasi dilanjutkan dari latar belakang, sehingga pengguna akan menerima pembaruan bahkan jika mereka tidak sepenuhnya menutup aplikasi ## Mengapa Pendekatan Ini? Menerapkan pembaruan pada saat latar belakang atau penutupan memiliki beberapa manfaat utama untuk pengalaman pengguna: * Pengguna tidak terganggu oleh permintaan pembaruan atau dipaksa menunggu unduhan di tengah sesi * Pembaruan diterapkan dengan mulus di antara sesi, sehingga pengalaman membuka aplikasi selalu baru * Anda dapat memberikan pembaruan secara sering tanpa khawatir mengganggu pengguna aktif Kerugian utamanya adalah jika pengguna menutup ke latar belakang dan dengan cepat melanjutkan aplikasi Anda, mereka mungkin kehilangan status yang belum disimpan karena pembaruan diterapkan di antara tindakan tersebut Untuk mengurangi hal ini, kami merekomendasikan: * Menyimpan status secara sering dan memulihkannya dengan baik ketika aplikasi dilanjutkan * Menghindari pembaruan yang sangat sering yang memodifikasi sebagian besar status aplikasi * Mempertimbangkan untuk menyesuaikan perilaku pembaruan untuk alur yang sensitif (lihat di bawah) ## Menyesuaikan Kapan Pembaruan Diterapkan Dalam beberapa kasus, Anda mungkin ingin lebih mengontrol kapan tepatnya pembaruan diterapkan. Misalnya, Anda mungkin ingin memastikan pengguna menyelesaikan alur yang sedang berlangsung sebelum memperbarui, atau mengoordinasikan pembaruan aplikasi dengan perubahan sisi server. Capgo menyediakan fungsi `setDelay` yang memungkinkan Anda menentukan kondisi yang harus dipenuhi sebelum pembaruan diinstal: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; await CapacitorUpdatersetMultiDelay({ delayConditions: [ { kind: 'date', value: '2023-06-01T00:00:00000Z', }, { kind: 'background', value: '60000', }, ], }); ``` Contoh ini akan menunda penginstalan pembaruan sampai setelah 1 Juni 2023 DAN aplikasi telah berada di latar belakang setidaknya 60 detik. Kondisi penundaan yang tersedia adalah: * `date`: Tunggu sampai setelah tanggal/waktu tertentu untuk menerapkan pembaruan * `background`: Tunggu durasi minimum setelah aplikasi berada di latar belakang untuk menerapkan pembaruan * `nativeVersion`: Tunggu hingga binary native dengan versi minimum terpasang sebelum menerapkan pembaruan * `kill`: Tunggu sampai event penutupan aplikasi berikutnya untuk menerapkan pembaruan Anda dapat menggabungkan kondisi-kondisi ini untuk mengontrol secara tepat kapan pembaruan diinstal Danger Perhatikan bahwa kondisi `kill` saat ini memicu pembaruan setelah event penutupan pertama, bukan event latar belakang berikutnya seperti kondisi lainnya. Ketidakkonsistenan ini akan diperbaiki dalam rilis mendatang ## Menerapkan Pembaruan Segera Untuk pembaruan kritis atau aplikasi dengan status yang sangat sederhana, Anda mungkin ingin menerapkan pembaruan segera setelah diunduh, tanpa menunggu event latar belakang atau penutupan. Capgo mendukung ini melalui opsi konfigurasi `directUpdate`. `directUpdate` diatur dalam file `capacitor.config.ts` Anda, bukan dalam kode JavaScript: ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: true, keepUrlPathAfterReload: true, }, }, }; export default config; ``` Dengan `directUpdate` diaktifkan, Capgo akan segera menerapkan pembaruan setelah unduhan selesai, bahkan jika pengguna sedang aktif menggunakan aplikasi. Perhatikan bahwa karena `directUpdate` adalah konfigurasi native, ini memerlukan penanganan tambahan dalam kode JavaScript Anda. Saat menggunakan `directUpdate`, Anda perlu mendengarkan event `appReady` dan menyembunyikan splash screen aplikasi Anda sebagai respons: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater'; import { SplashScreen } from '@capacitor/splash-screen'; CapacitorUpdater.addListener('appReady', () => { // Hide splash screen SplashScreen.hide(); }); CapacitorUpdater.notifyAppReady(); ``` Event `appReady` terpicu setelah aplikasi selesai menginisialisasi dan menerapkan pembaruan yang tertunda. Ini adalah saat yang tepat untuk menampilkan UI aplikasi Anda, karena memastikan pengguna akan melihat versi terbaru. Selain menangani event `appReady`, kami merekomendasikan mengatur opsi konfigurasi `keepUrlPathAfterReload` ke `true` saat menggunakan `directUpdate`. Ini mempertahankan path URL saat ini ketika aplikasi dimuat ulang karena pembaruan, membantu mempertahankan lokasi pengguna dalam aplikasi dan mengurangi disorientasi. Jika Anda tidak menangani event `appReady` dan mengatur `keepUrlPathAfterReload` saat menggunakan `directUpdate`, pengguna mungkin akan sekilas melihat versi lama aplikasi, kembali ke rute awal, atau melihat kedipan saat pembaruan diterapkan. Menggunakan `directUpdate` dapat berguna untuk memberikan perbaikan bug kritis atau patch keamanan, tetapi memiliki beberapa kelemahan: * Pengguna mungkin melihat kedipan atau status loading singkat saat pembaruan diterapkan jika Anda tidak menangani event `appReady` dengan benar * Jika pembaruan memodifikasi status atau UI aplikasi, pengguna mungkin melihat perubahan yang mengganggu di tengah sesi * Lokasi pengguna dalam aplikasi mungkin hilang jika `keepUrlPathAfterReload` tidak diatur, berpotensi membingungkan mereka * Anda perlu hati-hati menangani penyimpanan dan pemulihan status untuk memastikan transisi yang mulus Jika Anda mengaktifkan `directUpdate`, kami merekomendasikan: * Menangani event `appReady` untuk mengontrol kapan UI aplikasi Anda ditampilkan * Mengatur `keepUrlPathAfterReload` ke `true` untuk mempertahankan lokasi pengguna dalam aplikasi * Menyimpan dan memulihkan status aplikasi sesuai kebutuhan untuk menghindari kehilangan kemajuan pengguna * Menguji secara menyeluruh perilaku pembaruan aplikasi Anda untuk memastikan tidak ada transisi yang mengejutkan, status yang hilang, atau perubahan lokasi yang membingungkan Dalam kebanyakan kasus, perilaku pembaruan default memberikan keseimbangan terbaik antara memberikan pembaruan dengan cepat dan meminimalkan gangguan. Tetapi untuk aplikasi dengan kebutuhan khusus, Capgo memberikan fleksibilitas untuk menyesuaikan kapan dan bagaimana pembaruan diterapkan. # 기능 및 설정 > Semua metode dan konfigurasi plugin yang tersedia # Konfigurasi Plugin Updater Lihat [Readme](https://github.com/Cap-go/capacitor-updater) Github untuk informasi lebih lanjut CapacitorUpdater dapat dikonfigurasi dengan opsi berikut: | Prop | Type | Deskripsi | Default | Sejak | | ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | ----- | | **`appReadyTimeout`** | `number` | Mengatur jumlah milidetik plugin native harus menunggu sebelum menganggap pembaruan ‘gagal’ Hanya tersedia untuk Android dan iOS | `10000 // (10 detik)` | | | **`responseTimeout`** | `number` | Mengatur jumlah milidetik plugin native harus menunggu sebelum menganggap API timeout Hanya tersedia untuk Android dan iOS | `20 // (20 detik)` | | | **`autoDeleteFailed`** | `boolean` | Mengatur apakah plugin harus secara otomatis menghapus bundle yang gagal Hanya tersedia untuk Android dan iOS | `true` | | | **`autoDeletePrevious`** | `boolean` | Mengatur apakah plugin harus secara otomatis menghapus bundle sebelumnya setelah pembaruan berhasil Hanya tersedia untuk Android dan iOS | `true` | | | **`autoUpdate`** | `boolean` | Mengatur apakah plugin harus menggunakan Pembaruan Otomatis melalui server pembaruan Hanya tersedia untuk Android dan iOS | `true` | | | **`resetWhenUpdate`** | `boolean` | Secara otomatis menghapus bundle yang telah diunduh sebelumnya ketika bundle aplikasi native yang lebih baru diinstal ke perangkat Hanya tersedia untuk Android dan iOS | `true` | | | **`updateUrl`** | `string` | Mengatur URL / endpoint ke mana pemeriksaan pembaruan dikirim Hanya tersedia untuk Android dan iOS | `https://plugin.capgo.app/updates` | | | **`channelUrl`** | `string` | Mengatur URL / endpoint untuk operasi channel Hanya tersedia untuk Android dan iOS | `https://plugin.capgo.app/channel_self` | | | **`statsUrl`** | `string` | Mengatur URL / endpoint ke mana statistik pembaruan dikirim Hanya tersedia untuk Android dan iOS Atur ke "" untuk menonaktifkan pelaporan statistik | `https://plugin.capgo.app/stats` | | | **`privateKey`** | `string` | Mengatur kunci pribadi untuk enkripsi pembaruan langsung end to end Hanya tersedia untuk Android dan iOS Tidak digunakan lagi di versi 620 akan dihapus di versi 700 | `undefined` | | | **`publicKey`** | `string` | Mengatur kunci publik untuk enkripsi pembaruan langsung end to end Versi 2 Hanya tersedia untuk Android dan iOS | `undefined` | 620 | | **`version`** | `string` | Mengatur versi saat ini dari aplikasi Ini akan digunakan untuk permintaan pembaruan pertama Jika tidak diatur, plugin akan mendapatkan versi dari kode native Hanya untuk Android dan iOS | `undefined` | 41748 | | **`directUpdate`** | `boolean` | Membuat plugin langsung menginstal pembaruan ketika aplikasi baru saja diperbarui/diinstal Hanya untuk mode autoUpdate Hanya tersedia untuk Android dan iOS | `undefined` | 510 | | **`periodCheckDelay`** | `number` | Mengatur delay periode untuk pemeriksaan pembaruan berkala dalam satuan detik Hanya tersedia untuk Android dan iOS Tidak boleh kurang dari 600 detik (10 menit) | `600 // (10 menit)` | | | **`localS3`** | `boolean` | Mengatur CLI untuk menggunakan server lokal untuk pengujian atau server pembaruan self-hosted | `undefined` | 41748 | | **`localHost`** | `string` | Mengatur CLI untuk menggunakan server lokal untuk pengujian atau server pembaruan self-hosted | `undefined` | 41748 | | **`localWebHost`** | `string` | Mengatur CLI untuk menggunakan server lokal untuk pengujian atau server pembaruan self-hosted | `undefined` | 41748 | | **`localSupa`** | `string` | Mengatur CLI untuk menggunakan server lokal untuk pengujian atau server pembaruan self-hosted | `undefined` | 41748 | | **`localSupaAnon`** | `string` | Mengatur CLI untuk menggunakan server lokal untuk pengujian | `undefined` | 41748 | | **`localApi`** | `string` | Mengatur CLI untuk menggunakan api lokal untuk pengujian | `undefined` | 633 | | **`localApiFiles`** | `string` | Mengatur CLI untuk menggunakan api file lokal untuk pengujian | `undefined` | 633 | | **`allowModifyUrl`** | `boolean` | Mengizinkan plugin untuk memodifikasi updateUrl, statsUrl dan channelUrl secara dinamis dari sisi JavaScript | `false` | 540 | | **`defaultChannel`** | `string` | Mengatur channel default untuk aplikasi dalam konfigurasi | `undefined` | 550 | | **`appId`** | `string` | Mengkonfigurasi id aplikasi untuk aplikasi dalam konfigurasi | `undefined` | 600 | | **`keepUrlPathAfterReload`** | `boolean` | Mengkonfigurasi plugin untuk mempertahankan path URL setelah reload PERINGATAN: Ketika reload dipicu, ‘windowhistory’ akan dihapus | `false` | 680 | ## Contoh Dalam `capacitorconfigjson`: ```json { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 // (1 detik), "responseTimeout": 10 // (10 detik), "autoDeleteFailed": false, "autoDeletePrevious": false, "autoUpdate": false, "resetWhenUpdate": false, "updateUrl": https://examplecom/api/auto_update, "channelUrl": https://examplecom/api/channel, "statsUrl": https://examplecom/api/stats, "privateKey": undefined, "publicKey": undefined, "version": undefined, "directUpdate": undefined, "periodCheckDelay": undefined, "localS3": undefined, "localHost": undefined, "localWebHost": undefined, "localSupa": undefined, "localSupaAnon": undefined, "localApi": undefined, "localApiFiles": undefined, "allowModifyUrl": undefined, "defaultChannel": undefined, "appId": undefined, "keepUrlPathAfterReload": undefined } } } ``` Dalam `capacitorconfigts`: ```ts /// import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { appReadyTimeout: 1000 // (1 detik), responseTimeout: 10 // (10 detik), autoDeleteFailed: false, autoDeletePrevious: false, autoUpdate: false, resetWhenUpdate: false, updateUrl: https://examplecom/api/auto_update, channelUrl: https://examplecom/api/channel, statsUrl: https://examplecom/api/stats, privateKey: undefined, publicKey: undefined, version: undefined, directUpdate: undefined, periodCheckDelay: undefined, localS3: undefined, localHost: undefined, localWebHost: undefined, localSupa: undefined, localSupaAnon: undefined, localApi: undefined, localApiFiles: undefined, allowModifyUrl: undefined, defaultChannel: undefined, appId: undefined, keepUrlPathAfterReload: undefined, }, }, }; export default config; ``` * [`notifyAppReady()`](#notifyappready) * [`setUpdateUrl()`](#setupdateurl) * [`setStatsUrl()`](#setstatsurl) * [`setChannelUrl()`](#setchannelurl) * [`download()`](#download) * [`next()`](#next) * [`set()`](#set) * [`delete()`](#delete) * [`list()`](#list) * [`reset()`](#reset) * [`current()`](#current) * [`reload()`](#reload) * [`setMultiDelay()`](#setmultidelay) * [`cancelDelay()`](#canceldelay) * [`getLatest()`](#getlatest) * [`setChannel()`](#setchannel) * [`unsetChannel()`](#unsetchannel) * [`getChannel()`](#getchannel) * [`setCustomId()`](#setcustomid) * [`getBuiltinVersion()`](#getbuiltinversion) * [`getDeviceId()`](#getdeviceid) * [`getPluginVersion()`](#getpluginversion) * [`isAutoUpdateEnabled()`](#isautoupdateenabled) * [`removeAllListeners()`](#removealllisteners) * [`addListener('download', )`](#addlistenerdownload-) * [`addListener('noNeedUpdate', )`](#addlistenernoneedupdate-) * [`addListener('updateAvailable', )`](#addlistenerupdateavailable-) * [`addListener('downloadComplete', )`](#addlistenerdownloadcomplete-) * [`addListener('majorAvailable', )`](#addlistenermajoravailable-) * [`addListener('updateFailed', )`](#addlistenerupdatefailed-) * [`addListener('downloadFailed', )`](#addlistenerdownloadfailed-) * [`addListener('appReloaded', )`](#addlistenerappreloaded-) * [`addListener('appReady', )`](#addlistenerappready-) * [`isAutoUpdateAvailable()`](#isautoupdateavailable) * [`getNextBundle()`](#getnextbundle) * [Interfaces](#interfaces) * [Type Aliases](#type-aliases) # Methods ## notifyAppReady() ```typescript notifyAppReady() => Promise ``` Memberi tahu Capacitor Updater bahwa bundle saat ini berjalan (rollback akan terjadi jika metode ini tidak dipanggil pada setiap peluncuran aplikasi) Secara default metode ini harus dipanggil dalam 10 detik pertama setelah peluncuran aplikasi, jika tidak rollback akan terjadi Ubah perilaku ini dengan {@link appReadyTimeout} **Returns:** `Promise` *** ## setUpdateUrl() ```typescript setUpdateUrl(options: UpdateUrl) => Promise ``` Mengatur updateUrl untuk aplikasi, ini akan digunakan untuk memeriksa pembaruan | Param | Type | Description | | ------------- | ----------- | --------------------------------------------------- | | **`options`** | `UpdateUrl` | berisi URL yang digunakan untuk memeriksa pembaruan | **Since:** 540 *** ## setStatsUrl() ```typescript setStatsUrl(options: StatsUrl) => Promise ``` Mengatur statsUrl untuk aplikasi, ini akan digunakan untuk mengirim statistik. Memberikan string kosong akan menonaktifkan pengumpulan statistik | Param | Type | Description | | ------------- | ---------- | -------------------------------------------------- | | **`options`** | `StatsUrl` | berisi URL yang digunakan untuk mengirim statistik | **Since:** 540 *** ## setChannelUrl() ```typescript setChannelUrl(options: ChannelUrl) => Promise ``` Mengatur channelUrl untuk aplikasi, ini akan digunakan untuk mengatur channel | Param | Type | Description | | ------------- | ------------ | ------------------------------------------------ | | **`options`** | `ChannelUrl` | berisi URL yang digunakan untuk mengatur channel | **Since:** 540 *** ## download() ```typescript download(options: DownloadOptions) => Promise ``` Mengunduh bundle baru dari URL yang disediakan, ini harus berupa file zip, dengan file di dalamnya atau dengan id unik di dalamnya dengan semua file Anda | Param | Type | Description | | ------------- | ----------------- | ------------------------------------------------------------------------------- | | **`options`** | `DownloadOptions` | The {@link [DownloadOptions](#downloadoptions)} untuk mengunduh zip bundle baru | **Returns:** `Promise` *** ## next() ```typescript next(options: BundleId) => Promise ``` Mengatur bundle berikutnya yang akan digunakan ketika aplikasi dimuat ulang| Param | Type | Description | | ------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | Berisi ID Bundle berikutnya untuk diatur pada peluncuran aplikasi selanjutnya {@link [BundleInfoid](#bundleinfo)} | **Returns:** `Promise` *** ## set() ```typescript set(options: BundleId) => Promise ``` Mengatur bundle saat ini dan segera memuat ulang aplikasi | Param | Type | Description | | ------------- | ---------- | ------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | Objek {@link [BundleId](#bundleid)} berisi id bundle baru yang akan diatur sebagai saat ini | *** ## delete() ```typescript delete(options: BundleId) => Promise ``` Menghapus bundle yang ditentukan dari penyimpanan aplikasi native. Gunakan bersama {@link list} untuk mendapatkan ID Bundle yang tersimpan | Param | Type | Description | | ------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------ | | **`options`** | `BundleId` | Objek {@link [BundleId](#bundleid)} berisi ID bundle yang akan dihapus (catatan, ini adalah id bundle, BUKAN nama versi) | *** ## list() ```typescript list(options?: ListOptions | undefined) => Promise ``` Dapatkan semua bundle yang telah diunduh secara lokal di aplikasi Anda | Param | Type | Description | | ------------- | ------------- | ------------------------------------------------------- | | **`options`** | `ListOptions` | {@link [ListOptions](#listoptions)} untuk daftar bundle | **Returns:** `Promise` *** ## reset() ```typescript reset(options?: ResetOptions | undefined) => Promise ``` Mengatur ulang aplikasi ke bundle ‘builtin’ (yang dikirim ke Apple App Store / Google Play Store) atau bundle yang terakhir berhasil dimuat | Param | Type | Description | | ------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **`options`** | `ResetOptions` | Berisi {@link [ResetOptionstoLastSuccessful](#resetoptions)}, ‘true’ mengatur ulang ke bundle builtin dan ‘false’ akan mengatur ulang ke bundle terakhir yang berhasil dimuat | *** ## current() ```typescript current() => Promise ``` Dapatkan bundle saat ini, jika tidak ada yang diatur maka akan mengembalikan ‘builtin’ currentNative adalah bundle asli yang diinstal pada perangkat **Returns:** `Promise` *** ## reload() ```typescript reload() => Promise ``` Memuat ulang tampilan *** ## setMultiDelay() ```typescript setMultiDelay(options: MultiDelayConditions) => Promise ``` Mengatur array {@link [DelayCondition](#delaycondition)} yang berisi kondisi yang akan digunakan Plugin untuk menunda pembaruan Setelah semua kondisi terpenuhi, proses pembaruan akan berjalan kembali seperti biasa, jadi pembaruan akan diinstal setelah aplikasi masuk ke background atau dimatikan Untuk jenis ‘date’, nilai harus berupa string tanggal iso8601 Untuk jenis ‘background’, nilai harus berupa angka dalam milidetik Untuk jenis ‘nativeVersion’, nilai harus berupa nomor versi Untuk jenis ‘kill’, nilai tidak digunakan Fungsi ini memiliki perilaku yang tidak konsisten, opsi kill memicu pembaruan setelah kill pertama dan tidak setelah background berikutnya seperti opsi lainnya. Ini akan diperbaiki dalam rilis utama mendatang | Param | Type | Description | | ------------- | ---------------------- | ------------------------------------------------------------------------------------------- | | **`options`** | `MultiDelayConditions` | Berisi array {@link [MultiDelayConditions](#multidelayconditions)} kondisi yang akan diatur | **Since:** 430 *** ## cancelDelay() ```typescript cancelDelay() => Promise ``` Membatalkan {@link [DelayCondition](#delaycondition)} untuk memproses pembaruan segera **Since:** 400 *** ## getLatest() ```typescript getLatest(options?: GetLatestOptions | undefined) => Promise ``` Dapatkan bundle terbaru yang tersedia dari URL pembaruan | Param | Type | | ------------- | ------------------ | | **`options`** | `GetLatestOptions` | **Returns:** `Promise` **Since:** 400 *** ## setChannel() ```typescript setChannel(options: SetChannelOptions) => Promise ``` Mengatur channel untuk perangkat ini. Channel harus mengizinkan pengaturan sendiri agar ini berfungsi Jangan gunakan metode ini untuk mengatur channel saat boot ketika ‘autoUpdate’ diaktifkan di {@link PluginsConfig} Metode ini untuk mengatur channel setelah aplikasi siap Metode ini mengirim permintaan ke backend Capgo untuk menghubungkan ID perangkat ke channel. Capgo dapat menerima atau menolak tergantung pengaturan channel Anda | Param | Type | Description | | ------------- | ------------------- | ------------------------------------------------------------------------------- | | **`options`** | `SetChannelOptions` | Adalah {@link [SetChannelOptions](#setchanneloptions)} channel yang akan diatur | **Returns:** `Promise` **Since:** 470 *** ## unsetChannel() ```typescript unsetChannel(options: UnsetChannelOptions) => Promise ``` Menghapus pengaturan channel untuk perangkat iniPerangkat akan kembali ke channel default | Param | Type | | ------------- | --------------------- | | **`options`** | `UnsetChannelOptions` | **Since:** 470 *** ## getChannel() ```typescript getChannel() => Promise ``` Dapatkan channel untuk perangkat ini **Returns:** `Promise` **Since:** 480 *** ## setCustomId() ```typescript setCustomId(options: SetCustomIdOptions) => Promise ``` Atur ID kustom untuk perangkat ini | Param | Type | Description | | ------------- | -------------------- | ------------------------------------------------------------------------------ | | **`options`** | `SetCustomIdOptions` | adalah {@link [SetCustomIdOptions](#setcustomidoptions)} customId untuk diatur | **Since:** 490 *** ## getBuiltinVersion() ```typescript getBuiltinVersion() => Promise ``` Dapatkan versi aplikasi native atau versi builtin jika diatur dalam konfigurasi **Returns:** `Promise` **Since:** 520 *** ## getDeviceId() ```typescript getDeviceId() => Promise ``` Dapatkan ID unik yang digunakan untuk mengidentifikasi perangkat (dikirim ke server pembaruan otomatis) **Returns:** `Promise` *** ## getPluginVersion() ```typescript getPluginVersion() => Promise ``` Dapatkan versi plugin Capacitor Updater native (dikirim ke server pembaruan otomatis) **Returns:** `Promise` *** ## isAutoUpdateEnabled() ```typescript isAutoUpdateEnabled() => Promise ``` Dapatkan status konfigurasi pembaruan otomatis **Returns:** `Promise` *** ## removeAllListeners() ```typescript removeAllListeners() => Promise ``` Hapus semua listener untuk plugin ini **Since:** 100 *** ## addListener(‘download’, ) ```typescript addListener(eventName: 'download', listenerFunc: (state: DownloadEvent) => void) => Promise ``` Mendengarkan event pengunduhan bundle dalam Aplikasi. Aktif saat pengunduhan dimulai, selama mengunduh dan saat selesai | Param | Type | | ------------------ | -------------------------------- | | **`eventName`** | `’download’` | | **`listenerFunc`** | `(state: DownloadEvent) => void` | **Returns:** `Promise` **Since:** 2011 *** ## addListener(‘noNeedUpdate’, ) ```typescript addListener(eventName: 'noNeedUpdate', listenerFunc: (state: NoNeedEvent) => void) => Promise ``` Mendengarkan event tidak perlu pembaruan, berguna ketika Anda ingin memaksa pemeriksaan setiap kali aplikasi diluncurkan | Param | Type | | ------------------ | ------------------------------ | | **`eventName`** | `’noNeedUpdate’` | | **`listenerFunc`** | `(state: NoNeedEvent) => void` | **Returns:** `Promise` **Since:** 400 *** ## addListener(‘updateAvailable’, ) ```typescript addListener(eventName: 'updateAvailable', listenerFunc: (state: UpdateAvailableEvent) => void) => Promise ``` Mendengarkan event pembaruan tersedia, berguna ketika Anda ingin memaksa pemeriksaan setiap kali aplikasi diluncurkan | Param | Type | | ------------------ | --------------------------------------- | | **`eventName`** | `’updateAvailable’` | | **`listenerFunc`** | `(state: UpdateAvailableEvent) => void` | **Returns:** `Promise` **Since:** 400 *** ## addListener(‘downloadComplete’, ) ```typescript addListener(eventName: 'downloadComplete', listenerFunc: (state: DownloadCompleteEvent) => void) => Promise ``` Mendengarkan event downloadComplete | Param | Type | | ------------------ | ---------------------------------------- | | **`eventName`** | `’downloadComplete’` | | **`listenerFunc`** | `(state: DownloadCompleteEvent) => void` | **Returns:** `Promise` **Since:** 400 *** ## addListener(‘majorAvailable’, ) ```typescript addListener(eventName: 'majorAvailable', listenerFunc: (state: MajorAvailableEvent) => void) => Promise ``` Mendengarkan event pembaruan Major dalam Aplikasi, memberi tahu Anda ketika pembaruan major diblokir oleh pengaturan disableAutoUpdateBreaking | Param | Type | | ------------------ | -------------------------------------- | | **`eventName`** | `’majorAvailable’` | | **`listenerFunc`** | `(state: MajorAvailableEvent) => void` | **Returns:** `Promise` **Since:** 230 *** ## addListener(‘updateFailed’, ) ```typescript addListener(eventName: 'updateFailed', listenerFunc: (state: UpdateFailedEvent) => void) => Promise ``` Mendengarkan event kegagalan pembaruan dalam Aplikasi, memberi tahu Anda ketika pembaruan gagal diinstal saat aplikasi berikutnya dimulai | Param | Type | | ------------------ | ------------------------------------ | | **`eventName`** | `’updateFailed’` | | **`listenerFunc`** | `(state: UpdateFailedEvent) => void` | **Returns:** `Promise` **Since:** 230 *** ## addListener(‘downloadFailed’,) ```typescript addListener(eventName: 'downloadFailed', listenerFunc: (state: DownloadFailedEvent) => void) => Promise ``` Dengarkan event kegagalan unduhan di App, memberi tahu Anda ketika unduhan bundle gagal | Param | Type | | ------------------ | -------------------------------------- | | **`eventName`** | `’downloadFailed’` | | **`listenerFunc`** | `(state: DownloadFailedEvent) => void` | **Returns:** `Promise` **Since:** 400 *** ## addListener(‘appReloaded’, ) ```typescript addListener(eventName: 'appReloaded', listenerFunc: () => void) => Promise ``` Dengarkan event reload di App, memberi tahu Anda ketika reload terjadi | Param | Type | | ------------------ | --------------- | | **`eventName`** | `’appReloaded’` | | **`listenerFunc`** | `() => void` | **Returns:** `Promise` **Since:** 430 *** ## addListener(‘appReady’, ) ```typescript addListener(eventName: 'appReady', listenerFunc: (state: AppReadyEvent) => void) => Promise ``` Dengarkan event app ready di App, memberi tahu Anda ketika app siap digunakan | Param | Type | | ------------------ | -------------------------------- | | **`eventName`** | `’appReady’` | | **`listenerFunc`** | `(state: AppReadyEvent) => void` | **Returns:** `Promise` **Since:** 510 *** ## isAutoUpdateAvailable() ```typescript isAutoUpdateAvailable() => Promise ``` Dapatkan apakah pembaruan otomatis tersedia (tidak dinonaktifkan oleh serverUrl) **Returns:** `Promise` *** ## getNextBundle() ```typescript getNextBundle() => Promise ``` Dapatkan bundle selanjutnya yang akan digunakan ketika aplikasi dimuat ulang Mengembalikan null jika tidak ada bundle selanjutnya yang diatur **Returns:** `Promise` **Since:** 680 *** ## Interfaces ### AppReadyResult | Prop | Type | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | ### BundleInfo | Prop | Type | | ---------------- | -------------- | | **`id`** | `string` | | **`version`** | `string` | | **`downloaded`** | `string` | | **`checksum`** | `string` | | **`status`** | `BundleStatus` | ### UpdateUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### StatsUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### ChannelUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### DownloadOptions | Prop | Type | Deskripsi | Default | Since | | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ----- | | **`url`** | `string` | URL file zip bundle (misalnya: distzip) yang akan diunduh (Ini bisa berupa URL apa saja Misalnya: Amazon S3, tag GitHub, tempat lain dimana Anda meng-host bundle Anda) | | | | **`version`** | `string` | Kode/nama versi dari bundle/versi ini | | | | **`sessionKey`** | `string` | Kunci sesi untuk pembaruan | `undefined` | 400 | | **`checksum`** | `string` | Checksum untuk pembaruan | `undefined` | 400 | ### BundleId | Prop | Type | | -------- | -------- | | **`id`** | `string` | ### BundleListResult | Prop | Type | | ------------- | -------------- | | **`bundles`** | `BundleInfo[]` | ### ListOptions | Prop | Type | Deskripsi | Default | Since | | --------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ----- | | **`raw`** | `boolean` | Apakah akan mengembalikan daftar bundle mentah atau manifest Jika benar, daftar akan mencoba membaca database internal alih-alih file di disk | `false` | 6140 | ### ResetOptions | Prop | Type | | ---------------------- | --------- | | **`toLastSuccessful`** | `boolean` | ### CurrentBundleResult | Prop | Type | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | | **`native`** | `string` | ### MultiDelayConditions | Prop | Type | | --------------------- | ------------------ | | **`delayConditions`** | `DelayCondition[]` | ### DelayCondition | Prop | Type | Deskripsi | | ----------- | ---------------- | ----------------------------------- | | **`kind`** | `DelayUntilNext` | Atur kondisi delay di setMultiDelay | | **`value`** | `string` | | ### LatestVersion | Prop | Type | Deskripsi | Since | | ---------------- | ----------------- | --------------------------- | ----- | | **`version`** | `string` | Hasil dari metode getLatest | 400 | | **`checksum`** | `string` | | 6 | | **`major`** | `boolean` | | | | **`message`** | `string` | | | | **`sessionKey`** | `string` | | | | **`error`** | `string` | | | | **`old`** | `string` | | | | **`url`** | `string` | | | | **`manifest`** | `ManifestEntry[]` | | 61 | ### ManifestEntry | Prop | Type | | ------------------ | ---------------- | | **`file_name`** | `string \| null` | | **`file_hash`** | `string \| null` | | **`download_url`** | `string \| null` | ### GetLatestOptions | Prop | Type | Deskripsi | Default | Sejak | | ------------- | -------- | ---------------------------------------------------------------------------------------------------- | ----------- | ----- | | **`channel`** | `string` | Channel untuk mendapatkan versi terbaru. Channel harus mengizinkan ‘self\_assign’ agar ini berfungsi | `undefined` | 680 | ### ChannelRes | Prop | Type | Deskripsi | Sejak | | ------------- | -------- | ---------------------------------------- | ----- | | **`status`** | `string` | Status saat ini dari channel yang diatur | 470 | | **`error`** | `string` | | | | **`message`** | `string` | | | ### SetChannelOptions | Prop | Type | | ----------------------- | --------- | | **`channel`** | `string` | | **`triggerAutoUpdate`** | `boolean` | ### UnsetChannelOptions | Prop | Type | | ----------------------- | --------- | | **`triggerAutoUpdate`** | `boolean` | ### GetChannelRes | Prop | Type | Deskripsi | Sejak | | -------------- | --------- | ----------------------------------------- | ----- | | **`channel`** | `string` | Status saat ini dari channel yang didapat | 480 | | **`error`** | `string` | | | | **`message`** | `string` | | | | **`status`** | `string` | | | | **`allowSet`** | `boolean` | | | ### SetCustomIdOptions | Prop | Type | | -------------- | -------- | | **`customId`** | `string` | ### BuiltinVersion | Prop | Type | | ------------- | -------- | | **`version`** | `string` | ### DeviceId | Prop | Type | | -------------- | -------- | | **`deviceId`** | `string` | ### PluginVersion | Prop | Type | | ------------- | -------- | | **`version`** | `string` | ### AutoUpdateEnabled | Prop | Type | | ------------- | --------- | | **`enabled`** | `boolean` | ### PluginListenerHandle | Prop | Type | | ------------ | --------------------- | | **`remove`** | `() => Promise` | ### DownloadEvent | Prop | Type | Deskripsi | Sejak | | ------------- | ------------ | ----------------------------------------- | ----- | | **`percent`** | `number` | Status unduhan saat ini, antara 0 dan 100 | 400 | | **`bundle`** | `BundleInfo` | | | ### NoNeedEvent | Prop | Type | Deskripsi | Sejak | | ------------ | ------------ | ----------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Status unduhan saat ini, antara 0 dan 100 | 400 | ### UpdateAvailableEvent | Prop | Type | Deskripsi | Sejak | | ------------ | ------------ | ----------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Status unduhan saat ini, antara 0 dan 100 | 400 | ### DownloadCompleteEvent | Prop | Type | Deskripsi | Sejak | | ------------ | ------------ | ------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Muncul ketika pembaruan baru tersedia | 400 | ### MajorAvailableEvent | Prop | Type | Deskripsi | Sejak | | ------------- | -------- | ---------------------------------------- | ----- | | **`version`** | `string` | Muncul ketika bundle major baru tersedia | 400 | ### UpdateFailedEvent | Prop | Type | Deskripsi | Sejak | | ------------ | ------------ | -------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Muncul ketika pembaruan gagal diinstal | 400 | ### DownloadFailedEvent | Prop | Type | Deskripsi | Sejak | | ------------- | -------- | --------------------------- | ----- | | **`version`** | `string` | Muncul ketika unduhan gagal | 400 | ### AppReadyEvent | Prop | Type | Deskripsi | Sejak | | ------------ | ------------ | ------------------------------------- | ----- | | **`bundle`** | `BundleInfo` | Muncul ketika aplikasi siap digunakan | 520 | | **`status`** | `string` | | | ### AutoUpdateAvailable | Prop | Type | | --------------- | --------- | | **`available`** | `boolean` | ## Type Aliases ### BundleStatus `‘success’ | ‘error’ | ‘pending’ | ‘downloading’` ### DelayUntilNext `‘background’ | ‘kill’ | ‘nativeVersion’ | ‘date’` # Pembaruan Otomatis > Cara Pembaruan Otomatis menggunakan capacitor-updater Mode ini memungkinkan pengembang untuk menggunakan capacitor-updater dengan mode auto-update dan mengirim pembaruan melalui channel Capgo atau yang setara ### Prasyarat Pastikan versi aplikasi Anda menggunakan sebelum menggunakan auto-update Capgo Ini adalah konvensi yang digunakan untuk mengelola versi di Capgo Ada dua cara untuk mengatur versi di aplikasi Anda: Cara baru: Gunakan field `version` di file `capacitorconfigjson` Anda ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true, // Aktifkan auto-update, true secara default "appId": "comexampleapp", // Digunakan untuk mengidentifikasi aplikasi di server "version": "100" // Digunakan untuk memeriksa pembaruan } } } ``` Opsi ini akan digunakan oleh plugin untuk memeriksa pembaruan, dan CLI untuk mengunggah versi Cara lama: Di 3 file dalam proyek Anda: * `packagejson` di **version** * `android/app/buildgradle` di **versionName** * `ios/App/Appxcodeproj/projectpbxproj` di **CURRENT\_PROJECT\_VERSION** ### Tutorial Siapkan aplikasi Anda dalam 5 menit [Update aplikasi capacitor Anda dengan mulus menggunakan capacitor updater](https://capgo.app/blog/update-your-capacitor-apps-seamlessly-using-capacitor-updater) Siapkan CI Anda dalam 5 menit [Build dan rilis otomatis dengan GitHub actions](https://capgo.app/blog/automatic-build-and-release-with-github-actions) ### Instalasi ```bash npm install @capgo/capacitor-updater npx cap sync ``` ### Pendahuluan Klik [daftar](https://capgo.app) untuk membuat akun Anda Server memungkinkan Anda mengelola channel dan versi dan banyak lagi `autoUpdate` akan menggunakan data dari `capacitorconfig` untuk mengidentifikasi server Capgo Note Anda masih dapat menggunakan Capgo Cloud tanpa mengirim kode Anda ke server kami jika hal tersebut tidak diizinkan oleh perusahaan Anda #### Validasi versi Ketika auto-update diatur, Anda harus memberi tahu dari dalam JS bahwa aplikasi Anda hidup dan siap Ini dapat dilakukan dengan memanggil `notifyAppReady` dalam aplikasi Anda Lakukan sesegera mungkin ```ts import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdaternotifyAppReady() ``` #### Alur pengguna * Pengguna membuka aplikasi, aplikasi memanggil server untuk memeriksa pembaruan, jika ditemukan akan diunduh di latar belakang * Pengguna meninggalkan aplikasi, versi baru diatur sebagai aktif * Pengguna membuka aplikasi lagi, kita memuat versi aktif baru dan mengaturnya sebagai default * Jika `notifyAppReady()` dipanggil, ketika pengguna meninggalkan aplikasi, versi sebelumnya dihapus * Pengguna melanjutkan alur normal aplikasi sampai siklus pembaruan berikutnya Danger ⚠️ Tidak memanggil `notifyAppReady()` dalam aplikasi Anda, akan membuat versi saat ini ditandai sebagai tidak valid dan akan kembali ke bundle atau stok valid sebelumnya #### Alur pengembangan Saat Anda mengembangkan fitur baru, pastikan untuk memblokir `autoUpdate`, karena capgo akan terus menimpa pekerjaan Anda dengan bundle pembaruan terbaru Atur `autoUpdate` ke false dalam konfigurasi Anda Jika karena suatu alasan Anda terjebak pada pembaruan, Anda dapat menghapus aplikasi dan menginstalnya kembali Pastikan untuk mengatur `autoUpdate` ke false dalam konfigurasi Anda sebelum melakukannya Dan kemudian build lagi dengan Xcode atau Android studio Untuk mengunggah versi di setiap commit, atur CI/CD dengan panduan ini [Build dan rilis otomatis dengan GitHub actions](https://capgo.app/blog/automatic-build-and-release-with-github-actions) #### Event Major Available Ketika `disableAutoUpdateBreaking` diatur ke true, Anda dapat mendengarkan event untuk mengetahui kapan aplikasi menolak untuk melakukan pembaruan major breaking ```jsx import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdateraddListener('majorAvailable', (info: any) => { consolelog('majorAvailable was fired', infoversion) }) ``` # Sistem Channel > Cara menggunakan capacitor-updater dan sistem channel Capgo dan capacitor-updater hadir dengan sistem channel yang canggih ## Apa yang dapat Anda lakukan dengan channel: * Menghubungkan perangkat ke channel untuk pengembangan, uji beta * Menggunakan satu channel per cabang pengembangan dan membiarkan tim Anda mengatur sendiri dari ponsel untuk pengujian ## Menugaskan perangkat ke channel: * Jadikan channel sebagai default, setiap kali perangkat baru meminta pembaruan ke Capgo, channel ini akan merespons * Kirim **deviceId** (dengan metode [**getDeviceId**](/docs/plugin/api#getdeviceid)) ke backend Anda dan tugaskan dengan API publik Capgo * Buat channel dapat ditugaskan sendiri (dengan metode [**setChannel**](/docs/plugin/api#setchannel)), dan biarkan perangkat berlangganan ke channel (dengan atau tanpa interaksi pengguna) dengan metode `setChannel` dari plugin * Gunakan opsi `defaultChannel` dalam [config](/docs/plugin/settings#defaultchannel) untuk mengatur channel default untuk semua perangkat dengan konfigurasi plugin ini Note Anda juga dapat menugaskan perangkat langsung ke bundle ## Opsi Channel ![](/channel_setting_1.webp) Detail setiap opsi: | Opsi | Deskripsi | | --------------------------------------- | -------------------------------------------------------------------------------------------------------- | | **Disable auto downgrade under native** | Tidak mengirim pembaruan jika versi native aplikasi lebih besar dari versi channel | | **Disable auto upgrade above major** | Tidak mengirim pembaruan jika versi native aplikasi lebih rendah dari Major (**1**23) dari versi channel | | **Disable auto upgrade above minor** | Tidak mengirim pembaruan jika versi native aplikasi lebih rendah dari minor (1**2**3) dari versi channel | | **Allow the device to self-assign** | Mengizinkan perangkat menggunakan metode `setChannel` ke channel ini | | **IOS** | Mengizinkan perangkat IOS untuk mengunduh pembaruan dari channel ini | | **Android** | Mengizinkan perangkat Android untuk mengunduh pembaruan dari channel ini | | **Allow Emulator** | Mengizinkan emulator untuk menerima pembaruan dari channel ini | | **Allow development build** | Mengizinkan build pengembangan untuk menerima pembaruan dari channel ini | Note Capgo melakukan beberapa penyaringan otomatis untuk Anda. Jika Anda memiliki CI/CD yang dikonfigurasi untuk mengirim versi Anda ke Google Play, Google Play akan menjalankan aplikasi Anda setiap kali ke 20+ perangkat nyata. Selama 4 jam pertama bundle baru, kami akan memblokir IP pusat data Google untuk mencegah mereka dihitung dalam statistik Anda Note Capgo **tidak** menghitung emulator dan build pengembangan dalam penggunaan Anda, tetapi perlu diingat bahwa Anda tidak dapat memiliki lebih dari 3% dari keduanya, atau akun Anda akan dikunci sampai Anda memperbaikinya # Memulai > Pasang plugin ke dalam aplikasi Anda ## Pengenalan Capgo [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## Pembaruan langsung hanya 3 langkah ### Buat akun Anda Kunjungi halaman pendaftaran kami di ![onboarding screenshot](/onboard.webp "onboarding screenshot") ### Pasang Capgo dengan CLI Gunakan perintah ajaib untuk memulai ```bash npx @capgo/cli@latest init [APIKEY] ``` Perintah ini akan memandu Anda melalui proses pengaturan ### Cukup ikuti petunjuknya Di CLI, Anda akan diberikan serangkaian pertanyaan. Berikan jawaban yang diperlukan untuk menyelesaikan pengaturan otomatis Tip Dengan mengikuti langkah-langkah ini, Anda akan siap menggunakan dalam waktu singkat. Jika Anda membutuhkan bantuan lebih lanjut selama proses, tim dukungan kami siap membantu. Selamat mencoba! ### Nikmati keajaiban Capgo! Uji aplikasi Anda dan pelajari nanti tentang cara menggunakan fitur-fitur canggih Capgo # Mise à jour hybride > Metode pembaruan untuk pembaruan otomatis Ketika mendorong pembaruan kepada pengguna Anda, ada beberapa cara untuk menangani siklus pembaruan sesuai kebutuhan sebelum menerapkannya * Pembaruan diam-diam * Mendengarkan event `updateAvailable` * Menampilkan jendela modal atau menunda pembaruan ## Pembaruan diam-diam Anda dapat memaksa siklus pembaruan terjadi setiap kali aplikasi dimulai dengan mengatur `directUpdate` ke `true`, ini akan memicu siklus pembaruan seperti biasa tanpa interaksi pengguna ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "directUpdate": true, }, "SplashScreen": { "launchAutoHide": false, } } } ``` Dan kemudian di aplikasi Anda, Anda harus menyembunyikan splash screen ketika menerima event `appReady`: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' CapacitorUpdateraddListener('appReady', () => { // Hide splash SplashScreenhide() }) CapacitorUpdaternotifyAppReady() ``` ## Pembaruan paksa Tambahkan listener untuk event `updateAvailable` dan kemudian tampilkan peringatan untuk memberi tahu pengguna bahwa aplikasi akan diperbarui: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { Dialog } from '@capacitor/dialog' CapacitorUpdateraddListener('updateAvailable', async (res) => { try { await Dialogalert({ title: 'Pembaruan Tersedia', message: `Versi ${resbundleversion} tersedia. Aplikasi akan diperbarui sekarang`, }) CapacitorUpdaterset(resbundle) } catch (error) { consolelog(error) } }) CapacitorUpdaternotifyAppReady() ``` ## Pembaruan modal Anda juga dapat membiarkan pengguna memutuskan dengan menampilkan dialog untuk meminta mereka memperbarui: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { Dialog } from '@capacitor/dialog' CapacitorUpdateraddListener('updateAvailable', async (res) => { try { const { value } = await Dialogconfirm({ title: 'Pembaruan Tersedia', message: `Versi ${resbundleversion} tersedia. Apakah Anda ingin memperbarui sekarang?`, }) if (value) CapacitorUpdaterset(resbundle) } catch (error) { consolelog(error) } }) CapacitorUpdaternotifyAppReady() ``` # Aggiornamento Manuale > Cara Mengelola Pembaruan Aplikasi Jika Anda ingin mengatur sendiri kapan pembaruan diterapkan, gunakan mode manual dengan Capgo cloud Berikut yang perlu Anda lakukan, siapkan akun Anda seperti yang dijelaskan di Memulai [Memulai ](/docs/getting-started/quickstart/) #### Konfigurasi Nonaktifkan pembaruan otomatis di `capacitor.config.json` Anda ```tsx // capacitor.config.json { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` Kemudian tambahkan logika untuk menangani pembaruan sendiri\ Berikut contoh cara melakukannya: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater' import type { BundleInfo } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' CapacitorUpdater.notifyAppReady() let data: BundleInfo | null = null App.addListener('appStateChange', async (state: any) => { console.log('appStateChange', state) if (state.isActive) { console.log('getLatest') // Lakukan pengunduhan saat waktu aplikasi aktif pengguna untuk mencegah kegagalan unduhan const latest = await CapacitorUpdater.getLatest() console.log('latest', latest) if (latest.url) { data = await CapacitorUpdater.download(latest) console.log('download', data) } } if (!state.isActive && data) { console.log('set') // Lakukan pengalihan ketika pengguna meninggalkan aplikasi atau kapan pun Anda mau SplashScreen.show() try { await CapacitorUpdater.set({ id: data.id }) } catch (err) { console.log(err) SplashScreen.hide() // jika pengaturan gagal, jika tidak aplikasi baru harus menyembunyikannya } } }) ``` Dokumentasi semua API yang Tersedia dalam plugin: [Metode ](/docs/plugin/api/) Ada beberapa kasus penggunaan di mana Anda dapat mengizinkan pengguna untuk berlangganan ke saluran dan mencoba versi yang berbeda:\ # Cordova > Apakah capacitor-updater akan tersedia di Cordova? Anda mungkin bertanya-tanya apakah plugin ini akan tersedia untuk Cordova Saya telah memulai repositori R\&D untuk itu, tetapi ini membutuhkan banyak pekerjaan ## Masalah Saya tahu saya bisa melakukannya tetapi untuk itu, saya harus membaca semua kode dari codebase Cordova seperti yang saya lakukan untuk Capacitor, untuk memahami bagaimana membuatnya bekerja Versi Android lebih mudah dilakukan karena keduanya menggunakan Java, tetapi iOS membutuhkan penulisan ulang total karena Swift masih belum didukung dengan baik di Cordova ## Solusi Sementara itu inilah yang dapat Anda lakukan: * [Dukung saya](https://github.com/sponsors/riderx) di GitHub dan saya bisa memprioritaskan itu. Ini akan membutuhkan setidaknya 1 bulan kerja * Pekerjakan saya sebagai Konsultan, saya biasa membantu perusahaan besar bermigrasi ke capacitor, biasanya membutuhkan waktu \~10-20 hari, dan [manfaatnya](https://ionicio/resources/articles/capacitor-vs-cordova-modern-hybrid-app-development) sangat besar untuk tim # Debugging > Cara Men-debug Aplikasi Anda ## Memahami log cloud: ### Dikirim dari backend | code | Deskripsi | | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **InvalidIp** | Pengguna berada di pusat data Google dan pembaruan berusia kurang dari 4 jam. Ini dilakukan untuk mencegah perangkat bot Google terhitung sebagai perangkat di akun Anda | | **needPlanUpgrade** (sebelumnya **needUpgrade**) | Menunjukkan bahwa Anda telah mencapai batas paket Anda, dan perangkat tidak akan menerima pembaruan sampai Anda meningkatkan paket atau sampai bulan berikutnya | | **noNew** | Perangkat memiliki versi terbaru yang tersedia | | **disablePlatformIos** | Perangkat menggunakan platform iOS, tetapi dinonaktifkan dalam pengaturan saluran | | **disablePlatformAndroid** | Perangkat menggunakan platform Android, tetapi dinonaktifkan dalam pengaturan saluran | | **disableAutoUpdate** | ”major" | | **disableAutoUpdateUnderNative** | Perangkat memiliki versi (`123`), dan saluran memiliki pembaruan (`122`) di bawah versi perangkat untuk dikirim, tetapi dinonaktifkan dalam pengaturan saluran | | **disableDevBuild** | Perangkat memiliki build pengembangan, tetapi dinonaktifkan dalam pengaturan saluran | | **disableEmulator** | Perangkat adalah emulator, tetapi dinonaktifkan dalam pengaturan saluran | ### Dikirim dari perangkat | code | Deskripsi | | ------------------------- | ------------------------------------------------------------------------- | | **get** | Info untuk mengunduh versi baru telah dikirim ke perangkat | | **delete** | Satu bundle telah dihapus dari perangkat | | **set** | Bundle telah diatur pada perangkat | | **set\_fail** | Bundle gagal diatur | | **reset** | Perangkat direset ke bundle `builtin` | | **download\_XX** | Bundle baru telah diunduh - kemajuan ditunjukkan oleh XX% (kelipatan 10%) | | **download\_complete** | Bundle baru selesai diunduh | | **download\_fail** | Bundle baru gagal diunduh | | **update\_fail** | Bundle baru telah dipasang tetapi gagal memanggil `notifyAppReady` | | **checksum\_fail** | Bundle baru gagal memvalidasi checksum | | **windows\_path\_fail** | Zip memiliki file yang mengandung path Windows yang ilegal | | **canonical\_path\_fail** | Path file tidak kanonik | | **directory\_path\_fail** | Ada kesalahan dalam path file zip | | **unzip\_fail** | unzip gagal | | **low\_mem\_fail** | Unduhan gagal karena memori rendah di perangkat | ### Status Bundle * `SUCCESS`: instalasi bundle selesai * `ERROR`: instalasi atau unduhan gagal * `PENDING`: Unduhan selesai, menunggu rilis * `DELETED`: Bundle dihapus, masih ditampilkan untuk statistik * `DOWNLOADING`: Sedang mengunduh bundle ## Memahami log perangkat: ### Perintah debug: Ada perintah debug untuk pengguna Capgo cloud ```bash npx @capgo/cli@latest app debug ``` Ini akan memungkinkan Anda memeriksa semua kejadian yang terjadi di aplikasi dan menemukan solusi jika pembaruan tidak terjadi ### IOS untuk menemukan log Anda di Xcode [Getting the Device Log in Xcode ](https://intercomhelp/deploygate/en/articles/4682692-getting-the-device-log-in-xcode) ### Android: untuk menemukan log Anda di Android studio [View logs with Logcat ](https://developerandroidcom/studio/debug/am-logcat) ### Penjelasan Log * `Failed to download from` **=>** sama dengan **download\_fail** * `notifyAppReady was not called, roll back current bundle` => sama dengan **update\_fail** ## Menemukan bundle yang diunduh di perangkat Anda ### iOS Untuk debug di iOS, Anda perlu mengekspor aplikasi ke komputer Anda, Anda bisa melakukannya seperti ini: Xcode memiliki fitur bawaan untuk memeriksa sistem file aplikasi yang diinstal pengembang di perangkat iOS Untuk mencapainya: 1. Hubungkan perangkat Anda ke Mac dan pilih Window > Devices di menubar Xcode 2. Pilih perangkat Anda di panel kiri di bawah bagian Devices 3. Ini akan menampilkan daftar aplikasi yang diinstal pengembang untuk perangkat tersebut 4. Pilih aplikasi yang ingin Anda periksa lalu pilih ikon roda gigi di dekat bagian bawah layar 5. Di sini Anda dapat melihat sistem file saat ini dengan memilih Show Container atau mengunduh snapshot Memilih Download Container akan mengunduh dan mengekspor snapshot sistem file sebagai file xcappdata yang dapat Anda telusuri Klik kanan pada file ini dan pilih Show Package Contents untuk membuka folder Buka folder App Data, dan Anda sekarang akan melihat beberapa folder seperti Documents, Library, tmp, dll ![image](/ios_debug_update_1.webp) Kemudian Anda akan menemukan versi di 2 folder: `library/NoCloud/ionic_built_snapshots` diperlukan setelah aplikasi di-reboot dan `documents/versions` untuk hot reload ### Android Untuk debug di Android, Anda perlu mengakses perangkat dari Android Studio: 1. Klik View > Tool Windows > Device File Explorer atau klik tombol Device File Explorer di bar jendela alat untuk membuka Device File Explorer 2. Pilih perangkat dari daftar dropdown 3. Buka path **data/data/APP\_NAME/** dimana **APP\_NAME adalah ID aplikasi Anda** ![image](/android_debug_update.webp) Kemudian temukan folder `versions` untuk melihat semua versi Tahukah Anda? Di Android, semua versi disimpan dalam satu folder, tidak seperti IOS di mana harus diduplikasi di dua lokasi ## Memahami log crash iOS production [How to review your app's crash logs ](https://developer.apple.com/news/?id=nra79npr) # Nuxt 2 > Cara menginstall plugin di Nuxt 2 # Instalasi di Nuxt 2 Buat file plugin `capacitor-updaterjs` di direktori `plugins` ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' export default ({ app }) => { if (processclient) { windowonNuxtReady(() => { CapacitorUpdaternotifyAppReady() }) } } ``` Ini akan memuat plugin di sisi klien dan memberi tahu aplikasi bahwa aplikasi siap menerima pembaruan # 알려진 문제점 > Masalah yang Diketahui dengan Capacitor dan CapGo ## Live reload Ionic * Ketika Anda mengembangkan, jika Anda menggunakan fitur live reload Ionic dari CLI, itu akan menimpa plugin, sehingga Anda tidak akan pernah melihat pembaruan Anda ## Live reload Quasar * Ini menggunakan sistem yang sama seperti ionic di balik layar, jadi Anda tidak akan melihat pembaruan Anda ## Pembaruan gagal * Ini biasanya terjadi ketika pembaruan besar (> 20mb) dilakukan, persentase besar pengguna tidak akan mendapatkan versi terakhir Di masa lalu, pengguna perlu membuka aplikasi sampai unduhan selesai, sekarang kami menggunakan unduhan latar belakang, tapi masih terbatas pada beberapa detik ## Android ### Tidak dapat mengunduh Kami telah melihat beberapa masalah dengan perangkat di India, dan menghubungi pengguna, membuat mereka mencoba server DNS yang berbeda, dan berhasil Jadi jika Anda mengalami masalah, coba gunakan server DNS yang berbeda seperti Cloudflare atau Google DNS Cloudflare: 1111 dan 1001 Google DNS: 8888 dan 8844 atau dnsgoogle [Bagaimana mengatur server DNS pilihan di Android? ](https://wwwandroidpolicecom/use-preferred-dns-server-android-tutorial/) ### Self Hosted Ketika Anda melakukan pembaruan self-hosted, perhatikan bahwa Anda tidak dapat menggunakan endpoint “HTTP” karena bertentangan dengan kebijakan keamanan aplikasi Android, jika Anda masih ingin melakukannya, ikuti panduan ini: [Bagaimana mengizinkan semua jenis koneksi Jaringan HTTP dan HTTPS di Android (9) Pie? ](https://stackoverflow.com/a/51902630/5511370) ### Unzip Masalah Unzip: entri DEFLATED dapat memiliki deskriptor EXT Jika Anda mengkompres bundle Anda dengan sesuatu yang berbeda dari CLI, format zip Anda bisa salah, silakan gunakan perintah CLI `npx @capgo/cli zip BUNDLE_FOLDER` Ini adalah masalah yang diketahui dari Java: [Masalah Unzip: entri DEFLATED dapat memiliki deskriptor EXT ](https://bugsopenjdkorg/browse/JDK-8143613) ### Masalah Clearfix * Jika Anda memiliki masalah dengan usesCleartextTraffic, itu karena plugin mengikuti praktik baik yang direkomendasikan oleh sonar cloud, dalam 90% kasus akan bekerja dengan baik, tetapi dengan beberapa plugin yang menyebabkan masalah Untuk memperbaikinya, tambahkan di `android/app/src/main/AndroidManifestxml` dalam kunci `` : ```xml tools:replace="android:usesCleartextTraffic" xmlns:tools="http://schemasandroidcom/tools" ``` ## IOS ### Manifes privasi Tambahkan kunci kamus `NSPrivacyAccessedAPICategoryUserDefaults` ke [Privacy Manifest](https://capacitorjs.com/docs/ios/privacy-manifest) Anda (biasanya `ios/App/PrivacyInfoxcprivacy`): ```xml NSPrivacyAccessedAPITypes NSPrivacyAccessedAPIType NSPrivacyAccessedAPICategoryUserDefaults NSPrivacyAccessedAPITypeReasons CA921 ``` Kami merekomendasikan untuk mendeklarasikan [`CA921`](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278401) sebagai alasan untuk mengakses API [`UserDefaults`](https://developer.apple.com/documentation/foundation/userdefaults) ### Izin jaringan Ketika menggunakan server lokal untuk pengujian pembaruan, aplikasi akan meminta izin jaringan, ini adalah perilaku normal, ini tidak terjadi ketika Anda menggunakan server jarak jauh ## Kedua OS Saat melakukan pembaruan mode manual, beberapa event tidak mudah ditangkap, misalnya pembaruan gagal dipicu tepat sebelum kode JS Anda dimuat ulang, jadi Anda tidak akan bisa menangkapnya Salah satu alternatifnya adalah mendaftar bundle dan memeriksa statistik kesalahan untuk mengetahui jika pembaruan gagal Kami perlu menemukan cara yang lebih baik untuk menangani ini di masa depan, tetapi ini bukan prioritas, karena mode otomatis adalah cara yang direkomendasikan untuk melakukan pembaruan PR dipersilakan untuk membantu kami meningkatkan ini ## CLI jika CLI Anda mengalami masalah melakukan apa pun, Periksa apakah **appId** dan **appName** ada di **capacitorconfigts** Anda Ikuti panduan dari dokumentasi resmi: [Konfigurasi Capacitor ](https://capacitorjs.com/docs/config) # Gambaran Umum > Penjelasan dari dua pendekatan berbeda ### Mode Cloud (Direkomendasikan) Mode Cloud adalah pilihan yang kami rekomendasikan untuk pengelolaan pembaruan yang bebas masalah. Backend Capgo menangani semua logika pembaruan, membuat keputusan tentang pembaruan di sisi server untuk keamanan dan kontrol yang lebih baik. Mode ini mengutamakan kemudahan penggunaan: setelah diatur, berjalan dengan lancar secara mandiri, menawarkan fitur lanjutan seperti statistik, dan saluran. Mode ini juga dapat diatur dalam mode manual sehingga memberi Anda lebih banyak kontrol, memungkinkan Anda menentukan kapan akan memperbarui menggunakan kode JavaScript Anda. Backend tetap mengelola apa yang diperbarui. Mode ini berbagi banyak manfaat dengan Mode Auto, terutama dalam keamanan dan fitur lanjutan, tetapi menambahkan fleksibilitas untuk mengatur waktu pembaruan sendiri. ### Mode Self Hosted Mode Self-Hosted Auto adalah untuk mereka yang ingin menangani semua logika pembaruan di server mereka sendiri. Mode ini menawarkan otonomi penuh tetapi membutuhkan server terpisah dan lebih banyak pekerjaan untuk mengelola pembaruan dan persyaratan server. Mode Self-Hosted Manual menggabungkan kontrol dan otonomi. Anda memutuskan kapan akan memperbarui melalui JavaScript, tetapi server Anda menangani apa yang diperbarui. Ini agak kompleks karena Anda menyertakan kode pembaruan dalam pembaruan. Note Jika Anda memilih untuk self host, Anda akan kehilangan semua fitur hebat yang ditawarkan capgo cloud seperti: pengembalian otomatis, peringatan email, saluran, statistik, enkripsi dan lainnya Danger Jika Anda mengirim pembaruan yang buruk kepada pengguna Anda, Anda dapat dan akan merusak aplikasi mereka # 自動アップデート > Cara menggunakan plugin auto-update dalam mode self-hosted Dokumentasi ini akan menjelaskan cara menjalankan server pembaruan otomatis Anda ## Menyajikan bundle Anda Pastikan bundle Anda disajikan melalui HTTPS, dan server memiliki header CORS yang tepat untuk mengizinkan aplikasi mengunduh pembaruan contoh `https://myservercom/app/updates/updatesjson` Jika Anda tidak familiar dengan menyajikan bundle, kami sarankan Anda mencoba Capgo Cloud atau lihat contoh di sini: [Menyajikan Bundle ](/docs/self-hosted/auto-update/update-endpoint) ## Konfigurasi Tambahkan `updateUrl` ke `capacitorconfigjson` Anda ```json { "plugins": { "CapacitorUpdater": { "updateUrl": "https://myservercom/app/updates/updatesjson", } } } ``` Caution Ketika Anda melakukan push pembaruan yang dihosting sendiri, perhatikan bahwa Anda tidak dapat menggunakan endpoint “HTTP” karena bertentangan dengan kebijakan keamanan aplikasi Android, untuk keperluan pengujian Anda dapat [mengizinkannya](https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted) ## API Pembaruan Plugin akan melakukan panggilan POST ke API Anda setiap kali aplikasi dibuka, dengan body ini: ```typescript interface AppInfos { "platform": "ios" | "android", "device_id": "UUID_of_device_unique_by_install", "app_id": "APPID_FROM_CAPACITOR_CONFIG", "custom_id": "your_custom_id_set_on_runtime", "plugin_version": "PLUGIN_VERSION", "version_build": "VERSION_NUMBER_FROM_NATIVE_CODE", "version_code": "VERSION_CODE_FROM_NATIVE_CODE", "version_name": "LAST_DOWNLOADER_VERSION" | "builtin" "version_os": "VERSION_OF_SYSYEM_OS", "is_emulator": boolean, "is_prod": boolean, } ``` API server harus merespons, dalam JSON, ke plugin capacitor-updater dengan data ini jika pembaruan diperlukan: ```json { "version": "123", "url": "https://myservercom/app/updates/my-new-app-200zip" } ``` Dalam mode Auto-update, server harus membandingkan versi dan mengembalikan yang benar, jika kunci URL ada, plugin memulai proses unduhan Jika Anda menambahkan kunci “message” dan “error”, versi tidak akan diatur, dan pesan akan ditampilkan dalam log sebagai gantinya Kunci `version` harus dalam format [`semver`](https://semverorg/) Zip harus memiliki `indexhtml` sebagai file di root, atau hanya satu folder di root dengan `indexhtml` di dalamnya Anda dapat menggunakan perintah CLI untuk mengzip bundle Anda: Membuat bundle dengan file Anda untuk disajikan dari server Anda ```bash npx @capgo/cli bundle zip --path [/path/to/my/bundle] ``` # Contribuer > Berkontribusi pada proyek open source capgo ## Mengapa berkontribusi? Pertama-tama, terima kasih telah mempertimbangkan untuk berkontribusi pada proyek open source capgo! Orang-orang seperti Andalah yang membuat proyek open source capgo menjadi alat yang hebat. Berikut beberapa alasan mengapa Anda mungkin ingin mempertimbangkan untuk berkontribusi: * Berkontribusi pada proyek open source capgo adalah cara yang bagus untuk mendapatkan uang dari [banyak bounty](https://consolealgoraio/org/Capgo) yang ditawarkan oleh tim capgo * Berkontribusi pada proyek open source capgo adalah cara yang bagus untuk menambahkan fitur yang ingin Anda lihat * Berkontribusi pada proyek open source capgo adalah cara yang bagus untuk memperbaiki bug yang Anda temui * [Lisensi utama Capgo](https://github.com/Cap-go/capgo/blob/main/LICENSE) mengharuskan Anda untuk membuka source code dari perubahan yang Anda buat. Dengan berkontribusi kode Anda, Anda dapat menjaga perubahan Anda tetap open source dan membiarkan orang lain menggunakannya ## Cara berkontribusi * Pertama-tama, Anda perlu melakukan fork repository yang ingin Anda kontribusikan * Kedua, Anda perlu commit dan push perubahan Anda ke repository tersebut * Terakhir, Anda perlu membuka pull request * Itu saja! Sekarang Anda hanya perlu menunggu tim capgo untuk meninjau PR Anda ## Dokumen lebih lanjut untuk dibaca * [CONTRIBUTING.MD](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTINGmd) Capgo * [BOUNTY.md](https://github.com/Cap-go/capgo/blob/main/BOUNTYmd) Capgo # Paket Terenkripsi > Cara Menggunakan Fitur Pembaruan Manual dalam Mode Self Host ## Enkripsi End-to-end Mulai dari versi 4150 plugin ini memungkinkan Anda untuk mengirim pembaruan terenkripsi Untuk memulai, buatlah private key Create a private key ```bash npx @capgo/cli key create ``` Kemudian enkripsi zip Anda Encrypt bundled zip ```bash npx @capgo/cli encrypt [path/to/zip] ``` Perintah tersebut akan mencetak `ivSessionKey` yang harus dikirim dengan payload pembaruan Anda dalam key `session_key` ```json { "version": "123", "url": "https://myservercom/app/updates/my-new-app-200zip", "session_key": "encrypted_session_key", } ``` Kemudian aplikasi Anda akan dapat menggunakan private key untuk mendekripsi `session_key` dan menggunakan `session_key` yang sudah didekripsi untuk mendekripsi pembaruan Pelajari lebih lanjut di sini: [Self-hosted Live Updates ](https://capgo.app/blog/self-hosted-live-updates/) # Memulai > Cara Menjalankan Server Pembaruan Mandiri Dokumentasi ini akan menjelaskan cara menjalankan server pembaruan otomatis Anda sendiri ## Pendahuluan Jika Anda merasa pekerjaan ini bermanfaat, silakan pertimbangkan untuk mendukung pekerjaan saya dengan menjadi [sponsor Github](https://github.com/sponsors/riderx) Saya membuat taruhan untuk membuka source code semua kode yang saya buat di sini alih-alih memasang paywall. Dengan membukanya alih-alih melawan dan menyembunyikan, saya percaya kita dapat membuat dunia menjadi tempat yang lebih baik Lebih lanjut, saya ingin fokus pada alat Capgo, dan menjadikannya bisnis yang terbuka dan transparan Tetapi untuk mewujudkannya, kita semua perlu melakukan bagian kita masing-masing, termasuk Anda 🥹 Jika Capgo tidak cocok untuk Anda, maka bayar harga Anda sendiri dan [dukung Maker bootstrapped](https://github.com/sponsors/riderx) sesuai ketentuan Anda [Pertimbangkan Untuk Berkontribusi ](/docs/plugin/self-hosted/contributing/) ## Fitur paritas Jika Anda memilih untuk menggunakan server Anda sendiri, Anda akan kehilangan alur pengaturan 5 menit\ Anda perlu mengimplementasikan semua fitur ini sendiri | Fitur | Capgo | Self hosted | | ----------------------------- | ----- | ----------- | | Pembaruan | ✅ | 🚧 | | Kembali otomatis | ✅ | 🚧 | | Peringatan email saat gagal | ✅ | 🚧 | | Kanal | ✅ | 🚧 | | Override Kanal | ✅ | 🚧 | | Override Perangkat | ✅ | 🚧 | | Pengaturan Kanal | ✅ | 🚧 | | Pengaturan Perangkat | ✅ | 🚧 | | ID Kustom | ✅ | 🚧 | | Set Kanal Otomatis | ✅ | 🚧 | | API Kanal | ✅ | 🚧 | | Statistik Pembaruan | ✅ | 🚧 | | Statistik Unduhan Gagal | ✅ | 🚧 | | Statistik Penggunaan Aplikasi | ✅ | 🚧 | | Enkripsi Pembaruan | ✅ | 🚧 | Danger Jika Anda mengirim pembaruan yang buruk ke pengguna Anda, Anda dapat dan akan merusak aplikasi mereka > Perhatikan bahwa Anda tidak dapat menggunakan Capgo cloud dan server Anda secara bersamaan Danger Fitur pembaruan Over-the-Air (OTA) hanya berlaku untuk modifikasi yang dilakukan pada file HTML, CSS, dan JavaScript Jika Anda membuat perubahan pada kode native, seperti pembaruan plugin Capacitor, wajib mengirimkan ulang aplikasi ke app store untuk persetujuan ## Pilih antara Otomatis dan Manual Dalam mode otomatis, sebagian logika ditangani oleh kode Native, pembaruan diputuskan di sisi server, ini lebih aman dan memungkinkan pembaruan yang lebih detail, penerapan parsial ke satu perangkat atau grup dan lainnya Dalam mode manual, semua logika ditangani oleh JS [Pembaruan Otomatis ](/docs/plugin/self-hosted/auto-update/) [Manual ](/docs/plugin/self-hosted/manual-update/) ## Pasang Capacitor updater Install the Capacitor updater ```bash npm install @capgo/capacitor-updater npx cap sync ``` ## Siapkan bundle Anda Untuk mengirim pembaruan ke aplikasi Anda, Anda perlu mengzipnya Cara terbaik untuk memastikan zip Anda baik adalah menggunakan CLI Capgo untuk mengzip Create a bundle with your files to serve from your server ```bash npx @capgo/cli@latest bundle zip ``` Anda harus menyajikan zip ini dari server Anda sendiri [Pembaruan Otomatis ](/docs/plugin/self-hosted/auto-update/) [Manual ](/docs/plugin/self-hosted/manual-update/) Note Jika ini terlihat seperti banyak pekerjaan, coba uji coba Capgo Cloud # Menangani Statistik > Cara Membuat Endpoint Statistik Self-hosted Berikut contoh kode dalam JavaScript untuk menyimpan statistik plugin ```typescript interface AppInfos { version_name: string action: 'delete' | 'reset' | 'set' | 'set_fail' | 'update_fail' | 'windows_path_fail' | 'canonical_path_fail' | 'directory_path_fail' | 'unzip_fail' | 'low_mem_fail' | 'download_fail' | 'update_fail' | 'download_10' | 'download_20' | 'download_30' | 'download_40' | 'download_50' | 'download_60' | 'download_70' | 'download_80' | 'download_90' | 'download_complete' version_build: string version_code: string version_os: string plugin_version: string platform: string app_id: string device_id: string custom_id?: string is_prod?: boolean is_emulator?: boolean } export const handler: Handler = async (event) => { const body = JSONparse(eventbody || '{}') as AppInfos const { platform, app_id, action, version_code, version_os, device_id, version_name, version_build, plugin_version, } = body consolelog('update asked', platform, app_id, action, version_os, version_code, device_id, version_name, version_build, plugin_version) // Simpan di database Anda return { status: 'ok' } } ``` Endpoint ini harus mengembalikan JSON: ```json { "status": "ok" } ``` ## Tindakan: * **delete**: ketika bundle dihapus secara lokal * **reset**: ketika aplikasi direset ke bundle bawaan * **set**: ketika aplikasi menetapkan bundle baru * **set\_fail**: ketika aplikasi tidak dapat menemukan ID dari bundle yang ditetapkan * **update\_fail**: dikirim setelah penundaan dan `notifyAppReady` tidak pernah dipanggil * **download\_fail**: ketika unduhan tidak pernah selesai * **download\_complete**: Ketika unduhan selesai * **download\_xx**: Dikirim setiap 10% unduhan contoh: download\_20, download\_70 * **update\_fail**: ketika bundle gagal melakukan `notifyAppReady` dalam jangka waktu tertentu # Mengelola Pembaruan > Cara menggunakan plugin pembaruan otomatis dalam mode self-hosted Berikut adalah contoh kode dalam JavaScript untuk mengirim pembaruan ke plugin ```typescript interface AppInfos { version_name: string version_build: string version_os: string custom_id?: string is_prod?: boolean is_emulator?: boolean plugin_version: string platform: string app_id: string device_id: string } export const handler: Handler = async (event) => { const body = JSONparse(eventbody || '{}') as AppInfos const { platform, app_id, version_os, device_id, version_name, version_build, plugin_version, } = body consolelog('update asked', platform, app_id, version_os, device_id, version_name, version_build, plugin_version) if (version_name === '100') { return { version: '101', url: 'https://apiurlcom/mybuild_101zip', } } else if (version_name === '101') { return { version: '102', url: 'https://apiurlcom/mybuild_102zip', } } else { return { message: 'Error version not found' version: '', url: '', } } } ``` Endpoint ini harus mengembalikan JSON: ```json { "version": "102", "url": "https://apiurlcom/mybuild_102zip" } ``` Dan jika tidak ada pembaruan atau terjadi kesalahan, tambahkan kunci `message` dan opsional `error` ```json { "message": "Version not found", "error": "The backend crashed", "version": "102", "url": "https://apiurlcom/mybuild_102zip" } ``` # 手動での更新 > Cara Menggunakan Plugin Pembaruan Manual dalam Mode Self-hosted ## Konfigurasi Tambahkan ini ke `capacitorconfigjson` Anda, untuk menonaktifkan pembaruan otomatis ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false, } } } ``` ## Penggunaan Anda dapat menggunakan contoh ini atau membuat ulang logikanya di aplikasi Anda Caution Kita memaksa pengguna untuk memperbarui aplikasi dengan versi statis yang dideklarasikan dalam kode. Ini tidak direkomendasikan, Anda harus menggunakan versi dinamis dari server Anda Danger Kita tidak melakukan pengecekan versi, dekripsi atau validasi checksum dalam contoh ini. Anda harus melakukannya sendiri ```tsx import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' let data = {version: ""} CapacitorUpdaternotifyAppReady() AppaddListener('appStateChange', async(state) => { if (stateisActive) { // Lakukan unduhan selama waktu aplikasi aktif pengguna untuk mencegah unduhan gagal data = await CapacitorUpdaterdownload({ version: '004', url: 'https://github.com/Cap-go/demo-app/releases/download/004/distzip', }) } if (!stateisActive && dataversion !== "") { // Lakukan pengalihan ketika pengguna meninggalkan aplikasi SplashScreenshow() try { await CapacitorUpdaterset(data) } catch (err) { consolelog(err) SplashScreenhide() // jika set gagal, jika tidak aplikasi baru harus menyembunyikannya } } }) ``` Note Jika ini terlihat seperti banyak pekerjaan, pertimbangkan untuk mencoba [uji coba Capgo](https://capgo.app/register/) yang akan menangani semua ini untuk Anda # 설정 > Semua konfigurasi yang tersedia untuk Capacitor Updater Untuk memiliki kontrol yang lebih detail atas sistem pembaruan, Anda dapat mengonfigurasinya dengan pengaturan berikut: ## `appReadyTimeout` > Mengonfigurasi jumlah milidetik plugin native harus menunggu sebelum menganggap pembaruan ‘gagal’ Hanya tersedia untuk Android dan iOS Default: `10000` (10 detik) ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 } } } ``` ## `responseTimeout` > Mengonfigurasi jumlah milidetik plugin native harus menunggu sebelum menganggap API timeout Hanya tersedia untuk Android dan iOS Default: `20` (20 detik) ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "responseTimeout": 1000 } } } ``` ## `autoDeleteFailed` > Mengonfigurasi apakah plugin harus secara otomatis menghapus bundle yang gagal Hanya tersedia untuk Android dan iOS Default: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoDeleteFailed": false } } } ``` ## `autoDeletePrevious` > Mengonfigurasi apakah plugin harus secara otomatis menghapus bundle sebelumnya setelah pembaruan berhasil Hanya tersedia untuk Android dan iOS Default: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoDeletePrevious": false } } } ``` ## `autoUpdate` > Mengonfigurasi apakah plugin harus menggunakan Pembaruan Otomatis melalui server pembaruan Hanya tersedia untuk Android dan iOS Default: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` ## `updateUrl` > Mengonfigurasi URL / endpoint tempat pemeriksaan pembaruan dikirim Hanya tersedia untuk Android dan iOS Default: `https://apicapgo.app/updates` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "updateUrl": "https://examplecom/api/updates" } } } ``` ## `statsUrl` > Mengonfigurasi URL / endpoint tempat statistik pembaruan dikirim Hanya tersedia untuk Android dan iOS. Setel ke "" untuk menonaktifkan pelaporan statistik Default: `https://apicapgo.app/stats` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "statsUrl": "https://examplecom/api/stats" } } } ``` ## `privateKey` > Mengonfigurasi kunci pribadi untuk enkripsi pembaruan langsung end-to-end Hanya tersedia untuk Android dan iOS Buat kunci pribadi dengan perintah `npx @capgo/cli key create` Default: `undefined` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "privateKey": "YOUR_KEY" } } } ``` ## `directUpdate` > Membuat plugin langsung menginstal pembaruan ketika aplikasi baru saja diperbarui/diinstal. Hanya berlaku untuk mode autoUpdate Hanya tersedia untuk Android dan iOS Default: `undefined` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": true } } } ``` ## `resetWhenUpdate` Note Ketika pembaruan toko terjadi, nonaktifkan reset paksa ke versi native Ada banyak pengaturan lain yang tersedia hanya di [web app](https://web.capgo.app/login) Untuk mengonfigurasi plugin, gunakan pengaturan ini: ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } } ``` ## `directUpdate` Membuat plugin langsung menginstal pembaruan ketika aplikasi baru saja diperbarui/diinstal. Hanya berlaku untuk mode autoUpdate Caution Pengaturan ini mengharuskan Anda menyembunyikan aplikasi dari pengguna saat pembaruan sedang diinstal. Jika tidak, aplikasi akan reset ketika pengguna sedang bernavigasi ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": true } } } ``` ## `defaultChannel` Mengatur channel default untuk aplikasi. Ini akan menimpa channel lain yang diatur di Capgo jika channel mengizinkan penimpaan ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "defaultChannel": "production" } } } ``` ## `appId` Mengatur appId untuk aplikasi. Ini akan menimpa cara lain untuk mendapatkan appId. Ini berguna ketika Anda ingin memiliki appId yang berbeda di Capgo dan di kode native Anda Note Ini adalah cara baru untuk mengatur appId. Cara lama masih dan akan tetap didukung ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "AppId": "comexampleapp" } } } ``` ## `version` Mengatur versi untuk aplikasi. Ini akan menimpa cara lain untuk mendapatkan versi. Ini berguna ketika Anda ingin memiliki versi yang berbeda di Capgo dan di kode native Anda Note Ini adalah cara baru untuk mengatur versi. Cara lama masih dan akan tetap didukung ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "version": "123" } } } ``` # API Statistik > Cara menggunakan plugin pembaruan otomatis dalam mode self-hosted ## API Statistik Dimulai dari versi 130, sistem pembaruan dapat mengirim statistik! Secara default, semua statistik dikirim ke server kami untuk memahami penggunaan dan penelitian Note Tidak ada data pribadi yang dikirim untuk statistik, hanya UUID acak, pembaruan versi, versi aplikasi native, platform, tindakan, dan ID aplikasi Jika Anda ingin mengirim data ini ke server Anda, ubah konfigurasi di bawah ini: ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "statsUrl": "URL_ANDA" } } } ``` Yang akan diterima server Anda adalah: ```tsx interface AppInfosStats { "action": "set", // bisa berupa set, delete, set_fail, reset, revert // Kemudian informasi yang sama seperti pembaruan "app_id": "*******", // pengenal aplikasi di toko "device_id": "*******", // id unik per instalasi aplikasi "platform": "ios", // atau android "custom_id": "user_1", // mewakili pengguna Anda "version_name": "123", // versi dari web build "version_build": "120", // versi dari native build "version_code": "120", // nomor build dari native build "version_os": "16", // versi OS dari perangkat "plugin_version": "400"// untuk membuat api Anda berperilaku berbeda dengan plugin yang berbeda "is_emulator": false, "is_prod": false, } ``` Anda juga bisa menonaktifkannya sepenuhnya dengan string kosong. Perlu diingat, statistik dibuat ramah privasi dan membantu saya memahami bagaimana orang menggunakan plugin ini, untuk menyelesaikan masalah dan meningkatkannya [Menangani Pembaruan ](/docs/plugin/self-hosted/handling-updates/) # Migrasi dari AppFlow ke Capgo > Panduan lengkap untuk migrasi aplikasi Anda dari Ionic AppFlow ke Capgo ## Referensi Konfigurasi AppFlow Sebelum migrasi, catat konfigurasi AppFlow Anda saat ini di `capacitor.config.ts`: ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { LiveUpdates: { appId: 'your-app-id', channel: 'Production', autoUpdateMethod: 'background', // atau 'always latest', 'force update' maxVersions: 2 } } }; ``` Konfigurasi ini akan membantu Anda memetakan fitur AppFlow ke fitur yang setara di Capgo. ## Mengapa Migrasi ke Capgo? Dengan pengumuman penutupan Ionic AppFlow, migrasi ke Capgo menyediakan transisi yang lancar untuk alur kerja pengembangan aplikasi seluler Anda. Capgo menawarkan fitur yang ditingkatkan, kinerja yang lebih baik, dan penghematan biaya yang signifikan sambil mempertahankan semua fungsi penting yang Anda butuhkan. ### Manfaat Utama * Pengiriman pembaruan lebih cepat (< 1 menit vs 10 menit) * Harga lebih terjangkau ($14/bulan vs $499/bulan) * Enkripsi end-to-end termasuk dalam semua paket * Kontrol yang lebih baik atas saluran pembaruan * Opsi integrasi CI/CD yang lengkap ## Langkah-langkah Migrasi ### 1. Migrasi Pembaruan Langsung #### Hapus Dependensi Sebelumnya ```bash npm uninstall @ionic/appflow # Hapus konfigurasi khusus AppFlow dari capacitor.config.json ``` #### Pasang Capgo ```bash npm install @capgo/capacitor-updater npx cap sync ``` #### Perbarui Konfigurasi Tambahkan konfigurasi Capgo ke `capacitor.config.json` Anda: ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true } } } ``` ### 2. Migrasi CI/CD Capgo menawarkan opsi CI/CD yang fleksibel: #### Opsi 1: Gunakan CI/CD yang Ada Ikuti tutorial terperinci kami untuk menyiapkan CI/CD dengan platform populer: * [Pengaturan Build iOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) * [Pengaturan Build Android](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) * [Integrasi GitHub Actions](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) #### Opsi 2: CI/CD Terkelola Biarkan kami menangani pengaturan CI/CD Anda dengan [layanan terkelola](https://cal.com/team/capgo/mobile-ci-cd-done-for-you) kami. ### 3. Pengaturan Saluran 1. Buat saluran di dashboard Capgo: ```bash npx @capgo/cli channel create production npx @capgo/cli channel create staging ``` 2. Konfigurasi pengaturan saluran: ```bash # Atur saluran produksi npx @capgo/cli channel update production --no-downgrade --no-upgrade # Atur saluran staging npx @capgo/cli channel update staging ``` ### 4. Pengujian Migrasi 1. **Uji Pembaruan Langsung** ```bash # Buat dan unggah bundle pengujian npx @capgo/cli bundle create --channel staging ``` 2. **Verifikasi Penerimaan Pembaruan** * Pasang aplikasi di perangkat pengujian * Periksa bahwa pembaruan diterima dengan benar * Verifikasi proses pemasangan pembaruan * Uji fungsi pemulihan ## Pemecahan Masalah ### Masalah Umum #### Pembaruan Tidak Diterima * Periksa konfigurasi saluran * Periksa log perangkat * Pastikan konektivitas jaringan memadai * Validasi format versi bundle ## Langkah Selanjutnya 1. [Buat akun Capgo](/register/) 2. Ikuti [panduan mulai cepat](/docs/getting-started/quickstart/) kami 3. Siapkan [integrasi CI/CD](/docs/getting-started/cicd-integration/) 4. Konfigurasi [pembaruan langsung](/docs/live-updates/) Untuk tim perusahaan yang membutuhkan dukungan khusus selama migrasi, [jadwalkan panggilan dengan tim kami](https://cal.com/team/capgo/capgo-enterprise-inquiry). # V2 ke V3 > Cara Upgrade dari V2 ke V3 Dokumentasi ini akan menjelaskan cara meningkatkan ke versi 3 dari auto-update ## Pertama migrasikan ke tooling terbaru: ```bash npm remove -g capgo npm remove capacitor-updater npm i @capgo/cli npm i @capgo/capacitor-updater@3 npx cap sync ``` ## Hapus semua konfigurasi sebelumnya: ```json { CapacitorUpdater: { autoUpdateURL: "https", }, } ``` sehingga hanya tersisa ini: ```json { "CapacitorUpdater": { "autoUpdate": true } } ``` > ⚠️ Jika Anda menggunakan server Anda sendiri dengan `autoUpdateURL`, saya akan segera memperbarui panduan ini untuk Anda. Sementara itu, lihat opsi upload baru `external` yang memungkinkan Anda untuk hanya mengirim tautan zip Anda, bukan kode di Capgo cloud. Ini dibuat untuk perusahaan dengan kebijakan privasi yang ketat. Dalam mode external, kode tidak akan pernah masuk ke server Capgo, kami hanya menyimpan URL dan mengirimkannya ke perangkat, yang akan langsung mengunduhnya. Dalam cara standar, kode dikompresi dan disimpan di server kami, tetapi kami tidak akan pernah membukanya atau menggunakannya juga ## Apa yang berubah Semua konfigurasi menjadi server-side untuk auto-update, untuk memberi Anda lebih banyak kontrol tentang bagaimana Anda mengirim pembaruan ke pengguna Hal ini memungkinkan kita untuk mengembalikan, bahkan menerapkan hanya ke satu pengguna dengan channel! Pengaturan ini ditambahkan kembali ke antarmuka web: * menonaktifkan pengembalian di bawah native * menonaktifkan pembaruan di atas major > ⚠️ Mereka akan menjadi true secara default untuk semua channel Ini juga akan menghilangkan kebutuhan untuk sering memperbarui plugin, kebanyakan pembaruan akan dilakukan di sisi server, dan Anda akan mendapatkannya tanpa perubahan apa pun di sisi Anda > ⚠️ Reset ketika pembaruan menjadi default, jadi jika Anda lebih suka untuk tidak menghapus semua versi unduhan saat memperbarui dari toko, lakukan ini: ```json { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } ``` ## Perbarui kode Anda Terakhir, perbarui semua impor di JS dari: ```plaintext import { CapacitorUpdater } from 'capacitor-updater' ``` menjadi ```plaintext import { CapacitorUpdater } from '@capgo/capacitor-updater' ``` Kemudian build kode Anda lagi `npm run build` dan salin aset sekali lagi `npx cap copy` Sekarang Anda seharusnya bisa menguji sistem auto-update terbaru Kirim versi Anda dengan: ```plaintext npx @capgo/cli@latest bundle upload ``` alih-alih ```plaintext npx capgo upload ``` ## Evolusi mendatang Untuk saat ini hanya channel publik pertama yang digunakan, di masa depan, publik akan berubah untuk multi channel publik, jika lebih dari satu diatur ## Masalah umum: * Masalah build setelah upgrade: jika Anda sudah membuka source code plugin di Android studio atau Xcode, terkadang sync tidak menghapusnya, itu penyebab masalahnya. Buka IDE native dan hapus `capacitor-updater` secara manual dan lakukan `npx cap sync` ini seharusnya menyelesaikan masalah # V3 から V4 へ > Bagaimana Cara Mengupgrade dari V3 ke V4 ## Mengapa upgrade ini Setelah banyak diskusi di komunitas discord dengan Anda, saya menemukan mode manual sangat terlalu manual dan tidak aman untuk digunakan, misalnya, auto-revert tidak dimungkinkan, jadi jika Anda gagal memperbarui secara manual, pengguna harus menghapus aplikasi dan menginstal kembali, yang merupakan UX yang buruk Sementara itu, saya mengambil kesempatan ini untuk memberi Anda lebih banyak kebebasan, dan menghapus semua kode buruk yang saya buat ## Instalasi `npm i @capgo/capacitor-updater@4` ## Auto-update cloud Jika Anda menggunakan contoh dasar di aplikasi Anda, Anda aman untuk bermigrasi ke versi baru, selamat menikmati! ## Auto-update self-hosted Untuk Anda, tetap sederhana, perubahannya adalah: * Nama pengaturan dari `autoUpdateUrl` menjadi `updateUrl` * Metode Endpoint berubah dari `GET` ke POST ## Pengguna manual Untuk Anda, ini adalah perubahan yang paling signifikan, tetapi untuk yang terbaik! Anda mendapatkan banyak peningkatan, Baca dengan seksama ## Perubahan * `autoUpdateUrl` menjadi `updateUrl` karena pengaturan ini sekarang dapat digunakan dalam mode manual juga * Penghapusan `cancelDelay` dan `delayUpdate` digantikan oleh `setDelay` * Tidak ada lagi `versionName` dalam set * Perubahan kunci `version`, yang dikembalikan di sebagian besar fungsi ke objek `BundleInfo` ```typescript interface BundleInfo { id: string; version: string; downloaded: string; status: 'success' | 'error' | 'pending' | 'downloading' } ``` * Penamaan ulang nama yang menyesatkan sekarang (bahkan untuk menjelaskan tidak bisa jelas, tetapi pada penggunaan mudah memahami yang baru): * yang disebut `version` sekarang mengacu pada `bundle` * `id` mengacu pada `version` lama yang merupakan string acak 10 karakter, `id` ini adalah satu-satunya cara yang dapat dipercaya dan unik untuk mengakses bundle Anda, contoh `7Dfcd2RedN` * `version` sekarang mengacu pada `versionName` yang Anda pilih untuk bundle, contoh `100` * `updateUrl` berpindah dari `get` ke `post`, karena header kustom menjadi masalah bagi beberapa dari Anda dan post lebih logis, semua header sebelumnya masuk ke body dan prefix `cap_` menghilang * Metode `versionName` dihapus, digantikan oleh `getId` * list sekarang mengembalikan daftar `BundleInfo` * Mengganti nama `getId` menjadi `getDeviceId` * `autoUpdate` menjadi true secara default, jika Anda menggunakan mode Manual, atur ke false ## Berita * Metode `getLatest`, metode ini memungkinkan Anda mendapatkan dari server Anda yang diatur dengan `updateUrl` versi terakhir yang tersedia * Metode `setDelay` yang mengambil `{kind: "background" | "kill" | "nativeVersion" | "date", value?: string}` sebagai argumen untuk mengatur delay ke mode berbeda * Metode `next`, untuk mengatur versi di background berikutnya, berlawanan dengan `set` yang melakukannya secara instan * Metode `isAutoUpdateEnabled`, untuk memberi tahu Anda jika Anda berada dalam konteks auto-update * Event `downloadComplete` ketika download mencapai 100% * Menambahkan field wajib `version` dalam metode download * `notifyAppReady` menjadi wajib dalam mode manual juga, jika tidak dipanggil setelah 10 detik aplikasi kembali ke versi sebelumnya ## Kontributor [@lincolnthree](https://github.com/lincolnthree/) Terima kasih banyak telah memulai pekerjaan ini, tidak mungkin membuat pembaruan ini berhasil tanpa Anda # Dari V4 ke V5 > Cara Update dari V4 ke V5 ## Mengapa upgrade ini Versi major ini hadir untuk mengikuti versi major Capacitor Pertama ikuti panduan migrasi Capacitor: [https://capacitorjs.com/docs/updating/5-0](https://capacitorjs.com/docs/updating/5-0/) ## Instalasi `npm i @capgo/capacitor-updater@5` `Kemudian sinkronkan pembaruan kode native:` `npx cap sync` Itu saja! Sangat mudah! ## Mode manual Jika Anda mendapatkan pembaruan sendiri dengan getLatest, ada sedikit perubahan Sekarang jika Anda sudah memiliki versi terbaru, proses akan masuk ke catch Setiap respons yang berbeda dari pembaruan yang tersedia akan melakukan hal tersebut # De V5 à V6 > Bagaimana cara memperbarui dari V5 ke V6 ## Mengapa upgrade ini Versi mayor ini hadir untuk mengikuti versi mayor Capacitor Pertama ikuti panduan migrasi Capacitor: [https://capacitorjs.com/docs/updating/6-0](https://capacitorjs.com/docs/updating/6-0/) ## Instalasi `npm i @capgo/capacitor-updater@6` `Kemudian sinkronkan pembaruan kode native:` `npx cap sync` Selesai! Sangat mudah! # Pendahuluan > Pengenalan Aplikasi Web Cagpo ## Apa ini? Capgo memiliki webapp yang lengkap untuk membantu Anda mengelola proyek Anda. Webapp ini dibangun dengan Vuejs dan bersifat open source. Anda dapat menemukan kode sumbernya di [GitHub](https://github.com/Cap-go/capgo/tree/main/src/)\ Webapp tersedia [di sini](https://web.capgo.app/)\ Webapp ini memungkinkan Anda untuk [mengelola channel](/docs/webapp/channels/), [mengelola versi](/docs/webapp/bundles/), [mengelola perangkat](/docs/webapp/devices/), [memeriksa log](/docs/webapp/logs/), [mengelola billing](/docs/webapp/settings/) dan [mengelola akun Anda](/docs/webapp/settings/) ## Bagaimana cara menggunakannya? Pertama, Anda perlu membuat akun atau masuk. Ini relatif sederhana dan dapat dilakukan dengan mengklik tombol `Log in` di tengah layar. Setelah Anda masuk, Anda akan diarahkan ke dashboard. Ini adalah halaman utama webapp. Dari sini Anda dapat menavigasi ke semua halaman lainnya ![login page](/login.webp) ## Membuat akun Anda harus mengklik `Create a free account` di bagian bawah formulir login. Setelah itu akan sangat sederhana seperti mengisi formulir dan mengikuti instruksi ![create account](/create-account.webp) # API-Schlüssel verwalten > Cara Mengelola API Key ## Apa yang bisa saya lakukan dengan kunci api? Kunci API dapat dibuat ulang, dihapus atau bisa ditambahkan yang baru ## Bagaimana cara melihat semua kunci api? Anda perlu mengunjungi [halaman kunci API](https://web.capgo.app/dashboard/apikeys/) dan di sana Anda akan melihat semua kunci api Anda ## Bagaimana cara menambahkan kunci api baru? Untuk menambahkan kunci API baru klik pada tombol plus kecil ![add apikey](/apikeys-add.webp) dan kemudian pilih izin yang ingin Anda berikan ke kunci API baru. Anda dapat memilih: * Read - kunci API akan dapat membaca semua data * Upload - kunci API akan dapat mengunggah versi baru dari CLI dan membaca * All - Kunci API akan dapat melakukan semuanya ![select perm](/apikeys-select-perm.webp) ## Bagaimana cara menghapus kunci api? Untuk menghapus kunci API klik pada tombol sampah kecil ![remove apikey](/apikeys-remove.webp) Dan kemudian konfirmasi penghapusan kunci API ## Bagaimana cara membuat ulang kunci api? Untuk membuat ulang kunci API klik pada tombol refresh kecil ![generate apikey](/apikeys-regenerate.webp) Dan kemudian konfirmasi pembuatan ulang kunci API # Bundel > Pelajari cara mengelola bundle ## Tampilkan semua bundle Pertama, mari kita lihat halaman bundle. Anda dapat mengaksesnya dengan [mengklik aplikasi Anda](/docs/webapp/main-page) dan kemudian [mengklik tab bundle](/docs/webapp/main-app-page) ![bundle list](/bundles.webp) ## Menghapus bundle Ada dua cara untuk menghapus bundle: * Secara normal * Secara tidak aman Cara penghapusan bundle secara tidak aman ditambahkan ke Capgo pada 12 Agustus 2024 Perbedaan antara kedua cara tersebut adalah kemampuan untuk menggunakan kembali nomor versi setelah penghapusan Sebagai contoh, jika Anda menghapus versi `100` dengan cara normal dan kemudian mencoba mengunggah versi `100`, ini akan gagal Jika Anda menghapus versi ini melalui penghapusan tidak aman, Anda akan dapat mengunggah versi `100` Danger Menghapus versi secara tidak aman dan mengunggah ulang SANGAT berbahaya Ini dapat menyebabkan berbagai jenis bug dan perilaku yang tidak terprediksi dalam plugin JANGAN PERNAH digunakan untuk bundle yang telah digunakan dalam channel publik Karena alasan ini, menghapus versi secara tidak aman memerlukan hak akses “super\_admin” ## Mengelola bundle tertentu Setelah Anda melihat daftar semua bundle, klik pada bundle yang ingin Anda kelola. Setelah itu, Anda akan melihat tampilan seperti ini: ![bundle info](/bundle-info.webp) Mari kita bahas semua elemen di halaman ini *** Pertama, Anda dapat melihat `Channel`. Ini memberi tahu Anda channel mana bundle ini ditujukan. Anda dapat mengubah channel dengan mengkliknya Setelah Anda mengkliknya, Anda akan melihat tampilan seperti ini: ![bundle change](/bundle-change.webp) `Set bundle to channel` akan memungkinkan Anda menghubungkan bundle ini sebagai default untuk channel manapun\ `Open channel` akan membuka halaman channel untuk channel yang dituju bundle ini\ `Unlink bundle from channel` akan memutuskan hubungan bundle ini dari channel yang dituju (**PERINGATAN**: Jika bundle terhubung ke lebih dari 1 channel, maka Anda tidak akan diberi pilihan channel mana yang akan diputus hubungannya) *** Selanjutnya, Anda dapat melihat `Size`. Jika Anda mengkliknya, Anda akan dapat mengunduh bundle ini Tampilannya akan seperti ini: ![download bundle](/download-bundle.webp) *** Terakhir, ada bagian `Devices`. Anda dapat melihat semua perangkat yang menggunakan versi ini di sana # Canali > Channel adalah cara untuk mengelola pembaruan aplikasi Anda. Anda dapat memiliki beberapa channel dan setiap channel dapat memiliki beberapa versi. Ini memungkinkan Anda untuk menjalankan beberapa versi aplikasi secara bersamaan di lingkungan produksi. ## Mengelola Channel Pertama, mari kita lihat halaman channel. Anda dapat mengaksesnya dengan [mengklik aplikasi Anda](/docs/webapp/main-page) dan kemudian [mengklik tab channel](/docs/webapp/main-app-page) ![channel list](/channels.webp) ## Membuat Channel Seperti yang Anda lihat, ada tombol plus di pojok kanan bawah (`1` dalam gambar). Mengklik tombol tersebut akan membuka modal di mana Anda dapat membuat channel baru ![new channel](/new_channel_modal.webp) Kemudian setelah Anda mengklik `Add` channel baru akan muncul dalam daftar ![after channel create](/post-channel-create.webp) ## Apa arti misconfigured? Terkadang konfigurasi channel tidak valid. Dalam kasus tersebut, Anda akan mendapatkan peringatan besar dan kolom `Misconfigured` akan menunjukkan `Yes` untuk satu atau lebih channel. Anda dapat mempelajari lebih lanjut tentang hal ini [di sini](/docs/cli/commands/#disable-updates-strategy) ## Menghapus Channel Menghapus channel sangat mudah. Cukup klik ikon sampah dan konfirmasi penghapusan (`2` dalam gambar) ## Mengelola Channel Mengklik nama channel akan membuka modal di mana Anda dapat mengelola channel (`3` dalam gambar) Halaman ini seharusnya terlihat seperti ini: ![manage channel](/manage_channel_main.webp) Mari kita bahas bagian-bagian yang berbeda Pertama `Bundle number` (`1` dalam gambar). Ini adalah versi saat ini untuk channel tersebut. Ketika diminta untuk memberikan pembaruan, channel ini akan selalu mencoba merespon dengan versi tersebut\* \[^1] Mengkliknya akan membawa Anda ke halaman [bundle](/docs/webapp/bundles/) Kedua halaman `Shared to` (`2` dalam gambar). Saya sarankan untuk tidak menggunakannya. Sistem baru dan lebih baik sedang dikembangkan Sekarang forced devices (`3` dalam gambar). Ini adalah daftar perangkat yang akan selalu mendapatkan pembaruan dari channel ini. Ini berguna untuk tujuan pengujian. Anda dapat memaksa perangkat ke channel dari halaman [devices](/docs/webapp/devices/) Terakhir pengaturan (`4` dalam gambar). Di sinilah Anda dapat mengatur bagaimana channel berperilaku Setelah Anda mengkliknya, Anda seharusnya melihat sesuatu seperti ini: ![setting of channel](/channel_settings.webp) Daftar pengaturan cukup panjang, tapi saya akan berusaha menjelaskan semuanya *** Pertama `Default channel` **INI MUNGKIN YANG PALING PENTING**\ Jika channel ditandai sebagai default, maka akan digunakan sebagai channel default untuk semua perangkat baru\ Dalam istilah lain: Jika Anda memiliki pengguna baru, capgo akan mencoba memberikan versi terbaru dari channel default ini Hanya 1 channel yang dapat diatur sebagai default pada satu waktu. Jika Anda mencoba melanggar aturan ini, Anda akan diminta untuk mengkonfirmasi tindakan Anda ![confirm make change](/confirm-make-default.webp) Setelah Anda mengkonfirmasi, channel default lama akan tidak ditandai sebagai default dan yang baru akan ditandai sebagai default *** Kedua pengaturan `IOS`. Ini cukup sederhana. Jika ini false maka perangkat IOS tidak akan diizinkan mengunduh pembaruan dari channel ini Ketiga adalah pengaturan `Android`. Ini mirip dengan `IOS`. Jika ini false maka perangkat Android tidak akan diizinkan mengunduh pembaruan dari channel ini Keempat adalah pengaturan `Disable auto downgrade under native`. Jika ini true maka akan tidak mungkin untuk menurunkan versi dari versi native. Ini berarti jika Anda telah mengunggah versi `120` ke app store atau play store dan mencoba mengatur versi channel ke `110` maka pembaruan (downgrade) akan gagal Kelima adalah `Disable auto update`. Pengaturan ini cukup kompleks, dan Anda dapat mempelajari lebih lanjut tentang hal ini [di sini](/docs/cli/commands/#disable-updates-strategy) Untuk `Allow develoment build`. Jika ini true maka build pengembangan akan diizinkan mengunduh pembaruan dari channel ini. Jika tidak maka setiap permintaan pembaruan yang memiliki `prod` diatur ke false akan ditolak. Ini sebagian besar berguna untuk tujuan pengujian Ketujuh adalah `Allow Emulators`. Jika ini false maka capgo akan menolak setiap permintaan pembaruan yang berasal dari emulator. Ini sebagian besar berguna untuk tujuan pengujian Kedelapan adalah `Allow devices to self associate`. Jika ini true maka metode [setChannel](/docs/plugin/api/#setchannel) akan tersedia. Jika ini diatur ke false dan Anda mencoba memanggil metode [setChannel](/docs/plugin/api/#setchannel) dengan channel ini maka panggilan akan gagal # Perangkat > Cara menggunakan halaman Device ## Tampilkan daftar semua perangkat Pertama, mari kita lihat halaman perangkat. Anda dapat mengaksesnya dengan [mengklik aplikasi Anda](/docs/webapp/main-page) dan kemudian [mengklik tab perangkat](/docs/webapp/main-app-page) ![devices list](/devices.webp) ## Tampilkan hanya perangkat pengembang Anda mungkin ingin menampilkan hanya perangkat yang ditimpa (Perangkat yang memiliki [channel kustom](/docs/plugin/api/#setchannel) atau versi kustom) Untuk melakukan itu klik pada `Filters` dan kemudian pada `Override`. Tampilannya akan seperti ini: ![filter devices](/overwrite-filter.webp) ## Mengkonfigurasi perangkat Untuk mengkonfigurasi perangkat tertentu klik pada perangkat tersebut di tabel dan Anda akan melihat tampilan seperti ini: ![show one device](/device-specific.webp) Pertama `Custom ID`. Ini tidak terlalu berguna, dan saat ini tidak melakukan apa-apa. Anda dapat mengabaikannya Selanjutnya force version. Jika ini diatur maka perangkat ini akan **SELALU** menerima versi ini. Ini lebih diprioritaskan dibanding channel Terakhir channel kustom. Jika ini diatur maka perangkat ini tidak akan peduli dengan channel publik (default) dan hanya akan menggunakan channel ini # Log > Pelajari cara menggunakan halaman log ## Tampilkan semua log Pertama, mari kita lihat halaman log. Anda dapat mengaksesnya dengan [mengklik aplikasi Anda](/docs/webapp/main-page) dan kemudian [mengklik tab pembaruan](/docs/webapp/main-app-page) Dari sana Anda akan melihat halaman seperti ini: ![show logs](/logs.webp) ## Mendapatkan detail lebih lanjut tentang log Jika Anda mengklik sebuah log, itu akan membawa Anda ke [halaman perangkat](/docs/webapp/devices/) # メインアプリページ > Apa yang ditampilkan pada halaman utama? ## Apa yang ditampilkan di halaman utama? Pertama, mari kita lihat halaman utama aplikasi: ![Main page screeshot](/main-app-page.webp) Mari kita lihat lebih detail Pertama statistik. Statistik sedang dirombak sehingga belum bisa didokumentasikan saat ini. Kami akan menambahkan bagian statistik ketika sudah sepenuhnya beroperasi. Kedua, mari kita lihat semua menu yang tersedia dan fungsinya ![Multiple sections screeshot](/app-multiple-sections.webp) Tombol pertama akan membawa Anda ke halaman [channels](/docs/webapp/channels/). Anda dapat membuat/menghapus/mengkonfigurasi channel aplikasi di sana\ Tombol kedua akan membawa Anda ke halaman [bundles](/docs/webapp/bundles/). Anda dapat melihat semua versi aplikasi di sana Tombol kedua akan membawa Anda ke halaman [device](/docs/webapp/devices/). Anda dapat melihat semua perangkat di sana. Anda juga dapat mengatur pengaturan khusus perangkat dari sana Tombol kedua akan membawa Anda ke halaman [updates](/docs/webapp/logs/). Anda dapat melihat statistik detail (log) dan kesalahan yang dialami aplikasi Anda dari sana # Halaman Utama > Halaman ini menjelaskan tentang halaman utama aplikasi web ## Apa yang ditampilkan halaman utama? Pertama, mari kita lihat halaman utama: ![Main page screeshot](/main-page.webp) Mari kita mulai dari awal. Hal pertama yang Anda lihat adalah **statistik**. Ini berisi statistik khusus aplikasi. Pembaruan tersebut bergantung pada penggunaan aplikasi. Hal kedua yang Anda lihat adalah daftar semua aplikasi yang tersedia. Ini akan berubah tergantung pada berapa banyak aplikasi yang telah Anda buat. Anda dapat mengklik setiap aplikasi untuk melihat detail lebih lanjut tentangnya. Hal ketiga yang Anda lihat adalah tombol **API keys**. Tombol ini akan membawa Anda ke halaman [API keys](/docs/webapp/api-keys/). Hal berikutnya yang Anda lihat adalah tombol **test Capgo**. Tombol ini akan berubah tergantung pada nama depan dan nama belakang Anda dan akan membawa Anda ke halaman [pengaturan](/docs/webapp/settings/) atau dukungan. Terakhir, Anda melihat tombol untuk menambahkan aplikasi lain. Tombol ini akan membawa Anda ke halaman di mana Anda dapat menambahkan aplikasi baru ke Capgo. # Autentikasi dua faktor > Mengelola autentikasi dua faktor untuk melindungi akun capgo Anda dengan lebih baik. ## Apa itu 2FA? 2FA adalah langkah keamanan yang dirancang untuk mencegah pihak yang tidak bertanggung jawab mengambil alih akun capgo Anda\ Ini dicapai dengan meminta kode tambahan. Kode ini disimpan di ponsel Anda atau kunci perangkat keras 2FA. Kode berubah setiap 30 detik, sehingga tidak mungkin ditebak ## Persyaratan untuk panduan ini * Ponsel Android atau IOS * Koneksi internet ## Apa yang akan dibahas dalam panduan ini? Panduan ini akan menunjukkan cara mengatur 2FA menggunakan `Google Authenticator`. Ada aplikasi lain yang berfungsi serupa, namun saya tidak bisa membahas seluruh topik 2FA dalam panduan ini ## Bagaimana cara mengatur 2FA? Pertama unduh aplikasi `Google Authenticator`. Jika Anda menggunakan Android, Anda dapat mengunduhnya dari [play store](https://play.google.com/store/apps/details/?id=comgoogleandroidappsauthenticator2). Pada IOS Anda dapat mengunduhnya dari [App store](https://appsapplecom/us/app/google-authenticator/id388497605/) Kedua, silakan buka [pengaturan akun capgo](https://web.capgo.app/dashboard/settings/account/). Di sana Anda akan melihat tombol hijau yang terlihat seperti ini ![Button MFA](/button-mfa.webp) Klik tombol tersebut, dan setelah itu, kode QR akan muncul ![Enable MFA](/enable-mfa.webp) Danger ⚠️ Catatan Penting:\ Jangan pernah membagikan kode QR ini dengan siapa pun, atau Anda bisa terlogout dari akun Anda Selanjutnya, buka `Google Authenticator` di ponsel Anda. Setelah itu, ikuti langkah-langkah berikut: Klik tombol plus ![MFA auth plus](/mfa-auth-plus.webp) Setelah itu, silakan klik tombol kamera ![MFA scan QR](/mfa-scan-qr.webp) Itu akan membuka pratinjau kamera. Silakan pindai kode QR yang ditampilkan di PC Anda. Setelah melakukan itu, Anda akan melihat sesuatu seperti ini: ![MFA final code](/mfa-final-code.webp) Kemudian silakan kembali ke PC dan klik tombol verifikasi ![Verify MFA](/enable-mfa-verify.webp) Ini akan membuka jendela untuk mengetikkan kode 2FA kita. Dalam kasus saya, kode ini adalah `095101` tetapi akan berbeda untuk Anda\ Setelah Anda mengetikkan kode ini, silakan klik tombol `verify` ![MFA verify code final](/mfa-verify-final-code.webp) Jika Anda memasukkan kode yang benar dan menekan `verify`, Anda akan melihat pop-up seperti ini ![MFA enabled](/mfa-enabled.webp) Selamat!\ Anda telah mengaktifkan autentikasi 2FA 🎉 ## Cara login menggunakan 2FA Saat berikutnya Anda login ke akun Anda, Anda akan melihat jendela seperti ini ![MFA required](/mfa-required.webp) Silakan buka authenticator dan salin kode auth Anda ![MFA login](/mfa-login.webp) Danger ⚠️ Catatan Penting:\ Tekan `verify` sebelum kode diperbarui, jika tidak kode akan berubah, dan kode lama tidak akan valid lagi Kemudian masukkan kode tersebut ke dalam formulir login dan tekan `verify` ![MFA login](/mfa-final-login-verify.webp) Jika Anda memasukkan kode yang benar, Anda akan melihat dashboard capgo ## Cara menonaktifkan 2FA Untuk menonaktifkan 2FA silakan pergi ke [pengaturan akun capgo](https://web.capgo.app/dashboard/settings/account/). Di sana Anda akan melihat tombol merah yang terlihat seperti ini: ![MFA disable button](/mfa-disable-button.webp) Klik tombol tersebut, dan Anda akan melihat layar seperti ini ![MFA disabled](/mfa-disable-2.webp) Cukup tekan tombol `disable`, dan selesai # 조직 시스템 > Mengelola organisasi di akun capgo Anda. ## Apa itu sistem organisasi? Sistem organisasi adalah sistem di capgo yang memungkinkan Anda untuk berbagi aplikasi secara aman dengan anggota tim Anda ### Q: Bagaimana cara mengakses info organisasi saya? Untuk mengakses info organisasi Anda, silakan pergi ke [pengaturan](/docs/webapp/settings/#how-to-get-to-the-settings-page) lalu klik `Organization settings` ![Org settings](/orgs-settings.webp) ### Q: Bagaimana cara mengganti organisasi yang saya lihat? Untuk melihat pengaturan organisasi yang berbeda, silakan klik pemilih organisasi di dekat nama Anda ![Org selector](/org-selector.webp) Jika Anda tidak dapat melihat ini, kemungkinan Anda tidak berada di halaman pengaturan ### Q: Bagaimana cara melihat anggota organisasi saya? Silakan klik `members` ![Org Show members](/org-show-members.webp) ### Q: Bagaimana cara mengundang pengguna ke organisasi? Silakan klik `Add member` ![Org add member](/orgs-add-member.webp) Kemudian pop-out akan muncul - silakan masukkan alamat email pengguna ![Invite to org](/invite-to-org-email-enter.webp) Lalu klik `invite` Pop-out lain akan muncul, kali ini menanyakan tentang izin yang harus dimiliki pengguna yang diundang ![Select perm for org](/select-perm-orgs.webp) Berikut adalah rincian semua izin: | Izin | Read | Upload | Write | Admin | Super Admin | | ----------------------------- | ---- | ------ | ----- | ----- | ----------- | | Tampilkan statistik aplikasi | ✅ | ✅ | ✅ | ✅ | ✅ | | Tampilkan channel aplikasi | ✅ | ✅ | ✅ | ✅ | ✅ | | Tampilkan perangkat | ✅ | ✅ | ✅ | ✅ | ✅ | | Tampilkan log | ✅ | ✅ | ✅ | ✅ | ✅ | | Tampilkan bundle | ✅ | ✅ | ✅ | ✅ | ✅ | | Hapus aplikasi | ❌ | ❌ | ❌ | ❌ | ✅ | | Hapus channel | ❌ | ❌ | ❌ | ✅ | ✅ | | Hapus versi | ❌ | ❌ | ✅ | ✅ | ✅ | | Ubah pengaturan org | ❌ | ❌ | ❌ | ✅ | ✅ | | Kelola pengguna org | ❌ | ❌ | ❌ | ✅ | ✅ | | Ubah pengaturan channel | ❌ | ❌ | ✅ | ✅ | ✅ | | Unggah versi baru | ❌ | ✅ | ✅ | ✅ | ✅ | | Ubah perangkat | ❌ | ❌ | ✅ | ✅ | ✅ | | Ubah versi saat ini channel | ❌ | ❌ | ✅ | ✅ | ✅ | | Buat channel baru | ❌ | ❌ | ❌ | ✅ | ✅ | | Ubah versi (metadata) | ❌ | ❌ | ✅ | ✅ | ✅ | | Kelola penagihan | ❌ | ❌ | ❌ | ❌ | ✅ | | Hapus versi secara tidak aman | ❌ | ❌ | ❌ | ❌ | ✅ | ### Q: Bagaimana penagihan dilakukan dalam organisasi? Siapa pun dengan izin **super admin** dapat mengelola penagihan untuk organisasi tertentu Paket terhubung ke organisasi dan bukan ke akun pribadi Anda Danger ⚠️ Membeli paket HANYA akan mempengaruhi organisasi yang saat ini Anda pilih ### Q: Bisakah saya membuat lebih dari satu organisasi? Tidak, belum bisa # Sistem pembayaran > Manajemen pembayaran di akun Capgo Anda. ## Tentang apa ini? Halaman ini bertujuan untuk menjawab beberapa pertanyaan tentang sistem pembayaran di capgo #### Q: Bagaimana cara meningkatkan paket capgo saya? A: Anda dapat meningkatkan paket capgo dengan membuka [pengaturan](/docs/webapp/settings/#how-to-get-to-the-settings-page) dan mengklik tombol **Plans** ![Choose plan](/plans-button.webp) Kemudian Anda dapat memilih paket yang paling sesuai dengan kebutuhan Anda dan klik **Subscribe** ![Subscribe to plan](/plans-subscribe.webp) Kemudian halaman stripe akan terbuka. Di sana, Anda dapat memasukkan informasi pembayaran Anda ![Stripe portal](/plans-stripe.webp) #### Q: Apakah pembayaran aman? A: Ya, pembayaran sepenuhnya dikelola oleh stripe. Capgo tidak pernah mendapatkan akses ke detail kartu kredit Anda. Stripe sangat serius menangani keamanan. [Pelajari lebih lanjut tentang kebijakan keamanan stripe](https://stripecom/docs/security/) #### Q: Apakah capgo akan secara otomatis meningkatkan paket saya ketika melebihi batas? A: Tidak, capgo tidak akan pernah mengubah paket Anda #### Q: Apakah capgo akan mengirimkan email ketika paket saya mendekati batasnya? A: Ya, capgo akan mengirimkan email yang menginformasikan tentang penggunaan Anda #### Q: Apakah paket yang saya beli akan mempengaruhi organisasi yang saya diundang? A: Tidak, paket hanya akan mempengaruhi organisasi yang saat ini Anda pilih. Silakan merujuk ke [dokumentasi organisasi](/docs/webapp/organization-system/#q-how-is-billing-done-within-orgs) #### Q: Bagaimana jika saya membutuhkan paket yang lebih disesuaikan? A: [Silakan hubungi dukungan capgo secara langsung](/docs/getting-help#support-by-chat) #### Q: Bagaimana kebijakan pengembalian dana untuk capgo? A: Kebijakan pengembalian dana dapat ditemukan [di sini](https://capgo.app/return/) # Pengaturan > Cara Mengganti Pengaturan Pengguna ## Cara menuju halaman pengaturan Pertama klik pada **NAMA\_DEPAN NAMA\_BELAKANG** Dalam kasus saya ini adalah **test Capgo** Dalam kasus Anda, ini akan menjadi nama depan dan nama belakang Anda Kemudian klik pada **Settings** ![open settings](/settings-go.webp) ## Mengubah pengaturan pengguna Untuk mengubah pengaturan pengguna, Anda cukup mengisi formulir di akun dan kemudian klik **Update** ![save change in account](/account-save.webp) Kemudian konfirmasi akan muncul ![acount updated](/account-updated.webp) ## Mengubah kata sandi Untuk mengubah kata sandi, pergi ke halaman pengaturan dan klik **Password** Kemudian isi formulir dan klik **Update** ![update password](/update-passwd.webp) Ketika kata sandi tidak mengikuti aturan keamanan kata sandi capgo, Anda akan mendapatkan pesan kesalahan ![wrong password](/passwd-error.webp) # Capgoへようこそ > Capgo es una plataforma de código abierto de actualizaciones en tiempo real para Capacitor y equipos de desarrollo móvil, que permite entregar actualizaciones a los usuarios en minutos en lugar de días La potenza dell'aggiornamento in tempo reale Distribuisci senza interruzioni aggiornamenti dell’app in tempo reale, correzioni di bug critici, modifiche ai contenuti, funzionalità beta e altro ancora per offrire ai tuoi utenti la migliore esperienza possibile Facile da integrare Il plugin richiede 3 passaggi per essere integrato nel tuo codice e ti permette di inviare aggiornamenti ai tuoi utenti in pochi minuti invece che in giorni! Installazione Esegui `npx @capgo/cli@latest init [APIKEY]` per iniziare Documentazione completa Impara nella [Documentazione](/docs/getting-started/quickstart/) come padroneggiare il plugin in 5 minuti con il nostro video di onboarding # Comandi > Capgo CLI Documentation ### Utilizzo Tutti i comandi devono essere eseguiti nella cartella della tua app con il progetto Capacitor correttamente inizializzato [Capacitor Cross-platform native runtime for web apps ](https://capacitorjs.com/docs/getting-started/) ### **Init** `npx @capgo/cli@latest init [apikey]` Questo metodo serve per guidarti passo dopo passo Aggiungerà la tua app a Capgo Aggiungerà il codice alla tua app per validare l’aggiornamento Inoltre, compilerà la tua app Successivamente, caricherà la tua app su Capgo E ti aiuterà a verificare se l’aggiornamento funziona ### **Login** `npx @capgo/cli login [apikey]` Questo metodo serve a memorizzare l’`apikey` per te Note usa `--apikey=********` in qualsiasi comando per sovrascriverla **Opzionalmente puoi fornire:** `--local` Questo memorizzerà la tua **apikey** nel repository locale e la ignorerà in git ## **Doctor** `npx @capgo/cli doctor` Comando per verificare se sei aggiornato con i pacchetti Capgo Questo comando sarà utile anche per le segnalazioni di bug ## App ### **Add** `npx @capgo/cli app add [appId]` `[appId]` il tuo ID app il formato `comtestapp` è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) > 💡 Tutte le opzioni verranno dedotte dalla tua configurazione se non fornite Opzionalmente, puoi fornire: * `--icon [/path/to/my/icon]` per avere un’icona personalizzata visualizzata nell’app web Capgo * `--name [test]` per avere un nome personalizzato nella lista * `--apikey [key]` chiave API da collegare al tuo account * `--retention [retention]` periodo di conservazione del bundle dell’app in giorni, 0 di default = infinito Esempio di `capacitorconfigjson` per appId e AppName, l’icona viene cercata nella cartella resources ```json { "appId": "eeforgrcapacitor_go", "appName": "Capgo", "webDir": "dist" } ``` ### **Set** `npx @capgo/cli app set [appId]` `[appId]` è il tuo ID app, il formato è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) Opzionalmente, puoi fornire: * `--icon [/path/to/my/icon]` per avere un’icona personalizzata visualizzata nell’app web Capgo * `--name [test]` per avere un nome personalizzato nella lista * `--retention [retention]` periodo di conservazione del bundle dell’app in giorni, 0 di default = infinito * `--apikey [key]` chiave API da collegare al tuo account ### **List** `npx @capgo/cli app list [appId]` `[appId]` il tuo ID app il formato `comtestapp` è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) Opzionalmente, puoi fornire: * `--apikey [key]` chiave API da collegare al tuo account ### **Delete** `npx @capgo/cli app delete [appId]` `[appId]` il tuo ID app il formato `comtestapp` è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) Opzionalmente, puoi fornire: * `--apikey [key]` chiave API da collegare al tuo account * `--bundle` con il numero di versione eliminerà solo questa versione ### Debug `npx @capgo/cli app debug [appId]` `[appId]` il tuo ID app il formato `comtestapp` è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) Opzionalmente, puoi fornire: * `--apikey [key]` chiave API da collegare al tuo account * `--device` con il dispositivo specifico che vuoi debuggare ### Setting `npx @capgo/cli app setting [path]` Modifica la configurazione di Capacitor `[path]` - percorso dell’impostazione che vorresti modificare Per esempio, per modificare l’`appId`, fornisci `appId` Se desideri disabilitare l’aggiornamento automatico in `capacitor-updater` fornisci `pluginsCapacitorUpdaterautoUpdate` DEVI fornire o `--string` o `--bool`! Opzioni: * `--string ` - imposta l’impostazione come stringa * `--bool ` - imposta l’impostazione come booleano ## Bundle ### Upload `npx @capgo/cli bundle upload [appId]` `[appId]` è il tuo ID app, il formato è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) Opzionalmente, puoi fornire: * `--apikey ` chiave API da collegare al tuo account * `--path ` Percorso della cartella da caricare * `--channel ` Canale da collegare * `--external ` Collega a URL esterno invece di caricare su Capgo Cloud * `--iv-session-key ` Imposta la IV e la chiave di sessione per l’URL del bundle esterno * `--s3-endpoint ` URL dell’endpoint S3 Non funziona con il caricamento parziale o l’opzione external * `--s3-region ` Regione per il tuo bucket S3 * `--s3-apikey ` Chiave API per il tuo endpoint S3 * `--s3-apisecret ` Segreto API per il tuo endpoint S3 * `--s3-bucket-name ` Nome per il tuo bucket AWS S3 * `--s3-port ` Porta per il tuo endpoint S3 * `--no-s3-ssl` Disabilita SSL per il caricamento S3 * `--key ` Percorso personalizzato per la chiave di firma pubblica (sistema v1) * `--key-data ` Chiave di firma pubblica (sistema v1) * `--key-v2 ` Percorso personalizzato per la chiave di firma privata (sistema v2) * `--key-data-v2 ` Chiave di firma privata (sistema v2) * `--bundle-url` Stampa l’URL del bundle nello stdout * `--no-key` Ignora la chiave di firma e invia l’aggiornamento in chiaro * `--no-code-check` Ignora il controllo se notifyAppReady() è chiamato nel codice sorgente e index presente nella cartella root * `--display-iv-session` Mostra nella console la IV e la chiave di sessione utilizzate per crittografare l’aggiornamento * `--bundle ` Numero di versione del bundle da caricare * `--min-update-version ` Versione minima richiesta per aggiornare a questa versione Usato solo se l’aggiornamento automatico è disabilitato nei metadati del canale * `--auto-min-update-version` Imposta la versione minima di aggiornamento basata sui pacchetti nativi * `--ignore-metadata-check` Ignora il controllo dei metadati (node\_modules) durante il caricamento * `--ignore-checksum-check` Ignora il controllo del checksum durante il caricamento * `--timeout ` Timeout per il processo di caricamento in secondi * `--partial` Non carica file parziali su Capgo cloud * `--tus` Carica il bundle usando il protocollo tus * `--multipart` Usa il protocollo multipart per caricare dati su S3, Deprecato, usa TUS invece * `--encrypted-checksum ` Un checksum crittografato (firma) Usato solo quando si carica un bundle esterno * `--package-json ` Un percorso verso packagejson Utile per i monorepo * `--auto-set-bundle` Imposta il bundle in capacitorconfigjson * `--node-modules ` Una lista di percorsi verso node\_modules Utile per i monorepo (separati da virgola es: //node\_modules,/node\_modules) > ⭐️ L’opzione external aiuta a sbloccare 2 casi: aziende con preoccupazioni sulla privacy, non inviano il codice a terze parti e app più grandi di 200 MB Con questa impostazione, Capgo memorizza solo il link allo zip e invia il link a tutte le app > 👀 Capgo cloud non guarda mai cosa c’è nel link (per l’opzione external), o nel codice quando è memorizzato > 🔑 Puoi aggiungere un secondo livello di sicurezza usando la crittografia, quindi Capgo non sarà in grado di guardare o modificare nulla, diventa “trustless” Esempio di `packagejson` per la versione ```json { "version": "102" } ``` > ⛔ La versione deve essere maggiore di “000” > 💡 Non dimenticare di aggiornare il numero di versione ogni volta che ne invii uno, il numero di versione non può essere sovrascritto o riutilizzato dopo l’eliminazione per motivi di sicurezza ### **List** `npx @capgo/cli bundle list [appId]` `[appId]` il tuo ID app il formato `comtestapp` è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) Opzionalmente, puoi fornire: * `--apikey [key]` chiave API da collegare al tuo account ### **Delete** `npx @capgo/cli bundle delete [appId]` `[appId]` il tuo ID app il formato `comtestapp` è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) Opzionalmente, puoi fornire: * `--apikey [key]` chiave API da collegare al tuo account * `--bundle` con il numero di versione eliminerà solo questa versione ### Cleanup in un intervallo SemVer per una versione major su Cloud `npx @capgo/cli bundle cleanup [appId] --bundle=[majorVersion] --keep=[numberToKeep]` `[appId]` il tuo ID app il formato `comtestapp` è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) Opzionalmente, puoi fornire: * `--apikey [key]` chiave API da collegare al tuo account * `--bundle [majorVersion]` una versione per cui desideri rimuovere i pacchetti precedenti, manterrà l’ultimo + `numberToKeep`\* `--keep [numberToKeep]` il numero di pacchetti che desideri mantenere (predefinito 4) Per esempio: Se hai 10 versioni da 1001 a 10011, e usi `npx @capgo/cli cleanup [appId] --bundle=1000` rimuoverà da 1001 a 1006 mentre 1007 fino a 10011 verranno mantenuti Se hai 20 versioni in totale, e non fornisci un numero di bundle come questo: `npx @capgo/cli cleanup [appId] --keep=2` Rimuoverà 18 versioni e manterrà le ultime 2 > Questo comando chiederà conferma, mostra una tabella di ciò che manterrà e rimuoverà Note Questo comando ignorerà i bundle attualmente in uso in qualsiasi canale ### **Encrypt** > **Attenzione**: Questo comando è deprecato e verrà rimosso nella prossima versione maggiore. Si prega di utilizzare il nuovo sistema di crittografia `npx @capgo/cli bundle encrypt [path/to/zip]` Questo comando viene utilizzato quando si usa una fonte esterna per memorizzare il codice o per scopi di test Opzionalmente, puoi fornire: `--key [/path/to/my/private_key]` il percorso della tua chiave privata `--key-data [privateKey]` i dati della chiave privata, se vuoi usarla inline Il comando stamperà il tuo `ivSessionKey` e genererà uno zip crittografato, da utilizzare con il comando upload o decrypt ### **Encrypt V2** `npx @capgo/cli bundle encryptV2 [path/to/zip] [checksum]` Questo comando viene utilizzato quando si usa una fonte esterna per memorizzare il codice o per scopi di test Il checksum è lo sha256 del bundle (generato da —key-v2), viene utilizzato per verificare l’integrità del file dopo la decrittografia Verrà crittografato con la chiave privata e inviato insieme al bundle Nella crittografia v2 il checksum viene aggiornato per diventare una “firma” del bundle Opzionalmente, puoi fornire: `--key [/path/to/my/private_key]` il percorso della tua chiave privata `--key-data [privateKey]` i dati della chiave privata, se vuoi usarla inline `--json` per output info come json Il comando stamperà il tuo `ivSessionKey` e genererà uno zip crittografato, da utilizzare con il comando upload o decrypt ### **Decrypt** `npx @capgo/cli bundle decrypt [path/to/zip] [ivSessionKey]` Opzionalmente, puoi fornire: `--key [/path/to/my/private_key]` il percorso della tua chiave privata `--key-data [privateKey]` i dati della chiave privata, se vuoi usarla inline Questo comando è principalmente utilizzato per scopi di test, decrittograferà lo zip e stamperà la chiave di sessione decrittografata in base64 nella console ### **Decrypt V2** `npx @capgo/cli bundle decryptV2 [path/to/zip] [ivSessionKey]` Opzionalmente, puoi fornire: `--key [/path/to/my/private_key]` il percorso della tua chiave privata `--key-data [privateKey]` i dati della chiave privata, se vuoi usarla inline Questo comando è principalmente utilizzato per scopi di test, decrittograferà lo zip e stamperà la chiave di sessione decrittografata in base64 nella console `--checksum [checksum]` il checksum del file, verificherà il checksum dopo la decrittografia ### **Zip** `npx @capgo/cli bundle zip [appId]` `[appId]` è il tuo ID app, il formato è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) Opzionalmente, puoi fornire: * `--path [/path/to/my/bundle]` per caricare una cartella specifica * `--bundle [100]` per impostare il numero di versione del bundle del filename * `--name [myapp]` per sovrascrivere il nome del file * `--json` per output info come json * `--no-code-check` per ignorare il controllo del codice e inviare comunque il bundle * `--key-v2` per utilizzare il nuovo sistema di crittografia Questo è necessario poiché il nuovo sistema di crittografia utilizza checksum migliori per verificare l’integrità del file ### **Compatibility** `npx @capgo/cli bundle compatibility [appId] -c [channelId]` `[appId]` è il tuo ID app, il formato è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) `[channelId]` il nome del tuo nuovo canale Opzionalmente, puoi fornire: * `--apikey [key]` chiave API per collegare al tuo account * `--text` usa testo invece di emoji nella tabella * `--channel [channel]` il canale per verificare la compatibilità * `--package-json ` Un percorso verso packagejson Utile per monorepos * `--node-modules ` Una lista di percorsi verso node\_modules Utile per monorepos (separati da virgola es: //node\_modules,/node\_modules) ## Channel ### **Add** `npx @capgo/cli channel add [channelId] [appId]` `[channelId]` il nome del tuo nuovo canale `[appId]` il tuo ID app il formato `comtestapp` è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) ### **Delete** `npx @capgo/cli channel delete [channelId] [appId]` `[channelId]` il nome del canale che vuoi eliminare `[appId]` il tuo ID app il formato `comtestapp` è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) ### **List** `npx @capgo/cli channel list [appId]` `[appId]` il tuo ID app il formato `comtestapp` è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) Opzionalmente, puoi fornire: * `--apikey [key]` chiave API per collegare al tuo account ### **Set** `npx @capgo/cli channel set [channelId] [appId]` `[appId]` è il tuo ID app, il formato è spiegato [qui](https://capacitorjs.com/docs/cli/commands/init/) Opzionalmente, puoi fornire: * `--bundle [123]` il tuo bundle app già inviato al cloud, per collegarlo a un canale * `--latest` ottiene la versione del bundle da `packagejson:version`, non può essere usato con `--bundle` * `--state [ normal | default ]` imposta lo stato del canale, può essere `normal` o `default` Un canale deve essere `default` * `--downgrade` permette al canale di inviare versioni precedenti ai dispositivi * `--no-downgrade` non permette al canale di inviare versioni precedenti ai dispositivi * `--upgrade` permette al canale di inviare aggiornamenti (major) ai dispositivi * `--no-upgrade` non permette al canale di inviare aggiornamenti (major) ai dispositivi * `--ios` permette al canale di inviare versioni ai dispositivi iOS * `--no-ios` non permette al canale di inviare versioni ai dispositivi iOS * `--android` permette al canale di inviare versioni ai dispositivi android * `--no-android` non permette al canale di inviare versioni ai dispositivi android * `--self-assign` permette ai dispositivi di auto-assegnarsi a questo canale * `--no-self-assign` non permette ai dispositivi di auto-assegnarsi a questo canale * `--disable-auto-update STRATEGY` Disabilita la strategia di auto aggiornamento per questo canale Le opzioni possibili sono: major, minor, metadata, none * `--apikey [key]` chiave API per collegare al tuo account ## Strategia di disabilitazione aggiornamenti Ci sono diversi modi per gestire la disabilitazione degli aggiornamenti per versioni troppo vecchie\ Capgo non può aggiornare il codice nativo quindi un aggiornamento da una versione con il vecchio codice nativo a una versione con il codice nativo aggiornato non dovrebbe essere possibile Ci sono un paio di modi per ottenere questo Prima, la strategia `major` Impedisce un aggiornamento da `000` -> `100` Il major è il numero evidenziato (**1**00 e **0**00)\ Seconda è la strategia `minor` Impedisce un aggiornamento da `000` -> `110` o un aggiornamento da `110` a `120` **ATTENZIONE** questa strategia non impedisce un aggiornamento da `010` -> `110` Terza, la strategia `patch` È stata aggiunta in capgo come modalità molto rigorosa Non è raccomandato usarla a meno che non si comprenda completamente come funziona Affinché accetti un aggiornamento devono essere soddisfatte le seguenti condizioni: * Il major è lo stesso tra la nuova e la vecchia versione * Il minor è lo stesso tra la nuova e la vecchia versione * Il patch della nuova versione è maggiore del patch della vecchia versione Ecco un esempio di quali scenari l’aggiornamento è consentito o negato * 00311 -> 00314 ✅ * 000 -> 00314 ✅ * 00316 -> 00314 ❌ * 01312 -> 00314 ❌ * 10312 -> 00314 ❌ Infine la strategia più complicata La strategia `metadata`\ Prima devi sapere che inizialmente dopo averla abilitata gli aggiornamenti **FALLIRANNO** poiché il canale manca dei metadata richiesti\ Se il canale manca di metadata vedrai un messaggio come questo: ![Cannot find metadata](/fail-metadata.webp) Se vedi qualcosa del genere sai che devi andare al bundle corrente per il canale che sta fallendo e impostare i metadata\ Prima, scopri quale canale sta fallendo Puoi farlo guardando la colonna `misconfigured` ![Misconfigured table](/misconfigured-table.webp) Quindi vai al canale con errori e clicca su `Bundle number`. Questo ti porterà alla pagina del bundle ![Locate failing channel](/fail-channel-show.webp) Una volta lì, compila il campo `Minimal update version`. Deve essere un [semver](https://devhints.io/semver/)\ Se il valore che inserisci non è un semver riceverai un errore, ma se tutto va correttamente dovresti vedere qualcosa del genere: ![Set min version](/set-min-update-version.webp) Ora, probabilmente non vuoi impostare questi dati manualmente ogni volta che aggiorni. Fortunatamente, la CLI ti impedirà di inviare un aggiornamento senza questi metadati ![CLI fail no metadata](/cli-fail-no-metadata.webp) Per caricare correttamente un bundle quando si usa l’opzione `metadata` devi passare `--min-update-version` con un semver valido. Qualcosa del genere: ![CLI upload with metadata](/cli-upload-with-metadata.webp) `--min-update-version` non è l’UNICO modo per gestire la compatibilità. Esiste anche `--auto-min-update-version`. Ecco come funziona: 1. Prima, controlla la versione attualmente caricata sul canale. Verifica la compatibilità come farebbe il comando `bundle compatibility` 2. Secondo, se la nuova versione è compatibile al 100% riutilizza il `min_update_version` dall’ultima versione nel canale Se non lo è, imposta il `min_update_version` al numero del bundle della versione appena caricata Riceverai sempre un’informazione su quale sia il `min_update_version` quando usi questa opzione. Apparirà qualcosa del genere: ![Min update version](/min_update_version_info.webp) Se la nuova versione non è compatibile dovrebbe apparire qualcosa del genere: ![Min update version not compatible](/min_update_version_not_compatible.webp) ## Crittografia end-to-end (Trustless) Capgo supporta la crittografia end-to-end, questo significa che il tuo bundle (codice) viene crittografato prima di essere inviato al cloud e decrittografato sul dispositivo. Per questo, devi generare una coppia di chiavi RSA, puoi usare il seguente comando per generarla Il sistema di crittografia è una combinazione di RSA e AES, la chiave RSA viene usata per crittografare la chiave AES, e la chiave AES viene usata per crittografare il file Vedi sotto per maggiori informazioni sul sistema di crittografia ![How crypto works](/crypto_explained.webp) Schema di crittografia ### Crea una chiave per la tua app `npx @capgo/cli key create` Opzionalmente, puoi usare: `--force` per sovrascrivere la chiave esistente. Questo comando creerà per te una coppia di chiavi nella tua app, e ti chiederà di salvare la chiave privata in un posto sicuro. Si raccomanda di non committare su git la chiave privata e di non condividerla con nessuno > Dopo il test locale, rimuovi la chiave dal file di configurazione e aggiungila nel passo CI con `key save` ### Salva la chiave nella configurazione della tua app `npx @capgo/cli key save` Opzionalmente, puoi usare: `--key [/path/to/my/private_key]` il percorso della tua chiave privata `--key-data [privateKey]` i dati della chiave privata, se vuoi usarla inline. Questo comando è utile se hai seguito la raccomandazione e non hai committato la chiave nella tua app e nella configurazione ## Integrazione CI Per automatizzare il tuo lavoro, ti consiglio di far fare il lavoro di push al nostro server tramite GitHub action [Tutorial GitHub action](https://capgo.app/blog/automatic-build-and-release-with-github-actions/) ## La nostra app demo [GitHub - Cap-go/demo-app](https://github.com/Cap-go/demo-app/) Non dimenticare di configurare la variabile d’ambiente CI con la tua API key # Da CLI 0.x a 1.x > Come eseguire l'aggiornamento dalla versione 0.x alla 1.x Non ci sono cambiamenti significativi nella CLI Il cambiamento più importante riguarda principalmente il cambio di nome dell’argomento `--version` in `--bundle` per evitare conflitti e mantenere una nomenclatura coerente ovunque # Crittografia > Come fare la crittografia dei dati con una nuova crittografia Questa documentazione spiegherà come crittografare i tuoi dati con il nuovo sistema di crittografia e rimuovere quello vecchio Scopri di più sul nuovo sistema di crittografia nel [blog post](/blog/introducing-end-to-end-security-to-capacitor-updater-with-code-signing) *** Per prima cosa, crea una nuova coppia di chiavi con il seguente comando: ```bash npx @capgo/cli key create ``` Questo comando creerà una nuova coppia di chiavi nella tua app; è imperativo conservare la chiave privata in un luogo sicuro. Non bisogna mai committare la chiave privata nel controllo del codice sorgente né condividerla con una parte non fidata. Questo comando rimuoverà anche la vecchia chiave dalla tua configurazione Capacitor, ma non rimuoverà i vecchi file delle chiavi. La CLI li mantiene per permetterti di continuare a inviare aggiornamenti live per le app che non hanno ricevuto un aggiornamento dall’app store e stanno ancora utilizzando il vecchio plugin. Questo facilita la migrazione. Quando ti viene chiesto dalla migrazione “Vuoi configurare la crittografia con il nuovo canale per supportare le vecchie app e facilitare la migrazione?”, per favore accetta. Aggiungerà una nuova opzione “defaultChannel” alla tua configurazione Capacitor. Questo farà sì che la tua app utilizzi il canale “encryption\_v2”. Questo assicurerà che la nuova crittografia sia utilizzata solo dalle app che la supportano. Le app che non hanno ricevuto un aggiornamento dall’app store continueranno a utilizzare il canale predefinito precedente. *** Ora, devi compilare il tuo bundle JS e caricarlo sul nuovo canale. Esegui il seguente comando: ```bash npx @capgo/cli bundle upload --channel encryption_v2 ``` *** Quindi, esegui questo comando per permettere alle app di auto-assegnarsi al canale “encryption\_v2” Caution Questo è necessario per far funzionare la nuova opzione “defaultChannel” ```bash npx @capgo/cli channel set encryption_v2 --self-assign ``` *** Ora puoi eseguire l’app; utilizzerà il nuovo sistema di crittografia. Per caricare il nuovo bundle JS sul vecchio canale, devi solo eseguire il seguente comando: ```bash npx @capgo/cli bundle upload --channel production ``` *** Non devi preoccuparti della configurazione Capacitor, non viene mai caricata su Capgo. Quando tutti gli utenti avranno aggiornato le loro app (può richiedere fino a 3/4 mesi), puoi rimuovere “defaultChannel” dalla tua configurazione Capacitor. E poi, puoi rimuovere il vecchio canale con il seguente comando: ```bash npx @capgo/cli channel delete encryption_v2 ``` *** Dopo aver eliminato il canale “encryption\_v2”, tutte le app che lo utilizzano come predefinito inizieranno a utilizzare il canale “production” # Panoramica Utilizza la funzionalità Live Updates di Capgo per aggiornare i bundle JavaScript della tua app in remoto e in tempo reale. Invia aggiornamenti JS direttamente ai tuoi utenti senza passare attraverso il processo di revisione dell’app store per correggere bug e rilasciare nuove funzionalità istantaneamente. Note I Live Updates sono limitati alle modifiche dei bundle JavaScript. Se hai bisogno di aggiornare il codice nativo, come aggiungere o rimuovere un plugin o modificare la configurazione del progetto nativo, dovrai inviare una nuova build binaria nativa agli app store. ## Come funzionano i Live Updates Il sistema Live Update di Capgo ha due componenti chiave: 1. L’SDK Capgo, che installi nella tua app. L’SDK verifica la disponibilità di aggiornamenti e li scarica in background. 2. I Canali, che ti permettono di indirizzare gli aggiornamenti a specifici gruppi di utenti. Puoi usare i canali per gestire diverse tracce di rilascio, come `Production`, `Staging` e `Dev`. Quando carichi un nuovo bundle JS su Capgo e lo assegni a un canale, l’SDK Capgo nelle app configurate per quel canale rileverà l’aggiornamento e lo scaricherà. Al successivo riavvio dell’app, verrà caricato il nuovo bundle. ## Per iniziare Per iniziare a utilizzare i Live Updates, segui questi passaggi: 1. Completa il [Quickstart di Capgo](/docs/getting-started/quickstart) per configurare la tua app in Capgo e installare l’SDK Capgo 2. Nel codice della tua app, chiama `CapacitorUpdater.notifyAppReady()` dopo che la tua app ha terminato l’inizializzazione. Questo comunica all’SDK Capgo che la tua app è pronta a ricevere aggiornamenti 3. Compila il tuo bundle JS e caricalo su Capgo: ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. Apri la tua app e attendi che l’aggiornamento venga scaricato. Puoi controllare lo stato con: ```shell npx @capgo/cli@latest app debug ``` 5. Una volta scaricato l’aggiornamento, chiudi e riapri la tua app per caricare il nuovo bundle Consulta la guida [Deploying Live Updates](/docs/getting-started/deploy) per maggiori dettagli ## La CLI di Capgo La CLI di Capgo è uno strumento potente che permette agli sviluppatori di interagire con i servizi di Capgo dalle proprie pipeline CI/CD. Con la CLI, hai un controllo granulare su quando le build vengono prodotte e distribuite, permettendoti di integrare Capgo nei tuoi flussi di lavoro aziendali esistenti. ### A cosa serve la CLI di Capgo? La CLI di Capgo è progettata per sviluppatori e team che necessitano di maggior controllo e flessibilità nei loro flussi di lavoro di aggiornamento live. Utilizzando la CLI nelle tue pipeline CI/CD, puoi: * Decidere esattamente quando costruire e distribuire gli aggiornamenti, invece di affidarti all’automazione integrata di Capgo * Inserire i tuoi processi, come la firma del codice, il test QA o le approvazioni dei manager, tra le fasi di build e deploy * Integrare Capgo nei tuoi strumenti e flussi di lavoro DevOps esistenti ### Autenticazione Per utilizzare la CLI di Capgo, dovrai autenticarti con la tua chiave API. Puoi generare una chiave API nelle impostazioni del tuo account Capgo. Per accedere e memorizzare in modo sicuro la tua chiave API, esegui: ```shell npx @capgo/cli@latest login [API_KEY] ``` Questo comando verrà poi salvato per un uso futuro. Non dovrai fornire la tua chiave API con ogni comando dopo aver effettuato l’accesso. ### Differenze chiave rispetto ad altri strumenti CLI Se hai familiarità con altri strumenti CLI per aggiornamenti live, ci sono alcune cose importanti da notare sulla CLI di Capgo: * Capgo utilizza una singola CLI sia per lo sviluppo che per i casi d’uso CI/CD, poiché Capgo è focalizzato esclusivamente sul set di funzionalità di aggiornamento live * La CLI di Capgo non richiede un passaggio di installazione separato. È inclusa nel pacchetto `@capgo/cli` e può essere eseguita direttamente utilizzando `npx` * La CLI di Capgo è progettata specificamente per il flusso di lavoro di aggiornamento live, quindi potrebbe non includere alcune funzionalità o comandi presenti in strumenti CLI più generici ## Prossimi passi [ Canali](/docs/live-updates/channels/) [Scopri come utilizzare i canali per gestire diverse tracce di rilascio e indirizzare gli aggiornamenti a specifici utenti](/docs/live-updates/channels/) [ Rollback](/docs/live-updates/rollbacks/) [Scopri come tornare a una versione precedente del bundle JS se un aggiornamento causa problemi](/docs/live-updates/rollbacks/) [ Comportamento degli aggiornamenti](/docs/live-updates/update-behavior/) [Personalizza come e quando gli aggiornamenti vengono scaricati e applicati nella tua app](/docs/live-updates/update-behavior/) [ Aggiornamenti rapidi](/docs/live-updates/differentials/) [Scopri come utilizzare gli aggiornamenti rapidi per velocizzare il processo di aggiornamento](/docs/live-updates/differentials/) # Panoramica > Documentazione dettagliata per i comandi CLI di Capgo La CLI di Capgo fornisce una serie di comandi per gestire le tue app e i deployment di Capgo. Questo riferimento fornisce informazioni dettagliate su ogni comando disponibile, incluse le sue opzioni ed esempi di utilizzo ## Comandi [ init](/docs/cli/reference/init/) [Inizializza una nuova app Capgo](/docs/cli/reference/init/) [ login](/login/) [Autenticati con il servizio Capgo](/login/) [ doctor](/docs/cli/reference/doctor/) [Controlla la tua configurazione Capgo per potenziali problemi](/docs/cli/reference/doctor/) [ app](/docs/cli/reference/app/) [Gestisci le tue app Capgo](/docs/cli/reference/app/) [ bundle](/docs/cli/reference/bundle/) [Gestisci i bundle delle tue app](/docs/cli/reference/bundle/) [ channel](/docs/cli/reference/channel/) [Gestisci i tuoi canali di rilascio](/docs/cli/reference/channel/) [ key](/docs/cli/reference/key/) [Gestisci le tue chiavi di firma delle app](/docs/cli/reference/key/) ## Integrazione CI Per automatizzare il tuo lavoro, ti consigliamo di utilizzare GitHub Actions per inviare i tuoi aggiornamenti a Capgo. Consulta il nostro [tutorial su GitHub Actions](https://capgo.app/blog/automatic-build-and-release-with-github-actions/) per maggiori informazioni Non dimenticare di configurare le variabili d’ambiente del tuo CI con la tua chiave API Capgo ## App Demo Per un esempio completo di un’app Capgo con integrazione CI, dai un’occhiata alla nostra [app demo su GitHub](https://github.com/Cap-go/demo-app/) # account Il comando `account` ti permette di gestire il tuo account Capgo ### id `npx @capgo/cli account id` Ottiene il tuo ID account Opzioni: * `-a, --apikey `: Chiave API da collegare al tuo account # app Il comando `app` ti permette di gestire le tue app Capgo ### add `npx @capgo/cli app add [appId]` Aggiunge una nuova app al tuo account Capgo `[appId]` è l’ID della tua app nel formato `com.example.app`. Vedi la [documentazione Capacitor](https://capacitorjs.com/docs/cli/commands/init/) per maggiori informazioni > 💡 Tutte le opzioni verranno dedotte dal tuo `capacitor.config.json` se non specificate Opzioni: * `--icon [path]`: Percorso di un’icona personalizzata da mostrare nell’app web Capgo * `--name [name]`: Nome personalizzato da mostrare nella lista delle app * `--apikey [key]`: Chiave API per collegare al tuo account * `--retention [days]`: Periodo di conservazione dei bundle dell’app in giorni (default: 0 = infinito) ### set `npx @capgo/cli app set [appId]` Aggiorna un’app esistente nel tuo account Capgo Opzioni: * `--icon [path]`: Percorso di un’icona personalizzata da mostrare nell’app web Capgo * `--name [name]`: Nome personalizzato da mostrare nella lista delle app * `--retention [days]`: Periodo di conservazione dei bundle dell’app in giorni (default: 0 = infinito) * `--apikey [key]`: Chiave API per collegare al tuo account ### list `npx @capgo/cli app list [appId]` Elenca tutte le app nel tuo account Capgo Opzioni: * `--apikey [key]`: Chiave API per collegare al tuo account ### delete `npx @capgo/cli app delete [appId]` Elimina un’app dal tuo account Capgo Opzioni: * `--apikey [key]`: Chiave API per collegare al tuo account * `--bundle`: Elimina solo una specifica versione del bundle ### debug `npx @capgo/cli app debug [appId]` Mostra informazioni di debug per un’app Opzioni: * `--apikey [key]`: Chiave API per collegare al tuo account * `--device`: Debug di un dispositivo specifico ### setting `npx @capgo/cli app setting [path]` Modifica la configurazione Capacitor per un’app `[path]` è il percorso dell’impostazione che vuoi modificare (es. `appId` o `plugins.CapacitorUpdater.autoUpdate`) Devi fornire o `--string` o `--bool`: * `--string `: Imposta l’impostazione a un valore stringa * `--bool `: Imposta l’impostazione a un valore booleano # bundle Il comando `bundle` ti permette di gestire i bundle delle tue app ### upload `npx @capgo/cli bundle upload [appId]` Carica un nuovo bundle per un’app Opzioni: * `-a, --apikey `: Chiave API per collegarsi al tuo account * `-p, --path `: Percorso della cartella da caricare (predefinito sul `webDir` in `capacitorconfig`) * `-c, --channel `: Canale a cui collegare il bundle * `-e, --external `: Link a un URL esterno invece di caricare su Capgo Cloud * `--iv-session-key `: Imposta IV e chiave di sessione per un URL bundle esterno * `--s3-region `: Regione del tuo bucket S3 * `--s3-apikey `: Chiave API per il tuo endpoint S3 * `--s3-apisecret `: Secret API per il tuo endpoint S3 * `--s3-endpoint `: URL dell’endpoint S3 * `--s3-bucket-name `: Nome del tuo bucket S3 * `--s3-port `: Porta per il tuo endpoint S3 * `--no-s3-ssl`: Disabilita SSL per gli upload S3 * `--key `: Percorso personalizzato per la chiave di firma pubblica (sistema v1) * `--key-data `: Dati della chiave di firma pubblica (sistema v1) * `--key-v2 `: Percorso personalizzato per la chiave di firma privata (sistema v2) * `--key-data-v2 `: Dati della chiave di firma privata (sistema v2) * `--bundle-url`: Stampa l’URL del bundle su stdout * `--no-key`: Ignora la chiave di firma e invia un aggiornamento non firmato * `--no-code-check`: Salta il controllo di `notifyAppReady()` nel codice sorgente e `indexhtml` nella cartella root * `--display-iv-session`: Visualizza IV e chiave di sessione usati per criptare l’aggiornamento * `-b, --bundle `: Numero versione del bundle da caricare * `--min-update-version `: Versione minima dell’app richiesta per applicare questo aggiornamento (usato solo se l’auto-update è disabilitato via metadata) * `--auto-min-update-version`: Imposta automaticamente la versione minima di aggiornamento basata sulle versioni native del pacchetto * `--ignore-metadata-check`: Ignora il controllo dei metadata (node\_modules) durante l’upload * `--ignore-checksum-check`: Ignora il controllo del checksum durante l’upload * `--timeout `: Timeout per il processo di upload in secondi * `--multipart`: Usa il protocollo multipart per caricare dati su S3 (deprecato, usa `--tus` invece) * `--tus`: Carica il bundle usando il protocollo tus * `--tus-chunk-size `: Dimensione del chunk per l’upload tus * `--partial`: Carica solo i file modificati su Capgo Cloud * `--partial-only`: Carica solo file parziali su Capgo Cloud, saltando il file zippato (utile per bundle grandi) * `--encrypted-checksum `: Checksum criptato (firma) per un bundle esterno * `--auto-set-bundle`: Imposta automaticamente la versione del bundle in `capacitorconfigjson` * `--dry-upload`: Esegue una prova di upload senza caricare effettivamente i file (utile per test) * `--package-json `: Lista separata da virgole di percorsi ai file `packagejson` (utile per monorepos) * `--node-modules `: Lista separata da virgole di percorsi alle directory `node_modules` (utile per monorepos) * `--encrypt-partial`: Cripta i file di aggiornamento parziale * `--delete-linked-bundle-on-upload`: Elimina il bundle attualmente collegato nel canale target prima dell’upload ### compatibility `npx @capgo/cli bundle compatibility [appId]` Verifica la compatibilità di un bundle con un canale specifico Opzioni: * `-a, --apikey `: Chiave API per collegarsi al tuo account * `-c, --channel `: Canale con cui verificare la compatibilità * `--text`: Mostra i risultati come testo invece che emoji * `--package-json `: Lista separata da virgole di percorsi ai file `packagejson` (utile per monorepos) * `--node-modules `: Lista separata da virgole di percorsi alle directory `node_modules` (utile per monorepos) ### delete `npx @capgo/cli bundle delete [bundleId] [appId]` Elimina un bundle da un’app Opzioni: * `-a, --apikey `: Chiave API per collegarsi al tuo account ### list `npx @capgo/cli bundle list [appId]` Elenca tutti i bundle per un’app Opzioni: * `-a, --apikey `: Chiave API per collegarsi al tuo account ### cleanup `npx @capgo/cli bundle cleanup [appId]` Pulisce i vecchi bundle per una versione major, mantenendo il numero specificato di bundle più recenti Opzioni: * `-b, --bundle `: Numero versione major da pulire * `-a, --apikey `: Chiave API per collegarsi al tuo account * `-k, --keep `: Numero di bundle da mantenere (predefinito: 4) * `-f, --force`: Forza la rimozione senza conferma ### decrypt `npx @capgo/cli bundle decrypt [zipPath] [sessionKey]` Decripta un bundle zip firmato Opzioni: * `--key `: Percorso personalizzato per la chiave di firma privata * `--key-data `: Dati della chiave di firma privata ### encrypt `npx @capgo/cli bundle encrypt [zipPath]` Cripta un bundle zip Opzioni: * `--key `: Percorso personalizzato per la chiave di firma privata * `--key-data `: Dati della chiave di firma privata ### encryptV2 `npx @capgo/cli bundle encryptV2 [zipPath] [checksum]` Cripta un bundle zip usando il nuovo metodo di crittografia Opzioni: * `--key `: Percorso personalizzato per la chiave di firma privata * `--key-data `: Dati della chiave di firma privata * `-j, --json`: Mostra i risultati come JSON ### decryptV2 `npx @capgo/cli bundle decryptV2 [zipPath] [checksum]` Decripta un bundle zip usando il nuovo metodo di decrittografia Opzioni: * `--key `: Percorso personalizzato per la chiave di firma privata * `--key-data `: Dati della chiave di firma privata * `--checksum `: Checksum del bundle per verificarne l’integrità ### zip `npx @capgo/cli bundle zip [appId]` Genera un file zip per un bundle Opzioni: * `-p, --path `: Percorso della cartella da zippare (predefinito sul `webDir` in `capacitorconfig`) * `-b, --bundle `: Numero versione del bundle da usare nel nome del file * `-n, --name `: Nome file personalizzato per lo zip * `-j, --json`: Mostra i risultati come JSON * `--no-code-check`: Salta il controllo di `notifyAppReady()` nel codice sorgente e `indexhtml` nella cartella root * `--key-v2`: Usa il nuovo metodo di crittografia (v2) * `--package-json `: Lista separata da virgole di percorsi ai file `packagejson` (utile per monorepos) # canale Il comando `channel` ti permette di gestire i tuoi canali di rilascio ### add `npx @capgo/cli channel add [channelId] [appId]` Crea un nuovo canale per un’app Opzioni: * `-d, --default`: Imposta il nuovo canale come canale predefinito * `-a, --apikey `: Chiave API da collegare al tuo account ### delete `npx @capgo/cli channel delete [channelId] [appId]` Elimina un canale da un’app Opzioni: * `-a, --apikey `: Chiave API da collegare al tuo account * `--delete-bundle`: Elimina il bundle associato al canale ### list `npx @capgo/cli channel list [appId]` Elenca tutti i canali per un’app Opzioni: * `-a, --apikey `: Chiave API da collegare al tuo account ### currentBundle `npx @capgo/cli channel currentBundle [channel] [appId]` Ottiene il bundle corrente per un canale specifico Opzioni: * `-c, --channel `: Canale da cui ottenere il bundle corrente * `-a, --apikey `: Chiave API da collegare al tuo account * `--quiet`: Mostra solo la versione del bundle ### set `npx @capgo/cli channel set [channelId] [appId]` Imposta le proprietà di un canale Opzioni: * `-a, --apikey `: Chiave API da collegare al tuo account * `-b, --bundle `: Numero di versione del bundle da impostare per il canale * `-s, --state `: Imposta lo stato del canale (`default` o `normal`) * `--latest`: Usa l’ultima versione da `packagejson` come versione del bundle * `--downgrade`: Permetti downgrade a versioni inferiori alla versione nativa * `--no-downgrade`: Disabilita downgrade a versioni inferiori alla versione nativa * `--upgrade`: Permetti upgrade a versioni superiori alla versione nativa * `--no-upgrade`: Disabilita upgrade a versioni superiori alla versione nativa * `--ios`: Permetti l’invio di aggiornamenti ai dispositivi iOS * `--no-ios`: Disabilita l’invio di aggiornamenti ai dispositivi iOS * `--android`: Permetti l’invio di aggiornamenti ai dispositivi Android * `--no-android`: Disabilita l’invio di aggiornamenti ai dispositivi Android * `--self-assign`: Permetti ai dispositivi di auto-assegnarsi a questo canale * `--no-self-assign`: Disabilita l’auto-assegnazione dei dispositivi a questo canale * `--disable-auto-update `: Disabilita la strategia di auto-aggiornamento per questo canale (opzioni: `major`, `minor`, `metadata`, `patch`, `none`) * `--dev`: Permetti l’invio di aggiornamenti ai dispositivi di sviluppo * `--no-dev`: Disabilita l’invio di aggiornamenti ai dispositivi di sviluppo * `--emulator`: Permetti l’invio di aggiornamenti ai dispositivi emulatore * `--no-emulator`: Disabilita l’invio di aggiornamenti ai dispositivi emulatore * `--package-json `: Lista separata da virgole di percorsi ai file `packagejson` (utile per monorepo) # dottore `npx @capgo/cli doctor` Questo comando controlla se stai utilizzando l’ultima versione dei pacchetti Capgo È anche utile per la segnalazione di bug # inizializza `npx @capgo/cli@latest init [apikey]` Questo comando ti guida passo dopo passo per: * Aggiungere la tua app a Capgo * Aggiungere il codice alla tua app per validare l’aggiornamento * Compilare la tua app * Caricare la tua app su Capgo * Aiutarti a verificare se l’aggiornamento funziona # chiave Il comando `key` ti permette di gestire le chiavi di firma della tua app ### save `npx @capgo/cli key save` Salva una chiave di crittografia codificata in base64 nella configurazione di Capacitor (utile per CI) Opzioni: * `-f, --force`: Forza la generazione di una nuova chiave * `--key`: Percorso del file della chiave da salvare nella configurazione di Capacitor * `--key-data`: Dati della chiave da salvare direttamente nella configurazione di Capacitor ### create `npx @capgo/cli key create` Crea una nuova chiave di crittografia Opzioni: * `-f, --force`: Forza la generazione di una nuova chiave ### delete\_old `npx @capgo/cli key delete_old` Elimina la vecchia chiave di crittografia # accedi `npx @capgo/cli login [apikey]` Questo comando memorizza la tua API key di Capgo per usi futuri Note Puoi sovrascrivere l’API key memorizzata passando `--apikey=` a qualsiasi comando Opzioni: * `--local`: Memorizza l’API key nel repository locale e la aggiunge al `gitignore` # FAQ > Domande frequenti su Capgo Se hai domande che non hanno trovato risposta qui, chiedi pure! Puoi sia aprire una issue che chiedere su [Discord](https://discordcom/invite/VnYRvBfgA6) ### Cos’è il “code push”? Code push, chiamato anche “aggiornamenti over the air” (OTA), è un servizio cloud che permette agli sviluppatori Capacitor di distribuire aggiornamenti alle loro app in produzione. Capgo funziona attualmente su Android e iOS e in futuro funzionerà ovunque funzioni Capacitor. “Code Push” è un riferimento al nome di una funzionalità di deploy usata dalla community React Native da [Microsoft](https://appcenterms/) ed [Expo](https://expodev/), che non supportano Capacitor. ### Qual è la differenza tra bundle e release? Usiamo il termine “release” per indicare la preparazione di un binario per gli app store. Per poter generare un bundle successivamente, Capgo deve conoscere l’esatto binario inviato agli app store. Usiamo il termine “bundle” per indicare una patch che può essere applicata a una release per aggiornare il codice. Il comando `npx @capgo/cli app update` viene utilizzato per generare un bundle dal tuo nuovo codice locale che viene poi inviato agli utenti. ### Qual è la roadmap? Le nostre board di progetto sono pubbliche e si trovano su: [https://github.com/orgs/Cap-go/projects](https://github.com/orgs/Cap-go/projects/) Il nostro team opera pubblicamente, quindi puoi vedere a cosa stiamo lavorando in qualsiasi momento. Siamo felici di rispondere a qualsiasi domanda sulla nostra roadmap o priorità tramite Github issues o [Discord](https://discordcom/invite/VnYRvBfgA6). ### Posso usare Capgo con il mio team? Sì! Tutti i piani supportano sviluppatori illimitati. Limitiamo solo le metriche dell’app (MAU, archiviazione e larghezza di banda) per ogni organizzazione. Vedi [Teams](https://capgo.app/pricing/) per maggiori informazioni. ### Capgo memorizza il mio codice sorgente? No. I server Capgo non vedono mai il tuo codice sorgente. Quando esegui `npx @capgo/cli app update`, il tool `npx @capgo/cli` carica solo lo stesso codice compilato che invii agli app store. Se desideri ulteriore sicurezza, puoi utilizzare la crittografia End to End per crittografare il tuo bundle prima di caricarlo sui server Capgo. Vedi anche la nostra privacy policy: [https://capgo.app/privacy](https://capgo.app/privacy/) ### Posso usare Capgo dal mio sistema CI? Sì. Capgo è pensato per essere usato dai sistemi CI. Abbiamo pubblicato una guida per [Android e Github Actions](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) e [IOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/), e per [Gitlab](https://capgo.app/blog/setup-ci-and-cd-gitlab/), altri sistemi CI dovrebbero essere simili. Non esitare a contattarci tramite GitHub issues o Discord se incontri problemi. ### Che relazione ha con Firebase Remote Config o Launch Darkly? Code push permette di aggiungere nuovo codice / sostituire codice sul dispositivo. Firebase Remote Config e Launch Darkly sono entrambi sistemi di configurazione. Ti permettono di modificare la configurazione della tua app senza dover distribuire una nuova versione. Non sono pensati per sostituire il codice. ### Quanto è grande l’impronta delle dipendenze che aggiunge? Non ho misurato recentemente, ma mi aspetto che la libreria code push aggiunga meno di un megabyte alle app Capacitor. Conosciamo modi per renderlo più piccolo quando diventerà una priorità. Se la dimensione è un problema per te, faccelo sapere! ### Il code push funziona con applicazioni grandi? Sì. Non c’è limite alla dimensione dell’applicazione che può essere aggiornata con code push. Come notato [sotto](https://capgo.app/docs/faq/#what-types-of-changes-does-capgo-code-push-support), Capgo può modificare qualsiasi codice JS nella tua applicazione indipendentemente dalla dimensione. Da notare: Una dimensione maggiore rende più difficile per gli utenti scaricare gli aggiornamenti. Consigliamo di mantenere l’app il più piccola possibile. ### Per cosa posso usare il code push di Capgo? Abbiamo visto vari utilizzi, tra cui: * Correzioni di emergenza per app in produzione * Distribuzione di correzioni di bug agli utenti su versioni precedenti della tua app * Distribuzione costante (es. ogni ora) Nota che la maggior parte degli app store vieta la distribuzione di codice che modifica in modo significativo il comportamento dell’app. Vedi [sotto](https://capgo.app/docs/faq/#how-does-this-relate-to-the-appplay-store-review-process-or-policies) per maggiori informazioni. ### Cosa conta come “MAU” per Capgo? Un MAU è un “Utente Attivo Mensile”. Contiamo come MAU qualsiasi dispositivo che ha contattato i nostri server negli ultimi 30 giorni. Non contiamo i dispositivi che non hanno contattato i nostri server negli ultimi 30 giorni. Ogni volta che un dispositivo installa nuovamente la tua app, viene contato un nuovo MAU, questo accade a causa delle limitazioni di privacy dell’Apple Store. Non possiamo tracciare lo stesso dispositivo se l’utente reinstalla l’app. Durante lo sviluppo, ogni volta che reinstalli l’app, viene contato un nuovo MAU. Lo stesso vale per i download di testflight o il cambio di canale in Android. L’aggiornamento dell’app non crea un nuovo Device ID. > Consigliamo dopo il primo setup di disabilitare i dispositivi di sviluppo e gli emulatori per ridurre la quantità di dispositivi duplicati. ### Per cosa non possiamo usare il code push di Capgo? Come sopra, Capgo non dovrebbe essere usato per violare le policy degli app store. Vedi [sotto](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines) per maggiori informazioni. Inoltre Capgo non supporta la modifica del codice nativo (es. Java/Kotlin su Android o Objective-C/Swift su iOS). Lo strumento ti avviserà durante un tentativo di aggiornamento se hai modificato codice nativo. ### Capgo invia agli store per me? Attualmente Capgo non supporta l’invio agli app store per tuo conto. Abbiamo in programma di aggiungere questa funzionalità in futuro, ma per ora dovrai continuare a utilizzare i tuoi processi esistenti per inviare agli app store. Puoi usare la nostra [guida CI Android](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) per automatizzare questo processo e [guida CI iOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/). ### Cosa memorizza Capgo su disco e dove? L’updater di Capgo (incluso nella tua applicazione quando compili la tua app) memorizza nella cache l’ultimo bundle scaricato nell’unica directory da cui capacitor permette di caricare codice. Su Android, si trova in `/data/user/0/comexampleapp/code_cache/capgo_updater` anche se la base di quel percorso è fornita dal sistema Android e può cambiare dinamicamente durante l’esecuzione. Sui dispositivi iOS, i dati sono memorizzati sotto `Library/Application Support/capgo`. Gli strumenti da riga di comando di Capgo (es.`npx @capgo/cli app update`) vengono installati su disco nelle cache npm, i tuoi login sono memorizzati nella tua directory home in `~/capgo` ### Che relazione ha con il Capacitor Hot Reload?[](https://capgo.app/docs/faq/#how-does-this-relate-to-capacitor-hot-reload "Link diretto a Come si relaziona con Capacitor Hot Reload?") L’Hot reload di Capacitor è una funzionalità solo per lo sviluppo. Code push è per la produzione. L’hot reload è una funzionalità di Capacitor che permette di modificare il codice sul dispositivo durante lo sviluppo. Richiede la compilazione dell’app Capacitor con un proxy per connettersi alla tua macchina locale. Code push è una funzionalità che permette di modificare il codice sul dispositivo in produzione. Useremo diverse tecniche per renderlo possibile a seconda della piattaforma. ### Che tipo di modifiche supporta il code push di Capgo?[](https://capgo.app/docs/faq/#what-types-of-changes-does-capgo-code-push-support "Link diretto a Che tipo di modifiche supporta il code push di Capgo?") Capgo può modificare qualsiasi codice JS nella tua applicazione. Questo include il codice dell’app e il codice generato. Puoi anche aggiornare le dipendenze in `package.json` purché non richiedano modifiche al codice nativo. Non abbiamo in programma di supportare la modifica del codice nativo (es. Java/Kotlin su Android o Objective-C/Swift su iOS), e lo strumento ti avviserà se rileva che hai modificato il codice nativo poiché non sarà incluso nel bundle. ### Supporta il Web?[](https://capgo.app/docs/faq/#does-this-support-web "Link diretto a Supporta il Web?") Il code push non è necessario per il web poiché il web già funziona in questo modo. Quando un utente apre una web app, scarica l’ultima versione dal server se necessario. Se hai un caso d’uso per il code push con il web, ci piacerebbe saperlo! ### Funzionerà su iOS, Android, Mac, Windows, Linux, ecc?[](https://capgo.app/docs/faq/#will-this-work-on-ios-android-mac-windows-linux-etc "Link diretto a Funzionerà su iOS, Android, Mac, Windows, Linux, ecc?") Sì. Finora ci siamo concentrati sul supporto Android e iOS, ma il code push alla fine funzionerà ovunque funzioni Capacitor. Ci stiamo assicurando di aver costruito tutta l’infrastruttura necessaria per fornire il code push in modo affidabile e sicuro prima di espanderci ad altre piattaforme. ### Quali versioni OS supporta Capgo?[](https://capgo.app/docs/faq/#what-os-versions-does-capgo-support "Link diretto a Quali versioni OS supporta Capgo?") Capgo supporta le stesse versioni di Android che supporta Capacitor. Capacitor attualmente supporta Android API level 22+ e iOS 13.0+: [https://capacitorjs.com/docs/main/reference/support-policy](https://capacitorjs.com/docs/main/reference/support-policy/) ### Quali versioni di Capacitor supporta Capgo?[](https://capgo.app/docs/faq/#what-versions-of-flutter-does-capgo-support "Link diretto a Quali versioni di Capacitor supporta Capgo?") Capgo attualmente supporta solo le recenti versioni stabili di Capacitor. Potremmo supportare versioni più vecchie di Capacitor, semplicemente non abbiamo costruito l’infrastruttura necessaria per mantenerle nel tempo. Intendiamo supportare più versioni di Capacitor in futuro, inclusa qualsiasi versione per i nostri clienti enterprise: [https://github.com/Cap-go/capgo/issues/1100](https://github.com/Cap-go/capgo/issues/1100/) Capgo segue la versione stabile di Capacitor e generalmente si aggiorna entro poche ore da qualsiasi release stabile. Il nostro sistema per fare questi aggiornamenti è automatizzato e richiede pochi minuti per l’esecuzione. Quindi facciamo un ulteriore passaggio di verifica manuale prima della pubblicazione sui nostri server. ### Come si relaziona con il processo di revisione o le policy dell’App/Play Store?[](https://capgo.app/docs/faq/#how-does-this-relate-to-the-appplay-store-review-process-or-policies "Link diretto a Come si relaziona con il processo di revisione o le policy dell'App/Play Store?") Gli sviluppatori sono vincolati dai loro accordi con i fornitori degli store quando scelgono di utilizzare quegli store. Il code push è progettato per permettere agli sviluppatori di aggiornare le loro app e continuare a rispettare le policy degli store su iOS e Android. Simile alla varietà di prodotti commerciali disponibili per farlo con React Native (es. [Microsoft](https://appcenter.ms/), [Expo](https://expo.dev/)) Microsoft pubblica anche una guida su come la loro soluzione è conforme agli app store: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) Il code push è una tecnica ampiamente utilizzata negli app store. Tutte le grandi app che conosco usano il code push. La principale policy da tenere presente è di non modificare il comportamento dell’app in modo significativo. Per favore vedi [sotto](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines) per maggiori informazioni. ### Capgo è conforme alle linee guida del Play Store?[](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines "Link diretto a Capgo è conforme alle linee guida del Play Store?") Sì. Il Play Store offre due restrizioni relative agli strumenti di aggiornamento: 1. Gli aggiornamenti devono utilizzare un interprete o una macchina virtuale (Capgo usa la Dart Virtual Machine) [https://support.google.com/googleplay/android-developer/answer/9888379?hl=en](https://support.google.com/googleplay/android-developer/answer/9888379/?hl=en) ```plaintext Un'app distribuita tramite Google Play non può modificare, sostituire o aggiornare se stessa
utilizzando qualsiasi metodo diverso dal meccanismo di aggiornamento di Google Play. Allo stesso modo, un'app
non può scaricare codice eseguibile (come file dex, JAR, so) da una
fonte diversa da Google Play. *Questa restrizione non si applica al codice
che viene eseguito in una macchina virtuale o un interprete* dove entrambi forniscono
accesso indiretto alle API Android (come JavaScript in una webview o
browser)

Le app o il codice di terze parti, come SDK, con linguaggi interpretati (JavaScript,
Python, Lua, ecc.) caricati in runtime (ad esempio, non inclusi nell'
app) non devono consentire potenziali violazioni delle policy di Google Play
``` 2. Le modifiche all’app non devono essere ingannevoli (es. cambiare lo scopo dell’app tramite aggiornamento) [https://support.google.com/googleplay/android-developer/answer/9888077](https://support.google.com/googleplay/android-developer/answer/9888077/) Per favore sii chiaro con i tuoi utenti su cosa stai fornendo con la tua applicazione e non violare le loro aspettative con cambiamenti comportamentali significativi attraverso l’uso di Capgo. Capgo è progettato per essere compatibile con le linee guida del Play Store. Tuttavia Capgo è uno strumento e, come qualsiasi strumento, può essere abusato. Abusare deliberatamente di Capgo per violare le linee guida del Play Store è in violazione dei [Termini di Servizio](https://capgo.app/tos/) di Capgo e può portare alla chiusura del tuo account. Infine, i servizi di code push sono ampiamente utilizzati nell’industria (tutte le grandi app che conosco li usano) e ci sono molti altri servizi di code push disponibili pubblicamente (es. expo.dev & appcenter.ms). Questa è una strada ben battuta. Microsoft pubblica anche una guida su come la loro libreria “codepush” per react native è conforme agli app store: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### Capgo è conforme alle linee guida dell’App Store?[](https://capgo.app/docs/faq/#does-capgo-comply-with-app-store-guidelines "Link diretto a Capgo è conforme alle linee guida dell'App Store?") Sì. Simile al Play Store, l’App Store offre sia restrizioni tecniche che politiche. ```plaintext 3.2.2
Il codice interpretato può essere scaricato in un'Applicazione solo se
tale codice:
(a) non modifica lo scopo principale dell'Applicazione fornendo
funzionalità o caratteristiche che sono incompatibili con lo scopo previsto e
pubblicizzato dell'Applicazione come inviata all'App Store,
(b) non crea un negozio o vetrina per altro codice o applicazioni, e
(c) non aggira la firma, il sandbox o altre funzionalità di sicurezza del sistema operativo
Capgo utilizza un interprete Dart personalizzato per rispettare la restrizione solo interprete per gli aggiornamenti su iOS. Fintanto che la tua applicazione non ha comportamenti ingannevoli tramite gli aggiornamenti (es. modificare lo scopo dell'app tramite aggiornamento), l'aggiornamento tramite Capgo (o qualsiasi altra soluzione di code push) è una pratica standard del settore e conforme alle linee guida dell'App Store. L'abuso intenzionale di Capgo per violare le linee guida dell'App Store viola i [Termini di Servizio](https://capgo.app/tos/) di Capgo e può comportare la chiusura del tuo account. Microsoft pubblica anche una guida su come la loro libreria react native "codepush" è conforme agli app store: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### Posso utilizzare Capgo nel mio paese? Non abbiamo cercato di limitare l'accesso a Capgo da nessun paese. Riconosciamo che alcuni paesi hanno restrizioni sugli URL accessibili dall'interno del paese. Capgo attualmente utilizza Cloudflare Cloud per l'hosting, inclusi R2 Storage e Cloudflare workers. I seguenti URL sono utilizzati da Capgo: - [https://apicapgo.app](https://apicapgo.app/) -- utilizzato dagli strumenti da riga di comando `npx @capgo/cli` per interagire con i server Capgo e dall'updater Capgo sui dispositivi degli utenti per controllare gli aggiornamenti - [https://*r2cloudflarestoragecom](https://*r2cloudflarestoragecom/) -- utilizzato dallo strumento da riga di comando `npx @capgo/cli` per caricare e scaricare bundle Se tutti questi URL sono accessibili dal tuo paese, allora Capgo dovrebbe funzionare. Se la tua regione richiede il blocco dell'accesso a uno di questi URL, faccelo sapere e possiamo lavorare con te per trovare una soluzione. I server proxy sono un'opzione. ### Posso fare self-hosting di Capgo? Sì, puoi fare self-hosting di Capgo. La guida non è ancora scritta, ma il codice è open source e disponibile su [https://github.com/cap-go/capgo](https://github.com/cap-go/capgo/) ### Il code push richiede internet per funzionare? Sì. Si potrebbe immaginare di eseguire un server per distribuire gli aggiornamenti separatamente da internet generale, ma è necessaria qualche forma di connettività di rete per trasportare gli aggiornamenti ai dispositivi. ### Come viene influenzato Capgo dalla mancanza di connettività di rete? L'updater Capgo (incluso nella tua applicazione quando compili la tua app con Capgo) è progettato per essere resiliente ai problemi di connettività di rete. Nel comportamento di aggiornamento predefinito, quando l'applicazione si avvia avvisa l'updater Capgo, che genera un thread separato per effettuare una richiesta di rete ai server Capgo e chiedere un aggiornamento. Utilizziamo intenzionalmente un thread separato per evitare di bloccare qualsiasi altra cosa che l'applicazione potrebbe fare. Se la richiesta di rete fallisce o va in timeout, l'updater proverà semplicemente a controllare di nuovo al prossimo avvio dell'applicazione. Gli strumenti da riga di comando Capgo (es. `npx @capgo/cli app update`) richiedono connettività di rete per funzionare. Se stai utilizzando Capgo per distribuire la tua app, dovresti assicurarti che il tuo sistema CI abbia connettività di rete. ### Cosa succede se un utente non si aggiorna per molto tempo e perde un aggiornamento? La nostra implementazione invia sempre un aggiornamento specificamente adattato per il dispositivo che lo richiede, aggiornando sempre il richiedente all'ultima versione disponibile. Quindi se un utente non si aggiorna per un po' "perderà" gli aggiornamenti intermedi. Il server di aggiornamento potrebbe essere modificato per supportare la risposta con la versione incrementale successiva o l'ultima versione a seconda delle esigenze della tua applicazione. Facci sapere se comportamenti di aggiornamento alternativi sono importanti per te. ### Che relazione c'è tra Capgo e Capacitor? Capgo è un plugin per Capacitor che aggiunge il code push. Capgo non è un sostituto di Capacitor. Puoi continuare a utilizzare gli strumenti Capacitor che già conosci e ami. Seguiamo l'ultima versione stabile di Capacitor e aggiorniamo il nostro plugin code push per funzionare con essa. ### Quando avvengono gli aggiornamenti? Per impostazione predefinita, l'updater Capgo controlla gli aggiornamenti all'avvio dell'app. Viene eseguito su un thread in background e non blocca il thread UI. Tutti gli aggiornamenti verranno installati mentre l'utente sta utilizzando l'app e verranno applicati al successivo riavvio dell'app. È anche possibile eseguire l'updater Capgo manualmente utilizzando [package:capgo\_code\_push](https://pubdev/packages/capgo_code_push/), attraverso il quale è possibile attivare gli aggiornamenti in qualsiasi momento, anche tramite una notifica push. L'updater Capgo è progettato in modo che quando la rete non è disponibile, o il server è inattivo o comunque irraggiungibile, l'app continuerà a funzionare normalmente. Se dovessi mai scegliere di eliminare un aggiornamento dai nostri server, tutti i tuoi client continueranno a funzionare normalmente. Abbiamo aggiunto la possibilità di ripristinare le patch. La cosa più semplice è semplicemente allegare un bundle precedente al tuo canale per annullare. ### Devo mantenere segreto il mio app_id? No. L'`app_id` è incluso nella tua app ed è sicuro essere pubblico. Puoi includerlo nel controllo versione (anche pubblicamente) e non preoccuparti che qualcun altro vi acceda. Qualcuno che ha il tuo `app_id` può recuperare l'ultima versione della tua app dai server Capgo, ma non può inviare aggiornamenti alla tua app o accedere a qualsiasi altro aspetto del tuo account Capgo. ### Quali informazioni vengono inviate ai server Capgo? Anche se Capgo si connette alla rete, non invia alcuna informazione personalmente identificabile. Includere Capgo non dovrebbe influire sulle tue dichiarazioni per il Play Store o l'App Store. Le richieste inviate dall'app ai server Capgo includono: - app_id (specificato in `capacitorconfigjson`) - channel (opzionale in `capacitorconfigjson`) - release_version (versionName da AndroidManifestxml o CFBundleShortVersionString da Infoplist o `capacitorconfigjson` se impostato in [`CapacitorUpdaterversion`](/docs/plugin/settings/#version)) - version_number (generato come parte di `npx @capgo/cli app update`) - os_version (es. '1121') - platform (es. 'android', necessario per inviare la patch corretta) - device_id (generato sul dispositivo al primo avvio, utilizzato per deduplicare le installazioni per dispositivo e permetterci di addebitare in base agli utenti installati)utenti attivi mensili), piuttosto che patch totali o installazioni totali di patch) - custom_id (opzionale, impostato durante l'esecuzione dallo sviluppatore, utilizzato per collegare un dispositivo a un utente nel tuo sistema) ### Quali piattaforme supporta Capgo? Attualmente, Capgo supporta iOS e Android. Entrambi sono pronti per la produzione. L'uso di Capgo per iOS o Android può essere una decisione indipendente. Puoi impostare nel tuo canale di distribuire su Android e un ipa creato per l'App Store o viceversa. Capgo può (relativamente facilmente) essere adattato per supportare desktop o target embedded. Se questi sono importanti per te, faccelo sapere. ### Come interagisce Capgo con i Play Testing Tracks o Apple TestFlight? Ciascuno degli app store ha meccanismi separati per distribuire app a gruppi limitati di utenti (es. "test interno", "beta chiusa", ecc.). Questi sono tutti meccanismi per segmentare i tuoi utenti in gruppi e distribuire versioni specifiche delle tue app a ciascuno. Purtroppo, non tutti questi meccanismi permettono a terze parti di rilevare quando le app sono installate in uno specifico Test Track o tramite TestFlight. Quindi, non abbiamo una visibilità affidabile sulla composizione di questi gruppi e non possiamo limitare in modo affidabile l'accesso agli aggiornamenti Capgo basati su questi gruppi [https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play](https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play/) [https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i](https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i/) Se desideri segmentare la disponibilità del bundle Capgo, ci sono 4 opzioni potenziali: 1. Usa canali separati per ogni gruppo. Questo è l'approccio più diretto, ma richiede di gestire più canali. Potresti già avere canali di sviluppo e produzione con diverse disponibilità. Puoi quindi aggiornare i tuoi canali di sviluppo, verificarli e poi aggiornare separatamente i tuoi canali di produzione. Consigliamo di utilizzare branch / tag nel controllo versione per tenere traccia delle fonti associate a ciascun rilascio. 2. Traccia il tuo insieme di utenti opt-in, disabilita gli aggiornamenti automatici e attiva gli aggiornamenti solo per determinati utenti tramite package:capgo_code_push. Questo funziona oggi, ma richiede di gestire la propria lista opt-in. 3. Capgo permette di creare il proprio meccanismo opt-in su base per-dispositivo (simile a Test Tracks o TestFlight, solo agnostico alla piattaforma). Questo permette al tuo team QA di opt-in al bundle prima che venga promosso al pubblico generale. 4. Capgo ha rollout percentuali. Questo non ti permette di scegliere quali dispositivi inviare, ma può aiutarti a distribuire incrementalmente e tornare indietro alla vista di eventuali problemi. ## Fatturazione ### Come faccio ad aggiornare o declassare il mio piano? Puoi aggiornare o declassare il tuo piano in qualsiasi momento nel tuo dashboard: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Quando si resetta il mio periodo di fatturazione? I periodi di fatturazione vengono resettati automaticamente ogni mese nel mese in cui ti sei abbonato per la prima volta a Capgo. Per esempio, se ti sei abbonato il 15 del mese, il tuo periodo di fatturazione si resetterà il 15 di ogni mese. ### Come faccio a cancellare il mio abbonamento? Puoi cancellare il tuo abbonamento in qualsiasi momento nel tuo dashboard: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Posso pagare per un anno in anticipo? Sì puoi farlo in qualsiasi momento nel tuo dashboard: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### Statistiche e analytics Le statistiche nel tuo dashboard vengono aggiornate ogni mezzanotte UTC. Le statistiche sono calcolate in base al numero di [MAU](https://capgo.app/docs/faq/#what-is-the-difference-between-a-bundle-and-a-release) che sono stati installati sui tuoi dispositivi. # Come viene generato l'ID del dispositivo L'ID del dispositivo viene generato sul dispositivo al primo avvio e viene utilizzato per deduplicare le installazioni per dispositivo e permetterci di addebitare in base agli utenti installati (es. utenti attivi mensili), piuttosto che patch totali o installazioni totali di patch. MAU è una soluzione migliore del numero di installazioni per prezzare Capgo, in quanto è più accurato e riflette il costo effettivo di Capgo per dispositivo. Per ragioni di privacy, non possiamo tracciare lo stesso dispositivo se l'utente reinstalla l'app. Le regole sulla privacy sono imposte da Apple e Google, e non sono imposte da Capgo. L'ID del dispositivo non sarà elencato nella tua lista dispositivi finché non ottengono la loro prima patch installata. # Perché il mio numero di dispositivi è diverso dal mio MAU? Attualmente, la lista dei dispositivi non viene aggiornata con la stessa frequenza del MAU. La lista dei dispositivi viene aggiornata solo quando un dispositivo installa un aggiornamento. Mentre il MAU viene aggiornato ad ogni avvio dell'app. Questa è una limitazione attuale della piattaforma. La nostra piattaforma Analytics non supporta aggiornamenti raw quindi utilizziamo database convenzionali per la lista Dispositivi. Per limitare il numero di query al database, aggiorniamo le righe solo all'aggiornamento dell'app. Questa limitazione sarà rimossa in futuro. # Come avere aggiornamenti diversi per piattaforma? Puoi creare un canale per ogni piattaforma e disabilitare gli aggiornamenti specifici per piattaforma in ciascun canale. Sul canale ios disabilita gli aggiornamenti android e sul canale android disabilita gli aggiornamenti ios. Quindi carica un bundle su ciascun canale per avere aggiornamenti diversi per ogni piattaforma. Se hai bisogno di avere lo stesso aggiornamento per entrambe le piattaforme, puoi collegare un bundle a più canali. Non è necessario duplicare il bundle. ``` # Supporto tecnico per capgo > Come ottenere assistenza per Capgo ## Supporto tramite discord Capgo ha un [server discord](https://discordcom/invite/VnYRvBfgA6) ufficiale. Ottenere supporto tecnico qui è probabilmente uno dei modi più rapidi per ricevere una risposta. Ecco una guida veloce: 1. vai al canale `questions` ![Ask on discord](/discord-questions.webp) 2. crea il tuo thread ![Create a question on discord](/discord-newquestion.webp) 3. Descrivi il tuo problema e seleziona i tag pertinenti ![Create a post on discord](/discord-new-post.webp) 4. Condividi il tuo ID account sicuro (opzionale) Questo permetterà allo staff di Capgo di esaminare il tuo account. Condividere questo ID è sicuro, poiché è stato progettato per essere condiviso pubblicamente. Per condividerlo, vai alle [impostazioni di Capgo](https://web.capgo.app/dashboard/settings/account/). Qui clicca su `copy account id` ![Share your id without leaking your info](/share-secure-id.webp) Questo copierà l’ID account sicuro negli appunti. Includi questo ID nel tuo post su Discord. ## Supporto via email Questo è il modo più lento per ricevere supporto. Ti preghiamo di utilizzare prima il server Discord. Se hai bisogno di contattarci via email, invia un’email a # Ajouter une App > Aggiungi un'app al tuo account Capgo e installa il plugin nella tua app ## Introduzione a Capgo [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## Gli aggiornamenti live sono a 3 passi di distanza ### Configurazione guidata 1. Crea il tuo account su ![signup screenshot](/signup.webp "signup screenshot") 2. Usa il comando Init per iniziare ```bash npx @capgo/cli@latest init [APIKEY] ``` Ti verranno presentate una serie di domande. Fornisci le risposte necessarie per completare la configurazione automatica Tip Seguendo questi passaggi, sarai operativo in pochissimo tempo. Se hai bisogno di ulteriore assistenza durante il processo, il nostro team di supporto è [qui per aiutarti](https://support.capgo.app) Buon onboarding! 3. Distribuisci un aggiornamento live [Deploy a live update ](/docs/getting-started/deploy/)Impara come distribuire un aggiornamento live alla tua app ### Configurazione manuale Nel caso in cui il comando init non funzioni, puoi aggiungere manualmente un’app 1. Connetti la CLI al tuo account: ```bash npx @capgo/cli@latest login [APIKEY] ``` 2. Aggiungi l’app al tuo account con questo comando: ```bash npx @capgo/cli@latest app add [APP_NAME] ``` 3. Installa il plugin nella tua app: ```json { "plugins": { CapacitorUpdater: { "appId": "Your appID", "autoUpdate": true, "version": "1.0.0" } } } ``` 4. Chiama il metodo init il prima possibile nella tua app: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; CapacitorUpdater.notifyAppReady(); ``` 5. Distribuisci un aggiornamento live [Deploy a live update ](/docs/getting-started/deploy/)Impara come distribuire un aggiornamento live alla tua app # Integrazione CI/CD L’integrazione di Capgo nella tua pipeline CI/CD ti permette di automatizzare completamente il processo di build e deploy degli aggiornamenti alla tua app. Sfruttando la CLI di Capgo e semantic-release, puoi garantire deployment consistenti e affidabili e abilitare iterazioni rapide. ## Benefici dell’Integrazione CI/CD * **Automazione**: Niente più passaggi manuali o spazio per errori umani. L’intero processo di build, test e deployment può essere automatizzato da cima a fondo. * **Consistenza**: Ogni deployment segue lo stesso set di passaggi, garantendo un processo prevedibile e ripetibile. Questo è particolarmente importante quando hai più membri del team che contribuiscono al codice. * **Iterazioni più veloci**: Con i deployment automatizzati, puoi rilasciare aggiornamenti più frequentemente e con sicurezza. Niente più attese per QA manuale o approvazioni dei rilasci. ## CLI di Capgo La CLI di Capgo è la chiave per integrare Capgo nel tuo workflow CI/CD. Fornisce comandi per pubblicare nuove versioni del bundle, gestire i canali e altro. Il comando più importante per l’integrazione CI/CD è `upload`: ```shell npx @capgo/cli@latest bundle upload --channel=Production --apikey YOUR_API_KEY ``` Questo comando carica la build web corrente sul canale specificato. Tipicamente lo eseguirai come ultimo step nella tua pipeline CI/CD, dopo che la build web è stata completata con successo. ## Configurare Capgo nella tua Pipeline CI/CD Mentre i passaggi esatti varieranno a seconda del tuo strumento CI/CD, il processo generale per integrare Capgo è il seguente: 1. **Generare una API key**: Accedi alla dashboard di Capgo e crea una nuova API key. Questa chiave sarà usata per autenticare la CLI nel tuo ambiente CI/CD. Mantienila segreta e non committarla mai nel tuo repository! 2. **Configurare il comando `upload`**: Aggiungi uno step alla tua configurazione CI/CD che esegue il comando `upload` con gli argomenti appropriati: upload.yml ```yaml - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secrets.CAPGO_API_KEY }} ``` \n Sostituisci `Production` con il canale su cui vuoi fare il deploy, e `${{ secrets.CAPGO_API_KEY }}` con la variabile d’ambiente che contiene la tua API key. 3. **Aggiungere lo step `upload` dopo la build web**: Assicurati che lo step `upload` arrivi dopo che la build web è stata completata con successo. Questo garantisce che stai sempre distribuendo il tuo codice più recente.\n Ecco un esempio di configurazione per GitHub Actions:\n upload.yml ```yaml name: Deploy to Capgo on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v4 with: node-version: 18 - run: npm ci - run: npm run build - run: npm install -g @capgo/cli - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secrets.CAPGO_API_KEY }} ``` ## Integrazione Semantic-release Semantic-release è uno strumento potente per automatizzare la gestione delle versioni e generare note di rilascio. Integrando semantic-release con Capgo, puoi incrementare automaticamente la versione della tua app e generare changelog con ogni deployment. Ecco un esempio di file di configurazione `releaserc` per semantic-release: ```json { "branches": [ "main", { "name": "beta", "prerelease": true } ], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", [ "@semantic-release/exec", { "publishCmd": "npx @capgo/cli@latest bundle upload --channel=${nextRelease.channel} --apikey YOUR_API_KEY --partial" } ], [ "@semantic-release/git", { "assets": ["CHANGELOG.md", "package.json"], "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" } ] ] } ``` Questa configurazione fa quanto segue: 1. Analizza i messaggi di commit per determinare il prossimo numero di versione, seguendo la specifica Conventional Commits 2. Genera note di rilascio basate sui commit dall’ultimo rilascio 3. Aggiorna il file `CHANGELOG.md` con le nuove note di rilascio 4. Esegue il comando `upload` della CLI di Capgo, passando il nuovo numero di versione e usando il flag `--partial` per gli aggiornamenti differenziali 5. Committa il `CHANGELOG.md` aggiornato, `package.json` e qualsiasi altro file modificato nel repository Per usare semantic-release con Capgo, aggiungi semplicemente uno step alla tua configurazione CI/CD che esegue `npx semantic-release`. Assicurati che questo step arrivi dopo la build web e prima dello step `upload` di Capgo. ## Risoluzione dei problemi Se incontri problemi con la tua integrazione CI/CD di Capgo, ecco alcune cose da controllare: * **API key**: Assicurati che la tua API key sia valida e abbia i permessi necessari. Se usi una variabile d’ambiente, ricontrolla che sia impostata correttamente. * **Versione CLI**: Assicurati di usare l’ultima versione della CLI di Capgo. Le versioni più vecchie potrebbero avere problemi di compatibilità o mancare di alcune funzionalità. * **Artefatti di build**: Conferma che la tua build web stia generando i file di output previsti. La CLI di Capgo ha bisogno di una build web valida per creare un bundle. * **Connettività di rete**: Verifica che il tuo ambiente CI/CD abbia accesso di rete ai server Capgo. Problemi di firewall o proxy possono talvolta interferire con il comando `upload`. Se stai ancora avendo problemi, contatta il supporto Capgo per assistenza. Possono aiutare a risolvere qualsiasi problema con la tua configurazione specifica. ## Conclusione Integrare Capgo nella tua pipeline CI/CD e sfruttare semantic-release per la gestione delle versioni può semplificare notevolmente il tuo workflow di sviluppo. Automatizzando i tuoi deployment e il versioning, puoi rilasciare aggiornamenti più velocemente e con più sicurezza. La CLI di Capgo e semantic-release forniscono una combinazione potente per ottenere rilasci completamente automatizzati da cima a fondo. Con un po’ di configurazione, puoi avere un processo di deployment robusto e affidabile che ti permette di concentrarti sulla creazione di grandi funzionalità invece di preoccuparti dei passaggi manuali di rilascio. Per maggiori dettagli sui comandi e le opzioni della CLI di Capgo, consulta la [referenza CLI](/docs/cli/overview). E per un approfondimento sulla configurazione di semantic-release, vedi la [documentazione di semantic-release](https://github.com/semantic-release/semantic-release). Buon deployment! # Implementa un Live Update Usa la funzione Live Updates di Capgo per aggiornare l’interfaccia utente e la logica di business della tua app da remoto, in tempo reale. Invia aggiornamenti del bundle JS direttamente ai tuoi utenti senza passare attraverso l’app store per correggere bug e distribuire nuove funzionalità istantaneamente. Questa guida presuppone che tu abbia completato il [Quickstart di Capgo](/docs/getting-started/quickstart) e che tu abbia già: 1. Installato l’SDK `@capgo/capacitor-updater` nella tua app Capacitor 2. Configurato l’ID della tua app e il canale di aggiornamento in `capacitorconfigts` 3. Aggiunto nel tuo codice il metodo `CapacitorUpdaternotifyAppReady()` Se non hai ancora completato questi passaggi, torna indietro e completa prima il quickstart [Aggiungi un'app ](/docs/getting-started/add-an-app/)Aggiungi un'app al tuo account Capgo e installa il plugin nella tua app ## Caricamento di un Bundle Con l’SDK Capgo installato e configurato, sei pronto per caricare il tuo primo bundle di aggiornamento live: 1. Compila i tuoi asset web: ```shell npm run build ``` 2. Carica il bundle su Capgo: * Console ```shell npx @capgo/cli@latest bundle upload --channel=Production ``` * Github Actions github/workflows/build\_and\_deployyml ```yml name: Build source code and send to Capgo concurrency: group: ${{ githubworkflow }}-${{ githubref }} cancel-in-progress: true on: push: branches: - main jobs: deploy_to_capgo: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v5 - uses: actions/setup-node@v4 with: node-version: 18 - name: Install dependencies run: npm install - name: Build run: npm run build - name: Deploy to Capgo run: bunx @capgo/cli@latest bundle upload -a ${{ secretsCAPGO_TOKEN }} --channel ${{ envCHANNEL }} env: CAPGO_TOKEN: ${{ secretsCAPGO_TOKEN }} ``` * Gitlab ```yml // gitlab-ciyml stages: - build build: stage: build image: node:18 cache: - key: files: - package-lockjson paths: - node_modules/ script: - npm install - npm run build - npx @capgo/cli@latest bundle upload -a $CAPGO_TOKEN --channel $CAPGO_CHANNEL artifacts: paths: - node_modules/ - dist/ only: - master ``` Questo caricherà una nuova versione del bundle nel canale specificato nel comando ### Risoluzione dei problemi durante il caricamento Se il caricamento fallisce, verifica: * Che l’ID della tua app in `capacitorconfigts` corrisponda alla tua app nella dashboard di Capgo * Che stai eseguendo il comando di caricamento dalla root del tuo progetto Capacitor * Che i tuoi asset web siano compilati e aggiornati Se continui ad avere problemi, vai alla sezione [Risoluzione dei problemi](/docs/getting-started/troubleshooting/) ## Ricezione di un aggiornamento su un dispositivo Una volta caricato il bundle, puoi testare l’aggiornamento live su un dispositivo: 1. Sincronizza la tua app con il dispositivo: ```shell npx cap sync ios ``` 2. Apri un altro terminale ed esegui il seguente comando per controllare lo stato dell’aggiornamento: ```shell npx @capgo/cli@latest app debug ``` 3. Esegui la tua app localmente: ```shell npx cap run ios ``` Oppure apri il progetto iOS/Android in Xcode/Android Studio ed esegui un run nativo 4. Mantieni l’app aperta per circa 30 secondi per permettere all’aggiornamento di scaricarsi in background 5. I log impiegheranno alcuni secondi per aggiornarsi e mostrare lo stato dell’aggiornamento 6. Chiudi e riapri l’app. Dovresti vedere l’aggiornamento live applicato! Torna al [Quickstart di Capgo](/docs/getting-started/quickstart#receiving-a-live-update-on-a-device) per maggiori dettagli sul test degli aggiornamenti live ## Prossimi passi Congratulazioni per aver distribuito il tuo primo aggiornamento live con Capgo! 🎉 Per saperne di più, consulta il resto della [documentazione Live Updates di Capgo](/docs/live-updates). Alcuni argomenti chiave da controllare: * [Targeting degli aggiornamenti con i canali](/docs/live-updates/channels) * [Personalizzazione del comportamento degli aggiornamenti](/docs/live-updates/update-behavior) * [Rollback degli aggiornamenti live](/docs/live-updates/rollbacks) # Panoramica Il tutorial rapido ti guiderà attraverso i concetti chiave di Capgo! I concetti che verranno esplorati includono: 1. Aggiungere un’app al tuo account Capgo 2. Integrare Capgo con il tuo CI/CD 3. Attivare il caricamento del bundle su Capgo tramite commit 4. Configurare e personalizzare la pubblicazione del bundle Capgo 5. Configurare la tua app per abilitare gli aggiornamenti in tempo reale tramite Capgo 6. Distribuire aggiornamenti in tempo reale alla tua app da Capgo Segui semplicemente la guida passo dopo passo, oppure naviga direttamente nella documentazione del componente che ti interessa [ Inizia il Tutorial](/docs/getting-started/add-an-app/) [Segui il tutorial rapido e inizia a utilizzare Capgo in pochissimo tempo!](/docs/getting-started/add-an-app/) [ Facile da integrare](/docs/getting-started/deploy/) [Integra Capgo con il tuo CI/CD e attiva il caricamento dei bundle su Capgo tramite commit](/docs/getting-started/deploy/) [ Documentazione Aggiornamenti in Tempo Reale](/docs/live-updates/) [Aggiorna la tua app da remoto in tempo reale senza ritardi dell’app store](/docs/live-updates/) [ Risoluzione Problemi](/docs/getting-started/troubleshooting) [Problemi comuni e come risolverli](/docs/getting-started/troubleshooting) Tip La funzionalità di aggiornamento Over-the-Air (OTA) è applicabile solo per modifiche apportate ai file HTML, CSS e JavaScript Se apporti modifiche al codice nativo, come aggiornamenti ai plugin Capacitor, è obbligatorio inviare nuovamente l’applicazione all’app store per l’approvazione ## Unisciti alla Community Discord [Unisciti al Server Discord di Capacitor-updater!](https://discordcom/invite/VnYRvBfgA6) ## Manutenzione | Versione plugin | Compatibilità Capacitor | Manutenzione | | --------------- | ----------------------- | ------------------------------------------------------------------------ | | v6\*\* | v6\*\* | ✅ | | v5\*\* | v5\*\* | Solo bug critici | | v4\*\* | v4\*\* | ⚠️ Deprecato | | v3\*\* | v3\*\* | ⚠️ Deprecato | | > 7 | v4\*\* | ⚠️ Deprecato, il nostro CI è impazzito e ha aumentato troppo le versioni | ## Conformità alle Linee Guida degli Store Google Play Android e App Store iOS hanno linee guida corrispondenti con regole di cui dovresti essere consapevole prima di integrare la soluzione Capacitor-updater nella tua applicazione ### Google play Il terzo paragrafo del tema [Device and Network Abuse](https://supportgooglecom/googleplay/android-developer/answer/9888379/?hl=en) descrive che l’aggiornamento del codice sorgente con qualsiasi metodo diverso dal meccanismo di aggiornamento di Google Play è limitato. Ma questa restrizione non si applica all’aggiornamento dei bundle javascript > Questa restrizione non si applica al codice che viene eseguito in una macchina virtuale e ha accesso limitato alle API Android (come JavaScript in una webview o browser) Questo permette completamente Capacitor-updater poiché aggiorna solo i bundle JS e non aggiornerà il codice nativo ### App Store Il paragrafo **3.3.2** del [Apple Developer Program License Agreement](https://developer.apple.com/programs/ios/information/) permette completamente di eseguire aggiornamenti over-the-air di JavaScript e asset - e nella sua ultima versione (20170605) [scaricabile qui](https://developer.apple.com/terms/) questa regola è ancora più ampia: > Il codice interpretato può essere scaricato in un’Applicazione solo se tale codice: (a) non modifica lo scopo principale dell’Applicazione fornendo funzionalità non coerenti con lo scopo previsto e pubblicizzato dell’Applicazione come presentato all’App Store, (b) non crea un negozio o vetrina per altro codice o applicazioni, e (c) non aggira la firma, il sandbox o altre funzionalità di sicurezza del SO Capacitor-updater ti permette di seguire queste regole in piena conformità purché l’aggiornamento che distribuisci non si discosti significativamente dall’intento originale approvato dall’App Store del tuo prodotto Per rimanere ulteriormente in conformità con le linee guida di Apple suggeriamo che le app distribuite sull’App Store non abilitino lo scenario di “Aggiornamento forzato”, poiché nelle [Linee guida per la revisione dell’App Store](https://developer.apple.com/app-store/review/guidelines/) si afferma che: > Le app non devono forzare gli utenti a valutare l’app, recensire l’app, scaricare altre app o altre azioni simili per accedere alle funzionalità, ai contenuti o all’utilizzo dell’app Questo non è un problema per il comportamento predefinito dell’aggiornamento in background, poiché non forzerà l’utente ad applicare la nuova versione fino alla prossima chiusura dell’app, ma dovresti essere consapevole di questo ruolo se decidi di mostrarlo ## Open source Il plugin è sotto Licenza LGPL-3.0 e il back-end è sotto Licenza AGPL-3.0 > 💡 LGPL-3.0 significa che se qualcuno modifica il codice del plugin, è obbligatorio pubblicarlo, in open-source con la stessa licenza. Se utilizzi il codice senza modifiche, questo non ti riguarda. Vedi il problema sotto per maggiori dettagli, controlla il link 👇 [Licenza? ](https://github.com/Cap-go/capacitor-updater/issues/7) [Prova GPTS Capgo per ottenere aiuto invece di leggere la documentazione ](https://chatopenaicom/g/g-3dMwHbF2w-capgo-doc-gpt) > Puoi includerlo nella tua app senza preoccupazioni ## Note Finali Se fai self-hosting e trovi questo strumento utile, considera di supportare il mio lavoro diventando un [sponsor GitHub](https://github.com/sponsors/riderx/) Ho scommesso di rendere open-source tutto il codice che ho costruito qui invece di metterlo dietro un paywall. Aprendo invece di combattere e nascondere, credo che possiamo rendere il mondo un posto migliore Per rendere questo possibile, è necessario che tutti facciamo la nostra parte, incluso te 🥹 Se Capgo cloud non soddisfa le tue esigenze, puoi supportare un Maker bootstrapped [qui](https://github.com/sponsors/riderx/) alle tue condizioni ## Matematica Semplice Il prezzo del piano base: $14\*12 = $168 all’anno Mentre la media dev/ora = $60 Ciò significa che 3 ore perse di tempo di sviluppo sul self-host ti permettono di pagare un intero anno, se hai speso più di 3 ore stai perdendo soldi ^^ # Risoluzione dei problemi Ecco alcuni problemi comuni che potresti incontrare durante l’utilizzo di Capgo e come risolverli ### Errori di caricamento Se il caricamento del bundle fallisce, verifica: * L’ID della tua app in `capacitor.config.ts` corrisponda alla tua app nel dashboard di Capgo * Stai eseguendo il comando di upload dalla root del tuo progetto Capacitor * I tuoi asset web sono compilati e aggiornati #### Opzioni avanzate di caricamento La CLI di Capgo fornisce alcuni flag aggiuntivi per aiutare con i problemi comuni di caricamento: * `--tus`: Utilizza il [protocollo di caricamento riprendibile tus](https://tus.io/) per caricamenti più affidabili di bundle grandi o su connessioni di rete scadenti. Se il tuo bundle supera i 10MB o hai una connessione instabile, considera di usare `--tus`: ```shell npx @capgo/cli@latest bundle upload --tus ``` * `--package-json` e `--node-modules`: Indica a Capgo dove trovare il tuo `package.json` root e `node_modules` se la tua app usa una struttura non standard come un monorepo o workspace npm. Passa il percorso al `package.json` root e il percorso `--node-modules`: ```shell npx @capgo/cli@latest bundle upload --package-json=path/to/package.json --node-modules=path/to/node_modules ``` Capgo ha bisogno di queste informazioni per impacchettare correttamente le dipendenze della tua app Puoi combinare questi flag con altre opzioni come `--channel` secondo necessità. Consulta la [documentazione CLI di Capgo](/docs/cli/overview/) per i dettagli completi sulle opzioni di caricamento disponibili Se hai ancora problemi con i caricamenti, contatta il [supporto Capgo](https://support.capgo.app) per ulteriore assistenza ### Debug degli Aggiornamenti Se riscontri problemi con gli aggiornamenti live, il comando debug di Capgo è uno strumento utile per la risoluzione dei problemi. Per usarlo: 1. Esegui il seguente comando nella directory del tuo progetto: ```shell npx @capgo/cli@latest app debug ``` 2. Avvia la tua app su un dispositivo o emulatore ed esegui l’azione che dovrebbe attivare un aggiornamento (es. riaprire l’app dopo aver caricato un nuovo bundle) 3. Osserva l’output del comando debug. Registrerà informazioni sul processo di aggiornamento, incluso: * Quando l’app controlla la presenza di un aggiornamento * Se viene trovato un aggiornamento e quale versione è * Progresso del download e dell’installazione dell’aggiornamento * Eventuali errori che si verificano durante il processo di aggiornamento 4. Usa i log di debug per identificare dove si verifica il problema. Per esempio: * Se non viene trovato alcun aggiornamento, ricontrolla che il bundle sia stato caricato con successo e che l’app sia configurata per utilizzare il canale corretto * Se l’aggiornamento viene scaricato ma non installato, assicurati di aver chiamato `CapacitorUpdater.notifyAppReady()` e che l’app sia stata completamente chiusa e riaperta * Se vedi un messaggio di errore, cerca quell’errore specifico nella documentazione Capgo o contatta il supporto per aiuto Il comando debug è particolarmente utile per identificare problemi con il processo di download e installazione dell’aggiornamento. Se i log mostrano che la versione di aggiornamento prevista è stata trovata ma non applicata definitivamente, concentra la risoluzione dei problemi sui passaggi successivi al download ### Debug con Log Nativi Oltre al comando debug di Capgo, i log nativi su Android e iOS possono fornire preziose informazioni per la risoluzione dei problemi, specialmente per problemi sul lato nativo del processo di aggiornamento #### Log Android Per accedere ai log Android: 1. Collega il tuo dispositivo o avvia il tuo emulatore 2. Apri Android Studio e seleziona “View > Tool Windows > Logcat” 3. Nella finestra Logcat, filtra i log solo per il processo della tua app selezionandolo dal menu a tendina in alto 4. Cerca le righe che includono `Capgo` per trovare i log dell’SDK In alternativa, puoi usare il comando `adb logcat` e grep per `Capgo` per filtrare i log L’SDK Capgo registrerà eventi chiave durante il processo di aggiornamento, come: * Quando viene avviato un controllo degli aggiornamenti * Se viene trovato un aggiornamento e quale versione è * Quando il download dell’aggiornamento inizia e si completa * Quando viene attivata l’installazione dell’aggiornamento * Eventuali errori che si verificano durante i passaggi di aggiornamento nativi Problemi comuni specifici di Android che potresti vedere nei log includono: * Problemi di connettività di rete che impediscono il download dell’aggiornamento * Errori di permessi dei file durante il salvataggio o la lettura del bundle di aggiornamento * Spazio di archiviazione insufficiente per il bundle di aggiornamento * Impossibilità di riavviare l’app dopo l’installazione dell’aggiornamento #### Log iOS Per accedere ai log iOS: 1. Collega il tuo dispositivo o avvia il tuo simulatore 2. Apri Xcode e vai su “Window > Devices and Simulators” 3. Seleziona il tuo dispositivo e clicca su “Open Console” 4. Nell’output della console, cerca le righe che includono `Capgo` per trovare i log dell’SDK Puoi anche usare il comando `log stream` nel terminale e grep per `Capgo` per filtrare i log Similmente ad Android, l’SDK Capgo registrerà eventi chiave lato iOS: * Avvio e risultato del controllo aggiornamenti * Inizio, progresso e completamento del download * Attivazione e risultato dell’installazione * Eventuali errori durante il processo di aggiornamento nativo Problemi specifici di iOS che potresti identificare nei log includono: * Problemi con i certificati SSL durante il download dell’aggiornamento * App Transport Security che blocca il download dell’aggiornamento * Spazio di archiviazione insufficiente per il bundle di aggiornamento * Impossibilità di estrarre o applicare correttamente il bundle di aggiornamento Su entrambe le piattaforme, i log nativi forniscono una visione più dettagliata del processo di aggiornamento, con più dettagli sull’implementazione nativa. Sono particolarmente utili per identificare problemi che si verificano al di fuori del layer JavaScript di Capgo Quando si risolve un problema complesso di aggiornamento live, è consigliabile catturare sia i log di debug di Capgo che i log nativi per avere un quadro completo di ciò che sta accadendo. I due log insieme ti daranno la migliore possibilità di identificare e risolvere il problema ### Aggiornamenti non applicati Se hai caricato un bundle ma non vedi i cambiamenti sul tuo dispositivo: * Assicurati di aver chiamato `CapacitorUpdater.notifyAppReady()` nel codice della tua app come mostrato nel [quickstart](/docs/getting-started/quickstart) * Verifica che il tuo dispositivo sia connesso a internet e i log di debug di Capgo mostrino che l’aggiornamento è stato scaricato * Prova a chiudere completamente e riaprire l’app, poiché gli aggiornamenti vengono applicati solo all’avvio * Cerca eventuali errori nei log nativi che potrebbero indicare un problema nell’applicazione dell’aggiornamento Consulta la guida [deploying live updates](/docs/getting-started/deploy) per maggiori dettagli sul processo di aggiornamento. Se sei ancora bloccato, usa il comando `npx @capgo/cli@latest app debug` e i log nativi per avere più visibilità su ciò che sta accadendo ## Installazione SDK Se hai problemi con l’installazione dell’SDK Capgo, assicurati che: * La tua app stia usando una versione supportata di Capacitor (4.0 o più recente) * Hai seguito i passaggi del [quickstart](/docs/getting-started/quickstart) in ordine, inclusa la sincronizzazione della tua app dopo l’installazione dell’SDK ## Integrazione CI/CD Per problemi con l’attivazione dei caricamenti Capgo dalla tua pipeline CI/CD: * Ricontrolla che il tuo token di autenticazione Capgo sia configurato correttamente * Assicurati di eseguire il comando di upload dopo che i tuoi asset web sono stati compilati * Verifica che il comando di upload stia usando il nome del canale corretto per il tuo ambiente target Consulta la documentazione [CI/CD integration](/docs/getting-started/cicd-integration) per altri suggerimenti sulla risoluzione dei problemi. Puoi anche usare il comando `npx @capgo/cli@latest app debug` per confermare se i tuoi aggiornamenti attivati da CI/CD vengono ricevuti dall’app # Come fare > Come utilizzare Capgo, tutorial, suggerimenti e trucchi [Come funziona la gestione delle versioni in Capgo ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [Come rilasciare una versione major in Capgo ](https://capgo.app/blog/how-to-release-major-version-in-capgo/)capgo.app [Come inviare un aggiornamento specifico a un utente o a un gruppo ](https://capgo.app/blog/how-to-send-specific-version-to-users/)capgo.app ## CI / CD [Build e rilascio automatico con GitHub Actions ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [Gestire build di sviluppo e produzione con GitHub Actions ](https://capgo.app/blog/automatic-build-and-release-with-github-actions/)capgo.app ## Contribuire [Contribuire all'open source di Capgo ](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTINGmd)githubcom # Panoramica Utilizza la funzione Live Updates di Capgo per aggiornare i bundle JavaScript della tua app da remoto, in tempo reale. Invia aggiornamenti JS direttamente ai tuoi utenti senza passare attraverso il processo di revisione dell’app store per correggere bug e distribuire nuove funzionalità istantaneamente Note I Live Updates sono limitati alle modifiche del bundle JavaScript. Se hai bisogno di aggiornare il codice nativo, come aggiungere o rimuovere un plugin o modificare la configurazione del progetto nativo, dovrai inviare una nuova build binaria nativa agli app store ## Come funzionano i Live Updates Il sistema Live Update di Capgo ha due componenti chiave: 1. L’SDK Capgo, che installi nella tua app. L’SDK controlla la disponibilità di aggiornamenti e li scarica in background 2. I Canali, che ti permettono di indirizzare gli aggiornamenti a specifici gruppi di utenti. Puoi utilizzare i canali per gestire diverse tracce di rilascio, come `Production`, `Staging` e `Dev` Quando carichi un nuovo bundle JS su Capgo e lo assegni a un canale, l’SDK Capgo nelle app configurate per quel canale rileverà l’aggiornamento e lo scaricherà. Al successivo riavvio dell’app, verrà caricato il nuovo bundle ## Per iniziare Per iniziare a utilizzare i Live Updates, segui questi passaggi: 1. Completa il [Quickstart di Capgo](/docs/getting-started/quickstart) per configurare la tua app in Capgo e installare l’SDK Capgo 2. Nel codice della tua app, chiama `CapacitorUpdater.notifyAppReady()` dopo che la tua app ha terminato l’inizializzazione. Questo comunica all’SDK Capgo che la tua app è pronta a ricevere aggiornamenti 3. Compila il tuo bundle JS e caricalo su Capgo: ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. Apri la tua app e attendi che l’aggiornamento venga scaricato. Puoi controllare lo stato con: ```shell npx @capgo/cli@latest app debug ``` 5. Una volta scaricato l’aggiornamento, chiudi e riapri la tua app per caricare il nuovo bundle Consulta la guida [Deploying Live Updates](/docs/getting-started/deploy) per maggiori dettagli ## Prossimi passi [ Canali](/docs/live-updates/channels/) [Scopri come utilizzare i canali per gestire diverse tracce di rilascio e indirizzare gli aggiornamenti a specifici utenti](/docs/live-updates/channels/) [ Rollback](/docs/live-updates/rollbacks/) [Scopri come tornare a una versione precedente del bundle JS se un aggiornamento causa problemi](/docs/live-updates/rollbacks/) [ Comportamento degli aggiornamenti](/docs/live-updates/update-behavior/) [Personalizza come e quando gli aggiornamenti vengono scaricati e applicati nella tua app](/docs/live-updates/update-behavior/) [ Aggiornamenti rapidi](/docs/live-updates/differentials/) [Scopri come utilizzare gli aggiornamenti rapidi per velocizzare il processo di aggiornamento](/docs/live-updates/differentials/) # Canali Un canale Live Update punta a una specifica build del bundle JS della tua app che sarà condivisa con qualsiasi dispositivo configurato per ascoltare quel canale per gli aggiornamenti. Quando [installi l’SDK Capgo Live Updates](/docs/getting-started/quickstart/) nella tua app, ogni binario nativo configurato su quel canale controllerà gli aggiornamenti disponibili ogni volta che l’app viene avviata. Puoi cambiare la build a cui punta un canale in qualsiasi momento e puoi anche tornare a build precedenti se necessario. ## Configurare un Canale Ogni app viene fornita con un canale predefinito chiamato “Production” che non può essere eliminato. Per aggiungere nuovi canali: 1. Vai alla sezione “Channels” della dashboard Capgo 2. Clicca sul pulsante “New Channel” 3. Inserisci un nome per il canale e clicca “Create” I nomi dei canali possono essere qualsiasi cosa tu desideri. Una strategia comune è far corrispondere i canali alle tue fasi di sviluppo, come: * `Development` - per testare gli aggiornamenti live su dispositivi locali o emulatori * `QA` - per il team QA per verificare gli aggiornamenti prima del rilascio più ampio * `Staging` - per i test finali in un ambiente simile alla produzione * `Production` - per la versione della tua app che gli utenti finali ricevono dagli app store ## Configurare il Canale nella Tua App Con i tuoi canali creati, devi configurare la tua app per ascoltare il canale appropriato. In questo esempio, useremo il canale `Development` Apri il tuo file `capacitor.config.ts` (o `capacitor.config.json`). Nella sezione `plugins`, imposta la proprietà `channel` del plugin `CapacitorUpdater` con il nome del canale desiderato: ```ts import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { defaultChannel: 'Development', }, }, }; ``` Successivamente, compila la tua web app ed esegui `npx cap sync` per copiare il file di configurazione aggiornato nei tuoi progetti iOS e Android. Se salti questo passaggio di sincronizzazione, i tuoi progetti nativi continueranno a utilizzare il canale per cui erano precedentemente configurati. Caution La proprietà `defaultChannel` sovrascriverà sempre il canale predefinito del cloud. Ma puoi ancora forzare il deviceId a un canale nel Cloud ## Assegnare un Bundle a un Canale Per distribuire un aggiornamento live, devi caricare una nuova build del bundle JS e assegnarla a un canale. Puoi farlo in un unico passaggio con la CLI di Capgo: ```shell npx @capgo/cli@latest bundle upload --channel=Development ``` Questo caricherà i tuoi asset web compilati e imposterà il nuovo bundle come build attiva per il canale `Development`. Qualsiasi app configurata per ascoltare quel canale riceverà l’aggiornamento la prossima volta che controllerà. Puoi anche assegnare le build ai canali dalla sezione “Bundles” della dashboard Capgo. Clicca sull’icona del menu accanto a una build e seleziona “Assign to Channel” per scegliere il canale per quella build. ## Versionamento dei Bundle e Canali È importante notare che i bundle in Capgo sono globali per la tua app, non specifici per i singoli canali. Lo stesso bundle può essere assegnato a più canali. Per il versionamento dei bundle, consigliamo di utilizzare il versionamento semantico [semver](https://semver.org/) con identificatori di pre-release per le build specifiche del canale. Ad esempio, una versione beta potrebbe essere versionata come `1.2.3-beta.1`. Questo approccio ha diversi vantaggi: * Comunica chiaramente la relazione tra le build: `1.2.3-beta.1` è ovviamente una pre-release di `1.2.3` * Permette di riutilizzare i numeri di versione tra i canali, riducendo la confusione * Abilita percorsi di rollback chiari. Se devi tornare indietro da `1.2.3`, sai che `1.2.2` è la precedente versione stabile Ecco un esempio di come potresti allineare le versioni dei bundle con una tipica configurazione dei canali: * Canale `Development`: `1.2.3-dev.1`, `1.2.3-dev.2`, ecc. * Canale `QA`: `1.2.3-qa.1`, `1.2.3-qa.2`, ecc. * Canale `Staging`: `1.2.3-rc.1`, `1.2.3-rc.2`, ecc. * Canale `Production`: `1.2.3`, `1.2.4`, ecc. ## Rollback di un Aggiornamento Live Se distribuisci un aggiornamento live che introduce un bug o che necessita di essere revocato, puoi facilmente tornare a una build precedente. Dalla sezione “Channels” della dashboard: 1. Clicca sul nome del canale che vuoi ripristinare 2. Trova la build a cui vuoi tornare e clicca sull’icona della corona ![Rollback build](/select_bundle.webp) 3. Conferma l’azione La build selezionata diventerà immediatamente la build attiva per quel canale. Le app riceveranno la versione ripristinata la prossima volta che controlleranno gli aggiornamenti. ## Automatizzare i Deployment Per flussi di lavoro più avanzati, puoi automatizzare i tuoi deployment di aggiornamenti live come parte della tua pipeline CI/CD. Integrando Capgo nel tuo processo di build, puoi caricare automaticamente nuovi bundle e assegnarli ai canali ogni volta che fai push su determinati branch o crei nuove release. Consulta la documentazione [Integrazione CI/CD](/docs/getting-started/cicd-integration/) per saperne di più sull’automazione degli aggiornamenti live di Capgo. ## Distribuire su un Dispositivo Ora che hai compreso i canali, sei pronto per iniziare a distribuire aggiornamenti live su dispositivi reali. Il processo base è: 1. Installare l’SDK Capgo nella tua app 2. Configurare l’app per ascoltare il canale desiderato 3. Caricare una build e assegnarla a quel canale 4. Avviare l’app e attendere l’aggiornamento! Per una guida più dettagliata, consulta la guida [Distribuire Aggiornamenti Live](/docs/getting-started/deploy/). Buon aggiornamento! # Aggiornamenti rapidi Il sistema di Live Update di Capgo può distribuire aggiornamenti più velocemente e in modo più efficiente inviando solo i file modificati, invece dell’intero bundle JS Questo è particolarmente vantaggioso per gli utenti con connessioni di rete più lente o a consumo, poiché minimizza la quantità di dati da scaricare Un secondo vantaggio si ha quando l’app ha risorse pesanti che cambiano raramente, come immagini o video, rispetto ai file JS compressi verranno scaricati solo una volta ## Come Funzionano gli Aggiornamenti Differenziali Gli aggiornamenti differenziali in Capgo sono gestiti dal plugin Capgo installato nella tua app. Quando carichi una nuova versione della tua app usando il flag `--partial`, Capgo esegue quanto segue: 1. Ogni file nella tua build viene caricato individualmente 2. Vengono generati i checksum per ogni file 3. Viene creato un nuovo manifest json, che elenca tutti i file e i loro checksum 4. Questo manifest viene caricato nel database di Capgo Quando un dispositivo che esegue la tua app verifica la presenza di un aggiornamento, il plugin Capgo riceve il nuovo manifest dal server. Confronta questo manifest con quello che ha attualmente, identificando quali file sono cambiati in base ai checksum e ai percorsi dei file Il plugin quindi scarica solo i file modificati, invece dell’intero bundle JS. Ricostruisce la nuova versione dell’app combinando questi file scaricati con i file non modificati che ha già Manifest In caso di aggiornamenti differenziali, il dispositivo memorizza tutti i file scaricati in una cache comune, Capgo non la pulirà mai ma il sistema operativo può farlo in qualsiasi momento ## Abilitare gli Aggiornamenti Differenziali Per abilitare gli aggiornamenti differenziali per la tua app Capgo, usa semplicemente il flag `--partial` quando carichi una nuova versione: ## Imporre gli Aggiornamenti Differenziali Se vuoi assicurarti che tutti i caricamenti siano aggiornamenti differenziali e impedire qualsiasi caricamento accidentale del bundle completo, puoi usare il flag `--partial-only`: ```shell npx @capgo/cli@latest bundle upload --partial-only ``` Quando viene usato `--partial-only`, Capgo caricherà solo file individuali e genererà un manifest. Qualsiasi dispositivo che non supporta il parziale non sarà in grado di scaricare l’aggiornamento Potresti voler usare `--partial-only` se: * Vuoi sempre usare aggiornamenti differenziali e non vuoi mai permettere caricamenti di bundle completi * Stai configurando una pipeline CI/CD e vuoi assicurarti che tutti i caricamenti automatizzati siano differenziali * La tua app è grande e la banda è limitata, quindi devi minimizzare le dimensioni di upload/download Se hai bisogno di fare un caricamento del bundle completo mentre `--partial-only` è impostato, esegui semplicemente il comando di caricamento senza `--partial-only`. Questo sovrascriverà l’impostazione per quel singolo caricamento, permettendoti di inviare un bundle completo quando necessario ## Risoluzione dei Problemi Se gli aggiornamenti differenziali non sembrano funzionare (cioè i dispositivi stanno sempre scaricando l’intero bundle JS anche per piccole modifiche), verifica che: * Stai usando il flag `--partial` ogni volta che carichi una nuova versione * Se usi `--partial-only`, assicurati di non aver omesso accidentalmente il flag `--partial` * Il tuo dispositivo sta eseguendo l’ultima versione del plugin Capgo * Il tuo dispositivo ha una connessione di rete stabile e può raggiungere i server Capgo Puoi anche usare la webapp Capgo per controllare i dettagli del tuo ultimo caricamento: 1. Vai alla [webapp](https://app.capgo.io) 2. Clicca sulla tua app 3. Clicca sul numero dei bundle nella barra delle statistiche 4. Seleziona l’ultimo bundle 5. Controlla il campo `Partial` ![bundle type](/bundle_type.webp) Se continui ad avere problemi, contatta il supporto Capgo per ulteriore assistenza. Possono controllare i log del server per confermare che i tuoi caricamenti parziali vengono elaborati correttamente e che i dispositivi stanno ricevendo i manifest aggiornati Ecco fatto! Il flag `--partial` dice a Capgo di eseguire i caricamenti dei file individuali e la generazione del manifest necessari per gli aggiornamenti differenziali Nota che devi usare `--partial` ogni volta che carichi una nuova versione che vuoi sia distribuita come aggiornamento differenziale. Se ometti il flag, Capgo caricherà l’intero bundle JS come un singolo file, e i dispositivi scaricheranno l’intero bundle anche se solo una piccola parte è cambiata # Rollback Mentre gli aggiornamenti live di Capgo ti permettono di distribuire rapidamente miglioramenti e correzioni ai tuoi utenti, potrebbero esserci situazioni in cui devi tornare a una versione precedente della tua app. Forse un nuovo aggiornamento ha introdotto un problema critico inaspettato, o magari vuoi ripristinare una modifica specifica mentre lavori a una correzione. Capgo fornisce diversi modi per gestire le build di un canale e controllare la versione della tua app che gli utenti ricevono. ## Tornare a un Bundle Precedente Ogni volta che carichi una nuova build e la assegni a un canale, Capgo mantiene una cronologia di quelle build. Se hai bisogno di ripristinare un aggiornamento specifico, puoi selezionare una di queste build precedenti da ridistribuire sul canale. Per tornare a una build precedente: 1. Accedi alla [Dashboard di Capgo](https://app.capgo.io) 2. Vai alla sezione “Channels” 3. Clicca sul nome del canale che vuoi ripristinare 4. Trova la build a cui vuoi tornare nella cronologia delle build del canale 5. Clicca sull’icona della corona accanto a quella build per renderla la build attiva per il canale ![Opzioni di gestione del canale](/select_bundle.webp) 6. Conferma di voler tornare a questa build Note Il ripristino a una build precedente influisce solo sul canale selezionato. Se hai più canali (es. Produzione, Staging, ecc.), dovrai ripetere il processo di ripristino per ogni canale interessato. Dopo il ripristino, i dispositivi configurati per ascoltare il canale aggiornato riceveranno la build precedente al prossimo controllo degli aggiornamenti. La build ripristinata verrà trattata come un nuovo aggiornamento, quindi si applicano le solite condizioni e flussi di aggiornamento. ## Scollegare un Canale Se vuoi interrompere temporaneamente gli aggiornamenti su un canale mentre indaghi su un problema, puoi scollegare il canale dalla sua build corrente. Per scollegare un canale: 1. Vai al canale nella Dashboard di Capgo 2. Clicca sul pulsante “Unlink” accanto alla build corrente 3. Conferma di voler scollegare il canale Una volta che un canale è scollegato, non distribuirà nuovi aggiornamenti. I dispositivi configurati su quel canale rimarranno sulla loro build corrente fino a quando il canale non verrà ricollegato a una build. Questo è utile se hai identificato un problema con un aggiornamento ma non sei ancora sicuro a quale build vuoi tornare. Scollegare il canale ti dà tempo per indagare senza distribuire ulteriori aggiornamenti. ## Forzare il Bundle Integrato In situazioni più gravi, potresti voler riportare tutti i dispositivi su un canale al build web che era originariamente incluso nel binario nativo della tua app. Questo è noto come “bundle integrato”. Per forzare il bundle integrato su un canale: 1. Vai al canale nella Dashboard di Capgo 2. Clicca sul pulsante “Built-in Bundle” 3. Conferma di voler forzare il bundle integrato Quando forzi il bundle integrato, tutti i dispositivi configurati su quel canale torneranno al build web originale incluso nel pacchetto al prossimo controllo degli aggiornamenti. Questo accade indipendentemente dalla build su cui si trovano attualmente. Questa è un’opzione di ripristino più aggressiva rispetto al ritorno a una specifica build precedente, poiché scarta tutti gli aggiornamenti live rilasciati da quando l’app è stata pubblicata per l’ultima volta negli app store. Caution Sii cauto quando forzi il bundle integrato, poiché influirà su tutti i dispositivi sul canale. Assicurati di aver considerato l’impatto e di avere un piano per andare avanti prima di intraprendere questa azione. ## Monitoraggio e Risposta ai Problemi Per individuare rapidamente i problemi e minimizzare l’impatto degli aggiornamenti problematici, è importante avere un piano per monitorare i rilasci e rispondere ai problemi. Alcune strategie includono: * Monitorare i report di crash e il feedback degli utenti immediatamente dopo il rilascio di un aggiornamento * Utilizzare rollout graduali o un sistema di canali a fasi per testare gli aggiornamenti su un gruppo più piccolo prima del rilascio generale * Avere un processo decisionale chiaro per quando tornare indietro, scollegare o forzare il bundle integrato, e chi ha l’autorità per farlo * Comunicare agli utenti il problema e la risoluzione, se appropriato Combinando un attento monitoraggio con la capacità di gestire rapidamente gli aggiornamenti problematici, puoi offrire un’esperienza app in continuo miglioramento minimizzando le interruzioni per i tuoi utenti. # Comportamento di aggiornamento Quando rilasci un aggiornamento della tua app Capgo, probabilmente vuoi che i tuoi utenti lo ricevano il prima possibile. Ma non vuoi nemmeno interrompere la loro esperienza costringendoli ad attendere un download o riavviare l’app nel mezzo di una sessione. Il comportamento di aggiornamento di Capgo è progettato per trovare un equilibrio tra la distribuzione rapida degli aggiornamenti e la minimizzazione delle interruzioni per i tuoi utenti. ## Flusso di Aggiornamento Predefinito Di default, ecco come Capgo gestisce gli aggiornamenti dell’app: 1. All’avvio dell’app, il plugin Capgo verifica se è disponibile un nuovo aggiornamento 2. Se viene trovato un aggiornamento, viene scaricato in background mentre l’utente continua a utilizzare la versione corrente dell’app 3. Una volta completato il download, Capgo attende che l’utente metta l’app in background o la chiuda completamente 4. Quando l’utente avvia nuovamente l’app, utilizzerà la versione aggiornata Questo flusso garantisce che gli utenti utilizzino sempre l’ultima versione della tua app, senza mai essere interrotti da prompt di aggiornamento o costretti ad attendere i download. Tip Capgo controlla anche gli aggiornamenti quando l’app riprende dal background, quindi gli utenti riceveranno gli aggiornamenti anche se non chiudono completamente l’app ## Perché Questo Approccio? L’applicazione degli aggiornamenti in background o alla chiusura ha diversi vantaggi chiave per l’esperienza utente: * Gli utenti non vengono interrotti da prompt di aggiornamento o costretti ad attendere i download durante una sessione * Gli aggiornamenti vengono applicati senza problemi tra le sessioni, quindi l’esperienza di avvio dell’app è sempre nuova * Puoi distribuire aggiornamenti frequentemente senza preoccuparti di interrompere gli utenti attivi Lo svantaggio principale è che se un utente mette in background e riprende rapidamente la tua app, potrebbe perdere qualsiasi stato non salvato poiché l’aggiornamento è stato applicato tra queste azioni. Per mitigare questo, raccomandiamo di: * Salvare lo stato frequentemente e ripristinarlo correttamente quando l’app riprende * Evitare aggiornamenti molto frequenti che modificano grandi parti dello stato dell’app * Considerare la personalizzazione del comportamento di aggiornamento per i flussi sensibili (vedi sotto) ## Personalizzazione dell’Applicazione degli Aggiornamenti In alcuni casi, potresti volere più controllo su quando viene applicato un aggiornamento. Ad esempio, potresti voler assicurarti che un utente completi un flusso in corso prima dell’aggiornamento, o coordinare un aggiornamento dell’app con una modifica lato server. Capgo fornisce una funzione `setDelay` che ti permette di specificare le condizioni che devono essere soddisfatte prima che un aggiornamento venga installato: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; await CapacitorUpdater.setMultiDelay({ delayConditions: [ { kind: 'date', value: '2023-06-01T00:00:00.000Z', }, { kind: 'background', value: '60000', }, ], }); ``` Questo esempio ritarderebbe l’installazione di un aggiornamento fino a dopo il 1° giugno 2023 E l’app è stata in background per almeno 60 secondi. Le condizioni di ritardo disponibili sono: * `date`: Attendi fino a dopo una data/ora specifica per applicare l’aggiornamento * `background`: Attendi una durata minima dopo che l’app è stata messa in background per applicare l’aggiornamento * `nativeVersion`: Attendi che sia installata una versione binaria nativa con una versione minima prima di applicare l’aggiornamento * `kill`: Attendi fino al prossimo evento di chiusura dell’app per applicare l’aggiornamento Puoi combinare queste condizioni per controllare precisamente quando viene installato un aggiornamento. Danger Nota che la condizione `kill` attualmente attiva l’aggiornamento dopo il primo evento di chiusura, non il prossimo evento di background come le altre condizioni. Questa inconsistenza sarà corretta in una versione futura ## Applicazione Immediata degli Aggiornamenti Per aggiornamenti critici o app con stato molto semplice, potresti voler applicare un aggiornamento non appena viene scaricato, senza attendere un evento di background o chiusura. Capgo supporta questo tramite l’opzione di configurazione `directUpdate`. `directUpdate` viene impostato nel tuo file `capacitor.config.ts`, non nel codice JavaScript: ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: true, keepUrlPathAfterReload: true, }, }, }; export default config; ``` Con `directUpdate` abilitato, Capgo applicherà immediatamente un aggiornamento non appena il download è completato, anche se l’utente sta attivamente utilizzando l’app. Nota che poiché `directUpdate` è una configurazione nativa, richiede alcune gestioni aggiuntive nel tuo codice JavaScript. Quando usi `directUpdate`, devi ascoltare l’evento `appReady` e nascondere la schermata di splash della tua app in risposta: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater'; import { SplashScreen } from '@capacitor/splash-screen'; CapacitorUpdater.addListener('appReady', () => { // Nascondi la schermata di splash SplashScreen.hide(); }); CapacitorUpdater.notifyAppReady(); ``` L’evento `appReady` si attiva una volta che l’app ha finito di inizializzare e applicare eventuali aggiornamenti in sospeso. Questo è il momento in cui è sicuro mostrare l’interfaccia utente della tua app, poiché assicura che l’utente vedrà l’ultima versione. Oltre a gestire l’evento `appReady`, raccomandiamo di impostare l’opzione di configurazione `keepUrlPathAfterReload` su `true` quando si usa `directUpdate`. Questo preserva il percorso URL corrente quando l’app viene ricaricata a causa di un aggiornamento, aiutando a mantenere la posizione dell’utente nell’app e riducendo il disorientamento. Se non gestisci l’evento `appReady` e non imposti `keepUrlPathAfterReload` quando usi `directUpdate`, l’utente potrebbe vedere brevemente una versione obsoleta dell’app, essere riportato al percorso iniziale, o vedere uno sfarfallio mentre l’aggiornamento viene applicato. L’uso di `directUpdate` può essere utile per distribuire correzioni di bug critici o patch di sicurezza, ma comporta alcuni compromessi: * L’utente potrebbe vedere un breve sfarfallio o stato di caricamento mentre l’aggiornamento viene applicato se non gestisci correttamente l’evento `appReady` * Se l’aggiornamento modifica lo stato dell’app o l’interfaccia utente, l’utente potrebbe vedere un cambiamento dirompente nel mezzo di una sessione * La posizione dell’utente nell’app potrebbe essere persa se `keepUrlPathAfterReload` non è impostato, potenzialmente disorientandolo * Dovrai gestire attentamente il salvataggio e il ripristino dello stato per garantire una transizione fluida Se abiliti `directUpdate`, raccomandiamo di: * Gestire l’evento `appReady` per controllare quando viene mostrata l’interfaccia utente della tua app * Impostare `keepUrlPathAfterReload` su `true` per preservare la posizione dell’utente nell’app * Salvare e ripristinare lo stato dell’app secondo necessità per evitare di perdere i progressi dell’utente * Testare accuratamente il comportamento di aggiornamento della tua app per assicurarti che non ci siano transizioni brusche, stati persi o cambiamenti di posizione disorientanti Nella maggior parte dei casi, il comportamento di aggiornamento predefinito fornisce il miglior equilibrio tra la distribuzione rapida degli aggiornamenti e la minimizzazione delle interruzioni. Ma per app con esigenze specifiche, Capgo fornisce la flessibilità di personalizzare quando e come vengono applicati gli aggiornamenti. # Funzioni e impostazioni > Tutti i metodi e le impostazioni disponibili del plugin # Configurazione del Plugin Updater Consulta [Readme](https://github.com/Cap-go/capacitor-updater) su Github per maggiori informazioni CapacitorUpdater può essere configurato con queste opzioni: | Proprietà | Tipo | Descrizione | Predefinito | Da | | ------------------------ | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | ----- | | **`appReadyTimeout`** | `number` | Configura il numero di millisecondi che il plugin nativo deve attendere prima di considerare un aggiornamento ‘fallito’. Disponibile solo per Android e iOS | `10000 // (10 secondi)` | | | **`responseTimeout`** | `number` | Configura il numero di millisecondi che il plugin nativo deve attendere prima di considerare timeout l’API. Disponibile solo per Android e iOS | `20 // (20 secondi)` | | | **`autoDeleteFailed`** | `boolean` | Configura se il plugin deve eliminare automaticamente i bundle falliti. Disponibile solo per Android e iOS | `true` | | | **`autoDeletePrevious`** | `boolean` | Configura se il plugin deve eliminare automaticamente i bundle precedenti dopo un aggiornamento riuscito. Disponibile solo per Android e iOS | `true` | | | **`autoUpdate`** | `boolean` | Configura se il plugin deve utilizzare l’aggiornamento automatico tramite un server di aggiornamento. Disponibile solo per Android e iOS | `true` | | | **`resetWhenUpdate`** | `boolean` | Elimina automaticamente i bundle scaricati in precedenza quando viene installata una nuova versione nativa dell’app sul dispositivo. Disponibile solo per Android e iOS | `true` | | | **`updateUrl`** | `string` | Configura l’URL/endpoint a cui vengono inviati i controlli di aggiornamento. Disponibile solo per Android e iOS | `https://plugin.capgo.app/updates` | | | **`channelUrl`** | `string` | Configura l’URL/endpoint per le operazioni sui canali. Disponibile solo per Android e iOS | `https://plugin.capgo.app/channel_self` | | | **`statsUrl`** | `string` | Configura l’URL/endpoint a cui vengono inviate le statistiche di aggiornamento. Disponibile solo per Android e iOS. Impostare a "" per disabilitare la segnalazione delle statistiche | `https://plugin.capgo.app/stats` | | | **`privateKey`** | `string` | Configura la chiave privata per la crittografia end-to-end degli aggiornamenti live. Disponibile solo per Android e iOS. Deprecato nella versione 620, sarà rimosso nella versione 700 | `undefined` | | | **`publicKey`** | `string` | Configura la chiave pubblica per la crittografia end-to-end degli aggiornamenti live Versione 2. Disponibile solo per Android e iOS | `undefined` | 620 | | **`version`** | `string` | Configura la versione corrente dell’app. Verrà utilizzata per la prima richiesta di aggiornamento. Se non impostata, il plugin otterrà la versione dal codice nativo. Solo Android e iOS | `undefined` | 41748 | | **`directUpdate`** | `boolean` | Fa sì che il plugin installi direttamente l’aggiornamento quando l’app è stata appena aggiornata/installata. Solo per modalità autoUpdate. Disponibile solo per Android e iOS | `undefined` | 510 | | **`periodCheckDelay`** | `number` | Configura il periodo di ritardo per il controllo periodico degli aggiornamenti in secondi. Disponibile solo per Android e iOS. Non può essere inferiore a 600 secondi (10 minuti) | `600 // (10 minuti)` | | | **`localS3`** | `boolean` | Configura la CLI per utilizzare un server locale per test o server di aggiornamento self-hosted | `undefined` | 41748 | | **`localHost`** | `string` | Configura la CLI per utilizzare un server locale per test o server di aggiornamento self-hosted | `undefined` | 41748 | | **`localWebHost`** | `string` | Configura la CLI per utilizzare un server locale per test o server di aggiornamento self-hosted | `undefined` | 41748 | | **`localSupa`** | `string` | Configura la CLI per utilizzare un server locale per test o server di aggiornamento self-hosted | `undefined` | 41748 | | **`localSupaAnon`** | `string` | Configura la CLI per utilizzare un server locale per test | `undefined` | 41748 | | **`localApi`** | `string` | Configura la CLI per utilizzare un’API locale per test | `undefined` | 633 | | **`localApiFiles`** | `string` | Configura la CLI per utilizzare un’API di file locale per test | `undefined` | 633 | | **`allowModifyUrl`** | `boolean` | Permette al plugin di modificare dinamicamente updateUrl, statsUrl e channelUrl dal lato JavaScript | `false` | 540 | | **`defaultChannel`** | `string` | Imposta il canale predefinito per l’app nella configurazioneEcco la traduzione in italiano: | | | ```plaintext | undefined | 550 | ``` \| **`appId`** | `string` | Configura l’id dell’app per l’app nella configurazione | `undefined` | 600 | | **`keepUrlPathAfterReload`** | `boolean` | Configura il plugin per mantenere il percorso URL dopo un ricaricamento ATTENZIONE: Quando viene attivato un ricaricamento, la ‘windowhistory’ verrà cancellata | `false` | 680 | ## Esempi In `capacitorconfigjson`: ```json { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 // (1 secondo), "responseTimeout": 10 // (10 secondi), "autoDeleteFailed": false, "autoDeletePrevious": false, "autoUpdate": false, "resetWhenUpdate": false, "updateUrl": https://examplecom/api/auto_update, "channelUrl": https://examplecom/api/channel, "statsUrl": https://examplecom/api/stats, "privateKey": undefined, "publicKey": undefined, "version": undefined, "directUpdate": undefined, "periodCheckDelay": undefined, "localS3": undefined, "localHost": undefined, "localWebHost": undefined, "localSupa": undefined, "localSupaAnon": undefined, "localApi": undefined, "localApiFiles": undefined, "allowModifyUrl": undefined, "defaultChannel": undefined, "appId": undefined, "keepUrlPathAfterReload": undefined } } } ``` In `capacitorconfigts`: ```ts /// import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { appReadyTimeout: 1000 // (1 secondo), responseTimeout: 10 // (10 secondi), autoDeleteFailed: false, autoDeletePrevious: false, autoUpdate: false, resetWhenUpdate: false, updateUrl: https://examplecom/api/auto_update, channelUrl: https://examplecom/api/channel, statsUrl: https://examplecom/api/stats, privateKey: undefined, publicKey: undefined, version: undefined, directUpdate: undefined, periodCheckDelay: undefined, localS3: undefined, localHost: undefined, localWebHost: undefined, localSupa: undefined, localSupaAnon: undefined, localApi: undefined, localApiFiles: undefined, allowModifyUrl: undefined, defaultChannel: undefined, appId: undefined, keepUrlPathAfterReload: undefined, }, }, }; export default config; ``` * [`notifyAppReady()`](#notifyappready) * [`setUpdateUrl()`](#setupdateurl) * [`setStatsUrl()`](#setstatsurl) * [`setChannelUrl()`](#setchannelurl) * [`download()`](#download) * [`next()`](#next) * [`set()`](#set) * [`delete()`](#delete) * [`list()`](#list) * [`reset()`](#reset) * [`current()`](#current) * [`reload()`](#reload) * [`setMultiDelay()`](#setmultidelay) * [`cancelDelay()`](#canceldelay) * [`getLatest()`](#getlatest) * [`setChannel()`](#setchannel) * [`unsetChannel()`](#unsetchannel) * [`getChannel()`](#getchannel) * [`setCustomId()`](#setcustomid) * [`getBuiltinVersion()`](#getbuiltinversion) * [`getDeviceId()`](#getdeviceid) * [`getPluginVersion()`](#getpluginversion) * [`isAutoUpdateEnabled()`](#isautoupdateenabled) * [`removeAllListeners()`](#removealllisteners) * [`addListener('download', )`](#addlistenerdownload-) * [`addListener('noNeedUpdate', )`](#addlistenernoneedupdate-) * [`addListener('updateAvailable', )`](#addlistenerupdateavailable-) * [`addListener('downloadComplete', )`](#addlistenerdownloadcomplete-) * [`addListener('majorAvailable', )`](#addlistenermajoravailable-) * [`addListener('updateFailed', )`](#addlistenerupdatefailed-) * [`addListener('downloadFailed', )`](#addlistenerdownloadfailed-) * [`addListener('appReloaded', )`](#addlistenerappreloaded-) * [`addListener('appReady', )`](#addlistenerappready-) * [`isAutoUpdateAvailable()`](#isautoupdateavailable) * [`getNextBundle()`](#getnextbundle) * [Interfaces](#interfaces) * [Type Aliases](#type-aliases) # Metodi ## notifyAppReady() ```typescript notifyAppReady() => Promise ``` Notifica a Capacitor Updater che il bundle corrente sta funzionando (verrà eseguito un rollback se questo metodo non viene chiamato ad ogni avvio dell’app) Per impostazione predefinita questo metodo dovrebbe essere chiamato nei primi 10 secondi dopo l’avvio dell’app, altrimenti verrà eseguito un rollback Modifica questo comportamento con {@link appReadyTimeout} **Ritorna:** `Promise` *** ## setUpdateUrl() ```typescript setUpdateUrl(options: UpdateUrl) => Promise ``` Imposta l’updateUrl per l’app, questo sarà utilizzato per controllare gli aggiornamenti | Param | Type | Descrizione | | ------------- | ----------- | -------------------------------------------------------------- | | **`options`** | `UpdateUrl` | contiene l’URL da utilizzare per controllare gli aggiornamenti | **Dal:** 540 *** ## setStatsUrl() ```typescript setStatsUrl(options: StatsUrl) => Promise ``` Imposta la statsUrl per l’app, questa verrà utilizzata per inviare statistiche. L’inserimento di una stringa vuota disabiliterà la raccolta delle statistiche. | Param | Type | Descrizione | | ------------- | ---------- | ---------------------------------------------------- | | **`options`** | `StatsUrl` | contiene l’URL da utilizzare per inviare statistiche | **Dal:** 540 *** ## setChannelUrl() ```typescript setChannelUrl(options: ChannelUrl) => Promise ``` Imposta la channelUrl per l’app, questa verrà utilizzata per impostare il canale | Param | Type | Descrizione | | ------------- | ------------ | ---------------------------------------------------- | | **`options`** | `ChannelUrl` | contiene l’URL da utilizzare per impostare il canale | **Dal:** 540 *** ## download() ```typescript download(options: DownloadOptions) => Promise ``` Scarica un nuovo bundle dall’URL fornito, dovrebbe essere un file zip, con file al suo interno o con un ID unico al suo interno con tutti i tuoi file | Param | Type | Descrizione | | ------------- | ----------------- | -------------------------------------------------------------------------------- | | **`options`** | `DownloadOptions` | Le {@link [DownloadOptions](#downloadoptions)} per scaricare un nuovo bundle zip | **Ritorna:** `Promise` *** ## next() ```typescript next(options: BundleId) => Promise ``` Imposta il prossimo bundle da utilizzare quando l’app viene ricaricata| Param | Type | Description | | ------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | Contiene l’ID del prossimo Bundle da impostare al prossimo avvio dell’app {@link [BundleInfoid](#bundleinfo)} | **Returns:** `Promise` *** ## set() ```typescript set(options: BundleId) => Promise ``` Imposta il bundle corrente e riavvia immediatamente l’app | Param | Type | Description | | ------------- | ---------- | ------------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | Un oggetto {@link [BundleId](#bundleid)} contenente il nuovo bundle id da impostare come corrente | *** ## delete() ```typescript delete(options: BundleId) => Promise ``` Elimina il bundle specificato dalla memoria dell’app nativa. Usa con {@link list} per ottenere gli ID dei Bundle memorizzati | Param | Type | Description | | ------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | Un oggetto {@link [BundleId](#bundleid)} contenente l’ID di un bundle da eliminare (nota, questo è l’id del bundle, NON il nome della versione) | *** ## list() ```typescript list(options?: ListOptions | undefined) => Promise ``` Ottieni tutti i bundle scaricati localmente nella tua app | Param | Type | Description | | ------------- | ------------- | ------------------------------------------------------------ | | **`options`** | `ListOptions` | Le {@link [ListOptions](#listoptions)} per elencare i bundle | **Returns:** `Promise` *** ## reset() ```typescript reset(options?: ResetOptions | undefined) => Promise ``` Ripristina l’app al bundle ‘builtin’ (quello inviato all’Apple App Store / Google Play Store) o all’ultimo bundle caricato con successo | Param | Type | Description | | ------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **`options`** | `ResetOptions` | Contenente {@link [ResetOptionstoLastSuccessful](#resetoptions)}, `true` ripristina al bundle builtin e `false` ripristinerà all’ultimo bundle caricato con successo | *** ## current() ```typescript current() => Promise ``` Ottieni il bundle corrente, se nessuno è impostato restituisce `builtin` currentNative è il bundle originale installato sul dispositivo **Returns:** `Promise` *** ## reload() ```typescript reload() => Promise ``` Ricarica la vista *** ## setMultiDelay() ```typescript setMultiDelay(options: MultiDelayConditions) => Promise ``` Imposta un array {@link [DelayCondition](#delaycondition)} contenente le condizioni che il Plugin utilizzerà per ritardare l’aggiornamento Dopo che tutte le condizioni sono soddisfatte, il processo di aggiornamento ripartirà come al solito, quindi l’aggiornamento verrà installato dopo un background o l’uccisione dell’app Per il tipo ‘date’, il valore deve essere una stringa di data iso8601 Per il tipo ‘background’, il valore deve essere un numero in millisecondi Per il tipo ‘nativeVersion’, il valore deve essere il numero di versione Per il tipo ‘kill’, il valore non viene utilizzato La funzione ha un comportamento non coerente l’opzione kill fa scattare l’aggiornamento dopo il primo kill e non dopo il prossimo background come altre opzioni. Questo sarà corretto in una futura release maggiore | Param | Type | Description | | ------------- | ---------------------- | --------------------------------------------------------------------------------------------------- | | **`options`** | `MultiDelayConditions` | Contenente l’array {@link [MultiDelayConditions](#multidelayconditions)} di condizioni da impostare | **Since:** 430 *** ## cancelDelay() ```typescript cancelDelay() => Promise ``` Annulla un {@link [DelayCondition](#delaycondition)} per elaborare immediatamente un aggiornamento **Since:** 400 *** ## getLatest() ```typescript getLatest(options?: GetLatestOptions | undefined) => Promise ``` Ottieni l’ultimo bundle disponibile dall’URL di aggiornamento | Param | Type | | ------------- | ------------------ | | **`options`** | `GetLatestOptions` | **Returns:** `Promise` **Since:** 400 *** ## setChannel() ```typescript setChannel(options: SetChannelOptions) => Promise ``` Imposta il canale per questo dispositivo. Il canale deve consentire l’auto-assegnazione perché questo funzioni Non utilizzare questo metodo per impostare il canale all’avvio quando `autoUpdate` è abilitato nella {@link PluginsConfig} Questo metodo serve per impostare il canale dopo che l’app è pronta Questo metodo invia al backend di Capgo una richiesta per collegare l’ID del dispositivo al canale. Capgo può accettare o rifiutare a seconda delle impostazioni del tuo canale | Param | Type | Description | | ------------- | ------------------- | ------------------------------------------------------------------------ | | **`options`** | `SetChannelOptions` | È il canale {@link [SetChannelOptions](#setchanneloptions)} da impostare | **Returns:** `Promise` **Since:** 470 *** ## unsetChannel() ```typescript unsetChannel(options: UnsetChannelOptions) => Promise ``` Rimuove l’impostazione del canale per questo dispositivoIl dispositivo tornerà quindi al canale predefinito | Param | Tipo | | ------------- | --------------------- | | **`options`** | `UnsetChannelOptions` | **Da:** 470 *** ## getChannel() ```typescript getChannel() => Promise ``` Ottieni il canale per questo dispositivo **Ritorna:** `Promise` **Da:** 480 *** ## setCustomId() ```typescript setCustomId(options: SetCustomIdOptions) => Promise ``` Imposta un ID personalizzato per questo dispositivo | Param | Tipo | Descrizione | | ------------- | -------------------- | ---------------------------------------------------------------------------- | | **`options`** | `SetCustomIdOptions` | è il {@link [SetCustomIdOptions](#setcustomidoptions)} customId da impostare | **Da:** 490 *** ## getBuiltinVersion() ```typescript getBuiltinVersion() => Promise ``` Ottieni la versione nativa dell’app o la versione integrata se impostata nella configurazione **Ritorna:** `Promise` **Da:** 520 *** ## getDeviceId() ```typescript getDeviceId() => Promise ``` Ottieni ID univoco utilizzato per identificare il dispositivo (inviato al server di aggiornamento automatico) **Ritorna:** `Promise` *** ## getPluginVersion() ```typescript getPluginVersion() => Promise ``` Ottieni la versione nativa del plugin Capacitor Updater (inviata al server di aggiornamento automatico) **Ritorna:** `Promise` *** ## isAutoUpdateEnabled() ```typescript isAutoUpdateEnabled() => Promise ``` Ottieni lo stato della configurazione di aggiornamento automatico **Ritorna:** `Promise` *** ## removeAllListeners() ```typescript removeAllListeners() => Promise ``` Rimuovi tutti i listener per questo plugin **Da:** 100 *** ## addListener(‘download’, ) ```typescript addListener(eventName: 'download', listenerFunc: (state: DownloadEvent) => void) => Promise ``` Ascolta l’evento di download del bundle nell’App Si attiva quando inizia un download, durante il download e al termine | Param | Tipo | | ------------------ | -------------------------------- | | **`eventName`** | `’download’` | | **`listenerFunc`** | `(state: DownloadEvent) => void` | **Ritorna:** `Promise` **Da:** 2011 *** ## addListener(‘noNeedUpdate’, ) ```typescript addListener(eventName: 'noNeedUpdate', listenerFunc: (state: NoNeedEvent) => void) => Promise ``` Ascolta l’evento nessun aggiornamento necessario, utile quando vuoi forzare il controllo ogni volta che l’app viene avviata | Param | Tipo | | ------------------ | ------------------------------ | | **`eventName`** | `’noNeedUpdate’` | | **`listenerFunc`** | `(state: NoNeedEvent) => void` | **Ritorna:** `Promise` **Da:** 400 *** ## addListener(‘updateAvailable’, ) ```typescript addListener(eventName: 'updateAvailable', listenerFunc: (state: UpdateAvailableEvent) => void) => Promise ``` Ascolta l’evento aggiornamento disponibile, utile quando vuoi forzare il controllo ogni volta che l’app viene avviata | Param | Tipo | | ------------------ | --------------------------------------- | | **`eventName`** | `’updateAvailable’` | | **`listenerFunc`** | `(state: UpdateAvailableEvent) => void` | **Ritorna:** `Promise` **Da:** 400 *** ## addListener(‘downloadComplete’, ) ```typescript addListener(eventName: 'downloadComplete', listenerFunc: (state: DownloadCompleteEvent) => void) => Promise ``` Ascolta gli eventi downloadComplete | Param | Tipo | | ------------------ | ---------------------------------------- | | **`eventName`** | `’downloadComplete’` | | **`listenerFunc`** | `(state: DownloadCompleteEvent) => void` | **Ritorna:** `Promise` **Da:** 400 *** ## addListener(‘majorAvailable’, ) ```typescript addListener(eventName: 'majorAvailable', listenerFunc: (state: MajorAvailableEvent) => void) => Promise ``` Ascolta l’evento di aggiornamento Major nell’App, ti fa sapere quando l’aggiornamento major è bloccato dall’impostazione disableAutoUpdateBreaking | Param | Tipo | | ------------------ | -------------------------------------- | | **`eventName`** | `’majorAvailable’` | | **`listenerFunc`** | `(state: MajorAvailableEvent) => void` | **Ritorna:** `Promise` **Da:** 230 *** ## addListener(‘updateFailed’, ) ```typescript addListener(eventName: 'updateFailed', listenerFunc: (state: UpdateFailedEvent) => void) => Promise ``` Ascolta l’evento di fallimento dell’aggiornamento nell’App, ti fa sapere quando l’aggiornamento non è riuscito a installarsi al prossimo avvio dell’app | Param | Tipo | | ------------------ | ------------------------------------ | | **`eventName`** | `’updateFailed’` | | **`listenerFunc`** | `(state: UpdateFailedEvent) => void` | **Ritorna:** `Promise` **Da:** 230 *** ## addListener(‘downloadFailed’,) ```typescript addListener(eventName: 'downloadFailed', listenerFunc: (state: DownloadFailedEvent) => void) => Promise ``` Ascolta l’evento di fallimento del download nell’App, ti informa quando il download di un bundle è fallito | Param | Type | | ------------------ | -------------------------------------- | | **`eventName`** | `’downloadFailed’` | | **`listenerFunc`** | `(state: DownloadFailedEvent) => void` | **Returns:** `Promise` **Since:** 400 *** ## addListener(‘appReloaded’, ) ```typescript addListener(eventName: 'appReloaded', listenerFunc: () => void) => Promise ``` Ascolta l’evento di ricaricamento nell’App, ti informa quando è avvenuto il ricaricamento | Param | Type | | ------------------ | --------------- | | **`eventName`** | `’appReloaded’` | | **`listenerFunc`** | `() => void` | **Returns:** `Promise` **Since:** 430 *** ## addListener(‘appReady’, ) ```typescript addListener(eventName: 'appReady', listenerFunc: (state: AppReadyEvent) => void) => Promise ``` Ascolta l’evento di app pronta nell’App, ti informa quando l’app è pronta all’uso | Param | Type | | ------------------ | -------------------------------- | | **`eventName`** | `’appReady’` | | **`listenerFunc`** | `(state: AppReadyEvent) => void` | **Returns:** `Promise` **Since:** 510 *** ## isAutoUpdateAvailable() ```typescript isAutoUpdateAvailable() => Promise ``` Verifica se l’aggiornamento automatico è disponibile (non disabilitato da serverUrl) **Returns:** `Promise` *** ## getNextBundle() ```typescript getNextBundle() => Promise ``` Ottieni il prossimo bundle che verrà utilizzato quando l’app si ricaricherà Restituisce null se non è impostato alcun bundle successivo **Returns:** `Promise` **Since:** 680 *** ## Interfaces ### AppReadyResult | Prop | Type | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | ### BundleInfo | Prop | Type | | ---------------- | -------------- | | **`id`** | `string` | | **`version`** | `string` | | **`downloaded`** | `string` | | **`checksum`** | `string` | | **`status`** | `BundleStatus` | ### UpdateUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### StatsUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### ChannelUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### DownloadOptions | Prop | Type | Description | Default | Since | | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ----- | | **`url`** | `string` | L’URL del file zip del bundle (es: distzip) da scaricare (Può essere qualsiasi URL Es: Amazon S3, un tag GitHub, qualsiasi altro posto dove hai ospitato il tuo bundle) | | | | **`version`** | `string` | Il codice/nome versione di questo bundle/versione | | | | **`sessionKey`** | `string` | La chiave di sessione per l’aggiornamento | `undefined` | 400 | | **`checksum`** | `string` | Il checksum per l’aggiornamento | `undefined` | 400 | ### BundleId | Prop | Type | | -------- | -------- | | **`id`** | `string` | ### BundleListResult | Prop | Type | | ------------- | -------------- | | **`bundles`** | `BundleInfo[]` | ### ListOptions | Prop | Type | Description | Default | Since | | --------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------- | ----- | | **`raw`** | `boolean` | Se restituire la lista dei bundle grezza o il manifest Se true, la lista tenterà di leggere il database interno invece dei file su disco | `false` | 6140 | ### ResetOptions | Prop | Type | | ---------------------- | --------- | | **`toLastSuccessful`** | `boolean` | ### CurrentBundleResult | Prop | Type | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | | **`native`** | `string` | ### MultiDelayConditions | Prop | Type | | --------------------- | ------------------ | | **`delayConditions`** | `DelayCondition[]` | ### DelayCondition | Prop | Type | Description | | ----------- | ---------------- | ------------------------------------------------- | | **`kind`** | `DelayUntilNext` | Imposta le condizioni di ritardo in setMultiDelay | | **`value`** | `string` | | ### LatestVersion | Prop | Type | Description | Since | | ---------------- | ----------------- | ------------------------------ | ----- | | **`version`** | `string` | Risultato del metodo getLatest | 40 | | **`checksum`** | `string` | | 6 | | **`major`** | `boolean` | | | | **`message`** | `string` | | | | **`sessionKey`** | `string` | | | | **`error`** | `string` | | | | **`old`** | `string` | | | | **`url`** | `string` | | | | **`manifest`** | `ManifestEntry[]` | | 61 | ### ManifestEntry | Proprietà | Tipo | | ------------------ | ---------------- | | **`file_name`** | `string \| null` | | **`file_hash`** | `string \| null` | | **`download_url`** | `string \| null` | ### GetLatestOptions | Proprietà | Tipo | Descrizione | Predefinito | Da | | ------------- | -------- | ---------------------------------------------------------------------------------------------------- | ----------- | --- | | **`channel`** | `string` | Il canale per ottenere l’ultima versione. Il canale deve consentire ‘self\_assign’ affinché funzioni | `undefined` | 680 | ### ChannelRes | Proprietà | Tipo | Descrizione | Da | | ------------- | -------- | ---------------------------------- | --- | | **`status`** | `string` | Stato attuale del canale impostato | 470 | | **`error`** | `string` | | | | **`message`** | `string` | | | ### SetChannelOptions | Proprietà | Tipo | | ----------------------- | --------- | | **`channel`** | `string` | | **`triggerAutoUpdate`** | `boolean` | ### UnsetChannelOptions | Proprietà | Tipo | | ----------------------- | --------- | | **`triggerAutoUpdate`** | `boolean` | ### GetChannelRes | Proprietà | Tipo | Descrizione | Da | | -------------- | --------- | --------------------------------- | --- | | **`channel`** | `string` | Stato attuale del canale ottenuto | 480 | | **`error`** | `string` | | | | **`message`** | `string` | | | | **`status`** | `string` | | | | **`allowSet`** | `boolean` | | | ### SetCustomIdOptions | Proprietà | Tipo | | -------------- | -------- | | **`customId`** | `string` | ### BuiltinVersion | Proprietà | Tipo | | ------------- | -------- | | **`version`** | `string` | ### DeviceId | Proprietà | Tipo | | -------------- | -------- | | **`deviceId`** | `string` | ### PluginVersion | Proprietà | Tipo | | ------------- | -------- | | **`version`** | `string` | ### AutoUpdateEnabled | Proprietà | Tipo | | ------------- | --------- | | **`enabled`** | `boolean` | ### PluginListenerHandle | Proprietà | Tipo | | ------------ | --------------------- | | **`remove`** | `() => Promise` | ### DownloadEvent | Proprietà | Tipo | Descrizione | Da | | ------------- | ------------ | --------------------------------------- | --- | | **`percent`** | `number` | Stato attuale del download, tra 0 e 100 | 400 | | **`bundle`** | `BundleInfo` | | | ### NoNeedEvent | Proprietà | Tipo | Descrizione | Da | | ------------ | ------------ | --------------------------------------- | --- | | **`bundle`** | `BundleInfo` | Stato attuale del download, tra 0 e 100 | 400 | ### UpdateAvailableEvent | Proprietà | Tipo | Descrizione | Da | | ------------ | ------------ | --------------------------------------- | --- | | **`bundle`** | `BundleInfo` | Stato attuale del download, tra 0 e 100 | 400 | ### DownloadCompleteEvent | Proprietà | Tipo | Descrizione | Da | | ------------ | ------------ | -------------------------------------------------- | --- | | **`bundle`** | `BundleInfo` | Emesso quando è disponibile un nuovo aggiornamento | 400 | ### MajorAvailableEvent | Proprietà | Tipo | Descrizione | Da | | ------------- | -------- | ---------------------------------------------------- | --- | | **`version`** | `string` | Emesso quando è disponibile un nuovo bundle maggiore | 400 | ### UpdateFailedEvent | Proprietà | Tipo | Descrizione | Da | | ------------ | ------------ | ------------------------------------------------------- | --- | | **`bundle`** | `BundleInfo` | Emesso quando un aggiornamento non riesce a installarsi | 400 | ### DownloadFailedEvent | Proprietà | Tipo | Descrizione | Da | | ------------- | -------- | ---------------------------------- | --- | | **`version`** | `string` | Emesso quando un download fallisce | 400 | ### AppReadyEvent | Proprietà | Tipo | Descrizione | Da | | ------------ | ------------ | -------------------------------------- | --- | | **`bundle`** | `BundleInfo` | Emesso quando l’app è pronta per l’uso | 520 | | **`status`** | `string` | | | ### AutoUpdateAvailable | Proprietà | Tipo | | --------------- | --------- | | **`available`** | `boolean` | ## Type Aliases ### BundleStatus `‘success’ | ‘error’ | ‘pending’ | ‘downloading’` ### DelayUntilNext `‘background’ | ‘kill’ | ‘nativeVersion’ | ‘date’` # Aggiornamento automatico > Come utilizzare gli aggiornamenti automatici con capacitor-updater Questa modalità consente agli sviluppatori di utilizzare capacitor-updater in modalità di aggiornamento automatico e inviare aggiornamenti tramite i canali Capgo o equivalenti ### Prerequisiti Assicurati che la versione della tua app utilizzi prima di utilizzare l’aggiornamento automatico Capgo Questa è la convenzione che utilizza per gestire le versioni in Capgo Ci sono due modi per impostare la versione nella tua app: Nuovo modo: Usa il campo `version` nel tuo file `capacitorconfigjson` ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true, // Abilita l'aggiornamento automatico, true per default "appId": "comexampleapp", // Usato per identificare l'app nel server "version": "100" // Usato per controllare gli aggiornamenti } } } ``` Queste opzioni verranno utilizzate dal plugin per controllare gli aggiornamenti e dalla CLI per caricare la versione Vecchio modo: In 3 file nel tuo progetto: * `packagejson` in **version** * `android/app/buildgradle` in **versionName** * `ios/App/Appxcodeproj/projectpbxproj` in **CURRENT\_PROJECT\_VERSION** ### Tutorial Configura la tua app in 5 minuti [Aggiorna le tue app Capacitor senza problemi usando capacitor updater](https://capgo.app/blog/update-your-capacitor-apps-seamlessly-using-capacitor-updater) Configura il tuo CI in 5 minuti [Build e rilascio automatico con GitHub actions](https://capgo.app/blog/automatic-build-and-release-with-github-actions) ### Installazione ```bash npm install @capgo/capacitor-updater npx cap sync ``` ### Introduzione Clicca su [registrati](https://capgo.app) per creare il tuo account Il server ti permette di gestire canali, versioni e molto altro `autoUpdate` utilizzerà i dati da `capacitorconfig` per identificare il server Capgo Note Puoi ancora utilizzare Capgo Cloud senza inviare il tuo codice ai nostri server se ciò non è consentito dalla tua azienda #### Validare la versione Quando l’aggiornamento automatico è configurato, devi notificare da JS che la tua app è attiva e pronta Questo può essere fatto chiamando all’interno della tua app `notifyAppReady` Fallo il prima possibile ```ts import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdaternotifyAppReady() ``` #### Flusso utente * L’utente apre l’app, l’app chiama il server per controllare gli aggiornamenti, se ne vengono trovati verranno scaricati in background * L’utente chiude l’app, la nuova versione viene impostata come attiva * L’utente riapre l’app, carichiamo la nuova versione attiva e la impostiamo come predefinita * Se viene chiamato `notifyAppReady()`, quando l’utente chiude l’app, la versione precedente viene eliminata * L’utente continua il normale flusso dell’app fino al prossimo ciclo di aggiornamento Danger ⚠️ Non chiamare `notifyAppReady()` nella tua app farà sì che la versione corrente venga contrassegnata come non valida e tornerà al bundle precedente valido o di default #### Flusso di sviluppo Quando sviluppi nuove funzionalità, assicurati di bloccare `autoUpdate`, poiché capgo sovrascriverà costantemente il tuo lavoro con l’ultimo bundle di aggiornamento Imposta `autoUpdate` su false nella tua configurazione Se per qualche motivo sei bloccato su un aggiornamento, puoi eliminare l’app e reinstallarla Assicurati di impostare `autoUpdate` su false nella tua configurazione prima di farlo E poi ricompilala di nuovo con Xcode o Android studio Per caricare la versione ad ogni commit configura CI/CD con questa guida [Build e rilascio automatico con GitHub actions](https://capgo.app/blog/automatic-build-and-release-with-github-actions) #### Evento Major Available Quando `disableAutoUpdateBreaking` è impostato su true, puoi ascoltare l’evento per sapere quando l’app rifiuta di fare un aggiornamento major breaking ```jsx import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdateraddListener('majorAvailable', (info: any) => { consolelog('majorAvailable è stato attivato', infoversion) }) ``` # Sistem Channel > How to use capacitor-updater with the channel system Capgo e capacitor-updater sono dotati di un potente sistema di canali ## Cosa puoi fare con i canali: * Associare i dispositivi al canale per lo sviluppo, beta test * Utilizzare un canale per branch di sviluppo e lasciare che il team si auto-assegni dal telefono per testare ## Assegnare dispositivi a un canale: * Rendere il canale predefinito, ogni volta che un nuovo dispositivo chiede un aggiornamento a Capgo questo canale risponderà * Inviare il **deviceId** (con il metodo [**getDeviceId**](/docs/plugin/api#getdeviceid)) al tuo backend e assegnarlo con l’API pubblica di Capgo * Rendere il canale auto-assegnabile (con il metodo [**setChannel**](/docs/plugin/api#setchannel)), e lasciare che il dispositivo si iscriva al canale (con o senza interazione dell’utente) con il metodo `setChannel` del plugin * Utilizzare l’opzione `defaultChannel` nella [configurazione](/docs/plugin/settings#defaultchannel) per impostare il canale predefinito per tutti i dispositivi con questa configurazione del plugin Note Puoi anche assegnare un dispositivo direttamente a un bundle ## Opzioni del canale ![](/channel_setting_1.webp) Dettagli di ogni opzione: | Opzione | Descrizione | | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | | **Disabilita downgrade automatico sotto native** | Non invia un aggiornamento se la versione nativa dell’app è maggiore di quella del canale | | **Disabilita upgrade automatico sopra major** | Non invia un aggiornamento se la versione nativa dell’app è inferiore a una Major (**1**23) rispetto a quella del canale | | **Disabilita upgrade automatico sopra minor** | Non invia un aggiornamento se la versione nativa dell’app è inferiore a una minor (1**2**3) rispetto a quella del canale | | **Permetti al dispositivo di auto-assegnarsi** | Permette a un dispositivo di utilizzare il metodo `setChannel` per questo canale | | **IOS** | Permette ai dispositivi iOS di scaricare aggiornamenti da questo canale | | **Android** | Permette ai dispositivi Android di scaricare aggiornamenti da questo canale | | **Permetti Emulatore** | Permette agli emulatori di ricevere aggiornamenti da questo canale | | **Permetti build di sviluppo** | Permette alle build di sviluppo di ricevere aggiornamenti da questo canale | Note Capgo esegue alcuni filtraggi automatici per te. Se hai una CI/CD configurata per inviare la tua versione a Google Play, Google Play eseguirà la tua app ogni volta su più di 20 dispositivi reali. Durante le prime 4 ore di un nuovo bundle, bloccheremo gli IP del data center di Google per evitare che vengano conteggiati nelle tue statistiche Note Capgo **non** conta gli emulatori e le build di sviluppo nel tuo utilizzo, ma tieni presente che non puoi averne più del 3%, altrimenti il tuo account verrà bloccato finché non lo sistemi # 시작하기 > Installa il plugin nella tua app ## Introduzione a Capgo [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## Gli aggiornamenti in tempo reale sono a 3 passi ### Crea il tuo account Visita la nostra pagina di registrazione su ![onboarding screenshot](/onboard.webp "onboarding screenshot") ### Installa Capgo con la CLI Usa i comandi magici per iniziare ```bash npx @capgo/cli@latest init [APIKEY] ``` Questo comando ti guiderà attraverso il processo di configurazione ### Segui semplicemente le istruzioni Nella CLI, ti verranno presentate una serie di domande. Fornisci le risposte necessarie per completare la configurazione automatizzata Tip Seguendo questi passaggi, sarai operativo in pochissimo tempo. Se hai bisogno di ulteriore assistenza durante il processo, il nostro team di supporto è qui per aiutarti. Buon onboarding! ### Goditi la magia di Capgo! Testa la tua app e scopri in seguito come utilizzare le funzionalità avanzate di Capgo # Aggiornamento ibrido > Metodo di aggiornamento per gli aggiornamenti automatici Quando si inviano aggiornamenti agli utenti, ci sono diversi modi per gestire il ciclo di aggiornamento come meglio si crede prima di applicarli 1. Aggiornamento silenzioso 2. Ascolto dell’evento `updateAvailable` 3. Mostrare una finestra modale o ritardare gli aggiornamenti ## Aggiornamento silenzioso Puoi forzare un ciclo di aggiornamento ad ogni avvio dell’app impostando `directUpdate` su `true`, questo attiverà il ciclo di aggiornamento come al solito senza l’interazione dell’utente ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "directUpdate": true, }, "SplashScreen": { "launchAutoHide": false, } } } ``` E poi nella tua app, dovresti nascondere la schermata iniziale quando ricevi l’evento `appReady`: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' CapacitorUpdateraddListener('appReady', () => { // Hide splash SplashScreenhide() }) CapacitorUpdaternotifyAppReady() ``` ## Forza aggiornamento Aggiungi un listener all’evento `updateAvailable` e poi mostra un avviso per far sapere all’utente che l’app si aggiornerà: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { Dialog } from '@capacitor/dialog' CapacitorUpdateraddListener('updateAvailable', async (res) => { try { await Dialogalert({ title: 'Aggiornamento Disponibile', message: `La versione ${resbundleversion} è disponibile. L'app si aggiornerà ora`, }) CapacitorUpdaterset(resbundle) } catch (error) { consolelog(error) } }) CapacitorUpdaternotifyAppReady() ``` ## Aggiornamento modale Puoi anche lasciare decidere all’utente mostrando una finestra di dialogo per chiedere se vogliono aggiornare: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { Dialog } from '@capacitor/dialog' CapacitorUpdateraddListener('updateAvailable', async (res) => { try { const { value } = await Dialogconfirm({ title: 'Aggiornamento Disponibile', message: `La versione ${resbundleversion} è disponibile. Vuoi aggiornare ora?`, }) if (value) CapacitorUpdaterset(resbundle) } catch (error) { consolelog(error) } }) CapacitorUpdaternotifyAppReady() ``` # Aggiornamento Manuale > Come gestire gli aggiornamenti delle app Se desideri gestire autonomamente quando viene applicato l’aggiornamento, utilizza la modalità manuale con Capgo cloud Ecco cosa devi fare, configura il tuo account come spiegato in Iniziare [Iniziare ](/docs/getting-started/quickstart/) #### Configurazione Disabilita l’auto-aggiornamento nel tuo `capacitor.config.json` ```tsx // capacitor.config.json { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` Quindi aggiungi la logica per gestire gli aggiornamenti autonomamente\ Ecco un esempio di come puoi farlo: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater' import type { BundleInfo } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' CapacitorUpdater.notifyAppReady() let data: BundleInfo | null = null App.addListener('appStateChange', async (state: any) => { console.log('appStateChange', state) if (state.isActive) { console.log('getLatest') // Esegui il download durante il tempo di attività dell'app per prevenire download falliti const latest = await CapacitorUpdater.getLatest() console.log('latest', latest) if (latest.url) { data = await CapacitorUpdater.download(latest) console.log('download', data) } } if (!state.isActive && data) { console.log('set') // Esegui lo switch quando l'utente esce dall'app o quando vuoi SplashScreen.show() try { await CapacitorUpdater.set({ id: data.id }) } catch (err) { console.log(err) SplashScreen.hide() // in caso il set fallisca, altrimenti la nuova app dovrà nasconderlo } } }) ``` Documentazione di tutte le API disponibili nel plugin: [Metodi ](/docs/plugin/api/) Ci sono alcuni casi d’uso in cui puoi permettere agli utenti di iscriversi ai canali e provare diverse versioni:\ # Cordova > capacitor-updater sarà disponibile su Cordova? Ti starai chiedendo se questo plugin sarà mai disponibile per Cordova Ho iniziato un repository di R\&S per questo, ma è una quantità enorme di lavoro ## Problemi So che posso farlo ma per questo devo leggere tutto il codice del codebase di Cordova come ho fatto per Capacitor, per capire come farlo funzionare La versione Android è più facile da realizzare poiché entrambi utilizzano Java, ma iOS necessita di una riscrittura completa perché Swift non è ancora ben supportato in Cordova ## Soluzione Nel frattempo ecco cosa puoi fare: * [Supportami](https://github.com/sponsors/riderx) su GitHub e posso dare priorità a questo. Servirà almeno 1 mese di lavoro * Assumermi come Consulente, ero solito aiutare grandi aziende a migrare a Capacitor, di solito richiede \~10-20 giorni, e il [beneficio](https://ionicio/resources/articles/capacitor-vs-cordova-modern-hybrid-app-development) è enorme per il team # Debugging > Come debuggare la tua app ## Comprendere i log del cloud: ### Inviati dal backend | codice | Descrizione | | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **InvalidIp** | L’utente si trova in un data center Google e l’aggiornamento ha meno di 4 ore. Questo serve a impedire che i dispositivi dei bot di Google vengano contati come dispositivi nel tuo account | | **needPlanUpgrade** (precedentemente **needUpgrade**) | Indica che hai raggiunto il limite del tuo piano e il dispositivo non riceverà aggiornamenti fino a quando non effettuerai l’upgrade o fino al mese successivo | | **noNew** | Il dispositivo ha la versione più recente disponibile | | **disablePlatformIos** | Il dispositivo è sulla piattaforma iOS, ma è disabilitata nelle impostazioni del canale | | **disablePlatformAndroid** | Il dispositivo è sulla piattaforma Android, ma è disabilitata nelle impostazioni del canale | | **disableAutoUpdate** | ”major" | | **disableAutoUpdateUnderNative** | Il dispositivo ha la versione (`123`), e il canale ha un aggiornamento (`122`) sotto la versione del dispositivo da inviare, ma è disabilitato nelle impostazioni del canale | | **disableDevBuild** | Il dispositivo ha una build di sviluppo, ma è disabilitata nelle impostazioni del canale | | **disableEmulator** | Il dispositivo è un emulatore, ma è disabilitato nelle impostazioni del canale | ### Inviati dal dispositivo | codice | Descrizione | | ------------------------- | ---------------------------------------------------------------------------------- | | **get** | Le informazioni per scaricare la nuova versione sono state inviate al dispositivo | | **delete** | Un bundle è stato eliminato sul dispositivo | | **set** | Un bundle è stato impostato sul dispositivo | | **set\_fail** | Il bundle non è riuscito a impostarsi | | **reset** | Il dispositivo è stato resettato al bundle `builtin` | | **download\_XX** | È stato scaricato un nuovo bundle - progresso indicato da XX% (incrementi del 10%) | | **download\_complete** | Il nuovo bundle ha terminato il download | | **download\_fail** | Il nuovo bundle non è riuscito a scaricarsi | | **update\_fail** | Il nuovo bundle è stato installato ma non è riuscito a chiamare `notifyAppReady` | | **checksum\_fail** | Il nuovo bundle non è riuscito a validare il checksum | | **windows\_path\_fail** | Lo zip contiene file con percorsi Windows non validi | | **canonical\_path\_fail** | Il percorso dei file non è canonico | | **directory\_path\_fail** | C’è un errore nel percorso dei file zip | | **unzip\_fail** | Decompressione fallita | | **low\_mem\_fail** | Download fallito per memoria insufficiente nel dispositivo | ### Stato del bundle * `SUCCESS`: installazione bundle completata * `ERROR`: installazione o download fallito * `PENDING`: Download completato, in attesa di rilascio * `DELETED`: Bundle eliminato, ancora presente per le statistiche * `DOWNLOADING`: Attualmente in download di un bundle ## Comprendere i log del dispositivo: ### Comando debug: Esiste un comando debug per gli utenti di Capgo cloud ```bash npx @capgo/cli@latest app debug ``` Questo ti permetterà di controllare tutti gli eventi che accadono nell’app e trovare una soluzione se gli aggiornamenti non avvengono ### IOS per trovare i tuoi log su Xcode [Getting the Device Log in Xcode ](https://intercomhelp/deploygate/en/articles/4682692-getting-the-device-log-in-xcode) ### Android: per trovare i tuoi log su Android studio [View logs with Logcat ](https://developerandroidcom/studio/debug/am-logcat) ### Spiegazioni Log * `Failed to download from` **=>** uguale a **download\_fail** * `notifyAppReady was not called, roll back current bundle` => uguale a **update\_fail** ## Trovare il bundle scaricato nel tuo dispositivo ### iOS Per fare debug su iOS, devi esportare l’app sul tuo computer, puoi farlo così: Xcode ha una funzionalità integrata per ispezionare il file system delle app installate per sviluppatori su un dispositivo iOS Per farlo: * Collega il tuo dispositivo al Mac e seleziona Window > Devices nella barra dei menu di Xcode * Seleziona il tuo dispositivo nel pannello sinistro sotto la sezione Devices * Questo mostrerà una lista delle app installate per sviluppatori per quel dispositivo * Seleziona l’app che vuoi ispezionare e poi seleziona l’icona dell’ingranaggio vicino al fondo dello schermo * Qui puoi visualizzare il file system corrente selezionando Show Container o scaricare uno snapshot Selezionando Download Container scaricherà ed esporterà uno snapshot del file system come file xcappdata che puoi sfogliare Fai clic destro su questo file e seleziona Show Package Contents per aprire la cartella Apri la cartella App Data, e dovresti vedere alcune cartelle come Documents, Library, tmp, ecc ![image](/ios_debug_update_1.webp) Poi troverai una versione in 2 cartelle: `library/NoCloud/ionic_built_snapshots` è necessario dopo il riavvio dell’app e `documents/versions` per l’hot reload ### Android Per fare debug su Android, devi accedere al dispositivo da Android Studio: * Clicca View > Tool Windows > Device File Explorer o clicca il pulsante Device File Explorer nella barra degli strumenti per aprire Device File Explorer * Seleziona un dispositivo dal menu a tendina * Apri il percorso **data/data/APP\_NAME/** dove **APP\_NAME è l’ID della tua app** ![image](/android_debug_update.webp) Poi trova la cartella `versions` per vedere tutte le versioni Lo sapevi? Su Android, tutte le versioni sono memorizzate in una cartella, a differenza di iOS dove devono essere duplicate in due posizioni ## Comprendere i log dei crash in produzione su iOS [How to review your app's crash logs ](https://developer.apple.com/news/?id=nra79npr) # Nuxt 2 > Come installare il plugin in Nuxt 2 # Installazione in Nuxt 2 Crea un file plugin `capacitor-updaterjs` nella directory `plugins` ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' export default ({ app }) => { if (processclient) { windowonNuxtReady(() => { CapacitorUpdaternotifyAppReady() }) } } ``` Questo caricherà il plugin sul lato client e notificherà all’app che è pronta a ricevere aggiornamenti # Problemi noti > Problemi noti con Capacitor e CapGo ## Ricarica live di Ionic * Quando sviluppi, se utilizzi la funzione di ricarica live di Ionic dalla CLI, sovrascriverà il plugin, quindi non vedrai mai i tuoi aggiornamenti ## Ricarica live di Quasar * Utilizza lo stesso sistema di Ionic sotto il cofano, quindi non vedrai i tuoi aggiornamenti ## Errori negli aggiornamenti * Questo di solito accade quando vengono inviati aggiornamenti di grandi dimensioni (> 20mb), una grande percentuale di utenti non riceverà l’ultima versione In passato, gli utenti dovevano mantenere l’app aperta fino al completamento del download, ora utilizziamo il download in background, ma è ancora limitato a pochi secondi ## Android ### Impossibile scaricare Abbiamo riscontrato alcuni problemi con dispositivi in India, e parlando con gli utenti, facendogli provare diversi server DNS, ha funzionato Quindi se hai il problema, prova a utilizzare un server DNS diverso come Cloudflare o Google DNS Cloudflare: 1111 e 1001 Google DNS: 8888 e 8844 o dnsgoogle [Come configurare un server DNS preferito su Android? ](https://wwwandroidpolicecom/use-preferred-dns-server-android-tutorial/) ### Self Hosted Quando stai distribuendo un aggiornamento self-hosted, tieni presente che non puoi utilizzare endpoint “HTTP” poiché è contro le politiche di sicurezza delle app Android, se vuoi comunque farlo, segui questa guida: [Come consentire tutti i tipi di connessione di rete HTTP e HTTPS in Android (9) Pie? ](https://stackoverflow.com/a/51902630/5511370) ### Unzip Problema di unzip: le voci DEFLATED possono avere un descrittore EXT Se hai compresso il tuo bundle con qualcosa di diverso dalla CLI, il formato del tuo zip potrebbe essere errato, utilizza il comando CLI `npx @capgo/cli zip BUNDLE_FOLDER` Questo è un problema noto di Java: [Problema di unzip: le voci DEFLATED possono avere un descrittore EXT ](https://bugsopenjdkorg/browse/JDK-8143613) ### Problema Clearfix * Se hai problemi con usesCleartextTraffic, è perché il plugin segue le buone pratiche raccomandate da sonar cloud, nel 90% dei casi funzionerà bene, ma con alcuni plugin causa problemi Per risolverlo, aggiungi in `android/app/src/main/AndroidManifestxml` nella chiave ``: ```xml tools:replace="android:usesCleartextTraffic" xmlns:tools="http://schemasandroidcom/tools" ``` ## iOS ### Manifesto della Privacy Aggiungi la chiave dizionario `NSPrivacyAccessedAPICategoryUserDefaults` al tuo [Privacy Manifest](https://capacitorjs.com/docs/ios/privacy-manifest) (solitamente `ios/App/PrivacyInfoxcprivacy`): ```xml NSPrivacyAccessedAPITypes NSPrivacyAccessedAPIType NSPrivacyAccessedAPICategoryUserDefaults NSPrivacyAccessedAPITypeReasons CA921 ``` Raccomandiamo di dichiarare [`CA921`](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278401) come motivo per accedere all’API [`UserDefaults`](https://developer.apple.com/documentation/foundation/userdefaults) ### Permessi di rete Quando si utilizza un server locale per testare gli aggiornamenti, l’app chiederà i permessi di rete, è un comportamento normale, non accade quando si usa un server remoto ## Entrambi i SO Quando si eseguono aggiornamenti in modalità manuale, alcuni eventi non sono facili da catturare, ad esempio il fallimento dell’aggiornamento si attiva poco prima che il tuo codice JS si ricarichi, quindi non sarai in grado di catturarlo Un’alternativa è elencare i bundle e controllare le statistiche degli errori per sapere se l’aggiornamento fallisce Dobbiamo trovare un modo migliore per gestire questo in futuro, ma non è una priorità, poiché la modalità auto è il modo consigliato per fare gli aggiornamenti I PR sono benvenuti per aiutarci a migliorare questo aspetto ## CLI se la tua CLI ha problemi a fare qualsiasi cosa, Controlla se **appId** e **appName** sono presenti nel tuo **capacitorconfigts** Segui la guida della documentazione ufficiale: [Configurazione Capacitor ](https://capacitorjs.com/docs/config) # Vue d'ensemble > Spiegazione dei due diversi approcci ### Modalità Cloud (Consigliata) La Modalità Cloud è la nostra scelta consigliata per una gestione degli aggiornamenti senza problemi. Il backend di Capgo si occupa di tutta la logica degli aggiornamenti, prendendo decisioni lato server per una migliore sicurezza e controllo. Questa modalità è incentrata sulla facilità d’uso: una volta configurata, funziona autonomamente, offrendo funzionalità avanzate come statistiche e canali. Può essere anche configurata in modalità manuale per darti maggior controllo, permettendoti di decidere quando aggiornare usando il tuo codice JavaScript. Il backend continua a gestire cosa viene aggiornato. Questa modalità condivide molti benefici con la Modalità Auto, specialmente nella sicurezza e nelle funzionalità avanzate, ma aggiunge la flessibilità di temporizzare gli aggiornamenti autonomamente. ### Modalità Self Hosted La Modalità Self-Hosted Auto è per chi vuole gestire tutta la logica degli aggiornamenti sul proprio server. Offre completa autonomia ma richiede un server separato e più lavoro per gestire gli aggiornamenti e i requisiti del server. La Modalità Self-Hosted Manual combina controllo e autonomia. Decidi quando aggiornare tramite JavaScript, ma il tuo server gestisce cosa viene aggiornato. È un po’ complessa poiché stai includendo codice di aggiornamento negli aggiornamenti stessi. Note Se scegli il self hosting perderai tutte le ottime funzionalità che capgo cloud ha da offrire come: ripristini automatici, avvisi email, canali, statistiche, crittografia e altro Danger Se invii un aggiornamento errato ai tuoi utenti puoi e romperai la loro app # Auto Aggiornamento > Come utilizzare il plugin di aggiornamento automatico in modalità self-hosted Questa documentazione spiegherà come eseguire il tuo server di aggiornamento automatico ## Servire il bundle Assicurati che il tuo bundle sia servito tramite HTTPS e che il server abbia gli header CORS corretti per consentire all’app di scaricare l’aggiornamento es. `https://myserver.com/app/updates/updates.json` Se non hai familiarità con il serving di un bundle, ti consigliamo di provare Capgo Cloud o vedere un esempio qui: [Serving a Bundle ](/docs/self-hosted/auto-update/update-endpoint) ## Configurazione Aggiungi un `updateUrl` al tuo `capacitor.config.json` ```json { "plugins": { "CapacitorUpdater": { "updateUrl": "https://myserver.com/app/updates/updates.json", } } } ``` Caution Quando stai pubblicando un aggiornamento self-hosted, tieni presente che non puoi utilizzare endpoint “HTTP” poiché è contro le politiche di sicurezza delle app Android, per scopi di test puoi [consentirlo](https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted) ## API di aggiornamento Il plugin effettuerà una chiamata POST alla tua API ogni volta che l’app viene aperta, con questo corpo: ```typescript interface AppInfos { "platform": "ios" | "android", "device_id": "UUID_of_device_unique_by_install", "app_id": "APPID_FROM_CAPACITOR_CONFIG", "custom_id": "your_custom_id_set_on_runtime", "plugin_version": "PLUGIN_VERSION", "version_build": "VERSION_NUMBER_FROM_NATIVE_CODE", "version_code": "VERSION_CODE_FROM_NATIVE_CODE", "version_name": "LAST_DOWNLOADER_VERSION" | "builtin" "version_os": "VERSION_OF_SYSYEM_OS", "is_emulator": boolean, "is_prod": boolean, } ``` L’API del server dovrebbe rispondere, in JSON, al plugin capacitor-updater con questi dati se è necessario un aggiornamento: ```json { "version": "123", "url": "https://myserver.com/app/updates/my-new-app-200.zip" } ``` In modalità Auto-update il server dovrebbe confrontare le versioni e restituire quella corretta, se la chiave URL è presente, il plugin avvia il processo di download Se aggiungi le chiavi “message” ed “error”, la versione non verrà impostata e il messaggio verrà invece visualizzato nei log La chiave `version` dovrebbe essere nel formato [`semver`](https://semver.org/) Lo zip dovrebbe avere `index.html` come file nella root, o una sola cartella nella root con `index.html` all’interno Puoi utilizzare il comando della CLI per comprimere il tuo bundle: Crea un bundle con i tuoi file da servire dal tuo server ```bash npx @capgo/cli bundle zip --path [/path/to/my/bundle] ``` # 기여하기 > Contribuire ai progetti open source di capgo ## Perché contribuire? Prima di tutto, grazie per aver considerato di contribuire ai progetti open source di capgo! Sono persone come te che rendono i progetti open source di capgo strumenti così eccezionali. Ecco alcuni motivi per cui potresti voler contribuire: * Contribuire ai progetti open source di capgo è un ottimo modo per guadagnare denaro dai [numerosi bounty](https://consolealgoraio/org/Capgo) offerti dal team capgo * Contribuire ai progetti open source di capgo è un ottimo modo per aggiungere una funzionalità che vorresti vedere * Contribuire ai progetti open source di capgo è un ottimo modo per correggere un bug che hai incontrato * La [licenza principale di Capgo](https://github.com/Cap-go/capgo/blob/main/LICENSE) richiede di rendere open source qualsiasi modifica tu faccia. Contribuendo con il tuo codice, puoi mantenere le tue modifiche open source e permettere ad altri di utilizzarle ## Come contribuire 1. Prima di tutto, devi fare il fork del repository a cui vuoi contribuire 2. In secondo luogo devi committare e pushare le tue modifiche su quel repository 3. Infine, devi aprire una pull request 4. È tutto! Ora devi solo attendere che il team capgo riveda la tua PR ## Ulteriori documenti da leggere * [CONTRIBUTING.MD](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTINGmd) di Capgo * [BOUNTY.md](https://github.com/Cap-go/capgo/blob/main/BOUNTYmd) di Capgo # Bundle crittografati > Come utilizzare il plugin di aggiornamento manuale in modalità self-hosted ## Crittografia end-to-end A partire dalla versione 4150, il plugin consente di inviare aggiornamenti crittografati. Per iniziare, crea una chiave privata Create a private key ```bash npx @capgo/cli key create ``` Quindi cripta il tuo zip Encrypt bundled zip ```bash npx @capgo/cli encrypt [path/to/zip] ``` Il comando ti mostrerà un `ivSessionKey` che deve essere inviato con il payload del tuo aggiornamento nella chiave `session_key` ```json { "version": "123", "url": "https://myservercom/app/updates/my-new-app-200zip", "session_key": "encrypted_session_key", } ``` Quindi la tua app sarà in grado di utilizzare la chiave privata per decrittare la `session_key` e utilizzare la `session_key` decrittata per decrittare l’aggiornamento Scopri di più qui: [Self-hosted Live Updates ](https://capgo.app/blog/self-hosted-live-updates/) # Iniziamo > Come eseguire il proprio server di aggiornamento automatico Questa documentazione spiegherà come eseguire il tuo server di aggiornamento automatico ## Introduzione Se trovi utile questo lavoro, considera di supportare il mio lavoro diventando uno [sponsor Github](https://github.com/sponsors/riderx) Ho scommesso di rendere open source tutto il codice che ho costruito qui invece di metterlo dietro un paywall. Aprendo invece di combattere e nascondere, credo che possiamo rendere il mondo un posto migliore Inoltre, voglio concentrarmi sugli strumenti di Capgo e renderlo un business aperto e trasparente Ma per renderlo possibile, è necessario che tutti noi facciamo la nostra parte, incluso te 🥹 Se Capgo non fa per te, allora paga il tuo prezzo e [sostieni un Maker indipendente](https://github.com/sponsors/riderx) alle tue condizioni [Considera di Contribuire ](/docs/plugin/self-hosted/contributing/) ## Parità delle funzionalità Se scegli di utilizzare il tuo server, perderai il flusso di configurazione in 5 minuti\ Dovrai implementare tutte queste funzionalità da solo | Funzionalità | Capgo | Self hosted | | ---------------------------- | ----- | ----------- | | Aggiornamenti | ✅ | 🚧 | | Auto ripristino | ✅ | 🚧 | | Avvisi email sui fallimenti | ✅ | 🚧 | | Canali | ✅ | 🚧 | | Override dei Canali | ✅ | 🚧 | | Override dei Dispositivi | ✅ | 🚧 | | Impostazioni Canali | ✅ | 🚧 | | Impostazioni Dispositivi | ✅ | 🚧 | | ID Personalizzati | ✅ | 🚧 | | Auto Set Canali | ✅ | 🚧 | | API Canali | ✅ | 🚧 | | Statistiche Aggiornamenti | ✅ | 🚧 | | Statistiche Download Falliti | ✅ | 🚧 | | Statistiche Uso App | ✅ | 🚧 | | Crittografia Aggiornamenti | ✅ | 🚧 | Danger Se invii un aggiornamento errato ai tuoi utenti puoi e romperai la loro app > Tieni presente che non puoi utilizzare il cloud Capgo e il tuo server contemporaneamente Danger La funzione di aggiornamento Over-the-Air (OTA) è applicabile solo per modifiche apportate ai file HTML, CSS e JavaScript Se apporti modifiche al codice nativo, come aggiornamenti ai plugin Capacitor, è obbligatorio inviare nuovamente l’applicazione all’app store per l’approvazione ## Scegli tra Auto e Manuale In modalità auto, parte della logica è gestita dal codice nativo, gli aggiornamenti sono decisi lato server, questo è più sicuro e permette aggiornamenti granulari, distribuzioni parziali a un dispositivo o gruppo e altro In modalità manuale, tutta la logica è gestita da JS [Aggiornamento Automatico ](/docs/plugin/self-hosted/auto-update/) [Manuale ](/docs/plugin/self-hosted/manual-update/) ## Installa Capacitor updater Installa il Capacitor updater ```bash npm install @capgo/capacitor-updater npx cap sync ``` ## Prepara il tuo bundle Per inviare aggiornamenti alla tua app, devi comprimerla in zip Il modo migliore per essere certi che il tuo zip sia buono è utilizzare la CLI Capgo per la compressione Crea un bundle con i tuoi file da servire dal tuo server ```bash npx @capgo/cli@latest bundle zip ``` Dovrai servire questo zip dal tuo server in autonomia [Aggiornamento Automatico ](/docs/plugin/self-hosted/auto-update/) [Manuale ](/docs/plugin/self-hosted/manual-update/) Note Se questo sembra troppo lavoro, prova il trial di Capgo Cloud # Umgang mit Statistiken > Creare un endpoint di statistiche self-hosted Ecco un esempio di codice in JavaScript per salvare le statistiche del plugin ```typescript interface AppInfos { version_name: string action: 'delete' | 'reset' | 'set' | 'set_fail' | 'update_fail' | 'windows_path_fail' | 'canonical_path_fail' | 'directory_path_fail' | 'unzip_fail' | 'low_mem_fail' | 'download_fail' | 'update_fail' | 'download_10' | 'download_20' | 'download_30' | 'download_40' | 'download_50' | 'download_60' | 'download_70' | 'download_80' | 'download_90' | 'download_complete' version_build: string version_code: string version_os: string plugin_version: string platform: string app_id: string device_id: string custom_id?: string is_prod?: boolean is_emulator?: boolean } export const handler: Handler = async (event) => { const body = JSONparse(eventbody || '{}') as AppInfos const { platform, app_id, action, version_code, version_os, device_id, version_name, version_build, plugin_version, } = body consolelog('update asked', platform, app_id, action, version_os, version_code, device_id, version_name, version_build, plugin_version) // Salvalo nel tuo database return { status: 'ok' } } ``` Questo endpoint dovrebbe restituire un JSON: ```json { "status": "ok" } ``` ## Azioni: * **delete**: quando un bundle viene eliminato localmente * **reset**: quando l’app ripristina il bundle integrato * **set**: quando l’app imposta un nuovo bundle * **set\_fail**: quando l’app non riesce a trovare l’ID del bundle impostato * **update\_fail**: inviato dopo il ritardo e `notifyAppReady` non è mai stato chiamato * **download\_fail**: quando il download non è mai stato completato * **download\_complete:** Quando il download è completato * **download\_xx:** Inviato ogni 10% di download es: download\_20, download\_70 * **update\_fail:** quando il bundle non riesce a eseguire `notifyAppReady` nel periodo di tempo stabilito # Gestione degli aggiornamenti > Come utilizzare il plugin di aggiornamento automatico in modalità self-hosted Ecco un esempio di codice in JavaScript per inviare un aggiornamento al plugin ```typescript interface AppInfos { version_name: string version_build: string version_os: string custom_id?: string is_prod?: boolean is_emulator?: boolean plugin_version: string platform: string app_id: string device_id: string } export const handler: Handler = async (event) => { const body = JSONparse(eventbody || '{}') as AppInfos const { platform, app_id, version_os, device_id, version_name, version_build, plugin_version, } = body consolelog('update asked', platform, app_id, version_os, device_id, version_name, version_build, plugin_version) if (version_name === '100') { return { version: '101', url: 'https://apiurlcom/mybuild_101zip', } } else if (version_name === '101') { return { version: '102', url: 'https://apiurlcom/mybuild_102zip', } } else { return { message: 'Error version not found' version: '', url: '', } } } ``` Questo endpoint dovrebbe restituire un JSON: ```json { "version": "102", "url": "https://apiurlcom/mybuild_102zip" } ``` E se non ci sono aggiornamenti o si verifica un errore, aggiungere la chiave `message` e opzionalmente un `error` ```json { "message": "Version not found", "error": "The backend crashed", "version": "102", "url": "https://apiurlcom/mybuild_102zip" } ``` # Aggiornamento Manuale > Come utilizzare il plugin di aggiornamento manuale in modalità self-hosted ## Configurazione Aggiungi questo al tuo `capacitorconfigjson`, per disabilitare l’aggiornamento automatico ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false, } } } ``` ## Utilizzo Puoi utilizzare questo esempio o ricreare la logica nella tua app Caution Stiamo forzando l’utente ad aggiornare l’app con una versione statica dichiarata nel codice. Questo non è raccomandato, dovresti utilizzare una versione dinamica dal tuo server Danger In questo esempio non stiamo eseguendo alcun controllo della versione, decrittografia o validazione del checksum. Dovresti farlo per conto tuo ```tsx import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' let data = {version: ""} CapacitorUpdater.notifyAppReady() App.addListener('appStateChange', async(state) => { if (state.isActive) { // Esegui il download durante il tempo di attività dell'app dell'utente per evitare download falliti data = await CapacitorUpdater.download({ version: '004', url: 'https://github.com/Cap-go/demo-app/releases/download/004/dist.zip', }) } if (!state.isActive && data.version !== "") { // Esegui lo switch quando l'utente lascia l'app SplashScreen.show() try { await CapacitorUpdater.set(data) } catch (err) { console.log(err) SplashScreen.hide() // in caso il set fallisca, altrimenti la nuova app dovrà nasconderlo } } }) ``` Note Se questo sembra troppo lavoro, considera di provare [Capgo trial](https://capgo.app/register/). Gestirà tutto questo per te # 設定 > Tutte le configurazioni disponibili per Capacitor Updater Per avere un controllo più preciso sul sistema di aggiornamento, puoi configurarlo con queste impostazioni: ## `appReadyTimeout` > Configura il numero di millisecondi che il plugin nativo deve attendere prima di considerare un aggiornamento ‘fallito’ Disponibile solo per Android e iOS Predefinito: `10000` (10 secondi) ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 } } } ``` ## `responseTimeout` > Configura il numero di millisecondi che il plugin nativo deve attendere prima di considerare il timeout dell’API Disponibile solo per Android e iOS Predefinito: `20` (20 secondi) ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "responseTimeout": 1000 } } } ``` ## `autoDeleteFailed` > Configura se il plugin deve eliminare automaticamente i bundle falliti Disponibile solo per Android e iOS Predefinito: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoDeleteFailed": false } } } ``` ## `autoDeletePrevious` > Configura se il plugin deve eliminare automaticamente i bundle precedenti dopo un aggiornamento riuscito Disponibile solo per Android e iOS Predefinito: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoDeletePrevious": false } } } ``` ## `autoUpdate` > Configura se il plugin deve utilizzare l’aggiornamento automatico tramite un server di aggiornamento Disponibile solo per Android e iOS Predefinito: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` ## `updateUrl` > Configura l’URL / endpoint a cui vengono inviati i controlli di aggiornamento Disponibile solo per Android e iOS Predefinito: `https://apicapgo.app/updates` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "updateUrl": "https://examplecom/api/updates" } } } ``` ## `statsUrl` > Configura l’URL / endpoint a cui vengono inviate le statistiche di aggiornamento Disponibile solo per Android e iOS. Impostare a "" per disabilitare il reporting delle statistiche Predefinito: `https://apicapgo.app/stats` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "statsUrl": "https://examplecom/api/stats" } } } ``` ## `privateKey` > Configura la chiave privata per la crittografia end-to-end degli aggiornamenti live Disponibile solo per Android e iOS Crea la chiave privata con il comando `npx @capgo/cli key create` Predefinito: `undefined` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "privateKey": "YOUR_KEY" } } } ``` ## `directUpdate` > Fa sì che il plugin installi direttamente l’aggiornamento quando l’app è stata appena aggiornata/installata. Applicabile solo per la modalità autoUpdate Disponibile solo per Android e iOS Predefinito: `undefined` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": true } } } ``` ## `resetWhenUpdate` Note Quando avviene un aggiornamento del negozio, disabilita il reset forzato alla versione nativa Ci sono molte altre impostazioni disponibili solo sulla [web app](https://web.capgo.app/login) Per configurare il plugin, usa queste impostazioni: ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } } ``` ## `directUpdate` Fa sì che il plugin installi direttamente l’aggiornamento quando l’app è stata appena aggiornata/installata. Applicabile solo per la modalità autoUpdate Caution Questa impostazione richiede di nascondere l’app all’utente mentre l’aggiornamento viene installato. Altrimenti l’app si resetterà mentre l’utente sta navigando ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": true } } } ``` ## `defaultChannel` Imposta il canale predefinito per l’app. Questo sovrascriverà qualsiasi altro canale impostato in Capgo se il canale permette la sovrascrittura ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "defaultChannel": "production" } } } ``` ## `appId` Imposta l’appId per l’app. Questo sovrascriverà qualsiasi altro modo per ottenere l’appId. Questo è utile quando vuoi avere un appId diverso in Capgo e nel tuo codice nativo Note Questo è il nuovo modo per impostare l’appId. Il vecchio modo è ancora e rimarrà supportato ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "AppId": "comexampleapp" } } } ``` ## `version` Imposta la versione per l’app. Questo sovrascriverà qualsiasi altro modo per ottenere la versione. Questo è utile quando vuoi avere una versione diversa in Capgo e nel tuo codice nativo Note Questo è il nuovo modo per impostare la versione. Il vecchio modo è ancora e rimarrà supportato ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "version": "123" } } } ``` # API Statistik > Come utilizzare il plugin di auto-aggiornamento in modalità self-hosted ## API Statistiche A partire dalla versione 130 il sistema di aggiornamento è in grado di inviare statistiche! Per impostazione predefinita, tutte le statistiche vengono inviate al nostro server, per comprendere l’utilizzo e la ricerca Note Nessun dato privato viene inviato per le statistiche, solo UUID casuale, aggiornamento versione, versione app nativa, piattaforma, azione e ID app Se vuoi inviare questi dati al tuo server, modifica la configurazione qui sotto: ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "statsUrl": "TUO_URL" } } } ``` Ciò che il tuo server riceverà è: ```tsx interface AppInfosStats { "action": "set", // può essere set, delete, set_fail, reset, revert // Poi sono le stesse informazioni dell'aggiornamento "app_id": "*******", // identificatore dell'app nello store "device_id": "*******", // id unico per installazione app "platform": "ios", // o android "custom_id": "user_1", // rappresenta il tuo utente "version_name": "123", // versione del build web "version_build": "120", // versione del build nativo "version_code": "120", // numero build del build nativo "version_os": "16", // versione OS del dispositivo "plugin_version": "400"// per far comportare la tua api diversamente con plugin diversi "is_emulator": false, "is_prod": false, } ``` Puoi anche disabilitarlo completamente, con una stringa vuota. Tieni presente che le statistiche sono rese private e mi aiutano a capire come le persone utilizzano il plugin, per risolvere problemi e migliorarlo [Gestione degli Aggiornamenti ](/docs/plugin/self-hosted/handling-updates/) # Migrazione da AppFlow a Capgo > Guida completa per migrare la tua app da Ionic AppFlow a Capgo ## Riferimento alla Configurazione AppFlow Prima della migrazione, prendi nota della tua configurazione AppFlow attuale in `capacitor.config.ts`: ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { LiveUpdates: { appId: 'your-app-id', channel: 'Production', autoUpdateMethod: 'background', // oppure 'always latest', 'force update' maxVersions: 2 } } }; ``` Questa configurazione ti aiuterà a mappare le funzionalità di AppFlow con gli equivalenti di Capgo. ## Strategie di Aggiornamento ### Aggiornamenti in Background (Predefinito) Se stai utilizzando gli aggiornamenti in background di AppFlow: ```typescript // Equivalente Capgo in capacitor.config.ts { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: false, autoDeletePrevious: true } } } ``` ### Aggiornamenti Forzati Se stai utilizzando la strategia di aggiornamento forzato di AppFlow: ```typescript // Equivalente Capgo in capacitor.config.ts { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: true, keepUrlPathAfterReload: true } } } // Codice JavaScript richiesto import { CapacitorUpdater } from '@capgo/capacitor-updater'; import { SplashScreen } from '@capacitor/splash-screen'; CapacitorUpdater.addListener('appReady', () => { SplashScreen.hide(); }); CapacitorUpdater.notifyAppReady(); ``` ### Sempre l’Ultima Versione Se stai utilizzando la strategia “always latest” di AppFlow, implementa con Capgo: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; import { App } from '@capacitor/app'; async function setupAlwaysLatest() { App.addListener('resume', async () => { const result = await CapacitorUpdater.download({ url: 'your-update-url' }); if (result) { await CapacitorUpdater.set({ id: result.id }); } }); } ``` ## Migrazione dei Metodi API | Metodo AppFlow | Equivalente Capgo | Note | | -------------- | ----------------- | ---------------------------------------- | | `sync()` | `download()` | Scarica nuovi aggiornamenti | | `reload()` | `set()` | Applica gli aggiornamenti immediatamente | | `setConfig()` | `setChannel()` | Aggiorna la configurazione del canale | ### Esempio di Migrazione ```typescript // Codice AppFlow import * as LiveUpdates from '@capacitor/live-updates'; const result = await LiveUpdates.sync(); if (result.activeApplicationPathChanged) { await LiveUpdates.reload(); } // Equivalente Capgo import { CapacitorUpdater } from '@capgo/capacitor-updater'; const bundle = await CapacitorUpdater.download({ url: 'your-update-url' }); if (bundle) { await CapacitorUpdater.set({ id: bundle.id }); } ``` ## Perché migrare a Capgo? Con l’annuncio della chiusura di Ionic AppFlow, la migrazione a Capgo offre una transizione perfetta per il tuo flusso di lavoro di sviluppo di app mobili. Capgo offre funzionalità migliorate, prestazioni superiori e significativi risparmi sui costi mantenendo tutte le funzionalità critiche necessarie. ### Vantaggi Principali * Distribuzione degli aggiornamenti più veloce (< 1 minuto vs 10 minuti) * Prezzi più convenienti (14$/mese vs 499$/mese) * Crittografia end-to-end inclusa in tutti i piani * Maggiore controllo sui canali di aggiornamento * Opzioni complete di integrazione CI/CD ## Passaggi di Migrazione ### 1. Migrazione degli Aggiornamenti Live #### Rimuovere le Dipendenze Precedenti ```bash npm uninstall @ionic/appflow # Rimuovere le configurazioni specifiche di AppFlow da capacitor.config.json ``` #### Installare Capgo ```bash npm install @capgo/capacitor-updater npx cap sync ``` #### Aggiornare la Configurazione Aggiungi la configurazione Capgo al tuo `capacitor.config.json`: ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true } } } ``` ### 2. Migrazione CI/CD Capgo offre opzioni flessibili per CI/CD: #### Opzione 1: Usa il tuo CI/CD Esistente Segui i nostri tutorial dettagliati per configurare CI/CD con piattaforme popolari: * [Configurazione Build iOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) * [Configurazione Build Android](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) * [Integrazione GitHub Actions](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) #### Opzione 2: CI/CD Gestito Lascia che gestiamo noi la tua configurazione CI/CD con il nostro [servizio gestito](https://cal.com/team/capgo/mobile-ci-cd-done-for-you). ### 3. Configurazione dei Canali 1. Creare canali nella dashboard Capgo: ```bash npx @capgo/cli channel create production npx @capgo/cli channel create staging ``` 2. Configurare le impostazioni dei canali: ```bash # Configurare il canale di produzione npx @capgo/cli channel update production --no-downgrade --no-upgrade # Configurare il canale di staging npx @capgo/cli channel update staging ``` ### 4. Test della Migrazione 1. **Testare gli Aggiornamenti Live** ```bash # Creare e caricare un bundle di test npx @capgo/cli bundle create --channel staging ``` 2. **Verificare la Ricezione degli Aggiornamenti** * Installare l’app su un dispositivo di test * Verificare che gli aggiornamenti vengano ricevuti correttamente * Verificare il processo di installazione degli aggiornamenti * Testare la funzionalità di ripristino ## Risoluzione dei Problemi ### Problemi Comuni #### Aggiornamenti Non Ricevuti * Verificare la configurazione dei canali * Controllare i log del dispositivo * Assicurare una connettività di rete adeguata * Validare il formato della versione del bundle ## Prossimi Passi 1. [Crea un account Capgo](/register/) 2. Segui la nostra [guida rapida](/docs/getting-started/quickstart/) 3. Configura l’[integrazione CI/CD](/docs/getting-started/cicd-integration/) 4. Configura gli [aggiornamenti live](/docs/live-updates/) Per i team aziendali che richiedono supporto dedicato durante la migrazione, [programma una chiamata con il nostro team](https://cal.com/team/capgo/capgo-enterprise-inquiry). # Da V2 a V3 > Come aggiornare da V2 a V3 Questa documentazione spiegherà come aggiornare alla versione 3 di auto-update ## Prima migra all’ultimo tooling: ```bash npm remove -g capgo npm remove capacitor-updater npm i @capgo/cli npm i @capgo/capacitor-updater@3 npx cap sync ``` ## Rimuovi tutte le tue configurazioni precedenti: ```json { CapacitorUpdater: { autoUpdateURL: "https", }, } ``` per lasciare solo questo: ```json { "CapacitorUpdater": { "autoUpdate": true } } ``` > ⚠️ Se stavi utilizzando il tuo server con `autoUpdateURL`, aggiornerò presto questa guida per te. Nel frattempo, dai un’occhiata alla nuova opzione di upload `external` che ti permette di inviare solo il link del tuo zip, non il codice nel cloud Capgo. Questo è stato fatto per aziende con politiche sulla privacy rigorose. In modalità external, il codice non arriverà mai sul server Capgo, memorizziamo solo l’URL e lo inviamo al dispositivo, che lo scaricherà direttamente. Nel modo standard, il codice viene compresso e memorizzato nel nostro server, ma non lo apriremo né lo utilizzeremo mai ## Cosa cambia Tutte le configurazioni diventano lato server per l’auto-update, per darti più controllo su come invii un aggiornamento agli utenti Questo ci permette di ripristinare e persino distribuire solo a un utente con i canali! Queste impostazioni sono state aggiunte all’interfaccia web: * disabilita il ripristino sotto il nativo * disabilita l’aggiornamento sopra la versione major > ⚠️ Diventeranno true di default per tutti i canali Questo rimuoverà anche la necessità di aggiornare spesso il plugin, la maggior parte degli aggiornamenti sarà effettuata lato server e li riceverai senza alcuna modifica da parte tua > ⚠️ Reset quando un aggiornamento diventa predefinito, quindi se preferisci non rimuovere tutte le versioni scaricate durante l’aggiornamento dallo store, fai questo: ```json { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } ``` ## Aggiorna il tuo codice Infine, aggiorna tutti i tuoi import in JS da: ```plaintext import { CapacitorUpdater } from 'capacitor-updater' ``` a ```plaintext import { CapacitorUpdater } from '@capgo/capacitor-updater' ``` Quindi ricompila il tuo codice `npm run build` e copia nuovamente gli asset `npx cap copy` Ora dovresti essere in grado di testare l’ultimo sistema di auto-update Invia la tua versione con: ```plaintext npx @capgo/cli@latest bundle upload ``` invece di ```plaintext npx capgo upload ``` ## Evoluzioni future Per ora viene utilizzato solo il primo canale pubblico, in futuro, public cambierà per canali multi pubblici, se ne viene impostato più di uno ## Problemi comuni: * Problemi di build dopo l’aggiornamento: se hai già aperto il codice sorgente del plugin in Android Studio o Xcode, a volte la sincronizzazione non li rimuove, questa è la causa del problema. Apri l’IDE nativo e rimuovi `capacitor-updater` manualmente e fai `npx cap sync` questo dovrebbe risolvere # Da V3 a V4 > How to upgrade from V3 to V4 ## Perché questo aggiornamento Dopo molte discussioni nella community Discord con voi ho scoperto che la modalità manuale era troppo manuale e non sicura da usare, per esempio, il ripristino automatico non era possibile, quindi se l’aggiornamento falliva in modalità manuale l’utente doveva rimuovere l’app e reinstallarla, il che è una terribile esperienza utente Nel frattempo, ho colto questa opportunità per darvi più libertà e rimuovere tutto il codice mal fatto ## Installazione `npm i @capgo/capacitor-updater@4` ## Auto-aggiornamento cloud Se usi l’esempio base nella tua app, puoi migrare in sicurezza alla nuova versione, buon divertimento! ## Auto-aggiornamento self-hosted Per te, ancora semplice, i cambiamenti sono: * Il nome dell’impostazione da `autoUpdateUrl` a `updateUrl` * Il metodo dell’endpoint è cambiato da `GET` a `POST` ## Utenti manuali Per voi, questo è il cambiamento più significativo, ma per il meglio! Ottenete tonnellate di miglioramenti, leggete attentamente ## Cambiamenti * `autoUpdateUrl` diventa `updateUrl` dato che questa impostazione può essere usata anche in modalità manuale ora * Eliminazione di `cancelDelay` e `delayUpdate` in favore di `setDelay` * Non più `versionName` in set * Cambio della chiave `version`, che veniva restituita nella maggior parte delle funzioni all’oggetto `BundleInfo` ```typescript interface BundleInfo { id: string; version: string; downloaded: string; status: 'success' | 'error' | 'pending' | 'downloading' } ``` * Rinominati i nomi fuorvianti (anche se la spiegazione non può essere chiara, ma nell’uso è facile capire il nuovo): * quello che era chiamato `version` ora si riferisce a un `bundle` * `id` si riferisce alla vecchia `version` che era una stringa casuale di 10 caratteri, questo `id` è l’unico modo affidabile e univoco per accedere ai tuoi bundle, esempio `7Dfcd2RedN` * `version` si riferisce ora al `versionName` che scegli per un bundle, esempio `100` * `updateUrl` passa da `get` a `post`, poiché gli header personalizzati erano un problema per alcuni di voi e post è più logico, tutti i precedenti header vanno nel body e il prefisso `cap_` scompare * Il metodo `versionName` è eliminato, in favore di `getId` * list restituisce ora una lista di `BundleInfo` * Rinomina `getId` in `getDeviceId` * `autoUpdate` diventa true di default, se usi la modalità Manual, impostalo su false ## Novità * Metodo `getLatest`, questo metodo ti permette di ottenere dal tuo server impostato con `updateUrl` l’ultima versione disponibile * Metodo `setDelay` che prende `{kind: "background" | "kill" | "nativeVersion" | "date", value?: string}` come argomento per impostare il ritardo per diverse modalità * Metodo `next`, per impostare la versione al prossimo backgrounding, in opposizione a `set` che lo fa istantaneamente * Metodo `isAutoUpdateEnabled`, per farti sapere se sei in un contesto di auto-aggiornamento * Evento `downloadComplete` quando il download raggiunge il 100% * Aggiunto campo obbligatorio `version` nel metodo download * `notifyAppReady` diventa obbligatorio anche in modalità manuale, se non viene chiamato dopo 10 secondi l’app torna alla versione precedente ## Collaboratori [@lincolnthree](https://github.com/lincolnthree/) Grazie mille per aver iniziato questo lavoro, era impossibile far funzionare questo aggiornamento senza di te # Da V4 a V5 > Come passare dalla V4 alla V5 ## Perché questo aggiornamento Questa versione principale è qui per seguire la versione principale di Capacitor Prima segui la guida di migrazione di Capacitor: [https://capacitorjs.com/docs/updating/5-0](https://capacitorjs.com/docs/updating/5-0/) ## Installazione `npm i @capgo/capacitor-updater@5` `Poi sincronizza l'aggiornamento del codice nativo:` `npx cap sync` Ecco fatto! Molto semplice! ## Modalità manuale Se stavi ottenendo l’aggiornamento da solo con getLatest, c’è un piccolo cambiamento Ora se sei già aggiornato entrerà nel catch Qualsiasi risposta diversa da aggiornamento disponibile farà questo # Da V5 a V6 > Come aggiornare da V5 a V6 ## Perché questo aggiornamento Questa versione principale è qui per seguire la versione principale di Capacitor Prima segui la guida di migrazione di Capacitor: [https://capacitorjs.com/docs/updating/6-0](https://capacitorjs.com/docs/updating/6-0/) ## Installazione `npm i @capgo/capacitor-updater@6` `Quindi sincronizza l'aggiornamento del codice nativo:` `npx cap sync` Tutto qui! Molto facile! # Introduzione > Introduzione alla webapp Cagpo ## Che cos’è? Cagpo ha una webapp completa per aiutarti a gestire i tuoi progetti. Questa webapp è costruita con Vuejs ed è open source. Puoi trovare il codice sorgente su [GitHub](https://github.com/Cap-go/capgo/tree/main/src/)\ La webapp è disponibile [qui](https://web.capgo.app/)\ Questa webapp ti permette di [gestire i canali](/docs/webapp/channels/), [gestire le versioni](/docs/webapp/bundles/), [gestire i dispositivi](/docs/webapp/devices/), [ispezionare i log](/docs/webapp/logs/), [gestire la fatturazione](/docs/webapp/settings/) e [gestire il tuo account](/docs/webapp/settings/) ## Come si usa? Per prima cosa, devi creare un account o accedere. Questo è relativamente semplice e può essere fatto cliccando sul pulsante `Accedi` al centro dello schermo. Dopo aver effettuato l’accesso, verrai reindirizzato alla dashboard. Questa è la pagina principale della webapp. Da qui puoi navigare verso tutte le altre pagine ![login page](/login.webp) ## Creare un account Devi cliccare su `Crea un account gratuito` nella parte inferiore del modulo di accesso. Da quel momento sarà semplice come compilare un modulo e seguire le istruzioni ![create account](/create-account.webp) # Gestione delle chiavi api > Come gestire le chiavi API ## Cosa posso fare con le chiavi api? Una chiave API può essere rigenerata, rimossa o se ne può aggiungere una nuova ## Come vedere tutte le chiavi api? Devi andare alla [pagina delle chiavi API](https://web.capgo.app/dashboard/apikeys/) e lì vedrai tutte le tue chiavi api ## Come aggiungere una nuova chiave api? Per aggiungere una nuova chiave API clicca sul piccolo pulsante più ![add apikey](/apikeys-add.webp) e poi seleziona i permessi che vuoi dare alla nuova chiave API. Puoi selezionare: * Lettura - la chiave API potrà leggere tutti i dati * Caricamento - la chiave API potrà caricare nuove versioni dalla CLI e leggere * Tutto - La chiave API potrà fare tutto ![select perm](/apikeys-select-perm.webp) ## Come rimuovere una chiave api? Per rimuovere una chiave API clicca sul piccolo pulsante cestino ![remove apikey](/apikeys-remove.webp) E poi conferma la rimozione della chiave API ## Come rigenerare una chiave api? Per rigenerare una chiave API clicca sul piccolo pulsante di aggiornamento ![generate apikey](/apikeys-regenerate.webp) E poi conferma la rigenerazione della chiave API # Bundle > Scopri come gestire i bundle ## Mostra tutti i bundle Per prima cosa, diamo un’occhiata alla pagina dei bundle. Puoi accedervi [cliccando sulla tua app](/docs/webapp/main-page) e poi [cliccando sulla scheda bundle](/docs/webapp/main-app-page) ![bundle list](/bundles.webp) ## Eliminare un bundle Ci sono due modi per eliminare un bundle: * Normalmente * In modo non sicuro Il modo non sicuro di eliminare un bundle è stato aggiunto a Capgo il 12 agosto 2024 La differenza tra i due modi è la possibilità di riutilizzare il numero di versione dopo l’eliminazione Per esempio, se elimini una versione `100` nel modo normale e più tardi provi a caricare una versione `100`, fallirà Se elimini questa versione tramite l’eliminazione non sicura, potrai caricare una versione `100` Danger Eliminare una versione in modo non sicuro e ricaricarla è MOLTO pericoloso Può causare ogni tipo di bug e comportamenti imprevedibili nel plugin Non dovrebbe MAI essere usato per bundle che sono stati utilizzati in un canale pubblico Per questo motivo, eliminare una versione in modo non sicuro richiede privilegi di “super\_admin” ## Gestire un bundle specifico Una volta che vedi la lista di tutti i bundle, clicca su quello che vuoi gestire. Dopo averlo fatto dovresti vedere qualcosa del genere: ![bundle info](/bundle-info.webp) Analizziamo tutti gli elementi di questa pagina *** Per prima cosa puoi vedere un `Channel`. Questo ti fa sapere per quale canale è questo bundle. Puoi cambiare il canale cliccandoci sopra Una volta cliccato dovresti vedere qualcosa del genere: ![bundle change](/bundle-change.webp) `Set bundle to channel` ti permetterà di collegare questo bundle come predefinito per qualsiasi canale\ `Open channel` aprirà la pagina del canale per il canale a cui questo bundle è destinato\ `Unlink bundle from channel` scollegherà questo bundle dal canale a cui è destinato (**ATTENZIONE**: Se il bundle è collegato a più di 1 canale, non ti verrà data un’opzione su quale canale scollegare) *** Successivamente, puoi vedere la `Size`. Se ci clicchi sopra potrai scaricare questo bundle Dovrebbe apparire qualcosa del genere: ![download bundle](/download-bundle.webp) *** Infine, c’è la sezione `Devices`. Puoi vedere tutti i dispositivi che utilizzano questa versione lì # Canali > I canali sono un modo per gestire gli aggiornamenti della tua app. Puoi avere più canali e ogni canale può avere più versioni. Questo ti permette di gestire più versioni della tua app contemporaneamente in produzione. ## Gestione dei canali Per prima cosa, diamo un’occhiata alla pagina dei canali. Puoi accedervi [cliccando sulla tua app](/docs/webapp/main-page) e poi [cliccando sulla scheda canali](/docs/webapp/main-app-page) ![channel list](/channels.webp) ## Creazione di un canale Come puoi vedere, esiste un pulsante più nell’angolo in basso a destra (`1` nell’immagine). Cliccandoci si aprirà una finestra modale dove puoi creare un nuovo canale ![new channel](/new_channel_modal.webp) Dopo aver cliccato su `Aggiungi` un nuovo canale dovrebbe apparire nella lista ![after channel create](/post-channel-create.webp) ## Cosa significa mal configurato? A volte la configurazione di un canale non è valida. In questo caso, riceverai un grande avviso e la colonna `Mal configurato` dirà `Sì` per uno o più canali. Puoi saperne di più [qui](/docs/cli/commands/#disable-updates-strategy) ## Eliminazione di un canale Eliminare un canale è semplice. Basta cliccare sull’icona del cestino e confermare l’eliminazione (`2` nell’immagine) ## Gestione di un canale Cliccando sul nome del canale si aprirà una finestra modale dove puoi gestire il canale (`3` nell’immagine) Questa pagina dovrebbe apparire così: ![manage channel](/manage_channel_main.webp) Analizziamo le diverse sezioni Prima il `Numero del bundle` (`1` nell’immagine). Questa è la versione corrente per quel canale. Quando viene richiesto di servire un aggiornamento questo canale tenterà sempre di rispondere con quella versione\* \[^1] Cliccandoci sopra dovresti essere portato alla pagina dei [bundle](/docs/webapp/bundles/) Seconda la pagina `Condiviso con` (`2` nell’immagine). Sconsiglio di usarla. Un nuovo e migliore sistema è in fase di sviluppo Ora i dispositivi forzati (`3` nell’immagine). Questa è una lista di dispositivi che riceveranno sempre aggiornamenti da questo canale. Questo è utile per scopi di test. Puoi forzare un dispositivo a un canale dalla pagina dei [dispositivi](/docs/webapp/devices/) Infine le impostazioni (`4` nell’immagine). Qui puoi gestire come si comportano i canali Dopo aver cliccato dovresti vedere qualcosa del genere: ![setting of channel](/channel_settings.webp) La lista delle impostazioni è lunga, ma farò del mio meglio per spiegarle tutte *** Prima il `Canale predefinito` **QUESTA È PROBABILMENTE LA PIÙ IMPORTANTE**\ Se un canale è contrassegnato come predefinito, verrà utilizzato come canale predefinito per tutti i nuovi dispositivi\ In altri termini: Se hai un nuovo utente capgo cercherà di fornirgli l’ultima versione di questo canale predefinito Solo 1 canale può essere impostato come predefinito alla volta. Se provi a infrangere questa regola ti verrà chiesto di confermare la tua azione ![confirm make change](/confirm-make-default.webp) Dopo la conferma il vecchio canale predefinito non sarà più contrassegnato come predefinito e il nuovo sarà contrassegnato come predefinito *** Seconda l’impostazione `IOS`. È relativamente semplice. Se è falsa allora i dispositivi IOS non potranno scaricare aggiornamenti da questo canale Terza è l’impostazione `Android`. È simile a `IOS`. Se è falsa allora i dispositivi Android non potranno scaricare aggiornamenti da questo canale Quarta è l’impostazione `Disabilita il downgrade automatico sotto la versione nativa`. Se è vera allora sarà impossibile fare il downgrade da una versione nativa. Questo significa che se hai caricato una versione `120` sull’app store o play store e provi a impostare la versione del canale a `110` allora l’aggiornamento (downgrade) fallirà Quinta è `Disabilita aggiornamento automatico`. Questa impostazione è abbastanza complessa, e puoi saperne di più [qui](/docs/cli/commands/#disable-updates-strategy) Per quanto riguarda `Permetti build di sviluppo`. Se è vera allora le build di sviluppo potranno scaricare aggiornamenti da questo canale. In caso contrario qualsiasi richiesta di aggiornamento che ha il `prod` impostato su falso sarà rifiutata. Questo è principalmente utile per scopi di test Settima è `Permetti Emulatori`. Se è falsa allora capgo rifiuterà qualsiasi richiesta di aggiornamento che proviene da un emulatore. Questo è principalmente utile per scopi di test Ottava è `Permetti ai dispositivi di auto-associarsi`. Se è vera allora il metodo [setChannel](/docs/plugin/api/#setchannel) sarà disponibile. Se è impostata su falso e provi a chiamare il metodo [setChannel](/docs/plugin/api/#setchannel) con questo canale allora la chiamata fallirà # Dispositivi > How to use Device page ## Mostra l’elenco di tutti i dispositivi Prima di tutto, diamo un’occhiata alla pagina dei dispositivi. Puoi accedervi [cliccando sulla tua app](/docs/webapp/main-page) e poi [cliccando sulla scheda dispositivi](/docs/webapp/main-app-page) ![devices list](/devices.webp) ## Mostra solo i dispositivi sviluppatore Potresti voler mostrare solo i dispositivi sovrascritti (Dispositivi che hanno un [canale personalizzato](/docs/plugin/api/#setchannel) o una versione personalizzata) Per farlo, clicca su `Filtri` e poi su `Override`. Dovrebbe apparire qualcosa del genere: ![filter devices](/overwrite-filter.webp) ## Configurazione di un dispositivo Per configurare un dispositivo specifico, cliccalo nella tabella e dovresti vedere qualcosa del genere: ![show one device](/device-specific.webp) Prima il `Custom ID`. Questo non è realmente così utile e al momento non fa nulla. Puoi ignorarlo Poi la versione forzata. Se questa è impostata, questo dispositivo riceverà **SEMPRE** questa versione. Ha la precedenza sul canale Infine il canale personalizzato. Se questo è impostato, questo dispositivo non terrà conto del canale pubblico (predefinito) e userà solo questo # Log > Scopri la pagina dei log ## Mostra tutti i log Per prima cosa, diamo un’occhiata alla pagina dei log. Puoi accedervi [cliccando sulla tua app](/docs/webapp/main-page) e poi [cliccando sulla scheda aggiornamenti](/docs/webapp/main-app-page) Da lì dovresti vedere una pagina come questa: ![show logs](/logs.webp) ## Ottenere più dettagli su un log Se clicchi su un log ti porterà alla [pagina dei dispositivi](/docs/webapp/devices/) # Pagina principale dell'app > What is shown on the main page? ## Cosa mostra la pagina principale? Per prima cosa, diamo un’occhiata alla pagina principale dell’app: ![Main page screeshot](/main-app-page.webp) Analizziamola più nel dettaglio Prima le statistiche. Le statistiche sono in fase di revisione quindi non possono essere documentate in questo momento. Aggiungeremo una sezione statistiche quando saranno pienamente operative. Secondo, diamo un’occhiata a tutti i menu disponibili e cosa fanno ![Multiple sections screeshot](/app-multiple-sections.webp) Il primo pulsante ti porterà alla pagina dei [canali](/docs/webapp/channels/) dove puoi creare/eliminare/configurare i canali dell’app\ Il secondo pulsante ti porterà alla pagina dei [bundle](/docs/webapp/bundles/) dove puoi vedere tutte le versioni dell’app Il secondo pulsante ti porterà alla pagina dei [dispositivi](/docs/webapp/devices/) dove puoi vedere tutti i dispositivi. Puoi anche impostare sovrascritture specifiche per dispositivo da lì Il secondo pulsante ti porterà alla pagina degli [aggiornamenti](/docs/webapp/logs/) dove puoi vedere le statistiche dettagliate (log) e gli errori che la tua app sta riscontrando # Pagina principale > Questa pagina descrive la pagina principale della webapp ## Cosa mostra la pagina principale? Per prima cosa, diamo un’occhiata alla pagina principale: ![Main page screeshot](/main-page.webp) Iniziamo dall’inizio. La prima cosa che vedi sono le **statistiche**. Contiene statistiche specifiche dell’app. Questi aggiornamenti dipendono dall’utilizzo dell’app. La seconda cosa che vedi è l’elenco di tutte le app disponibili. Questo cambierà a seconda di quante app hai creato. Puoi fare clic su ciascuna app per vedere maggiori dettagli al riguardo. La terza cosa che vedi è il pulsante **API keys**. Questo pulsante ti porterà alla pagina [API keys](/docs/webapp/api-keys/). La prossima cosa che vedi è il pulsante **test Capgo**. Questo pulsante cambierà a seconda del tuo nome e cognome e ti porterà alla pagina delle [impostazioni](/docs/webapp/settings/) o del supporto. Infine, vedi un pulsante per aggiungere un’altra app. Questo pulsante ti porterà a una pagina dove puoi aggiungere una nuova app a Capgo. # 二要素認証 > Gestione l'autenticazione a due fattori per proteggere al meglio il tuo account capgo ## Cos’è il 2FA? Il 2FA è una misura di sicurezza progettata per impedire a malintenzionati di impossessarsi del tuo account capgo\ Lo fa richiedendo un codice aggiuntivo. Questo codice è memorizzato sul tuo telefono cellulare o su una chiave hardware 2FA. Cambia ogni 30 secondi, rendendo impossibile indovinarlo. ## Requisiti per questa guida * Un telefono Android o iOS * Connessione Internet ## Cosa coprirà questa guida? Questa guida mostrerà come configurare il 2FA utilizzando `Google Authenticator`. Esistono altre app che servono a uno scopo simile, tuttavia non posso coprire l’intero argomento del 2FA in questa guida. ## Come configurare il 2FA? Prima scarica l’app `Google Authenticator`. Se sei su Android, puoi scaricarla dal [play store](https://play.google.com/store/apps/details/?id=comgoogleandroidappsauthenticator2). Su iOS puoi scaricarla dall’[App Store](https://appsapplecom/us/app/google-authenticator/id388497605/) Secondo, vai alle [impostazioni dell’account capgo](https://web.capgo.app/dashboard/settings/account/). Lì dovresti vedere un pulsante verde che dovrebbe apparire così: ![Button MFA](/button-mfa.webp) Cliccalo, e una volta fatto, apparirà un codice QR ![Enable MFA](/enable-mfa.webp) Danger ⚠️ Nota Importante:\ Non condividere mai questo codice QR con nessuno, o potresti essere disconnesso dal tuo account Successivamente, apri `Google Authenticator` sul tuo telefono. Una volta fatto, segui questi passaggi: Clicca il pulsante più ![MFA auth plus](/mfa-auth-plus.webp) Dopo di che, clicca il pulsante della fotocamera ![MFA scan QR](/mfa-scan-qr.webp) Questo aprirà l’anteprima della fotocamera. Scansiona il codice QR mostrato sul tuo PC. Dopo averlo fatto, dovresti vedere qualcosa del genere: ![MFA final code](/mfa-final-code.webp) Quindi torna al PC e clicca il pulsante verifica ![Verify MFA](/enable-mfa-verify.webp) Questo aprirà una finestra per digitare il nostro codice 2FA. Nel mio caso, questo codice è `095101` ma sarà diverso per te\ Dopo aver digitato questo codice, clicca sul pulsante `verifica` ![MFA verify code final](/mfa-verify-final-code.webp) Se hai inserito il codice corretto e premuto `verifica` dovresti vedere un pop-up come questo ![MFA enabled](/mfa-enabled.webp) Congratulazioni!\ Hai abilitato l’autenticazione 2FA 🎉 ## Come accedere usando il 2FA La prossima volta che accedi al tuo account, vedrai una finestra come questa ![MFA required](/mfa-required.webp) Apri l’authenticator e copia il tuo codice di autenticazione ![MFA login](/mfa-login.webp) Danger ⚠️ Nota Importante:\ Premi `verifica` prima che il codice si aggiorni, altrimenti il codice cambierà e quello vecchio non sarà più valido Quindi inserisci il codice nel modulo di accesso e premi `verifica` ![MFA login](/mfa-final-login-verify.webp) Se hai inserito il codice corretto dovresti vedere la dashboard di capgo ## Come disabilitare il 2FA Per disabilitare il 2FA vai alle [impostazioni dell’account capgo](https://web.capgo.app/dashboard/settings/account/). Lì dovresti vedere un pulsante rosso che dovrebbe apparire così: ![MFA disable button](/mfa-disable-button.webp) Cliccalo, e dovresti vedere una schermata come questa ![MFA disabled](/mfa-disable-2.webp) Basta premere il pulsante `disabilita`, e questo è tutto # Sistema di organizzazione > Gestione delle organizzazioni nel tuo account capgo. ## Che cos’è il sistema delle organizzazioni? Il sistema delle organizzazioni è un sistema in capgo che ti permette di condividere in modo sicuro le tue app con i membri del tuo team ### D: Come posso accedere alle informazioni della mia organizzazione? Per accedere alle informazioni della tua organizzazione, vai su [impostazioni](/docs/webapp/settings/#how-to-get-to-the-settings-page) e poi clicca su `Impostazioni organizzazione` ![Org settings](/orgs-settings.webp) ### D: Come posso cambiare l’organizzazione che sto visualizzando? Per visualizzare le impostazioni di un’organizzazione diversa, clicca sul selettore dell’organizzazione vicino al tuo nome ![Org selector](/org-selector.webp) Se non riesci a vederlo, probabilmente non sei nella pagina delle impostazioni ### D: Come posso vedere i membri della mia organizzazione? Clicca su `membri` ![Org Show members](/org-show-members.webp) ### D: Come posso invitare un utente a un’organizzazione? Clicca su `Aggiungi membro` ![Org add member](/orgs-add-member.webp) Apparirà un pop-out - inserisci l’indirizzo email dell’utente ![Invite to org](/invite-to-org-email-enter.webp) Poi clicca su `invita` Apparirà un altro pop-out, questa volta ti chiederà i permessi che l’utente invitato dovrebbe avere ![Select perm for org](/select-perm-orgs.webp) Ecco una panoramica di tutti i permessi: | Permesso | Lettura | Caricamento | Scrittura | Admin | Super Admin | | ----------------------------------- | ------- | ----------- | --------- | ----- | ----------- | | Mostra statistiche app | ✅ | ✅ | ✅ | ✅ | ✅ | | Mostra canali app | ✅ | ✅ | ✅ | ✅ | ✅ | | Mostra dispositivi | ✅ | ✅ | ✅ | ✅ | ✅ | | Mostra log | ✅ | ✅ | ✅ | ✅ | ✅ | | Mostra bundle | ✅ | ✅ | ✅ | ✅ | ✅ | | Elimina app | ❌ | ❌ | ❌ | ❌ | ✅ | | Elimina canale | ❌ | ❌ | ❌ | ✅ | ✅ | | Elimina versione | ❌ | ❌ | ✅ | ✅ | ✅ | | Modifica impostazioni org | ❌ | ❌ | ❌ | ✅ | ✅ | | Gestisci utenti org | ❌ | ❌ | ❌ | ✅ | ✅ | | Modifica impostazioni canale | ❌ | ❌ | ✅ | ✅ | ✅ | | Carica nuova versione | ❌ | ✅ | ✅ | ✅ | ✅ | | Modifica dispositivi | ❌ | ❌ | ✅ | ✅ | ✅ | | Cambia versione corrente canale | ❌ | ❌ | ✅ | ✅ | ✅ | | Crea nuovo canale | ❌ | ❌ | ❌ | ✅ | ✅ | | Modifica versione (metadata) | ❌ | ❌ | ✅ | ✅ | ✅ | | Gestisci fatturazione | ❌ | ❌ | ❌ | ❌ | ✅ | | Elimina versione in modo non sicuro | ❌ | ❌ | ❌ | ❌ | ✅ | ### D: Come funziona la fatturazione nelle organizzazioni? Chiunque abbia il permesso di **super admin** può gestire la fatturazione per una determinata organizzazione I piani sono collegati a un’organizzazione e non al tuo account personale Danger ⚠️ L’acquisto di un piano influenzerà SOLO le organizzazioni che hai attualmente selezionato ### D: Posso creare più di un’organizzazione? No, non ancora # Sistema di pagamento > Gestione dei pagamenti nel tuo account capgo. ## Di cosa si tratta? Questa pagina mira a rispondere ad alcune domande sul sistema di pagamento in capgo #### D: Come posso aggiornare il mio piano capgo? R: Puoi aggiornare il tuo piano capgo andando nelle [impostazioni](/docs/webapp/settings/#how-to-get-to-the-settings-page) e cliccando sul pulsante **Piani** ![Choose plan](/plans-button.webp) Quindi puoi selezionare il piano più adatto alle tue esigenze e cliccare su **Abbonati** ![Subscribe to plan](/plans-subscribe.webp) Poi si aprirà una pagina stripe dove potrai inserire i tuoi dati di pagamento ![Stripe portal](/plans-stripe.webp) #### D: I pagamenti sono sicuri? R: Sì, i pagamenti sono completamente gestiti da stripe. Capgo non accede mai ai dettagli della tua carta di credito. Stripe prende molto seriamente la sicurezza. [Scopri di più sulla politica di sicurezza di stripe](https://stripecom/docs/security/) #### D: Capgo aggiornerà automaticamente il mio piano quando supero il limite? R: No, capgo non cambierà mai il tuo piano #### D: Capgo mi invierà un’email quando il mio piano è vicino ai suoi limiti? R: Sì, capgo ti invierà un’email per informarti sull’utilizzo #### D: Il piano che acquisto influenzerà le organizzazioni a cui sono stato invitato? R: No, il piano influenzerà solo l’organizzazione che hai attualmente selezionato Fai riferimento alla [documentazione dell’organizzazione](/docs/webapp/organization-system/#q-how-is-billing-done-within-orgs) #### D: E se ho bisogno di un piano più personalizzato? R: [Contatta direttamente il supporto di capgo](/docs/getting-help#support-by-chat) #### D: Qual è la politica di rimborso per capgo? R: La politica di rimborso può essere trovata [qui](https://capgo.app/return/) # Impostazioni > Come modificare le impostazioni utente ## Come arrivare alla pagina delle impostazioni Prima clicca su **NOME COGNOME** Nel mio caso è **test Capgo** Nel tuo caso, sarà il tuo nome e poi il tuo cognome Quindi clicca su **Impostazioni** ![open settings](/settings-go.webp) ## Modificare le impostazioni utente Per modificare qualsiasi impostazione utente puoi semplicemente compilare il modulo nell’account e poi cliccare su **Aggiorna** ![save change in account](/account-save.webp) Dovrebbe quindi apparire una conferma ![acount updated](/account-updated.webp) ## Cambiare la password Per cambiare la password vai alla pagina delle impostazioni e clicca su **Password** Quindi compila il modulo e clicca su **Aggiorna** ![update password](/update-passwd.webp) Quando la password non segue le regole di sicurezza di Capgo riceverai un messaggio di errore ![wrong password](/passwd-error.webp) # Capgoへようこそ > Capgoは、Capacitorとモバイル開発チームのためのオープンソースのリアルタイムアップデートプラットフォームで、数日ではなく数分でユーザーにアップデートを提供することができます リアルタイム更新の力 シームレスなアプリのライブ更新、重要なバグ修正、コンテンツの変更、ベータ機能などを提供し、ユーザーに最高の体験を提供します 簡単な統合 プラグインはコードベースへの統合が3ステップで完了し、数日ではなく数分でユーザーに更新を送信できます! インストール `npx @capgo/cli@latest init [APIKEY]` を実行して始めましょう 詳細なドキュメント [ドキュメント](/docs/getting-started/quickstart/)で、オンボーディング動画を使用して5分でプラグインをマスターする方法を学びましょう # Comandi > Capgo CLIドキュメント ### 使用方法 すべてのコマンドは、Capacitorプロジェクトが適切に初期化されたアプリフォルダで実行する必要があります [Capacitor ウェブアプリ用のクロスプラットフォームネイティブランタイム ](https://capacitorjs.com/docs/getting-started/) ### **初期化** `npx @capgo/cli@latest init [apikey]` このメソッドは、ステップバイステップで導入をサポートします アプリをCapgoに追加し、アップデートを検証するコードをアプリに追加します。同様に、アプリをビルドし、Capgoにアップロードし、アップデートが機能するかを確認するのに役立ちます ### **ログイン** `npx @capgo/cli login [apikey]` このメソッドは、`apikey`を記憶するためのものです Note 任意のコマンドで`--apikey=********`を使用して上書きできます **オプションで指定可能:** `--local` **apikey**をローカルリポジトリに保存し、gitで無視します ## **ドクター** `npx @capgo/cli doctor` Capgoパッケージが最新かどうかを確認するコマンド このコマンドはバグレポートにも役立ちます ## アプリ ### **追加** `npx @capgo/cli app add [appId]` `[appId]` アプリIDのフォーマット`comtestapp`は[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています > 💡 提供されていない場合、すべてのオプションは設定から推測されます オプションで指定可能: * `--icon [/path/to/my/icon]` Capgoウェブアプリに表示するカスタムアイコン * `--name [test]` リストでのカスタム名 * `--apikey [key]` アカウントにリンクするAPIキー * `--retention [retention]` アプリバンドルの保持期間(日数)、デフォルトは0 = 無期限 appIdとAppNameの`capacitorconfigjson`の例、アイコンはresourcesフォルダから推測されます ```json { "appId": "eeforgrcapacitor_go", "appName": "Capgo", "webDir": "dist" } ``` ### **設定** `npx @capgo/cli app set [appId]` `[appId]` はアプリID、フォーマットは[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています オプションで指定可能: * `--icon [/path/to/my/icon]` Capgoウェブアプリに表示するカスタムアイコン * `--name [test]` リストでのカスタム名 * `--retention [retention]` アプリバンドルの保持期間(日数)、デフォルトは0 = 無期限 * `--apikey [key]` アカウントにリンクするAPIキー ### **一覧** `npx @capgo/cli app list [appId]` `[appId]` アプリIDのフォーマット`comtestapp`は[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています オプションで指定可能: * `--apikey [key]` アカウントにリンクするAPIキー ### **削除** `npx @capgo/cli app delete [appId]` `[appId]` アプリIDのフォーマット`comtestapp`は[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています オプションで指定可能: * `--apikey [key]` アカウントにリンクするAPIキー * `--bundle` バージョン番号を指定してそのバージョンのみを削除 ### デバッグ `npx @capgo/cli app debug [appId]` `[appId]` アプリIDのフォーマット`comtestapp`は[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています オプションで指定可能: * `--apikey [key]` アカウントにリンクするAPIキー * `--device` デバッグしたい特定のデバイス ### 設定 `npx @capgo/cli app setting [path]` Capacitor設定を編集 `[path]` - 変更したい設定のパス。例えば、`appId`を変更するには`appId`を指定します `capacitor-updater`の自動更新を無効にするには`pluginsCapacitorUpdaterautoUpdate`を指定します `--string`または`--bool`のいずれかを指定する必要があります! オプション: * `--string ` - 設定を文字列に設定 * `--bool ` - 設定をブーリアンに設定 ## バンドル ### アップロード `npx @capgo/cli bundle upload [appId]` `[appId]` はアプリID、フォーマットは[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています オプションで指定可能: * `--apikey ` アカウントにリンクするAPIキー * `--path ` アップロードするフォルダのパス * `--channel ` リンクするチャンネル * `--external ` Capgoクラウドにアップロードする代わりに外部URLにリンク * `--iv-session-key ` バンドルURL外部用のIVとセッションキーを設定 * `--s3-endpoint ` S3エンドポイントのURL 部分アップロードまたは外部オプションでは動作しません * `--s3-region ` S3バケットのリージョン * `--s3-apikey ` S3エンドポイントのAPIキー * `--s3-apisecret ` S3エンドポイントのAPIシークレット * `--s3-bucket-name ` AWS S3バケットの名前 * `--s3-port ` S3エンドポイントのポート * `--no-s3-ssl` S3アップロード用のSSLを無効化 * `--key ` 公開署名キーのカスタムパス(v1システム) * `--key-data ` 公開署名キー(v1システム) * `--key-v2 ` 秘密署名キーのカスタムパス(v2システム) * `--key-data-v2 ` 秘密署名キー(v2システム) * `--bundle-url` バンドルURLをstdoutに出力 * `--no-key` 署名キーを無視してクリアアップデートを送信 * `--no-code-check` ソースコードでnotifyAppReady()が呼び出されているかとルートフォルダにindexが存在するかのチェックを無視 * `--display-iv-session` アップデートの暗号化に使用されたIVとセッションキーをコンソールに表示 * `--bundle ` アップロードするバンドルのバージョン番号 * `--min-update-version ` このバージョンに更新するために必要な最小バージョン チャンネルで自動更新が無効になっている場合のみ使用 * `--auto-min-update-version` ネイティブパッケージに基づいて最小更新バージョンを設定 * `--ignore-metadata-check` アップロード時のメタデータ(node\_modules)チェックを無視 * `--ignore-checksum-check` アップロード時のチェックサムチェックを無視 * `--timeout ` アップロードプロセスのタイムアウト(秒) * `--partial` 部分ファイルをCapgoクラウドにアップロードしない * `--tus` tusプロトコルを使用してバンドルをアップロード * `--multipart` S3にデータをアップロードするためにマルチパートプロトコルを使用、非推奨、代わりにTUSを使用 * `--encrypted-checksum ` 暗号化されたチェックサム(署名) 外部バンドルをアップロードする場合のみ使用 * `--package-json ` packagejsonへのパス モノレポで有用 * `--auto-set-bundle` capacitorconfigjsonでバンドルを設定 * `--node_modules ` node\_modulesへのパスのリスト モノレポで有用(カンマ区切り 例://node\_modules,/node\_modules) > ⭐️ 外部オプションは2つのケースを解決するのに役立ちます:プライバシーに関する企業の懸念、サードパーティにコードを送信しない、200 MB以上のアプリ。この設定では、Capgoはzipへのリンクのみを保存し、すべてのアプリにリンクを送信します > 👀 Capgoクラウドは、リンク内(外部オプションの場合)や保存されたコードの内容を一切確認しません > 🔑 暗号化を追加することで2層目のセキュリティを追加できます。そうすることでCapgoは何も確認や変更ができなくなり、「トラストレス」になります バージョンの`packagejson`の例 ```json { "version": "102" } ``` > ⛔ バージョンは”000”より大きい必要があります > 💡 セキュリティ上の理由から、バージョン番号は削除後に上書きまたは再利用することはできないため、送信するたびにバージョン番号を更新することを忘れないでください ### **一覧** `npx @capgo/cli bundle list [appId]` `[appId]` アプリIDのフォーマット`comtestapp`は[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています オプションで指定可能: * `--apikey [key]` アカウントにリンクするAPIキー ### **削除** `npx @capgo/cli bundle delete [appId]` `[appId]` アプリIDのフォーマット`comtestapp`は[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています オプションで指定可能: * `--apikey [key]` アカウントにリンクするAPIキー * `--bundle` バージョン番号を指定してそのバージョンのみを削除 ### クリーンアップ クラウドのメジャーバージョンのSemVer範囲内で `npx @capgo/cli bundle cleanup [appId] --bundle=[majorVersion] --keep=[numberToKeep]` `[appId]` アプリIDのフォーマット`comtestapp`は[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています オプションで指定可能: * `--apikey [key]` アカウントにリンクするAPIキー * `--bundle [majorVersion]` 以前のパッケージを削除したいバージョン、最後のものと`numberToKeep`を保持します\* `--keep [numberToKeep]` 保持したいパッケージの数(デフォルトは4) 例: バージョン1001から10011まで10個のバージョンがあり、`npx @capgo/cli cleanup [appId] --bundle=1000`を使用した場合、1001から1006までが削除され、1007から10011が保持されます 合計20バージョンがあり、バンドル番号を指定せずに`npx @capgo/cli cleanup [appId] --keep=2`のように実行した場合、18バージョンが削除され、最後の2つが保持されます > このコマンドは確認を求め、保持および削除される内容の一覧を表示します Note このコマンドは、現在いずれかのチャンネルで使用中のバンドルは無視します ### **暗号化** > **警告**: このコマンドは非推奨であり、次のメジャーリリースで削除されます。新しい暗号化システムを使用してください `npx @capgo/cli bundle encrypt [path/to/zip]` このコマンドは、コードを外部ソースに保存する場合やテスト目的で使用します オプションで以下を指定できます: `--key [/path/to/my/private_key]` プライベートキーのパス `--key-data [privateKey]` インラインで使用する場合のプライベートキーデータ コマンドは`ivSessionKey`を表示し、アップロードコマンドまたは復号化コマンドで使用する暗号化されたzipを生成します ### **暗号化 V2** `npx @capgo/cli bundle encryptV2 [path/to/zip] [checksum]` このコマンドは、コードを外部ソースに保存する場合やテスト目的で使用します チェックサムはバンドルのsha256(—key-v2で生成)で、復号化後のファイルの整合性を確認するために使用されます プライベートキーで暗号化され、バンドルと共に送信されます 暗号化v2では、チェックサムがバンドルの「署名」にアップグレードされます オプションで以下を指定できます: `--key [/path/to/my/private_key]` プライベートキーのパス `--key-data [privateKey]` インラインで使用する場合のプライベートキーデータ `--json` 情報をJSONとして出力 コマンドは`ivSessionKey`を表示し、アップロードコマンドまたは復号化コマンドで使用する暗号化されたzipを生成します ### **復号化** `npx @capgo/cli bundle decrypt [path/to/zip] [ivSessionKey]` オプションで以下を指定できます: `--key [/path/to/my/private_key]` プライベートキーのパス `--key-data [privateKey]` インラインで使用する場合のプライベートキーデータ このコマンドは主にテスト目的で使用され、zipを復号化してbase64でエンコードされた復号化されたセッションキーをコンソールに表示します ### **復号化 V2** `npx @capgo/cli bundle decryptV2 [path/to/zip] [ivSessionKey]` オプションで以下を指定できます: `--key [/path/to/my/private_key]` プライベートキーのパス `--key-data [privateKey]` インラインで使用する場合のプライベートキーデータ このコマンドは主にテスト目的で使用され、zipを復号化してbase64でエンコードされた復号化されたセッションキーをコンソールに表示します `--checksum [checksum]` ファイルのチェックサム、復号化後にチェックサムを検証します ### **Zip** `npx @capgo/cli bundle zip [appId]` `[appId]` はアプリIDです。フォーマットについては[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています オプションで以下を指定できます: * `--path [/path/to/my/bundle]` 特定のフォルダをアップロードする場合 * `--bundle [100]` ファイル名のバンドルバージョン番号を設定 * `--name [myapp]` ファイル名をオーバーライド * `--json` 情報をJSONとして出力 * `--no-code-check` コードチェックを無視してバンドルを送信 * `--key-v2` 新しい暗号化システムを使用 これは、新しい暗号化システムがファイルの整合性を確認するためのより良いチェックサムを使用するために必要です ### **互換性** `npx @capgo/cli bundle compatibility [appId] -c [channelId]` `[appId]` はアプリIDです。フォーマットについては[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています `[channelId]` は新しいチャンネルの名前です オプションで以下を指定できます: * `--apikey [key]` アカウントにリンクするAPIキー * `--text` テーブルで絵文字の代わりにテキストを使用 * `--channel [channel]` 互換性をチェックするチャンネル * `--package-json ` packagejsonへのパス モノレポで有用です * `--node-modules ` node\_modulesへのパスのリスト モノレポで有用です(カンマ区切り 例: //node\_modules,/node\_modules) ## チャンネル ### **追加** `npx @capgo/cli channel add [channelId] [appId]` `[channelId]` 新しいチャンネルの名前 `[appId]` アプリID フォーマット`comtestapp`については[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています ### **削除** `npx @capgo/cli channel delete [channelId] [appId]` `[channelId]` 削除したいチャンネルの名前 `[appId]` アプリID フォーマット`comtestapp`については[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています ### **一覧** `npx @capgo/cli channel list [appId]` `[appId]` アプリID フォーマット`comtestapp`については[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています オプションで以下を指定できます: * `--apikey [key]` アカウントにリンクするAPIキー ### **設定** `npx @capgo/cli channel set [channelId] [appId]` `[appId]` はアプリIDです。フォーマットについては[こちら](https://capacitorjs.com/docs/cli/commands/init/)で説明されています オプションで以下を指定できます: * `--bundle [123]` クラウドに既に送信済みのアプリバンドルを、チャンネルにリンクする場合 * `--latest` `packagejson:version`からバンドルバージョンを取得、`--bundle`との併用不可 * `--state [ normal | default ]` チャンネルの状態を設定、`normal`または`default`を指定可能 1つのチャンネルは`default`である必要があります * `--downgrade` チャンネルがデバイスにダウングレードバージョンを送信することを許可 * `--no-downgrade` チャンネルがデバイスにダウングレードバージョンを送信することを禁止 * `--upgrade` チャンネルがデバイスにアップグレード(メジャー)バージョンを送信することを許可 * `--no-upgrade` チャンネルがデバイスにアップグレード(メジャー)バージョンを送信することを禁止 * `--ios` チャンネルがiOSデバイスにバージョンを送信することを許可 * `--no-ios` チャンネルがiOSデバイスにバージョンを送信することを禁止 * `--android` チャンネルがAndroidデバイスにバージョンを送信することを許可 * `--no-android` チャンネルがAndroidデバイスにバージョンを送信することを禁止 * `--self-assign` デバイスがこのチャンネルに自己割り当てすることを許可 * `--no-self-assign` デバイスがこのチャンネルに自己割り当てすることを禁止 * `--disable-auto-update STRATEGY` このチャンネルの自動更新戦略を無効化 可能なオプション: major, minor, metadata, none * `--apikey [key]` アカウントにリンクするAPIキー ## 更新無効化戦略 古いバージョンの更新を無効化する方法がいくつかあります\ Capgoはネイティブコードを更新できないため、古いネイティブコードを持つバージョンから更新されたネイティブコードを持つバージョンへの更新はできないようにする必要があります これを実現するには複数の方法があります まず、`major`戦略 これは`000`から`100`への更新を防ぎます メジャーは強調表示された数字(**1**00と**0**00)です\ 次に、`minor`戦略 これは`000`から`110`への更新や`110`から`120`への更新を防ぎます **注意**この戦略は`010`から`110`への更新は防げません 3番目に、`patch`戦略 これはとても厳格なモードとしてcapgoに追加されました 完全に動作を理解している場合を除き、使用は推奨されません 更新を許可するには、以下の条件を満たす必要があります: * 新旧バージョン間でメジャーバージョンが同じ * 新旧バージョン間でマイナーバージョンが同じ * 新バージョンのパッチが旧バージョンのパッチより大きい 以下は更新が許可または拒否されるシナリオの例です * 00311 -> 00314 ✅ * 000 -> 00314 ✅ * 00316 -> 00314 ❌ * 01312 -> 00314 ❌ * 10312 -> 00314 ❌ 最後に最も複雑な戦略である`metadata`戦略\ まず知っておく必要があるのは、有効化した直後は必要なメタデータがチャンネルにないため更新は**失敗する**ということです\ チャンネルにメタデータがない場合、このようなメッセージが表示されます: ![Cannot find metadata](/fail-metadata.webp) このように表示された場合、失敗しているチャンネルの現在のバンドルにメタデータを設定する必要があることがわかります\ まず、どのチャンネルが失敗しているかを特定します。`misconfigured`列を確認することでわかります ![Misconfigured table](/misconfigured-table.webp) 失敗しているチャンネルに移動し、`Bundle number`をクリックしてください。これでバンドルページに移動します。 ![Locate failing channel](/fail-channel-show.webp) そこで`Minimal update version`フィールドに入力します。これは[semver](https://devhints.io/semver/)である必要があります。\ 入力値がsemverでない場合はエラーが表示されますが、すべて正しければ次のように表示されるはずです: ![Set min version](/set-min-update-version.webp) 更新するたびにこのデータを手動で設定したくないかもしれません。幸いなことに、CLIはこのメタデータなしでの更新を防止します。 ![CLI fail no metadata](/cli-fail-no-metadata.webp) `metadata`オプションを使用する際にバンドルを正しくアップロードするには、有効なsemverで`--min-update-version`を渡す必要があります。このようになります: ![CLI upload with metadata](/cli-upload-with-metadata.webp) `--min-update-version`は互換性を確保する唯一の方法ではありません。 `--auto-min-update-version`も存在します。これは次のように動作します: まず、チャンネルに現在アップロードされているバージョンを確認します。`bundle compatibility`コマンドと同様に互換性をチェックします。 次に、新しいバージョンが100%互換性がある場合、チャンネル内の最新バージョンの`min_update_version`を再利用します。 そうでない場合、新しくアップロードされたバージョンのバンドル番号を`min_update_version`として設定します。 このオプションを使用する際は、常に`min_update_version`の情報が表示されます。このように表示されます: ![Min update version](/min_update_version_info.webp) 新しいバージョンに互換性がない場合は、このように表示されます: ![Min update version not compatible](/min_update_version_not_compatible.webp) ## エンドツーエンド暗号化(トラストレス) Capgoはエンドツーエンド暗号化をサポートしています。これはバンドル(コード)がクラウドに送信される前に暗号化され、デバイス上で復号化されることを意味します。そのために、RSAキーペアを生成する必要があります。次のコマンドで生成できます。 暗号化システムはRSAとAESの組み合わせで、RSAキーはAESキーの暗号化に使用され、AESキーはファイルの暗号化に使用されます。 暗号化システムの詳細については以下をご覧ください: ![How crypto works](/crypto_explained.webp) 暗号化スキーマ ### アプリのキーを作成する `npx @capgo/cli key create` オプションで、`--force`を指定して既存のキーを上書きできます。このコマンドはアプリにキーペアを作成し、プライベートキーを安全な場所に保存するよう促します。プライベートキーはgitにコミットせず、誰とも共有しないことをお勧めします。 > ローカルでテストした後、設定ファイルからキーを削除し、`key save`でCIステップに追加してください。 ### アプリ設定にキーを保存する `npx @capgo/cli key save` オプションで以下を指定できます: `--key [/path/to/my/private_key]` プライベートキーのパス `--key-data [privateKey]` インラインで使用する場合のプライベートキーデータ。このコマンドは、推奨に従ってキーをアプリと設定にコミットしなかった場合に便利です。 ## CI統合 作業を自動化するために、GitHub actionsを使用してサーバーにプッシュすることをお勧めします。 [GitHub action チュートリアル](https://capgo.app/blog/automatic-build-and-release-with-github-actions/) ## デモアプリ [GitHub - Cap-go/demo-app](https://github.com/Cap-go/demo-app/) APIキーでCI環境変数を設定することを忘れないでください。 # 0.x から 1.x への CLIアップグレード > 0.xから1.xへのアップグレード方法 CLIに大きな変更はありません 主な破壊的変更は、競合を避けるため、また新しい命名規則に従うため、引数`--version`を`--bundle`に名前変更したことです # 暗号化 > データを新しい暗号化で暗号化する方法 この文書では、新しい暗号化システムでデータを暗号化し、古いシステムを削除する方法について説明します。 新しい暗号化システムについての詳細は[ブログ投稿](/blog/introducing-end-to-end-security-to-capacitor-updater-with-code-signing)をご覧ください。 *** まず、以下のコマンドで新しい鍵ペアを作成します: ```bash npx @capgo/cli key create ``` このコマンドはアプリに新しい鍵ペアを作成します。秘密鍵は安全な場所に保管することが重要です。秘密鍵をソースコントロールにコミットしたり、信頼できない相手と共有したりしてはいけません。 このコマンドは、Capacitorの設定から古い鍵を削除しますが、古い鍵ファイルは削除しません。CLIはこれらを保持し、アプリストアの更新を受け取っていない古いプラグインを使用しているアププリへのライブアップデートの送信を継続できるようにします。これにより移行が容易になります。 移行時に「古いアプリのサポートと移行を容易にするために、新しいチャンネルで暗号化を設定しますか?」と尋ねられたら、同意してください。これによりCapacitorの設定に新しい「defaultChannel」オプションが追加されます。これにより、アプリは「encryption\_v2」チャンネルを使用するようになります。これにより、新しい暗号化はそれをサポートするアプリでのみ使用されます。アプリストアの更新を受け取っていないアプリは、以前のデフォルトチャンネルを引き続き使用します。 *** 次に、JSバンドルをビルドして新しいチャンネルにアップロードする必要があります。以下のコマンドを実行してください: ```bash npx @capgo/cli bundle upload --channel encryption_v2 ``` *** その後、アプリが「encryption\_v2」チャンネルに自己割り当てできるようにするために、このコマンドを実行します: Caution これは新しい「defaultChannel」オプションが機能するために必要です ```bash npx @capgo/cli channel set encryption_v2 --self-assign ``` *** これでアプリを実行できます。新しい暗号化システムが使用されます。 古いチャンネルに新しいJSバンドルをアップロードするには、以下のコマンドを実行するだけです: ```bash npx @capgo/cli bundle upload --channel production ``` *** Capacitorの設定については心配する必要はありません。これはCapgoにアップロードされることはありません。 すべてのユーザーがアプリを更新した後(3〜4ヶ月かかる可能性があります)、Capacitorの設定から「defaultChannel」を削除できます。 その後、以下のコマンドで古いチャンネルを削除できます: ```bash npx @capgo/cli channel delete encryption_v2 ``` *** 「encryption\_v2」チャンネルを削除すると、それをデフォルトとして使用していたすべてのアプリは「production」チャンネルを使用し始めます。 # 概要 Capgoのライブアップデート機能を使用して、アプリのJavaScriptバンドルをリアルタイムでリモートに更新し、アプリストアのレビュープロセスを経ることなく、JSの更新を直接ユーザーにプッシュして、バグの修正や新機能の提供を即座に行うことができます。 Note ライブアップデートはJavaScriptバンドルの変更に限定されます。プラグインの追加や削除、ネイティブプロジェクトの設定変更などネイティブコードを更新する必要がある場合は、新しいネイティブバイナリビルドをアプリストアに提出する必要があります。 ## ライブアップデートの仕組み Capgoのライブアップデートシステムには2つの主要なコンポーネントがあります: 1. アプリにインストールするCapgo SDK。SDKは利用可能なアップデートを確認し、バックグラウンドでダウンロードします。 2. 特定のユーザーグループにアップデートを対象とするためのチャンネル。`Production`、`Staging`、`Dev`などの異なるリリーストラックを管理するためにチャンネルを使用できます。 新しいJSバンドルをCapgoにアップロードしチャンネルに割り当てると、そのチャンネル用に設定されたアプリ内のCapgo SDKがアップデートを検出してダウンロードします。アプリが次回再起動する際に、新しいバンドルが読み込まれます。 ## はじめに ライブアップデートを使い始めるには、以下の手順に従ってください: 1. [Capgoクイックスタート](/docs/getting-started/quickstart)を完了して、アプリをCapgoで設定し、Capgo SDKをインストールします。 2. アプリコードで、アプリの初期化が完了した後に`CapacitorUpdater.notifyAppReady()`を呼び出します。これにより、アプリがアップデートを受信する準備ができたことをCapgo SDKに通知します。 3. JSバンドルをビルドしCapgoにアップロードします: ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. アプリを開き、アップデートのダウンロードを待ちます。ステータスは以下のコマンドで確認できます: ```shell npx @capgo/cli@latest app debug ``` 5. アップデートがダウンロードされたら、アプリを閉じて再度開き、新しいバンドルを読み込みます。 詳細については、[ライブアップデートのデプロイ](/docs/getting-started/deploy)ガイドを参照してください。 ## Capgo CLI Capgo CLIは、開発者が独自のCI/CDパイプラインからCapgoのサービスと対話できる強力なツールです。CLIを使用することで、ビルドの作成とデプロイのタイミングを細かく制御でき、既存のエンタープライズワークフローにCapgoを統合することができます。 ### Capgo CLIの用途 Capgo CLIは、ライブアップデートワークフローでより多くの制御と柔軟性を必要とする開発者やチーム向けに設計されています。CI/CDパイプラインでCLIを使用することで、以下のことが可能になります: * Capgoの組み込み自動化に頼らず、アップデートのビルドとデプロイのタイミングを正確に決定できます * ビルドとデプロイのステップの間に、コード署名、QAテスト、マネージャーの承認など、独自のプロセスを挿入できます * 既存のDevOpsツールやワークフローにCapgoを統合できます ### 認証 Capgo CLIを使用するには、APIキーで認証する必要があります。APIキーはCapgoアカウント設定で生成できます。 ログインしてAPIキーを安全に保存するには、以下を実行します: ```shell npx @capgo/cli@latest login [API_KEY] ``` このコマンドは将来の使用のために保存されます。ログイン後は、各コマンドでAPIキーを提供する必要はありません。 ### 他のCLIツールとの主な違い 他のライブアップデートCLIツールに慣れている場合、Capgo CLIについて注意すべき点がいくつかあります: * CapgoはライブアップデートのFeatureセットに特化しているため、開発とCI/CD両方のユースケースで単一のCLIを使用します * Capgo CLIは別途インストールする必要はありません。`@capgo/cli`パッケージにバンドルされており、`npx`を使用して直接実行できます * Capgo CLIはライブアップデートワークフロー向けに特別に設計されているため、より汎用的なCLIツールにある機能やコマンドの一部が含まれていない場合があります ## 次のステップ [ チャンネル](/docs/live-updates/channels/) [異なるリリーストラックを管理し、特定のユーザーにアップデートを対象とするためのチャンネルの使用方法を学びます](/docs/live-updates/channels/) [ ロールバック](/docs/live-updates/rollbacks/) [アップデートに問題が発生した場合に、以前のJSバンドルバージョンにロールバックする方法を発見します](/docs/live-updates/rollbacks/) [ アップデートの動作](/docs/live-updates/update-behavior/) [アプリでのアップデートのダウンロードと適用のタイミングと方法をカスタマイズします](/docs/live-updates/update-behavior/) [ 高速アップデート](/docs/live-updates/differentials/) [アップデートプロセスを高速化するための高速アップデートの使用方法を学びます](/docs/live-updates/differentials/) # 概要 > CapgoのCLIコマンドに関する詳細なドキュメント Capgo CLIは、Capgoアプリとデプロイメントを管理するためのコマンドセットを提供します。このリファレンスでは、各利用可能なコマンドについて、そのオプションと使用例を含む詳細な情報を提供します。 ## コマンド [ init](/docs/cli/reference/init/) [新しいCapgoアプリを初期化](/docs/cli/reference/init/) [ login](/login/) [Capgoサービスで認証](/login/) [ doctor](/docs/cli/reference/doctor/) [潜在的な問題についてCapgoセットアップをチェック](/docs/cli/reference/doctor/) [ app](/docs/cli/reference/app/) [Capgoアプリを管理](/docs/cli/reference/app/) [ bundle](/docs/cli/reference/bundle/) [アプリバンドルを管理](/docs/cli/reference/bundle/) [ channel](/docs/cli/reference/channel/) [リリースチャンネルを管理](/docs/cli/reference/channel/) [ key](/docs/cli/reference/key/) [アプリ署名キーを管理](/docs/cli/reference/key/) ## CI統合 作業を自動化するために、GitHub Actionsを使用してCapgoに更新をプッシュすることをお勧めします。詳細については、[GitHub Actionsチュートリアル](https://capgo.app/blog/automatic-build-and-release-with-github-actions/)をご覧ください。 CI環境変数にCapgo APIキーを設定することを忘れないでください。 ## デモアプリ CI統合を含むCapgoアプリの完全な例については、[GitHubのデモアプリ](https://github.com/Cap-go/demo-app/)をご確認ください。 # アカウント `account` コマンドを使用してCapgoアカウントを管理できます ### id `npx @capgo/cli account id` アカウントIDを取得します オプション: * `-a, --apikey `: アカウントにリンクするAPIキー # アプリ `app`コマンドでCapgoアプリを管理できます ### add `npx @capgo/cli app add [appId]` Capgoアカウントに新しいアプリを追加します `[appId]`は`comexampleapp`形式のアプリIDです。詳細は[Capacitorドキュメント](https://capacitorjs.com/docs/cli/commands/init/)を参照してください > 💡 提供されていない場合、すべてのオプションは`capacitorconfigjson`から推測されます オプション: * `--icon [path]`: Capgoウェブアプリに表示するカスタムアイコンへのパス * `--name [name]`: アプリリストに表示するカスタム名 * `--apikey [key]`: アカウントにリンクするAPIキー * `--retention [days]`: アプリバンドルの保持期間(日数)(デフォルト: 0 = 無制限) ### set `npx @capgo/cli app set [appId]` Capgoアカウントの既存のアプリを更新します オプション: * `--icon [path]`: Capgoウェブアプリに表示するカスタムアイコンへのパス * `--name [name]`: アプリリストに表示するカスタム名 * `--retention [days]`: アプリバンドルの保持期間(日数)(デフォルト: 0 = 無制限) * `--apikey [key]`: アカウントにリンクするAPIキー ### list `npx @capgo/cli app list [appId]` Capgoアカウントのすべてのアプリを一覧表示します オプション: * `--apikey [key]`: アカウントにリンクするAPIキー ### delete `npx @capgo/cli app delete [appId]` Capgoアカウントからアプリを削除します オプション: * `--apikey [key]`: アカウントにリンクするAPIキー * `--bundle`: 特定のバンドルバージョンのみを削除 ### debug `npx @capgo/cli app debug [appId]` アプリのデバッグ情報を表示します オプション: * `--apikey [key]`: アカウントにリンクするAPIキー * `--device`: 特定のデバイスをデバッグ ### setting `npx @capgo/cli app setting [path]` アプリのCapacitor設定を編集します `[path]`は変更したい設定へのパスです(例:`appId`や`pluginsCapacitorUpdaterautoUpdate`) `--string`または`--bool`のいずれかを指定する必要があります: * `--string `: 設定を文字列値に設定 * `--bool `: 設定をブール値に設定 # バンドル `bundle`コマンドでアプリバンドルを管理できます ### upload `npx @capgo/cli bundle upload [appId]` アプリの新しいバンドルをアップロードします オプション: * `-a, --apikey `: アカウントにリンクするAPIキー * `-p, --path `: アップロードするフォルダのパス(デフォルトでは`capacitorconfig`の`webDir`) * `-c, --channel `: バンドルをリンクするチャンネル * `-e, --external `: Capgo Cloudにアップロードする代わりに外部URLにリンク * `--iv-session-key `: 外部バンドルURLのIVとセッションキーを設定 * `--s3-region `: S3バケットのリージョン * `--s3-apikey `: S3エンドポイントのAPIキー * `--s3-apisecret `: S3エンドポイントのAPIシークレット * `--s3-endpoint `: S3エンドポイントのURL * `--s3-bucket-name `: S3バケットの名前 * `--s3-port `: S3エンドポイントのポート * `--no-s3-ssl`: S3アップロード用のSSLを無効化 * `--key `: 公開署名キーのカスタムパス(v1システム) * `--key-data `: 公開署名キーデータ(v1システム) * `--key-v2 `: 秘密署名キーのカスタムパス(v2システム) * `--key-data-v2 `: 秘密署名キーデータ(v2システム) * `--bundle-url`: バンドルURLを標準出力に出力 * `--no-key`: 署名キーを無視して未署名のアップデートを送信 * `--no-code-check`: ソースコードの`notifyAppReady()`とルートフォルダの`indexhtml`のチェックをスキップ * `--display-iv-session`: アップデートの暗号化に使用されるIVとセッションキーを表示 * `-b, --bundle `: アップロードするバンドルのバージョン番号 * `--min-update-version `: このアップデートを適用するために必要な最小アプリバージョン(メタデータで自動アップデートが無効化されている場合のみ使用) * `--auto-min-update-version`: ネイティブパッケージバージョンに基づいて最小アップデートバージョンを自動設定 * `--ignore-metadata-check`: アップロード時のメタデータ(node\_modules)チェックを無視 * `--ignore-checksum-check`: アップロード時のチェックサムチェックを無視 * `--timeout `: アップロードプロセスのタイムアウト(秒) * `--multipart`: S3へのデータアップロードにマルチパートプロトコルを使用(非推奨、代わりに`--tus`を使用) * `--tus`: tusプロトコルを使用してバンドルをアップロード * `--tus-chunk-size `: tusアップロードのチャンクサイズ * `--partial`: 変更されたファイルのみをCapgo Cloudにアップロード * `--partial-only`: 圧縮ファイルをスキップして部分ファイルのみをCapgo Cloudにアップロード(大きなバンドルに有用) * `--encrypted-checksum `: 外部バンドルの暗号化されたチェックサム(署名) * `--auto-set-bundle`: `capacitorconfigjson`のバンドルバージョンを自動設定 * `--dry-upload`: 実際のファイルアップロードを行わないアップロードプロセスのドライラン(テスト用) * `--package-json `: `packagejson`ファイルへのパスのカンマ区切りリスト(モノレポ用) * `--node-modules `: `node_modules`ディレクトリへのパスのカンマ区切りリスト(モノレポ用) * `--encrypt-partial`: 部分アップデートファイルを暗号化 * `--delete-linked-bundle-on-upload`: アップロード前にターゲットチャンネルの現在リンクされているバンドルを削除 ### compatibility `npx @capgo/cli bundle compatibility [appId]` 特定のチャンネルとバンドルの互換性をチェック オプション: * `-a, --apikey `: アカウントにリンクするAPIキー * `-c, --channel `: 互換性をチェックするチャンネル * `--text`: 結果を絵文字ではなくテキストとして出力 * `--package-json `: `packagejson`ファイルへのパスのカンマ区切りリスト(モノレポ用) * `--node-modules `: `node_modules`ディレクトリへのパスのカンマ区切りリスト(モノレポ用) ### delete `npx @capgo/cli bundle delete [bundleId] [appId]` アプリからバンドルを削除 オプション: * `-a, --apikey `: アカウントにリンクするAPIキー ### list `npx @capgo/cli bundle list [appId]` アプリの全バンドルをリスト表示 オプション: * `-a, --apikey `: アカウントにリンクするAPIキー ### cleanup `npx @capgo/cli bundle cleanup [appId]` メジャーバージョンの古いバンドルをクリーンアップし、指定された数の最新バンドルを保持 オプション: * `-b, --bundle `: クリーンアップするメジャーバージョン番号 * `-a, --apikey `: アカウントにリンクするAPIキー * `-k, --keep `: 保持するバンドル数(デフォルト: 4) * `-f, --force`: 確認なしで強制削除 ### decrypt `npx @capgo/cli bundle decrypt [zipPath] [sessionKey]` 署名付きZIPバンドルを復号化 オプション: * `--key `: 秘密署名キーのカスタムパス * `--key-data `: 秘密署名キーデータ ### encrypt `npx @capgo/cli bundle encrypt [zipPath]` ZIPバンドルを暗号化 オプション: * `--key `: 秘密署名キーのカスタムパス * `--key-data `: 秘密署名キーデータ ### encryptV2 `npx @capgo/cli bundle encryptV2 [zipPath] [checksum]` 新しい暗号化方式でZIPバンドルを暗号化 オプション: * `--key `: 秘密署名キーのカスタムパス * `--key-data `: 秘密署名キーデータ * `-j, --json`: 結果をJSONとして出力 ### decryptV2 `npx @capgo/cli bundle decryptV2 [zipPath] [checksum]` 新しい暗号化方式でZIPバンドルを復号化 オプション: * `--key `: 秘密署名キーのカスタムパス * `--key-data `: 秘密署名キーデータ * `--checksum `: 整合性を確認するバンドルのチェックサム ### zip `npx @capgo/cli bundle zip [appId]` バンドル用のZIPファイルを生成 オプション: * `-p, --path `: ZIPするフォルダのパス(デフォルトでは`capacitorconfig`の`webDir`) * `-b, --bundle `: ファイル名に使用するバンドルバージョン番号 * `-n, --name `: ZIPのカスタムファイル名 * `-j, --json`: 結果をJSONとして出力 * `--no-code-check`: ソースコードの`notifyAppReady()`とルートフォルダの`indexhtml`のチェックをスキップ * `--key-v2`: 新しい暗号化方式(v2)を使用 * `--package-json `: `packagejson`ファイルへのパスのカンマ区切りリスト(モノレポ用) # チャネル `channel`コマンドを使用してリリースチャンネルを管理できます ### add `npx @capgo/cli channel add [channelId] [appId]` アプリの新しいチャンネルを作成します オプション: * `-d, --default`: 新しいチャンネルをデフォルトチャンネルとして設定 * `-a, --apikey `: アカウントにリンクするAPIキー ### delete `npx @capgo/cli channel delete [channelId] [appId]` アプリからチャンネルを削除します オプション: * `-a, --apikey `: アカウントにリンクするAPIキー * `--delete-bundle`: チャンネルに関連付けられたバンドルを削除 ### list `npx @capgo/cli channel list [appId]` アプリのすべてのチャンネルを一覧表示します オプション: * `-a, --apikey `: アカウントにリンクするAPIキー ### currentBundle `npx @capgo/cli channel currentBundle [channel] [appId]` 特定のチャンネルの現在のバンドルを取得します オプション: * `-c, --channel `: 現在のバンドルを取得するチャンネル * `-a, --apikey `: アカウントにリンクするAPIキー * `--quiet`: バンドルバージョンのみを表示 ### set `npx @capgo/cli channel set [channelId] [appId]` チャンネルのプロパティを設定します オプション: * `-a, --apikey `: アカウントにリンクするAPIキー * `-b, --bundle `: チャンネルに設定するバンドルのバージョン番号 * `-s, --state `: チャンネルの状態を設定(`default`または`normal`) * `--latest`: バンドルバージョンとして`packagejson`の最新バージョンを使用 * `--downgrade`: ネイティブバージョンより下のバージョンへのダウングレードを許可 * `--no-downgrade`: ネイティブバージョンより下のバージョンへのダウングレードを無効化 * `--upgrade`: ネイティブバージョンより上のバージョンへのアップグレードを許可 * `--no-upgrade`: ネイティブバージョンより上のバージョンへのアップグレードを無効化 * `--ios`: iOSデバイスへの更新送信を許可 * `--no-ios`: iOSデバイスへの更新送信を無効化 * `--android`: Androidデバイスへの更新送信を許可 * `--no-android`: Androidデバイスへの更新送信を無効化 * `--self-assign`: デバイスのこのチャンネルへの自己割り当てを許可 * `--no-self-assign`: デバイスのこのチャンネルへの自己割り当てを無効化 * `--disable-auto-update `: このチャンネルの自動更新戦略を無効化(オプション:`major`、`minor`、`metadata`、`patch`、`none`) * `--dev`: 開発デバイスへの更新送信を許可 * `--no-dev`: 開発デバイスへの更新送信を無効化 * `--emulator`: エミュレータデバイスへの更新送信を許可 * `--no-emulator`: エミュレータデバイスへの更新送信を無効化 * `--package-json `: `packagejson`ファイルのパスをカンマ区切りで指定(モノレポの場合に便利) # 医師 `npx @capgo/cli doctor` このコマンドは、Capgoパッケージの最新バージョンを使用しているかどうかを確認します。 バグレポートにも役立ちます。 # 初期化 `npx @capgo/cli@latest init [apikey]` このコマンドでは、以下の手順でステップバイステップの設定を行います: 1. アプリをCapgoに追加 2. アップデートを検証するためのコードをアプリに追加 3. アプリのビルド 4. アプリをCapgoにアップロード 5. アップデートが正常に機能するかの確認をサポート # 鍵 `key` コマンドでアプリの署名キーを管理できます ### save `npx @capgo/cli key save` base64エンコードされた暗号化キーをCapacitorの設定に保存します(CIで便利) オプション: * `-f, --force`: 新しいキーの生成を強制 * `--key`: Capacitorの設定に保存するキーファイルのパス * `--key-data`: Capacitorの設定に直接保存するキーデータ ### create `npx @capgo/cli key create` 新しい暗号化キーを作成します オプション: * `-f, --force`: 新しいキーの生成を強制 ### delete\_old `npx @capgo/cli key delete_old` 古い暗号化キーを削除します # ログイン `npx @capgo/cli login [apikey]` このコマンドは、将来使用するためにCapgo APIキーを保存します Note `--apikey=`を任意のコマンドに渡すことで、保存されたAPIキーを上書きできます オプション: * `--local`: APIキーをローカルリポジトリに保存し、`gitignore`に追加します # よくある質問 > Capgoについてよくある質問 ここに回答のない質問がある場合は、お気軽にお尋ねください! GitHubで問題を報告するか、[Discord](https://discordcom/invite/VnYRvBfgA6)で質問するのがおすすめです。 ### コードプッシュとは? コードプッシュ(「OTA(Over The Air)アップデート」とも呼ばれる)は、Capacitorの開発者が本番環境のアプリをアップデートできるようにするクラウドサービスです。Capgoは現在AndroidとiOSで動作し、将来的にはCapacitorが動作する全てのプラットフォームで動作する予定です。 「Code Push」という名称は、React Nativeコミュニティで使用されている[Microsoft](https://appcenterms/)と[Expo](https://expodev/)のデプロイ機能に由来しますが、これらはCapacitorをサポートしていません。 ### バンドルとリリースの違いは? 「リリース」とは、アプリストア向けにバイナリを準備することを指します。後でバンドルを生成するために、Capgoはアプリストアに配信された正確なバイナリを把握する必要があります。 「バンドル」とは、リリースに適用して新しいコードに更新できるパッチを指します。`npx @capgo/cli app update`コマンドを使用して、ローカルの新しいコードからバンドルを生成し、ユーザーに配信します。 ### ロードマップは? プロジェクトボードは公開されており、こちらで確認できます: [https://github.com/orgs/Cap-go/projects](https://github.com/orgs/Cap-go/projects/) チームも公開で活動しているため、いつでも取り組んでいることを確認できます。ロードマップや優先順位についての質問は、GitHubのissueや[Discord](https://discordcom/invite/VnYRvBfgA6)で喜んでお答えします。 ### チームでCapgoを使用できますか? はい! 全てのプランで開発者数は無制限です。組織ごとにアプリのメトリクス(MAU、ストレージ、帯域幅)のみを制限しています。 詳細は[Teams](https://capgo.app/pricing/)をご覧ください。 ### Capgoはソースコードを保存しますか? いいえ。Capgoのサーバーがソースコードを見ることはありません。`npx @capgo/cli app update`を実行すると、`npx @capgo/cli`ツールはアプリストアに送信するのと同じコンパイル済みコードのみをアップロードします。さらなるセキュリティが必要な場合は、エンドツーエンドの暗号化を使用してCapgoサーバーにアップロードする前にバンドルを暗号化できます。 プライバシーポリシーもご覧ください: [https://capgo.app/privacy](https://capgo.app/privacy/) ### CIシステムからCapgoを使用できますか? はい。CapgoはCIシステムからの使用を想定しています。[AndroidとGithub Actions](https://capgo.app/blog/automatic-capacitor-android-build-github-action/)と[IOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/)、[Gitlab](https://capgo.app/blog/setup-ci-and-cd-gitlab/)のガイドを公開しています。他のCIシステムも同様の方法で設定できるはずです。 問題が発生した場合は、GitHubのissueやDiscordでお気軽にご連絡ください。 ### Firebase Remote ConfigやLaunch Darklyとの関係は? コードプッシュはデバイス上のコードを追加/置換することができます。Firebase Remote ConfigとLaunch Darklyはどちらも設定システムです。新しいバージョンをリリースすることなくアプリの設定を変更できますが、コードを置き換えることは想定されていません。 ### 依存関係のフットプリントはどれくらいですか? 最近測定していませんが、コードプッシュライブラリはCapacitorアプリに1MB未満しか追加しないと予想されます。必要になれば、さらに小さくする方法も把握しています。サイズが課題となる場合は、ぜひお知らせください! ### コードプッシュは大規模なアプリケーションでも動作しますか? はい。コードプッシュでアップデートできるアプリケーションのサイズに制限はありません。[以下](https://capgo.app/docs/faq/#what-types-of-changes-does-capgo-code-push-support)に記載の通り、Capgoはサイズに関係なくアプリケーション内のすべてのJSコードを変更できます。 注意: サイズが大きいとユーザーがアップデートをダウンロードしにくくなります。できるだけアプリを小さく保つことをお勧めします。 ### Capgoコードプッシュは何に使用できますか? 以下のような様々な用途で使用されています: * 本番アプリの緊急修正 * 古いバージョンのアプリユーザーへのバグ修正の配信 * 定期的な配信(例: 1時間ごと) ほとんどのアプリストアでは、アプリの動作を大きく変更するコードの配信は禁止されています。詳細は[以下](https://capgo.app/docs/faq/#how-does-this-relate-to-the-appplay-store-review-process-or-policies)をご覧ください。 ### CapgoのMAUとは何ですか? MAUは「月間アクティブユーザー」です。過去30日以内にサーバーにアクセスしたデバイスをMAUとしてカウントします。過去30日以内にサーバーにアクセスしていないデバイスはカウントしません。 ユーザーがアプリを再インストールするたびに新しいMAUとしてカウントされます。これはAppleストアのプライバシー制限によるものです。アプリが再インストールされた場合、同じデバイスを追跡できません。 開発中は、アプリを再インストールするたびに新しいMAUがカウントされます。 TestFlightのダウンロードやAndroidでのチャンネル切り替えも同様です。アプリのアップデートでは新しいDevice IDは作成されません。 > 初期設定後は、重複したデバイスの数を減らすため、開発用デバイスとエミュレータを無効にすることをお勧めします。 ### Capgoコードプッシュで使用できないものは? 上記の通り、Capgoはアプリストアのポリシーに違反する用途には使用しないでください。詳細は[以下](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines)をご覧ください。 また、Capgoはネイティブコード(AndroidのJava/KotlinやiOSのObjective-C/Swiftなど)の変更をサポートしていません。ネイティブコードを変更しようとすると、アップデート時にツールが警告を表示します。 ### Capgoはストアへの提出を代行しますか? 現在、Capgoはアプリストアへの提出を代行するサポートは行っていません。将来的には追加する予定ですが、現時点では既存のプロセスを使用してアプリストアに提出する必要があります。 このプロセスを自動化するには、[Android用CIガイド](https://capgo.app/blog/automatic-capacitor-android-build-github-action/)と[iOS用CIガイド](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/)をご利用ください。 ### Capgoはディスク上に何を保存しますか? Capgoアップデーター(アプリのビルド時に含まれる)は、最新のダウンロードされたバンドルをCapacitorがコードの読み込みを許可する唯一のディレクトリにキャッシュします。Androidでは`/data/user/0/comexampleapp/code_cache/capgo_updater`にありますが、このパスのベースはAndroidシステムによって提供され、実行時に動的に変更される可能性があります。iOSデバイスでは、データは`Library/Application Support/capgo`に保存されます。 Capgoコマンドラインツール(例:`npx @capgo/cli app update`)はディスク上のnpmキャッシュにインストールされ、ログイン情報はホームディレクトリの`~/capgo`に保存されます ### CapacitorのHot Reloadとの関係は?[](https://capgo.app/docs/faq/#how-does-this-relate-to-capacitor-hot-reload "Direct link to How does this relate to Capacitor Hot Reload?") Capacitorのホットリロードは開発時のみの機能です。Code pushは本番環境用です。 ホットリロードはCapacitorの機能で、開発中にデバイス上のコードを変更することができます。ローカルマシンに接続するためのプロキシを使用してCapacitorアプリをビルドする必要があります。 Code pushは本番環境でデバイス上のコードを変更できる機能です。プラットフォームに応じて様々な手法を使用して実現しています。 ### Capgo code pushはどのような変更をサポートしていますか?[](https://capgo.app/docs/faq/#what-types-of-changes-does-capgo-code-push-support "Direct link to What types of changes does Capgo code push support?") CapgoはアプリケーションのすべてのJSコードを変更できます。アプリコードと生成コードの両方が含まれます。ネイティブコードの変更が必要ない限り、`packages.json`の依存関係も更新できます。 ネイティブコード(AndroidのJava/KotlinやiOSのObjective-C/Swiftなど)の変更はサポートする予定はなく、ネイティブコードの変更を検出した場合はバンドルに含まれないため警告が表示されます。 ### Webはサポートしていますか?[](https://capgo.app/docs/faq/#does-this-support-web "Direct link to Does this support Flutter Web?") Webの場合はcode pushは不要です。Webはすでにこの方法で動作しているためです。ユーザーがWebアプリを開くと、必要に応じて最新バージョンをサーバーからダウンロードします。 WebでCode pushのユースケースがある場合は、ぜひ教えてください! ### iOS、Android、Mac、Windows、Linux等で動作しますか?[](https://capgo.app/docs/faq/#will-this-work-on-ios-android-mac-windows-linux-etc "Direct link to Will this work on iOS, Android, Mac, Windows, Linux, etc?") はい。 今のところAndroidとiOSのサポートに注力していますが、最終的にはCapacitorが動作するすべてのプラットフォームで動作するようになります。より多くのプラットフォームに展開する前に、code pushを確実に、安全に提供するために必要なインフラを整備しています。 ### CapgoはどのOSバージョンをサポートしていますか?[](https://capgo.app/docs/faq/#what-os-versions-does-capgo-support "Direct link to What OS versions does Capgo support?") CapgoはCapacitorがサポートしているのと同じAndroidバージョンをサポートしています。 現在、CapacitorはAndroid APIレベル22以上とiOS 13.0以上をサポートしています: [https://capacitorjs.com/docs/main/reference/support-policy](https://capacitorjs.com/docs/main/reference/support-policy/) ### CapgoはどのバージョンのCapacitorをサポートしていますか?[](https://capgo.app/docs/faq/#what-versions-of-flutter-does-capgo-support "Direct link to What versions of Flutter does Capgo support?") Capgoは現在、Capacitorの最新の安定版のみをサポートしています。古いバージョンのCapacitorもサポートすることは可能ですが、そのために必要なインフラをまだ構築していません。将来的には、エンタープライズ顧客向けを含め、より多くのバージョンのCapacitorをサポートする予定です。[https://github.com/Cap-go/capgo/issues/1100](https://github.com/Cap-go/capgo/issues/1100/) CapgoはCapacitorの安定版に追従しており、通常安定版のリリースから数時間以内に更新されます。更新のシステムは自動化されており、実行には数分かかります。その後、サーバーに公開する前に追加の手動検証ステップを実施しています。 ### App/Play Storeのレビュープロセスやポリシーとの関係は?[](https://capgo.app/docs/faq/#how-does-this-relate-to-the-appplay-store-review-process-or-policies "Direct link to How does this relate to the App/Play Store review process or policies?") 開発者は、それらのストアを使用することを選択した場合、ストアプロバイダーとの契約に拘束されます。Code pushは、開発者がiOSとAndroidのストアポリシーに準拠しながらアプリを更新できるように設計されています。React Nativeで利用可能な様々な商用製品([Microsoft](https://appcenter.ms/)、[Expo](https://expo.dev/)など)と同様です。 Microsoftも、彼らのソリューションがアプリストアにどのように準拠しているかについてのガイドを公開しています: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) Code pushはアプリストア全体で広く使用されている技術です。私が知っている主要なアプリはすべてcode pushを使用しています。注意すべき主要なポリシーは、アプリの動作を大幅に変更しないことです。詳細については[以下](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines)を参照してください。 ### CapgoはPlay Storeのガイドラインに準拠していますか?[](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines "Direct link to Does Capgo comply with Play Store guidelines?") はい。 Play Storeは更新ツールに関して2つの制限を設けています。 1. 更新はインタープリターまたは仮想マシンを使用する必要があります(CapgoはDart Virtual Machineを使用します) [https://support.google.com/googleplay/android-developer/answer/9888379?hl=en](https://support.google.com/googleplay/android-developer/answer/9888379/?hl=en) ```plaintext Google Play経由で配布されるアプリは、Google Playの更新メカニズム以外の方法で
自身を変更、置換、更新することはできません。同様に、アプリは
Google Play以外のソースから実行可能コード(dex、JAR、soファイルなど)を
ダウンロードすることはできません。*この制限は、Android APIへの
間接的なアクセスを提供する仮想マシンまたはインタープリターで実行される
コード(webviewまたはブラウザのJavaScriptなど)には適用されません*

実行時にロードされる(つまり、アプリにパッケージングされていない)
インタープリター言語(JavaScript、Python、Luaなど)を使用するアプリまたは
サードパーティのコード(SDKなど)は、Google Playポリシーの違反の
可能性を許可してはなりません
``` 2. アプリの変更は欺瞞的であってはなりません(例:更新を通じてアプリの目的を変更するなど) [https://support.google.com/googleplay/android-developer/answer/9888077](https://support.google.com/googleplay/android-developer/answer/9888077/) アプリケーションで提供するものについてユーザーに明確に説明し、Capgoを使用して重要な動作変更を行うことでユーザーの期待を裏切らないようにしてください。 CapgoはPlay Storeのガイドラインに準拠するように設計されています。ただし、Capgoはツールであり、どのようなツールでも悪用される可能性があります。意図的にCapgoを悪用してPlay Storeのガイドラインに違反することは、Capgoの[利用規約](https://capgo.app/tos/)に違反し、アカウントの停止につながる可能性があります。 最後に、code pushサービスは業界で広く使用されており(私が知っている主要なアプリはすべて使用しています)、他にも複数のcode pushサービスが公開されています(例:expo.devやappcenter.ms)。これは十分に確立された道です。 Microsoftも、彼らのReact Native “codepush”ライブラリがアププストアにどのように準拠しているかについてのガイドを公開しています: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### CapgoはApp Storeのガイドラインに準拠していますか?[](https://capgo.app/docs/faq/#does-capgo-comply-with-app-store-guidelines "Direct link to Does Capgo comply with App Store guidelines?") はい。 Play Storeと同様に、App Storeも技術的およびポリシーの制限を設けています。 ```plaintext 3.2.2
解釈されたコードはアプリケーションにダウンロードできますが、以下の条件を満たす場合に限ります:

(a) App Storeに提出された際のアプリケーションの意図された目的や宣伝された目的と矛盾する機能を提供することにより、アプリケーションの主要な目的を変更しない

(b) 他のコードやアプリケーション用のストアやストアフロントを作成しない

(c) OSの署名、サンドボックス、その他のセキュリティ機能を迂回しない CapgoはiOS上での更新に関する解釈専用の制限に準拠するために、カスタムのDartインタプリタを使用します。更新を通じて不正な動作(例:更新によりアプリの目的を変更する)を行わない限り、Capgo(または他のコードプッシュソリューション)を通じた更新は標準的な業界慣行であり、App Storeのガイドラインに準拠しています。 意図的にApp Storeのガイドラインに違反するためにCapgoを悪用することは、Capgoの[利用規約](https://capgo.app/tos/)に違反し、アカウントの停止につながる可能性があります。 MicrosoftもReact Nativeの「codepush」ライブラリがアプリストアにどのように準拠しているかについてのガイドを公開しています: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### 自分の国でCapgoを使用できますか?[](https://capgo.app/docs/faq/#can-i-use-capgo-in-my-country "Direct link to Can I use Capgo in my country?") いかなる国からのCapgoへのアクセスも制限していません。 一部の国ではその国内からアクセスできるURLに制限があることを認識しています。現在、CapgoはCloudflare Cloud(R2ストレージとCloudflareワーカーを含む)をホスティングに使用しています。 Capgoは以下のURLを使用します: - [https://apicapgo.app](https://apicapgo.app/) -- `npx @capgo/cli`コマンドラインツールがCapgoサーバーと対話するため、およびユーザーのデバイス上のCapgoアップデーターが更新を確認するために使用 - [https://*r2cloudflarestoragecom](https://*r2cloudflarestoragecom/) -- `npx @capgo/cli`コマンドラインツールがバンドルのアップロードとダウンロードに使用 これらのURLすべてがあなたの国からアクセス可能であれば、Capgoは動作するはずです。 あなたの地域でこれらのURLへのアクセスをブロックする必要がある場合は、お知らせください。解決策を見つけるためにご協力させていただきます。プロキシサーバーは一つの選択肢です。 ### Capgoをセルフホストできますか?[](https://capgo.app/docs/faq/#can-i-self-host-capgo "Direct link to Can I self-host Capgo?") はい、Capgoをセルフホストできます。ガイドはまだ作成されていませんが、コードはオープンソースで[https://github.com/cap-go/capgo](https://github.com/cap-go/capgo/)で利用可能です。 ### コードプッシュは動作にインターネットが必要ですか?[](https://capgo.app/docs/faq/#does-code-push-require-the-internet-to-work "Direct link to Does code push require the internet to work?") はい。一般のインターネットとは別に更新を配信するサーバーを運用することも考えられますが、デバイスに更新を配信するには何らかのネットワーク接続が必要です。 ### ネットワーク接続がない場合、Capgoはどうなりますか?[](https://capgo.app/docs/faq/#how-is-capgo-affected-by-lack-of-network-connectivity "Direct link to How is Capgo affected by lack of network connectivity?") Capgoアップデーター(Capgoでアプリをビルドする際にアプリケーションに含まれる)は、ネットワーク接続の問題に対して耐性があるように設計されています。 デフォルトの更新動作では、アプリケーションが起動すると、Capgoアップデーターに通知され、別のスレッドを生成してCapgoサーバーにネットワークリクエストを送信し、更新を確認します。アプリケーションが実行している他の処理をブロックしないように、意図的に別のスレッドを使用しています。ネットワークリクエストが失敗またはタイムアウトした場合、アップデーターは次回のアプリケーション起動時に再度確認を試みます。 Capgoコマンドラインツール(例: `npx @capgo/cli app update`)は動作にネットワーク接続が必要です。Capgoを使用してアプリを配布する場合は、CIシステムにネットワーク接続があることを確認してください。 ### ユーザーが長期間更新しておらず、更新を見逃した場合はどうなりますか?[](https://capgo.app/docs/faq/#what-happens-if-a-user-doesnt-update-for-a-long-time-and-misses-an-update "Direct link to What happens if a user doesn't update for a long time and misses an update?") 私たちの実装では、リクエストを送信したデバイス専用に調整された更新を常に送信し、リクエスト元を常に利用可能な最新バージョンに更新します。そのため、ユーザーが長期間更新しない場合、中間の更新を「見逃す」ことになります。 更新サーバーは、アプリケーションのニーズに応じて、次の増分バージョンまたは最新バージョンのいずれかで応答するように変更できます。代替の更新動作が重要な場合は、お知らせください。 ### CapgoはCapacitorとどのような関係にありますか?[](https://capgo.app/docs/faq/#how-does-capgo-relate-to-capacitor "Direct link to How does Capgo relate to Capacitor?") CapgoはCapacitorのプラグインで、コードプッシュ機能を追加します。CapgoはCapacitorの代替ではありません。すでに知っているCapacitorのツール群を引き続き使用できます。 私たちはCapacitorの最新の安定版リリースを追跡し、コードプッシュプラグインがそれで動作するように更新しています。 ### 更新はいつ行われますか?[](https://capgo.app/docs/faq/#when-do-updates-happen "Direct link to When do updates happen?") デフォルトでは、Capgoアップデーターはアプリ起動時に更新を確認します。バックグラウンドスレッドで実行され、UIスレッドをブロックしません。更新はユーザーがアプリを使用している間にインストールされ、次回アプリを再起動したときに適用されます。 [package:capgo_code_push](https://pubdev/packages/capgo_code_push/)を使用してCapgoアップデーターを手動で実行することも可能で、プッシュ通知を含め、いつでも更新をトリガーできます。 Capgoアップデーターは、ネットワークが利用できない場合やサーバーがダウンしているか到達不能な場合でも、アプリが通常通り動作し続けるように設計されています。サーバーから更新を削除することを選択した場合でも、すべてのクライアントは通常通り動作し続けます。 パッチをロールバックする機能を追加しました。元に戻すには、以前のバンドルをチャンネルに添付するのが最も簡単です。 ### app_idを秘密にしておく必要がありますか?[](https://capgo.app/docs/faq/#do-i-need-to-keep-my-app_id-secret "Direct link to Do I need to keep my app_id secret?") いいえ。`app_id`はアプリに含まれており、公開しても安全です。バージョン管理(公開リポジトリでも)にチェックインしても、他の人がアクセスすることを心配する必要はありません。 あなたの`app_id`を持っている人はCapgoサーバーから最新バージョンのアプリを取得できますが、アプリに更新をプッシュしたり、Capgoアカウントの他の側面にアクセスしたりすることはできません。 ### Capgoサーバーにはどのような情報が送信されますか?[](https://capgo.app/docs/faq/#what-information-is-sent-to-capgo-servers "Direct link to What information is sent to Capgo servers?") Capgoはネットワークに接続しますが、個人を特定できる情報は送信しません。Capgoを含めることで、Play StoreやApp Storeの宣言に影響を与えることはありません。 アプリからCapgoサーバーに送信されるリクエストには以下が含まれます: - app_id (`capacitorconfigjson`で指定) - channel (`capacitorconfigjson`でオプション) - release_version (AndroidManifestxmlのversionNameまたはInfoplistのCFBundleShortVersionString、または[`CapacitorUpdaterversion`](/docs/plugin/settings/#version)で設定されている場合は`capacitorconfigjson`から) - version_number (`npx @capgo/cli app update`の一部として生成) - os_version (例:'1121') - platform (例:'android'、適切なパッチを送信するために必要) これ以外はありません。このコードは`updater/library/src/networkrs`にあります。 - device_id (デバイスの初回実行時に生成され、デバイスごとのインストールの重複を排除し、インストールされたユーザー数に基づいて課金できるようにするために使用)月間アクティブユーザー数)で、パッチの合計数やパッチインストールの合計数ではありません) - custom_id(オプション、開発者が実行時に設定、システム内のデバイスをユーザーにリンクするために使用) ### Capgoはどのプラットフォームをサポートしていますか? 現在、CapgoはiOSとAndroidの両方をサポートしており、両方とも本番環境で使用可能です。 iOSまたはAndroidでのCapgoの使用は、独立した判断が可能です。チャンネルでAndroidへの配信とApp Storeへのipaのビルド、またはその逆を設定できます。 Capgoはデスクトップや組み込みターゲットをサポートすることも(比較的容易に)可能です。これらが重要な場合は、お知らせください。 ### CapgoはPlay Testing TracksやApple TestFlightとどのように連携しますか? アプリストアにはそれぞれ、限定されたユーザーグループにアプリを配布するメカニズム(「内部テスト」、「クローズドベータ」など)があります。これらはすべて、ユーザーをグループに分け、特定のバージョンのアプリを各グループに配布するメカニズムです。 残念ながら、これらのメカニズムの全てが、特定のTest TrackやTestFlightを通じてインストールされたアプリを第三者が検出することを許可していません。そのため、これらのグループの構成を確実に把握することができず、これらのグループに基づいてCapgoパッチへのアクセスを確実に制御することができません。[https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play](https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play/) [https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i](https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i/) Capgoバンドルの利用可能性をセグメント化したい場合、4つのオプションがあります: 1. 各グループに別々のチャンネルを使用する。これは最も直接的なアプローチですが、複数のチャンネルを管理する必要があります。既に異なる可用性を持つ開発チャンネルと本番チャンネルがある可能性があります。そのため、開発チャンネルを更新し、確認してから、本番チャンネルを別途更新することができます。各リリースに関連するソースを追跡するために、バージョン管理でブランチ/タグを使用することをお勧めします。 2. 独自のオプトインユーザーリストを追跡し、自動更新を無効にし、package:capgo_code_pushを介して特定のユーザーに対してのみ更新をトリガーする。これは現在機能していますが、独自のオプトインリストを管理する必要があります。 3. Capgoはデバイスごとに独自のオプトインメカニズムを作成できます(Test TracksやTestFlightと同様に、プラットフォームに依存しない)。これにより、QAチームは一般公開される前にバンドルにオプトインできます。 4. Capgoはパーセンテージベースのロールアウトを持っています。これはどのデバイスに送信するかを選択することはできませんが、段階的にロールアウトし、問題が発生した場合にロールバックするのに役立ちます。 ## 請求 ### プランをアップグレードまたはダウングレードするにはどうすればよいですか? ダッシュボードでいつでもプランをアップグレードまたはダウングレードできます:[https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### 請求期間はいつリセットされますか? 請求期間は、Capgoに最初に登録した月の毎月自動的にリセットされます。例えば、15日に登録した場合、請求期間は毎月15日にリセットされます。 ### サブスクリプションをキャンセルするにはどうすればよいですか? ダッシュボードでいつでもサブスクリプションをキャンセルできます:[https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### 1年分を前払いできますか? ダッシュボードでいつでも可能です:[https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### 統計と分析 ダッシュボードの統計は毎日深夜(UTC)に更新されます。 統計はデバイスにインストールされた[MAU](https://capgo.app/docs/faq/#what-is-the-difference-between-a-bundle-and-a-release)の数に基づいて計算されます。 # デバイスIDの生成方法 デバイスIDは初回起動時にデバイス上で生成され、デバイスごとのインストールの重複を排除し、パッチの合計数やパッチインストールの合計数ではなく、インストールされたユーザー数(月間アクティブユーザー数など)に基づいて課金できるようにするために使用されます。 MAUはCapgoの価格設定において、インストール数よりも優れたソリューションです。より正確で、デバイスごとの実際のCapgoのコストを反映しているためです。 プライバシー上の理由から、ユーザーがアプリを再インストールした場合、同じデバイスを追跡することはできません。 プライバシールールはAppleとGoogleによって強制され、Capgoによって強制されるものではありません。 デバイスIDは、最初のパッチがインストールされるまでデバイスリストに表示されません。 # デバイス数がMAUと異なる理由は? 現在、デバイスリストはMAUほど頻繁に更新されません。 デバイスリストはデバイスが更新をインストールした時のみ更新されます。 一方、MAUはアプリの起動時に毎回更新されます。これはプラットフォームの現在の制限です。アナリティクスプラットフォームは生の更新をサポートしていないため、デバイスリストには従来のデータベースを使用しています。 データベースクエリの数を制限するために、アプリの更新時にのみ行を更新します。 この制限は将来的に解消される予定です。 # プラットフォームごとに異なる更新を行うには? 各プラットフォーム用のチャンネルを作成し、各チャンネルでプラットフォーム固有の更新を無効にすることができます。 iOSチャンネルではAndroid更新を無効にし、Androidチャンネルではios更新を無効にします。 その後、各チャンネルにバンドルをアップロードして、プラットフォームごとに異なる更新を行うことができます。 両プラットフォームで同じ更新が必要な場合は、1つのバンドルを複数のチャンネルにリンクすることができます。バンドルを複製する必要はありません。 ``` # capgoのテクニカルサポート > capgoのヘルプを得る方法 ## Discordでのサポート Capgoには公式の[discordサーバー](https://discordcom/invite/VnYRvBfgA6)があります。テクニカルサポートを受けるには、こちらが最も早い対応を得られる方法の一つです。 簡単な手順は以下の通りです: 1. `questions`チャンネルに移動します ![Ask on discord](/discord-questions.webp) 2. スレッドを作成します ![Create a question on discord](/discord-newquestion.webp) 3. 問題を説明し、関連するタグを選択します ![Create a post on discord](/discord-new-post.webp) 4. セキュアアカウントIDを共有します(任意) これによりCapgoスタッフがあなたのアカウントを確認することができます。このIDは公開することを想定して設計されているため、共有しても安全です。 共有するには、[capgoの設定](https://web.capgo.app/dashboard/settings/account/)に移動してください。そこで`copy account id`をクリックしてください。 ![Share your id without leaking your info](/share-secure-id.webp) これによりセキュアアカウントIDがクリップボードにコピーされます。このIDをDiscordの投稿に含めてください。 ## メールでのサポート これはサポートを受ける最も遅い方法です。まずはDiscordサーバーをご利用ください。 メールでの連絡が必要な場合は、までメールをお送りください。 # アプリを追加する > Capgoアカウントにアプリを追加し、プラグインをアプリにインストールする ## Capgoの紹介 [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## ライブアップデートまであと3ステップ ### ガイド付きセットアップ 1. でアカウントを作成 ![signup screenshot](/signup.webp "signup screenshot") 2. 初期化コマンドを使用して開始 ```bash npx @capgo/cli@latest init [APIKEY] ``` 一連の質問が表示されます。自動セットアップを完了するために必要な回答を提供してください。 Tip これらの手順に従えば、すぐに使用開始できます。プロセス中にさらなるサポートが必要な場合は、サポートチームが[お手伝いします](https://support.capgo.app)。セットアップをお楽しみください! 3. ライブアップデートをデプロイ [ライブアップデートをデプロイ ](/docs/getting-started/deploy/)アプリにライブアップデートをデプロイする方法を学ぶ ### 手動セットアップ 初期化コマンドが機能しない場合は、手動でアプリを追加できます 1. CLIをアカウントに接続: ```bash npx @capgo/cli@latest login [APIKEY] ``` 2. このコマンドでアプリをアカウントに追加: ```bash npx @capgo/cli@latest app add [APP_NAME] ``` 3. アプリにプラグインをインストール: ```json { "plugins": { CapacitorUpdater: { "appId": "Your appID", "autoUpdate": true, "version": "1.0.0" } } } ``` 4. アプリでできるだけ早く初期化メソッドを呼び出す: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; CapacitorUpdater.notifyAppReady(); ``` 5. ライブアップデートをデプロイ [ライブアップデートをデプロイ ](/docs/getting-started/deploy/)アプリにライブアップデートをデプロイする方法を学ぶ # CI/CD インテグレーション CapgoをCI/CDパイプラインに統合することで、アプリのアップデートのビルドとデプロイのプロセスを完全に自動化することができます。Capgo CLIとsemantic-releaseを活用することで、一貫性のある信頼できるデプロイメントを確保し、迅速な反復を可能にします。 ## CI/CD統合のメリット * **自動化**:手動のステップやヒューマンエラーの余地がなくなります。ビルド、テスト、デプロイメントのプロセス全体を端から端まで自動化できます。 * **一貫性**:すべてのデプロイメントが同じ手順に従い、予測可能で再現性のあるプロセスを確保します。これは特に、複数のチームメンバーがコードに貢献している場合に価値があります。 * **迅速な反復**:自動化されたデプロイメントにより、より頻繁に、かつ自信を持ってアップデートをリリースできます。手動のQAやリリース承認を待つ必要がありません。 ## Capgo CLI Capgo CLIは、CapgoをCI/CDワークフローに統合するための鍵となります。新しいバンドルバージョンのプッシュ、チャンネルの管理などのコマンドを提供します。 CI/CD統合で最も重要なコマンドは`upload`です: ```shell npx @capgo/cli@latest bundle upload --channel=Production --apikey YOUR_API_KEY ``` このコマンドは、現在のWebビルドを指定されたチャンネルにアップロードします。通常、Webビルドが正常に完了した後、CI/CDパイプラインの最後のステップとしてこれを実行します。 ## CI/CDパイプラインでのCapgoのセットアップ CI/CDツールの選択によって具体的な手順は異なりますが、Capgoを統合する一般的なプロセスは次のようになります: 1. **APIキーの生成**:Capgoダッシュボードにログインし、新しいAPIキーを作成します。このキーはCI/CD環境でCLIを認証するために使用されます。秘密にし、リポジトリにコミットしないでください! 2. **`upload`コマンドの設定**:CI/CD設定に適切な引数で`upload`コマンドを実行するステップを追加します: uploadyml ```yaml - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secretsCAPGO_API_KEY }} ``` \n `Production`をデプロイしたいチャンネルに、`${{ secretsCAPGO_API_KEY }}`をAPIキーを保持する環境変数に置き換えてください。 3. **Webビルド後に`upload`ステップを追加**:`upload`ステップがWebビルドの完了後に実行されることを確認してください。これにより、常に最新のコードがデプロイされます。\n GitHub Actionsの設定例:\n uploadyml ```yaml name: Deploy to Capgo on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v4 with: node-version: 18 - run: npm ci - run: npm run build - run: npm install -g @capgo/cli - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secretsCAPGO_API_KEY }} ``` ## Semantic-release統合 Semantic-releaseは、バージョン管理の自動化とリリースノートの生成のための強力なツールです。Semantic-releaseとCapgoを統合することで、各デプロイメントでアプリのバージョンを自動的にインクリメントし、変更ログを生成できます。 以下はsemantic-releaseの`releaserc`設定ファイルのサンプルです: ```json { "branches": [ "main", { "name": "beta", "prerelease": true } ], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", [ "@semantic-release/exec", { "publishCmd": "npx @capgo/cli@latest bundle upload --channel=${nextReleasechannel} --apikey YOUR_API_KEY --partial" } ], [ "@semantic-release/git", { "assets": ["CHANGELOGmd", "packagejson"], "message": "chore(release): ${nextReleaseversion} [skip ci]\n\n${nextReleasenotes}" } ] ] } ``` この設定は以下のことを行います: 1. Conventional Commits仕様に従って、次のバージョン番号を決定するためにコミットメッセージを分析します 2. 最後のリリース以降のコミットに基づいてリリースノートを生成します 3. 新しいリリースノートで`CHANGELOGmd`ファイルを更新します 4. Capgo CLIの`upload`コマンドを実行し、新しいバージョン番号を渡し、差分更新用の`--partial`フラグを使用します 5. 更新された`CHANGELOGmd`、`packagejson`、その他の変更されたファイルをリポジトリにコミットします Semantic-releaseをCapgoで使用するには、CI/CD設定に`npx semantic-release`を実行するステップを追加するだけです。このステップがWebビルドの後、Capgoの`upload`ステップの前に来るようにしてください。 ## トラブルシューティング CapgoのCI/CD統合で問題が発生した場合は、以下の点を確認してください: * **APIキー**:APIキーが有効で、必要な権限を持っていることを確認してください。環境変数を使用している場合は、正しく設定されているか再確認してください。 * **CLIバージョン**:最新バージョンのCapgo CLIを使用していることを確認してください。古いバージョンには互換性の問題や特定の機能が欠けている可能性があります。 * **ビルド成果物**:Webビルドが期待される出力ファイルを生成していることを確認してください。Capgo CLIはバンドルを作成するために有効なWebビルドが必要です。 * **ネットワーク接続**:CI/CD環境がCapgoサーバーにネットワークアクセスできることを確認してください。ファイアウォールやプロキシの問題が`upload`コマンドを妨げることがあります。 まだ問題が解決しない場合は、Capgoサポートにお問い合わせください。特定のセットアップに関する問題のトラブルシューティングをお手伝いします。 ## 結論 CapgoをCI/CDパイプラインに統合し、バージョン管理にsemantic-releaseを活用することで、開発ワークフローを大幅に効率化できます。デプロイメントとバージョニングを自動化することで、より迅速に、より確実にアップデートをリリースできます。 Capgo CLIとsemantic-releaseは、完全に自動化されたエンドツーエンドのリリースを実現するための強力な組み合わせを提供します。少しの設定で、手動のリリースステップを気にすることなく、優れた機能の構築に集中できる堅牢で信頼性の高いデプロイメントプロセスを実現できます。 Capgo CLIのコマンドとオプションの詳細については、[CLIリファレンス](/docs/cli/overview)をご覧ください。また、semantic-releaseの設定について詳しく知りたい場合は、[semantic-releaseのドキュメント](https://github.com/semantic-release/semantic-release)をご覧ください。 デプロイをお楽しみください! # ライブアップデートの配布 Capgoのライブアップデート機能を使用して、アプリのUIとビジネスロジックをリモートでリアルタイムに更新し、バグ修正や新機能の追加をアプリストアを経由せずに直接ユーザーにJSバンドルをプッシュすることができます このガイドは、[Capgoクイックスタート](/docs/getting-started/quickstart)を完了し、以下の作業が済んでいることを前提としています: 1. Capacitorアプリに`@capgo/capacitor-updater` SDKをインストール 2. `capacitor.config.ts`でアプリIDとアップデートチャンネルを設定 3. コードに`CapacitorUpdater.notifyAppReady()`メソッドを追加 これらのステップがまだ完了していない場合は、先にクイックスタートに戻って完了してください [アプリを追加 ](/docs/getting-started/add-an-app/)Capgoアカウントにアプリを追加し、アプリにプラグインをインストールする ## バンドルのアップロード Capgo SDKのインストールと設定が完了したら、最初のライブアップデートバンドルをアップロードする準備が整いました: 1. Webアセットをビルドします: ```shell npm run build ``` 2. バンドルをCapgoにアップロードします: * Console ```shell npx @capgo/cli@latest bundle upload --channel=Production ``` * Github Actions github/workflows/build\_and\_deploy.yml ```yml name: Build source code and send to Capgo concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true on: push: branches: - main jobs: deploy_to_capgo: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v5 - uses: actions/setup-node@v4 with: node-version: 18 - name: Install dependencies run: npm install - name: Build run: npm run build - name: Deploy to Capgo run: bunx @capgo/cli@latest bundle upload -a ${{ secrets.CAPGO_TOKEN }} --channel ${{ env.CHANNEL }} env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} ``` * Gitlab gitlab-ci.yml ```yml stages: - build build: stage: build image: node:18 cache: - key: files: - package-lock.json paths: - node_modules/ script: - npm install - npm run build - npx @capgo/cli@latest bundle upload -a $CAPGO_TOKEN --channel $CAPGO_CHANNEL artifacts: paths: - node_modules/ - dist/ only: - master ``` これにより、コマンドで指定したチャンネルに新しいバンドルバージョンがアップロードされます ### アップロードのトラブルシューティング アップロードが失敗した場合は、以下を確認してください: * `capacitor.config.ts`のアプリIDがCapgoダッシュボードのアプリと一致していること * アップロードコマンドをCapacitorプロジェクトのルートから実行していること * Webアセットがビルドされ、最新の状態であること まだ問題が解決しない場合は、[トラブルシューティング](/docs/getting-started/troubleshooting/)セクションを確認してください ## デバイスでのアップデートの受信 バンドルがアップロードされたら、デバイスでライブアップデートをテストできます: 1. アプリをデバイスに同期します: ```shell npx cap sync ios ``` 2. 別のターミナルで以下のコマンドを実行してアップデートの状態を確認します: ```shell npx @capgo/cli@latest app debug ``` 3. アプリをローカルで実行します: ```shell npx cap run ios ``` または、iOS/AndroidプロジェクトをXcode/Android Studioで開いてネイティブ実行します 4. バックグラウンドでアップデートがダウンロードされるように、アプリを約30秒間開いたままにします 5. ログが更新されるまで数秒かかり、アップデートの状態が表示されます 6. アプリを閉じて再度開きます。ライブアップデートが適用されているはずです! ライブアップデートのテストについての詳細は、[Capgoクイックスタート](/docs/getting-started/quickstart#receiving-a-live-update-on-a-device)を参照してください ## 次のステップ Capgoで最初のライブアップデートのデプロイに成功しましたね!🎉 詳細を学ぶには、[Capgoライブアップデートのドキュメント](/docs/live-updates)の残りを確認してください。次に確認すべき重要なトピック: * [チャンネルを使用したアップデートのターゲティング](/docs/live-updates/channels) * [アップデート動作のカスタマイズ](/docs/live-updates/update-behavior) * [ライブアップデートのロールバック](/docs/live-updates/rollbacks) # 概要 Capgo!のクイックスタートチュートリアルでは、以下の主要な概念を説明します: 1. Capgoアカウントにアプリを追加する 2. CapgoをCI/CDと統合する 3. コミットをプッシュしてCapgoでバンドルアップロードをトリガーする 4. Capgoバンドルの公開を設定・カスタマイズする 5. Capgo経由でライブアップデートを有効にするようアプリを設定する 6. Capgoからアプリにライブアップデートをデプロイする ガイドに沿って順番に進むか、興味のあるコンポーネントのドキュメントに直接移動してください。 [ チュートリアルを始める](/docs/getting-started/add-an-app/) [クイックスタートチュートリアルに従って、すぐにCapgoを使い始めましょう!](/docs/getting-started/add-an-app/) [ 簡単な統合](/docs/getting-started/deploy/) [CapgoをCI/CDと統合し、コミットのプッシュでバンドルアップロードをトリガーします](/docs/getting-started/deploy/) [ ライブアップデートドキュメント](/docs/live-updates/) [アプリストアの遅延なしでリアルタイムにリモートでアプリを更新](/docs/live-updates/) [ トラブルシューティング](/docs/getting-started/troubleshooting) [一般的な問題とその解決方法](/docs/getting-started/troubleshooting) Tip Over-the-Air (OTA)アップデート機能は、HTML、CSS、JavaScriptファイルの変更にのみ適用されます。 Capacitorプラグインの更新などネイティブコードを変更する場合は、アプリストアに再提出して承認を得る必要があります。 ## Discordコミュニティに参加する [Capacitor-updater Discordサーバーに参加しましょう!](https://discordcom/invite/VnYRvBfgA6) ## メンテナンス | プラグインバージョン | Capacitor互換性 | メンテナンス状況 | | ---------- | ------------ | --------------------------- | | v6\*\* | v6\*\* | ✅ | | v5\*\* | v5\*\* | 重大なバグのみ | | v4\*\* | v4\*\* | ⚠️ 非推奨 | | v3\*\* | v3\*\* | ⚠️ 非推奨 | | > 7 | v4\*\* | ⚠️ 非推奨、CIが暴走してバージョンを上げすぎました | ## ストアガイドラインの遵守 Android Google PlayとiOS App Storeには、Capacitor-updaterソリューションをアプリケーションに統合する前に知っておくべきルールがあるガイドラインがあります。 ### Google play [デバイスとネットワークの悪用](https://supportgooglecom/googleplay/android-developer/answer/9888379/?hl=en)トピックの第3段落では、Google Playのアップデートメカニズム以外の方法でソースコードを更新することは制限されていますが、この制限はJavaScriptバンドルの更新には適用されません。 > この制限は、仮想マシンで実行され、AndroidのAPIへのアクセスが制限されているコード(WebviewやブラウザのJavaScriptなど)には適用されません。 これにより、JavaScriptバンドルのみを更新し、ネイティブコードを更新しないCapacitor-updaterは完全に許可されています。 ### App Store 2015年の[Apple Developer Program License Agreement](https://developer.apple.com/programs/ios/information/)の**332**段落以降、JavaScriptとアセットのOver-the-Airアップデートが完全に許可されており、最新バージョン(20170605) [ここからダウンロード可能](https://developer.apple.com/terms/)ではこの規定はさらに広範になっています: > インタープリタされるコードはアプリケーションにダウンロードできますが、次の条件を満たす場合に限ります:(a) App Storeに提出されたアプリケーションの意図された広告目的と一致しない機能や機能性を提供することによって、アプリケーションの主要な目的を変更しない、(b) 他のコードやアプリケーションのストアやストアフロントを作成しない、(c) OSの署名、サンドボックス、その他のセキュリティ機能をバイパスしない Capacitor-updaterを使用すると、プッシュするアップデートがApp Storeで承認された元の意図から大きく逸脱しない限り、これらのルールを完全に遵守することができます。 Appleのガイドラインに更に準拠するため、App Storeで配布されるアプリでは `強制アップデート` シナリオを有効にしないことを提案します。[App Store審査ガイドライン](https://developer.apple.com/app-store/review/guidelines/)には以下のように記載されているためです: > アプリは、機能やコンテンツへのアクセス、またはアプリの使用のために、ユーザーにアプリの評価、レビュー、他のアプリのダウンロード、または同様のアクションを強制してはいけません。 これはバックグラウンドアップデートのデフォルトの動作には問題ありません。ユーザーがアプリを閉じるまで新バージョンの適用を強制しないためですが、強制表示を決定する場合はこのルールを意識しておく必要があります。 ## オープンソース このプラグインはLGPL-3.0ライセンス、バックエンドはAGPL-3.0ライセンスの下にあります。 > 💡 LGPL-3.0は、プラグインのコードを修正した場合、同じライセンスでオープンソースとして公開することが必須であることを意味します。コードを修正せずに使用する場合は、これは該当しません。詳細は以下のリンクの問題をご確認ください 👇 [ライセンスについて? ](https://github.com/Cap-go/capacitor-updater/issues/7) [ドキュメントを読む代わりにGPTS Capgoを使って支援を受ける ](https://chatopenaicom/g/g-3dMwHbF2w-capgo-doc-gpt) > アプリに組み込んでも心配ありません ## 最後に セルフホストを利用していて、このツールが役立つと感じた場合は、[GitHubスポンサー](https://github.com/sponsors/riderx/)になって私の仕事をサポートすることをご検討ください。 ここで構築したすべてのコードを有料化する代わりにオープンソース化することを選択しました。隠したり戦ったりする代わりにオープンにすることで、世界をより良い場所にできると信じています。 これを実現するためには、あなたを含む私たち全員が自分の役割を果たす必要があります🥹 Capgoクラウドがニーズに合わない場合は、[ここ](https://github.com/sponsors/riderx/)で独立した開発者をあなたの条件でサポートすることができます。 ## 簡単な計算 基本プランの価格:$14\*12 = 年間$168 平均的な開発者の時給 = $60 つまり、セルフホストで3時間を無駄にすれば1年分の料金を支払えることになり、3時間以上費やすとお金を失うことになります^^ # トラブルシューティング Capgoを使用する際によくある問題とその解決方法をご紹介します。 ### アップロードの失敗 バンドルのアップロードが失敗する場合、以下を確認してください: * `capacitor.config.ts`のアプリIDがCapgoダッシュボードのアプリと一致していること * Capacitorプロジェクトのルートからアップロードコマンドを実行していること * Webアセットがビルドされ、最新の状態であること #### 高度なアップロードオプション Capgo CLIには、一般的なアップロードの問題に対応するための追加フラグがあります: * `--tus`: 大きなバンドルや不安定なネットワーク接続での、より信頼性の高いアップロードのための[tus再開可能アップロードプロトコル](https://tus.io/)を使用します。バンドルが10MB以上の場合や、接続が不安定な場合は`--tus`の使用を検討してください: ```shell npx @capgo/cli@latest bundle upload --tus ``` * `--package-json`と`--node-modules`: モノレポやnpmワークスペースなどの非標準構造のアプリの場合、ルートの`package.json`と`node_modules`の場所をCapgoに指定します。ルートの`package.json`へのパスと`--node_modules`パスを指定してください: ```shell npx @capgo/cli@latest bundle upload --package-json=path/to/package.json --node_modules=path/to/node_modules ``` Capgoはアプリの依存関係を正しくバンドルするためにこの情報を必要とします。 これらのフラグは`--channel`などの他のオプションと組み合わせることができます。利用可能なアップロードオプションの詳細については、[Capgo CLIドキュメント](/docs/cli/overview/)を参照してください。 アップロードの問題が解決しない場合は、[Capgoサポート](https://support.capgo.app)にお問い合わせください。 ### アップデートのデバッグ ライブアップデートに問題がある場合、Capgoのデバッグコマンドがトラブルシューティングに役立ちます。使用方法: 1. プロジェクトディレクトリで以下のコマンドを実行: ```shell npx @capgo/cli@latest app debug ``` 2. デバイスまたはエミュレータでアプリを起動し、アップデートをトリガーするアクション(新しいバンドルをアップロードした後にアプリを再起動するなど)を実行します。 3. デバッグコマンドの出力を監視します。以下の情報が記録されます: * アプリがアップデートをチェックするタイミング * アップデートが見つかった場合とそのバージョン * アップデートのダウンロードとインストールの進行状況 * アップデート中に発生したエラー 4. デバッグログを使用して問題の発生箇所を特定します。例えば: * アップデートが見つからない場合、バンドルが正常にアップロードされ、アプリが正しいチャンネルを使用するように設定されているか確認 * アップデートがダウンロードされても適用されない場合、`CapacitorUpdater.notifyAppReady()`を呼び出し、アプリが完全に閉じられて再起動されたか確認 * エラーメッセージが表示される場合、Capgoドキュメントでそのエラーを確認するか、サポートに問い合わせ デバッグコマンドは、特にアップデートのダウンロードとインストールプロセスの問題を特定するのに有効です。期待されるアップデートバージョンは見つかったものの、最終的に適用されていない場合は、ダウンロード後の手順をトラブルシューティングの重点としてください。 ### ネイティブログでのデバッグ Capgoデバッグコマンドに加えて、AndroidとiOSのネイティブログは、特にアップデートプロセスのネイティブ側の問題に関して、貴重なトラブルシューティング情報を提供できます。 #### Androidのログ Androidログにアクセスするには: 1. デバイスを接続するかエミュレータを起動します 2. Android Studioを開き、“View > Tool Windows > Logcat”を選択 3. Logcatウィンドウで、上部のドロップダウンからアプリのプロセスを選択してログをフィルタリング 4. `Capgo`を含む行を探してSDKのログを確認 または、`adb logcat`コマンドを使用し、`Capgo`でgrepしてログをフィルタリングすることもできます。 Capgo SDKは、アップデートプロセス中の重要なイベントを記録します: * アップデートチェックが開始されたとき * アップデートが見つかった場合とそのバージョン * アップデートのダウンロードの開始と完了 * アップデートのインストールがトリガーされたとき * ネイティブアップデート手順中に発生したエラー ログで見られる一般的なAndroid特有の問題には以下があります: * アップデートのダウンロードを妨げるネットワーク接続の問題 * アップデートバンドルの保存や読み取り時のファイルパーミッションエラー * アップデートバンドル用のストレージ容量不足 * アップデート適用後のアプリ再起動の失敗 #### iOSのログ iOSログにアクセスするには: 1. デバイスを接続するかシミュレータを起動します 2. Xcodeを開き、“Window > Devices and Simulators”に移動 3. デバイスを選択し、“Open Console”をクリック 4. コンソール出力で`Capgo`を含む行を探してSDKのログを確認 また、ターミナルで`log stream`コマンドを使用し、`Capgo`でgrepしてログをフィルタリングすることもできます。 Androidと同様に、Capgo SDKはiOS側の重要なイベントを記録します: * アップデートチェックの開始と結果 * ダウンロードの開始、進行状況、完了 * インストールのトリガーと結果 * ネイティブアップデートプロセス中のエラー ログで見られるiOS特有の問題には以下があります: * アップデートダウンロード時のSSL証明書の問題 * アップデートダウンロードをブロックするApp Transport Security * アップデートバンドル用の容量不足 * アップデートバンドルの展開や適用の失敗 両プラットフォームにおいて、ネイティブログはアップデートプロセスのより低レベルの視点を提供し、ネイティブ実装の詳細を示します。これらは特にCapgo JavaScriptレイヤーの外で発生する問題の特定に有用です。 複雑なライブアップデートの問題をトラブルシューティングする際は、Capgoデバッグログとネイティブログの両方を取得して包括的な状況把握をすることをお勧めします。2つのログを合わせることで、問題を特定し解決する最善のチャンスが得られます。 ### アップデートが適用されない場合 バンドルをアップロードしたのに変更がデバイスに反映されない場合: * [クイックスタート](/docs/getting-started/quickstart)で示されているように、アプリコードで`CapacitorUpdater.notifyAppReady()`を呼び出していることを確認 * デバイスがインターネットに接続されており、Capgoデバッグログでアップデートがダウンロードされたことを確認 * アップデートは新規起動時のみ適用されるため、アプリを完全に閉じて再起動してみてください * アップデートの適用に問題がある可能性を示すネイティブログのエラーを確認 アップデートプロセスの詳細については、[ライブアップデートのデプロイ](/docs/getting-started/deploy)ガイドを参照してください。まだ問題が解決しない場合は、`npx @capgo/cli@latest app debug`コマンドとネイティブログを使用して、何が起きているかをより詳しく確認してください。 ## SDKのインストール Capgo SDKのインストールに問題がある場合、以下を確認してください: * アプリがサポートされているバージョンのCapacitor(4.0以上)を使用していること * [クイックスタート](/docs/getting-started/quickstart)の手順を順番通りに実行し、SDKのインストール後にアプリを同期したこと ## CI/CD統合 CI/CDパイプラインからCapgoアップロードをトリガーする際の問題: * Capgo認証トークンが正しく設定されているか確認 * Webアセットのビルド後にアップロードコマンドを実行していることを確認 * アップロードコマンドが対象環境に対して正しいチャンネル名を使用していることを確認 より詳しいトラブルシューティングのヒントは[CI/CD統合](/docs/getting-started/cicd-integration)ドキュメントを参照してください。また、`npx @capgo/cli@latest app debug`コマンドを使用して、CI/CDでトリガーされたアップデートがアプリに受信されているか確認することもできます。 # So geht's > Capgoの使用方法、チュートリアル、ヒントとコツ [Capgoでのバージョンの仕組み ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [Capgoでメジャーバージョンをリリースする方法 ](https://capgo.app/blog/how-to-release-major-version-in-capgo/)capgo.app [特定のユーザーまたはグループに特定の更新を送信する方法 ](https://capgo.app/blog/how-to-send-specific-version-to-users/)capgo.app ## CI / CD [GitHub Actionsを使用した自動ビルドとリリース ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [GitHub Actionsを使用した開発とプロダクションビルドの管理 ](https://capgo.app/blog/automatic-build-and-release-with-github-actions/)capgo.app ## コントリビューション [Capgoオープンソースへの貢献 ](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTINGmd)githubcom # 概要 Capgoのライブアップデート機能を使用して、アプリのJavaScriptバンドルをリモートでリアルタイムに更新し、アプリストアのレビュープロセスを経ることなく、バグの修正や新機能の提供を直接ユーザーにプッシュできます Note ライブアップデートはJavaScriptバンドルの変更に限定されます。プラグインの追加や削除、ネイティブプロジェクトの設定変更などネイティブコードを更新する必要がある場合は、アプリストアに新しいネイティブバイナリビルドを提出する必要があります ## ライブアップデートの仕組み Capgoのライブアップデートシステムには2つの主要なコンポーネントがあります: 1. アプリにインストールするCapgo SDK。SDKは利用可能なアップデートを確認し、バックグラウンドでダウンロードします 2. 特定のユーザーグループにアップデートを配信するためのチャネル。チャネルを使用して、`Production`、`Staging`、`Dev`などの異なるリリーストラックを管理できます 新しいJSバンドルをCapgoにアップロードしチャネルに割り当てると、そのチャネルに設定されたアプリのCapgo SDKがアップデートを検出してダウンロードします。アプリが次回再起動する際に、新しいバンドルが読み込まれます ## 始め方 ライブアップデートを使用開始するには、以下の手順に従ってください: 1. [Capgoクイックスタート](/docs/getting-started/quickstart)を完了して、CapgoでアプリをセットアップしCapgo SDKをインストールします 2. アプリコードで、アプリの初期化が完了した後に`CapacitorUpdater.notifyAppReady()`を呼び出します。これによりアプリがアップデートを受信する準備ができたことをCapgo SDKに通知します 3. JSバンドルをビルドしCapgoにアップロードします: ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. アプリを開き、アップデートのダウンロードを待ちます。以下のコマンドでステータスを確認できます: ```shell npx @capgo/cli@latest app debug ``` 5. アップデートがダウンロードされたら、アプリを閉じて再度開き、新しいバンドルを読み込みます 詳細については[ライブアップデートのデプロイ](/docs/getting-started/deploy)ガイドを参照してください ## 次のステップ [ チャネル](/docs/live-updates/channels/) [異なるリリーストラックを管理し、特定のユーザーにアップデートを配信するためのチャネルの使用方法を学びます](/docs/live-updates/channels/) [ ロールバック](/docs/live-updates/rollbacks/) [アップデートで問題が発生した場合に以前のJSバンドルバージョンに戻す方法を確認します](/docs/live-updates/rollbacks/) [ アップデートの動作](/docs/live-updates/update-behavior/) [アプリでのアップデートのダウンロードと適用のタイミングと方法をカスタマイズします](/docs/live-updates/update-behavior/) [ 高速アップデート](/docs/live-updates/differentials/) [アップデートプロセスを高速化するための高速アップデートの使用方法を学びます](/docs/live-updates/differentials/) # チャンネル Live Updateチャンネルは、そのチャンネルに対してアップデートを待ち受けるように設定された全てのデバイスと共有される、特定のJSバンドルビルドを指します。アプリに[Capgo Live Updates SDKをインストール](/docs/getting-started/quickstart/)すると、そのチャンネルに設定された全てのネイティブバイナリは、アプリ起動時に利用可能なアップデートを確認します。チャンネルが指すビルドはいつでも変更でき、必要に応じて以前のビルドにロールバックすることもできます。 ## チャンネルの設定 全てのアプリには削除できないデフォルトの「Production」チャンネルが付属しています。新しいチャンネルを追加するには: 1. Capgoダッシュボードの「Channels」セクションに移動します 2. 「New Channel」ボタンをクリックします 3. チャンネル名を入力して「Create」をクリックします チャンネル名は任意のものを設定できます。一般的な戦略として、開発段階に合わせてチャンネルを設定することがあります: * `Development` - ローカルデバイスやエミュレータでライブアップデートをテストするため * `QA` - QAチームが広範なリリース前にアップデートを検証するため * `Staging` - 本番環境に近い環境で最終テストを行うため * `Production` - エンドユーザーがアプリストアから受け取るアプリのバージョン用 ## アプリでのチャンネルの設定 チャンネルを作成したら、適切なチャンネルを監視するようにアプリを設定する必要があります。この例では、`Development`チャンネルを使用します。 `capacitor.config.ts`(または`capacitor.config.json`)ファイルを開きます。`plugins`セクションで、`CapacitorUpdater`プラグインの`channel`プロパティを希望のチャンネル名に設定します: ```ts import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { defaultChannel: 'Development', }, }, }; ``` 次に、Webアプリをビルドし、`npx cap sync`を実行して更新された設定ファイルをiOSとAndroidプロジェクトにコピーします。このSync手順をスキップすると、ネイティブプロジェクトは以前に設定されていたチャンネルを使い続けます。 Caution `defaultChannel`プロパティは常にクラウドのデフォルトチャンネルをオーバーライドしますが、Cloudでデバイスを特定のチャンネルに強制的に割り当てることは可能です。 ## チャンネルへのバンドルの割り当て ライブアップデートをデプロイするには、新しいJSバンドルビルドをアップロードし、それをチャンネルに割り当てる必要があります。Capgo CLIを使用して1つのステップでこれを行うことができます: ```shell npx @capgo/cli@latest bundle upload --channel=Development ``` これにより、ビルドされたWebアセットがアップロードされ、新しいバンドルが`Development`チャンネルのアクティブビルドとして設定されます。そのチャンネルを監視するように設定されているアプリは、次回のアップデートチェック時に更新を受け取ります。 Capgoダッシュボードの「Bundles」セクションからもチャンネルにビルドを割り当てることができます。ビルド横のメニューアイコンをクリックし、「Assign to Channel」を選択してそのビルドのチャンネルを選択します。 ## バンドルのバージョン管理とチャンネル Capgoでは、バンドルは個々のチャンネルに特有ではなく、アプリ全体でグローバルであることに注意することが重要です。同じバンドルを複数のチャンネルに割り当てることができます。 バンドルのバージョン管理では、チャンネル固有のビルドにはプレリリース識別子を使用した[semver](https://semver.org/)セマンティックバージョニングを推奨します。例えば、ベータリリースは`1.2.3-beta.1`のようにバージョン管理されます。 このアプローチには以下の利点があります: * ビルド間の関係を明確に伝えます。`1.2.3-beta.1`は明らかに`1.2.3`のプレリリースです * チャンネル間でバージョン番号を再利用でき、混乱を減らせます * 明確なロールバックパスを可能にします。`1.2.3`からロールバックする必要がある場合、`1.2.2`が前の安定リリースであることがわかります 典型的なチャンネル設定でのバンドルバージョンの例: * `Development`チャンネル:`1.2.3-dev.1`、`1.2.3-dev.2`など * `QA`チャンネル:`1.2.3-qa.1`、`1.2.3-qa.2`など * `Staging`チャンネル:`1.2.3-rc.1`、`1.2.3-rc.2`など * `Production`チャンネル:`1.2.3`、`1.2.4`など プレリリース識別子を使用したsemverは推奨されるアプローチですが、厳密に必要というわけではありません。重要なのは、ビルド間の関係を明確に伝え、チームの開発プロセスに合ったバージョニング方式を見つけることです。 ## ライブアップデートのロールバック バグを導入するライブアップデートをデプロイした場合や、その他の理由で元に戻す必要がある場合、簡単に以前のビルドにロールバックできます。ダッシュボードの「Channels」セクションから: 1. ロールバックしたいチャンネル名をクリックします 2. 戻したいビルドを見つけ、クラウンアイコンをクリックします ![ロールバックビルド](/select_bundle.webp) 3. アクションを確認します 選択したビルドは即座にそのチャンネルのアクティブビルドになります。アプリは次回のアップデートチェック時にロールバックされたバージョンを受け取ります。 ## デプロイメントの自動化 より高度なワークフロー向けに、CI/CDパイプラインの一部としてライブアップデートのデプロイメントを自動化できます。Capgoをビルドプロセスに統合することで、特定のブランチへのプッシュや新しいリリースの作成時に、自動的に新しいバンドルをアップロードしチャンネルに割り当てることができます。 Capgoライブアップデートの自動化についての詳細は、[CI/CD Integration](/docs/getting-started/cicd-integration/)ドキュメントを参照してください。 ## デバイスへのデプロイ チャンネルについて理解したところで、実際のデバイスへのライブアップデートのデプロイを開始する準備が整いました。基本的なプロセスは: 1. アプリにCapgo SDKをインストールする 2. 希望のチャンネルを監視するようにアプリを設定する 3. ビルドをアップロードしそのチャンネルに割り当てる 4. アプリを起動してアップデートを待つ! より詳細な手順については、[Deploying Live Updates](/docs/getting-started/deploy/)ガイドを参照してください。ハッピーアップデート! # 高速アップデート CapgoのLiveUpdateシステムは、JS bundle全体ではなく、変更されたファイルのみを送信することで、より速く、より効率的にアップデートを提供できます。 これは特に、低速または従量制のネットワーク接続を使用しているユーザーにとって有益です。ダウンロードが必要なデータ量を最小限に抑えることができるためです。 2つ目の利点は、画像や動画のような、めったに変更されない大きなアセットがアプリにある場合、圧縮されたJSファイルと比較して1回だけダウンロードされることです。 ## 差分アップデートの仕組み Capgoの差分アップデートは、アプリにインストールされているCapgoプラグインによって処理されます。`--partial`フラグを使用して新しいバージョンのアプリをアップロードすると、Capgoは以下の処理を行います: 1. ビルド内の各ファイルが個別にアップロードされます 2. 各ファイルのチェックサムが生成されます 3. すべてのファイルとそのチェックサムを列挙した新しいjsonマニフェストが作成されます 4. このマニフェストがCapgoデータベースにアップロードされます アプリを実行しているデバイスがアップデートを確認すると、Capgoプラグインはサーバーから新しいマニフェストを受信します。このマニフェストを現在のものと比較し、チェックサムとファイルパスに基づいて変更されたファイルを特定します。 プラグインは、JS bundle全体ではなく、変更されたファイルのみをダウンロードします。ダウンロードしたファイルと既存の変更されていないファイルを組み合わせて、アプリの新しいバージョンを再構築します。 マニフェスト 差分アップデートの場合、デバイスはダウンロードしたすべてのファイルを共通のキャッシュに保存します。Capgoは決してクリーンアップしませんが、OSはいつでもクリーンアップできます。 ## 差分アップデートの有効化 Capgoアプリで差分アップデートを有効にするには、新しいバージョンをアップロードする際に単に`--partial`フラグを使用します: ## 差分アップデートの強制 すべてのアップロードを差分アップデートにし、誤って完全なバンドルがアップロードされることを防ぎたい場合は、`--partial-only`フラグを使用できます: ```shell npx @capgo/cli@latest bundle upload --partial-only ``` `--partial-only`を使用すると、Capgoは個別のファイルのアップロードとマニフェストの生成のみを行います。パーシャルをサポートしていないデバイスはアップデートをダウンロードできなくなります。 以下のような場合に`--partial-only`の使用を検討することができます: * 常に差分アップデートを使用し、完全なバンドルアップロードを許可したくない場合 * CI/CDパイプラインを設定していて、すべての自動アップロードを差分にしたい場合 * アプリが大きく、帯域幅が制限されているため、アップロード/ダウンロードサイズを最小限に抑える必要がある場合 `--partial-only`が設定されている状態で完全なバンドルアップロードが必要な場合は、単に`--partial-only`なしでアップロードコマンドを実行します。これにより、その単一のアップロードに対して設定が上書きされ、必要に応じて完全なバンドルをプッシュできます。 ## トラブルシューティング 差分アップデートが機能していないように見える場合(小さな変更でもデバイスが常に完全なJSバンドルをダウンロードしている場合)、以下を確認してください: * 新しいバージョンをアップロードするたびに`--partial`フラグを使用していること * `--partial-only`を使用している場合、`--partial`フラグを誤って省略していないこと * デバイスが最新バージョンのCapgoプラグインを実行していること * デバイスが安定したネットワーク接続を持ち、Capgoサーバーに到達できること Capgo webappを使用して、最後のアップロードの詳細を確認することもできます: 1. [webapp](https://app.capgo.io)に移動 2. アプリをクリック 3. 統計バーのバンドル数をクリック 4. 最後のバンドルを選択 5. `Partial`フィールドを確認 ![bundle type](/bundle_type.webp) 問題が続く場合は、Capgoサポートにお問い合わせください。サーバーログを確認して、パーシャルアップロードが正しく処理され、デバイスが更新されたマニフェストを受信していることを確認できます。 以上です!`--partial`フラグは、Capgoに差分アップデートに必要な個別ファイルのアップロードとマニフェスト生成を実行するように指示します。 差分アップデートとして配信したい新しいバージョンをアップロードするたびに`--partial`を使用する必要があることに注意してください。フラグを省略すると、Capgoは JS bundle全体を単一ファイルとしてアップロードし、小さな部分のみが変更された場合でも、デバイスは完全なバンドルをダウンロードします。 # ロールバック Capgoのライブアップデートはユーザーに迅速な改善と修正を提供できますが、アプリの以前のバージョンにロールバックする必要がある状況もあります。新しいアップデートで予期せぬ重大な問題が発生した場合や、修正作業中に特定の変更を元に戻したい場合などです。 Capgoはチャンネルのビルドを管理し、ユーザーが受け取るアプリのバージョンを制御するための複数の方法を提供しています。 ## 以前のバンドルへのロールバック 新しいビルドをアップロードしチャンネルに割り当てるたびに、Capgoはそれらのビルドの履歴を保持します。特定のアップデートを元に戻す必要がある場合、これらの以前のビルドの1つを選択してチャンネルに再デプロイできます。 以前のビルドにロールバックするには: 1. [Capgoダッシュボード](https://app.capgo.io)にログインします 2. 「Channels」セクションに移動します 3. ロールバックしたいチャンネルの名前をクリックします 4. チャンネルのビルド履歴から元に戻したいビルドを見つけます 5. そのビルドの横にあるクラウンアイコンをクリックして、チャンネルのアクティブビルドにします ![チャンネル管理オプション](/select_bundle.webp) 6. このビルドにロールバックすることを確認します Note 以前のビルドへのロールバックは、選択したチャンネルにのみ影響します。複数のチャンネル(例:本番環境、ステージング環境など)がある場合、影響を受ける各チャンネルでロールバックプロセスを繰り返す必要があります。 ロールバック後、更新されたチャンネルをリッスンするように設定されたデバイスは、次回のアップデートチェック時に以前のビルドを受け取ります。ロールバックされたビルドは新しいアップデートとして扱われるため、通常のアップデートフローと条件が適用されます。 ## チャンネルのリンク解除 問題を調査している間、チャンネルのアップデートを一時的に停止したい場合は、チャンネルを現在のビルドからリンク解除できます。 チャンネルをリンク解除するには: 1. Capgoダッシュボードでチャンネルに移動します 2. 現在のビルドの横にある「Unlink」ボタンをクリックします 3. チャンネルのリンクを解除することを確認します チャンネルがリンク解除されると、新しいアップデートは配信されなくなります。そのチャンネルに設定されたデバイスは、チャンネルが再びビルドにリンクされるまで現在のビルドのままとなります。 これは、アップデートに問題を特定したものの、どのビルドにロールバックするか確信が持てない場合に便利です。チャンネルをリンク解除することで、さらなるアップデートを配信することなく調査する時間を確保できます。 ## ビルトインバンドルの強制 より深刻な状況では、チャンネル上のすべてのデバイスをアプリのネイティブバイナリに最初からパッケージされていたウェブビルドに戻したい場合があります。これは「ビルトインバンドル」として知られています。 チャンネルでビルトインバンドルを強制するには: 1. Capgoダッシュボードでチャンネルに移動します 2. 「Built-in Bundle」ボタンをクリックします 3. ビルトインバンドルを強制することを確認します ビルトインバンドルを強制すると、そのチャンネルに設定されているすべてのデバイスは、次回のアップデートチェック時に元のパッケージされたウェブビルドに戻ります。これは現在のビルドに関係なく発生します。 これは特定の以前のビルドに戻すよりも積極的なロールバックオプションで、アプリがアプリストアに最後に公開されて以降にリリースされたすべてのライブアップデートが破棄されます。 Caution ビルトインバンドルの強制は、チャンネル上のすべてのデバイスに影響を与えるため注意が必要です。この操作を行う前に、影響を考慮し、前進するための計画を立ててください。 ## 問題のモニタリングと対応 問題をすばやく発見し、問題のあるアップデートの影響を最小限に抑えるためには、リリースのモニタリングと問題への対応計画を立てることが重要です。 いくつかの戦略には以下が含まれます: * アップデートのリリース直後のクラッシュレポートとユーザーフィードバックのモニタリング * 段階的なロールアウトやステージドチャンネルシステムを使用して、広範なリリース前に小規模なグループでアップデートをテスト * ロールバック、リンク解除、またはビルトインバンドルの強制をいつ行うか、誰に権限があるかについての明確な決定プロセスの確立 * 適切な場合、問題と解決策についてユーザーへの通知 慎重なモニタリングと問題のあるアップデートを迅速に管理する能力を組み合わせることで、ユーザーへの混乱を最小限に抑えながら、継続的に改善するアプリ体験を提供できます。 # アップデート動作 Capgoアプリのアップデートをリリースする際、ユーザーにできるだけ早くそのアップデートを受け取ってもらいたいと思うでしょう。しかし、セッション中にダウンロードを待たせたりアプリを再起動させたりして、ユーザーエクスペリエンスを妨げたくはありません。 Capgoのアップデート動作は、アップデートを迅速に配信することとユーザーの中断を最小限に抑えることのバランスを取るように設計されています。 ## デフォルトのアップデートフロー デフォルトでは、Capgoは以下のようにアプリのアップデートを処理します: 1. アプリ起動時、Capgoプラグインは新しいアップデートが利用可能かどうかをチェックします 2. アップデートが見つかった場合、ユーザーが現在のバージョンを使用し続けている間にバックグラウンドでダウンロードされます 3. ダウンロードが完了すると、Capgoはユーザーがアプリをバックグラウンドにするか完全に終了するのを待ちます 4. ユーザーが次回アプリを起動すると、更新されたバージョンが実行されます このフローにより、ユーザーはアップデートプロンプトによって中断されたり、ダウンロードを待たされたりすることなく、常にアプリの最新バージョンを実行できます。 Tip Capgoはアプリがバックグラウンドから再開する際にもアップデートをチェックするため、ユーザーはアプリを完全に終了しなくてもアップデートを受け取ることができます。 ## なぜこのアプローチなのか? バックグラウンドまたは終了イベントでアップデートを適用することには、ユーザーエクスペリエンスにおいて以下のような主要な利点があります: * セッション中にアップデートプロンプトで中断されたり、ダウンロードを待たされたりすることがありません * アップデートはセッション間でシームレスに適用されるため、アプリの起動エクスペリエンスは常に新鮮です * アクティブなユーザーを中断する心配なく、頻繁にアップデートを配信できます 主な欠点は、ユーザーがアプリをバックグラウンドにして素早く再開した場合、それらのアクション間でアップデートが適用されたため、保存されていない状態が失われる可能性があることです。 これを緩和するために、以下を推奨します: * 状態を頻繁に保存し、アプリが再開したときに適切に復元する * アプリの状態の大部分を変更する頻繁なアップデートを避ける * 重要なフローについては、アップデート動作をカスタマイズすることを検討する(以下参照) ## アップデートが適用されるタイミングのカスタマイズ 場合によっては、アップデートがいつ適用されるかをより細かく制御したい場合があります。例えば、進行中のフローが完了するまでアップデートを確実に待機させたい場合や、サーバーサイドの変更とアプリのアップデートを連携させたい場合などです。 Capgoは`setDelay`関数を提供しており、アップデートがインストールされる前に満たす必要がある条件を指定できます: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; await CapacitorUpdater.setMultiDelay({ delayConditions: [ { kind: 'date', value: '2023-06-01T00:00:00.000Z', }, { kind: 'background', value: '60000', }, ], }); ``` この例では、2023年6月1日以降AND アプリが60秒以上バックグラウンドになるまでアップデートのインストールを遅延させます。 利用可能な遅延条件は以下の通りです: * `date`: 特定の日時以降までアップデートの適用を待機 * `background`: アプリがバックグラウンドになってから最小限の期間が経過するまで待機 * `nativeVersion`: アップデートを適用する前に、最小バージョンのネイティブバイナリがインストールされるまで待機 * `kill`: 次のアプリ終了イベントまでアップデートの適用を待機 これらの条件を組み合わせることで、アップデートがインストールされるタイミングを正確に制御できます。 Danger 現在、`kill`条件は他の条件のように次のバックグラウンドイベントではなく、最初の終了イベント後にアップデートをトリガーすることに注意してください。この不整合は将来のリリースで修正される予定です。 ## 即時アップデートの適用 重要なアップデートや非常にシンプルな状態のアプリの場合、バックグラウンドや終了イベントを待たずに、ダウンロード完了後すぐにアップデートを適用したい場合があります。Capgoは`directUpdate`設定オプションでこれをサポートしています。 `directUpdate`はJavaScriptコードではなく、`capacitor.config.ts`ファイルで設定します: ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: true, keepUrlPathAfterReload: true, }, }, }; export default config; ``` `directUpdate`を有効にすると、ユーザーがアプリをアクティブに使用している最中でも、ダウンロードが完了次第すぐにアップデートが適用されます。 `directUpdate`はネイティブ設定であるため、JavaScriptコードで追加の処理が必要になることに注意してください。 `directUpdate`を使用する場合、`appReady`イベントをリッスンし、それに応じてアプリのスプラッシュスクリーンを非表示にする必要があります: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater'; import { SplashScreen } from '@capacitor/splash-screen'; CapacitorUpdater.addListener('appReady', () => { // スプラッシュスクリーンを非表示 SplashScreen.hide(); }); CapacitorUpdater.notifyAppReady(); ``` `appReady`イベントは、アプリの初期化と保留中のアップデートの適用が完了した時点で発火します。これは、ユーザーが最新バージョンを確実に見られるようにするため、アプリのUIを表示しても安全なポイントです。 `appReady`イベントの処理に加えて、`directUpdate`を使用する場合は`keepUrlPathAfterReload`設定オプションを`true`に設定することを推奨します。これにより、アップデートによってアプリがリロードされた際に現在のURLパスが保持され、アプリ内でのユーザーの位置を維持し、混乱を軽減します。 `directUpdate`を使用する際に`appReady`イベントを処理せず、`keepUrlPathAfterReload`を設定しない場合、ユーザーは一時的に古いバージョンのアプリを見たり、初期ルートに戻されたり、アップデートが適用される際にちらつきを見る可能性があります。 `directUpdate`は重要なバグ修正やセキュリティパッチを配信する際に便利ですが、いくつかのトレードオフがあります: * `appReady`イベントを適切に処理しない場合、アップデートが適用される際に短いちらつきやローディング状態が見える可能性があります * アップデートがアプリの状態やUIを変更する場合、セッション中に破壊的な変更が見える可能性があります * `keepUrlPathAfterReload`が設定されていない場合、アプリ内でのユーザーの位置が失われ、混乱を招く可能性があります * スムーズな移行を確保するために、状態の保存と復元を慎重に処理する必要があります `directUpdate`を有効にする場合は、以下を推奨します: * `appReady`イベントを処理してアプリのUIが表示されるタイミングを制御する * `keepUrlPathAfterReload`を`true`に設定してアプリ内でのユーザーの位置を保持する * ユーザーの進行状況を失わないように、必要に応じてアプリの状態を保存および復元する * 不自然な遷移、状態の損失、位置の混乱がないことを確認するために、アプリのアップデート動作を徹底的にテストする ほとんどの場合、デフォルトのアップデート動作がアップデートの迅速な配信と中断の最小化の最適なバランスを提供します。しかし、特定のニーズを持つアプリの場合、Capgoはアップデートがいつどのように適用されるかをカスタマイズする柔軟性を提供します。 # 関数と設定 > プラグインで利用可能なメソッドとコンフィグレーション # アップデータープラグイン設定 詳細については、Github の[Readme](https://github.com/Cap-go/capacitor-updater)をご覧ください CapacitorUpdaterは以下のオプションで設定できます: | プロパティ | 型 | 説明 | デフォルト値 | 導入バージョン | | ---------------------------- | --------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------- | ------- | | **`appReadyTimeout`** | `number` | ネイティブプラグインがアップデートを「失敗」とみなすまでの待機時間をミリ秒単位で設定します。AndroidとiOSのみで利用可能です | `10000 // (10秒)` | | | **`responseTimeout`** | `number` | ネイティブプラグインがAPIタイムアウトとみなすまでの待機時間をミリ秒単位で設定します。AndroidとiOSのみで利用可能です | `20 // (20秒)` | | | **`autoDeleteFailed`** | `boolean` | 失敗したバンドルを自動的に削除するかどうかを設定します。AndroidとiOSのみで利用可能です | `true` | | | **`autoDeletePrevious`** | `boolean` | アップデート成功後に以前のバンドルを自動的に削除するかどうかを設定します。AndroidとiOSのみで利用可能です | `true` | | | **`autoUpdate`** | `boolean` | アップデートサーバーを介した自動アップデートを使用するかどうかを設定します。AndroidとiOSのみで利用可能です | `true` | | | **`resetWhenUpdate`** | `boolean` | 新しいネイティブアプリバンドルがデバイスにインストールされた時に、以前にダウンロードしたバンドルを自動的に削除します。AndroidとiOSのみで利用可能です | `true` | | | **`updateUrl`** | `string` | アップデートチェックが送信されるURL/エンドポイントを設定します。AndroidとiOSのみで利用可能です | `https://plugin.capgo.app/updates` | | | **`channelUrl`** | `string` | チャンネル操作用のURL/エンドポイントを設定します。AndroidとiOSのみで利用可能です | `https://plugin.capgo.app/channel_self` | | | **`statsUrl`** | `string` | アップデート統計が送信されるURL/エンドポイントを設定します。AndroidとiOSのみで利用可能です。統計レポートを無効にするには""に設定します | `https://plugin.capgo.app/stats` | | | **`privateKey`** | `string` | エンドツーエンドのライブアップデート暗号化用の秘密鍵を設定します。AndroidとiOSのみで利用可能です。バージョン620で非推奨となり、バージョン700で削除予定です | `undefined` | | | **`publicKey`** | `string` | エンドツーエンドのライブアップデート暗号化用の公開鍵を設定します(バージョン2)。AndroidとiOSのみで利用可能です | `undefined` | 620 | | **`version`** | `string` | アプリの現在のバージョンを設定します。これは最初のアップデートリクエストで使用されます。設定されていない場合、プラグインはネイティブコードからバージョンを取得します。AndroidとiOSのみで利用可能です | `undefined` | 41748 | | **`directUpdate`** | `boolean` | アプリが更新/インストールされた直後にアップデートを直接インストールするようにプラグインを設定します。自動アップデートモードのみです。AndroidとiOSのみで利用可能です | `undefined` | 510 | | **`periodCheckDelay`** | `number` | 定期的なアップデートチェックの遅延時間を秒単位で設定します。AndroidとiOSのみで利用可能です。600秒(10分)未満にはできません | `600 // (10分)` | | | **`localS3`** | `boolean` | テストまたはセルフホストアップデートサーバー用にローカルサーバーを使用するようにCLIを設定します | `undefined` | 41748 | | **`localHost`** | `string` | テストまたはセルフホストアップデートサーバー用にローカルサーバーを使用するようにCLIを設定します | `undefined` | 41748 | | **`localWebHost`** | `string` | テストまたはセルフホストアップデートサーバー用にローカルサーバーを使用するようにCLIを設定します | `undefined` | 41748 | | **`localSupa`** | `string` | テストまたはセルフホストアップデートサーバー用にローカルサーバーを使用するようにCLIを設定します | `undefined` | 41748 | | **`localSupaAnon`** | `string` | テスト用にローカルサーバーを使用するようにCLIを設定します | `undefined` | 41748 | | **`localApi`** | `string` | テスト用にローカルAPIを使用するようにCLIを設定します | `undefined` | 633 | | **`localApiFiles`** | `string` | テスト用にローカルファイルAPIを使用するようにCLIを設定します | `undefined` | 633 | | **`allowModifyUrl`** | `boolean` | JavaScript側からupdateUrl、statsUrl、channelUrlを動的に変更することを許可します | `false` | 540 | | **`defaultChannel`** | `string` | 設定でアプリのデフォルトチャンネルを設定します | `undefined` | | | **`appId`** | `string` | アプリのIDを設定します | `undefined` | 600 | | **`keepUrlPathAfterReload`** | `boolean` | リロード後もURLパスを保持するようにプラグインを設定します。警告:リロードがトリガーされると、‘windowhistory’がクリアされます | `false` | 680 | ## 例 `capacitor.config.json`の場合: ```json { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 // (1秒), "responseTimeout": 10 // (10秒), "autoDeleteFailed": false, "autoDeletePrevious": false, "autoUpdate": false, "resetWhenUpdate": false, "updateUrl": https://example.com/api/auto_update, "channelUrl": https://example.com/api/channel, "statsUrl": https://example.com/api/stats, "privateKey": undefined, "publicKey": undefined, "version": undefined, "directUpdate": undefined, "periodCheckDelay": undefined, "localS3": undefined, "localHost": undefined, "localWebHost": undefined, "localSupa": undefined, "localSupaAnon": undefined, "localApi": undefined, "localApiFiles": undefined, "allowModifyUrl": undefined, "defaultChannel": undefined, "appId": undefined, "keepUrlPathAfterReload": undefined } } } ``` `capacitor.config.ts`の場合: ```ts /// import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { appReadyTimeout: 1000 // (1秒), responseTimeout: 10 // (10秒), autoDeleteFailed: false, autoDeletePrevious: false, autoUpdate: false, resetWhenUpdate: false, updateUrl: https://example.com/api/auto_update, channelUrl: https://example.com/api/channel, statsUrl: https://example.com/api/stats, privateKey: undefined, publicKey: undefined, version: undefined, directUpdate: undefined, periodCheckDelay: undefined, localS3: undefined, localHost: undefined, localWebHost: undefined, localSupa: undefined, localSupaAnon: undefined, localApi: undefined, localApiFiles: undefined, allowModifyUrl: undefined, defaultChannel: undefined, appId: undefined, keepUrlPathAfterReload: undefined, }, }, }; export default config; ``` * [`notifyAppReady()`](#notifyappready) * [`setUpdateUrl()`](#setupdateurl) * [`setStatsUrl()`](#setstatsurl) * [`setChannelUrl()`](#setchannelurl) * [`download()`](#download) * [`next()`](#next) * [`set()`](#set) * [`delete()`](#delete) * [`list()`](#list) * [`reset()`](#reset) * [`current()`](#current) * [`reload()`](#reload) * [`setMultiDelay()`](#setmultidelay) * [`cancelDelay()`](#canceldelay) * [`getLatest()`](#getlatest) * [`setChannel()`](#setchannel) * [`unsetChannel()`](#unsetchannel) * [`getChannel()`](#getchannel) * [`setCustomId()`](#setcustomid) * [`getBuiltinVersion()`](#getbuiltinversion) * [`getDeviceId()`](#getdeviceid) * [`getPluginVersion()`](#getpluginversion) * [`isAutoUpdateEnabled()`](#isautoupdateenabled) * [`removeAllListeners()`](#removealllisteners) * [`addListener('download', )`](#addlistenerdownload-) * [`addListener('noNeedUpdate', )`](#addlistenernoneedupdate-) * [`addListener('updateAvailable', )`](#addlistenerupdateavailable-) * [`addListener('downloadComplete', )`](#addlistenerdownloadcomplete-) * [`addListener('majorAvailable', )`](#addlistenermajoravailable-) * [`addListener('updateFailed', )`](#addlistenerupdatefailed-) * [`addListener('downloadFailed', )`](#addlistenerdownloadfailed-) * [`addListener('appReloaded', )`](#addlistenerappreloaded-) * [`addListener('appReady', )`](#addlistenerappready-) * [`isAutoUpdateAvailable()`](#isautoupdateavailable) * [`getNextBundle()`](#getnextbundle) * [インターフェース](#interfaces) * [型エイリアス](#type-aliases) # メソッド ## notifyAppReady() ```typescript notifyAppReady() => Promise ``` 現在のバンドルが正常に動作していることをCapacitor Updaterに通知します(このメソッドが全てのアプリ起動時に呼び出されない場合、ロールバックが発生します) デフォルトでは、このメソッドはアプリ起動後10秒以内に呼び出される必要があります。そうでない場合はロールバックが発生します この動作は{@link appReadyTimeout}で変更できます **戻り値:** `Promise` *** ## setUpdateUrl() ```typescript setUpdateUrl(options: UpdateUrl) => Promise ``` アプリのupdateUrlを設定します。これは更新を確認するために使用されます | パラメータ | 型 | 説明 | | ------------- | ----------- | ------------------ | | **`options`** | `UpdateUrl` | 更新の確認に使用するURLを含みます | **提供開始:** 540 *** ## setStatsUrl() ```typescript setStatsUrl(options: StatsUrl) => Promise ``` アプリのstatsUrlを設定します。これは統計情報の送信に使用されます。空文字列を渡すと統計情報の収集が無効になります | パラメータ | 型 | 説明 | | ------------- | ---------- | -------------------- | | **`options`** | `StatsUrl` | 統計情報の送信に使用するURLを含みます | **提供開始:** 540 *** ## setChannelUrl() ```typescript setChannelUrl(options: ChannelUrl) => Promise ``` アプリのchannelUrlを設定します。これはチャンネルの設定に使用されます | パラメータ | 型 | 説明 | | ------------- | ------------ | --------------------- | | **`options`** | `ChannelUrl` | チャンネルの設定に使用するURLを含みます | **提供開始:** 540 *** ## download() ```typescript download(options: DownloadOptions) => Promise ``` 提供されたURLから新しいバンドルをダウンロードします。これはZIPファイルで、ファイルを内部に含むか、全てのファイルを含む一意のIDを内部に持つ必要があります | パラメータ | 型 | 説明 | | ------------- | ----------------- | ----------------------------------------------------------------- | | **`options`** | `DownloadOptions` | 新しいバンドルZIPをダウンロードするための{@link [DownloadOptions](#downloadoptions)} | **戻り値:** `Promise` *** ## next() ```typescript next(options: BundleId) => Promise ``` アプリがリロードされたときに使用する次のバンドルを設定します| パラメータ | タイプ | 説明 | | ------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | 次回アプリ起動時に設定する次のバンドルのID {@link [BundleInfoid](#bundleinfo)} | **戻り値:** `Promise` *** ## set() ```typescript set(options: BundleId) => Promise ``` 現在のバンドルを設定し、すぐにアプリを再読み込みします | パラメータ | タイプ | 説明 | | ------------- | ---------- | --------------------------------------------------------------- | | **`options`** | `BundleId` | 現在のバンドルとして設定する新しいバンドルIDを含む {@link [BundleId](#bundleid)} オブジェクト | *** ## delete() ```typescript delete(options: BundleId) => Promise ``` ネイティブアプリストレージから指定されたバンドルを削除します。{@link list}を使用して保存されているバンドルIDを取得してください | パラメータ | タイプ | 説明 | | ------------- | ---------- | -------------------------------------------------------------------------------- | | **`options`** | `BundleId` | 削除するバンドルのIDを含む {@link [BundleId](#bundleid)} オブジェクト (注意: これはバージョン名ではなく、バンドルIDです) | *** ## list() ```typescript list(options?: ListOptions | undefined) => Promise ``` アプリにローカルにダウンロードされているすべてのバンドルを取得します | パラメータ | タイプ | 説明 | | ------------- | ------------- | ------------------------------------------------- | | **`options`** | `ListOptions` | バンドルをリストするための {@link [ListOptions](#listoptions)} | **戻り値:** `Promise` *** ## reset() ```typescript reset(options?: ResetOptions | undefined) => Promise ``` アプリを`builtin`バンドル(Apple App Store / Google Play Storeに送信されたもの)または最後に正常に読み込まれたバンドルにリセットします | パラメータ | タイプ | 説明 | | ------------- | -------------- | ------------------------------------------------------------------------------------------------------------ | | **`options`** | `ResetOptions` | {@link [ResetOptionstoLastSuccessful](#resetoptions)}を含む、`true`でビルトインバンドルにリセット、`false`で最後に正常に読み込まれたバンドルにリセット | *** ## current() ```typescript current() => Promise ``` 現在のバンドルを取得します。設定されていない場合は`builtin`を返します。currentNativeはデバイスにインストールされている元のバンドルです **戻り値:** `Promise` *** ## reload() ```typescript reload() => Promise ``` ビューを再読み込みします *** ## setMultiDelay() ```typescript setMultiDelay(options: MultiDelayConditions) => Promise ``` プラグインが更新を遅延させるために使用する {@link [DelayCondition](#delaycondition)} 配列を設定します すべての条件が満たされた後、更新プロセスは通常通り再開されます。そのため、アプリのバックグラウンド化または終了後に更新がインストールされます `date`タイプの場合、値はiso8601日付文字列である必要があります `background`タイプの場合、値はミリ秒単位の数値である必要があります `nativeVersion`タイプの場合、値はバージョン番号である必要があります `kill`タイプの場合、値は使用されません この関数は、killオプションが他のオプションのように次のバックグラウンド後ではなく、最初の終了後に更新をトリガーする一貫性のない動作をします。これは将来のメジャーリリースで修正される予定です | パラメータ | タイプ | 説明 | | ------------- | ---------------------- | ------------------------------------------------------------------- | | **`options`** | `MultiDelayConditions` | 設定する条件の {@link [MultiDelayConditions](#multidelayconditions)} 配列を含む | **Since:** 430 *** ## cancelDelay() ```typescript cancelDelay() => Promise ``` 更新を即座に処理するために {@link [DelayCondition](#delaycondition)} をキャンセルします **Since:** 400 *** ## getLatest() ```typescript getLatest(options?: GetLatestOptions | undefined) => Promise ``` 更新URLから利用可能な最新のバンドルを取得します | パラメータ | タイプ | | ------------- | ------------------ | | **`options`** | `GetLatestOptions` | **戻り値:** `Promise` **Since:** 400 *** ## setChannel() ```typescript setChannel(options: SetChannelOptions) => Promise ``` このデバイスのチャンネルを設定します。チャンネルは自己割り当てを許可する必要があります {@link PluginsConfig}で`autoUpdate`が有効な場合、起動時にチャンネルを設定するためにこのメソッドを使用しないでください このメソッドはアプリの準備完了後にチャンネルを設定するためのものです このメソッドはデバイスIDをチャンネルにリンクするリクエストをCapgoバックエンドに送信します。Capgoはチャンネルの設定に応じて受け入れまたは拒否します | パラメータ | タイプ | 説明 | | ------------- | ------------------- | ---------------------------------------------------------- | | **`options`** | `SetChannelOptions` | 設定する {@link [SetChannelOptions](#setchanneloptions)} チャンネル | **戻り値:** `Promise` **Since:** 470 *** ## unsetChannel() ```typescript unsetChannel(options: UnsetChannelOptions) => Promise ``` このデバイスのチャンネルを解除しますデバイスはデフォルトチャンネルに戻ります。 | パラメータ | 型 | | ------------- | --------------------- | | **`options`** | `UnsetChannelOptions` | **導入バージョン:** 470 *** ## getChannel() ```typescript getChannel() => Promise ``` このデバイスのチャンネルを取得します。 **戻り値:** `Promise` **導入バージョン:** 480 *** ## setCustomId() ```typescript setCustomId(options: SetCustomIdOptions) => Promise ``` このデバイスにカスタムIDを設定します。 | パラメータ | 型 | 説明 | | ------------- | -------------------- | ---------------------------------------------------------------- | | **`options`** | `SetCustomIdOptions` | は設定する {@link [SetCustomIdOptions](#setcustomidoptions)} customId | **導入バージョン:** 490 *** ## getBuiltinVersion() ```typescript getBuiltinVersion() => Promise ``` ネイティブアプリのバージョンまたは設定で指定されたビルトインバージョンを取得します。 **戻り値:** `Promise` **導入バージョン:** 520 *** ## getDeviceId() ```typescript getDeviceId() => Promise ``` デバイスを識別するために使用される一意のID(自動更新サーバーに送信)を取得します。 **戻り値:** `Promise` *** ## getPluginVersion() ```typescript getPluginVersion() => Promise ``` ネイティブCapacitor Updaterプラグインのバージョン(自動更新サーバーに送信)を取得します。 **戻り値:** `Promise` *** ## isAutoUpdateEnabled() ```typescript isAutoUpdateEnabled() => Promise ``` 自動更新設定の状態を取得します。 **戻り値:** `Promise` *** ## removeAllListeners() ```typescript removeAllListeners() => Promise ``` このプラグインのすべてのリスナーを削除します。 **導入バージョン:** 100 *** ## addListener(‘download’, ) ```typescript addListener(eventName: 'download', listenerFunc: (state: DownloadEvent) => void) => Promise ``` アプリでのバンドルダウンロードイベントをリッスンします。ダウンロードが開始された時、ダウンロード中、および完了時に発火します。 | パラメータ | 型 | | ------------------ | -------------------------------- | | **`eventName`** | `’download’` | | **`listenerFunc`** | `(state: DownloadEvent) => void` | **戻り値:** `Promise` **導入バージョン:** 2011 *** ## addListener(‘noNeedUpdate’, ) ```typescript addListener(eventName: 'noNeedUpdate', listenerFunc: (state: NoNeedEvent) => void) => Promise ``` 更新不要イベントをリッスンします。アプリが起動されるたびに強制的にチェックしたい場合に便利です。 | パラメータ | 型 | | ------------------ | ------------------------------ | | **`eventName`** | `’noNeedUpdate’` | | **`listenerFunc`** | `(state: NoNeedEvent) => void` | **戻り値:** `Promise` **導入バージョン:** 400 *** ## addListener(‘updateAvailable’, ) ```typescript addListener(eventName: 'updateAvailable', listenerFunc: (state: UpdateAvailableEvent) => void) => Promise ``` 利用可能な更新イベントをリッスンします。アプリが起動されるたびに強制的にチェックしたい場合に便利です。 | パラメータ | 型 | | ------------------ | --------------------------------------- | | **`eventName`** | `’updateAvailable’` | | **`listenerFunc`** | `(state: UpdateAvailableEvent) => void` | **戻り値:** `Promise` **導入バージョン:** 400 *** ## addListener(‘downloadComplete’, ) ```typescript addListener(eventName: 'downloadComplete', listenerFunc: (state: DownloadCompleteEvent) => void) => Promise ``` ダウンロード完了イベントをリッスンします。 | パラメータ | 型 | | ------------------ | ---------------------------------------- | | **`eventName`** | `’downloadComplete’` | | **`listenerFunc`** | `(state: DownloadCompleteEvent) => void` | **戻り値:** `Promise` **導入バージョン:** 400 *** ## addListener(‘majorAvailable’, ) ```typescript addListener(eventName: 'majorAvailable', listenerFunc: (state: MajorAvailableEvent) => void) => Promise ``` アプリでのメジャーアップデートイベントをリッスンします。disableAutoUpdateBreaking設定によってメジャーアップデートがブロックされている場合に通知します。 | パラメータ | 型 | | ------------------ | -------------------------------------- | | **`eventName`** | `’majorAvailable’` | | **`listenerFunc`** | `(state: MajorAvailableEvent) => void` | **戻り値:** `Promise` **導入バージョン:** 230 *** ## addListener(‘updateFailed’, ) ```typescript addListener(eventName: 'updateFailed', listenerFunc: (state: UpdateFailedEvent) => void) => Promise ``` アプリでの更新失敗イベントをリッスンします。次回のアプリ起動時に更新のインストールが失敗した場合に通知します。 | パラメータ | 型 | | ------------------ | ------------------------------------ | | **`eventName`** | `’updateFailed’` | | **`listenerFunc`** | `(state: UpdateFailedEvent) => void` | **戻り値:** `Promise` **導入バージョン:** 230 *** ## addListener(‘downloadFailed’,\`\`\`typescript addListener(eventName: ‘downloadFailed’, listenerFunc: (state: DownloadFailedEvent) => void) => Promise ````plaintext アプリでのダウンロード失敗イベントを監視し、バンドルのダウンロードが失敗した時に通知します | Param | Type | | ------------------ | --------------------------------------------------------------------------------------- | | **`eventName`** | 'downloadFailed' | | **`listenerFunc`** | (state: DownloadFailedEvent) => void | **Returns:** Promise<PluginListenerHandle> **Since:** 400 -------------------- ## addListener('appReloaded', ) ```typescript addListener(eventName: 'appReloaded', listenerFunc: () => void) => Promise ```` アプリでのリロードイベントを監視し、リロードが発生した時に通知します | Param | Type | | ------------------ | --------------- | | **`eventName`** | `’appReloaded’` | | **`listenerFunc`** | `() => void` | **Returns:** `Promise` **Since:** 430 *** ## addListener(‘appReady’, ) ```typescript addListener(eventName: 'appReady', listenerFunc: (state: AppReadyEvent) => void) => Promise ``` アプリでのアプリ準備完了イベントを監視し、アプリが使用可能になった時に通知します | Param | Type | | ------------------ | -------------------------------- | | **`eventName`** | `’appReady’` | | **`listenerFunc`** | `(state: AppReadyEvent) => void` | **Returns:** `Promise` **Since:** 510 *** ## isAutoUpdateAvailable() ```typescript isAutoUpdateAvailable() => Promise ``` 自動更新が利用可能かどうかを取得します (serverUrlによって無効化されていないか) **Returns:** `Promise` *** ## getNextBundle() ```typescript getNextBundle() => Promise ``` アプリがリロードされる時に使用される次のバンドルを取得します 次のバンドルが設定されていない場合はnullを返します **Returns:** `Promise` **Since:** 680 *** ## インターフェース ### AppReadyResult | Prop | Type | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | ### BundleInfo | Prop | Type | | ---------------- | -------------- | | **`id`** | `string` | | **`version`** | `string` | | **`downloaded`** | `string` | | **`checksum`** | `string` | | **`status`** | `BundleStatus` | ### UpdateUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### StatsUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### ChannelUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### DownloadOptions | Prop | Type | Description | Default | Since | | ---------------- | -------- | ----------------------------------------------------------------------------------- | ----------- | ----- | | **`url`** | `string` | ダウンロードするバンドルzipファイル(例: distzip)のURL (Amazon S3、GitHubタグ、その他バンドルをホストしている場所のURLを指定可能) | | | | **`version`** | `string` | このバンドル/バージョンのバージョンコード/名前 | | | | **`sessionKey`** | `string` | 更新用のセッションキー | `undefined` | 400 | | **`checksum`** | `string` | 更新用のチェックサム | `undefined` | 400 | ### BundleId | Prop | Type | | -------- | -------- | | **`id`** | `string` | ### BundleListResult | Prop | Type | | ------------- | -------------- | | **`bundles`** | `BundleInfo[]` | ### ListOptions | Prop | Type | Description | Default | Since | | --------- | --------- | ----------------------------------------------------------------- | ------- | ----- | | **`raw`** | `boolean` | 生のバンドルリストを返すかマニフェストを返すか。trueの場合、ディスク上のファイルではなく内部データベースから読み取りを試みます | `false` | 6140 | ### ResetOptions | Prop | Type | | ---------------------- | --------- | | **`toLastSuccessful`** | `boolean` | ### CurrentBundleResult | Prop | Type | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | | **`native`** | `string` | ### MultiDelayConditions | Prop | Type | | --------------------- | ------------------ | | **`delayConditions`** | `DelayCondition[]` | ### DelayCondition | Prop | Type | Description | | ----------- | ---------------- | ------------------------ | | **`kind`** | `DelayUntilNext` | setMultiDelayで遅延条件を設定します | | **`value`** | `string` | | ### LatestVersion | Prop | Type | Description | Since | | ---------------- | ----------------- | ---------------- | ----- | | **`version`** | `string` | getLatestメソッドの結果 | 40 | | **`major`** | `boolean` | | | | **`message`** | `string` | | | | **`sessionKey`** | `string` | | | | **`error`** | `string` | | | | **`old`** | `string` | | | | **`url`** | `string` | | | | **`manifest`** | `ManifestEntry[]` | | 61 | ### ManifestEntry | Prop | Type | | ------------------ | ---------------- | | **`file_name`** | `string \| null` | | **`file_hash`** | `string \| null` | | **`download_url`** | `string \| null` | ### GetLatestOptions | Prop | Type | 説明 | デフォルト | Since | | ------------- | -------- | ----------------------------------------------------------------- | ----------- | ----- | | **`channel`** | `string` | 最新バージョンを取得するためのチャンネル。チャンネルはこの機能を使用するために’self\_assign’を許可する必要があります | `undefined` | 680 | ### ChannelRes | Prop | Type | 説明 | Since | | ------------- | -------- | ------------------- | ----- | | **`status`** | `string` | 設定されたチャンネルの現在のステータス | 470 | | **`error`** | `string` | | | | **`message`** | `string` | | | ### SetChannelOptions | Prop | Type | | ----------------------- | --------- | | **`channel`** | `string` | | **`triggerAutoUpdate`** | `boolean` | ### UnsetChannelOptions | Prop | Type | | ----------------------- | --------- | | **`triggerAutoUpdate`** | `boolean` | ### GetChannelRes | Prop | Type | 説明 | Since | | -------------- | --------- | ------------------ | ----- | | **`channel`** | `string` | 取得したチャンネルの現在のステータス | 480 | | **`error`** | `string` | | | | **`message`** | `string` | | | | **`status`** | `string` | | | | **`allowSet`** | `boolean` | | | ### SetCustomIdOptions | Prop | Type | | -------------- | -------- | | **`customId`** | `string` | ### BuiltinVersion | Prop | Type | | ------------- | -------- | | **`version`** | `string` | ### DeviceId | Prop | Type | | -------------- | -------- | | **`deviceId`** | `string` | ### PluginVersion | Prop | Type | | ------------- | -------- | | **`version`** | `string` | ### AutoUpdateEnabled | Prop | Type | | ------------- | --------- | | **`enabled`** | `boolean` | ### PluginListenerHandle | Prop | Type | | ------------ | --------------------- | | **`remove`** | `() => Promise` | ### DownloadEvent | Prop | Type | 説明 | Since | | ------------- | ------------ | ------------------------ | ----- | | **`percent`** | `number` | ダウンロードの現在の進捗状況(0から100の間) | 400 | | **`bundle`** | `BundleInfo` | | | ### NoNeedEvent | Prop | Type | 説明 | Since | | ------------ | ------------ | ------------------------ | ----- | | **`bundle`** | `BundleInfo` | ダウンロードの現在の進捗状況(0から100の間) | 400 | ### UpdateAvailableEvent | Prop | Type | 説明 | Since | | ------------ | ------------ | ------------------------ | ----- | | **`bundle`** | `BundleInfo` | ダウンロードの現在の進捗状況(0から100の間) | 400 | ### DownloadCompleteEvent | Prop | Type | 説明 | Since | | ------------ | ------------ | -------------------- | ----- | | **`bundle`** | `BundleInfo` | 新しいアップデートが利用可能な場合に発生 | 400 | ### MajorAvailableEvent | Prop | Type | 説明 | Since | | ------------- | -------- | ---------------------- | ----- | | **`version`** | `string` | 新しいメジャーバンドルが利用可能な場合に発生 | 400 | ### UpdateFailedEvent | Prop | Type | 説明 | Since | | ------------ | ------------ | ----------------------- | ----- | | **`bundle`** | `BundleInfo` | アップデートのインストールが失敗した場合に発生 | 400 | ### DownloadFailedEvent | Prop | Type | 説明 | Since | | ------------- | -------- | ---------------- | ----- | | **`version`** | `string` | ダウンロードが失敗した場合に発生 | 400 | ### AppReadyEvent | Prop | Type | 説明 | Since | | ------------ | ------------ | -------------------- | ----- | | **`bundle`** | `BundleInfo` | アプリが使用可能な状態になった場合に発生 | 520 | | **`status`** | `string` | | | ### AutoUpdateAvailable | Prop | Type | | --------------- | --------- | | **`available`** | `boolean` | ## Type Aliases ### BundleStatus `‘success’ | ‘error’ | ‘pending’ | ‘downloading’` ### DelayUntilNext `‘background’ | ‘kill’ | ‘nativeVersion’ | ‘date’` # Auto actualización > capacitor-updaterを使用した自動更新の方法 このモードにより、開発者はcapacitor-updaterを自動更新モードで使用し、Capgoチャンネルまたは同等のものを通じて更新をプッシュすることができます。 ### 前提条件 Capgo自動更新を使用する前に、アプリのバージョンがを使用していることを確認してください。 これはCapgoでバージョンを管理するための規則です。 アプリでバージョンを設定するには2つの方法があります: 新しい方法:`capacitorconfigjson`ファイルの`version`フィールドを使用 ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true, // 自動更新を有効化、デフォルトはtrue "appId": "comexampleapp", // サーバーでアプリを識別するために使用 "version": "100" // アップデートをチェックするために使用 } } } ``` これらのオプションは、プラグインがアップデートをチェックする際とCLIがバージョンをアップロードする際に使用されます。 古い方法: プロジェクト内の3つのファイルで: * `packagejson`の**version** * `android/app/buildgradle`の**versionName** * `ios/App/Appxcodeproj/projectpbxproj`の**CURRENT\_PROJECT\_VERSION** ### チュートリアル 5分でアプリをセットアップ [capacitor updaterを使用してcapacitorアプリをシームレスに更新する](https://capgo.app/blog/update-your-capacitor-apps-seamlessly-using-capacitor-updater) 5分でCIをセットアップ [GitHub actionsによる自動ビルドとリリース](https://capgo.app/blog/automatic-build-and-release-with-github-actions) ### インストール ```bash npm install @capgo/capacitor-updater npx cap sync ``` ### はじめに [登録](https://capgo.app)をクリックしてアカウントを作成してください。 サーバーではチャンネルやバージョンなど、さらに多くの機能を管理できます。 `autoUpdate`は`capacitorconfig`のデータを使用してCapgoサーバーを識別します。 Note 会社の規定でコードをサーバーに送信できない場合でも、Capgo Cloudを使用することは可能です。 #### バージョンの検証 自動更新を設定した場合、アプリが動作中で準備ができていることをJS内から通知する必要があります。 これは、アプリ内で`notifyAppReady`を呼び出すことで実行できます。 できるだけ早く実行してください。 ```ts import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdaternotifyAppReady() ``` #### ユーザーフロー * ユーザーがアプリを開くと、アプリはサーバーにアップデートの確認を行い、見つかった場合はバックグラウンドでダウンロードされます * ユーザーがアプリを終了すると、新しいバージョンがアクティブに設定されます * ユーザーが再度アプリを開くと、新しいアクティブバージョンを読み込み、デフォルトとして設定します * `notifyAppReady()`が呼び出された場合、ユーザーがアプリを終了すると、過去のバージョンは削除されます * ユーザーは次の更新サイクルまで通常のアプリフローを続けます Danger ⚠️ アプリで`notifyAppReady()`を呼び出さないと、現在のバージョンが無効としてマークされ、前回の有効なバンドルまたはストックに戻ります #### 開発フロー 新機能を開発する際は、capgoが最新の更新バンドルで作業を上書きし続けるため、`autoUpdate`をブロックしてください。 設定で`autoUpdate`をfalseに設定してください。 何らかの理由で更新に行き詰まった場合は、アプリを削除して再インストールできます。 その前に必ず設定で`autoUpdate`をfalseに設定してください。 そしてXcodeまたはAndroid studioで再度ビルドしてください。 各コミット時にバージョンをアップロードするようにCI/CDを設定するには、このガイドに従ってください。 [GitHub actionsによる自動ビルドとリリース](https://capgo.app/blog/automatic-build-and-release-with-github-actions) #### メジャーアップデート利用可能イベント `disableAutoUpdateBreaking`がtrueに設定されている場合、アプリがメジャーな破壊的更新を拒否したときにイベントをリッスンできます。 ```jsx import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdateraddListener('majorAvailable', (info: any) => { consolelog('majorAvailable was fired', infoversion) }) ``` # チャネルシステム > capacitor-updater でチャンネルシステムを使用する方法 CapgoとCapacitor-updaterには強力なチャンネルシステムが付属しています ## チャンネルでできること: * 開発やベータテスト用にデバイスをチャンネルに関連付ける * 開発ブランチごとに1つのチャンネルを使用し、チームメンバーが端末から自己割り当てしてテストできるようにする ## デバイスをチャンネルに割り当てる: * チャンネルをデフォルトに設定すると、新しいデバイスがCapgoに更新を要求するたびにこのチャンネルが応答します * [**getDeviceId**](/docs/plugin/api#getdeviceid)メソッドで**deviceId**をバックエンドに送信し、Capgo公開APIで割り当てる * チャンネルを自己割り当て可能に設定し([**setChannel**](/docs/plugin/api#setchannel)メソッド)、プラグインの`setChannel`メソッドでデバイスがチャンネルを購読できるようにする(ユーザーの操作の有無は問わない) * [設定](/docs/plugin/settings#defaultchannel)の`defaultChannel`オプションを使用して、このプラグイン設定を持つすべてのデバイスのデフォルトチャンネルを設定する Note デバイスを直接バンドルに割り当てることもできます ## チャンネルオプション ![](/channel_setting_1.webp) 各オプションの詳細: | オプション | 説明 | | ------------------------------ | ------------------------------------------------------- | | **ネイティブ以下への自動ダウングレードを無効化** | アプリのネイティブバージョンがチャンネルのバージョンより大きい場合、更新を送信しない | | **メジャーバージョン以上への自動アップグレードを無効化** | アプリのネイティブバージョンがチャンネルのバージョンのメジャー(**1**23)より低い場合、更新を送信しない | | **マイナーバージョン以上への自動アップグレードを無効化** | アプリのネイティブバージョンがチャンネルのバージョンのマイナー(1**2**3)より低い場合、更新を送信しない | | **デバイスの自己割り当てを許可** | デバイスがこのチャンネルに対して`setChannel`メソッドを使用することを許可 | | **iOS** | iOSデバイスがこのチャンネルから更新をダウンロードすることを許可 | | **Android** | Androidデバイスがこのチャンネルから更新をダウンロードすることを許可 | | **エミュレータを許可** | エミュレータがこのチャンネルから更新を受信することを許可 | | **開発ビルドを許可** | 開発ビルドがこのチャンネルから更新を受信することを許可 | Note CI/CDをGoogle Playへのバージョン送信用に設定している場合、Google Playは毎回20台以上の実機でアプリを実行します。Capgoは新しいバンドルの最初の4時間、統計にカウントされるのを防ぐためにGoogleデータセンターのIPをブロックします Note Capgoはエミュレータと開発ビルドを使用量にカウントしませんが、これらが3%を超えるとアカウントは修正されるまでロックされることに注意してください # 시작하기 > アプリにプラグインをインストールする ## Capgoの紹介 [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## ライブアップデートまであと3ステップ ### アカウントを作成する 登録ページにアクセスしてください: ![onboarding screenshot](/onboard.webp "onboarding screenshot") ### CLIでCapgoをインストールする マジックコマンドで始めましょう ```bash npx @capgo/cli@latest init [APIKEY] ``` このコマンドがセットアップ手順をご案内します ### プロンプトに従って進める CLIで一連の質問が表示されます。自動セットアップを完了するために必要な回答を提供してください Tip これらの手順に従えば、すぐに使い始めることができます。セットアップ中にサポートが必要な場合は、サポートチームがお手伝いいたします。楽しいオンボーディングを! ### Capgoのマジックを楽しもう! アプリをテストして、後からCapgoのパワフルな機能の使い方を学びましょう # Mise à jour hybride > 自動アップデートの更新方法 ユーザーへの更新を配信する際、適用前に必要に応じて以下の方法で更新サイクルに対応できます: * サイレント更新 * `updateAvailable`イベントのリッスン * モーダルウィンドウの表示または更新の遅延 ## サイレント更新 `directUpdate`を`true`に設定することで、アプリ起動時ごとに強制的に更新サイクルを実行できます。 これにより、ユーザーの操作なしで通常の更新サイクルがトリガーされます ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "directUpdate": true, }, "SplashScreen": { "launchAutoHide": false, } } } ``` そしてアプリ内では、`appReady`イベントを受信したときにスプラッシュスクリーンを非表示にする必要があります: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' CapacitorUpdateraddListener('appReady', () => { // Hide splash SplashScreenhide() }) CapacitorUpdaternotifyAppReady() ``` ## 強制更新 `updateAvailable`イベントにリスナーを追加し、アプリが更新されることをユーザーに通知するアラートを表示します: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { Dialog } from '@capacitor/dialog' CapacitorUpdateraddListener('updateAvailable', async (res) => { try { await Dialogalert({ title: '更新が利用可能です', message: `バージョン${resbundleversion}が利用可能です。アプリは今更新されます`, }) CapacitorUpdaterset(resbundle) } catch (error) { consolelog(error) } }) CapacitorUpdaternotifyAppReady() ``` ## モーダル更新 ダイアログを表示して更新するかどうかをユーザーに決定させることもできます: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { Dialog } from '@capacitor/dialog' CapacitorUpdateraddListener('updateAvailable', async (res) => { try { const { value } = await Dialogconfirm({ title: '更新が利用可能です', message: `バージョン${resbundleversion}が利用可能です。今すぐ更新しますか?`, }) if (value) CapacitorUpdaterset(resbundle) } catch (error) { consolelog(error) } }) CapacitorUpdaternotifyAppReady() ``` # 手動更新 > アプリケーションのアップデートを管理する方法 Capgo cloudで更新がいつ適用されるかを自分で管理したい場合は、手動モードを使用してください アカウントの設定は、Getting Startedで説明されているように行う必要があります [Getting Started ](/docs/getting-started/quickstart/) #### 設定 `capacitor.config.json`で自動更新を無効にします ```tsx // capacitor.config.json { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` その後、更新を自分で処理するロジックを追加します\ 以下は実装例です: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater' import type { BundleInfo } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' CapacitorUpdater.notifyAppReady() let data: BundleInfo | null = null App.addListener('appStateChange', async (state: any) => { console.log('appStateChange', state) if (state.isActive) { console.log('getLatest') // ダウンロードの失敗を防ぐため、アプリがアクティブな時にダウンロードを実行 const latest = await CapacitorUpdater.getLatest() console.log('latest', latest) if (latest.url) { data = await CapacitorUpdater.download(latest) console.log('download', data) } } if (!state.isActive && data) { console.log('set') // ユーザーがアプリを離れた時、または任意のタイミングで切り替えを実行 SplashScreen.show() try { await CapacitorUpdater.set({ id: data.id }) } catch (err) { console.log(err) SplashScreen.hide() // setが失敗した場合、そうでなければ新しいアプリが非表示にする必要がある } } }) ``` プラグインで利用可能なすべてのAPIのドキュメント: [Methods ](/docs/plugin/api/) ユーザーがチャンネルを購読して異なるバージョンを試すことができるユースケースがあります:\ # Cordova > Is Capacitor-updater available for Cordova? You’ve been wondering if this plugin will ever be available for Cordova このプラグインがCordovaで利用可能になるのかと疑問に思っていたかもしれません I have started a R\&D repository for that, but it’s a huge amount of work そのためのR\&Dリポジトリを開始しましたが、作業量が膨大です ## Problems ## 問題点 I know I can do it but for that, I have to read all the code of Cordova codebase as I did for Capacitor, to understand how to make it work 実現可能だとは分かっていますが、その為にはCapacitorの時と同様にCordovaのコードベース全体を読んで、どのように動作させるかを理解する必要があります The Android version is easier to do since both use Java, but iOS needs a full rewrite because Swift is still not well-supported in Cordova AndroidバージョンはどちらもJavaを使用しているため比較的簡単ですが、CordovaではSwiftのサポートがまだ十分ではないため、iOSは完全な書き直しが必要です ## Solution ## 解決策 In the mean time heres what you can do: 当面は以下のことができます: * [Support me](https://github.com/sponsors/riderx) on GitHub and I can prioritize that This will need at least 1 month of work * Hire me as a Consultant, I used to help big companies migrate to capacitor, it usually takes \~10-20 days, and the [benefit](https://ionicio/resources/articles/capacitor-vs-cordova-modern-hybrid-app-development) is huge for the team * GitHubで[サポート](https://github.com/sponsors/riderx)していただければ、優先的に取り組むことができます。少なくとも1ヶ月の作業が必要です * コンサルタントとして雇用してください。大企業のCapacitorへの移行を支援してきた経験があり、通常10-20日かかりますが、チームにとって[メリット](https://ionicio/resources/articles/capacitor-vs-cordova-modern-hybrid-app-development)は非常に大きいです # デバッグ > アプリのデバッグ方法 ## クラウドログの理解: ### バックエンドから送信 | コード | 説明 | | ----------------------------------------- | --------------------------------------------------------------------------------- | | **InvalidIp** | ユーザーがGoogleデータセンターに位置し、更新が4時間以内の場合。これはGoogleボットのデバイスがアカウントのデバイスとしてカウントされるのを防ぐためです | | **needPlanUpgrade** (以前は **needUpgrade**) | プランの制限に達したことを示し、アップグレードするか次の月まで、デバイスは更新を受信しません | | **noNew** | デバイスは利用可能な最新バージョンを持っています | | **disablePlatformIos** | デバイスはiOSプラットフォーム上にありますが、チャンネル設定で無効化されています | | **disablePlatformAndroid** | デバイスはAndroidプラットフォーム上にありますが、チャンネル設定で無効化されています | | **disableAutoUpdate** | ”major" | | **disableAutoUpdateUnderNative** | デバイスのバージョン(`123`)があり、チャンネルにデバイスバージョンより低い更新(`122`)を送信しようとしていますが、チャンネル設定で無効化されています | | **disableDevBuild** | デバイスは開発ビルドですが、チャンネル設定で無効化されています | | **disableEmulator** | デバイスはエミュレーターですが、チャンネル設定で無効化されています | ### デバイスから送信 | コード | 説明 | | ------------------------- | ------------------------------------------------- | | **get** | 新バージョンのダウンロード情報がデバイスに送信されました | | **delete** | デバイス上で1つのバンドルが削除されました | | **set** | バンドルがデバイスにセットされました | | **set\_fail** | バンドルのセットに失敗しました | | **reset** | デバイスが`builtin`バンドルにリセットされました | | **download\_XX** | 新しいバンドルがダウンロードされました - XXは進捗率を示します(10%単位) | | **download\_complete** | 新しいバンドルのダウンロードが完了しました | | **download\_fail** | 新しいバンドルのダウンロードに失敗しました | | **update\_fail** | 新しいバンドルはインストールされましたが、`notifyAppReady`の呼び出しに失敗しました | | **checksum\_fail** | 新しいバンドルのチェックサム検証に失敗しました | | **windows\_path\_fail** | ZIPファイルに不正なWindowsパスが含まれています | | **canonical\_path\_fail** | ファイルパスが正規形式ではありません | | **directory\_path\_fail** | ZIPファイルのパスにエラーがあります | | **unzip\_fail** | 解凍に失敗しました | | **low\_mem\_fail** | デバイスのメモリ不足によりダウンロードに失敗しました | ### バンドルステータス * `SUCCESS`: バンドルのインストールが完了 * `ERROR`: インストールまたはダウンロードに失敗 * `PENDING`: ダウンロード完了、リリース待ち * `DELETED`: バンドルが削除されました(統計用に表示) * `DOWNLOADING`: 現在バンドルをダウンロード中 ## デバイスログの理解: ### デバッグコマンド: Capgoクラウドユーザー向けのデバッグコマンドがあります ```bash npx @capgo/cli@latest app debug ``` これによりアプリで発生するすべてのイベントを確認し、更新が行われない場合の解決策を見つけることができます ### iOS Xcodeでログを見つけるには [Getting the Device Log in Xcode ](https://intercomhelp/deploygate/en/articles/4682692-getting-the-device-log-in-xcode) ### Android: Android Studioでログを見つけるには [View logs with Logcat ](https://developerandroidcom/studio/debug/am-logcat) ### ログの説明 * `Failed to download from` **=>** **download\_fail**と同じ * `notifyAppReady was not called, roll back current bundle` => **update\_fail**と同じ ## デバイスでダウンロードされたバンドルを見つける ### iOS iOSでデバッグするには、アプリをコンピュータにダンプする必要があります: XcodeにはiOSデバイスの開発者インストールアプリのファイルシステムを検査する機能が組み込まれています 手順: * デバイスをMacに接続し、Xcodeメニューバーで Window > Devices を選択 * Devicesセクションの左ペインでデバイスを選択 * そのデバイスの開発者インストールアプリの一覧が表示されます * 検査したいアプリを選択し、画面下部の歯車アイコンを選択 * Show Containerを選択してファイルシステムを表示するか、スナップショットをダウンロードできます Download Containerを選択すると、xcappdataファイルとしてファイルシステムのスナップショットがダウンロード・エクスポートされます このファイルを右クリックしてShow Package Contentsを選択してフォルダを開きます App Dataフォルダを開くと、Documents、Library、tmpなどのフォルダが表示されます ![image](/ios_debug_update_1.webp) バージョンは2つのフォルダにあります: `library/NoCloud/ionic_built_snapshots`はアプリの再起動後に必要です そして`documents/versions`はホットリロード用です ### Android Androidでデバッグするには、Android Studioからデバイスにアクセスする必要があります: * View > Tool Windows > Device File Explorerをクリックするか、ツールウィンドウバーのDevice File ExplorerボタンをクリックしてDevice Explorerを開きます * ドロップダウンリストからデバイスを選択します * \*\*data/data/APP\_NAME/\*\*のパスを開きます。**APP\_NAMEはアプリのID**です ![image](/android_debug_update.webp) `versions`フォルダを探してすべてのバージョンを確認します ご存知ですか? Androidではすべてのバージョンが1つのフォルダに保存されますが、iOSでは2つの場所に複製する必要があります ## iOSの本番環境でのクラッシュログの理解 [How to review your app's crash logs ](https://developer.apple.com/news/?id=nra79npr) # Nuxt 2 > Nuxt 2 にプラグインをインストールする方法 # Nuxt 2 へのインストール プラグインファイル `capacitor-updaterjs` を `plugins` ディレクトリに作成します ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' export default ({ app }) => { if (processclient) { windowonNuxtReady(() => { CapacitorUpdaternotifyAppReady() }) } } ``` これにより、クライアントサイドでプラグインが読み込まれ、アプリがアップデートを受信する準備ができたことを通知します # Problemas conocidos > Capacitor と CapGo の既知の問題 Here’s the Japanese translation: ## Ionic のライブリロード * 開発時に、CLIからIonicのライブリロード機能を使用すると、プラグインが上書きされるため、更新が反映されません ## Quasar のライブリロード * 内部でIonicと同じシステムを使用しているため、更新が反映されません ## 更新の失敗 * これは通常、大きな更新(20MB以上)がプッシュされた場合に発生し、多くのユーザーが最新バージョンを取得できません\ 以前は、ダウンロードが完了するまでアプリを開いたままにする必要がありましたが、現在はバックグラウンドダウンロードを使用していますが、数秒間に制限されています ## Android ### ダウンロードできない インドのデバイスで問題が発生し、ユーザーと通話して異なるDNSサーバーを試してもらったところ、解決しました 問題が発生した場合は、CloudflareやGoogle DNSなど、異なるDNSサーバーを試してください Cloudflare: 1111と1001 Google DNS: 8888と8844、またはdnsgoogle [How to setup a preferred DNS server on Android? ](https://wwwandroidpolicecom/use-preferred-dns-server-android-tutorial/) ### セルフホスティング セルフホストの更新をプッシュする場合、Androidアププのセキュリティポリシーに反するため、“HTTP”エンドポイントは使用できないことに注意してください。それでも使用したい場合は、このガイドに従ってください: [How to allow all Network connection types HTTP and HTTPS in Android (9) Pie? ](https://stackoverflow.com/a/51902630/5511370) ### 解凍 解凍の問題:DEFLATED entriesはEXT descriptorを持つことができます CLIとは異なるもので bundles を圧縮した場合、zipのフォーマットが正しくない可能性があります。CLIコマンド `npx @capgo/cli zip BUNDLE_FOLDER` を使用してください これはJavaの既知の問題です: [Unzip issue: DEFLATED entries can have EXT descriptor ](https://bugsopenjdkorg/browse/JDK-8143613) ### Clearfixの問題 * usesCleartextTrafficで問題がある場合、プラグインがsonar cloudで推奨されているグッドプラクティスに従っているためです。90%のケースでは問題なく動作しますが、一部のプラグインで問題が発生する場合があります 修正するには、`android/app/src/main/AndroidManifestxml`の``キーに以下を追加してください: ```xml tools:replace="android:usesCleartextTraffic" xmlns:tools="http://schemasandroidcom/tools" ``` ## iOS ### プライバシーマニフェスト [Privacy Manifest](https://capacitorjs.com/docs/ios/privacy-manifest)(通常は`ios/App/PrivacyInfoxcprivacy`)に`NSPrivacyAccessedAPICategoryUserDefaults`ディクショナリキーを追加してください: ```xml NSPrivacyAccessedAPITypes NSPrivacyAccessedAPIType NSPrivacyAccessedAPICategoryUserDefaults NSPrivacyAccessedAPITypeReasons CA921 ``` [`UserDefaults`](https://developer.apple.com/documentation/foundation/userdefaults) APIへのアクセス理由として[`CA921`](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278401)を宣言することを推奨します ### ネットワーク権限 ローカルサーバーを使用して更新テストを行う場合、アプリはネットワーク権限を要求します。これは正常な動作で、リモートサーバーを使用する場合は発生しません ## 両OS共通 手動モードで更新を行う場合、一部のイベントのキャッチが困難です。例えば、更新失敗はJSコードがリロードする直前にトリガーされるため、キャッチできません 代替手段として、bundlesをリストアップしてエラー統計を確認することで、更新が失敗したかどうかを知ることができます 将来的にはより良い対処方法を見つける必要がありますが、自動モードが推奨される更新方法であるため、優先度は高くありません PRsを歓迎しています ## CLI CLIで何か問題がある場合は、 **capacitorconfigts**に**appId**と**appName**が存在することを確認してください 公式ドキュメントのガイドに従ってください: [Capacitor Configuration ](https://capacitorjs.com/docs/config) # 概要 > 2つのアプローチの説明 ### クラウドモード(推奨) クラウドモードは、手間のかからないアップデート管理のための推奨される選択肢です。Capgoのバックエンドがすべてのアップデートロジックを処理し、セキュリティと制御を向上させるためにサーバーサイドでアップデートに関する決定を行います。このモードは使いやすさを重視しており、一度設定すれば、統計やチャンネルなどの高度な機能を提供しながら、スムーズに動作します。また、手動モードで設定することもでき、JavaScriptコードを使用してアップデートのタイミングを決定できる柔軟性も提供します。バックエンドは引き続き何をアップデートするかを管理します。このモードは、自動モードと同様のセキュリティや高度な機能の利点を共有しながら、アップデートのタイミングを自分で決められる柔軟性を追加します。 ### セルフホストモード セルフホスト自動モードは、すべてのアップデートロジックを自身のサーバーで処理したい場合のためのものです。完全な自律性を提供しますが、別のサーバーが必要で、アップデートとサーバー要件の管理により多くの作業が必要です。 セルフホスト手動モードは、制御と自律性を組み合わせたものです。JavaScriptを通じてアップデートのタイミングを決定しますが、サーバーが何をアップデートするかを処理します。アップデートコードをアップデートに含める必要があるため、やや複雑です。 Note セルフホストを選択した場合、自動復元、メールアラート、チャンネル、統計、暗号化などのcapgoクラウドが提供する素晴らしい機能を利用できなくなります。 Danger ユーザーに不適切なアップデートを送信すると、アプリが破損する可能性があります。 # 自動アップデート > 自動更新プラグインをセルフホスティングモードで使用する方法 この文書では、自動更新サーバーの実行方法について説明します ## バンドルの提供 バンドルがHTTPS経由で提供され、アプリが更新をダウンロードできるように適切なCORSヘッダーがサーバーに設定されていることを確認してください 例:`https://myservercom/app/updates/updatesjson` バンドルの提供に不慣れな場合は、Capgo Cloudを試すか、以下の例を参照することをお勧めします: [バンドルの提供 ](/docs/self-hosted/auto-update/update-endpoint) ## 設定 `capacitorconfigjson`に`updateUrl`を追加します ```json { "plugins": { "CapacitorUpdater": { "updateUrl": "https://myservercom/app/updates/updatesjson", } } } ``` Caution セルフホスト更新をプッシュする際は、Androidアプリのセキュリティポリシーに反するため、“HTTP”エンドポイントを使用できないことに注意してください。テスト目的の場合は[許可することができます](https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted) ## 更新API プラグインは、アプリが開かれるたびに、以下のボディでAPIにPOSTリクエストを送信します: ```typescript interface AppInfos { "platform": "ios" | "android", "device_id": "UUID_of_device_unique_by_install", "app_id": "APPID_FROM_CAPACITOR_CONFIG", "custom_id": "your_custom_id_set_on_runtime", "plugin_version": "PLUGIN_VERSION", "version_build": "VERSION_NUMBER_FROM_NATIVE_CODE", "version_code": "VERSION_CODE_FROM_NATIVE_CODE", "version_name": "LAST_DOWNLOADER_VERSION" | "builtin" "version_os": "VERSION_OF_SYSYEM_OS", "is_emulator": boolean, "is_prod": boolean, } ``` サーバーAPIは、更新が必要な場合、capacitor-updaterプラグインに対して以下のようなJSONデータで応答する必要があります: ```json { "version": "123", "url": "https://myservercom/app/updates/my-new-app-200zip" } ``` 自動更新モードでは、サーバーはバージョンを比較して適切なものを返す必要があります。URLキーが存在する場合、プラグインはダウンロードプロセスを開始します “message”と”error”キーを追加すると、バージョンは設定されず、代わりにメッセージがログに表示されます `version`キーは[`semver`](https://semverorg/)形式である必要があります zipファイルには、ルートに`indexhtml`ファイルがあるか、ルートに`indexhtml`を含む1つのフォルダのみが必要です CLIのコマンドを使用してバンドルをzip化できます: サーバーから提供するファイルのバンドルを作成 ```bash npx @capgo/cli bundle zip --path [/path/to/my/bundle] ``` # 貢献 > capgoのオープンソースプロジェクトに貢献 ## 貢献する理由 まず初めに、capgoのオープンソースプロジェクトへの貢献を検討いただき、ありがとうございます!あなたのような方々のおかげで、capgoのオープンソースプロジェクトは素晴らしいツールとなっています。 貢献を検討する理由として以下が挙げられます: * capgoチームが提供する[多数のバウンティ](https://consolealgoraio/org/Capgo)から報酬を得る絶好の機会です * 実装したい機能を追加する良い機会です * 遭遇したバグを修正する良い機会です * [Capgoのメインライセンス](https://github.com/Cap-go/capgo/blob/main/LICENSE)では、変更した部分をオープンソース化する必要があります。コードを貢献することで、あなたの変更をオープンソースとして保持し、他の人が使用できるようになります ## 貢献方法 * まず、貢献したいリポジトリをフォークする必要があります * 次に、そのリポジトリに変更をコミットしてプッシュする必要があります * 最後に、プルリクエストを作成する必要があります * 以上です!あとはcapgoチームがPRをレビューするのを待つだけです ## さらに読むべき文書 * Capgoの[CONTRIBUTINGMD](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTINGmd) * Capgoの[BOUNTYmd](https://github.com/Cap-go/capgo/blob/main/BOUNTYmd) # 暗号化されたバンドル > 手動アップデート機能をセルフホストモードで使用する方法 ## エンドツーエンド暗号化 バージョン4150以降、プラグインで暗号化された更新を送信できるようになりました 開始するには、まず秘密鍵を作成します Create a private key ```bash npx @capgo/cli key create ``` 次にzipを暗号化します Encrypt bundled zip ```bash npx @capgo/cli encrypt [path/to/zip] ``` このコマンドは`ivSessionKey`を出力します。これは更新ペイロードの`session_key`キーと共に送信する必要があります ```json { "version": "123", "url": "https://myservercom/app/updates/my-new-app-200zip", "session_key": "encrypted_session_key", } ``` その後、アプリは秘密鍵を使用して`session_key`を復号化し、復号化された`session_key`を使用して更新を復号化することができます 詳細はこちらをご覧ください: [セルフホスト型ライブアップデート ](https://capgo.app/blog/self-hosted-live-updates/) # はじめに > セルフアップデートサーバーの実行 独自の自動更新サーバーの実行方法について説明します ## はじめに この作業が役立つと思われる場合は、[Githubスポンサー](https://github.com/sponsors/riderx)になって私の活動をサポートすることをご検討ください ここで構築したコードを有料化する代わりにオープンソース化することを決めました。隠したり戦ったりする代わりにオープンにすることで、世界をより良い場所にできると信じています さらに、Capgoのツール開発に注力し、オープンで透明性のあるビジネスにしたいと考えています しかし、それを実現するためには、あなたを含む私たち全員が各自の役割を果たす必要があります 🥹 Capgoが合わない場合は、ご自身で価格を決めて、[ブートストラップ開発者](https://github.com/sponsors/riderx)を支援してください [貢献を検討する ](/docs/plugin/self-hosted/contributing/) ## 機能の比較 独自のサーバーを選択した場合、5分セットアップのフローは利用できなくなります\ 以下の機能をすべて自分で実装する必要があります | 機能 | Capgo | セルフホスト | | ------------ | ----- | ------ | | 更新 | ✅ | 🚧 | | 自動ロールバック | ✅ | 🚧 | | 失敗時のメールアラート | ✅ | 🚧 | | チャンネル | ✅ | 🚧 | | チャンネルオーバーライド | ✅ | 🚧 | | デバイスオーバーライド | ✅ | 🚧 | | チャンネル設定 | ✅ | 🚧 | | デバイス設定 | ✅ | 🚧 | | カスタムID | ✅ | 🚧 | | 自動チャンネル設定 | ✅ | 🚧 | | APIチャンネル | ✅ | 🚧 | | 更新統計 | ✅ | 🚧 | | ダウンロード失敗統計 | ✅ | 🚧 | | アプリ使用統計 | ✅ | 🚧 | | 更新の暗号化 | ✅ | 🚧 | Danger ユーザーに不正な更新を送信すると、アプリが破損する可能性があります > Capgoクラウドと独自サーバーを同時に使用することはできませんのでご注意ください Danger Over-the-Air (OTA)更新機能は、HTML、CSS、JavaScriptファイルの変更にのみ適用されます Capacitorプラグインなどのネイティブコードを変更した場合は、アプリストアに再提出して承認を得る必要があります ## 自動と手動の選択 自動モードでは、ロジックの一部がネイティブコードで処理され、更新はサーバーサイドで決定されます。これはより安全で、1つのデバイスやグループへの部分的なデプロイメントなど、きめ細かい更新が可能です 手動モードでは、すべてのロジックがJSで処理されます [自動更新 ](/docs/plugin/self-hosted/auto-update/) [手動 ](/docs/plugin/self-hosted/manual-update/) ## Capacitor updaterのインストール Capacitor updaterのインストール ```bash npm install @capgo/capacitor-updater npx cap sync ``` ## バンドルの準備 アプリに更新を送信するには、zipファイルにする必要があります 良好なzipファイルを確実に作成する最良の方法は、Capgo CLIを使用することです サーバーから提供するファイルのバンドルを作成 ```bash npx @capgo/cli@latest bundle zip ``` このzipファイルは独自のサーバーから提供する必要があります [自動更新 ](/docs/plugin/self-hosted/auto-update/) [手動 ](/docs/plugin/self-hosted/manual-update/) Note これが面倒な作業に思える場合は、Capgo Cloudの試用版をお試しください # 統計情報の処理 > セルフホステッドな統計エンドポイントの作成方法 プラグインの統計を保存するためのJavaScriptコードの例です ```typescript interface AppInfos { version_name: string action: 'delete' | 'reset' | 'set' | 'set_fail' | 'update_fail' | 'windows_path_fail' | 'canonical_path_fail' | 'directory_path_fail' | 'unzip_fail' | 'low_mem_fail' | 'download_fail' | 'update_fail' | 'download_10' | 'download_20' | 'download_30' | 'download_40' | 'download_50' | 'download_60' | 'download_70' | 'download_80' | 'download_90' | 'download_complete' version_build: string version_code: string version_os: string plugin_version: string platform: string app_id: string device_id: string custom_id?: string is_prod?: boolean is_emulator?: boolean } export const handler: Handler = async (event) => { const body = JSONparse(eventbody || '{}') as AppInfos const { platform, app_id, action, version_code, version_os, device_id, version_name, version_build, plugin_version, } = body consolelog('update asked', platform, app_id, action, version_os, version_code, device_id, version_name, version_build, plugin_version) // データベースに保存 return { status: 'ok' } } ``` このエンドポイントは次のようなJSONを返す必要があります: ```json { "status": "ok" } ``` ## アクション: * **delete**:バンドルがローカルで削除された時 * **reset**:アプリが組み込みバンドルにリセットされた時 * **set**:アプリが新しいバンドルを設定した時 * **set\_fail**:アプリが設定されたバンドルのIDを見つけられなかった時 * **update\_fail**:遅延後に`notifyAppReady`が呼び出されなかった時 * **download\_fail**:ダウンロードが完了しなかった時 * **download\_complete**:ダウンロードが完了した時 * **download\_xx**:ダウンロードの10%ごとに送信(例:download\_20、download\_70) * **update\_fail**:バンドルが指定された時間内に`notifyAppReady`の実行に失敗した時 # Manejo de Actualizaciones > セルフホストモードでのAuto Updateプラグインの使用 プラグインに更新を送信するJavaScriptのコード例です ```typescript interface AppInfos { version_name: string version_build: string version_os: string custom_id?: string is_prod?: boolean is_emulator?: boolean plugin_version: string platform: string app_id: string device_id: string } export const handler: Handler = async (event) => { const body = JSONparse(eventbody || '{}') as AppInfos const { platform, app_id, version_os, device_id, version_name, version_build, plugin_version, } = body consolelog('update asked', platform, app_id, version_os, device_id, version_name, version_build, plugin_version) if (version_name === '100') { return { version: '101', url: 'https://apiurlcom/mybuild_101zip', } } else if (version_name === '101') { return { version: '102', url: 'https://apiurlcom/mybuild_102zip', } } else { return { message: 'Error version not found' version: '', url: '', } } } ``` このエンドポイントは以下のようなJSONを返します: ```json { "version": "102", "url": "https://apiurlcom/mybuild_102zip" } ``` 更新がない場合やエラーの場合は、`message`キーと任意で`error`を追加します ```json { "message": "Version not found", "error": "The backend crashed", "version": "102", "url": "https://apiurlcom/mybuild_102zip" } ``` # 手動での更新 > Self-Hosted モードでマニュアルアップデートプラグインを使用する ## 設定 auto-updateを無効にするには、`capacitorconfigjson`に以下を追加してください。 ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false, } } } ``` ## 使用方法 このサンプルを使用するか、アプリ内でロジックを再作成することができます。 Caution コードで宣言された静的バージョンでユーザーに強制的にアプリを更新させています。これは推奨されません。サーバーから動的なバージョンを使用するべきです。 Danger このサンプルではバージョンチェック、復号化、チェックサム検証を行っていません。これらは独自に実装する必要があります。 ```tsx import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' let data = {version: ""} CapacitorUpdaternotifyAppReady() AppaddListener('appStateChange', async(state) => { if (stateisActive) { // ダウンロードの失敗を防ぐため、アプリがアクティブな時間中にダウンロードを実行 data = await CapacitorUpdaterdownload({ version: '004', url: 'https://github.com/Cap-go/demo-app/releases/download/004/distzip', }) } if (!stateisActive && dataversion !== "") { // ユーザーがアプリを離れた時に切り替えを実行 SplashScreenshow() try { await CapacitorUpdaterset(data) } catch (err) { consolelog(err) SplashScreenhide() // セットに失敗した場合、新しいアプリが非表示にする必要がある } } }) ``` Note これが大変に思える場合は、[Capgo trial](https://capgo.app/register/)を試してみることをご検討ください。これらすべてを代わりに処理してくれます。 # 설정 > Capacitor Updater で利用可能なすべての設定 更新システムをより細かく制御するために、以下の設定で構成することができます: ## `appReadyTimeout` > ネイティブプラグインがアップデートを「失敗」とみなすまでの待機時間(ミリ秒)を設定します AndroidとiOSのみで利用可能 デフォルト:`10000`(10秒) ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 } } } ``` ## `responseTimeout` > ネイティブプラグインがAPIタイムアウトとみなすまでの待機時間(ミリ秒)を設定します AndroidとiOSのみで利用可能 デフォルト:`20`(20秒) ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "responseTimeout": 1000 } } } ``` ## `autoDeleteFailed` > 失敗したバンドルを自動的に削除するかどうかを設定します AndroidとiOSのみで利用可能 デフォルト:`true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoDeleteFailed": false } } } ``` ## `autoDeletePrevious` > アップデート成功後に以前のバンドルを自動的に削除するかどうかを設定します AndroidとiOSのみで利用可能 デフォルト:`true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoDeletePrevious": false } } } ``` ## `autoUpdate` > アップデートサーバーを介した自動アップデートを使用するかどうかを設定します AndroidとiOSのみで利用可能 デフォルト:`true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` ## `updateUrl` > アップデートチェックを送信するURL/エンドポイントを設定します AndroidとiOSのみで利用可能 デフォルト:`https://apicapgo.app/updates` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "updateUrl": "https://examplecom/api/updates" } } } ``` ## `statsUrl` > アップデート統計を送信するURL/エンドポイントを設定します AndroidとiOSのみで利用可能。統計レポートを無効にするには""に設定します デフォルト:`https://apicapgo.app/stats` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "statsUrl": "https://examplecom/api/stats" } } } ``` ## `privateKey` > エンドツーエンドのライブアップデート暗号化用の秘密鍵を設定します AndroidとiOSのみで利用可能 `npx @capgo/cli key create`コマンドで秘密鍵を作成します デフォルト:`undefined` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "privateKey": "YOUR_KEY" } } } ``` ## `directUpdate` > アプリが更新/インストールされた直後にアップデートを直接インストールするようにプラグインを設定します。自動アップデートモードでのみ適用されます AndroidとiOSのみで利用可能 デフォルト:`undefined` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": true } } } ``` ## `resetWhenUpdate` Note ストアアップデートが発生した場合、ネイティブバージョンへの強制リセットを無効にします [ウェブアプリ](https://web.capgo.app/login)でのみ利用可能な設定が他にもたくさんあります プラグインを設定するには、以下の設定を使用します: ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } } ``` ## `directUpdate` アプリが更新/インストールされた直後にアップデートを直接インストールするようにプラグインを設定します。自動アップデートモードでのみ適用されます Caution この設定では、アップデートのインストール中にユーザーからアプリを隠す必要があります。そうしないと、ユーザーが操作中にアプリがリセットされます ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": true } } } ``` ## `defaultChannel` アプリのデフォルトチャンネルを設定します。チャンネルが上書きを許可している場合、Capgoで設定された他のチャンネルよりも優先されます ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "defaultChannel": "production" } } } ``` ## `appId` アプリのappIdを設定します。他の方法で取得したappIdを上書きします。Capgoとネイティブコードで異なるappIdを持ちたい場合に便利です Note これはappIdを設定する新しい方法です。古い方法も引き続きサポートされます ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "AppId": "comexampleapp" } } } ``` ## `version` アプリのバージョンを設定します。他の方法で取得したバージョンを上書きします。Capgoとネイティブコードで異なるバージョンを持ちたい場合に便利です Note これはバージョンを設定する新しい方法です。古い方法も引き続きサポートされます ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "version": "123" } } } ``` # 統計情報 API > 自己ホストモードでの自動更新プラグインの使用方法 ## 統計API バージョン130以降、アップデートシステムは統計を送信できるようになりました! デフォルトでは、すべての統計は使用状況を理解し研究するために我々のサーバーに送信されます Note 統計には個人データは送信されません。ランダムUUID、バージョンアップデート、ネイティブアプリのバージョン、プラットフォーム、アクション、アプリIDのみが送信されます 代わりにこのデータを自分のサーバーに送信したい場合は、以下の設定を変更してください: ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "statsUrl": "YOUR_URL" } } } ``` サーバーが受け取るデータは以下の通りです: ```tsx interface AppInfosStats { "action": "set", // set、delete、set_fail、reset、revertが可能 // 以下はアップデートと同じ情報 "app_id": "*******", // ストア内のアプリ識別子 "device_id": "*******", // アプリインストールごとの一意のID "platform": "ios", // またはandroid "custom_id": "user_1", // ユーザーを表す "version_name": "123", // Webビルドのバージョン "version_build": "120", // ネイティブビルドのバージョン "version_code": "120", // ネイティブビルドのビルド番号 "version_os": "16", // デバイスのOSバージョン "plugin_version": "400"// 異なるプラグインで異なる動作をさせるため "is_emulator": false, "is_prod": false, } ``` 空の文字列を使用して完全に無効にすることもできます。統計はプライバシーに配慮して作られており、プラグインの使用状況を理解し、問題解決と改善に役立てるためのものであることを覚えておいてください [アップデートの取り扱い ](/docs/plugin/self-hosted/handling-updates/) # AppFlowからCapgoへの移行 > Ionic AppFlowからCapgoへのアプリ移行完全ガイド ## AppFlow設定リファレンス 移行前に、現在の`capacitor.config.ts`のAppFlow設定を確認してください: ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { LiveUpdates: { appId: 'your-app-id', channel: 'Production', autoUpdateMethod: 'background', // または 'always latest'、'force update' maxVersions: 2 } } }; ``` この設定は、AppFlowの機能をCapgoの同等の機能にマッピングする際に役立ちます。 ## アップデート戦略の移行 ### バックグラウンドアップデート(デフォルト) AppFlowのデフォルトのバックグラウンドアップデートを使用している場合: ```typescript // Capgoでの同等の設定(capacitor.config.ts) { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: false, autoDeletePrevious: true } } } ``` ### 強制アップデート AppFlowの強制アップデート戦略を使用している場合: ```typescript // Capgoでの同等の設定(capacitor.config.ts) { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: true, keepUrlPathAfterReload: true } } } // 必要なJavaScriptコード import { CapacitorUpdater } from '@capgo/capacitor-updater'; import { SplashScreen } from '@capacitor/splash-screen'; CapacitorUpdater.addListener('appReady', () => { SplashScreen.hide(); }); CapacitorUpdater.notifyAppReady(); ``` ### 常に最新版 AppFlowの「always latest」戦略を使用している場合、Capgoでは以下のように実装します: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; import { App } from '@capacitor/app'; async function setupAlwaysLatest() { App.addListener('resume', async () => { const result = await CapacitorUpdater.download({ url: 'your-update-url' }); if (result) { await CapacitorUpdater.set({ id: result.id }); } }); } ``` ## APIメソッドの移行 | AppFlowメソッド | Capgo同等メソッド | 備考 | | ------------- | -------------- | ---------------- | | `sync()` | `download()` | 新しいアップデートをダウンロード | | `reload()` | `set()` | アップデートを即時適用 | | `setConfig()` | `setChannel()` | チャネル設定を更新 | ### 移行例 ```typescript // AppFlowコード import * as LiveUpdates from '@capacitor/live-updates'; const result = await LiveUpdates.sync(); if (result.activeApplicationPathChanged) { await LiveUpdates.reload(); } // Capgo同等コード import { CapacitorUpdater } from '@capgo/capacitor-updater'; const bundle = await CapacitorUpdater.download({ url: 'your-update-url' }); if (bundle) { await CapacitorUpdater.set({ id: bundle.id }); } ``` ## Capgoへ移行する理由 Ionic AppFlowのサービス終了に伴い、Capgoへの移行によってモバイルアプリ開発ワークフローをスムーズに移行できます。Capgoは、重要な機能をすべて維持しながら、機能の向上、パフォーマンスの改善、大幅なコスト削減を提供します。 ### 主なメリット * より高速なアップデート配信(10分から1分未満へ) * より手頃な価格(499ドル/月から14ドル/月へ) * すべてのプランにエンドツーエンド暗号化を含む * アップデートチャネルの制御性向上 * 包括的なCI/CD統合オプション ## 移行手順 ### 1. ライブアップデートの移行 #### 既存の依存関係を削除 ```bash npm uninstall @ionic/appflow # capacitor.config.jsonからAppFlow固有の設定を削除 ``` #### Capgoのインストール ```bash npm install @capgo/capacitor-updater npx cap sync ``` #### 設定の更新 `capacitor.config.json`にCapgoの設定を追加: ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true } } } ``` ### 2. CI/CDの移行 Capgoは柔軟なCI/CDオプションを提供: #### オプション1:既存のCI/CDを使用 人気のプラットフォームでCI/CDを設定する詳細なチュートリアル: * [iOSビルド設定](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) * [Androidビルド設定](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) * [GitHub Actions統合](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) #### オプション2:CI/CDサービス [マネージドサービス](https://cal.com/team/capgo/mobile-ci-cd-done-for-you)で私たちがCI/CD設定を代行します。 ### 3. チャネル設定 1. Capgoダッシュボードでチャネルを作成: ```bash npx @capgo/cli channel create production npx @capgo/cli channel create staging ``` 2. チャネル設定の構成: ```bash # プロダクションチャネルの設定 npx @capgo/cli channel update production --no-downgrade --no-upgrade # ステージングチャネルの設定 npx @capgo/cli channel update staging ``` ### 4. 移行のテスト 1. **ライブアップデートのテスト** ```bash # テストバンドルの作成とアップロード npx @capgo/cli bundle create --channel staging ``` 2. **アップデート受信の確認** * テスト端末にアプリをインストール * アップデートが正しく受信されることを確認 * アップデートのインストールプロセスを確認 * リカバリー機能をテスト ## トラブルシューティング ### 一般的な問題 #### アップデートが受信されない * チャネル設定の確認 * デバイスログの確認 * ネットワーク接続の確認 * バンドルバージョン形式の検証 ## 次のステップ 1. [Capgoアカウントの作成](/register/) 2. [クイックスタートガイド](/docs/getting-started/quickstart/)に従う 3. [CI/CD統合](/docs/getting-started/cicd-integration/)のセットアップ 4. [ライブアップデート](/docs/live-updates/)の設定 移行時に専任サポートが必要な企業チームは、[チームとの通話を予約](https://cal.com/team/capgo/capgo-enterprise-inquiry)してください。 # V2から V3へ > V2 から V3 へのアップグレード方法 auto-updateのバージョン3へのアップグレード方法について説明します。 ## まず最新のツールに移行します: ```bash npm remove -g capgo npm remove capacitor-updater npm i @capgo/cli npm i @capgo/capacitor-updater@3 npx cap sync ``` ## 以前の設定をすべて削除します: ```json { CapacitorUpdater: { autoUpdateURL: "https", }, } ``` これだけを残します: ```json { "CapacitorUpdater": { "autoUpdate": true } } ``` > ⚠️ `autoUpdateURL`で独自のサーバーを使用していた場合、このガイドは近日中に更新される予定です。それまでの間、新しいアップロードオプション`external`をご確認ください。これにより、Capgoクラウドにコードを送信せず、zipファイルのリンクのみを送信できます。これは厳格なプライバシーポリシーを持つ企業向けに作られました。externalモードでは、コードはCapgoサーバーに保存されず、URLのみを保存してデバイスに送信し、デバイスが直接ダウンロードします。標準的な方法では、コードは圧縮されて当社のサーバーに保存されますが、開封したり使用したりすることはありません。 ## 変更点 auto-updateのすべての設定がサーバーサイドになり、ユーザーへの更新の送信方法をより細かく制御できるようになりました。 これにより、チャンネルを使用して元に戻したり、1人のユーザーにだけデプロイしたりすることが可能になります。これらの設定はWeb インターフェイスに追加されます: * ネイティブ以下のリバートを無効化 * メジャーバージョン以上の更新を無効化 > ⚠️ これらはすべてのチャンネルでデフォルトでtrueになります これにより、プラグインを頻繁に更新する必要がなくなり、ほとんどの更新はサーバーサイドで行われ、ユーザー側での変更なしに更新を受け取ることができます > ⚠️ 更新がデフォルトになった時にリセットされます。ストアからの更新時にダウンロードしたバージョンをすべて削除したくない場合は、以下のようにしてください: ```json { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } ``` ## コードの更新 最後に、JSのすべてのインポートを以下から: ```plaintext import { CapacitorUpdater } from 'capacitor-updater' ``` 以下に更新します: ```plaintext import { CapacitorUpdater } from '@capgo/capacitor-updater' ``` その後、コードを再ビルドし`npm run build`、アセットを再度コピーします`npx cap copy` これで最新のauto-updateシステムをテストできるはずです バージョンの送信は以下のようになります: ```plaintext npx @capgo/cli@latest bundle upload ``` 以下の代わりに: ```plaintext npx capgo upload ``` ## 今後の展開 現在は最初のパブリックチャンネルのみが使用されていますが、将来的には複数のパブリックチャンネルが設定されている場合、パブリックは複数のパブリックチャンネルに変更される予定です ## よくある問題: * アップグレード後のビルドの問題: プラグインのソースコードをAndroid StudioやXcodeですでに開いている場合、同期で削除されないことがあります。これが問題の原因です。ネイティブIDEを開いて手動で`capacitor-updater`を削除し、`npx cap sync`を実行してください。これで解決するはずです # V3 から V4 へ > V3からV4へのアップグレード方法 ## アップグレードの理由 Discordコミュニティでの多くの対話を通じて、手動モードが非常に手動的すぎて安全でないことが分かりました。例えば、自動リバートが不可能で、手動更新に失敗した場合、ユーザーはアプリを削除して再インストールする必要があり、これは terrible UXでした。 その間、これを機会としてより多くの自由度を提供し、私が作成した悪いコードをすべて削除することにしました。 ## インストール `npm i @capgo/capacitor-updater@4` ## クラウド自動更新 アプリで基本的な例を使用している場合は、新しいバージョンに安全に移行できます。お楽しみください! ## セルフホスト自動更新 こちらも簡単です。変更点は以下の通りです: * 設定名が`autoUpdateUrl`から`updateUrl`に変更 * エンドポイントメソッドが`GET`から`POST`に変更 ## 手動ユーザー これが最も大きな変更ですが、良い方向への変更です!多くの改善が加えられました。注意深くお読みください。 ## 変更点 * `autoUpdateUrl`が`updateUrl`になりました。この設定は手動モードでも使用できるようになったためです * `cancelDelay`と`delayUpdate`を削除し、`setDelay`に統合 * セットに`versionName`が不要に * ほとんどの関数で返される`version`キーが`BundleInfo`オブジェクトに変更 ```typescript interface BundleInfo { id: string; version: string; downloaded: string; status: 'success' | 'error' | 'pending' | 'downloading' } ``` * 紛らわしい名前の変更(説明は難しいかもしれませんが、使用時には新しい名前が理解しやすいはずです): * `version`と呼ばれていたものは現在`bundle`を指します * `id`は10文字のランダムな文字列だった古い`version`を指し、このidはバンドルにアクセスする唯一の信頼できるユニークな方法です。例:`7Dfcd2RedN` * `version`は現在、バンドルに選択した`versionName`を指します。例:`100` * `updateUrl`が`get`から`post`に変更。カスタムヘッダーが一部のユーザーで問題となっていたため、またpostの方が論理的なため。以前のヘッダーはすべてボディに移動し、`cap_`プレフィックスは削除 * `versionName`メソッドが削除され、`getId`に統合 * listが`BundleInfo`のリストを返すように * `getId`を`getDeviceId`に改名 * `autoUpdate`がデフォルトでtrueに。手動モードを使用する場合は、falseに設定 ## 新機能 * メソッド`getLatest`:`updateUrl`で設定したサーバーから利用可能な最新バージョンを取得可能 * メソッド`setDelay`:`{kind: "background" | "kill" | "nativeVersion" | "date", value?: string}`を引数として受け取り、異なるモードの遅延を設定 * メソッド`next`:次のバックグラウンド化時にバージョンを設定。即時実行する`set`の反対 * メソッド`isAutoUpdateEnabled`:自動更新コンテキストにいるかどうかを確認 * イベント`downloadComplete`:ダウンロードが100%に達した時 * ダウンロードメソッドで`version`フィールドが必須に * `notifyAppReady`が手動モードでも必須に。10秒以内に呼び出されないと以前のバージョンに戻ります ## 貢献者 [@lincolnthree](https://github.com/lincolnthree/) この作業を始めていただき、ありがとうございます。このアップデートはあなたなしでは実現不可能でした。 # V4 から V5 へ > V4 から V5 へのアップデート方法 ## このアップグレードの理由 このメジャーバージョンは、Capacitorのメジャーバージョンに追従するためのものです まず、Capacitorの移行ガイドに従ってください: [https://capacitorjs.com/docs/updating/5-0](https://capacitorjs.com/docs/updating/5-0/) ## インストール `npm i @capgo/capacitor-updater@5` `その後、ネイティブコードの更新を同期します:` `npx cap sync` これだけです!とても簡単です! ## マニュアルモード getLatestで自身でアップデートを取得していた場合、小さな変更があります。 現在既に最新の場合は、catchに入ります。 利用可能なアップデートとは異なる応答はすべてそのような動作をします。 # Da V5 a V6 > V5 から V6 へのアップデート方法 ## アップグレードの理由 このメジャーバージョンは、Capacitorのメジャーバージョンに追従するためのものです まず、Capacitorの移行ガイドに従ってください: [https://capacitorjs.com/docs/updating/6-0](https://capacitorjs.com/docs/updating/6-0/) ## インストール `npm i @capgo/capacitor-updater@6` `その後、ネイティブコードの更新を同期します:` `npx cap sync` これで完了です!とても簡単ですね! # Introduction > Cagpoウェブアプリケーション入門 ## これは何ですか? Capgoには、プロジェクトの管理を支援する包括的なウェブアプリがあります。このウェブアプリはVuejsで構築されており、オープンソースです。ソースコードは[GitHub](https://github.com/Cap-go/capgo/tree/main/src/)で確認できます。\ ウェブアプリは[こちら](https://web.capgo.app/)で利用可能です。\ このウェブアプリでは、[チャンネルの管理](/docs/webapp/channels/)、[バージョンの管理](/docs/webapp/bundles/)、[デバイスの管理](/docs/webapp/devices/)、[ログの確認](/docs/webapp/logs/)、[請求の管理](/docs/webapp/settings/)、[アカウントの管理](/docs/webapp/settings/)が可能です。 ## 使用方法 まず、アカウントを作成するかログインする必要があります。画面中央の`ログイン`ボタンをクリックするだけで簡単にできます。ログインすると、ダッシュボードにリダイレクトされます。これがウェブアプリのメインページです。ここから他のすべてのページに移動できます。 ![login page](/login.webp) ## アカウントの作成 ログインフォームの下部にある`無料アカウントを作成`をクリックする必要があります。そこからはフォームに記入し、指示に従うだけの簡単な手順です。 ![create account](/create-account.webp) # API キーの管理 > API キーを管理する方法 ## APIキーで何ができますか? APIキーは再生成、削除、または新規追加が可能です ## すべてのAPIキーを確認するには? [APIキーページ](https://web.capgo.app/dashboard/apikeys/)にアクセスすると、すべてのAPIキーを確認できます ## 新しいAPIキーを追加するには? 新しいAPIキーを追加するには、小さなプラスボタンをクリックします ![add apikey](/apikeys-add.webp) そして、新しいAPIキーに付与したい権限を選択します。以下から選択できます: * 読み取り - APIキーはすべてのデータを読み取ることができます * アップロード - APIキーはCLIから新しいバージョンをアップロードし、読み取ることができます * すべて - APIキーはすべての操作を実行できます ![select perm](/apikeys-select-perm.webp) ## APIキーを削除するには? APIキーを削除するには、小さなゴミ箱ボタンをクリックします ![remove apikey](/apikeys-remove.webp) そしてAPIキーの削除を確認します ## APIキーを再生成するには? APIキーを再生成するには、小さな更新ボタンをクリックします ![generate apikey](/apikeys-regenerate.webp) そしてAPIキーの再生成を確認します # Bundel > バンドルの管理方法を学ぶ ## バンドルの一覧表示 まず、バンドルページを見てみましょう。[アプリをクリックして](/docs/webapp/main-page)から[バンドルタブをクリック](/docs/webapp/main-app-page)することでアクセスできます。 ![bundle list](/bundles.webp) ## バンドルの削除 バンドルを削除するには2つの方法があります: * 通常削除 * アンセーフ削除 アンセーフ削除は2024年8月12日にCapgoに追加されました。 2つの方法の違いは、削除後にバージョン番号を再利用できるかどうかです。 例えば、バージョン`100`を通常削除した後に、新しいバージョン`100`をアップロードしようとすると失敗します。 アンセーフ削除を使用した場合は、バージョン`100`を再度アップロードすることが可能です。 Danger バンドルをアンセーフ削除して再アップロードすることは非常に危険です。 プラグインで様々なバグや予期せぬ動作を引き起こす可能性があります。 公開チャンネルで使用されたバンドルに対しては決して使用すべきではありません。 そのため、アンセーフ削除には「super\_admin」権限が必要です。 ## 特定のバンドルの管理 バンドル一覧から管理したいバンドルをクリックします。クリックすると以下のような画面が表示されます: ![bundle info](/bundle-info.webp) このページの要素を見ていきましょう。 *** 最初に`Channel`が表示されます。これはこのバンドルがどのチャンネルのものかを示しています。クリックすることでチャンネルを変更できます。 クリックすると以下のような画面が表示されます: ![bundle change](/bundle-change.webp) `Set bundle to channel`では、任意のチャンネルのデフォルトとしてこのバンドルをリンクできます。\ `Open channel`では、このバンドルが属するチャンネルのページを開きます。\ `Unlink bundle from channel`では、このバンドルを現在のチャンネルからリンク解除します。 (**警告**: バンドルが複数のチャンネルにリンクされている場合、どのチャンネルのリンクを解除するかの選択肢は表示されません) *** 次に`Size`が表示されます。クリックするとこのバンドルをダウンロードできます。 以下のような画面が表示されます: ![download bundle](/download-bundle.webp) *** 最後に`Devices`セクションがあります。このバージョンを使用している全デバイスを確認できます。 # チャネル > チャネルはアプリケーションの更新を管理する方法です。複数のチャネルを持つことができ、各チャネルは複数のバージョンを持つことができます。これにより、本番環境で複数のアプリケーションバージョンを同時に実行することができます。 ## チャンネルの管理 まず、チャンネルページを見てみましょう。[アプリをクリック](/docs/webapp/main-page)して、[チャンネルタブをクリック](/docs/webapp/main-app-page)することでアクセスできます。 ![channel list](/channels.webp) ## チャンネルの作成 右下に表示されているプラスボタン(画像の`1.`)をクリックすると、新しいチャンネルを作成できるモーダルが開きます。 ![new channel](/new_channel_modal.webp) `Add`をクリックすると、リストに新しいチャンネルが表示されます。 ![after channel create](/post-channel-create.webp) ## 設定ミスとは? チャンネルの設定が無効な場合があります。その場合、大きな警告が表示され、1つ以上のチャンネルで`Misconfigured`列に`Yes`と表示されます。 詳細は[こちら](/docs/cli/commands/#disable-updates-strategy)をご覧ください。 ## チャンネルの削除 チャンネルの削除は簡単です。ゴミ箱アイコン(画像の`2.`)をクリックして削除を確認するだけです。 ## チャンネルの管理 チャンネル名をクリックすると、チャンネルを管理できるモーダルが開きます(画像の`3.`)。 このページは以下のように表示されます: ![manage channel](/manage_channel_main.webp) 各セクションを見ていきましょう。 まず`Bundle number`(画像の`1.`)です。これはそのチャンネルの現在のバージョンです。アップデートを提供する際、このチャネルは常にそのバージョンを提供しようとします\* \[^1]。 クリックすると[bundle](/docs/webapp/bundles/)ページに移動します。 次に`Shared to`(画像の`2.`)ページです。これは使用を推奨しません。新しい、より良いシステムが開発中です。 続いて強制デバイス(画像の`3.`)です。これは常にこのチャンネルからアップデートを受け取るデバイスのリストです。テスト目的で便利です。[devices](/docs/webapp/devices/)ページからデバイスをチャンネルに強制的に追加できます。 最後に設定(画像の`4.`)です。ここでチャンネルの動作を管理できます。 クリックすると以下のように表示されます: ![setting of channel](/channel_settings.webp) 設定リストは長いですが、すべて説明します。 *** まず`Default channel`です。**これが最も重要な設定です**\ チャンネルがデフォルトとしてマークされている場合、すべての新しいデバイスのデフォルトチャンネルとして使用されます。\ 言い換えると:新しいユーザーがいる場合、capgoはこのデフォルトチャンネルの最新バージョンを提供しようとします。 デフォルトに設定できるチャンネルは1つだけです。この規則を破ろうとすると、確認を求められます。 ![confirm make change](/confirm-make-default.webp) 確認後、古いデフォルトチャンネルのマークが解除され、新しいものがデフォルトとしてマークされます。 *** 次に`IOS`設定です。これは単純で、falseの場合、iOSデバイスはこのチャンネルからアップデートをダウンロードできません。 3番目は`Android`設定です。これは`IOS`と同様で、falseの場合、Androidデバイスはこのチャンネルからアップデートをダウンロードできません。 4番目は`Disable auto downgrade under native`設定です。これがtrueの場合、ネイティブバージョンからのダウングレードは不可能になります。つまり、App StoreやPlay Storeにバージョン`120`をアップロードし、チャンネルバージョンを`110`に設定しようとすると、アップデート(ダウングレード)は失敗します。 5番目は`Disable auto update`です。この設定は複雑で、詳細は[こちら](/docs/cli/commands/#disable-updates-strategy)で確認できます。 `Allow develoment build`について、これがtrueの場合、開発ビルドはこのチャンネルからアップデートをダウンロードできます。falseの場合、`prod`がfalseに設定されているすべてのアップデートリクエストは拒否されます。これは主にテスト目的で役立ちます。 7番目は`Allow Emulators`です。falseの場合、capgoはエミュレータからのアップデートリクエストを拒否します。これは主にテスト目的で役立ちます。 8番目は`Allow devices to self associate`です。これがtrueの場合、[setChannel](/docs/plugin/api/#setchannel)メソッドが利用可能になります。falseに設定されている場合にこのチャンネルで[setChannel](/docs/plugin/api/#setchannel)メソッドを呼び出そうとすると、呼び出しは失敗します。 # デバイス > デバイスの使用方法 ## すべてのデバイスの一覧を表示する まず、デバイスページを見てみましょう。[アプリをクリックして](/docs/webapp/main-page)、[デバイスタブをクリックする](/docs/webapp/main-app-page)ことでアクセスできます。 ![devices list](/devices.webp) ## 開発者デバイスのみを表示する [カスタムチャンネル](/docs/plugin/api/#setchannel)やカスタムバージョンを持つ上書きされたデバイスのみを表示したい場合があります。 それには`Filters`をクリックし、`Override`をクリックします。次のように表示されるはずです: ![filter devices](/overwrite-filter.webp) ## デバイスの設定 特定のデバイスを設定するには、テーブル内でそのデバイスをクリックすると、次のような画面が表示されます: ![show one device](/device-specific.webp) まず`Custom ID`ですが、これは実際にはあまり有用ではなく、現時点では何もしません。無視して構いません。 次にforce versionです。これが設定されている場合、このデバイスは**常に**このバージョンを受け取ります。これはチャンネルよりも優先されます。 最後にカスタムチャンネルです。これが設定されている場合、このデバイスはパブリック(デフォルト)チャンネルを無視し、このチャンネルのみを使用します。 # ログ > ログページを見つける ## すべてのログを表示 まず、ログページを見てみましょう。[アプリをクリックして](/docs/webapp/main-page)、[更新タブをクリックする](/docs/webapp/main-app-page)ことでアクセスできます。 そこから、このようなページが表示されます: ![show logs](/logs.webp) ## ログの詳細を取得する ログをクリックすると、[デバイスページ](/docs/webapp/devices/)に移動します # メインアプリページ > メインページには何が表示されますか? ## メインページには何が表示されますか? まず、アプリのメインページを見てみましょう: ![Main page screeshot](/main-app-page.webp) より詳しく見ていきましょう まず統計情報について。統計情報は現在改修中のため、現時点では文書化できません。完全に運用可能になった時点で統計セクションを追加する予定です。 次に、利用可能なすべてのメニューとその機能を見てみましょう ![Multiple sections screeshot](/app-multiple-sections.webp) 最初のボタンで[チャンネル](/docs/webapp/channels/)ページに移動します。そこでアプリのチャンネルの作成/削除/設定ができます\ 2番目のボタンで[バンドル](/docs/webapp/bundles/)ページに移動します。そこでアプリのすべてのバージョンを確認できます 3番目のボタンで[デバイス](/docs/webapp/devices/)ページに移動します。そこですべてのデバイスを確認できます。また、デバイス固有の上書き設定もそこから行えます 4番目のボタンで[更新](/docs/webapp/logs/)ページに移動します。そこでアプリが経験している詳細な統計(ログ)とエラーを確認できます # 메인 페이지 > このページではWebアプリケーションのメインページについて説明します ## メインページには何が表示されますか? まず、メインページを見てみましょう: ![Main page screeshot](/main-page.webp) 最初から見ていきましょう。最初に目に入るのは**統計情報**です。これにはアプリ固有の統計が含まれており、アプリの使用状況に応じて更新されます。 次に目に入るのは、利用可能なすべてのアプリのリストです。これは作成したアプリの数によって変化します。各アプリをクリックすると、そのアプリの詳細を見ることができます。 3番目に目に入るのは**APIキー**ボタンです。このボタンをクリックすると、[APIキー](/docs/webapp/api-keys/)ページに移動します。 次に目にするのは**test Capgo**ボタンです。このボタンは、あなたの名前と姓によって変化し、[設定](/docs/webapp/settings/)またはサポートページに移動します。 最後に、アプリを追加するためのボタンが表示されます。このボタンをクリックすると、Capgoに新しいアプリを追加するページに移動します。 # Authentification à deux facteurs > 2段階認証を管理してcapgoアカウントをより安全に保護 ## 2FAとは? 2FAは、悪意のある人があなたのcapgoアカウントを乗っ取るのを防ぐために設計されたセキュリティ対策です\ 追加のコードを要求することでこれを実現します。このコードはあなたのスマートフォンまたはハードウェア2FAキーに保存され、30秒ごとに変更されるため、推測することは不可能です ## このガイドの要件 * AndroidまたはiOSスマートフォン * インターネット接続 ## このガイドの内容 このガイドでは、`Google認証システム`を使用して2FAを設定する方法を説明します。同様の目的を果たす他のアプリも存在しますが、このガイドで2FAの全てを網羅することはできません ## 2FAの設定方法 まず、`Google認証システム`アプリをダウンロードしてください。Androidの場合は[Playストア](https://play.google.com/store/apps/details/?id=comgoogleandroidappsauthenticator2)から、iOSの場合は[App Store](https://appsapplecom/us/app/google-authenticator/id388497605/)からダウンロードできます 次に、[capgoのアカウント設定](https://web.capgo.app/dashboard/settings/account/)に移動してください。このような緑色のボタンが表示されるはずです ![Button MFA](/button-mfa.webp) クリックすると、QRコードが表示されます ![Enable MFA](/enable-mfa.webp) Danger ⚠️ 重要な注意事項:\ このQRコードは誰とも共有しないでください。アカウントからログアウトされる可能性があります 次に、スマートフォンで`Google認証システム`を開いてください。開いたら、以下の手順に従ってください: プラスボタンをクリックします ![MFA auth plus](/mfa-auth-plus.webp) その後、カメラボタンをクリックしてください ![MFA scan QR](/mfa-scan-qr.webp) カメラプレビューが開きます。PCに表示されているQRコードをスキャンしてください。スキャン後、このような画面が表示されるはずです: ![MFA final code](/mfa-final-code.webp) PCに戻り、確認ボタンをクリックしてください ![Verify MFA](/enable-mfa-verify.webp) 2FAコードを入力するウィンドウが開きます。この例では、コードは`095101`ですが、あなたの場合は異なります\ このコードを入力したら、`確認`ボタンをクリックしてください ![MFA verify code final](/mfa-verify-final-code.webp) 正しいコードを入力して`確認`を押すと、このようなポップアップが表示されます ![MFA enabled](/mfa-enabled.webp) おめでとうございます!\ 2FA認証が有効になりました 🎉 ## 2FAを使用してログインする方法 次回アカウントにログインする際、このようなウィンドウが表示されます ![MFA required](/mfa-required.webp) 認証システムを開いて認証コードをコピーしてください ![MFA login](/mfa-login.webp) Danger ⚠️ 重要な注意事項:\ コードが更新される前に`確認`を押してください。更新されると古いコードは無効になります コードをログインフォームに入力し、`確認`を押してください ![MFA login](/mfa-final-login-verify.webp) 正しいコードを入力すると、capgoダッシュボードが表示されます ## 2FAを無効にする方法 2FAを無効にするには、[capgoのアカウント設定](https://web.capgo.app/dashboard/settings/account/)に移動してください。このような赤いボタンが表示されるはずです: ![MFA disable button](/mfa-disable-button.webp) クリックすると、このような画面が表示されます ![MFA disabled](/mfa-disable-2.webp) `無効化`ボタンを押すだけです。これで完了です # Sistem organisasi > capgo アカウントでの組織の管理 ## 組織システムとは何ですか? 組織システムは、チームメンバーとアプリを安全に共有できるCapgoのシステムです ### Q: 組織の情報にアクセスするにはどうすればよいですか? 組織の情報にアクセスするには、[設定](/docs/webapp/settings/#how-to-get-to-the-settings-page)に移動し、`Organization settings`をクリックしてください ![Org settings](/orgs-settings.webp) ### Q: 表示する組織を変更するにはどうすればよいですか? 別の組織の設定を表示するには、名前の近くにある組織セレクターをクリックしてください ![Org selector](/org-selector.webp) これが表示されない場合は、設定ページにいない可能性があります ### Q: 組織のメンバーを確認するにはどうすればよいですか? `members`をクリックしてください ![Org Show members](/org-show-members.webp) ### Q: ユーザーを組織に招待するにはどうすればよいですか? `Add member`をクリックしてください ![Org add member](/orgs-add-member.webp) ポップアップが表示されます - ユーザーのメールアドレスを入力してください ![Invite to org](/invite-to-org-email-enter.webp) `invite`をクリックすると、別のポップアップが表示され、招待されたユーザーに付与する権限について尋ねられます ![Select perm for org](/select-perm-orgs.webp) すべての権限の内訳は以下の通りです: | 権限 | 読取 | アップロード | 書込 | 管理者 | スーパー管理者 | | ---------------- | -- | ------ | -- | --- | ------- | | アプリ統計の表示 | ✅ | ✅ | ✅ | ✅ | ✅ | | アプリチャンネルの表示 | ✅ | ✅ | ✅ | ✅ | ✅ | | デバイスの表示 | ✅ | ✅ | ✅ | ✅ | ✅ | | ログの表示 | ✅ | ✅ | ✅ | ✅ | ✅ | | バンドルの表示 | ✅ | ✅ | ✅ | ✅ | ✅ | | アプリの削除 | ❌ | ❌ | ❌ | ❌ | ✅ | | チャンネルの削除 | ❌ | ❌ | ❌ | ✅ | ✅ | | バージョンの削除 | ❌ | ❌ | ✅ | ✅ | ✅ | | 組織設定の変更 | ❌ | ❌ | ❌ | ✅ | ✅ | | 組織ユーザーの管理 | ❌ | ❌ | ❌ | ✅ | ✅ | | チャンネル設定の変更 | ❌ | ❌ | ✅ | ✅ | ✅ | | 新しいバージョンのアップロード | ❌ | ✅ | ✅ | ✅ | ✅ | | デバイスの変更 | ❌ | ❌ | ✅ | ✅ | ✅ | | チャンネルの現在バージョンの変更 | ❌ | ❌ | ✅ | ✅ | ✅ | | 新規チャンネルの作成 | ❌ | ❌ | ❌ | ✅ | ✅ | | バージョンの変更(メタデータ) | ❌ | ❌ | ✅ | ✅ | ✅ | | 課金管理 | ❌ | ❌ | ❌ | ❌ | ✅ | | バージョンの安全でない削除 | ❌ | ❌ | ❌ | ❌ | ✅ | ### Q: 組織内での課金はどのように行われますか? **スーパー管理者**権限を持つユーザーが、特定の組織の課金を管理できます プランは個人アカウントではなく、組織に紐付けられています Danger ⚠️ プランの購入は、現在選択している組織にのみ影響します ### Q: 複数の組織を作成できますか? いいえ、まだできません # Sistema di pagamento > capgo アカウントでの支払いの管理 ## これは何についてですか? このページではcapgoの支払いシステムに関する質問にお答えします #### Q: capgoのプランをアップグレードするにはどうすればよいですか? A: [設定](/docs/webapp/settings/#how-to-get-to-the-settings-page)に移動し、**プラン**ボタンをクリックしてcapgoプランをアップグレードできます ![Choose plan](/plans-button.webp) 次に、ニーズに最も合ったプランを選択し**購読する**をクリックします ![Subscribe to plan](/plans-subscribe.webp) その後、stripeページが開きます。そこで支払い情報を入力できます ![Stripe portal](/plans-stripe.webp) #### Q: 支払いは安全ですか? A: はい、支払いは完全にstripeによって管理されています。Capgoはクレジットカードの詳細にアクセスすることはありません。Stripeはセキュリティを非常に重視しています。[Stripeのセキュリティポリシーについて詳しく見る](https://stripecom/docs/security/) #### Q: 制限を超えた場合、capgoは自動的にプランをアップグレードしますか? A: いいえ、capgoが自動的にプランを変更することはありません #### Q: プランが制限に近づいた時、capgoからメールが送られてきますか? A: はい、capgoは使用状況についてメールでお知らせします #### Q: 購入したプランは、招待されている組織に影響しますか? A: いいえ、プランは現在選択している組織にのみ影響します [組織のドキュメント](/docs/webapp/organization-system/#q-how-is-billing-done-within-orgs)を参照してください #### Q: より柔軟なプランが必要な場合はどうすればよいですか? A: [capgoのサポートに直接お問い合わせください](/docs/getting-help#support-by-chat) #### Q: capgoの返金ポリシーはどのようになっていますか? A: 返金ポリシーは[こちら](https://capgo.app/return/)でご確認いただけます # 설정 > ユーザー設定の変更方法 ## 設定ページへのアクセス方法 最初に**FIRS\_NAME SECOND\_NAME**をクリックします。私の場合は**test Capgo**です。あなたの場合は、あなたの名前と姓になります。その後、**設定**をクリックします。 ![open settings](/settings-go.webp) ## ユーザー設定の変更 ユーザー設定を変更するには、アカウントのフォームに記入し、**更新**をクリックするだけです。 ![save change in account](/account-save.webp) 確認メッセージが表示されます。 ![acount updated](/account-updated.webp) ## パスワードの変更 パスワードを変更するには、設定ページに移動して**パスワード**をクリックします。その後、フォームに記入し、**更新**をクリックします。 ![update password](/update-passwd.webp) パスワードがCapgoのパスワードセキュリティルールに従っていない場合は、エラーメッセージが表示されます。 ![wrong password](/passwd-error.webp) # Selamat datang di Capgo > Capgo는 Capacitor와 모바일 개발팀을 위한 오픈 소스 실시간 업데이트 플랫폼으로, 사용자에게 수일이 아닌 수분 만에 실시간 업데이트를 제공할 수 있게 해줍니다 실시간 업데이트의 힘 사용자에게 최상의 경험을 제공하기 위해 실시간 앱 업데이트, 중요한 버그 수정, 콘텐츠 변경, 베타 기능 등을 원활하게 제공합니다 쉬운 통합 플러그인은 코드베이스에 통합하는 데 3단계만 필요하며, 며칠이 아닌 몇 분 만에 사용자에게 업데이트를 보낼 수 있습니다! 설치 Run `npx @capgo/cli@latest init [APIKEY]` 를 실행하여 시작하세요 광범위한 문서 온보딩 비디오와 함께 5분 안에 플러그인을 마스터하는 방법을 [문서](/docs/getting-started/quickstart/)에서 알아보세요 # 명령 > Capgo CLI 문서 ### 사용법 모든 명령어는 Capacitor 프로젝트가 올바르게 설정된 앱 폴더에서 실행되어야 합니다. [Capacitor 웹 앱을 위한 크로스 플랫폼 네이티브 런타임 ](https://capacitorjs.com/docs/getting-started/) ### **초기화** `npx @capgo/cli@latest init [apikey]` 이 메서드는 단계별로 온보딩을 도와줍니다. 앱을 Capgo에 추가하고, 업데이트를 검증하는 코드를 앱에 추가하며, 앱을 빌드하고, Capgo에 업로드한 후 업데이트가 제대로 작동하는지 확인하는 것을 도와줍니다. ### **로그인** `npx @capgo/cli login [apikey]` 이 메서드는 `apikey`를 기억하는데 사용됩니다. Note 모든 명령어에서 `--apikey=********`를 사용하여 재정의할 수 있습니다. **선택적으로 다음을 제공할 수 있습니다:** `--local` 로컬 저장소에 **apikey**를 저장하고 git에서 무시합니다. ## **진단** `npx @capgo/cli doctor` Capgo 패키지가 최신 상태인지 확인하는 명령어입니다. 이 명령어는 버그 리포트에도 유용합니다. ## 앱 ### **추가** `npx @capgo/cli app add [appId]` `[appId]` 앱 ID의 형식 `comtestapp`은 [여기](https://capacitorjs.com/docs/cli/commands/init/)에서 설명됩니다. > 💡 제공되지 않은 모든 옵션은 설정에서 추측됩니다. 선택적으로 다음을 제공할 수 있습니다: * `--icon [/path/to/my/icon]` Capgo 웹 앱에 표시될 사용자 정의 아이콘 * `--name [test]` 목록에 표시될 사용자 정의 이름 * `--apikey [key]` 계정에 연결할 API 키 * `--retention [retention]` 앱 번들의 보관 기간(일), 기본값 0 = 무제한 appId와 AppName을 위한 `capacitorconfigjson` 예시, 아이콘은 resources 폴더에서 추측됩니다. ```json { "appId": "eeforgrcapacitor_go", "appName": "Capgo", "webDir": "dist" } ``` \[나머지 번역은 동일한 형식으로 계속됩니다…]\* `--keep [numberToKeep]` 유지하고자 하는 패키지 수 (기본값 4) 예를 들어: 1001부터 10011까지 10개의 버전이 있고 `npx @capgo/cli cleanup [appId] --bundle=1000`을 사용하면 1001부터 1006까지 제거되고 1007부터 10011까지 유지됩니다 총 20개의 버전이 있고 번들 번호를 지정하지 않고 다음과 같이 실행하면: `npx @capgo/cli cleanup [appId] --keep=2` 18개의 버전이 제거되고 마지막 2개가 유지됩니다 > 이 명령은 확인을 요청하며, 유지되고 제거될 항목의 테이블을 보여줍니다 Note 이 명령은 현재 채널에서 사용 중인 번들은 무시합니다 ### **Encrypt** > **Warning**: 이 명령은 더 이상 사용되지 않으며 다음 주요 릴리스에서 제거될 예정입니다. 새로운 암호화 시스템을 사용해 주세요 `npx @capgo/cli bundle encrypt [path/to/zip]` 이 명령은 외부 소스에 코드를 저장하거나 테스트 목적으로 사용할 때 사용됩니다 선택적으로 다음을 제공할 수 있습니다: `--key [/path/to/my/private_key]` 개인 키의 경로 `--key-data [privateKey]` 인라인으로 사용하려는 개인 키 데이터 이 명령은 `ivSessionKey`를 출력하고 암호화된 zip을 생성하여 업로드 명령이나 복호화 명령과 함께 사용할 수 있습니다 ### **Encrypt V2** `npx @capgo/cli bundle encryptV2 [path/to/zip] [checksum]` 이 명령은 외부 소스에 코드를 저장하거나 테스트 목적으로 사용할 때 사용됩니다 체크섬은 번들의 sha256(—key-v2로 생성)이며, 복호화 후 파일의 무결성을 확인하는 데 사용됩니다 개인 키로 암호화되어 번들과 함께 전송됩니다 암호화 v2에서 체크섬은 번들의 “서명”이 되도록 업그레이드되었습니다 선택적으로 다음을 제공할 수 있습니다: `--key [/path/to/my/private_key]` 개인 키의 경로 `--key-data [privateKey]` 인라인으로 사용하려는 개인 키 데이터 `--json` 정보를 json으로 출력 이 명령은 `ivSessionKey`를 출력하고 암호화된 zip을 생성하여 업로드 명령이나 복호화 명령과 함께 사용할 수 있습니다 ### **Decrypt** `npx @capgo/cli bundle decrypt [path/to/zip] [ivSessionKey]` 선택적으로 다음을 제공할 수 있습니다: `--key [/path/to/my/private_key]` 개인 키의 경로 `--key-data [privateKey]` 인라인으로 사용하려는 개인 키 데이터 이 명령은 주로 테스트 목적으로 사용되며, zip을 복호화하고 콘솔에 복호화된 세션 키를 base64로 출력합니다 ### **Decrypt V2** `npx @capgo/cli bundle decryptV2 [path/to/zip] [ivSessionKey]` 선택적으로 다음을 제공할 수 있습니다: `--key [/path/to/my/private_key]` 개인 키의 경로 `--key-data [privateKey]` 인라인으로 사용하려는 개인 키 데이터 이 명령은 주로 테스트 목적으로 사용되며, zip을 복호화하고 콘솔에 복호화된 세션 키를 base64로 출력합니다 `--checksum [checksum]` 파일의 체크섬으로, 복호화 후 체크섬을 확인합니다 ### **Zip** `npx @capgo/cli bundle zip [appId]` `[appId]`는 앱 ID이며, 형식은 [여기](https://capacitorjs.com/docs/cli/commands/init/)에서 설명됩니다 선택적으로 다음을 제공할 수 있습니다: * `--path [/path/to/my/bundle]` 특정 폴더를 업로드 * `--bundle [100]` 파일 이름의 번들 버전 번호를 설정 * `--name [myapp]` 파일 이름을 재정의 * `--json` 정보를 json으로 출력 * `--no-code-check` 코드 검사를 무시하고 번들을 전송 * `--key-v2` 새로운 암호화 시스템을 사용 새로운 암호화 시스템은 파일의 무결성을 확인하기 위해 더 나은 체크섬을 사용하므로 필수입니다 ### **Compatibility** `npx @capgo/cli bundle compatibility [appId] -c [channelId]` `[appId]`는 앱 ID이며, 형식은 [여기](https://capacitorjs.com/docs/cli/commands/init/)에서 설명됩니다 `[channelId]` 새 채널의 이름 선택적으로 다음을 제공할 수 있습니다: * `--apikey [key]` 계정에 연결할 API 키 * `--text` 테이블에서 이모지 대신 텍스트 사용 * `--channel [channel]` 호환성을 확인할 채널 * `--package-json ` packagejson의 경로 모노레포에 유용 * `--node_modules ` node\_modules 경로 목록 모노레포에 유용 (쉼표로 구분 예: //node\_modules,/node\_modules) ## Channel ### **Add** `npx @capgo/cli channel add [channelId] [appId]` `[channelId]` 새로운 채널의 이름 `[appId]` 앱 ID 형식 `comtestapp`은 [여기](https://capacitorjs.com/docs/cli/commands/init/)에서 설명됩니다 ### **Delete** `npx @capgo/cli channel delete [channelId] [appId]` `[channelId]` 삭제하려는 채널의 이름 `[appId]` 앱 ID 형식 `comtestapp`은 [여기](https://capacitorjs.com/docs/cli/commands/init/)에서 설명됩니다 ### **List** `npx @capgo/cli channel list [appId]` `[appId]` 앱 ID 형식 `comtestapp`은 [여기](https://capacitorjs.com/docs/cli/commands/init/)에서 설명됩니다 선택적으로 다음을 제공할 수 있습니다: * `--apikey [key]` 계정에 연결할 API 키 ### **Set** `npx @capgo/cli channel set [channelId] [appId]` `[appId]`는 앱 ID이며, 형식은 [여기](https://capacitorjs.com/docs/cli/commands/init/)에서 설명됩니다 선택적으로 다음을 제공할 수 있습니다: * `--bundle [123]` 클라우드에 이미 전송된 앱 번들을 채널에 연결 * `--latest` `packagejson:version`에서 번들 버전을 가져옴, `--bundle`과 함께 사용할 수 없음 * `--state [ normal | default ]` 채널 상태를 설정, `normal` 또는 `default`가 될 수 있음 하나의 채널은 반드시 `default`여야 함 * `--downgrade` 채널이 디바이스에 다운그레이드 버전을 전송하도록 허용 * `--no-downgrade` 채널이 디바이스에 다운그레이드 버전을 전송하지 못하도록 함 * `--upgrade` 채널이 디바이스에 업그레이드(메이저) 버전을 전송하도록 허용 * `--no-upgrade` 채널이 디바이스에 업그레이드(메이저) 버전을 전송하지 못하도록 함 * `--ios` 채널이 iOS 디바이스에 버전을 전송하도록 허용 * `--no-ios` 채널이 iOS 디바이스에 버전을 전송하지 못하도록 함 * `--android` 채널이 안드로이드 디바이스에 버전을 전송하도록 허용 * `--no-android` 채널이 안드로이드 디바이스에 버전을 전송하지 못하도록 함 * `--self-assign` 디바이스가 이 채널에 자체 할당하도록 허용 * `--no-self-assign` 디바이스가 이 채널에 자체 할당하지 못하도록 함 * `--disable-auto-update STRATEGY` 이 채널에 대한 자동 업데이트 전략을 비활성화 가능한 옵션: major, minor, metadata, none * `--apikey [key]` 계정에 연결할 API 키 ## 업데이트 비활성화 전략 너무 오래된 버전에 대한 업데이트를 비활성화하는 방법이 몇 가지 있습니다\ Capgo는 네이티브 코드를 업데이트할 수 없으므로 이전 네이티브 코드가 있는 버전에서 업데이트된 네이티브 코드가 있는 버전으로의 업데이트는 불가능해야 합니다 이를 달성하는 방법이 몇 가지 있습니다 첫째, `major` 전략 `000` -> `100` 업데이트를 방지합니다 메이저는 강조 표시된 숫자입니다 (**1**00 및 **0**00)\ 둘째, `minor` 전략 `000` -> `110` 또는 `110`에서 `120`으로의 업데이트를 방지합니다 **주의하세요** 이 전략은 `010` -> `110` 업데이트는 방지하지 않습니다 셋째, `patch` 전략은 매우 엄격한 모드로 Capgo에 추가되었습니다 완전히 이해하지 않는 한 사용하지 않는 것이 좋습니다 업데이트를 허용하기 위해서는 다음 조건을 충족해야 합니다: * 새 버전과 이전 버전의 메이저가 동일해야 함 * 새 버전과 이전 버전의 마이너가 동일해야 함 * 새 버전의 패치가 이전 버전의 패치보다 커야 함 다음은 업데이트가 허용되거나 거부되는 시나리오의 예입니다 * 00311 -> 00314 ✅ * 000 -> 00314 ✅ * 00316 -> 00314 ❌ * 01312 -> 00314 ❌ * 10312 -> 00314 ❌ 마지막으로 가장 복잡한 전략인 `metadata` 전략\ 먼저 활성화한 후에는 채널에 필요한 메타데이터가 없기 때문에 업데이트가 **실패**할 것입니다\ 채널에 메타데이터가 없는 경우 다음과 같은 메시지가 표시됩니다: ![Cannot find metadata](/fail-metadata.webp) 이와 같은 것이 보이면 실패하는 채널의 현재 번들로 가서 메타데이터를 설정해야 합니다\ 먼저 어떤 채널이 실패하는지 확인하세요 `misconfigured` 열을 보면 알 수 있습니다 ![Misconfigured table](/misconfigured-table.webp) 실패한 채널로 이동하여 `Bundle number`를 클릭하세요. 이렇게 하면 번들 페이지로 이동합니다 ![Locate failing channel](/fail-channel-show.webp) 거기서 `Minimal update version` 필드를 채우세요. 이는 [semver](https://devhintsio/semver/) 형식이어야 합니다\ 입력한 값이 semver가 아니면 오류가 발생하지만, 모든 것이 정상적으로 진행되면 다음과 같은 화면이 표시됩니다: ![Set min version](/set-min-update-version.webp) 업데이트할 때마다 이 데이터를 수동으로 설정하고 싶지 않을 것입니다. 다행히도 CLI는 이 메타데이터 없이 업데이트를 보내는 것을 방지합니다 ![CLI fail no metadata](/cli-fail-no-metadata.webp) `metadata` 옵션을 사용할 때 번들을 올바르게 업로드하려면 유효한 semver와 함께 `--min-update-version`을 전달해야 합니다. 다음과 같이: ![CLI upload with metadata](/cli-upload-with-metadata.webp) `--min-update-version`이 호환성을 설정하는 유일한 방법은 아닙니다 `--auto-min-update-version`도 있습니다. 작동 방식은 다음과 같습니다 먼저, 현재 채널에 업로드된 버전을 확인합니다. `bundle compatibility` 명령과 동일한 방식으로 호환성을 확인합니다 둘째, 새 버전이 100% 호환되면 채널의 최신 버전에서 `min_update_version`을 재사용합니다 그렇지 않으면 새로 업로드된 버전의 번들 번호로 `min_update_version`을 설정합니다 이 옵션을 사용할 때는 항상 `min_update_version`에 대한 정보를 얻을 수 있습니다. 다음과 같이 보일 것입니다: ![Min update version](/min_update_version_info.webp) 새 버전이 호환되지 않으면 다음과 같이 보일 것입니다 ![Min update version not compatible](/min_update_version_not_compatible.webp) ## 종단 간 암호화 (신뢰 불필요) Capgo는 종단 간 암호화를 지원합니다. 이는 번들(코드)이 클라우드로 전송되기 전에 암호화되고 기기에서 복호화된다는 의미입니다. 이를 위해 RSA 키 쌍을 생성해야 하며, 다음 명령을 사용하여 생성할 수 있습니다 암호화 시스템은 RSA와 AES의 조합입니다. RSA 키는 AES 키를 암호화하는 데 사용되고, AES 키는 파일을 암호화하는 데 사용됩니다 암호화 시스템에 대한 자세한 내용은 아래를 참조하세요 ![How crypto works](/crypto_explained.webp) 암호화 스키마 ### 앱용 키 생성하기 `npx @capgo/cli key create` 선택적으로 다음을 사용할 수 있습니다: `--force`로 기존 키를 덮어쓸 수 있습니다. 이 명령은 앱에 키 쌍을 생성하고 개인 키를 안전한 곳에 저장하도록 요청합니다. 개인 키를 git에 커밋하거나 다른 사람과 공유하지 않는 것이 좋습니다 > 로컬 테스트 후에는 구성 파일에서 키를 제거하고 `key save`로 CI 단계에 추가하세요 ### 앱 구성에 키 저장하기 `npx @capgo/cli key save` 선택적으로 다음을 사용할 수 있습니다: `--key [/path/to/my/private_key]` 개인 키의 경로 `--key-data [privateKey]` 인라인으로 사용하려는 경우 개인 키 데이터. 이 명령은 권장 사항을 따랐고 앱과 구성에 키를 커밋하지 않은 경우 유용합니다 ## CI 통합 작업을 자동화하기 위해 GitHub 액션을 사용하여 서버에 푸시하는 것을 권장합니다 [GitHub 액션 튜토리얼](https://capgo.app/blog/automatic-build-and-release-with-github-actions/) ## 데모 앱 [GitHub - Cap-go/demo-app](https://github.com/Cap-go/demo-app/) API 키로 CI 환경 변수를 구성하는 것을 잊지 마세요 # 0.x에서 1.x로의 CLI > 0.x에서 1.x로 업그레이드하는 방법 CLI에는 중요한 변경 사항이 없습니다 주요 변경 사항은 충돌을 피하고 새로운 이름을 모든 곳에서 일관되게 사용하기 위해 `--version` 인자를 `--bundle`로 변경한 것입니다 # 암호화 > 새로운 암호화로 데이터를 암호화하는 방법 이 문서는 새로운 암호화 시스템으로 데이터를 암호화하고 이전 시스템을 제거하는 방법을 설명합니다 새로운 암호화 시스템에 대해 [블로그 포스트](/blog/introducing-end-to-end-security-to-capacitor-updater-with-code-signing)에서 자세히 알아보세요 *** 먼저, 다음 명령어로 새로운 키 쌍을 생성하세요: ```bash npx @capgo/cli key create ``` 이 명령어는 앱에 새로운 키 쌍을 생성합니다. 개인 키를 안전한 곳에 보관하는 것이 매우 중요합니다. 절대로 개인 키를 소스 제어에 커밋하거나 신뢰할 수 없는 당사자와 공유해서는 안 됩니다 이 명령어는 또한 Capacitor 설정에서 이전 키를 제거하지만, 이전 키 파일은 제거하지 않습니다. CLI는 앱스토어 업데이트를 받지 않고 이전 플러그인을 계속 사용하는 앱들에 대해 라이브 업데이트를 계속 전송할 수 있도록 이전 키를 유지합니다. 이는 마이그레이션을 용이하게 합니다 마이그레이션 중에 “이전 앱을 지원하고 마이그레이션을 용이하게 하기 위해 새로운 채널에서 암호화를 설정하시겠습니까?”라는 질문을 받으면 동의해 주세요. 이는 Capacitor 설정에 새로운 “defaultChannel” 옵션을 추가할 것입니다. 이로 인해 앱은 “encryption\_v2” 채널을 사용하게 됩니다. 이는 새로운 암호화가 이를 지원하는 앱에서만 사용되도록 보장합니다. 앱스토어 업데이트를 받지 않은 앱들은 이전 기본 채널을 계속 사용하게 됩니다 *** 이제 JS 번들을 빌드하고 새로운 채널에 업로드해야 합니다. 다음 명령어를 실행하세요: ```bash npx @capgo/cli bundle upload --channel encryption_v2 ``` *** 그런 다음, 앱이 “encryption\_v2” 채널에 자체 할당될 수 있도록 다음 명령어를 실행하세요: Caution 이는 새로운 “defaultChannel” 옵션이 작동하기 위해 필요합니다 ```bash npx @capgo/cli channel set encryption_v2 --self-assign ``` *** 이제 앱을 실행할 수 있습니다. 새로운 암호화 시스템을 사용하게 됩니다 이전 채널에 새로운 JS 번들을 업로드하려면 다음 명령어만 실행하면 됩니다: ```bash npx @capgo/cli bundle upload --channel production ``` *** Capacitor 설정에 대해서는 걱정하지 않아도 됩니다. 이는 절대 Capgo에 업로드되지 않습니다 모든 사용자가 앱을 업데이트했을 때(3\~4개월이 걸릴 수 있음), Capacitor 설정에서 “defaultChannel”을 제거할 수 있습니다 그런 다음, 다음 명령어로 이전 채널을 제거할 수 있습니다: ```bash npx @capgo/cli channel delete encryption_v2 ``` *** “encryption\_v2” 채널을 삭제한 후, 이를 기본값으로 사용하는 모든 앱은 “production” 채널을 사용하기 시작합니다 # 개요 Capgo의 Live Updates 기능을 사용하여 앱의 JavaScript 번들을 원격으로 실시간 업데이트하세요. 앱 스토어 검토 과정 없이 JS 업데이트를 사용자에게 직접 푸시하여 즉시 버그를 수정하고 새로운 기능을 배포할 수 있습니다. Note Live Updates는 JavaScript 번들 변경으로 제한됩니다. 플러그인 추가/제거나 네이티브 프로젝트 구성 변경과 같은 네이티브 코드를 업데이트해야 하는 경우, 앱 스토어에 새로운 네이티브 바이너리 빌드를 제출해야 합니다. ## Live Updates 작동 방식 Capgo의 Live Update 시스템에는 두 가지 주요 구성 요소가 있습니다: 1. 앱에 설치하는 Capgo SDK. SDK는 사용 가능한 업데이트를 확인하고 백그라운드에서 다운로드합니다. 2. 특정 사용자 그룹에 업데이트를 대상으로 지정할 수 있는 채널. 채널을 사용하여 `Production`, `Staging`, `Dev`와 같은 다양한 릴리스 트랙을 관리할 수 있습니다. 새로운 JS 번들을 Capgo에 업로드하고 채널에 할당하면, 해당 채널로 구성된 앱의 Capgo SDK가 업데이트를 감지하고 다운로드합니다. 앱이 다시 시작될 때 새로운 번들이 로드됩니다. ## 시작하기 Live Updates 사용을 시작하려면 다음 단계를 따르세요: 1. [Capgo 퀵스타트](/docs/getting-started/quickstart)를 완료하여 Capgo에서 앱을 설정하고 Capgo SDK를 설치하세요. 2. 앱 코드에서 앱 초기화가 완료된 후 `CapacitorUpdater.notifyAppReady()`를 호출하세요. 이는 Capgo SDK에 앱이 업데이트를 받을 준비가 되었음을 알립니다. 3. JS 번들을 빌드하고 Capgo에 업로드하세요: ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. 앱을 열고 업데이트가 다운로드될 때까지 기다리세요. 다음 명령으로 상태를 확인할 수 있습니다: ```shell npx @capgo/cli@latest app debug ``` 5. 업데이트가 다운로드되면 앱을 닫았다가 다시 열어 새로운 번들을 로드하세요. 자세한 내용은 [Live Updates 배포하기](/docs/getting-started/deploy) 가이드를 참조하세요. ## Capgo CLI Capgo CLI는 개발자가 자체 CI/CD 파이프라인에서 Capgo 서비스와 상호 작용할 수 있게 해주는 강력한 도구입니다. CLI를 사용하면 빌드가 생성되고 배포되는 시기를 세밀하게 제어할 수 있어, Capgo를 기존 엔터프라이즈 워크플로우에 통합할 수 있습니다. ### Capgo CLI의 용도는 무엇인가요? Capgo CLI는 라이브 업데이트 워크플로우에서 더 많은 제어와 유연성이 필요한 개발자와 팀을 위해 설계되었습니다. CI/CD 파이프라인에서 CLI를 사용하면 다음과 같은 작업을 수행할 수 있습니다: * Capgo의 내장 자동화에 의존하지 않고 정확히 언제 업데이트를 빌드하고 배포할지 결정 * 빌드와 배포 단계 사이에 코드 서명, QA 테스트 또는 관리자 승인과 같은 자체 프로세스 삽입 * 기존 DevOps 도구 및 워크플로우에 Capgo 통합 ### 인증 Capgo CLI를 사용하려면 API 키로 인증해야 합니다. Capgo 계정 설정에서 API 키를 생성할 수 있습니다. 로그인하고 API 키를 안전하게 저장하려면 다음을 실행하세요: ```shell npx @capgo/cli@latest login [API_KEY] ``` 이 명령은 나중에 사용할 수 있도록 저장됩니다. 로그인 후에는 각 명령마다 API 키를 제공할 필요가 없습니다. ### 다른 CLI 도구와의 주요 차이점 다른 라이브 업데이트 CLI 도구에 익숙하다면, Capgo CLI에 대한 몇 가지 주요 사항을 알아두어야 합니다: * Capgo는 라이브 업데이트 기능 세트에만 중점을 두기 때문에 개발과 CI/CD 사용 사례 모두에 단일 CLI를 사용합니다. * Capgo CLI는 별도의 설치 단계가 필요하지 않습니다. `@capgo/cli` 패키지에 번들로 제공되며 `npx`를 사용하여 직접 실행할 수 있습니다. * Capgo의 CLI는 라이브 업데이트 워크플로우에 특화되어 있어 더 일반적인 CLI 도구에서 찾을 수 있는 일부 기능이나 명령이 포함되지 않을 수 있습니다. ## 다음 단계 [ 채널](/docs/live-updates/channels/) [채널을 사용하여 다양한 릴리스 트랙을 관리하고 특정 사용자에게 업데이트를 대상으로 지정하는 방법을 알아보세요.](/docs/live-updates/channels/) [ 롤백](/docs/live-updates/rollbacks/) [업데이트로 인해 문제가 발생할 경우 이전 JS 번들 버전으로 롤백하는 방법을 알아보세요.](/docs/live-updates/rollbacks/) [ 업데이트 동작](/docs/live-updates/update-behavior/) [앱에서 업데이트가 다운로드되고 적용되는 방식과 시기를 사용자 지정하세요.](/docs/live-updates/update-behavior/) [ 빠른 업데이트](/docs/live-updates/differentials/) [빠른 업데이트를 사용하여 업데이트 프로세스를 가속화하는 방법을 알아보세요.](/docs/live-updates/differentials/) # Gambaran Umum > Capgo CLI 명령에 대한 자세한 설명 Capgo CLI는 Capgo 앱과 배포를 관리하기 위한 명령어 세트를 제공합니다. 이 참조 문서는 각 명령어의 옵션과 사용 예시를 포함한 상세 정보를 제공합니다. ## 명령어 [ init](/docs/cli/reference/init/) [새로운 Capgo 앱 초기화](/docs/cli/reference/init/) [ login](/login/) [Capgo 서비스 인증](/login/) [ doctor](/docs/cli/reference/doctor/) [잠재적 문제에 대한 Capgo 설정 확인](/docs/cli/reference/doctor/) [ app](/docs/cli/reference/app/) [Capgo 앱 관리](/docs/cli/reference/app/) [ bundle](/docs/cli/reference/bundle/) [앱 번들 관리](/docs/cli/reference/bundle/) [ channel](/docs/cli/reference/channel/) [릴리스 채널 관리](/docs/cli/reference/channel/) [ key](/docs/cli/reference/key/) [앱 서명 키 관리](/docs/cli/reference/key/) ## CI 통합 작업을 자동화하기 위해 GitHub Actions를 사용하여 Capgo에 업데이트를 푸시하는 것을 추천합니다. 자세한 내용은 [GitHub Actions 튜토리얼](https://capgo.app/blog/automatic-build-and-release-with-github-actions/)을 확인하세요. CI 환경 변수에 Capgo API 키를 설정하는 것을 잊지 마세요. ## 데모 앱 CI 통합이 포함된 완전한 Capgo 앱 예제는 [GitHub의 데모 앱](https://github.com/Cap-go/demo-app/)을 확인하세요. # 계정 `account` 명령어를 사용하여 Capgo 계정을 관리할 수 있습니다 ### id `npx @capgo/cli account id` 계정 ID를 가져옵니다 옵션: * `-a, --apikey `: 계정에 연결할 API 키 # 앱 `app` 명령을 사용하면 Capgo 앱을 관리할 수 있습니다 ### add `npx @capgo/cli app add [appId]` Capgo 계정에 새 앱을 추가합니다 `[appId]`는 `com.example.app` 형식의 앱 ID입니다. 자세한 내용은 [Capacitor 문서](https://capacitorjs.com/docs/cli/commands/init/)를 참조하세요 > 💡 제공되지 않은 경우 모든 옵션은 `capacitor.config.json`에서 추측됩니다 옵션: * `--icon [path]`: Capgo 웹 앱에 표시할 사용자 지정 아이콘 경로 * `--name [name]`: 앱 목록에 표시할 사용자 지정 이름 * `--apikey [key]`: 계정에 연결할 API 키 * `--retention [days]`: 앱 번들의 보존 기간(일) (기본값: 0 = 무제한) ### set `npx @capgo/cli app set [appId]` Capgo 계정의 기존 앱을 업데이트합니다 옵션: * `--icon [path]`: Capgo 웹 앱에 표시할 사용자 지정 아이콘 경로 * `--name [name]`: 앱 목록에 표시할 사용자 지정 이름 * `--retention [days]`: 앱 번들의 보존 기간(일) (기본값: 0 = 무제한) * `--apikey [key]`: 계정에 연결할 API 키 ### list `npx @capgo/cli app list [appId]` Capgo 계정의 모든 앱을 나열합니다 옵션: * `--apikey [key]`: 계정에 연결할 API 키 ### delete `npx @capgo/cli app delete [appId]` Capgo 계정에서 앱을 삭제합니다 옵션: * `--apikey [key]`: 계정에 연결할 API 키 * `--bundle`: 특정 번들 버전만 삭제 ### debug `npx @capgo/cli app debug [appId]` 앱의 디버그 정보를 표시합니다 옵션: * `--apikey [key]`: 계정에 연결할 API 키 * `--device`: 특정 기기 디버그 ### setting `npx @capgo/cli app setting [path]` 앱의 Capacitor 구성을 편집합니다 `[path]`는 변경하려는 설정의 경로입니다 (예: `appId` 또는 `plugins.CapacitorUpdater.autoUpdate`) `--string` 또는 `--bool` 중 하나를 제공해야 합니다: * `--string `: 설정을 문자열 값으로 설정 * `--bool `: 설정을 부울 값으로 설정 # 번들 `bundle` 명령어를 사용하면 앱 번들을 관리할 수 있습니다 ### upload `npx @capgo/cli bundle upload [appId]` 앱에 대한 새 번들을 업로드합니다 옵션: * `-a, --apikey `: 계정에 연결할 API 키 * `-p, --path `: 업로드할 폴더 경로 (`capacitorconfig`의 `webDir` 기본값) * `-c, --channel `: 번들을 연결할 채널 * `-e, --external `: Capgo Cloud에 업로드하는 대신 외부 URL에 연결 * `--iv-session-key `: 외부 번들 URL의 IV 및 세션 키 설정 * `--s3-region `: S3 버킷의 리전 * `--s3-apikey `: S3 엔드포인트의 API 키 * `--s3-apisecret `: S3 엔드포인트의 API 시크릿 * `--s3-endpoint `: S3 엔드포인트 URL * `--s3-bucket-name `: S3 버킷 이름 * `--s3-port `: S3 엔드포인트의 포트 * `--no-s3-ssl`: S3 업로드에 대한 SSL 비활성화 * `--key `: 공개 서명 키의 사용자 지정 경로 (v1 시스템) * `--key-data `: 공개 서명 키 데이터 (v1 시스템) * `--key-v2 `: 개인 서명 키의 사용자 지정 경로 (v2 시스템) * `--key-data-v2 `: 개인 서명 키 데이터 (v2 시스템) * `--bundle-url`: 번들 URL을 stdout에 출력 * `--no-key`: 서명 키를 무시하고 서명되지 않은 업데이트 전송 * `--no-code-check`: 소스 코드의 `notifyAppReady()`와 루트 폴더의 `indexhtml` 확인 건너뛰기 * `--display-iv-session`: 업데이트 암호화에 사용된 IV 및 세션 키 표시 * `-b, --bundle `: 업로드할 번들 버전 번호 * `--min-update-version `: 이 업데이트를 적용하는데 필요한 최소 앱 버전 (메타데이터를 통해 자동 업데이트가 비활성화된 경우에만 사용) * `--auto-min-update-version`: 네이티브 패키지 버전을 기반으로 최소 업데이트 버전 자동 설정 * `--ignore-metadata-check`: 업로드 시 메타데이터(node\_modules) 확인 무시 * `--ignore-checksum-check`: 업로드 시 체크섬 확인 무시 * `--timeout `: 업로드 프로세스의 타임아웃(초) * `--multipart`: S3에 데이터를 업로드하기 위해 멀티파트 프로토콜 사용 (더 이상 사용되지 않음, 대신 `--tus` 사용) * `--tus`: tus 프로토콜을 사용하여 번들 업로드 * `--tus-chunk-size `: tus 업로드의 청크 크기 * `--partial`: Capgo Cloud에 변경된 파일만 업로드 * `--partial-only`: Capgo Cloud에 부분 파일만 업로드하고 압축 파일은 건너뜀 (큰 번들에 유용) * `--encrypted-checksum `: 외부 번들의 암호화된 체크섬(서명) * `--auto-set-bundle`: `capacitorconfigjson`에서 번들 버전 자동 설정 * `--dry-upload`: 실제 파일을 업로드하지 않고 업로드 프로세스의 테스트 실행 (테스트에 유용) * `--package-json `: `packagejson` 파일 경로의 쉼표로 구분된 목록 (모노레포에 유용) * `--node-modules `: `node_modules` 디렉토리 경로의 쉼표로 구분된 목록 (모노레포에 유용) * `--encrypt-partial`: 부분 업데이트 파일 암호화 * `--delete-linked-bundle-on-upload`: 업로드하기 전에 대상 채널에서 현재 연결된 번들 삭제 ### compatibility `npx @capgo/cli bundle compatibility [appId]` 특정 채널과의 번들 호환성을 확인합니다 옵션: * `-a, --apikey `: 계정에 연결할 API 키 * `-c, --channel `: 호환성을 확인할 채널 * `--text`: 결과를 이모지 대신 텍스트로 출력 * `--package-json `: `packagejson` 파일 경로의 쉼표로 구분된 목록 (모노레포에 유용) * `--node-modules `: `node_modules` 디렉토리 경로의 쉼표로 구분된 목록 (모노레포에 유용) ### delete `npx @capgo/cli bundle delete [bundleId] [appId]` 앱에서 번들을 삭제합니다 옵션: * `-a, --apikey `: 계정에 연결할 API 키 ### list `npx @capgo/cli bundle list [appId]` 앱의 모든 번들을 나열합니다 옵션: * `-a, --apikey `: 계정에 연결할 API 키 ### cleanup `npx @capgo/cli bundle cleanup [appId]` 주요 버전에 대한 이전 번들을 정리하고 지정된 수의 최신 번들을 유지합니다 옵션: * `-b, --bundle `: 정리할 주요 버전 번호 * `-a, --apikey `: 계정에 연결할 API 키 * `-k, --keep `: 유지할 번들 수 (기본값: 4) * `-f, --force`: 확인 없이 강제 제거 ### decrypt `npx @capgo/cli bundle decrypt [zipPath] [sessionKey]` 서명된 zip 번들을 복호화합니다 옵션: * `--key `: 개인 서명 키의 사용자 지정 경로 * `--key-data `: 개인 서명 키 데이터 ### encrypt `npx @capgo/cli bundle encrypt [zipPath]` zip 번들을 암호화합니다 옵션: * `--key `: 개인 서명 키의 사용자 지정 경로 * `--key-data `: 개인 서명 키 데이터 ### encryptV2 `npx @capgo/cli bundle encryptV2 [zipPath] [checksum]` 새로운 암호화 방식을 사용하여 zip 번들을 암호화합니다 옵션: * `--key `: 개인 서명 키의 사용자 지정 경로 * `--key-data `: 개인 서명 키 데이터 * `-j, --json`: 결과를 JSON으로 출력 ### decryptV2 `npx @capgo/cli bundle decryptV2 [zipPath] [checksum]` 새로운 암호화 방식을 사용하여 zip 번들을 복호화합니다 옵션: * `--key `: 개인 서명 키의 사용자 지정 경로 * `--key-data `: 개인 서명 키 데이터 * `--checksum `: 무결성을 확인할 번들의 체크섬 ### zip `npx @capgo/cli bundle zip [appId]` 번들용 zip 파일을 생성합니다 옵션: * `-p, --path `: 압축할 폴더 경로 (`capacitorconfig`의 `webDir` 기본값) * `-b, --bundle `: 파일 이름에 사용할 번들 버전 번호 * `-n, --name `: zip의 사용자 지정 파일 이름 * `-j, --json`: 결과를 JSON으로 출력 * `--no-code-check`: 소스 코드의 `notifyAppReady()`와 루트 폴더의 `indexhtml` 확인 건너뛰기 * `--key-v2`: 새로운 암호화 방식 사용 (v2) * `--package-json `: `packagejson` 파일 경로의 쉼표로 구분된 목록 (모노레포에 유용) # 채널 `channel` 명령어를 사용하여 릴리스 채널을 관리할 수 있습니다 ### add `npx @capgo/cli channel add [channelId] [appId]` 앱의 새로운 채널을 생성합니다 옵션: * `-d, --default`: 새 채널을 기본 채널로 설정 * `-a, --apikey `: 계정에 연결할 API 키 ### delete `npx @capgo/cli channel delete [channelId] [appId]` 앱에서 채널을 삭제합니다 옵션: * `-a, --apikey `: 계정에 연결할 API 키 * `--delete-bundle`: 채널과 연결된 번들 삭제 ### list `npx @capgo/cli channel list [appId]` 앱의 모든 채널을 나열합니다 옵션: * `-a, --apikey `: 계정에 연결할 API 키 ### currentBundle `npx @capgo/cli channel currentBundle [channel] [appId]` 특정 채널의 현재 번들을 가져옵니다 옵션: * `-c, --channel `: 현재 번들을 가져올 채널 * `-a, --apikey `: 계정에 연결할 API 키 * `--quiet`: 번들 버전만 출력 ### set `npx @capgo/cli channel set [channelId] [appId]` 채널의 속성을 설정합니다 옵션: * `-a, --apikey `: 계정에 연결할 API 키 * `-b, --bundle `: 채널에 설정할 번들 버전 번호 * `-s, --state `: 채널의 상태 설정 (`default` 또는 `normal`) * `--latest`: `packagejson`의 최신 버전을 번들 버전으로 사용 * `--downgrade`: 네이티브 버전 이하로 다운그레이드 허용 * `--no-downgrade`: 네이티브 버전 이하로 다운그레이드 비활성화 * `--upgrade`: 네이티브 버전 이상으로 업그레이드 허용 * `--no-upgrade`: 네이티브 버전 이상으로 업그레이드 비활성화 * `--ios`: iOS 기기로 업데이트 전송 허용 * `--no-ios`: iOS 기기로 업데이트 전송 비활성화 * `--android`: Android 기기로 업데이트 전송 허용 * `--no-android`: Android 기기로 업데이트 전송 비활성화 * `--self-assign`: 기기가 이 채널에 자체 할당되도록 허용 * `--no-self-assign`: 이 채널에 대한 기기 자체 할당 비활성화 * `--disable-auto-update `: 이 채널의 자동 업데이트 전략 비활성화 (옵션: `major`, `minor`, `metadata`, `patch`, `none`) * `--dev`: 개발 기기로 업데이트 전송 허용 * `--no-dev`: 개발 기기로 업데이트 전송 비활성화 * `--emulator`: 에뮬레이터 기기로 업데이트 전송 허용 * `--no-emulator`: 에뮬레이터 기기로 업데이트 전송 비활성화 * `--package-json `: `packagejson` 파일 경로의 쉼표로 구분된 목록 (모노레포에 유용) # 의사 `npx @capgo/cli doctor` 이 명령어는 Capgo 패키지의 최신 버전을 사용하고 있는지 확인합니다 버그 리포팅에도 유용하게 사용됩니다 # 초기화 `npx @capgo/cli@latest init [apikey]` 이 명령어는 다음의 단계를 통해 안내합니다: * Capgo에 앱 추가 * 업데이트 검증을 위한 코드를 앱에 추가 * 앱 빌드 * Capgo에 앱 업로드 * 업데이트가 제대로 작동하는지 확인 지원 # 키 `key` 명령어를 사용하여 앱 서명 키를 관리할 수 있습니다 ### save `npx @capgo/cli key save` Capacitor 설정에 base64로 인코딩된 암호화 키를 저장합니다 (CI에서 유용) 옵션: * `-f, --force`: 새 키 생성 강제 * `--key`: Capacitor 설정에 저장할 키 파일 경로 * `--key-data`: Capacitor 설정에 직접 저장할 키 데이터 ### create `npx @capgo/cli key create` 새 암호화 키를 생성합니다 옵션: * `-f, --force`: 새 키 생성 강제 ### delete\_old `npx @capgo/cli key delete_old` 이전 암호화 키를 삭제합니다 # 로그인 `npx @capgo/cli login [apikey]` 이 명령어는 이후 사용을 위해 Capgo API 키를 저장합니다 Note 모든 명령어에 `--apikey=`를 전달하여 저장된 API 키를 재정의할 수 있습니다 옵션: * `--local`: API 키를 로컬 저장소에 저장하고 `gitignore`에 추가합니다 # FAQ > Capgo에 대한 자주 묻는 질문 여기에서 답변하지 않은 질문이 있다면 언제든 문의해 주세요! [Discord](https://discordcom/invite/VnYRvBfgA6)에서 이슈를 제기하거나 질문하는 것 모두 가능합니다. ### ”코드 푸시”란 무엇인가요? 코드 푸시는 “무선 업데이트”(OTA)라고도 하며, Capacitor 개발자가 프로덕션 앱을 업데이트할 수 있게 해주는 클라우드 서비스입니다. Capgo는 현재 Android와 iOS에서 작동하며, 향후 Capacitor가 작동하는 모든 플랫폼에서 작동할 예정입니다. “코드 푸시”는 [Microsoft](https://appcenterms/)와 [Expo](https://expodev/)의 React Native 커뮤니티에서 사용하는 배포 기능의 이름을 참조한 것이며, 둘 다 Capacitor를 지원하지 않습니다. ### 번들과 릴리스의 차이점은 무엇인가요? “릴리스”는 앱 스토어용 바이너리를 준비하는 것을 의미합니다. 나중에 번들을 생성하기 위해 Capgo는 앱 스토어에 배포된 정확한 바이너리를 알아야 합니다. “번들”은 릴리스에 적용하여 새로운 코드로 업데이트할 수 있는 패치를 의미합니다. `npx @capgo/cli app update` 명령어는 로컬의 새로운 코드로부터 번들을 생성하여 사용자에게 배포하는데 사용됩니다. ### 로드맵은 무엇인가요? 우리의 프로젝트 보드는 공개되어 있으며 다음에서 확인할 수 있습니다: [https://github.com/orgs/Cap-go/projects](https://github.com/orgs/Cap-go/projects/) 우리 팀은 공개적으로 운영되므로 언제든지 우리가 무엇을 하고 있는지 확인할 수 있습니다. Github 이슈나 [Discord](https://discordcom/invite/VnYRvBfgA6)를 통해 로드맵이나 우선순위에 대한 질문에 기꺼이 답변해 드리겠습니다. ### Capgo를 팀과 함께 사용할 수 있나요? 네! 모든 요금제는 무제한 개발자를 지원합니다. 각 조직에 대해 앱 메트릭(MAU, 저장소, 대역폭)만 제한합니다. 자세한 내용은 [Teams](https://capgo.app/pricing/)를 참조하세요. ### Capgo가 소스 코드를 저장하나요? 아니요. Capgo 서버는 귀하의 소스 코드를 보지 않습니다. `npx @capgo/cli app update`를 실행할 때 `npx @capgo/cli` 도구는 앱 스토어에 보내는 것과 동일한 컴파일된 코드만 업로드합니다. 추가 보안이 필요한 경우 엔드 투 엔드 암호화를 사용하여 Capgo 서버에 업로드하기 전에 번들을 암호화할 수 있습니다. 개인정보 보호정책도 참조하세요: [https://capgo.app/privacy](https://capgo.app/privacy/) ### CI 시스템에서 Capgo를 사용할 수 있나요? 네. Capgo는 CI 시스템에서 사용하도록 설계되었습니다. [Android와 Github Actions](https://capgo.app/blog/automatic-capacitor-android-build-github-action/)와 [IOS](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/), 그리고 [Gitlab](https://capgo.app/blog/setup-ci-and-cd-gitlab/)에 대한 가이드를 발행했으며, 다른 CI 시스템도 비슷할 것입니다. 문제가 발생하면 GitHub 이슈나 Discord를 통해 문의해 주시기 바랍니다. ### Firebase Remote Config나 Launch Darkly와는 어떤 관계가 있나요? 코드 푸시는 기기에 새로운 코드를 추가하거나 코드를 교체할 수 있게 합니다. Firebase Remote Config와 Launch Darkly는 모두 구성 시스템입니다. 새 버전을 배포하지 않고도 앱의 구성을 변경할 수 있게 해주지만, 코드를 교체하기 위한 것은 아닙니다. ### 이것이 추가하는 의존성 공간은 얼마나 되나요? 최근에 측정하지는 않았지만, 코드 푸시 라이브러리가 Capacitor 앱에 1메가바이트 미만을 추가할 것으로 예상됩니다. 이것이 우선순위가 될 때 더 작게 만들 수 있는 방법을 알고 있습니다. 크기가 문제가 된다면 알려주세요! ### 코드 푸시가 큰 애플리케이션에서도 작동하나요? 네. 코드 푸시로 업데이트할 수 있는 애플리케이션 크기에는 제한이 없습니다. [아래](https://capgo.app/docs/faq/#what-types-of-changes-does-capgo-code-push-support)에 언급된 대로, Capgo는 크기에 관계없이 애플리케이션의 모든 JS 코드를 변경할 수 있습니다. 참고: 크기가 클수록 사용자가 업데이트를 다운로드하기 어려워집니다. 앱을 가능한 한 작게 유지하는 것을 권장합니다. ### Capgo 코드 푸시를 어디에 사용할 수 있나요? 다음과 같은 다양한 용도로 사용되는 것을 보았습니다: * 프로덕션 앱의 긴급 수정 * 이전 버전 앱 사용자에게 버그 수정 배포 * 지속적인 배포(예: 매시간) 대부분의 앱 스토어는 앱의 동작을 크게 변경하는 코드 배포를 금지한다는 점에 유의하세요. 자세한 내용은 [아래](https://capgo.app/docs/faq/#how-does-this-relate-to-the-appplay-store-review-process-or-policies)를 참조하세요. ### Capgo에서 “MAU”는 어떻게 계산되나요? MAU는 “월간 활성 사용자”입니다. 지난 30일 동안 서버에 접속한 모든 기기를 MAU로 계산합니다. 지난 30일 동안 서버에 접속하지 않은 기기는 계산하지 않습니다. 기기가 앱을 다시 설치할 때마다 새로운 MAU로 계산됩니다. 이는 Apple 스토어의 개인정보 보호 제한 때문에 발생합니다. 사용자가 앱을 재설치하면 같은 기기를 추적할 수 없습니다. 개발 중에는 앱을 재설치할 때마다 새로운 MAU가 계산됩니다. TestFlight 다운로드나 Android에서 채널을 전환할 때도 마찬가지입니다. 앱 업데이트는 새로운 Device ID를 생성하지 않습니다. > 첫 설정 후에는 중복 기기 수를 줄이기 위해 개발 기기와 에뮬레이터를 비활성화하는 것을 권장합니다. ### Capgo 코드 푸시를 사용할 수 없는 경우는 무엇인가요? 위에서 언급했듯이, Capgo는 앱 스토어 정책을 위반하는 데 사용해서는 안 됩니다. 자세한 내용은 [아래](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines)를 참조하세요. 또한 Capgo는 네이티브 코드(예: Android의 Java/Kotlin 또는 iOS의 Objective-C/Swift) 변경을 지원하지 않습니다. 네이티브 코드를 변경한 경우 업데이트를 시도하는 동안 도구가 경고를 표시합니다. ### Capgo가 스토어에 제출해 주나요? Capgo는 현재 앱 스토어에 자동으로 제출하는 기능을 지원하지 않습니다. 향후 이 기능을 추가할 계획이지만, 현재는 기존 프로세스를 계속 사용하여 앱 스토어에 제출해야 합니다. 이 프로세스를 자동화하기 위해 [Android CI 가이드](https://capgo.app/blog/automatic-capacitor-android-build-github-action/)와 [iOS CI 가이드](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/)를 사용할 수 있습니다. ### Capgo는 디스크에 무엇을 어디에 저장하나요? Capgo 업데이터(앱 빌드 시 포함됨)는 capacitor가 코드를 로드할 수 있는 유일한 디렉토리에 최신 다운로드된 번들을 캐시합니다. Android에서는 `/data/user/0/comexampleapp/code_cache/capgo_updater`에 있지만, 해당 경로의 기본은 Android 시스템에서 제공되며 런타임에 동적으로 변경될 수 있습니다. iOS 기기에서는 데이터가 `Library/Application Support/capgo` 아래에 저장됩니다. Capgo 명령줄 도구(예:`npx @capgo/cli app update`)는 npm 캐시에 디스크에 설치되며, 로그인 정보는 홈 디렉토리의 `~/capgo`에 저장됩니다. ### Capacitor Hot Reload와 어떤 관계가 있나요? Capacitor의 Hot reload는 개발 단계에서만 사용하는 기능이며, Code push는 프로덕션용입니다. Hot reload는 개발 중에 기기에서 코드를 변경할 수 있게 해주는 Capacitor의 기능입니다. 로컬 머신에 연결하기 위한 프록시로 Capacitor 앱을 빌드해야 합니다. Code push는 프로덕션 환경에서 기기의 코드를 변경할 수 있게 해주는 기능입니다. 플랫폼에 따라 다양한 기술을 사용하여 이를 가능하게 합니다. ### Capgo code push는 어떤 종류의 변경을 지원하나요? Capgo는 애플리케이션의 모든 JS 코드를 변경할 수 있습니다. 앱 코드와 생성된 코드가 포함됩니다. 네이티브 코드 변경이 필요하지 않은 한 `packages.json`의 의존성도 업데이트할 수 있습니다. 네이티브 코드(예: Android의 Java/Kotlin 또는 iOS의 Objective-C/Swift) 변경을 지원할 계획은 없으며, 네이티브 코드가 변경된 것이 감지되면 번들에 포함되지 않을 것이라고 도구가 경고할 것입니다. ### 웹을 지원하나요? 웹은 이미 이러한 방식으로 작동하기 때문에 code push가 필요하지 않습니다. 사용자가 웹 앱을 열 때 필요한 경우 서버에서 최신 버전을 다운로드합니다. 웹에서 code push가 필요한 사용 사례가 있다면 알려주세요! ### iOS, Android, Mac, Windows, Linux 등에서 작동하나요? 네. 지금까지는 Android와 iOS 지원에 집중했지만, code push는 결국 Capacitor가 작동하는 모든 곳에서 작동할 것입니다. 더 많은 플랫폼으로 확장하기 전에 code push를 안정적이고 안전하게 제공하는 데 필요한 모든 인프라를 구축하고 있습니다. ### Capgo는 어떤 OS 버전을 지원하나요? Capgo는 Capacitor가 지원하는 것과 동일한 Android 버전을 지원합니다. Capacitor는 현재 Android API 레벨 22+ 및 iOS 13.0+를 지원합니다: [https://capacitorjs.com/docs/main/reference/support-policy](https://capacitorjs.com/docs/main/reference/support-policy/) ### Capgo는 어떤 버전의 Capacitor를 지원하나요? Capgo는 현재 Capacitor의 최신 안정 릴리스만 지원합니다. 시간이 지남에 따라 유지 관리하는 데 필요한 인프라를 아직 구축하지 않았기 때문에 Capacitor의 이전 버전도 지원할 수 있습니다. 앞으로 더 많은 버전의 Capacitor를 지원할 예정이며, 엔터프라이즈 고객을 위해 모든 버전을 지원할 계획입니다. [https://github.com/Cap-go/capgo/issues/1100](https://github.com/Cap-go/capgo/issues/1100/) Capgo는 Flutter 안정 버전을 추적하며 일반적으로 안정 릴리스 후 몇 시간 이내에 업데이트됩니다. 이러한 업데이트를 수행하는 시스템은 자동화되어 있으며 실행하는 데 몇 분이 걸립니다. 그런 다음 서버에 게시하기 전에 추가 수동 확인 단계를 수행합니다. ### App/Play Store 검토 프로세스나 정책과 어떤 관련이 있나요? 개발자는 해당 스토어를 선택할 때 스토어 제공업체와의 계약을 준수해야 합니다. Code push는 개발자가 iOS 및 Android의 스토어 정책을 준수하면서 앱을 업데이트할 수 있도록 설계되었습니다. React Native에서 사용 가능한 다양한 상용 제품과 유사합니다(예: [Microsoft](https://appcenter.ms/), [Expo](https://expo.dev/)) Microsoft도 그들의 솔루션이 앱 스토어를 준수하는 방법에 대한 가이드를 게시합니다: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) Code push는 앱 스토어 전반에 걸쳐 널리 사용되는 기술입니다. 제가 알고 있는 모든 대형 앱들이 code push를 사용합니다. 주의해야 할 주요 정책은 앱의 동작을 크게 변경하지 않는 것입니다. 자세한 내용은 [아래](https://capgo.app/docs/faq/#does-capgo-comply-with-play-store-guidelines)를 참조하세요. ### Capgo는 Play Store 가이드라인을 준수하나요? 네. Play Store는 업데이트 도구와 관련하여 두 가지 제한 사항을 제공합니다. 1. 업데이트는 인터프리터 또는 가상 머신을 사용해야 합니다(Capgo는 Dart Virtual Machine 사용) [https://support.google.com/googleplay/android-developer/answer/9888379?hl=en](https://support.google.com/googleplay/android-developer/answer/9888379/?hl=en) ```plaintext An app distributed via Google Play may not modify, replace, or update itself
using any method other than Google Play's update mechanism. Likewise, an app
may not download executable code (such as dex, JAR, .so files) from a
source other than Google Play. *This restriction does not apply to code
that runs in a virtual machine or an interpreter* where either provides
indirect access to Android APIs (such as JavaScript in a webview or
browser)

Apps or third-party code, like SDKs, with interpreted languages (JavaScript,
Python, Lua, etc.) loaded at run time (for example, not packaged with the
app) must not allow potential violations of Google Play policies
``` 2. 앱의 변경 사항은 기만적이어서는 안 됩니다(예: 업데이트를 통한 앱의 목적 변경) [https://support.google.com/googleplay/android-developer/answer/9888077](https://support.google.com/googleplay/android-developer/answer/9888077/) 앱을 통해 제공하는 내용에 대해 사용자에게 명확히 알리고 Capgo를 통한 중요한 동작 변경으로 사용자의 기대를 위반하지 마세요. Capgo는 Play Store 가이드라인과 호환되도록 설계되었습니다. 하지만 Capgo는 도구이며, 다른 도구와 마찬가지로 남용될 수 있습니다. Play Store 가이드라인을 위반하기 위해 의도적으로 Capgo를 남용하는 것은 Capgo [이용 약관](https://capgo.app/tos/)을 위반하는 것이며 계정이 해지될 수 있습니다. 마지막으로, code push 서비스는 업계에서 널리 사용됩니다(제가 알고 있는 모든 대형 앱이 사용합니다)하며 공개적으로 사용 가능한 여러 code push 서비스가 있습니다(예: expo.dev & appcenter.ms). 이는 잘 확립된 경로입니다. Microsoft도 그들의 react native “codepush” 라이브러리가 앱 스토어를 준수하는 방법에 대한 가이드를 게시합니다: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### Capgo는 App Store 가이드라인을 준수하나요? 네. Play Store와 마찬가지로 App Store도 기술적 및 정책적 제한 사항을 제공합니다. ```plaintext 3.2.2
해석된 코드는 애플리케이션에 다운로드될 수 있지만 다음과 같은 코드인 경우에만 가능합니다:
(a) App Store에 제출된 애플리케이션의 의도된 목적과 일치하지 않는 기능을 제공함으로써 애플리케이션의 주요 목적을 변경하지 않음
(b) 다른 코드나 애플리케이션을 위한 스토어나 상점을 만들지 않음
(c) OS의 서명, 샌드박스 또는 기타 보안 기능을 우회하지 않음
Capgo는 iOS에서 업데이트를 위한 인터프리터 전용 제한을 준수하기 위해 커스텀 Dart 인터프리터를 사용합니다. 업데이트를 통해 기만적인 행위(예: 업데이트를 통한 앱 목적 변경)를 하지 않는 한, Capgo(또는 다른 코드 푸시 솔루션)를 통한 업데이트는 업계의 표준 관행이며 App Store 가이드라인을 준수합니다. App Store 가이드라인을 위반하기 위해 Capgo를 의도적으로 악용하는 것은 Capgo [서비스 약관](https://capgo.app/tos/)을 위반하는 것이며 계정이 해지될 수 있습니다. Microsoft도 그들의 react native "codepush" 라이브러리가 앱스토어를 준수하는 방법에 대한 가이드를 제공합니다: [https://github.com/microsoft/react-native-code-push#store-guideline-compliance](https://github.com/microsoft/react-native-code-push/#store-guideline-compliance) ### 내 국가에서 Capgo를 사용할 수 있나요?[](https://capgo.app/docs/faq/#can-i-use-capgo-in-my-country "Direct link to Can I use Capgo in my country?") 우리는 어떤 국가에서도 Capgo 접근을 제한하지 않았습니다. 일부 국가에서는 국가 내에서 접근할 수 있는 URL에 제한이 있다는 것을 인지하고 있습니다. Capgo는 현재 R2 스토리지와 Cloudflare 워커를 포함한 Cloudflare Cloud를 호스팅에 사용합니다. Capgo가 사용하는 URL은 다음과 같습니다: - [https://apicapgo.app](https://apicapgo.app/) -- `npx @capgo/cli` 명령줄 도구가 Capgo 서버와 상호작용하고 사용자 기기의 Capgo 업데이터가 업데이트를 확인하는데 사용됩니다 - [https://*r2cloudflarestoragecom](https://*r2cloudflarestoragecom/) -- `npx @capgo/cli` 명령줄 도구가 번들을 업로드하고 다운로드하는데 사용됩니다 이러한 URL들이 모두 귀하의 국가에서 접근 가능하다면 Capgo는 작동할 것입니다. 만약 귀하의 지역에서 이러한 URL들의 접근을 차단해야 한다면, 알려주시면 해결책을 찾아보겠습니다. 프록시 서버가 한 가지 옵션입니다. ### Capgo를 자체 호스팅할 수 있나요?[](https://capgo.app/docs/faq/#can-i-self-host-capgo "Direct link to Can I self-host Capgo?") 네, Capgo를 자체 호스팅할 수 있습니다. 가이드는 아직 작성되지 않았지만, 코드는 오픈 소스이며 [https://github.com/cap-go/capgo](https://github.com/cap-go/capgo/)에서 이용 가능합니다. ### 코드 푸시가 작동하려면 인터넷이 필요한가요?[](https://capgo.app/docs/faq/#does-code-push-require-the-internet-to-work "Direct link to Does code push require the internet to work?") 네. 일반 인터넷과 별도로 업데이트를 배포하기 위한 서버를 운영할 수도 있지만, 기기에 업데이트를 전송하려면 어떤 형태든 네트워크 연결이 필요합니다. ### 네트워크 연결이 없을 때 Capgo는 어떻게 영향을 받나요?[](https://capgo.app/docs/faq/#how-is-capgo-affected-by-lack-of-network-connectivity "Direct link to How is Capgo affected by lack of network connectivity?") Capgo 업데이터(Capgo로 앱을 빌드할 때 앱에 포함됨)는 네트워크 연결 문제에 대응할 수 있도록 설계되었습니다. 기본 업데이트 동작에서, 애플리케이션이 실행될 때 Capgo 업데이터에 알리고, 이는 Capgo 서버에 업데이트를 요청하기 위한 네트워크 요청을 별도의 스레드에서 실행합니다. 우리는 의도적으로 애플리케이션이 수행할 수 있는 다른 작업을 차단하지 않기 위해 별도의 스레드를 사용합니다. 네트워크 요청이 실패하거나 시간 초과되면, 업데이터는 다음 애플리케이션 실행 시 다시 확인을 시도합니다. Capgo 명령줄 도구(예: `npx @capgo/cli app update`)는 작동하기 위해 네트워크 연결이 필요합니다. Capgo를 사용하여 앱을 배포하는 경우, CI 시스템이 네트워크 연결을 가지고 있는지 확인해야 합니다. ### 사용자가 오랫동안 업데이트하지 않고 업데이트를 놓치면 어떻게 되나요?[](https://capgo.app/docs/faq/#what-happens-if-a-user-doesnt-update-for-a-long-time-and-misses-an-update "Direct link to What happens if a user doesn't update for a long time and misses an update?") 우리의 구현은 항상 요청하는 기기에 맞춤화된 업데이트를 전송하여 요청자를 항상 사용 가능한 최신 버전으로 업데이트합니다. 따라서 사용자가 한동안 업데이트하지 않으면 중간 업데이트를 "놓치게" 됩니다. 업데이트 서버는 애플리케이션의 필요에 따라 다음 증분 버전이나 최신 버전으로 응답하도록 변경될 수 있습니다. 대체 업데이트 동작이 중요하다면 알려주시기 바랍니다. ### Capgo는 Capacitor와 어떤 관계가 있나요?[](https://capgo.app/docs/faq/#how-does-capgo-relate-to-capacitor "Direct link to How does Capgo relate to Capacitor?") Capgo는 코드 푸시를 추가하는 Capacitor 플러그인입니다. Capgo는 Capacitor의 대체품이 아닙니다. 이미 알고 있고 좋아하는 Capacitor 도구를 계속 사용할 수 있습니다. 우리는 Capacitor의 최신 안정 릴리스를 추적하고 코드 푸시 플러그인이 이와 함께 작동하도록 업데이트합니다. ### 업데이트는 언제 발생하나요?[](https://capgo.app/docs/faq/#when-do-updates-happen "Direct link to When do updates happen?") 기본적으로 Capgo 업데이터는 앱 시작 시 업데이트를 확인합니다. 백그라운드 스레드에서 실행되며 UI 스레드를 차단하지 않습니다. 모든 업데이트는 사용자가 앱을 사용하는 동안 설치되며 앱이 다음에 재시작될 때 적용됩니다. [package:capgo_code_push](https://pubdev/packages/capgo_code_push/)를 사용하여 Capgo 업데이터를 수동으로 실행할 수도 있으며, 이를 통해 푸시 알림을 포함한 언제든지 업데이트를 트리거할 수 있습니다. Capgo 업데이터는 네트워크를 사용할 수 없거나 서버가 다운되었거나 도달할 수 없을 때도 앱이 정상적으로 계속 실행되도록 설계되었습니다. 서버에서 업데이트를 삭제하기로 결정한 경우에도 모든 클라이언트는 정상적으로 계속 실행됩니다. 패치를 롤백하는 기능을 추가했습니다. 가장 간단한 방법은 이전 번들을 채널에 다시 연결하여 실행 취소하는 것입니다. ### app_id를 비밀로 유지해야 하나요?[](https://capgo.app/docs/faq/#do-i-need-to-keep-my-app_id-secret "Direct link to Do I need to keep my app_id secret?") 아니요. `app_id`는 앱에 포함되어 있으며 공개해도 안전합니다. 버전 관리(공개적으로도)에 포함시킬 수 있으며 다른 사람이 접근하는 것에 대해 걱정할 필요가 없습니다. 귀하의 `app_id`를 가진 사람은 Capgo 서버에서 앱의 최신 버전을 가져올 수 있지만, 앱에 업데이트를 푸시하거나 Capgo 계정의 다른 측면에 접근할 수 없습니다. ### Capgo 서버로 어떤 정보가 전송되나요?[](https://capgo.app/docs/faq/#what-information-is-sent-to-capgo-servers "Direct link to What information is sent to Capgo servers?") Capgo가 네트워크에 연결되더라도 개인 식별 정보는 전송하지 않습니다. Capgo를 포함시키는 것은 Play Store나 App Store에 대한 선언에 영향을 미치지 않아야 합니다. 앱에서 Capgo 서버로 전송되는 요청에는 다음이 포함됩니다: - app_id (`capacitorconfigjson`에 지정됨) - channel (`capacitorconfigjson`에서 선택 사항) - release_version (AndroidManifestxml의 versionName 또는 Infoplist의 CFBundleShortVersionString 또는 [`CapacitorUpdaterversion`](/docs/plugin/settings/#version)에서 설정된 경우 `capacitorconfigjson`) - version_number (`npx @capgo/cli app update`의 일부로 생성됨) - os_version (예: '1121') - platform (예: 'android', 올바른 패치를 전송하는데 필요) 코드는 `updater/library/src/networkrs`에 있습니다 - device_id (첫 실행 시 기기에서 생성됨, 기기별 설치를 중복 제거하고 설치된 사용자 수에 기반하여 요금을 부과할 수 있게 함)월간 활성 사용자), 전체 패치나 전체 패치 설치가 아닌) - custom_id (선택사항, 개발자가 런타임에 설정하며 사용자 시스템에서 기기를 사용자와 연결하는데 사용) ### Capgo는 어떤 플랫폼을 지원하나요? 현재 Capgo는 iOS와 Android를 지원합니다. 두 플랫폼 모두 프로덕션 준비가 되어있습니다. Capgo의 iOS 또는 Android 사용은 독립적으로 결정할 수 있습니다. 채널에서 Android로 배포하고 App Store에 ipa를 빌드하거나 그 반대로 설정할 수 있습니다. Capgo는 (비교적 쉽게) 데스크톱이나 임베디드 대상을 지원하도록 만들 수 있습니다. 이것이 중요하다면 알려주세요. ### Capgo는 Play 테스트 트랙이나 Apple TestFlight와 어떻게 상호작용하나요? 각 앱스토어는 제한된 사용자 그룹에게 앱을 배포하는 별도의 메커니즘("내부 테스트", "클로즈드 베타" 등)을 가지고 있습니다. 이는 모두 사용자를 그룹으로 분류하고 각 그룹에 특정 버전의 앱을 배포하는 메커니즘입니다. 안타깝게도, 이러한 메커니즘 중 일부는 특정 테스트 트랙이나 TestFlight를 통해 앱이 설치되었는지 제3자가 감지하는 것을 허용하지 않습니다. 따라서 이러한 그룹의 구성을 신뢰성 있게 파악할 수 없고, 이러한 그룹을 기반으로 Capgo 패치에 대한 접근을 제한할 수 없습니다. [https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play](https://stackoverflow.com/questions/53291007/can-an-android-application-identify-the-test-track-within-google-play/) [https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i](https://stackoverflow.com/questions/26081543/how-to-tell-at-runtime-whether-an-ios-app-is-running-through-a-testflight-beta-i/) Capgo 번들의 가용성을 분할하고 싶다면, 4가지 옵션이 있습니다: 1. 각 그룹마다 별도의 채널 사용. 이것이 가장 간단한 접근법이지만 여러 채널을 관리해야 합니다. 이미 다른 가용성을 가진 개발 채널과 프로덕션 채널이 있을 수 있습니다. 따라서 개발 채널을 업데이트하고 확인한 다음 별도로 프로덕션 채널을 업데이트할 수 있습니다. 각 릴리스와 관련된 소스를 추적하는데 버전 관리의 브랜치/태그를 사용하는 것을 추천합니다. 2. 자체 옵트인 사용자 목록을 추적하고 자동 업데이트를 비활성화한 다음 package:capgo_code_push를 통해 특정 사용자에게만 업데이트를 트리거. 현재 작동하지만 자체 옵트인 목록을 관리해야 합니다. 3. Capgo는 기기별로 자체 옵트인 메커니즘을 생성할 수 있습니다(테스트 트랙이나 TestFlight와 유사하지만 플랫폼에 구애받지 않음). 이를 통해 QA 팀이 일반 공개 전에 번들에 옵트인할 수 있습니다. 4. Capgo는 비율 기반 출시를 지원합니다. 어떤 기기에 전송할지 선택할 수는 없지만 점진적으로 출시하고 문제가 발생하면 롤백하는데 도움이 됩니다. ## 결제 ### 플랜을 어떻게 업그레이드하거나 다운그레이드하나요? 대시보드에서 언제든지 플랜을 업그레이드하거나 다운그레이드할 수 있습니다: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### 결제 기간은 언제 재설정되나요? 결제 기간은 처음 Capgo를 구독한 달의 해당 일자에 매월 자동으로 재설정됩니다. 예를 들어, 15일에 구독했다면 매월 15일에 결제 기간이 재설정됩니다. ### 구독을 어떻게 취소하나요? 대시보드에서 언제든지 구독을 취소할 수 있습니다: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### 1년치를 미리 결제할 수 있나요? 대시보드에서 언제든지 가능합니다: [https://web.capgo.app/dashboard/settings/plans](https://web.capgo.app/dashboard/settings/plans/) ### 통계와 분석 대시보드의 통계는 매일 자정 UTC에 업데이트됩니다. 통계는 기기에 설치된 [MAU](https://capgo.app/docs/faq/#what-is-the-difference-between-a-bundle-and-a-release) 수를 기준으로 계산됩니다. # 기기 ID는 어떻게 생성되나요? 기기 ID는 첫 실행 시 기기에서 생성되며, 기기별 설치를 중복 제거하고 전체 패치나 패치 설치가 아닌 설치된 사용자 수(예: 월간 활성 사용자)를 기준으로 과금할 수 있게 해줍니다. MAU는 Capgo 가격 책정에 있어 설치 횟수보다 더 나은 솔루션입니다. 더 정확하고 기기당 실제 Capgo 비용을 반영하기 때문입니다. 개인정보 보호를 위해 사용자가 앱을 재설치할 경우 동일한 기기를 추적할 수 없습니다. 개인정보 보호 규칙은 Apple과 Google에 의해 시행되며 Capgo에 의해 시행되지 않습니다. 기기 ID는 첫 패치가 설치될 때까지 기기 목록에 표시되지 않습니다. # 내 기기 수가 MAU와 다른 이유는 무엇인가요? 현재 기기 목록은 MAU만큼 자주 업데이트되지 않습니다. 기기 목록은 기기가 업데이트를 설치할 때만 업데이트됩니다. 반면 MAU는 앱이 실행될 때마다 업데이트됩니다. 이는 플랫폼의 현재 제한사항입니다. 분석 플랫폼이 원시 업데이트를 지원하지 않아 기기 목록에는 기존 데이터베이스를 사용합니다. 데이터베이스 쿼리 수를 제한하기 위해 앱 업데이트 시에만 행을 업데이트합니다. 이 제한사항은 향후 제거될 예정입니다. # 플랫폼별로 다른 업데이트를 어떻게 할 수 있나요? 각 플랫폼별로 채널을 생성하고 각 채널에서 플랫폼별 업데이트를 비활성화할 수 있습니다. iOS 채널에서는 Android 업데이트를 비활성화하고 Android 채널에서는 iOS 업데이트를 비활성화합니다. 그런 다음 각 채널에 번들을 업로드하여 각 플랫폼별로 다른 업데이트를 할 수 있습니다. 두 플랫폼에 동일한 업데이트가 필요한 경우 하나의 번들을 여러 채널에 연결할 수 있습니다. 번들을 복제할 필요가 없습니다. ``` # Capgo 기술 지원 > capgo의 기술 지원을 받는 방법 ## Discord 지원 Capgo는 공식 [discord 서버](https://discordcom/invite/VnYRvBfgA6)가 있습니다. 여기서 기술 지원을 받는 것이 가장 빠른 응답을 받을 수 있는 방법 중 하나입니다. 간단한 안내입니다: 1. `questions` 채널로 이동하세요 ![Ask on discord](/discord-questions.webp) 2. 스레드를 생성하세요 ![Create a question on discord](/discord-newquestion.webp) 3. 문제를 설명하고 관련 태그를 선택하세요 ![Create a post on discord](/discord-new-post.webp) 4. 보안 계정 ID를 공유하세요 (선택사항) 이를 통해 Capgo 직원이 귀하의 계정을 확인할 수 있습니다. 이 ID는 공개적으로 공유하도록 설계되었기 때문에 공유해도 안전합니다. 공유하려면 [Capgo 설정](https://web.capgo.app/dashboard/settings/account/)으로 이동하세요. 거기서 `계정 ID 복사`를 클릭하세요. ![Share your id without leaking your info](/share-secure-id.webp) 이렇게 하면 보안 계정 ID가 클립보드에 복사됩니다. 이를 Discord 게시물에 포함해 주세요. ## 이메일 지원 이메일은 지원을 받는 가장 느린 방법입니다. 먼저 Discord 서버를 이용해 주세요. 이메일로 연락이 필요한 경우, 으로 이메일을 보내주세요. # Ajouter une App > Capgo 계정에 앱을 추가하고 앱에 플러그인을 설치하세요 ## Capgo 소개 [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## 실시간 업데이트는 3단계로 가능합니다 ### 가이드 설정 1. 에서 계정을 생성하세요 ![signup screenshot](/signup.webp "signup screenshot") 2. 시작하기 위해 Init 명령어를 사용하세요 ```bash npx @capgo/cli@latest init [APIKEY] ``` 일련의 질문이 표시될 것입니다. 자동 설정을 완료하기 위해 필요한 답변을 제공하세요 Tip 이러한 단계를 따르면 곧바로 시작할 수 있습니다. 과정 중에 추가 도움이 필요하시다면, 저희 지원팀이 [도와드리겠습니다](https://support.capgo.app). 즐거운 온보딩 되세요! 3. 실시간 업데이트 배포하기 [실시간 업데이트 배포 ](/docs/getting-started/deploy/)앱에 실시간 업데이트를 배포하는 방법 알아보기 ### 수동 설정 init 명령어가 작동하지 않는 경우, 수동으로 앱을 추가할 수 있습니다 1. CLI를 계정에 연결하세요: ```bash npx @capgo/cli@latest login [APIKEY] ``` 2. 이 명령어로 계정에 앱을 추가하세요: ```bash npx @capgo/cli@latest app add [APP_NAME] ``` 3. 앱에 플러그인을 설치하세요: ```json { "plugins": { CapacitorUpdater: { "appId": "Your appID", "autoUpdate": true, "version": "1.0.0" } } } ``` 4. 앱에서 가능한 한 빨리 init 메소드를 호출하세요: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; CapacitorUpdater.notifyAppReady(); ``` 5. 실시간 업데이트 배포하기 [실시간 업데이트 배포 ](/docs/getting-started/deploy/)앱에 실시간 업데이트를 배포하는 방법 알아보기 # CI/CD 통합 CI/CD 파이프라인에 Capgo를 통합하면 앱 업데이트의 빌드 및 배포 프로세스를 완전히 자동화할 수 있습니다. Capgo CLI와 semantic-release를 활용하여 일관되고 안정적인 배포를 보장하고 빠른 반복을 가능하게 할 수 있습니다. ## CI/CD 통합의 장점 * **자동화**: 더 이상 수동 단계나 인적 오류가 발생할 여지가 없습니다. 전체 빌드, 테스트 및 배포 프로세스를 처음부터 끝까지 자동화할 수 있습니다. * **일관성**: 모든 배포가 동일한 단계를 따르므로 예측 가능하고 반복 가능한 프로세스를 보장합니다. 여러 팀원이 코드를 기여할 때 특히 가치가 있습니다. * **빠른 반복**: 자동화된 배포를 통해 더 자주 그리고 자신감 있게 업데이트를 배포할 수 있습니다. 더 이상 수동 QA나 배포 승인을 기다릴 필요가 없습니다. ## Capgo CLI Capgo CLI는 CI/CD 워크플로우에 Capgo를 통합하는 핵심입니다. 새로운 번들 버전 푸시, 채널 관리 등을 위한 명령어를 제공합니다. CI/CD 통합에서 가장 중요한 명령어는 `upload`입니다: ```shell npx @capgo/cli@latest bundle upload --channel=Production --apikey YOUR_API_KEY ``` 이 명령어는 현재 웹 빌드를 지정된 채널에 업로드합니다. 일반적으로 웹 빌드가 성공적으로 완료된 후 CI/CD 파이프라인의 마지막 단계로 실행됩니다. ## CI/CD 파이프라인에서 Capgo 설정하기 사용하는 CI/CD 도구에 따라 정확한 단계는 다르지만, Capgo를 통합하는 일반적인 프로세스는 다음과 같습니다: 1. **API 키 생성**: Capgo 대시보드에 로그인하여 새 API 키를 생성합니다. 이 키는 CI/CD 환경에서 CLI를 인증하는 데 사용됩니다. 비밀로 유지하고 절대 저장소에 커밋하지 마세요! 2. **`upload` 명령어 구성**: CI/CD 구성에 적절한 인수와 함께 `upload` 명령어를 실행하는 단계를 추가합니다: uploadyml ```yaml - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secretsCAPGO_API_KEY }} ``` \n `Production`을 배포하려는 채널로 바꾸고, `${{ secretsCAPGO_API_KEY }}`를 API 키를 보유한 환경 변수로 바꾸세요. 3. **웹 빌드 후 `upload` 단계 추가**: `upload` 단계가 웹 빌드가 성공적으로 완료된 후에 오도록 하세요. 이렇게 하면 항상 최신 코드를 배포할 수 있습니다.\n GitHub Actions용 구성 예시입니다:\n uploadyml ```yaml name: Deploy to Capgo on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v4 with: node-version: 18 - run: npm ci - run: npm run build - run: npm install -g @capgo/cli - run: npx @capgo/cli@latest bundle upload --channel=Production --apikey=${{ secretsCAPGO_API_KEY }} ``` ## Semantic-release 통합 Semantic-release는 버전 관리를 자동화하고 릴리스 노트를 생성하는 강력한 도구입니다. Semantic-release를 Capgo와 통합하면 각 배포마다 앱 버전을 자동으로 증가시키고 변경 로그를 생성할 수 있습니다. 다음은 semantic-release용 샘플 `releaserc` 구성 파일입니다: ```json { "branches": [ "main", { "name": "beta", "prerelease": true } ], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", [ "@semantic-release/exec", { "publishCmd": "npx @capgo/cli@latest bundle upload --channel=${nextReleasechannel} --apikey YOUR_API_KEY --partial" } ], [ "@semantic-release/git", { "assets": ["CHANGELOGmd", "packagejson"], "message": "chore(release): ${nextReleaseversion} [skip ci]\n\n${nextReleasenotes}" } ] ] } ``` 이 구성은 다음을 수행합니다: 1. Conventional Commits 명세를 따라 커밋 메시지를 분석하여 다음 버전 번호를 결정합니다 2. 마지막 릴리스 이후의 커밋을 기반으로 릴리스 노트를 생성합니다 3. 새로운 릴리스 노트로 `CHANGELOGmd` 파일을 업데이트합니다 4. Capgo CLI `upload` 명령어를 실행하며, 새 버전 번호를 전달하고 차등 업데이트를 위해 `--partial` 플래그를 사용합니다 5. 업데이트된 `CHANGELOGmd`, `packagejson` 및 기타 변경된 파일을 저장소에 다시 커밋합니다 Capgo에서 semantic-release를 사용하려면 CI/CD 구성에 `npx semantic-release`를 실행하는 단계를 추가하기만 하면 됩니다. 이 단계가 웹 빌드 이후, Capgo `upload` 단계 이전에 오도록 하세요. ## 문제 해결 Capgo CI/CD 통합에서 문제가 발생하면 다음 사항을 확인하세요: * **API 키**: API 키가 유효하고 필요한 권한이 있는지 확인하세요. 환경 변수를 사용하는 경우 올바르게 설정되어 있는지 다시 확인하세요. * **CLI 버전**: 최신 버전의 Capgo CLI를 사용하고 있는지 확인하세요. 이전 버전은 호환성 문제가 있거나 특정 기능이 없을 수 있습니다. * **빌드 아티팩트**: 웹 빌드가 예상된 출력 파일을 생성하고 있는지 확인하세요. Capgo CLI는 번들을 만들기 위해 유효한 웹 빌드가 필요합니다. * **네트워크 연결**: CI/CD 환경이 Capgo 서버에 네트워크 액세스할 수 있는지 확인하세요. 방화벽이나 프록시 문제가 때때로 `upload` 명령어를 방해할 수 있습니다. 여전히 문제가 있다면 Capgo 지원팀에 연락하세요. 특정 설정과 관련된 문제를 해결하는 데 도움을 줄 수 있습니다. ## 결론 CI/CD 파이프라인에 Capgo를 통합하고 버전 관리를 위해 semantic-release를 활용하면 개발 워크플로우를 크게 간소화할 수 있습니다. 배포와 버전 관리를 자동화함으로써 더 빠르고 자신감 있게 업데이트를 배포할 수 있습니다. Capgo CLI와 semantic-release는 완전히 자동화된 엔드투엔드 릴리스를 위한 강력한 조합을 제공합니다. 약간의 구성만으로 수동 릴리스 단계에 대해 걱정하는 대신 훌륭한 기능을 구축하는 데 집중할 수 있는 강력하고 신뢰할 수 있는 배포 프로세스를 가질 수 있습니다. Capgo CLI 명령어와 옵션에 대한 자세한 내용은 [CLI 참조](/docs/cli/overview)를 확인하세요. 그리고 semantic-release 구성에 대한 자세한 내용은 [semantic-release 문서](https://github.com/semantic-release/semantic-release)를 참조하세요. 즐거운 배포 되세요! # Live Update 배포하기 Capgo의 실시간 업데이트 기능을 사용하여 앱의 UI와 비즈니스 로직을 원격으로 실시간 업데이트하세요. JS 번들 업데이트를 앱 스토어를 거치지 않고 사용자에게 직접 푸시하여 즉시 버그를 수정하고 새로운 기능을 배포할 수 있습니다. 이 가이드는 [Capgo 퀵스타트](/docs/getting-started/quickstart)를 완료했고 다음 사항을 이미 수행했다고 가정합니다: 1. Capacitor 앱에 `@capgo/capacitor-updater` SDK를 설치했음 2. `capacitor.config.ts`에서 앱 ID와 업데이트 채널을 구성했음 3. 코드에 `CapacitorUpdater.notifyAppReady()` 메서드를 추가했음 아직 이러한 단계를 완료하지 않았다면, 먼저 퀵스타트로 돌아가서 완료해주세요. [앱 추가하기 ](/docs/getting-started/add-an-app/)Capgo 계정에 앱을 추가하고 앱에 플러그인을 설치하세요 ## 번들 업로드하기 Capgo SDK를 설치하고 구성했다면 첫 실시간 업데이트 번들을 업로드할 준비가 된 것입니다: 1. 웹 에셋을 빌드하세요: ```shell npm run build ``` 2. 번들을 Capgo에 업로드하세요: * Console ```shell npx @capgo/cli@latest bundle upload --channel=Production ``` * Github Actions github/workflows/build\_and\_deploy.yml ```yml name: Build source code and send to Capgo concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true on: push: branches: - main jobs: deploy_to_capgo: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v5 - uses: actions/setup-node@v4 with: node-version: 18 - name: Install dependencies run: npm install - name: Build run: npm run build - name: Deploy to Capgo run: bunx @capgo/cli@latest bundle upload -a ${{ secrets.CAPGO_TOKEN }} --channel ${{ env.CHANNEL }} env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} ``` * Gitlab gitlab-ci.yml ```yml stages: - build build: stage: build image: node:18 cache: - key: files: - package-lock.json paths: - node_modules/ script: - npm install - npm run build - npx @capgo/cli@latest bundle upload -a $CAPGO_TOKEN --channel $CAPGO_CHANNEL artifacts: paths: - node_modules/ - dist/ only: - master ``` 이것은 명령에서 지정한 채널에 새로운 번들 버전을 업로드합니다. ### 업로드 문제 해결 업로드가 실패하면 다음 사항을 확인하세요: * `capacitor.config.ts`의 앱 ID가 Capgo 대시보드의 앱과 일치하는지 * Capacitor 프로젝트의 루트에서 업로드 명령을 실행하는지 * 웹 에셋이 빌드되어 있고 최신 상태인지 여전히 문제가 있다면 [문제 해결](/docs/getting-started/troubleshooting/) 섹션으로 이동하세요. ## 디바이스에서 업데이트 받기 번들이 업로드되면 디바이스에서 실시간 업데이트를 테스트할 수 있습니다: 1. 앱을 디바이스와 동기화하세요: ```shell npx cap sync ios ``` 2. 다른 터미널을 열고 다음 명령을 실행하여 업데이트 상태를 확인하세요: ```shell npx @capgo/cli@latest app debug ``` 3. 앱을 로컬에서 실행하세요: ```shell npx cap run ios ``` 또는 Xcode/Android Studio에서 iOS/Android 프로젝트를 열고 네이티브 실행을 하세요. 4. 업데이트가 백그라운드에서 다운로드되도록 앱을 약 30초 동안 열어두세요. 5. 로그가 업데이트되어 업데이트 상태를 표시하는 데 몇 초가 걸립니다. 6. 앱을 닫았다가 다시 여세요. 실시간 업데이트가 적용된 것을 확인할 수 있습니다! 실시간 업데이트 테스트에 대한 자세한 내용은 [Capgo 퀵스타트](/docs/getting-started/quickstart#receiving-a-live-update-on-a-device)를 참조하세요. ## 다음 단계 Capgo로 첫 실시간 업데이트를 배포한 것을 축하합니다! 🎉 더 자세히 알아보려면 [Capgo 실시간 업데이트 문서](/docs/live-updates)의 나머지 부분을 검토하세요. 다음으로 살펴볼 주요 주제들: * [채널을 통한 업데이트 타겟팅](/docs/live-updates/channels) * [업데이트 동작 커스터마이징](/docs/live-updates/update-behavior) * [실시간 업데이트 롤백](/docs/live-updates/rollbacks) # 개요 Capgo의 주요 개념을 안내하는 퀵스타트 튜토리얼입니다! 다음과 같은 개념들을 살펴볼 것입니다: 1. Capgo 계정에 앱 추가하기 2. CI/CD와 Capgo 통합하기 3. 커밋을 푸시하여 Capgo에서 번들 업로드 트리거하기 4. Capgo 번들 배포 구성 및 커스터마이징하기 5. Capgo를 통한 라이브 업데이트를 활성화하도록 앱 설정하기 6. Capgo에서 앱에 라이브 업데이트 배포하기 가이드를 순서대로 따라가거나, 관심 있는 컴포넌트의 문서로 바로 이동하세요. [ 튜토리얼 시작하기](/docs/getting-started/add-an-app/) [퀵스타트 튜토리얼을 따라 순식간에 Capgo를 시작해보세요!](/docs/getting-started/add-an-app/) [ 쉬운 통합](/docs/getting-started/deploy/) [CI/CD와 Capgo를 통합하고 커밋을 푸시하여 번들 업로드를 트리거하세요](/docs/getting-started/deploy/) [ 라이브 업데이트 문서](/docs/live-updates/) [앱스토어 지연 없이 실시간으로 원격 앱 업데이트](/docs/live-updates/) [ 문제 해결](/docs/getting-started/troubleshooting) [일반적인 문제와 해결 방법](/docs/getting-started/troubleshooting) Tip 무선 업데이트(OTA) 기능은 HTML, CSS, JavaScript 파일의 수정에만 적용됩니다. Capacitor 플러그인 업데이트와 같은 네이티브 코드를 변경하는 경우에는 반드시 앱스토어에 재승인을 받아야 합니다 ## Discord 커뮤니티 참여하기 [Capacitor-updater Discord 서버에 참여하세요!](https://discord.capgo.app) ## 유지보수 | 플러그인 버전 | Capacitor 호환성 | 유지보수 상태 | | ------- | ------------- | --------------------------------- | | v6\*\* | v6\*\* | ✅ | | v5\*\* | v5\*\* | 중요 버그만 수정 | | v4\*\* | v4\*\* | ⚠️ 지원 중단 | | v3\*\* | v3\*\* | ⚠️ 지원 중단 | | > 7 | v4\*\* | ⚠️ 지원 중단, CI가 오작동하여 버전이 너무 많이 올라감 | ## 스토어 가이드라인 준수 Android Google Play와 iOS App Store는 Capacitor-updater 솔루션을 애플리케이션에 통합하기 전에 알아야 할 규칙이 있는 해당 가이드라인이 있습니다 ### Google Play [기기 및 네트워크 남용](https://support.google.com/googleplay/android-developer/answer/9888379/?hl=en) 주제의 세 번째 단락에서는 Google Play의 업데이트 메커니즘 이외의 방법으로 소스 코드를 업데이트하는 것이 제한된다고 설명합니다. 하지만 이 제한은 자바스크립트 번들 업데이트에는 적용되지 않습니다 > 이 제한은 가상 머신에서 실행되고 Android API에 대한 제한된 접근 권한을 가진 코드(예: 웹뷰나 브라우저의 JavaScript)에는 적용되지 않습니다 이는 JS 번들만 업데이트하고 네이티브 코드는 업데이트하지 않는 Capacitor-updater를 완전히 허용합니다 ### App Store 2015년부터 [Apple Developer Program License Agreement](https://developer.apple.com/programs/ios/information/)의 **332**항은 JavaScript와 자산의 무선 업데이트를 완전히 허용했으며, 최신 버전(20170605)([여기서 다운로드](https://developer.apple.com/terms/))에서는 이 규정이 더 광범위해졌습니다: > 해석된 코드는 다음과 같은 조건에서만 애플리케이션에 다운로드할 수 있습니다: (a) App Store에 제출된 애플리케이션의 의도된 광고 목적과 일치하지 않는 기능을 제공하여 애플리케이션의 주요 목적을 변경하지 않음, (b) 다른 코드나 애플리케이션을 위한 스토어나 상점을 만들지 않음, (c) OS의 서명, 샌드박스 또는 기타 보안 기능을 우회하지 않음 Capacitor-updater를 사용하면 푸시하는 업데이트가 원래 App Store에서 승인된 의도에서 크게 벗어나지 않는 한 이러한 규칙을 완전히 준수할 수 있습니다 Apple의 가이드라인을 더욱 준수하기 위해, [App Store 검토 가이드라인](https://developer.apple.com/app-store/review/guidelines/)에서 다음과 같이 명시하고 있으므로 App Store에 배포되는 앱은 ‘강제 업데이트’ 시나리오를 활성화하지 않는 것이 좋습니다: > 앱은 기능, 콘텐츠에 접근하거나 앱을 사용하기 위해 사용자에게 앱 평가, 앱 리뷰, 다른 앱 다운로드 또는 기타 유사한 작업을 강요해서는 안 됩니다 이는 사용자가 앱을 닫을 때까지 새 버전을 적용하도록 강제하지 않는 백그라운드 업데이트의 기본 동작에는 문제가 되지 않지만, 이를 표시하기로 결정한 경우에는 해당 역할을 알고 있어야 합니다 ## 오픈 소스 이 플러그인은 LGPL-3.0 라이선스이며 백엔드는 AGPL-3.0 라이선스입니다 > 💡 LGPL-3.0은 누군가 플러그인의 코드를 수정하면 동일한 라이선스로 오픈 소스로 공개해야 함을 의미합니다. 코드를 수정하지 않고 사용한다면 이는 해당되지 않습니다. 자세한 내용은 아래 링크를 확인하세요 👇 [라이선스? ](https://github.com/Cap-go/capacitor-updater/issues/7) [문서를 읽는 대신 GPTS Capgo를 사용하여 도움을 받으세요 ](https://chat.openai.com/g/g-3dMwHbF2w-capgo-doc-gpt) > 걱정 없이 앱에 포함시킬 수 있습니다 ## 마지막 참고 사항 셀프 호스팅을 하고 이 도구가 유용하다고 생각되시면, [GitHub 스폰서](https://github.com/sponsors/riderx/)가 되어 제 작업을 지원해 주시기 바랍니다 저는 여기서 구축한 모든 코드를 유료화하는 대신 오픈 소스로 공개하기로 결정했습니다. 숨기고 싸우는 대신 공개함으로써 더 나은 세상을 만들 수 있다고 믿습니다 이를 가능하게 하려면 여러분을 포함한 우리 모두가 각자의 역할을 해야 합니다 🥹 Capgo 클라우드가 요구 사항을 충족하지 못한다면, [여기서](https://github.com/sponsors/riderx/) 자신의 조건으로 부트스트랩 메이커를 지원할 수 있습니다 ## 간단한 수학 기본 요금제 가격: $14\*12 = 연간 $168 평균 개발자 시급 = $60 즉, 셀프 호스팅에 3시간의 개발 시간을 낭비하면 1년 전체 요금을 지불할 수 있으며, 3시간 이상 소비한다면 돈을 잃게 됩니다 ^^ # 문제 해결 Capgo 사용 시 발생할 수 있는 일반적인 문제와 해결 방법을 소개합니다 ### 업로드 실패 번들 업로드가 실패하면 다음 사항을 확인하세요: * `capacitor.config.ts`의 앱 ID가 Capgo 대시보드의 앱과 일치하는지 * Capacitor 프로젝트 루트에서 업로드 명령을 실행하는지 * 웹 에셋이 빌드되어 최신 상태인지 #### 고급 업로드 옵션 Capgo CLI는 일반적인 업로드 문제를 해결하기 위한 추가 플래그를 제공합니다: * `--tus`: 대용량 번들이나 불안정한 네트워크 연결에서 더 안정적인 업로드를 위해 [tus 재개 가능 업로드 프로토콜](https://tus.io/)을 사용합니다. 번들이 10MB 이상이거나 연결이 불안정한 경우 `--tus` 사용을 고려하세요: ```shell npx @capgo/cli@latest bundle upload --tus ``` * `--package-json`과 `--node-modules`: 모노레포나 npm 워크스페이스와 같은 비표준 구조를 사용하는 경우 루트 `package.json`과 `node_modules`의 위치를 Capgo에 알려줍니다. 루트 `package.json`과 `--node-modules` 경로를 전달하세요: ```shell npx @capgo/cli@latest bundle upload --package-json=path/to/package.json --node-modules=path/to/node_modules ``` Capgo는 앱의 종속성을 올바르게 번들링하기 위해 이 정보가 필요합니다 이러한 플래그는 `--channel`과 같은 다른 옵션과 함께 사용할 수 있습니다. 사용 가능한 모든 업로드 옵션은 [Capgo CLI 문서](/docs/cli/overview/)를 참조하세요 업로드에 문제가 계속되면 [Capgo 지원팀](https://support.capgo.app)에 문의하세요 ### 업데이트 디버깅 라이브 업데이트에 문제가 있다면 Capgo 디버그 명령이 문제 해결에 도움이 됩니다. 사용 방법: 1. 프로젝트 디렉토리에서 다음 명령을 실행하세요: ```shell npx @capgo/cli@latest app debug ``` 2. 기기나 에뮬레이터에서 앱을 실행하고 업데이트를 트리거할 동작을 수행하세요(예: 새 번들 업로드 후 앱 재실행) 3. 디버그 명령의 출력을 확인하세요. 다음과 같은 업데이트 프로세스 정보가 기록됩니다: * 앱이 업데이트를 확인하는 시점 * 업데이트가 발견되었는지와 어떤 버전인지 * 업데이트의 다운로드 및 설치 진행 상황 * 업데이트 과정에서 발생하는 오류 4. 디버그 로그를 사용해 문제가 발생하는 위치를 파악하세요. 예: * 업데이트가 발견되지 않으면 번들이 성공적으로 업로드되었는지, 앱이 올바른 채널을 사용하도록 구성되었는지 확인 * 업데이트가 다운로드되지만 설치되지 않으면 `CapacitorUpdater.notifyAppReady()`를 호출했는지, 앱이 완전히 종료되고 다시 열렸는지 확인 * 오류 메시지가 표시되면 Capgo 문서에서 해당 오류를 찾아보거나 지원팀에 도움을 요청 디버그 명령은 특히 업데이트 다운로드 및 설치 프로세스의 문제를 파악하는 데 유용합니다. 로그에 예상된 업데이트 버전이 발견되었지만 최종적으로 적용되지 않은 것으로 나타나면 다운로드 이후 단계에서 문제 해결에 집중하세요 ### 네이티브 로그로 디버깅하기 Capgo 디버그 명령 외에도 Android와 iOS의 네이티브 로그는 특히 업데이트 프로세스의 네이티브 측면에서 발생하는 문제에 대해 중요한 문제 해결 정보를 제공할 수 있습니다 #### Android 로그 Android 로그에 접근하는 방법: 1. 기기를 연결하거나 에뮬레이터를 시작하세요 2. Android Studio를 열고 “View > Tool Windows > Logcat”을 선택하세요 3. Logcat 창에서 상단 드롭다운에서 앱의 프로세스를 선택하여 로그를 필터링하세요 4. `Capgo`를 포함하는 라인을 찾아 SDK 로그를 확인하세요 또는 `adb logcat` 명령을 사용하고 `Capgo`로 grep하여 로그를 필터링할 수 있습니다 Capgo SDK는 업데이트 프로세스 동안 다음과 같은 주요 이벤트를 기록합니다: * 업데이트 확인이 시작될 때 * 업데이트가 발견되었을 때와 어떤 버전인지 * 업데이트 다운로드가 시작되고 완료될 때 * 업데이트 설치가 트리거될 때 * 네이티브 업데이트 단계에서 발생하는 오류 로그에서 볼 수 있는 일반적인 Android 관련 문제는 다음과 같습니다: * 업데이트 다운로드를 방해하는 네트워크 연결 문제 * 업데이트 번들 저장 또는 읽기 시 파일 권한 오류 * 업데이트 번들을 위한 저장 공간 부족 * 업데이트 설치 후 앱 재시작 실패 #### iOS 로그 iOS 로그에 접근하는 방법: 1. 기기를 연결하거나 시뮬레이터를 시작하세요 2. Xcode를 열고 “Window > Devices and Simulators”로 이동하세요 3. 기기를 선택하고 “Open Console”을 클릭하세요 4. 콘솔 출력에서 `Capgo`를 포함하는 라인을 찾아 SDK 로그를 확인하세요 터미널에서 `log stream` 명령을 사용하고 `Capgo`로 grep하여 로그를 필터링할 수도 있습니다 Android와 마찬가지로 Capgo SDK는 주요 iOS 측 이벤트를 기록합니다: * 업데이트 확인 시작 및 결과 * 다운로드 시작, 진행 상황 및 완료 * 설치 트리거 및 결과 * 네이티브 업데이트 프로세스 중 발생하는 오류 로그에서 식별할 수 있는 iOS 관련 문제는 다음과 같습니다: * 업데이트 다운로드 시 SSL 인증서 문제 * 업데이트 다운로드를 차단하는 앱 전송 보안 * 업데이트 번들을 위한 저장 공간 부족 * 업데이트 번들을 제대로 추출하거나 적용하지 못함 두 플랫폼 모두에서 네이티브 로그는 업데이트 프로세스에 대한 더 낮은 수준의 뷰를 제공하며, 네이티브 구현에 대한 더 자세한 정보를 제공합니다. 특히 Capgo JavaScript 레이어 외부에서 발생하는 문제를 식별하는 데 유용합니다 까다로운 라이브 업데이트 문제를 해결할 때는 Capgo 디버그 로그와 네이티브 로그를 모두 캡처하는 것이 좋습니다. 두 로그를 함께 사용하면 문제를 식별하고 해결할 가능성이 가장 높아집니다 ### 업데이트가 적용되지 않는 경우 번들을 업로드했지만 기기에서 변경 사항이 표시되지 않는 경우: * [퀵스타트](/docs/getting-started/quickstart)에 표시된 대로 앱 코드에서 `CapacitorUpdater.notifyAppReady()`를 호출했는지 확인하세요 * 기기가 인터넷에 연결되어 있고 Capgo 디버그 로그에서 업데이트가 다운로드되었는지 확인하세요 * 업데이트는 새로 실행할 때만 적용되므로 앱을 완전히 종료하고 다시 여세요 * 업데이트 적용에 문제가 있음을 나타내는 네이티브 로그의 오류를 확인하세요 업데이트 프로세스에 대한 자세한 내용은 [라이브 업데이트 배포](/docs/getting-started/deploy) 가이드를 참조하세요. 여전히 문제가 있다면 `npx @capgo/cli@latest app debug` 명령과 네이티브 로그를 사용하여 무슨 일이 일어나고 있는지 더 자세히 확인하세요 ## SDK 설치 Capgo SDK 설치에 문제가 있다면 다음을 확인하세요: * 앱이 지원되는 버전의 Capacitor(4.0 이상)를 사용하고 있는지 * SDK 설치 후 앱 동기화를 포함하여 [퀵스타트](/docs/getting-started/quickstart) 단계를 순서대로 따랐는지 ## CI/CD 통합 CI/CD 파이프라인에서 Capgo 업로드 트리거에 문제가 있는 경우: * Capgo 인증 토큰이 올바르게 설정되어 있는지 다시 확인하세요 * 웹 에셋이 빌드된 후 업로드 명령을 실행하는지 확인하세요 * 업로드 명령이 대상 환경에 맞는 채널 이름을 사용하고 있는지 확인하세요 자세한 문제 해결 팁은 [CI/CD 통합](/docs/getting-started/cicd-integration) 문서를 참조하세요. `npx @capgo/cli@latest app debug` 명령을 사용하여 CI/CD로 트리거된 업데이트가 앱에 수신되고 있는지도 확인할 수 있습니다 # So geht's > Capgo 사용 방법, 튜토리얼, 팁과 요령 [Capgo에서 버전이 작동하는 방식 ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [Capgo에서 메이저 버전을 출시하는 방법 ](https://capgo.app/blog/how-to-release-major-version-in-capgo/)capgo.app [특정 사용자나 그룹에게 특정 업데이트를 보내는 방법 ](https://capgo.app/blog/how-to-send-specific-version-to-users/)capgo.app ## CI / CD [GitHub Actions를 사용한 자동 빌드 및 릴리스 ](https://capgo.app/blog/how-version-work-in-capgo/)capgo.app [GitHub Actions를 사용한 개발 및 프로덕션 빌드 관리 ](https://capgo.app/blog/automatic-build-and-release-with-github-actions/)capgo.app ## 기여하기 [Capgo 오픈소스에 기여하기 ](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTINGmd)githubcom # 개요 Capgo의 실시간 업데이트 기능을 사용하여 앱의 JavaScript 번들을 원격으로 실시간으로 업데이트하세요. 앱 스토어 검토 과정 없이 사용자에게 직접 JS 업데이트를 푸시하여 즉시 버그를 수정하고 새로운 기능을 배포할 수 있습니다. Note 실시간 업데이트는 JavaScript 번들 변경으로 제한됩니다. 플러그인 추가 또는 제거, 네이티브 프로젝트 구성 변경과 같은 네이티브 코드를 업데이트해야 하는 경우 앱 스토어에 새로운 네이티브 바이너리 빌드를 제출해야 합니다. ## 실시간 업데이트 작동 방식 Capgo의 실시간 업데이트 시스템에는 두 가지 주요 구성 요소가 있습니다: 1. 앱에 설치하는 Capgo SDK. SDK는 사용 가능한 업데이트를 확인하고 백그라운드에서 다운로드합니다. 2. 특정 사용자 그룹에 업데이트를 대상으로 하는 채널. 채널을 사용하여 `Production`, `Staging`, `Dev`와 같은 다양한 릴리스 트랙을 관리할 수 있습니다. Capgo에 새로운 JS 번들을 업로드하고 채널에 할당하면, 해당 채널로 구성된 앱의 Capgo SDK가 업데이트를 감지하고 다운로드합니다. 앱이 다시 시작될 때 새로운 번들이 로드됩니다. ## 시작하기 실시간 업데이트를 시작하려면 다음 단계를 따르세요: 1. [Capgo 퀵스타트](/docs/getting-started/quickstart)를 완료하여 Capgo에서 앱을 설정하고 Capgo SDK를 설치하세요. 2. 앱 코드에서 앱 초기화가 완료된 후 `CapacitorUpdaternotifyAppReady()`를 호출하세요. 이는 Capgo SDK에게 앱이 업데이트를 받을 준비가 되었음을 알립니다. 3. JS 번들을 빌드하고 Capgo에 업로드하세요: ```shell npm run build npx @capgo/cli@latest bundle upload --channel=Production ``` 4. 앱을 열고 업데이트가 다운로드될 때까지 기다리세요. 다음으로 상태를 확인할 수 있습니다: ```shell npx @capgo/cli@latest app debug ``` 5. 업데이트가 다운로드되면 앱을 종료하고 다시 열어 새로운 번들을 로드하세요. 자세한 내용은 [실시간 업데이트 배포](/docs/getting-started/deploy) 가이드를 참조하세요. ## 다음 단계 [ 채널](/docs/live-updates/channels/) [채널을 사용하여 다양한 릴리스 트랙을 관리하고 특정 사용자에게 업데이트를 대상으로 하는 방법을 알아보세요.](/docs/live-updates/channels/) [ 롤백](/docs/live-updates/rollbacks/) [업데이트로 인해 문제가 발생할 경우 이전 JS 번들 버전으로 롤백하는 방법을 알아보세요.](/docs/live-updates/rollbacks/) [ 업데이트 동작](/docs/live-updates/update-behavior/) [앱에서 업데이트가 다운로드되고 적용되는 방법과 시기를 사용자 지정하세요.](/docs/live-updates/update-behavior/) [ 빠른 업데이트](/docs/live-updates/differentials/) [업데이트 프로세스를 가속화하기 위해 빠른 업데이트를 사용하는 방법을 알아보세요.](/docs/live-updates/differentials/) # 채널 Live Update 채널은 앱의 특정 JS 번들 빌드를 가리키며, 해당 채널의 업데이트를 수신하도록 설정된 모든 기기와 공유됩니다. [Capgo Live Updates SDK를 설치](/docs/getting-started/quickstart/)하면, 해당 채널로 구성된 모든 네이티브 바이너리는 앱이 실행될 때마다 사용 가능한 업데이트를 확인합니다. 언제든지 채널이 가리키는 빌드를 변경할 수 있으며, 필요한 경우 이전 빌드로 롤백할 수도 있습니다. ## 채널 설정하기 모든 앱에는 삭제할 수 없는 “Production”이라는 기본 채널이 제공됩니다. 새 채널을 추가하려면: 1. Capgo 대시보드의 “Channels” 섹션으로 이동합니다. 2. “New Channel” 버튼을 클릭합니다. 3. 채널 이름을 입력하고 “Create”를 클릭합니다. 채널 이름은 원하는 대로 지정할 수 있습니다. 일반적인 전략은 다음과 같이 개발 단계에 맞춰 채널을 지정하는 것입니다: * `Development` - 로컬 기기나 에뮬레이터에서 라이브 업데이트 테스트용 * `QA` - QA 팀이 광범위한 배포 전에 업데이트를 확인하기 위한 용도 * `Staging` - 프로덕션과 유사한 환경에서 최종 테스트용 * `Production` - 최종 사용자가 앱 스토어에서 받는 버전용 ## 앱에서 채널 구성하기 채널을 생성한 후에는 앱이 적절한 채널을 수신하도록 구성해야 합니다. 이 예시에서는 `Development` 채널을 사용하겠습니다. `capacitor.config.ts` (또는 `capacitor.config.json`) 파일을 엽니다. `plugins` 섹션에서 `CapacitorUpdater` 플러그인의 `channel` 속성을 원하는 채널 이름으로 설정합니다: ```ts import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { defaultChannel: 'Development', }, }, }; ``` 다음으로, 웹 앱을 빌드하고 `npx cap sync`를 실행하여 업데이트된 구성 파일을 iOS와 Android 프로젝트에 복사합니다. 이 동기화 단계를 건너뛰면, 네이티브 프로젝트는 이전에 구성된 채널을 계속 사용하게 됩니다. Caution `defaultChannel` 속성은 항상 클라우드 기본 채널을 재정의합니다. 하지만 Cloud에서 deviceId를 채널에 강제로 지정할 수 있습니다. ## 채널에 번들 할당하기 라이브 업데이트를 배포하려면 새로운 JS 번들 빌드를 업로드하고 채널에 할당해야 합니다. Capgo CLI를 사용하여 한 번에 이 작업을 수행할 수 있습니다: ```shell npx @capgo/cli@latest bundle upload --channel=Development ``` 이렇게 하면 빌드된 웹 자산을 업로드하고 새 번들을 `Development` 채널의 활성 빌드로 설정합니다. 해당 채널을 수신하도록 구성된 모든 앱은 다음 업데이트 확인 시 업데이트를 받게 됩니다. Capgo 대시보드의 “Bundles” 섹션에서도 빌드를 채널에 할당할 수 있습니다. 빌드 옆의 메뉴 아이콘을 클릭하고 “Assign to Channel”을 선택하여 해당 빌드의 채널을 선택합니다. ## 번들 버전 관리와 채널 Capgo의 번들은 개별 채널에 특정되지 않고 앱 전체에 전역적이라는 점을 주의해야 합니다. 동일한 번들을 여러 채널에 할당할 수 있습니다. 번들 버전 관리 시, 채널별 빌드에 대해 [semver](https://semver.org/) 시맨틱 버저닝과 사전 릴리스 식별자를 사용하는 것을 권장합니다. 예를 들어, 베타 릴리스는 `1.2.3-beta.1`과 같이 버전을 지정할 수 있습니다. 이 접근 방식에는 여러 이점이 있습니다: * 빌드 간의 관계를 명확하게 전달합니다. `1.2.3-beta.1`은 명백하게 `1.2.3`의 사전 릴리스입니다. * 채널 간에 버전 번호를 재사용할 수 있어 혼란을 줄입니다. * 명확한 롤백 경로를 제공합니다. `1.2.3`에서 롤백해야 하는 경우 `1.2.2`가 이전 안정 릴리스임을 알 수 있습니다. 일반적인 채널 설정에 따른 번들 버전 예시입니다: * `Development` 채널: `1.2.3-dev.1`, `1.2.3-dev.2` 등 * `QA` 채널: `1.2.3-qa.1`, `1.2.3-qa.2` 등 * `Staging` 채널: `1.2.3-rc.1`, `1.2.3-rc.2` 등 * `Production` 채널: `1.2.3`, `1.2.4` 등 시맨틱 버저닝과 사전 릴리스 식별자 사용은 권장되는 접근 방식이지만 필수는 아닙니다. 중요한 것은 빌드 간의 관계를 명확하게 전달하고 팀의 개발 프로세스에 부합하는 버전 관리 체계를 찾는 것입니다. ## 라이브 업데이트 롤백하기 버그가 있거나 되돌려야 하는 라이브 업데이트를 배포한 경우, 이전 빌드로 쉽게 롤백할 수 있습니다. 대시보드의 “Channels” 섹션에서: 1. 롤백하려는 채널의 이름을 클릭합니다. 2. 되돌리려는 빌드를 찾아 왕관 아이콘을 클릭합니다. ![롤백 빌드](/select_bundle.webp) 3. 작업을 확인합니다. 선택한 빌드가 즉시 해당 채널의 활성 빌드가 됩니다. 앱은 다음 업데이트 확인 시 롤백된 버전을 받게 됩니다. ## 배포 자동화하기 더 고급 워크플로우의 경우, CI/CD 파이프라인의 일부로 라이브 업데이트 배포를 자동화할 수 있습니다. Capgo를 빌드 프로세스에 통합하면, 특정 브랜치에 푸시하거나 새 릴리스를 생성할 때마다 새 번들을 자동으로 업로드하고 채널에 할당할 수 있습니다. Capgo 라이브 업데이트 자동화에 대해 자세히 알아보려면 [CI/CD 통합](/docs/getting-started/cicd-integration/) 문서를 확인하세요. ## 기기에 배포하기 이제 채널에 대해 이해했으므로 실제 기기에 라이브 업데이트를 배포할 준비가 되었습니다. 기본 프로세스는 다음과 같습니다: 1. 앱에 Capgo SDK 설치 2. 앱이 원하는 채널을 수신하도록 구성 3. 빌드를 업로드하고 해당 채널에 할당 4. 앱을 실행하고 업데이트를 기다립니다! 자세한 설명은 [라이브 업데이트 배포](/docs/getting-started/deploy/) 가이드를 참조하세요. 즐거운 업데이트 되세요! # 빠른 업데이트 Capgo의 실시간 업데이트 시스템은 전체 JS 번들이 아닌 변경된 파일만 전송하여 더 빠르고 효율적으로 업데이트를 제공할 수 있습니다 이는 특히 다운로드해야 하는 데이터양을 최소화하므로 느리거나 데이터 요금제가 있는 네트워크 연결을 사용하는 사용자에게 유용합니다 두 번째 이점은 앱에 이미지나 비디오와 같이 거의 변경되지 않는 큰 에셋이 있을 때, 압축된 JS 파일과 비교하여 한 번만 다운로드된다는 점입니다 ## 차등 업데이트 작동 방식 Capgo의 차등 업데이트는 앱에 설치된 Capgo 플러그인에 의해 처리됩니다. `--partial` 플래그를 사용하여 앱의 새 버전을 업로드하면 Capgo는 다음과 같이 처리합니다: 1. 빌드의 각 파일이 개별적으로 업로드됩니다 2. 각 파일에 대한 체크섬이 생성됩니다 3. 모든 파일과 해당 체크섬을 나열하는 새로운 json 매니페스트가 생성됩니다 4. 이 매니페스트는 Capgo 데이터베이스에 업로드됩니다 앱을 실행하는 기기가 업데이트를 확인할 때, Capgo 플러그인은 서버로부터 새 매니페스트를 받습니다. 이 매니페스트를 현재 가지고 있는 것과 비교하여 체크섬과 파일 경로를 기반으로 어떤 파일이 변경되었는지 식별합니다 그런 다음 플러그인은 전체 JS 번들이 아닌 변경된 파일만 다운로드합니다. 이 다운로드된 파일들과 이미 가지고 있는 변경되지 않은 파일들을 결합하여 앱의 새 버전을 재구성합니다 매니페스트 차등 업데이트의 경우, 기기는 모든 다운로드된 파일을 공통 캐시에 저장합니다. Capgo는 절대 이를 정리하지 않지만 OS는 언제든지 정리할 수 있습니다 ## 차등 업데이트 활성화 Capgo 앱에서 차등 업데이트를 활성화하려면 새 버전을 업로드할 때 간단히 `--partial` 플래그를 사용하면 됩니다: ## 차등 업데이트 강제 적용 모든 업로드가 차등 업데이트이며 실수로 전체 번들 업로드를 방지하고 싶다면 `--partial-only` 플래그를 사용할 수 있습니다: ```shell npx @capgo/cli@latest bundle upload --partial-only ``` `--partial-only`가 사용되면 Capgo는 개별 파일만 업로드하고 매니페스트를 생성합니다. 부분 업데이트를 지원하지 않는 기기는 업데이트를 다운로드할 수 없습니다 다음과 같은 경우에 `--partial-only`를 사용하고 싶을 수 있습니다: * 항상 차등 업데이트를 사용하고 전체 번들 업로드를 절대 허용하지 않으려는 경우 * CI/CD 파이프라인을 설정하고 모든 자동화된 업로드가 차등적으로 이루어지도록 하려는 경우 * 앱이 크고 대역폭이 제한적이어서 업로드/다운로드 크기를 최소화해야 하는 경우 `--partial-only`가 설정된 상태에서 전체 번들 업로드가 필요한 경우, 단순히 `--partial-only` 없이 업로드 명령을 실행하면 됩니다. 이는 해당 단일 업로드에 대해 설정을 재정의하여 필요할 때 완전한 번들을 푸시할 수 있게 합니다 ## 문제 해결 차등 업데이트가 작동하지 않는 것 같다면 (즉, 작은 변경사항에도 기기가 항상 전체 JS 번들을 다운로드하는 경우), 다음 사항을 확인하세요: * 새 버전을 업로드할 때마다 `--partial` 플래그를 사용하고 있는지 * `--partial-only`를 사용하는 경우, 실수로 `--partial` 플래그를 생략하지 않았는지 * 기기가 최신 버전의 Capgo 플러그인을 실행하고 있는지 * 기기가 안정적인 네트워크 연결을 가지고 있고 Capgo 서버에 접근할 수 있는지 Capgo 웹앱에서 마지막 업로드의 세부 정보를 확인할 수도 있습니다: 1. [웹앱](https://app.capgo.io)으로 이동 2. 앱을 클릭 3. 통계 바의 번들 수를 클릭 4. 마지막 번들 선택 5. `Partial` 필드 확인 ![bundle type](/bundle_type.webp) 계속해서 문제가 있다면 Capgo 지원팀에 연락하여 추가 지원을 받으세요. 그들은 서버 로그를 확인하여 부분 업로드가 올바르게 처리되고 있는지, 기기가 업데이트된 매니페스트를 받고 있는지 확인할 수 있습니다 이게 전부입니다! `--partial` 플래그는 Capgo에게 차등 업데이트에 필요한 개별 파일 업로드와 매니페스트 생성을 수행하도록 지시합니다 차등 업데이트로 전달하려는 새 버전을 업로드할 때마다 `--partial`을 사용해야 한다는 점에 유의하세요. 플래그를 생략하면 Capgo는 전체 JS 번들을 단일 파일로 업로드하고, 작은 부분만 변경되었더라도 기기는 전체 번들을 다운로드하게 됩니다 # 롤백 Capgo의 실시간 업데이트를 통해 사용자에게 빠르게 개선사항과 수정사항을 전달할 수 있지만, 이전 버전의 앱으로 롤백해야 하는 상황이 있을 수 있습니다. 새로운 업데이트가 예기치 않은 심각한 문제를 일으키거나, 수정 작업을 하는 동안 특정 변경사항을 되돌리고 싶을 수 있습니다. Capgo는 채널의 빌드를 관리하고 사용자가 받는 앱 버전을 제어하는 여러 가지 방법을 제공합니다. ## 이전 번들로 롤백하기 새로운 빌드를 업로드하고 채널에 할당할 때마다 Capgo는 해당 빌드의 기록을 보관합니다. 특정 업데이트를 되돌려야 하는 경우, 이전 빌드 중 하나를 선택하여 채널에 재배포할 수 있습니다. 이전 빌드로 롤백하는 방법: 1. [Capgo 대시보드](https://app.capgo.io)에 로그인합니다. 2. “Channels” 섹션으로 이동합니다. 3. 롤백하려는 채널의 이름을 클릭합니다. 4. 채널의 빌드 기록에서 되돌리고 싶은 빌드를 찾습니다. 5. 해당 빌드 옆의 왕관 아이콘을 클릭하여 채널의 활성 빌드로 지정합니다. ![Channel management options](/select_bundle.webp) 6. 이 빌드로 롤백할 것인지 확인합니다. Note 이전 빌드로 롤백하는 것은 선택한 채널에만 영향을 미칩니다. 여러 채널(예: Production, Staging 등)이 있는 경우, 영향을 받는 각 채널에 대해 롤백 과정을 반복해야 합니다. 롤백 후, 업데이트된 채널을 수신하도록 구성된 기기는 다음 업데이트 확인 시 이전 빌드를 받게 됩니다. 롤백된 빌드는 새로운 업데이트로 취급되므로, 일반적인 업데이트 흐름과 조건이 적용됩니다. ## 채널 연결 해제하기 문제를 조사하는 동안 채널의 업데이트를 일시적으로 중단하고 싶다면, 채널을 현재 빌드에서 연결 해제할 수 있습니다. 채널 연결을 해제하는 방법: 1. Capgo 대시보드에서 채널로 이동합니다. 2. 현재 빌드 옆의 “Unlink” 버튼을 클릭합니다. 3. 채널 연결을 해제할 것인지 확인합니다. 채널이 연결 해제되면 새로운 업데이트가 배포되지 않습니다. 해당 채널로 구성된 기기는 채널이 다시 빌드에 연결될 때까지 현재 빌드를 유지합니다. 이는 업데이트에 문제가 있지만 어떤 빌드로 롤백할지 아직 확실하지 않은 경우에 유용합니다. 채널 연결을 해제하면 추가 업데이트를 푸시하지 않고 조사할 시간을 확보할 수 있습니다. ## 기본 내장 번들 강제 적용하기 더 심각한 상황에서는 채널의 모든 기기를 앱의 네이티브 바이너리와 함께 원래 패키징된 웹 빌드로 되돌리고 싶을 수 있습니다. 이를 “기본 내장 번들”이라고 합니다. 채널에서 기본 내장 번들을 강제 적용하는 방법: 1. Capgo 대시보드에서 채널로 이동합니다. 2. “Built-in Bundle” 버튼을 클릭합니다. 3. 기본 내장 번들을 강제 적용할 것인지 확인합니다. 기본 내장 번들을 강제 적용하면, 해당 채널로 구성된 모든 기기가 다음 업데이트 확인 시 원래 패키징된 웹 빌드로 되돌아갑니다. 이는 현재 사용 중인 빌드와 관계없이 발생합니다. 이는 특정 이전 빌드로 되돌리는 것보다 더 적극적인 롤백 옵션이며, 앱이 마지막으로 앱스토어에 게시된 이후 출시된 모든 실시간 업데이트를 무시합니다. Caution 기본 내장 번들을 강제 적용할 때는 주의하세요. 채널의 모든 기기에 영향을 미치므로, 영향을 고려하고 이 조치를 취하기 전에 향후 계획을 세워야 합니다. ## 문제 모니터링 및 대응 문제를 빠르게 발견하고 문제가 있는 업데이트의 영향을 최소화하기 위해서는 릴리스를 모니터링하고 문제에 대응하는 계획을 수립하는 것이 중요합니다. 몇 가지 전략은 다음과 같습니다: * 업데이트 출시 직후 크래시 리포트와 사용자 피드백 모니터링 * 단계적 출시나 단계별 채널 시스템을 사용하여 광범위한 출시 전에 작은 그룹에서 업데이트 테스트 * 롤백, 연결 해제 또는 기본 내장 번들 강제 적용을 결정하는 명확한 프로세스와 권한을 가진 담당자 지정 * 적절한 경우 문제와 해결 방안에 대해 사용자와 소통 신중한 모니터링과 문제가 있는 업데이트를 신속하게 관리하는 능력을 결합함으로써, 사용자의 중단을 최소화하면서 지속적으로 개선되는 앱 경험을 제공할 수 있습니다. # 업데이트 동작 Capgo 앱의 업데이트를 배포할 때, 사용자가 최대한 빨리 업데이트를 받기를 원할 것입니다. 하지만 다운로드를 기다리거나 세션 중간에 앱을 재시작하도록 강요하여 사용자 경험을 방해하고 싶지는 않을 것입니다. Capgo의 업데이트 동작은 빠른 업데이트 제공과 사용자 방해 최소화 사이의 균형을 맞추도록 설계되었습니다. ## 기본 업데이트 흐름 기본적으로 Capgo는 다음과 같이 앱 업데이트를 처리합니다: 1. 앱 실행 시, Capgo 플러그인이 새 업데이트가 있는지 확인합니다 2. 업데이트가 발견되면, 사용자가 현재 버전의 앱을 계속 사용하는 동안 백그라운드에서 다운로드됩니다 3. 다운로드가 완료되면, Capgo는 사용자가 앱을 백그라운드로 보내거나 완전히 종료할 때까지 기다립니다 4. 사용자가 다음에 앱을 실행하면, 업데이트된 버전이 실행됩니다 이 흐름은 사용자가 업데이트 프롬프트에 의해 중단되거나 다운로드를 기다릴 필요 없이 항상 앱의 최신 버전을 실행하도록 보장합니다. Tip Capgo는 앱이 백그라운드에서 재개될 때도 업데이트를 확인하므로, 사용자가 앱을 완전히 종료하지 않아도 업데이트를 받을 수 있습니다. ## 이 접근 방식을 선택한 이유 백그라운드나 종료 이벤트에서 업데이트를 적용하는 것은 사용자 경험에 몇 가지 주요 이점이 있습니다: * 세션 중간에 업데이트 프롬프트로 인한 중단이나 다운로드 대기가 없습니다 * 업데이트는 세션 사이에 원활하게 적용되므로, 앱 실행 경험이 항상 새롭습니다 * 활성 사용자를 방해할 걱정 없이 자주 업데이트를 제공할 수 있습니다 주요 단점은 사용자가 앱을 백그라운드로 보내고 빠르게 재개할 경우, 업데이트가 그 사이에 적용되어 저장되지 않은 상태를 잃을 수 있다는 것입니다. 이를 완화하기 위해 다음을 권장합니다: * 상태를 자주 저장하고 앱이 재개될 때 원활하게 복원 * 앱 상태의 큰 부분을 수정하는 매우 빈번한 업데이트 피하기 * 중요한 흐름에 대해서는 업데이트 동작을 커스터마이징 고려(아래 참조) ## 업데이트 적용 시점 커스터마이징 경우에 따라 업데이트가 적용되는 정확한 시점을 더 세밀하게 제어하고 싶을 수 있습니다. 예를 들어, 사용자가 진행 중인 흐름을 완료하도록 보장하거나, 서버 측 변경과 앱 업데이트를 조정하고 싶을 수 있습니다. Capgo는 업데이트가 설치되기 전에 충족되어야 하는 조건을 지정할 수 있는 `setDelay` 함수를 제공합니다: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater'; await CapacitorUpdater.setMultiDelay({ delayConditions: [ { kind: 'date', value: '2023-06-01T00:00:00.000Z', }, { kind: 'background', value: '60000', }, ], }); ``` 이 예제는 2023년 6월 1일 이후 AND 앱이 60초 이상 백그라운드 상태가 된 후에 업데이트 설치를 지연시킵니다. 사용 가능한 지연 조건은 다음과 같습니다: * `date`: 특정 날짜/시간 이후에 업데이트 적용 * `background`: 앱이 백그라운드로 전환된 후 최소 지속 시간 동안 대기 * `nativeVersion`: 최소 버전의 네이티브 바이너리가 설치될 때까지 대기 * `kill`: 다음 앱 종료 이벤트까지 대기 이러한 조건들을 조합하여 업데이트가 설치되는 시점을 정밀하게 제어할 수 있습니다. Danger `kill` 조건은 현재 다른 조건들처럼 다음 백그라운드 이벤트가 아닌 첫 번째 종료 이벤트 후에 업데이트를 트리거한다는 점에 유의하세요. 이 불일치는 향후 릴리스에서 수정될 예정입니다. ## 즉시 업데이트 적용 중요한 업데이트나 매우 단순한 상태를 가진 앱의 경우, 백그라운드나 종료 이벤트를 기다리지 않고 다운로드 완료 즉시 업데이트를 적용하고 싶을 수 있습니다. Capgo는 `directUpdate` 구성 옵션을 통해 이를 지원합니다. `directUpdate`는 JavaScript 코드가 아닌 `capacitor.config.ts` 파일에서 설정됩니다: ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { autoUpdate: true, directUpdate: true, keepUrlPathAfterReload: true, }, }, }; export default config; ``` `directUpdate`가 활성화되면, Capgo는 사용자가 앱을 활발히 사용 중이더라도 다운로드가 완료되는 즉시 업데이트를 적용합니다. `directUpdate`는 네이티브 구성이므로 JavaScript 코드에서 추가적인 처리가 필요합니다. `directUpdate`를 사용할 때는 `appReady` 이벤트를 수신하고 이에 응답하여 앱의 스플래시 스크린을 숨겨야 합니다: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater'; import { SplashScreen } from '@capacitor/splash-screen'; CapacitorUpdater.addListener('appReady', () => { // 스플래시 스크린 숨기기 SplashScreen.hide(); }); CapacitorUpdater.notifyAppReady(); ``` `appReady` 이벤트는 앱 초기화가 완료되고 대기 중인 업데이트가 적용된 후에 발생합니다. 이는 사용자가 최신 버전을 볼 수 있도록 보장하므로 앱의 UI를 표시하기에 안전한 시점입니다. `appReady` 이벤트 처리 외에도, `directUpdate`를 사용할 때는 `keepUrlPathAfterReload` 구성 옵션을 `true`로 설정하는 것을 권장합니다. 이는 업데이트로 인한 앱 리로드 시 현재 URL 경로를 유지하여 앱에서 사용자의 위치를 유지하고 혼란을 줄이는 데 도움이 됩니다. `directUpdate`를 사용할 때 `appReady` 이벤트를 처리하지 않고 `keepUrlPathAfterReload`를 설정하지 않으면, 사용자가 잠시 오래된 버전의 앱을 보거나, 초기 경로로 돌아가거나, 업데이트가 적용될 때 깜빡임을 볼 수 있습니다. `directUpdate` 사용은 중요한 버그 수정이나 보안 패치를 제공하는 데 유용할 수 있지만, 몇 가지 트레이드오프가 있습니다: * `appReady` 이벤트를 적절히 처리하지 않으면 업데이트가 적용될 때 사용자가 깜빡임이나 로딩 상태를 볼 수 있습니다 * 업데이트가 앱 상태나 UI를 수정하는 경우, 사용자는 세션 중간에 방해가 되는 변경을 볼 수 있습니다 * `keepUrlPathAfterReload`가 설정되지 않은 경우 앱에서 사용자의 위치가 손실되어 혼란을 줄 수 있습니다 * 원활한 전환을 보장하기 위해 상태 저장 및 복원을 신중하게 처리해야 합니다 `directUpdate`를 활성화하는 경우 다음을 권장합니다: * `appReady` 이벤트를 처리하여 앱의 UI가 표시되는 시점을 제어 * `keepUrlPathAfterReload`를 `true`로 설정하여 앱에서 사용자의 위치 유지 * 사용자 진행 상태를 잃지 않도록 필요에 따라 앱 상태 저장 및 복원 * 갑작스러운 전환, 상태 손실 또는 혼란스러운 위치 변경이 없도록 앱의 업데이트 동작을 철저히 테스트 대부분의 경우 기본 업데이트 동작이 빠른 업데이트 제공과 방해 최소화 사이의 최상의 균형을 제공합니다. 하지만 특정 요구 사항이 있는 앱의 경우, Capgo는 업데이트가 적용되는 시기와 방법을 커스터마이징할 수 있는 유연성을 제공합니다. # 기능 및 설정 > 플러그인의 모든 사용 가능한 메서드와 구성 # 업데이터 플러그인 설정 자세한 내용은 Github [Readme](https://github.com/Cap-go/capacitor-updater)를 참조하세요 CapacitorUpdater는 다음 옵션으로 구성할 수 있습니다: | 속성 | 타입 | 설명 | 기본값 | 버전 | | ---------------------------- | --------- | -------------------------------------------------------------------------------------------------------- | --------------------------------------- | ----- | | **`appReadyTimeout`** | `number` | 네이티브 플러그인이 업데이트를 ‘실패’로 간주하기 전에 대기할 밀리초 수를 설정합니다. Android와 iOS에서만 사용 가능 | `10000 // (10초)` | | | **`responseTimeout`** | `number` | 네이티브 플러그인이 API 타임아웃으로 간주하기 전에 대기할 밀리초 수를 설정합니다. Android와 iOS에서만 사용 가능 | `20 // (20초)` | | | **`autoDeleteFailed`** | `boolean` | 플러그인이 실패한 번들을 자동으로 삭제할지 여부를 설정합니다. Android와 iOS에서만 사용 가능 | `true` | | | **`autoDeletePrevious`** | `boolean` | 성공적인 업데이트 후 플러그인이 이전 번들을 자동으로 삭제할지 여부를 설정합니다. Android와 iOS에서만 사용 가능 | `true` | | | **`autoUpdate`** | `boolean` | 플러그인이 업데이트 서버를 통한 자동 업데이트를 사용할지 여부를 설정합니다. Android와 iOS에서만 사용 가능 | `true` | | | **`resetWhenUpdate`** | `boolean` | 새로운 네이티브 앱 번들이 기기에 설치될 때 이전에 다운로드한 번들을 자동으로 삭제합니다. Android와 iOS에서만 사용 가능 | `true` | | | **`updateUrl`** | `string` | 업데이트 확인이 전송되는 URL/엔드포인트를 설정합니다. Android와 iOS에서만 사용 가능 | `https://plugin.capgo.app/updates` | | | **`channelUrl`** | `string` | 채널 작업을 위한 URL/엔드포인트를 설정합니다. Android와 iOS에서만 사용 가능 | `https://plugin.capgo.app/channel_self` | | | **`statsUrl`** | `string` | 업데이트 통계가 전송되는 URL/엔드포인트를 설정합니다. Android와 iOS에서만 사용 가능. 통계 보고를 비활성화하려면 ""로 설정 | `https://plugin.capgo.app/stats` | | | **`privateKey`** | `string` | 엔드-투-엔드 라이브 업데이트 암호화를 위한 개인 키를 설정합니다. Android와 iOS에서만 사용 가능. 버전 6.2.0에서 deprecated되었으며 버전 7.0.0에서 제거될 예정 | `undefined` | | | **`publicKey`** | `string` | 엔드-투-엔드 라이브 업데이트 암호화를 위한 공개 키를 설정합니다 (버전 2). Android와 iOS에서만 사용 가능 | `undefined` | 620 | | **`version`** | `string` | 앱의 현재 버전을 설정합니다. 첫 업데이트 요청에 사용됩니다. 설정하지 않으면 플러그인이 네이티브 코드에서 버전을 가져옵니다. Android와 iOS에서만 사용 가능 | `undefined` | 41748 | | **`directUpdate`** | `boolean` | 앱이 방금 업데이트/설치되었을 때 플러그인이 업데이트를 직접 설치하도록 합니다. 자동 업데이트 모드에서만 사용 가능. Android와 iOS에서만 사용 가능 | `undefined` | 510 | | **`periodCheckDelay`** | `number` | 주기적 업데이트 확인의 지연 시간을 초 단위로 설정합니다. Android와 iOS에서만 사용 가능. 600초(10분) 미만으로 설정할 수 없음 | `600 // (10분)` | | | **`localS3`** | `boolean` | 테스트 또는 자체 호스팅 업데이트 서버를 위해 CLI가 로컬 서버를 사용하도록 설정 | `undefined` | 41748 | | **`localHost`** | `string` | 테스트 또는 자체 호스팅 업데이트 서버를 위해 CLI가 로컬 서버를 사용하도록 설정 | `undefined` | 41748 | | **`localWebHost`** | `string` | 테스트 또는 자체 호스팅 업데이트 서버를 위해 CLI가 로컬 서버를 사용하도록 설정 | `undefined` | 41748 | | **`localSupa`** | `string` | 테스트 또는 자체 호스팅 업데이트 서버를 위해 CLI가 로컬 서버를 사용하도록 설정 | `undefined` | 41748 | | **`localSupaAnon`** | `string` | 테스트를 위해 CLI가 로컬 서버를 사용하도록 설정 | `undefined` | 41748 | | **`localApi`** | `string` | 테스트를 위해 CLI가 로컬 API를 사용하도록 설정 | `undefined` | 633 | | **`localApiFiles`** | `string` | 테스트를 위해 CLI가 로컬 파일 API를 사용하도록 설정 | `undefined` | 633 | | **`allowModifyUrl`** | `boolean` | 플러그인이 JavaScript 측에서 updateUrl, statsUrl 및 channelUrl을 동적으로 수정할 수 있도록 허용 | `false` | 540 | | **`defaultChannel`** | `string` | 설정에서 앱의 기본 채널 설정 | `undefined` | 550 | | **`appId`** | `string` | 앱의 설정에서 앱 ID를 구성합니다 | `undefined` | 600 | | **`keepUrlPathAfterReload`** | `boolean` | 리로드 후 URL 경로를 유지하도록 플러그인을 구성합니다 경고: 리로드가 트리거되면 ‘windowhistory’가 지워집니다 | `false` | 680 | ## 예시 `capacitorconfigjson`에서: ```json { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 // (1초), "responseTimeout": 10 // (10초), "autoDeleteFailed": false, "autoDeletePrevious": false, "autoUpdate": false, "resetWhenUpdate": false, "updateUrl": https://examplecom/api/auto_update, "channelUrl": https://examplecom/api/channel, "statsUrl": https://examplecom/api/stats, "privateKey": undefined, "publicKey": undefined, "version": undefined, "directUpdate": undefined, "periodCheckDelay": undefined, "localS3": undefined, "localHost": undefined, "localWebHost": undefined, "localSupa": undefined, "localSupaAnon": undefined, "localApi": undefined, "localApiFiles": undefined, "allowModifyUrl": undefined, "defaultChannel": undefined, "appId": undefined, "keepUrlPathAfterReload": undefined } } } ``` `capacitorconfigts`에서: ```ts /// import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { CapacitorUpdater: { appReadyTimeout: 1000 // (1초), responseTimeout: 10 // (10초), autoDeleteFailed: false, autoDeletePrevious: false, autoUpdate: false, resetWhenUpdate: false, updateUrl: https://examplecom/api/auto_update, channelUrl: https://examplecom/api/channel, statsUrl: https://examplecom/api/stats, privateKey: undefined, publicKey: undefined, version: undefined, directUpdate: undefined, periodCheckDelay: undefined, localS3: undefined, localHost: undefined, localWebHost: undefined, localSupa: undefined, localSupaAnon: undefined, localApi: undefined, localApiFiles: undefined, allowModifyUrl: undefined, defaultChannel: undefined, appId: undefined, keepUrlPathAfterReload: undefined, }, }, }; export default config; ``` # 메서드 ## notifyAppReady() ```typescript notifyAppReady() => Promise ``` 현재 번들이 제대로 작동하고 있다는 것을 Capacitor Updater에 알립니다 (이 메서드가 모든 앱 실행 시 호출되지 않으면 롤백이 발생합니다) 기본적으로 이 메서드는 앱 실행 후 처음 10초 내에 호출되어야 하며, 그렇지 않으면 롤백이 발생합니다 이 동작은 {@link appReadyTimeout}으로 변경할 수 있습니다 **반환:** `Promise` ## setUpdateUrl() ```typescript setUpdateUrl(options: UpdateUrl) => Promise ``` 앱의 업데이트 URL을 설정합니다. 이는 업데이트를 확인하는 데 사용됩니다 | 매개변수 | 타입 | 설명 | | ------------- | ----------- | ----------------------- | | **`options`** | `UpdateUrl` | 업데이트 확인에 사용할 URL을 포함합니다 | **버전:** 540부터 ## setStatsUrl() ```typescript setStatsUrl(options: StatsUrl) => Promise ``` 앱의 통계 URL을 설정합니다. 이는 통계를 전송하는 데 사용됩니다. 빈 문자열을 전달하면 통계 수집이 비활성화됩니다 | 매개변수 | 타입 | 설명 | | ------------- | ---------- | --------------------- | | **`options`** | `StatsUrl` | 통계 전송에 사용할 URL을 포함합니다 | **버전:** 540부터 ## setChannelUrl() ```typescript setChannelUrl(options: ChannelUrl) => Promise ``` 앱의 채널 URL을 설정합니다. 이는 채널을 설정하는 데 사용됩니다 | 매개변수 | 타입 | 설명 | | ------------- | ------------ | --------------------- | | **`options`** | `ChannelUrl` | 채널 설정에 사용할 URL을 포함합니다 | **버전:** 540부터 ## download() ```typescript download(options: DownloadOptions) => Promise ``` 제공된 URL에서 새 번들을 다운로드합니다. 이는 내부에 파일이 있는 zip 파일이거나 모든 파일이 포함된 고유 ID가 있는 zip 파일이어야 합니다 | 매개변수 | 타입 | 설명 | | ------------- | ----------------- | --------------------------------------------------------------- | | **`options`** | `DownloadOptions` | 새 번들 zip을 다운로드하기 위한 {@link [DownloadOptions](#downloadoptions)} | **반환:** `Promise` ## next() ```typescript next(options: BundleId) => Promise ``` 앱이 리로드될 때 사용할 다음 번들을 설정합니다| Param | Type | Description | | ------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | **`options`** | `BundleId` | 다음 앱 실행 시 설정할 다음 번들의 ID를 포함합니다 {@link [BundleInfoid](#bundleinfo)} | **Returns:** `Promise` *** ## set() ```typescript set(options: BundleId) => Promise ``` 현재 번들을 설정하고 즉시 앱을 리로드합니다 | Param | Type | Description | | ------------- | ---------- | ----------------------------------------------------- | | **`options`** | `BundleId` | 현재 설정할 새 번들 ID를 포함하는 {@link [BundleId](#bundleid)} 객체 | *** ## delete() ```typescript delete(options: BundleId) => Promise ``` 네이티브 앱 저장소에서 지정된 번들을 삭제합니다. {@link list}와 함께 저장된 번들 ID를 가져오는 데 사용하세요. | Param | Type | Description | | ------------- | ---------- | ------------------------------------------------------------------------------ | | **`options`** | `BundleId` | 삭제할 번들의 ID를 포함하는 {@link [BundleId](#bundleid)} 객체 (참고: 이것은 버전 이름이 아닌 번들 ID입니다) | *** ## list() ```typescript list(options?: ListOptions | undefined) => Promise ``` 앱에 로컬로 다운로드된 모든 번들을 가져옵니다 | Param | Type | Description | | ------------- | ------------- | ----------------------------------------------- | | **`options`** | `ListOptions` | 번들을 나열하기 위한 {@link [ListOptions](#listoptions)} | **Returns:** `Promise` *** ## reset() ```typescript reset(options?: ResetOptions | undefined) => Promise ``` 앱을 `builtin` 번들(Apple App Store / Google Play Store에 전송된 것) 또는 마지막으로 성공적으로 로드된 번들로 리셋합니다 | Param | Type | Description | | ------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------- | | **`options`** | `ResetOptions` | {@link [ResetOptionstoLastSuccessful](#resetoptions)}을 포함하며, `true`는 기본 제공 번들로 리셋하고 `false`는 마지막으로 성공적으로 로드된 번들로 리셋합니다 | *** ## current() ```typescript current() => Promise ``` 현재 번들을 가져옵니다. 설정된 것이 없으면 `builtin`을 반환합니다. currentNative는 기기에 설치된 원본 번들입니다 **Returns:** `Promise` *** ## reload() ```typescript reload() => Promise ``` 뷰를 리로드합니다 *** ## setMultiDelay() ```typescript setMultiDelay(options: MultiDelayConditions) => Promise ``` 플러그인이 업데이트를 지연시키는 데 사용할 조건이 포함된 {@link [DelayCondition](#delaycondition)} 배열을 설정합니다 모든 조건이 충족되면 업데이트 프로세스가 다시 평소대로 시작되므로 앱을 백그라운드로 전환하거나 종료한 후에 업데이트가 설치됩니다 `date` 종류의 경우 값은 iso8601 날짜 문자열이어야 합니다 `background` 종류의 경우 값은 밀리초 단위의 숫자여야 합니다 `nativeVersion` 종류의 경우 값은 버전 번호여야 합니다 `kill` 종류의 경우 값이 사용되지 않습니다 이 함수는 kill 옵션이 다른 옵션처럼 다음 백그라운드 후가 아닌 첫 번째 종료 후에 업데이트를 트리거하는 일관되지 않은 동작을 보입니다. 이는 향후 주요 릴리스에서 수정될 예정입니다 | Param | Type | Description | | ------------- | ---------------------- | --------------------------------------------------------------------- | | **`options`** | `MultiDelayConditions` | 설정할 조건 배열을 포함하는 {@link [MultiDelayConditions](#multidelayconditions)} | **Since:** 430 *** ## cancelDelay() ```typescript cancelDelay() => Promise ``` 업데이트를 즉시 처리하기 위해 {@link [DelayCondition](#delaycondition)}을 취소합니다 **Since:** 400 *** ## getLatest() ```typescript getLatest(options?: GetLatestOptions | undefined) => Promise ``` 업데이트 URL에서 사용 가능한 최신 번들을 가져옵니다 | Param | Type | | ------------- | ------------------ | | **`options`** | `GetLatestOptions` | **Returns:** `Promise` **Since:** 400 *** ## setChannel() ```typescript setChannel(options: SetChannelOptions) => Promise ``` 이 기기의 채널을 설정합니다. 이 작업이 작동하려면 채널이 자체 할당을 허용해야 합니다 `autoUpdate`가 {@link PluginsConfig}에서 활성화된 경우 부팅 시 채널을 설정하는 데 이 메서드를 사용하지 마세요 이 메서드는 앱이 준비된 후에 채널을 설정하는 데 사용됩니다 이 메서드는 기기 ID를 채널에 연결하는 요청을 Capgo 백엔드로 보냅니다. Capgo는 채널 설정에 따라 수락하거나 거부할 수 있습니다 | Param | Type | Description | | ------------- | ------------------- | ------------------------------------------------------- | | **`options`** | `SetChannelOptions` | 설정할 채널인 {@link [SetChannelOptions](#setchanneloptions)} | **Returns:** `Promise` **Since:** 470 *** ## unsetChannel() ```typescript unsetChannel(options: UnsetChannelOptions) => Promise ``` 이 기기의 채널 설정을 해제합니다디바이스가 기본 채널로 돌아갑니다 | Param | Type | | ------------- | --------------------- | | **`options`** | `UnsetChannelOptions` | **Since:** 470 *** ## getChannel() ```typescript getChannel() => Promise ``` 이 디바이스의 채널을 가져옵니다 **Returns:** `Promise` **Since:** 480 *** ## setCustomId() ```typescript setCustomId(options: SetCustomIdOptions) => Promise ``` 이 디바이스에 대한 커스텀 ID를 설정합니다 | Param | Type | Description | | ------------- | -------------------- | ----------------------------------------------------------------- | | **`options`** | `SetCustomIdOptions` | {@link [SetCustomIdOptions](#setcustomidoptions)} 설정할 customId입니다 | **Since:** 490 *** ## getBuiltinVersion() ```typescript getBuiltinVersion() => Promise ``` 네이티브 앱 버전 또는 config에 설정된 빌트인 버전을 가져옵니다 **Returns:** `Promise` **Since:** 520 *** ## getDeviceId() ```typescript getDeviceId() => Promise ``` 디바이스를 식별하는데 사용되는 고유 ID를 가져옵니다(자동 업데이트 서버로 전송됨) **Returns:** `Promise` *** ## getPluginVersion() ```typescript getPluginVersion() => Promise ``` 네이티브 Capacitor Updater 플러그인 버전을 가져옵니다(자동 업데이트 서버로 전송됨) **Returns:** `Promise` *** ## isAutoUpdateEnabled() ```typescript isAutoUpdateEnabled() => Promise ``` 자동 업데이트 설정 상태를 가져옵니다 **Returns:** `Promise` *** ## removeAllListeners() ```typescript removeAllListeners() => Promise ``` 이 플러그인의 모든 리스너를 제거합니다 **Since:** 100 *** ## addListener(‘download’, ) ```typescript addListener(eventName: 'download', listenerFunc: (state: DownloadEvent) => void) => Promise ``` 앱에서 번들 다운로드 이벤트를 수신합니다. 다운로드가 시작되고, 다운로드 중이며, 완료되었을 때 발생합니다 | Param | Type | | ------------------ | -------------------------------- | | **`eventName`** | `’download’` | | **`listenerFunc`** | `(state: DownloadEvent) => void` | **Returns:** `Promise` **Since:** 2011 *** ## addListener(‘noNeedUpdate’, ) ```typescript addListener(eventName: 'noNeedUpdate', listenerFunc: (state: NoNeedEvent) => void) => Promise ``` 업데이트가 필요 없음 이벤트를 수신합니다. 앱이 실행될 때마다 강제로 확인하고 싶을 때 유용합니다 | Param | Type | | ------------------ | ------------------------------ | | **`eventName`** | `’noNeedUpdate’` | | **`listenerFunc`** | `(state: NoNeedEvent) => void` | **Returns:** `Promise` **Since:** 400 *** ## addListener(‘updateAvailable’, ) ```typescript addListener(eventName: 'updateAvailable', listenerFunc: (state: UpdateAvailableEvent) => void) => Promise ``` 사용 가능한 업데이트 이벤트를 수신합니다. 앱이 실행될 때마다 강제로 확인하고 싶을 때 유용합니다 | Param | Type | | ------------------ | --------------------------------------- | | **`eventName`** | `’updateAvailable’` | | **`listenerFunc`** | `(state: UpdateAvailableEvent) => void` | **Returns:** `Promise` **Since:** 400 *** ## addListener(‘downloadComplete’, ) ```typescript addListener(eventName: 'downloadComplete', listenerFunc: (state: DownloadCompleteEvent) => void) => Promise ``` 다운로드 완료 이벤트를 수신합니다 | Param | Type | | ------------------ | ---------------------------------------- | | **`eventName`** | `’downloadComplete’` | | **`listenerFunc`** | `(state: DownloadCompleteEvent) => void` | **Returns:** `Promise` **Since:** 400 *** ## addListener(‘majorAvailable’, ) ```typescript addListener(eventName: 'majorAvailable', listenerFunc: (state: MajorAvailableEvent) => void) => Promise ``` 앱에서 메이저 업데이트 이벤트를 수신합니다. disableAutoUpdateBreaking 설정에 의해 메이저 업데이트가 차단된 경우를 알려줍니다 | Param | Type | | ------------------ | -------------------------------------- | | **`eventName`** | `’majorAvailable’` | | **`listenerFunc`** | `(state: MajorAvailableEvent) => void` | **Returns:** `Promise` **Since:** 230 *** ## addListener(‘updateFailed’, ) ```typescript addListener(eventName: 'updateFailed', listenerFunc: (state: UpdateFailedEvent) => void) => Promise ``` 업데이트 실패 이벤트를 수신합니다. 다음 앱 시작 시 업데이트 설치가 실패했을 때를 알려줍니다 | Param | Type | | ------------------ | ------------------------------------ | | **`eventName`** | `’updateFailed’` | | **`listenerFunc`** | `(state: UpdateFailedEvent) => void` | **Returns:** `Promise` **Since:** 230 *** ## addListener(‘downloadFailed’,\`\`\`typescript addListener(eventName: ‘downloadFailed’, listenerFunc: (state: DownloadFailedEvent) => void) => Promise ````plaintext 앱에서 다운로드 실패 이벤트를 수신하여 번들 다운로드가 실패했을 때 알려줍니다 | Param | Type | | ------------------ | ----------------------------------------------------------------------- | | **`eventName`** | 'downloadFailed' | | **`listenerFunc`** | (state: DownloadFailedEvent) => void | **Returns:** Promise<PluginListenerHandle> **Since:** 400 -------------------- ## addListener('appReloaded', ) ```typescript addListener(eventName: 'appReloaded', listenerFunc: () => void) => Promise ```` 앱의 리로드 이벤트를 수신하여 리로드가 발생했을 때 알려줍니다 | Param | Type | | ------------------ | --------------- | | **`eventName`** | `’appReloaded’` | | **`listenerFunc`** | `() => void` | **Returns:** `Promise` **Since:** 430 *** ## addListener(‘appReady’, ) ```typescript addListener(eventName: 'appReady', listenerFunc: (state: AppReadyEvent) => void) => Promise ``` 앱의 준비 완료 이벤트를 수신하여 앱을 사용할 준비가 되었을 때 알려줍니다 | Param | Type | | ------------------ | -------------------------------- | | **`eventName`** | `’appReady’` | | **`listenerFunc`** | `(state: AppReadyEvent) => void` | **Returns:** `Promise` **Since:** 510 *** ## isAutoUpdateAvailable() ```typescript isAutoUpdateAvailable() => Promise ``` 자동 업데이트가 사용 가능한지 확인합니다 (serverUrl에 의해 비활성화되지 않음) **Returns:** `Promise` *** ## getNextBundle() ```typescript getNextBundle() => Promise ``` 앱이 리로드될 때 사용될 다음 번들을 가져옵니다 다음 번들이 설정되지 않은 경우 null을 반환합니다 **Returns:** `Promise` **Since:** 680 *** ## Interfaces ### AppReadyResult | Prop | Type | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | ### BundleInfo | Prop | Type | | ---------------- | -------------- | | **`id`** | `string` | | **`version`** | `string` | | **`downloaded`** | `string` | | **`checksum`** | `string` | | **`status`** | `BundleStatus` | ### UpdateUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### StatsUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### ChannelUrl | Prop | Type | | --------- | -------- | | **`url`** | `string` | ### DownloadOptions | Prop | Type | Description | Default | Since | | ---------------- | -------- | ------------------------------------------------------------------------------------- | ----------- | ----- | | **`url`** | `string` | 다운로드할 번들 zip 파일(예: distzip)의 URL(Amazon S3, GitHub 태그, 번들을 호스팅한 다른 위치 등의 URL일 수 있습니다) | | | | **`version`** | `string` | 이 번들/버전의 버전 코드/이름 | | | | **`sessionKey`** | `string` | 업데이트를 위한 세션 키 | `undefined` | 400 | | **`checksum`** | `string` | 업데이트를 위한 체크섬 | `undefined` | 400 | ### BundleId | Prop | Type | | -------- | -------- | | **`id`** | `string` | ### BundleListResult | Prop | Type | | ------------- | -------------- | | **`bundles`** | `BundleInfo[]` | ### ListOptions | Prop | Type | Description | Default | Since | | --------- | --------- | --------------------------------------------------------------------- | ------- | ----- | | **`raw`** | `boolean` | 원시 번들 목록 또는 매니페스트를 반환할지 여부. true인 경우 디스크의 파일 대신 내부 데이터베이스를 읽으려고 시도합니다 | `false` | 6140 | ### ResetOptions | Prop | Type | | ---------------------- | --------- | | **`toLastSuccessful`** | `boolean` | ### CurrentBundleResult | Prop | Type | | ------------ | ------------ | | **`bundle`** | `BundleInfo` | | **`native`** | `string` | ### MultiDelayConditions | Prop | Type | | --------------------- | ------------------ | | **`delayConditions`** | `DelayCondition[]` | ### DelayCondition | Prop | Type | Description | | ----------- | ---------------- | ------------------------ | | **`kind`** | `DelayUntilNext` | setMultiDelay에서 지연 조건 설정 | | **`value`** | `string` | | ### LatestVersion | Prop | Type | Description | Since | | ---------------- | ----------------- | ----------------- | ----- | | **`version`** | `string` | getLatest 메서드의 결과 | 40 | | **`major`** | `boolean` | | | | **`message`** | `string` | | | | **`sessionKey`** | `string` | | | | **`error`** | `string` | | | | **`old`** | `string` | | | | **`url`** | `string` | | | | **`manifest`** | `ManifestEntry[]` | | 61 | ### ManifestEntry | Prop | Type | | ------------------ | ---------------- | | **`file_name`** | `string \| null` | | **`file_hash`** | `string \| null` | | **`download_url`** | `string \| null` | ### GetLatestOptions | Prop | Type | Description | Default | Since | | ------------- | -------- | -------------------------------------------------------- | ----------- | ----- | | **`channel`** | `string` | 최신 버전을 받을 채널입니다. 이 작업을 위해서는 채널이 ‘self\_assign’을 허용해야 합니다 | `undefined` | 680 | ### ChannelRes | Prop | Type | Description | Since | | ------------- | -------- | ------------- | ----- | | **`status`** | `string` | 설정된 채널의 현재 상태 | 470 | | **`error`** | `string` | | | | **`message`** | `string` | | | ### SetChannelOptions | Prop | Type | | ----------------------- | --------- | | **`channel`** | `string` | | **`triggerAutoUpdate`** | `boolean` | ### UnsetChannelOptions | Prop | Type | | ----------------------- | --------- | | **`triggerAutoUpdate`** | `boolean` | ### GetChannelRes | Prop | Type | Description | Since | | -------------- | --------- | ------------- | ----- | | **`channel`** | `string` | 가져온 채널의 현재 상태 | 480 | | **`error`** | `string` | | | | **`message`** | `string` | | | | **`status`** | `string` | | | | **`allowSet`** | `boolean` | | | ### SetCustomIdOptions | Prop | Type | | -------------- | -------- | | **`customId`** | `string` | ### BuiltinVersion | Prop | Type | | ------------- | -------- | | **`version`** | `string` | ### DeviceId | Prop | Type | | -------------- | -------- | | **`deviceId`** | `string` | ### PluginVersion | Prop | Type | | ------------- | -------- | | **`version`** | `string` | ### AutoUpdateEnabled | Prop | Type | | ------------- | --------- | | **`enabled`** | `boolean` | ### PluginListenerHandle | Prop | Type | | ------------ | --------------------- | | **`remove`** | `() => Promise` | ### DownloadEvent | Prop | Type | Description | Since | | ------------- | ------------ | ----------------------- | ----- | | **`percent`** | `number` | 다운로드의 현재 상태, 0에서 100 사이 | 400 | | **`bundle`** | `BundleInfo` | | | ### NoNeedEvent | Prop | Type | Description | Since | | ------------ | ------------ | ----------------------- | ----- | | **`bundle`** | `BundleInfo` | 다운로드의 현재 상태, 0에서 100 사이 | 400 | ### UpdateAvailableEvent | Prop | Type | Description | Since | | ------------ | ------------ | ----------------------- | ----- | | **`bundle`** | `BundleInfo` | 다운로드의 현재 상태, 0에서 100 사이 | 400 | ### DownloadCompleteEvent | Prop | Type | Description | Since | | ------------ | ------------ | ------------------ | ----- | | **`bundle`** | `BundleInfo` | 새로운 업데이트가 가능할 때 발생 | 400 | ### MajorAvailableEvent | Prop | Type | Description | Since | | ------------- | -------- | -------------------- | ----- | | **`version`** | `string` | 새로운 메이저 번들이 가능할 때 발생 | 400 | ### UpdateFailedEvent | Prop | Type | Description | Since | | ------------ | ------------ | ------------------ | ----- | | **`bundle`** | `BundleInfo` | 업데이트 설치에 실패했을 때 발생 | 400 | ### DownloadFailedEvent | Prop | Type | Description | Since | | ------------- | -------- | ------------ | ----- | | **`version`** | `string` | 다운로드 실패 시 발생 | 400 | ### AppReadyEvent | Prop | Type | Description | Since | | ------------ | ------------ | ------------------ | ----- | | **`bundle`** | `BundleInfo` | 앱이 사용 준비가 되었을 때 발생 | 520 | | **`status`** | `string` | | | ### AutoUpdateAvailable | Prop | Type | | --------------- | --------- | | **`available`** | `boolean` | ## Type Aliases ### BundleStatus `‘success’ | ‘error’ | ‘pending’ | ‘downloading’` ### DelayUntilNext `‘background’ | ‘kill’ | ‘nativeVersion’ | ‘date’` # Aggiornamento automatico > capacitor-updater를 사용한 자동 업데이트 방법 이 모드를 사용하면 개발자가 자동 업데이트 모드로 capacitor-updater를 사용하고 Capgo 채널 또는 동등한 방법을 통해 업데이트를 푸시할 수 있습니다. ### 전제 조건 Capgo 자동 업데이트를 사용하기 전에 앱 버전이 를 사용하는지 확인하세요. 이는 Capgo에서 버전을 관리하는 데 사용하는 규칙입니다. 앱에서 버전을 설정하는 두 가지 방법이 있습니다: 새로운 방법: `capacitorconfigjson` 파일의 `version` 필드 사용 ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true, // 자동 업데이트 활성화, 기본값은 true "appId": "comexampleapp", // 서버에서 앱을 식별하는데 사용 "version": "100" // 업데이트 확인에 사용 } } } ``` 이러한 옵션은 플러그인이 업데이트를 확인하고 CLI가 버전을 업로드하는데 사용됩니다. 이전 방법: 프로젝트의 3개 파일에서: * `packagejson`의 **version** * `android/app/buildgradle`의 **versionName** * `ios/App/Appxcodeproj/projectpbxproj`의 **CURRENT\_PROJECT\_VERSION** ### 튜토리얼 5분 만에 앱 설정하기 [capacitor updater를 사용하여 원활하게 capacitor 앱 업데이트하기](https://capgo.app/blog/update-your-capacitor-apps-seamlessly-using-capacitor-updater) 5분 만에 CI 설정하기 [GitHub actions를 사용한 자동 빌드 및 릴리스](https://capgo.app/blog/automatic-build-and-release-with-github-actions) ### 설치 ```bash npm install @capgo/capacitor-updater npx cap sync ``` ### 소개 [등록](https://capgo.app)을 클릭하여 계정을 만드세요 서버에서 채널과 버전 등을 관리할 수 있습니다 `autoUpdate`는 Capgo 서버를 식별하기 위해 `capacitorconfig`의 데이터를 사용합니다 Note 회사에서 허용하지 않는 경우 코드를 서버로 전송하지 않고도 Capgo Cloud를 계속 사용할 수 있습니다 #### 버전 확인 자동 업데이트가 설정되면 JS 내에서 앱이 살아있고 준비되었음을 알려야 합니다 이는 앱 내에서 `notifyAppReady`를 호출하여 수행할 수 있습니다 가능한 한 빨리 수행하세요 ```ts import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdater.notifyAppReady() ``` #### 사용자 흐름 * 사용자가 앱을 열면 앱이 서버에 업데이트를 확인하고, 업데이트가 발견되면 백그라운드에서 다운로드됩니다 * 사용자가 앱을 나가면 새 버전이 활성 상태로 설정됩니다 * 사용자가 앱을 다시 열면 새로운 활성 버전을 로드하고 기본값으로 설정합니다 * `notifyAppReady()`가 호출되면 사용자가 앱을 나갈 때 이전 버전이 삭제됩니다 * 사용자는 다음 업데이트 주기까지 앱의 정상적인 흐름을 계속합니다 Danger ⚠️ 앱에서 `notifyAppReady()`를 호출하지 않으면 현재 버전이 유효하지 않은 것으로 표시되고 이전의 유효한 번들이나 기본 버전으로 되돌아갑니다 #### 개발 흐름 새로운 기능을 개발할 때는 capgo가 지속적으로 최신 업데이트 번들로 작업을 덮어쓰므로 `autoUpdate`를 차단해야 합니다 설정에서 `autoUpdate`를 false로 설정하세요 어떤 이유로 업데이트에 문제가 생기면 앱을 삭제하고 다시 설치할 수 있습니다 그렇게 하기 전에 설정에서 `autoUpdate`를 false로 설정하세요 그리고 Xcode나 Android studio로 다시 빌드하세요 각 커밋에서 버전을 업로드하려면 이 가이드로 CI/CD를 설정하세요 [GitHub actions를 사용한 자동 빌드 및 릴리스](https://capgo.app/blog/automatic-build-and-release-with-github-actions) #### Major Available 이벤트 `disableAutoUpdateBreaking`이 true로 설정되어 있을 때, 앱이 주요 브레이킹 업데이트를 거부할 때를 알기 위해 이벤트를 수신할 수 있습니다 ```jsx import { CapacitorUpdater } from '@capgo/capacitor-updater' CapacitorUpdater.addListener('majorAvailable', (info: any) => { console.log('majorAvailable was fired', info.version) }) ``` # Kanalsystem > capacitor-updater와 채널 시스템을 사용하는 방법 Capgo와 capacitor-updater는 강력한 채널 시스템을 제공합니다 ## 채널로 할 수 있는 것: * 개발, 베타 테스트를 위해 기기를 채널에 연결 * 개발 브랜치당 하나의 채널을 사용하고 팀원이 휴대폰에서 자체 할당하여 테스트 ## 기기를 채널에 할당하기: * 채널을 기본값으로 설정하면 새로운 기기가 Capgo에 업데이트를 요청할 때마다 이 채널이 응답 * [**getDeviceId**](/docs/plugin/api#getdeviceid) 메소드로 **deviceId**를 백엔드에 전송하고 Capgo 공개 API로 할당 * 채널을 자체 할당 가능하도록 설정([**setChannel**](/docs/plugin/api#setchannel) 메소드)하고 플러그인의 `setChannel` 메소드를 사용하여 기기가 채널을 구독하도록 함(사용자 상호작용 여부 선택) * [config](/docs/plugin/settings#defaultchannel)의 `defaultChannel` 옵션을 사용하여 이 플러그인 구성의 모든 기기에 대한 기본 채널 설정 Note 기기를 번들에 직접 할당할 수도 있습니다 ## 채널 옵션 ![](/channel_setting_1.webp) 각 옵션에 대한 설명: | 옵션 | 설명 | | ------------------------------ | ---------------------------------------------------- | | **네이티브 버전 이하로 자동 다운그레이드 비활성화** | 앱의 네이티브 버전이 채널 버전보다 큰 경우 업데이트를 보내지 않음 | | **메이저 버전 이상으로 자동 업그레이드 비활성화** | 앱의 네이티브 버전이 채널의 메이저 버전(**1**23)보다 낮은 경우 업데이트를 보내지 않음 | | **마이너 버전 이상으로 자동 업그레이드 비활성화** | 앱의 네이티브 버전이 채널의 마이너 버전(1**2**3)보다 낮은 경우 업데이트를 보내지 않음 | | **기기 자체 할당 허용** | 기기가 이 채널에 `setChannel` 메소드를 사용할 수 있도록 허용 | | **iOS** | iOS 기기가 이 채널에서 업데이트를 다운로드할 수 있도록 허용 | | **Android** | Android 기기가 이 채널에서 업데이트를 다운로드할 수 있도록 허용 | | **에뮬레이터 허용** | 에뮬레이터가 이 채널에서 업데이트를 받을 수 있도록 허용 | | **개발 빌드 허용** | 개발 빌드가 이 채널에서 업데이트를 받을 수 있도록 허용 | Note CI/CD가 Google Play에 버전을 보내도록 구성된 경우, Google Play는 매번 20개 이상의 실제 기기에서 앱을 실행합니다. Capgo는 통계에 포함되는 것을 방지하기 위해 새로운 번들의 처음 4시간 동안 Google 데이터 센터 IP를 차단합니다. Note Capgo는 에뮬레이터와 개발 빌드를 사용량에 포함하지 **않지만**, 3% 이상을 초과할 수 없으며 초과 시 수정할 때까지 계정이 잠긴다는 점을 유의하세요 # 시작하기 > 앱에 플러그인 설치하기 ## Capgo 소개 [Play](https://youtube.com/watch?v=NzXXKoyhTIo) ## 라이브 업데이트까지 3단계만 남았습니다 ### 계정 만들기 에서 등록 페이지를 방문하세요 ![onboarding screenshot](/onboard.webp "onboarding screenshot") ### CLI로 Capgo 설치하기 시작하려면 매직 커맨드를 사용하세요 ```bash npx @capgo/cli@latest init [APIKEY] ``` 이 명령어가 설정 과정을 안내할 것입니다 ### 안내에 따라 진행하기 CLI에서 일련의 질문들이 표시됩니다. 자동 설정을 완료하기 위해 필요한 답변을 제공하세요 Tip 이 단계들을 따르면 금방 시작하실 수 있습니다. 과정 중에 추가 도움이 필요하시다면 저희 지원팀이 도와드리겠습니다. 즐거운 온보딩 되세요! ### Capgo의 마법을 즐기세요! 앱을 테스트하고 나중에 Capgo의 강력한 기능들을 사용하는 방법을 배워보세요 # 하이브리드 업데이트 > 자동 업데이트를 위한 업데이트 방법 사용자에게 업데이트를 푸시할 때, 업데이트를 적용하기 전에 상황에 맞게 업데이트 주기를 처리하는 몇 가지 방법이 있습니다 * 자동 업데이트 * `updateAvailable` 이벤트 감지 * 모달 창 표시 또는 업데이트 지연 ## 자동 업데이트 `directUpdate`를 `true`로 설정하여 앱 시작마다 업데이트 주기가 강제로 실행되도록 할 수 있습니다. 이는 사용자 상호작용 없이 일반적인 업데이트 주기를 트리거합니다 ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "directUpdate": true, }, "SplashScreen": { "launchAutoHide": false, } } } ``` 그리고 앱에서 `appReady` 이벤트를 받으면 스플래시 화면을 숨겨야 합니다: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' CapacitorUpdateraddListener('appReady', () => { // Hide splash SplashScreenhide() }) CapacitorUpdaternotifyAppReady() ``` ## 강제 업데이트 `updateAvailable` 이벤트에 리스너를 추가하고 앱이 업데이트될 것임을 사용자에게 알리는 알림을 표시합니다: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { Dialog } from '@capacitor/dialog' CapacitorUpdateraddListener('updateAvailable', async (res) => { try { await Dialogalert({ title: '업데이트 가능', message: `버전 ${resbundleversion}이 사용 가능합니다. 지금 앱이 업데이트됩니다`, }) CapacitorUpdaterset(resbundle) } catch (error) { consolelog(error) } }) CapacitorUpdaternotifyAppReady() ``` ## 모달 업데이트 사용자에게 업데이트 여부를 물어보는 대화상자를 표시하여 사용자가 결정하도록 할 수도 있습니다: ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' import { Dialog } from '@capacitor/dialog' CapacitorUpdateraddListener('updateAvailable', async (res) => { try { const { value } = await Dialogconfirm({ title: '업데이트 가능', message: `버전 ${resbundleversion}이 사용 가능합니다. 지금 업데이트하시겠습니까?`, }) if (value) CapacitorUpdaterset(resbundle) } catch (error) { consolelog(error) } }) CapacitorUpdaternotifyAppReady() ``` # 수동 업데이트 > 앱 업데이트 관리 방법 Capgo 클라우드와 함께 수동 모드를 사용하여 업데이트가 적용되는 시기를 직접 관리하고 싶다면 다음과 같이 해야 합니다. Getting Started에 설명된 대로 계정을 설정하세요. [Getting Started ](/docs/getting-started/quickstart/) #### 설정 `capacitor.config.json`에서 자동 업데이트를 비활성화하세요 ```tsx // capacitor.config.json { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` 그런 다음 업데이트를 직접 처리하는 로직을 추가하세요\ 다음은 구현 예시입니다: ```typescript import { CapacitorUpdater } from '@capgo/capacitor-updater' import type { BundleInfo } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' CapacitorUpdater.notifyAppReady() let data: BundleInfo | null = null App.addListener('appStateChange', async (state: any) => { console.log('appStateChange', state) if (state.isActive) { console.log('getLatest') // 다운로드 실패를 방지하기 위해 앱이 활성화된 상태에서 다운로드를 수행합니다 const latest = await CapacitorUpdater.getLatest() console.log('latest', latest) if (latest.url) { data = await CapacitorUpdater.download(latest) console.log('download', data) } } if (!state.isActive && data) { console.log('set') // 사용자가 앱을 나갈 때나 원하는 시점에 전환을 수행합니다 SplashScreen.show() try { await CapacitorUpdater.set({ id: data.id }) } catch (err) { console.log(err) SplashScreen.hide() // set이 실패한 경우를 위해, 그렇지 않으면 새 앱에서 숨겨야 합니다 } } }) ``` 플러그인의 모든 사용 가능한 API 문서: [Methods ](/docs/plugin/api/) 사용자가 채널을 구독하고 다른 버전을 시도할 수 있게 하는 사용 사례가 있습니다:\ # 코르도바 > Capacitor-updater가 Cordova에서 사용 가능할까요? 이 플러그인이 Cordova에서도 사용 가능할지 궁금하셨을 것입니다 저는 이를 위한 R\&D 저장소를 시작했지만, 이는 많은 작업이 필요합니다 ## 문제점 가능하다는 것을 알고 있지만, 이를 위해서는 Capacitor에서 했던 것처럼 Cordova 코드베이스의 모든 코드를 읽어봐야 작동 방식을 이해할 수 있습니다 Android 버전은 둘 다 Java를 사용하기 때문에 더 쉽지만, iOS는 Swift가 Cordova에서 아직 잘 지원되지 않기 때문에 전체적인 재작성이 필요합니다 ## 해결방안 그동안 다음과 같은 방법을 시도해 볼 수 있습니다: * GitHub에서 [저를 후원](https://github.com/sponsors/riderx)하시면 우선순위를 둘 수 있습니다. 이는 최소 1개월의 작업이 필요합니다 * 저를 컨설턴트로 고용하세요. 저는 큰 기업들이 capacitor로 마이그레이션하는 것을 도와왔습니다. 보통 10-20일이 소요되며, 팀에게 [이점](https://ionicio/resources/articles/capacitor-vs-cordova-modern-hybrid-app-development)이 매우 큽니다 # デバッグ > 앱 디버깅하기 ## 클라우드 로그 이해하기: ### 백엔드에서 전송됨 | code | 설명 | | ----------------------------------------- | ------------------------------------------------------------------------------------------ | | **InvalidIp** | 사용자가 Google 데이터 센터에 위치해 있고 업데이트가 4시간 미만인 경우입니다. 이는 Google 봇 기기가 계정의 기기로 집계되는 것을 방지하기 위함입니다 | | **needPlanUpgrade** (이전의 **needUpgrade**) | 플랜 한도에 도달했으며, 업그레이드하거나 다음 달까지 기기가 업데이트를 받지 못함을 나타냅니다 | | **noNew** | 기기가 최신 버전을 사용 중입니다 | | **disablePlatformIos** | 기기가 iOS 플랫폼이지만 채널 설정에서 비활성화되어 있습니다 | | **disablePlatformAndroid** | 기기가 Android 플랫폼이지만 채널 설정에서 비활성화되어 있습니다 | | **disableAutoUpdate** | ”major" | | **disableAutoUpdateUnderNative** | 기기가 버전(`123`)을 가지고 있고, 채널에 기기 버전 아래의 업데이트(`122`)가 있지만 채널 설정에서 비활성화되어 있습니다 | | **disableDevBuild** | 기기가 개발 빌드이지만 채널 설정에서 비활성화되어 있습니다 | | **disableEmulator** | 기기가 에뮬레이터이지만 채널 설정에서 비활성화되어 있습니다 | ### 기기에서 전송됨 | code | 설명 | | ------------------------- | ------------------------------------------ | | **get** | 새 버전 다운로드 정보가 기기로 전송되었습니다 | | **delete** | 기기에서 번들이 삭제되었습니다 | | **set** | 기기에 번들이 설정되었습니다 | | **set\_fail** | 번들 설정에 실패했습니다 | | **reset** | 기기가 `builtin` 번들로 초기화되었습니다 | | **download\_XX** | 새 번들이 다운로드되었습니다 - XX%로 진행률 표시 (10% 단위로 증가) | | **download\_complete** | 새 번들 다운로드가 완료되었습니다 | | **download\_fail** | 새 번들 다운로드에 실패했습니다 | | **update\_fail** | 새 번들이 설치되었지만 `notifyAppReady` 호출에 실패했습니다 | | **checksum\_fail** | 새 번들의 체크섬 검증에 실패했습니다 | | **windows\_path\_fail** | zip 파일에 잘못된 Windows 경로가 포함되어 있습니다 | | **canonical\_path\_fail** | 파일 경로가 정규화되지 않았습니다 | | **directory\_path\_fail** | zip 파일 경로에 오류가 있습니다 | | **unzip\_fail** | 압축 해제에 실패했습니다 | | **low\_mem\_fail** | 기기의 메모리 부족으로 다운로드에 실패했습니다 | ### 번들 상태 * `SUCCESS`: 번들 설치 완료 * `ERROR`: 설치 또는 다운로드 실패 * `PENDING`: 다운로드 완료, 배포 대기 중 * `DELETED`: 번들 삭제됨, 통계를 위해 표시됨 * `DOWNLOADING`: 현재 번들 다운로드 중 ## 기기 로그 이해하기: ### 디버그 명령어: Capgo 클라우드 사용자를 위한 디버그 명령어가 있습니다 ```bash npx @capgo/cli@latest app debug ``` 이를 통해 앱에서 발생하는 모든 이벤트를 확인하고 업데이트가 되지 않는 경우 해결책을 찾을 수 있습니다 ### IOS Xcode에서 로그를 찾는 방법 [Getting the Device Log in Xcode ](https://intercomhelp/deploygate/en/articles/4682692-getting-the-device-log-in-xcode) ### Android: Android Studio에서 로그를 찾는 방법 [View logs with Logcat ](https://developerandroidcom/studio/debug/am-logcat) ### 로그 설명 * `Failed to download from` **=>** **download\_fail**과 동일 * `notifyAppReady was not called, roll back current bundle` => **update\_fail**과 동일 ## 기기에서 다운로드된 번들 찾기 ### iOS iOS에서 디버깅하려면 앱을 컴퓨터에 덤프해야 합니다. 다음과 같이 할 수 있습니다: Xcode에는 iOS 기기에 개발자가 설치한 앱의 파일 시스템을 검사하는 기능이 내장되어 있습니다 이를 위해: 1. 기기를 Mac에 연결하고 Xcode 메뉴바에서 Window > Devices를 선택합니다 2. Devices 섹션에서 왼쪽 창에 있는 기기를 선택합니다 3. 해당 기기에 대한 개발자 설치 앱 목록이 표시됩니다 4. 검사하려는 앱을 선택한 다음 화면 하단의 기어 아이콘을 선택합니다 5. 여기서 Show Container를 선택하여 현재 파일 시스템을 보거나 스냅샷을 다운로드할 수 있습니다 Download Container를 선택하면 xcappdata 파일로 파일 시스템의 스냅샷을 다운로드하고 내보냅니다 이 파일을 우클릭하고 Show Package Contents를 선택하여 폴더를 엽니다 App Data 폴더를 열면 Documents, Library, tmp 등의 폴더가 보입니다 ![image](/ios_debug_update_1.webp) 그런 다음 2개의 폴더에서 버전을 찾을 수 있습니다: `library/NoCloud/ionic_built_snapshots`는 앱 재부팅 후 필요합니다 그리고 `documents/versions`는 핫 리로드용입니다 ### Android Android에서 디버깅하려면 Android Studio에서 기기에 접근해야 합니다: 1. View > Tool Windows > Device File Explorer를 클릭하거나 도구 창 바에서 Device File Explorer 버튼을 클릭하여 Device File Explorer를 엽니다 2. 드롭다운 목록에서 기기를 선택합니다 3. **data/data/APP\_NAME/** 경로를 엽니다. 여기서 **APP\_NAME은 앱 ID**입니다 ![image](/android_debug_update.webp) 그런 다음 `versions` 폴더에서 모든 버전을 확인할 수 있습니다 알고 계셨나요? Android에서는 모든 버전이 하나의 폴더에 저장되며, IOS와 달리 두 위치에 복제할 필요가 없습니다 ## iOS 프로덕션 크래시 로그 이해하기 [How to review your app's crash logs ](https://developer.apple.com/news/?id=nra79npr) # Nuxt 2 > Nuxt 2에서 플러그인 설치 방법 # Nuxt 2에서 설치하기 `plugins` 디렉토리에 `capacitor-updaterjs` 플러그인 파일 생성 ```js import { CapacitorUpdater } from '@capgo/capacitor-updater' export default ({ app }) => { if (processclient) { windowonNuxtReady(() => { CapacitorUpdaternotifyAppReady() }) } } ``` 이는 클라이언트 측에서 플러그인을 로드하고 앱이 업데이트를 받을 준비가 되었음을 알립니다 # Problemi noti > Capacitor와 CapGo의 알려진 문제점 ## Ionic 실시간 리로드 * 개발할 때 CLI에서 Ionic 실시간 리로드 기능을 사용하면 플러그인을 덮어쓰므로 업데이트가 반영되지 않습니다 ## Quasar 실시간 리로드 * 내부적으로 Ionic과 동일한 시스템을 사용하므로 업데이트가 반영되지 않습니다 ## 업데이트 실패 * 일반적으로 큰 업데이트(> 20mb)를 푸시할 때 발생하며, 많은 사용자가 최신 버전을 받지 못합니다\ 이전에는 사용자가 다운로드가 완료될 때까지 앱을 열어두어야 했지만, 이제는 백그라운드 다운로드를 사용합니다. 하지만 여전히 몇 초로 제한됩니다 ## Android ### 다운로드 불가 인도의 기기에서 문제가 발생했고, 사용자와 통화하여 다른 DNS 서버를 시도하게 했더니 작동했습니다 따라서 문제가 있다면 Cloudflare나 Google DNS와 같은 다른 DNS 서버를 사용해보세요 Cloudflare: 1111 및 1001 Google DNS: 8888 및 8844 또는 dnsgoogle [How to setup a preferred DNS server on Android? ](https://wwwandroidpolicecom/use-preferred-dns-server-android-tutorial/) ### 자체 호스팅 자체 호스팅 업데이트를 푸시할 때, Android 앱의 보안 정책 때문에 “HTTP” 엔드포인트를 사용할 수 없다는 점을 유의하세요. 그래도 사용하고 싶다면 이 가이드를 따르세요: [How to allow all Network connection types HTTP and HTTPS in Android (9) Pie? ](https://stackoverflow.com/a/51902630/5511370) ### 압축 해제 압축 해제 문제: DEFLATED entries can have EXT descriptor CLI가 아닌 다른 방법으로 번들을 압축했다면 zip 형식이 잘못되었을 수 있습니다. CLI 명령어 `npx @capgo/cli zip BUNDLE_FOLDER`를 사용하세요 이는 Java의 알려진 문제입니다: [Unzip issue: DEFLATED entries can have EXT descriptor ](https://bugsopenjdkorg/browse/JDK-8143613) ### Clearfix 문제 * usesCleartextTraffic 문제가 있다면, 플러그인이 sonar cloud에서 권장하는 모범 사례를 따르기 때문입니다. 90%의 경우에는 잘 작동하지만 일부 플러그인에서 문제가 발생할 수 있습니다 해결하려면 `android/app/src/main/AndroidManifestxml`의 `` 키에 다음을 추가하세요: ```xml tools:replace="android:usesCleartextTraffic" xmlns:tools="http://schemasandroidcom/tools" ``` ## IOS ### 개인정보 보호 매니페스트 [Privacy Manifest](https://capacitorjs.com/docs/ios/privacy-manifest)(일반적으로 `ios/App/PrivacyInfoxcprivacy`)에 `NSPrivacyAccessedAPICategoryUserDefaults` 사전 키를 추가하세요: ```xml NSPrivacyAccessedAPITypes NSPrivacyAccessedAPIType NSPrivacyAccessedAPICategoryUserDefaults NSPrivacyAccessedAPITypeReasons CA921 ``` [`UserDefaults`](https://developer.apple.com/documentation/foundation/userdefaults) API 접근 이유로 [`CA921`](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278401)을 선언하는 것을 권장합니다 ### 네트워크 권한 업데이트 테스트를 위해 로컬 서버를 사용할 때 앱이 네트워크 권한을 요청하는 것은 정상적인 동작입니다. 원격 서버를 사용할 때는 이런 일이 발생하지 않습니다 ## 양쪽 OS 수동 모드 업데이트를 할 때 일부 이벤트를 캐치하기가 어렵습니다. 예를 들어 업데이트 실패는 JS 코드가 리로드되기 직전에 트리거되므로 캐치할 수 없습니다 대안으로 번들을 나열하고 오류 통계를 확인하여 업데이트 실패 여부를 알 수 있습니다 향후 더 나은 방법을 찾아야 하지만, 자동 모드가 권장되는 업데이트 방법이므로 우선순위는 아닙니다 PR을 통해 개선에 도움을 주시면 환영합니다 ## CLI CLI에 문제가 있다면, **capacitorconfigts**에 **appId**와 **appName**이 있는지 확인하세요 공식 문서의 가이드를 따르세요: [Capacitor Configuration ](https://capacitorjs.com/docs/config) # Vue d'ensemble > 두 가지 다른 접근 방식에 대한 설명 ### 클라우드 모드 (권장) 클라우드 모드는 번거로움 없는 업데이트 관리를 위한 권장 선택입니다. Capgo의 백엔드가 모든 업데이트 로직을 처리하며, 더 나은 보안과 제어를 위해 서버 측에서 업데이트에 대한 결정을 내립니다. 이 모드는 사용의 편의성에 중점을 두고 있습니다. 한번 설정하면 통계와 채널과 같은 고급 기능을 제공하면서 자체적으로 원활하게 작동합니다. 수동 모드로도 설정할 수 있어 JavaScript 코드를 사용하여 업데이트 시기를 결정할 수 있는 더 많은 제어 권한을 제공합니다. 백엔드는 여전히 무엇이 업데이트되는지 관리합니다. 이 모드는 자동 모드와 많은 이점을 공유하며, 특히 보안과 고급 기능에서 그렇지만 업데이트 타이밍을 직접 조절할 수 있는 유연성이 추가됩니다. ### 자체 호스팅 모드 자체 호스팅 자동 모드는 모든 업데이트 로직을 자체 서버에서 처리하고자 하는 사용자를 위한 것입니다. 완전한 자율성을 제공하지만 별도의 서버와 업데이트 및 서버 요구사항을 관리하는데 더 많은 작업이 필요합니다. 자체 호스팅 수동 모드는 제어와 자율성이 혼합되어 있습니다. JavaScript를 통해 업데이트 시기를 결정하지만 서버가 무엇이 업데이트되는지 처리합니다. 업데이트 코드를 업데이트에 포함시켜야 하므로 다소 복잡합니다. Note 자체 호스팅을 선택하면 자동 복구, 이메일 알림, 채널, 통계, 암호화 등과 같은 capgo 클라우드가 제공하는 모든 훌륭한 기능을 놓치게 됩니다. Danger 잘못된 업데이트를 사용자에게 전송하면 앱이 손상될 수 있습니다. # 自動アップデート > 자동 업데이트 플러그인을 자체 호스팅 모드에서 사용하는 방법 이 문서에서는 자동 업데이트 서버를 실행하는 방법을 설명합니다. ## 번들 제공 번들이 HTTPS를 통해 제공되고 서버에 앱이 업데이트를 다운로드할 수 있도록 적절한 CORS 헤더가 설정되어 있는지 확인하세요. 예시: `https://myservercom/app/updates/updatesjson` 번들 제공에 익숙하지 않다면 Capgo Cloud를 사용해보거나 다음 예제를 참조하시기 바랍니다: [번들 제공하기 ](/docs/self-hosted/auto-update/update-endpoint) ## 구성 `capacitorconfigjson`에 `updateUrl`을 추가하세요 ```json { "plugins": { "CapacitorUpdater": { "updateUrl": "https://myservercom/app/updates/updatesjson", } } } ``` Caution 자체 호스팅 업데이트를 푸시할 때, Android 앱의 보안 정책으로 인해 “HTTP” 엔드포인트를 사용할 수 없다는 점에 유의하세요. 테스트 목적으로는 [허용](https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted)할 수 있습니다. ## 업데이트 API 플러그인은 앱이 열릴 때마다 다음 본문과 함께 API에 POST 요청을 보냅니다: ```typescript interface AppInfos { "platform": "ios" | "android", "device_id": "UUID_of_device_unique_by_install", "app_id": "APPID_FROM_CAPACITOR_CONFIG", "custom_id": "your_custom_id_set_on_runtime", "plugin_version": "PLUGIN_VERSION", "version_build": "VERSION_NUMBER_FROM_NATIVE_CODE", "version_code": "VERSION_CODE_FROM_NATIVE_CODE", "version_name": "LAST_DOWNLOADER_VERSION" | "builtin" "version_os": "VERSION_OF_SYSYEM_OS", "is_emulator": boolean, "is_prod": boolean, } ``` 서버 API는 업데이트가 필요한 경우 capacitor-updater 플러그인에 다음과 같은 JSON 데이터로 응답해야 합니다: ```json { "version": "123", "url": "https://myservercom/app/updates/my-new-app-200zip" } ``` 자동 업데이트 모드에서 서버는 버전을 비교하고 올바른 버전을 반환해야 합니다. URL 키가 있으면 플러그인이 다운로드 프로세스를 시작합니다. “message”와 “error” 키를 추가하면 버전이 설정되지 않고 대신 로그에 메시지가 표시됩니다. `version` 키는 [`semver`](https://semverorg/) 형식이어야 합니다. zip 파일은 루트에 `indexhtml` 파일이 있거나 루트에 `indexhtml`이 포함된 폴더가 하나만 있어야 합니다. CLI 명령을 사용하여 번들을 압축할 수 있습니다: 서버에서 제공할 파일로 번들 생성하기 ```bash npx @capgo/cli bundle zip --path [/path/to/my/bundle] ``` # Contribuer > Capgo 오픈소스 프로젝트에 기여하기 ## 기여하는 이유는 무엇인가요? 먼저, capgo 오픈 소스 프로젝트에 기여하는 것을 고려해 주셔서 감사합니다! 여러분과 같은 분들 덕분에 capgo 오픈 소스 프로젝트가 훌륭한 도구가 될 수 있습니다. 기여를 고려해야 하는 몇 가지 이유는 다음과 같습니다: * capgo 오픈 소스 프로젝트에 기여하는 것은 capgo 팀이 제공하는 [수많은 바운티](https://consolealgoraio/org/Capgo)로부터 돈을 벌 수 있는 좋은 방법입니다 * capgo 오픈 소스 프로젝트에 기여하는 것은 보고 싶은 기능을 추가할 수 있는 좋은 방법입니다 * capgo 오픈 소스 프로젝트에 기여하는 것은 발견한 버그를 수정할 수 있는 좋은 방법입니다 * [Capgo 메인 라이선스](https://github.com/Cap-go/capgo/blob/main/LICENSE)는 여러분이 수정한 내용을 오픈 소스로 공개하도록 요구합니다. 코드를 기여함으로써 여러분의 변경사항을 오픈 소스로 유지하고 다른 사람들이 사용할 수 있게 할 수 있습니다 ## 기여하는 방법 * 먼저, 기여하고자 하는 저장소를 포크해야 합니다 * 둘째, 해당 저장소에 변경사항을 커밋하고 푸시해야 합니다 * 마지막으로, 풀 리퀘스트를 열어야 합니다 * 이게 전부입니다! 이제 capgo 팀이 PR을 검토하기를 기다리면 됩니다 ## 추가로 읽어볼 문서들 * Capgo의 [CONTRIBUTINGMD](https://github.com/Cap-go/capgo/blob/main/CONTRIBUTINGmd) * Capgo의 [BOUNTYmd](https://github.com/Cap-go/capgo/blob/main/BOUNTYmd) # Paket Terenkripsi > Self-Hosted 모드에서 수동 업데이트 플러그인 사용하기 ## 엔드투엔드 암호화 버전 4150부터 플러그인에서 암호화된 업데이트를 전송할 수 있습니다 시작하려면 먼저 개인 키를 생성하세요 개인 키 생성 ```bash npx @capgo/cli key create ``` 그런 다음 zip 파일을 암호화하세요 번들된 zip 암호화 ```bash npx @capgo/cli encrypt [path/to/zip] ``` 명령어는 `ivSessionKey`를 출력합니다. 이는 업데이트 페이로드에서 `session_key` 키와 함께 전송되어야 합니다 ```json { "version": "123", "url": "https://myservercom/app/updates/my-new-app-200zip", "session_key": "encrypted_session_key", } ``` 그러면 앱에서 개인 키를 사용하여 `session_key`를 복호화하고 복호화된 `session_key`를 사용하여 업데이트를 복호화할 수 있습니다 자세한 내용은 여기에서 확인하세요: [셀프 호스팅 라이브 업데이트 ](https://capgo.app/blog/self-hosted-live-updates/) # 시작하기 > 자체 업데이트 서버 실행 방법 자체 자동 업데이트 서버를 실행하는 방법을 설명하는 문서입니다. ## 소개 이 작업이 도움이 된다고 생각하시면, [Github 스폰서](https://github.com/sponsors/riderx)가 되어 제 작업을 지원해주시면 감사하겠습니다. 저는 여기서 구축한 모든 코드를 유료화하는 대신 오픈소스로 공개하기로 결정했습니다. 숨기고 싸우는 대신 공개함으로써 우리가 더 나은 세상을 만들 수 있다고 믿습니다. 더불어, Capgo 도구에 집중하고 개방적이고 투명한 비즈니스를 만들고 싶습니다. 하지만 이를 가능하게 하려면 여러분을 포함한 우리 모두가 각자의 역할을 해야 합니다 🥹 Capgo가 적합하지 않다면, 원하시는 가격으로 [부트스트랩 메이커를 지원](https://github.com/sponsors/riderx)해주세요. [기여 고려하기 ](/docs/plugin/self-hosted/contributing/) ## 기능 비교 자체 서버를 선택하면 5분 설정 흐름을 잃게 됩니다\ 모든 기능을 직접 구현해야 합니다 | 기능 | Capgo | 자체 호스팅 | | ----------- | ----- | ------ | | 업데이트 | ✅ | 🚧 | | 자동 복구 | ✅ | 🚧 | | 실패 시 이메일 알림 | ✅ | 🚧 | | 채널 | ✅ | 🚧 | | 채널 재정의 | ✅ | 🚧 | | 기기 재정의 | ✅ | 🚧 | | 채널 설정 | ✅ | 🚧 | | 기기 설정 | ✅ | 🚧 | | 커스텀 ID | ✅ | 🚧 | | 자동 채널 설정 | ✅ | 🚧 | | API 채널 | ✅ | 🚧 | | 업데이트 통계 | ✅ | 🚧 | | 다운로드 실패 통계 | ✅ | 🚧 | | 앱 사용 통계 | ✅ | 🚧 | | 업데이트 암호화 | ✅ | 🚧 | Danger 잘못된 업데이트를 사용자에게 보내면 앱이 손상될 수 있습니다 > Capgo 클라우드와 자체 서버를 동시에 사용할 수 없습니다 Danger Over-the-Air (OTA) 업데이트 기능은 HTML, CSS, JavaScript 파일의 수정에만 적용됩니다 Capacitor 플러그인과 같은 네이티브 코드를 변경하는 경우, 앱스토어에 다시 제출하여 승인을 받아야 합니다 ## 자동과 수동 중 선택 자동 모드에서는 로직의 일부가 네이티브 코드에서 처리되고 업데이트는 서버 측에서 결정됩니다. 이는 더 안전하며 세밀한 업데이트, 한 기기나 그룹에 대한 부분 배포 등이 가능합니다 수동 모드에서는 모든 로직이 JS에서 처리됩니다 [자동 업데이트 ](/docs/plugin/self-hosted/auto-update/) [수동 ](/docs/plugin/self-hosted/manual-update/) ## Capacitor updater 설치 Capacitor updater 설치하기 ```bash npm install @capgo/capacitor-updater npx cap sync ``` ## 번들 준비하기 앱에 업데이트를 보내려면 zip으로 압축해야 합니다 zip이 올바른지 확인하는 가장 좋은 방법은 Capgo CLI를 사용하는 것입니다 서버에서 제공할 파일로 번들 만들기 ```bash npx @capgo/cli@latest bundle zip ``` 이 zip 파일을 서버에서 직접 제공해야 합니다 [자동 업데이트 ](/docs/plugin/self-hosted/auto-update/) [수동 ](/docs/plugin/self-hosted/manual-update/) Note 이 작업이 많아 보인다면, Capgo Cloud 체험판을 사용해보세요 # Umgang mit Statistiken > self-hosted 통계 엔드포인트를 만드는 방법 플러그인의 통계를 저장하기 위한 JavaScript 코드 예시입니다 ```typescript interface AppInfos { version_name: string action: 'delete' | 'reset' | 'set' | 'set_fail' | 'update_fail' | 'windows_path_fail' | 'canonical_path_fail' | 'directory_path_fail' | 'unzip_fail' | 'low_mem_fail' | 'download_fail' | 'update_fail' | 'download_10' | 'download_20' | 'download_30' | 'download_40' | 'download_50' | 'download_60' | 'download_70' | 'download_80' | 'download_90' | 'download_complete' version_build: string version_code: string version_os: string plugin_version: string platform: string app_id: string device_id: string custom_id?: string is_prod?: boolean is_emulator?: boolean } export const handler: Handler = async (event) => { const body = JSONparse(eventbody || '{}') as AppInfos const { platform, app_id, action, version_code, version_os, device_id, version_name, version_build, plugin_version, } = body consolelog('update asked', platform, app_id, action, version_os, version_code, device_id, version_name, version_build, plugin_version) // 데이터베이스에 저장 return { status: 'ok' } } ``` 이 엔드포인트는 다음과 같은 JSON을 반환해야 합니다: ```json { "status": "ok" } ``` ## 액션: * **delete** : 번들이 로컬에서 삭제될 때 * **reset** : 앱이 내장 번들로 재설정될 때 * **set** : 앱이 새로운 번들을 설정할 때 * **set\_fail** : 앱이 설정된 번들의 ID를 찾을 수 없을 때 * **update\_fail** : 지연 후 `notifyAppReady`가 호출되지 않았을 때 전송 * **download\_fail** : 다운로드가 완료되지 않았을 때 * **download\_complete:** 다운로드가 완료되었을 때 * **download\_xx:** 다운로드 진행률 10% 마다 전송 예: download\_20, download\_70 * **update\_fail:** 번들이 주어진 시간 내에 `notifyAppReady`를 실행하지 못했을 때 # 업데이트 처리 > 자체 호스팅 모드에서 자동 업데이트 플러그인 사용하기 다음은 플러그인에 업데이트를 보내는 JavaScript 코드 예시입니다 ```typescript interface AppInfos { version_name: string version_build: string version_os: string custom_id?: string is_prod?: boolean is_emulator?: boolean plugin_version: string platform: string app_id: string device_id: string } export const handler: Handler = async (event) => { const body = JSONparse(eventbody || '{}') as AppInfos const { platform, app_id, version_os, device_id, version_name, version_build, plugin_version, } = body consolelog('update asked', platform, app_id, version_os, device_id, version_name, version_build, plugin_version) if (version_name === '100') { return { version: '101', url: 'https://apiurlcom/mybuild_101zip', } } else if (version_name === '101') { return { version: '102', url: 'https://apiurlcom/mybuild_102zip', } } else { return { message: 'Error version not found' version: '', url: '', } } } ``` 이 엔드포인트는 다음과 같은 JSON을 반환해야 합니다: ```json { "version": "102", "url": "https://apiurlcom/mybuild_102zip" } ``` 그리고 업데이트가 없거나 오류가 있는 경우 `message` 키와 선택적으로 `error`를 추가합니다 ```json { "message": "Version not found", "error": "The backend crashed", "version": "102", "url": "https://apiurlcom/mybuild_102zip" } ``` # 수동 업데이트 > 수동 업데이트 플러그인을 셀프 호스팅 모드에서 사용하는 방법 ## 구성 자동 업데이트를 비활성화하려면 `capacitor.config.json`에 다음을 추가하세요 ```tsx // capacitor.config.json { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "autoUpdate": false, } } } ``` ## 사용법 이 예제를 사용하거나 앱에서 로직을 다시 만들 수 있습니다 Caution 코드에 선언된 정적 버전으로 사용자에게 앱 업데이트를 강제하고 있습니다. 이는 권장되지 않으며, 서버에서 동적 버전을 사용해야 합니다 Danger 이 예제에서는 버전 확인, 복호화 또는 체크섬 검증을 수행하지 않습니다. 이는 직접 구현해야 합니다 ```tsx import { CapacitorUpdater } from '@capgo/capacitor-updater' import { SplashScreen } from '@capacitor/splash-screen' import { App } from '@capacitor/app' let data = {version: ""} CapacitorUpdater.notifyAppReady() App.addListener('appStateChange', async(state) => { if (state.isActive) { // 다운로드 실패를 방지하기 위해 앱이 활성 상태일 때 다운로드를 수행합니다 data = await CapacitorUpdater.download({ version: '004', url: 'https://github.com/Cap-go/demo-app/releases/download/004/dist.zip', }) } if (!state.isActive && data.version !== "") { // 사용자가 앱을 떠날 때 전환을 수행합니다 SplashScreen.show() try { await CapacitorUpdater.set(data) } catch (err) { console.log(err) SplashScreen.hide() // set이 실패한 경우를 위해, 그렇지 않으면 새 앱에서 숨겨야 합니다 } } }) ``` Note 이 작업이 많아 보인다면 [Capgo 체험판](https://capgo.app/register/)을 시도해 보세요. 이 모든 것을 대신 처리해 줄 것입니다 # 설정 > Capacitor Updater에 사용 가능한 모든 구성 업데이트 시스템을 더 세밀하게 제어하려면 다음 설정으로 구성할 수 있습니다: ## `appReadyTimeout` > 네이티브 플러그인이 업데이트를 ‘실패’로 간주하기 전에 대기할 밀리초 수를 구성합니다 Android와 iOS에서만 사용 가능 기본값: `10000` (10초) ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "appReadyTimeout": 1000 } } } ``` ## `responseTimeout` > 네이티브 플러그인이 API 타임아웃으로 간주하기 전에 대기할 밀리초 수를 구성합니다 Android와 iOS에서만 사용 가능 기본값: `20` (20초) ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "responseTimeout": 1000 } } } ``` ## `autoDeleteFailed` > 플러그인이 실패한 번들을 자동으로 삭제할지 여부를 구성합니다 Android와 iOS에서만 사용 가능 기본값: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoDeleteFailed": false } } } ``` ## `autoDeletePrevious` > 성공적인 업데이트 후 플러그인이 이전 번들을 자동으로 삭제할지 여부를 구성합니다 Android와 iOS에서만 사용 가능 기본값: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoDeletePrevious": false } } } ``` ## `autoUpdate` > 플러그인이 업데이트 서버를 통한 자동 업데이트를 사용할지 여부를 구성합니다 Android와 iOS에서만 사용 가능 기본값: `true` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": false } } } ``` ## `updateUrl` > 업데이트 확인이 전송되는 URL/엔드포인트를 구성합니다 Android와 iOS에서만 사용 가능 기본값: `https://apicapgo.app/updates` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "updateUrl": "https://examplecom/api/updates" } } } ``` ## `statsUrl` > 업데이트 통계가 전송되는 URL/엔드포인트를 구성합니다 Android와 iOS에서만 사용 가능. 통계 보고를 비활성화하려면 ""로 설정 기본값: `https://apicapgo.app/stats` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "statsUrl": "https://examplecom/api/stats" } } } ``` ## `privateKey` > 엔드-투-엔드 라이브 업데이트 암호화를 위한 개인 키를 구성합니다 Android와 iOS에서만 사용 가능 `npx @capgo/cli key create` 명령으로 개인 키 생성 기본값: `undefined` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "privateKey": "YOUR_KEY" } } } ``` ## `directUpdate` > 앱이 방금 업데이트/설치되었을 때 플러그인이 직접 업데이트를 설치하도록 합니다. 자동 업데이트 모드에서만 적용됩니다 Android와 iOS에서만 사용 가능 기본값: `undefined` ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": true } } } ``` ## `resetWhenUpdate` Note 스토어 업데이트가 발생할 때, 네이티브 버전으로의 강제 재설정을 비활성화합니다 [웹 앱](https://web.capgo.app/login)에서만 사용 가능한 더 많은 설정이 있습니다 플러그인을 구성하려면 다음 설정을 사용하세요: ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } } ``` ## `directUpdate` 앱이 방금 업데이트/설치되었을 때 플러그인이 직접 업데이트를 설치하도록 합니다. 자동 업데이트 모드에서만 적용됩니다 Caution 이 설정은 업데이트가 설치되는 동안 사용자로부터 앱을 숨길 것을 요구합니다. 그렇지 않으면 사용자가 탐색하는 동안 앱이 재설정됩니다 ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "autoUpdate": true, "directUpdate": true } } } ``` ## `defaultChannel` 앱의 기본 채널을 설정합니다. 채널이 덮어쓰기를 허용하는 경우 Capgo에 설정된 다른 모든 채널을 재정의합니다 ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "defaultChannel": "production" } } } ``` ## `appId` 앱의 appId를 설정합니다. 다른 모든 appId 획득 방법을 재정의합니다. Capgo와 네이티브 코드에서 다른 appId를 사용하고 싶을 때 유용합니다 Note 이것은 appId를 설정하는 새로운 방법입니다. 기존 방법도 계속 지원됩니다 ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "AppId": "comexampleapp" } } } ``` ## `version` 앱의 버전을 설정합니다. 다른 모든 버전 획득 방법을 재정의합니다. Capgo와 네이티브 코드에서 다른 버전을 사용하고 싶을 때 유용합니다 Note 이것은 버전을 설정하는 새로운 방법입니다. 기존 방법도 계속 지원됩니다 ```json // capacitorconfigjson { "plugins": { "CapacitorUpdater": { "version": "123" } } } ``` # Statistics API > 자체 호스팅 모드에서 자동 업데이트 플러그인 사용하기 ## 통계 API 버전 130부터 업데이트 시스템이 통계를 전송할 수 있게 되었습니다! 기본적으로 모든 통계는 사용량 파악과 연구를 위해 우리 서버로 전송됩니다 Note 통계를 위해 개인 데이터는 전송되지 않으며, 임의의 UUID, 업데이트 버전, 네이티브 앱 버전, 플랫폼, 액션 및 앱 ID만 전송됩니다 이 데이터를 대신 귀하의 서버로 전송하려면 아래 설정을 변경하세요: ```tsx // capacitorconfigjson { "appId": "*******", "appName": "Name", "plugins": { "CapacitorUpdater": { "statsUrl": "YOUR_URL" } } } ``` 귀하의 서버가 받게 될 내용: ```tsx interface AppInfosStats { "action": "set", // set, delete, set_fail, reset, revert 가능 // 그 다음은 업데이트와 동일한 정보 "app_id": "*******", // 스토어의 앱 식별자 "device_id": "*******", // 앱 설치당 고유 ID "platform": "ios", // 또는 android "custom_id": "user_1", // 사용자를 나타냄 "version_name": "123", // 웹 빌드 버전 "version_build": "120", // 네이티브 빌드 버전 "version_code": "120", // 네이티브 빌드의 빌드 번호 "version_os": "16", // 기기의 OS 버전 "plugin_version": "400"// 다른 플러그인과 API가 다르게 동작하도록 함 "is_emulator": false, "is_prod": false, } ``` 빈 문자열로 완전히 비활성화할 수도 있습니다. 통계는 개인정보 보호를 위해 만들어졌으며 플러그인 사용 방식을 이해하고 문제를 해결하고 개선하는 데 도움이 된다는 점을 기억하세요 [업데이트 처리 ](/docs/plugin/self-hosted/handling-updates/) # AppFlow에서 Capgo로 마이그레이션 > Ionic AppFlow에서 Capgo로 앱을 마이그레이션하는 완벽한 가이드 ## AppFlow 설정 참조 마이그레이션 전에 현재 `capacitor.config.ts`의 AppFlow 설정을 확인하세요: ```typescript import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { plugins: { LiveUpdates: { appId: 'your-app-id', channel: 'Production', autoUpdateMethod: 'background', // 또는 'always latest', 'force update' maxVersions: 2 } } }; ``` 이 설정은 AppFlow 기능을 Capgo의 동등한 기능으로 매핑하는 데 도움이 됩니다. ## Capgo로 마이그레이션하는 이유 Ionic AppFlow 서비스 종료 발표와 함께, Capgo로의 마이그레이션은 모바일 앱 개발 워크플로우를 원활하게 전환할 수 있는 기회를 제공합니다. Capgo는 모든 중요한 기능을 유지하면서 향상된 기능, 더 나은 성능, 그리고 상당한 비용 절감을 제공합니다. ### 주요 이점 * 더 빠른 업데이트 배포 (10분에서 1분 미만으로) * 더 저렴한 가격 ($499/월에서 $14/월로) * 모든 요금제에 엔드투엔드 암호화 포함 * 업데이트 채널에 대한 향상된 제어 * 포괄적인 CI/CD 통합 옵션 ## 마이그레이션 단계 ### 1. 실시간 업데이트 마이그레이션 #### 이전 종속성 제거 ```bash npm uninstall @ionic/appflow # capacitor.config.json에서 AppFlow 관련 설정 제거 ``` #### Capgo 설치 ```bash npm install @capgo/capacitor-updater npx cap sync ``` #### 설정 업데이트 `capacitor.config.json`에 Capgo 설정 추가: ```json { "plugins": { "CapacitorUpdater": { "autoUpdate": true } } } ``` ### 2. CI/CD 마이그레이션 Capgo는 유연한 CI/CD 옵션을 제공합니다: #### 옵션 1: 기존 CI/CD 사용 인기 있는 플랫폼과 함께 CI/CD를 설정하는 상세 튜토리얼: * [iOS 빌드 설정](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) * [Android 빌드 설정](https://capgo.app/blog/automatic-capacitor-android-build-github-action/) * [GitHub Actions 통합](https://capgo.app/blog/automatic-capacitor-ios-build-github-action/) #### 옵션 2: CI/CD 서비스 [관리형 서비스](https://cal.com/team/capgo/mobile-ci-cd-done-for-you)로 CI/CD 설정을 맡기세요. ### 3. 채널 설정 1. Capgo 대시보드에서 채널 생성: ```bash npx @capgo/cli channel create production npx @capgo/cli channel create staging ``` 2. 채널 설정 구성: ```bash # 프로덕션 채널 설정 npx @capgo/cli channel update production --no-downgrade --no-upgrade # 스테이징 채널 설정 npx @capgo/cli channel update staging ``` ### 4. 마이그레이션 테스트 1. **실시간 업데이트 테스트** ```bash # 테스트 번들 생성 및 업로드 npx @capgo/cli bundle create --channel staging ``` 2. **업데이트 수신 확인** * 테스트 기기에 앱 설치 * 업데이트가 올바르게 수신되는지 확인 * 업데이트 설치 프로세스 검증 * 복구 기능 테스트 ## 문제 해결 ### 일반적인 문제 #### 업데이트가 수신되지 않음 * 채널 구성 확인 * 기기 로그 확인 * 네트워크 연결 확인 * 번들 버전 형식 검증 ## 다음 단계 1. [Capgo 계정 생성](/register/) 2. [빠른 시작 가이드](/docs/getting-started/quickstart/) 따르기 3. [CI/CD 통합](/docs/getting-started/cicd-integration/) 설정 4. [실시간 업데이트](/docs/live-updates/) 구성 마이그레이션 중 전담 지원이 필요한 기업 팀의 경우, [우리 팀과 통화 예약](https://cal.com/team/capgo/capgo-enterprise-inquiry)을 해주세요. # V2에서 V3로 > V2에서 V3로 업그레이드 하는 방법 auto-update 버전 3으로 업그레이드하는 방법을 설명하는 문서입니다. ## 먼저 최신 도구로 마이그레이션하세요: ```bash npm remove -g capgo npm remove capacitor-updater npm i @capgo/cli npm i @capgo/capacitor-updater@3 npx cap sync ``` ## 이전 구성을 모두 제거하세요: ```json { CapacitorUpdater: { autoUpdateURL: "https", }, } ``` 다음과 같이만 남기세요: ```json { "CapacitorUpdater": { "autoUpdate": true } } ``` > ⚠️ `autoUpdateURL`로 자체 서버를 사용 중이었다면, 곧 이 가이드를 업데이트하겠습니다. 그동안 새로운 업로드 옵션 `external`을 확인해보세요. 이를 통해 Capgo 클라우드에 코드를 저장하지 않고 zip 파일의 링크만 전송할 수 있습니다. 엄격한 개인정보 보호 정책을 가진 기업을 위해 만들어졌습니다. external 모드에서는 코드가 Capgo 서버에 저장되지 않고, URL만 저장하여 기기로 전송하면 직접 다운로드합니다. 표준 방식에서는 코드가 압축되어 서버에 저장되지만, 우리는 절대 열어보거나 사용하지 않습니다. ## 변경사항 auto-update의 모든 구성이 서버 측으로 이동하여 사용자에게 업데이트를 보내는 방법을 더 잘 제어할 수 있습니다. 이를 통해 채널을 사용하여 한 사용자에게만 배포하거나 되돌리기가 가능합니다! 이러한 설정들이 웹 인터페이스에 추가되었습니다: * 네이티브 아래에서 되돌리기 비활성화 * 메이저 버전 이상 업데이트 비활성화 > ⚠️ 모든 채널에서 기본적으로 true가 됩니다 이로 인해 플러그인을 자주 업데이트할 필요가 없어지며, 대부분의 업데이트는 서버 측에서 이루어지므로 사용자 측에서 변경 없이 적용됩니다 > ⚠️ 업데이트가 기본값이 되면 리셋됩니다. 스토어에서 업데이트할 때 모든 다운로드 버전을 제거하지 않으려면 다음과 같이 설정하세요: ```json { "CapacitorUpdater": { "autoUpdate": true, "resetWhenUpdate": false } } ``` ## 코드 업데이트 마지막으로, JS의 모든 임포트를 다음과 같이 업데이트하세요: ```plaintext import { CapacitorUpdater } from 'capacitor-updater' ``` 에서 ```plaintext import { CapacitorUpdater } from '@capgo/capacitor-updater' ``` 로 변경하세요. 그런 다음 코드를 다시 빌드하고 `npm run build` 자산을 다시 복사하세요 `npx cap copy` 이제 최신 auto-update 시스템을 테스트할 수 있습니다 다음 명령으로 버전을 전송하세요: ```plaintext npx @capgo/cli@latest bundle upload ``` 다음 대신: ```plaintext npx capgo upload ``` ## 향후 발전 방향 현재는 첫 번째 공개 채널만 사용 중이지만, 향후에는 여러 공개 채널이 설정된 경우 public이 다중 공개 채널로 변경될 예정입니다 ## 일반적인 문제: * 업그레이드 후 빌드 문제: 플러그인의 소스 코드를 Android Studio나 Xcode에서 이미 열어본 경우, 때로는 동기화가 제거하지 못할 수 있습니다. 네이티브 IDE를 열고 `capacitor-updater`를 수동으로 제거한 후 `npx cap sync`를 실행하면 해결될 것입니다 # V3에서 V4로 > V3에서 V4로 업그레이드하는 방법 ## 업그레이드가 필요한 이유 Discord 커뮤니티에서 여러분과 대화를 나누면서 수동 모드가 너무 수동적이고 사용하기에 안전하지 않다는 것을 발견했습니다. 예를 들어, 자동 복구가 불가능했기 때문에 수동 업데이트에 실패하면 사용자가 앱을 제거하고 다시 설치해야 했는데, 이는 매우 좋지 않은 사용자 경험이었습니다. 한편, 이를 기회로 삼아 여러분에게 더 많은 자유를 제공하고 제가 만든 모든 나쁜 코드를 제거하게 되었습니다. ## 설치 `npm i @capgo/capacitor-updater@4` ## 클라우드 자동 업데이트 앱에서 기본 예제를 사용하고 있다면, 새 버전으로 안전하게 마이그레이션할 수 있습니다. 즐기세요! ## 자체 호스팅 자동 업데이트 여러분에게는 여전히 간단합니다. 변경 사항은 다음과 같습니다: * `autoUpdateUrl` 설정의 이름이 `updateUrl`로 변경 * 엔드포인트 메서드가 `GET`에서 `POST`로 변경 ## 수동 사용자 여러분에게는 가장 큰 변화이지만, 더 나은 방향입니다! 수많은 개선 사항을 얻게 되었습니다. 주의 깊게 읽어보세요. ## 변경 사항 * `autoUpdateUrl`이 `updateUrl`로 변경되었습니다. 이제 이 설정은 수동 모드에서도 사용할 수 있습니다 * `cancelDelay`와 `delayUpdate`가 삭제되고 `setDelay`로 대체되었습니다 * set에서 더 이상 `versionName`을 사용하지 않습니다 * 대부분의 함수에서 반환되던 `version` 키가 `BundleInfo` 객체로 변경되었습니다 ```typescript interface BundleInfo { id: string; version: string; downloaded: string; status: 'success' | 'error' | 'pending' | 'downloading' } ``` * 혼란스러운 이름들이 이제 변경되었습니다 (설명하기는 어렵지만 실제 사용할 때는 새로운 이름을 쉽게 이해할 수 있습니다): * `version`이라고 불리던 것은 이제 `bundle`을 지칭합니다 * `id`는 10자리 무작위 문자열이었던 이전의 `version`을 의미합니다. 이 `id`는 번들에 접근하는 유일하고 신뢰할 수 있는 방법입니다. 예: `7Dfcd2RedN` * `version`은 이제 번들을 위해 선택한 `versionName`을 의미합니다. 예: `100` * `updateUrl`이 `get`에서 `post`로 변경되었습니다. 일부 사용자에게 사용자 정의 헤더가 문제가 되었고 post가 더 논리적이기 때문입니다. 이전의 모든 헤더는 본문으로 이동하고 `cap_` 접두사는 사라집니다 * `versionName` 메서드가 삭제되고 `getId`로 대체되었습니다 * list는 이제 `BundleInfo` 목록을 반환합니다 * `getId`가 `getDeviceId`로 변경되었습니다 * `autoUpdate`가 기본적으로 true가 됩니다. 수동 모드를 사용한다면 false로 설정하세요 ## 새로운 기능 * `getLatest` 메서드: 이 메서드를 통해 `updateUrl`로 설정된 서버에서 사용 가능한 최신 버전을 가져올 수 있습니다 * `setDelay` 메서드: `{kind: "background" | "kill" | "nativeVersion" | "date", value?: string}`를 인자로 받아 다양한 모드에 대한 지연을 설정합니다 * `next` 메서드: 즉시 실행되는 `set`과 달리 다음 백그라운드 전환 시 버전을 설정합니다 * `isAutoUpdateEnabled` 메서드: 자동 업데이트 컨텍스트인지 확인할 수 있습니다 * `downloadComplete` 이벤트: 다운로드가 100%에 도달했을 때 발생합니다 * download 메서드에 필수 필드 `version` 추가 * `notifyAppReady`가 수동 모드에서도 필수가 되었습니다. 10초 안에 호출하지 않으면 앱이 이전 버전으로 되돌아갑니다 ## 기여자 [@lincolnthree](https://github.com/lincolnthree/) 이 작업을 시작해주셔서 정말 감사합니다. 여러분의 도움 없이는 이 업데이트를 완성하는 것이 불가능했을 것입니다. # Dari V4 ke V5 > V4에서 V5로 업데이트하는 방법 ## 업그레이드가 필요한 이유 이 메이저 버전은 Capacitor 메이저 버전을 따르기 위한 것입니다 먼저 Capacitor의 마이그레이션 가이드를 따르세요: [https://capacitorjs.com/docs/updating/5-0](https://capacitorjs.com/docs/updating/5-0/) ## 설치 `npm i @capgo/capacitor-updater@5` `그런 다음 네이티브 코드 업데이트를 동기화하세요:` `npx cap sync` 이게 전부입니다! 매우 쉽죠! ## 수동 모드 getLatest로 직접 업데이트를 받고 있었다면, 약간의 변경사항이 있습니다 이제 이미 최신 상태인 경우 catch로 이동합니다 업데이트 가능 상태가 아닌 다른 모든 응답도 동일하게 작동합니다 # V5에서 V6으로 > V5에서 V6로 업데이트하는 방법 ## 이 업그레이드가 필요한 이유 이 메이저 버전은 Capacitor 메이저 버전을 따르기 위한 것입니다 먼저 Capacitor의 마이그레이션 가이드를 따르세요: [https://capacitorjs.com/docs/updating/6-0](https://capacitorjs.com/docs/updating/6-0/) ## 설치 `npm i @capgo/capacitor-updater@6` `그런 다음 네이티브 코드 업데이트를 동기화하세요:` `npx cap sync` 이게 전부입니다! 매우 쉽죠! # Introduction > Cagpo 웹 애플리케이션 소개 ## 이게 무엇인가요? Capgo는 프로젝트를 관리하는데 도움이 되는 광범위한 웹앱을 제공합니다. 이 웹앱은 Vuejs로 만들어졌으며 오픈소스입니다. 소스 코드는 [GitHub](https://github.com/Cap-go/capgo/tree/main/src/)에서 확인하실 수 있습니다.\ 웹앱은 [여기](https://web.capgo.app/)에서 사용 가능합니다.\ 이 웹앱에서는 [채널 관리](/docs/webapp/channels/), [버전 관리](/docs/webapp/bundles/), [디바이스 관리](/docs/webapp/devices/), [로그 검사](/docs/webapp/logs/), [결제 관리](/docs/webapp/settings/) 그리고 [계정 관리](/docs/webapp/settings/)가 가능합니다. ## 어떻게 사용하나요? 먼저 계정을 만들거나 로그인해야 합니다. 화면 중앙의 `Log in` 버튼을 클릭하면 비교적 간단하게 할 수 있습니다. 로그인하면 대시보드로 리디렉션됩니다. 이곳이 웹앱의 메인 페이지입니다. 여기서 다른 모든 페이지로 이동할 수 있습니다. ![login page](/login.webp) ## 계정 만들기 로그인 양식 하단에 있는 `Create a free account`를 클릭해야 합니다. 그 후에는 양식을 작성하고 안내를 따르기만 하면 됩니다. ![create account](/create-account.webp) # API 키 관리 > API 키 관리 방법 ## API 키로 무엇을 할 수 있나요? API 키는 재생성하거나 삭제하거나 새로 추가할 수 있습니다 ## 모든 API 키를 어떻게 볼 수 있나요? [API 키 페이지](https://web.capgo.app/dashboard/apikeys/)로 이동하면 모든 API 키를 볼 수 있습니다 ## 새로운 API 키를 어떻게 추가하나요? 새로운 API 키를 추가하려면 작은 플러스 버튼을 클릭하세요 ![add apikey](/apikeys-add.webp) 그리고 새로운 API 키에 부여할 권한을 선택하세요. 다음과 같은 권한을 선택할 수 있습니다: * 읽기 - API 키로 모든 데이터를 읽을 수 있습니다 * 업로드 - API 키로 CLI에서 새 버전을 업로드하고 읽을 수 있습니다 * 모두 - API 키로 모든 작업을 수행할 수 있습니다 ![select perm](/apikeys-select-perm.webp) ## API 키를 어떻게 삭제하나요? API 키를 삭제하려면 작은 휴지통 버튼을 클릭하세요 ![remove apikey](/apikeys-remove.webp) 그리고 API 키 삭제를 확인하세요 ## API 키를 어떻게 재생성하나요? API 키를 재생성하려면 작은 새로고침 버튼을 클릭하세요 ![generate apikey](/apikeys-regenerate.webp) 그리고 API 키 재생성을 확인하세요 # 번들 > 번들 관리 방법 알아보기 ## 모든 번들 보기 먼저 번들 페이지를 살펴보겠습니다. [앱을 클릭](/docs/webapp/main-page)한 다음 [번들 탭을 클릭](/docs/webapp/main-app-page)하여 접근할 수 있습니다. ![bundle list](/bundles.webp) ## 번들 삭제하기 번들을 삭제하는 방법에는 두 가지가 있습니다: * 일반 삭제 * 안전하지 않은 삭제 안전하지 않은 번들 삭제 방식은 2024년 8월 12일 Capgo에 추가되었습니다. 두 방식의 차이점은 삭제 후 버전 번호를 재사용할 수 있는지 여부입니다. 예를 들어, 버전 `100`을 일반적인 방식으로 삭제하고 나중에 `100` 버전을 업로드하려고 하면 실패합니다. 안전하지 않은 삭제를 통해 이 버전을 삭제하면 `100` 버전을 업로드할 수 있게 됩니다. Danger 버전을 안전하지 않게 삭제하고 다시 업로드하는 것은 매우 위험합니다. 플러그인에서 각종 버그와 예측할 수 없는 동작을 일으킬 수 있습니다. 공개 채널에서 사용된 번들에는 절대 사용해서는 안 됩니다. 이러한 이유로 버전을 안전하지 않게 삭제하려면 “super\_admin” 권한이 필요합니다. ## 특정 번들 관리하기 모든 번들 목록에서 관리하고자 하는 번들을 클릭하세요. 클릭하면 다음과 같은 화면이 나타납니다: ![bundle info](/bundle-info.webp) 이 페이지의 모든 요소를 살펴보겠습니다. *** 먼저 `Channel`을 볼 수 있습니다. 이 번들이 어떤 채널용인지 알려줍니다. 클릭하여 채널을 변경할 수 있습니다. 클릭하면 다음과 같은 화면이 나타납니다: ![bundle change](/bundle-change.webp) `Set bundle to channel`은 이 번들을 모든 채널의 기본값으로 연결할 수 있게 합니다\ `Open channel`은 이 번들이 속한 채널 페이지를 엽니다\ `Unlink bundle from channel`은 이 번들을 해당 채널에서 연결 해제합니다 (**경고**: 번들이 2개 이상의 채널에 연결되어 있는 경우 어떤 채널의 연결을 해제할지 선택할 수 없습니다) *** 다음으로 `Size`를 볼 수 있습니다. 클릭하면 이 번들을 다운로드할 수 있습니다. 다음과 같이 보일 것입니다: ![download bundle](/download-bundle.webp) *** 마지막으로 `Devices` 섹션이 있습니다. 이 버전을 사용하는 모든 기기를 여기서 볼 수 있습니다. # 채널 > 채널은 앱의 업데이트를 관리하는 방법입니다. 여러 채널을 가질 수 있으며 각 채널은 여러 버전을 가질 수 있습니다. 이를 통해 동시에 여러 버전의 앱을 프로덕션 환경에서 운영할 수 있습니다. ## 채널 관리하기 먼저 채널 페이지를 살펴보겠습니다. [앱을 클릭](/docs/webapp/main-page)한 다음 [채널 탭을 클릭](/docs/webapp/main-app-page)하여 접근할 수 있습니다. ![channel list](/channels.webp) ## 채널 생성하기 보시다시피 우측 하단에 플러스 버튼이 있습니다(이미지의 `1`). 이를 클릭하면 새 채널을 생성할 수 있는 모달이 열립니다. ![new channel](/new_channel_modal.webp) `추가`를 클릭하면 목록에 새 채널이 나타납니다. ![after channel create](/post-channel-create.webp) ## 잘못 구성됨은 무엇을 의미하나요? 때때로 채널의 구성이 유효하지 않을 수 있습니다. 이 경우 큰 경고가 표시되고 하나 이상의 채널에서 `잘못 구성됨` 열에 `예`라고 표시됩니다. 자세한 내용은 [여기](/docs/cli/commands/#disable-updates-strategy)에서 확인할 수 있습니다. ## 채널 삭제하기 채널 삭제는 간단합니다. 휴지통 아이콘을 클릭하고 삭제를 확인하면 됩니다(이미지의 `2`). ## 채널 관리하기 채널 이름을 클릭하면 채널을 관리할 수 있는 모달이 열립니다(이미지의 `3`). 이 페이지는 다음과 같이 보일 것입니다: ![manage channel](/manage_channel_main.webp) 각 섹션을 살펴보겠습니다. 먼저 `번들 번호`(이미지의 `1`)입니다. 이는 해당 채널의 현재 버전입니다. 업데이트를 제공할 때 이 채널은 항상 해당 버전으로 응답하려 할 것입니다\* \[^1]. 이를 클릭하면 [번들](/docs/webapp/bundles/) 페이지로 이동합니다. 두 번째로 `공유 대상`(이미지의 `2`) 페이지입니다. 이것의 사용을 권장하지 않습니다. 새롭고 더 나은 시스템이 개발 중입니다. 그 다음은 강제 디바이스(이미지의 `3`)입니다. 이는 항상 이 채널에서 업데이트를 받을 디바이스 목록입니다. 테스트 목적으로 유용합니다. [디바이스](/docs/webapp/devices/) 페이지에서 디바이스를 채널에 강제 할당할 수 있습니다. 마지막으로 설정(이미지의 `4`)입니다. 여기서 채널의 동작을 관리할 수 있습니다. 클릭하면 다음과 같은 화면이 보일 것입니다: ![setting of channel](/channel_settings.webp) 설정 목록이 길지만, 모두 설명하도록 하겠습니다. *** 첫째로 `기본 채널` **이것이 아마도 가장 중요할 것입니다**\ 채널이 기본으로 표시되면 모든 새 디바이스의 기본 채널로 사용됩니다\ 다시 말해서: 새 사용자가 있다면 capgo는 이 기본 채널의 최신 버전을 제공하려 할 것입니다. 한 번에 하나의 채널만 기본으로 설정할 수 있습니다. 이 규칙을 어기려 하면 작업을 확인하라는 메시지가 표시됩니다. ![confirm make change](/confirm-make-default.webp) 확인하면 이전 기본 채널의 기본 설정이 해제되고 새 채널이 기본으로 설정됩니다. *** 둘째로 `IOS` 설정입니다. 이는 비교적 간단합니다. false로 설정되면 iOS 디바이스는 이 채널에서 업데이트를 다운로드할 수 없습니다. 셋째는 `Android` 설정입니다. 이는 `IOS`와 유사합니다. false로 설정되면 Android 디바이스는 이 채널에서 업데이트를 다운로드할 수 없습니다. 넷째는 `네이티브 버전 이하로 자동 다운그레이드 비활성화` 설정입니다. true로 설정되면 네이티브 버전에서 다운그레이드가 불가능합니다. 즉, 앱스토어나 플레이스토어에 `120` 버전을 업로드했는데 채널 버전을 `110`으로 설정하려 하면 업데이트(다운그레이드)가 실패합니다. 다섯째는 `자동 업데이트 비활성화`입니다. 이 설정은 꽤 복잡하며, [여기](/docs/cli/commands/#disable-updates-strategy)에서 자세히 알아볼 수 있습니다. `개발 빌드 허용`의 경우, true로 설정되면 개발 빌드가 이 채널에서 업데이트를 다운로드할 수 있습니다. 그렇지 않으면 `prod`가 false로 설정된 모든 업데이트 요청이 거부됩니다. 이는 주로 테스트 목적으로 유용합니다. 일곱째는 `에뮬레이터 허용`입니다. false로 설정되면 capgo는 에뮬레이터에서 오는 모든 업데이트 요청을 거부합니다. 이는 주로 테스트 목적으로 유용합니다. 여덟째는 `디바이스 자체 연결 허용`입니다. true로 설정되면 [setChannel](/docs/plugin/api/#setchannel) 메서드를 사용할 수 있습니다. false로 설정되고 이 채널로 [setChannel](/docs/plugin/api/#setchannel) 메서드를 호출하려 하면 호출이 실패합니다. # 디바이스 > 디바이스 페이지 사용 방법 ## 모든 기기 목록 표시 먼저 기기 페이지를 살펴보겠습니다. [앱을 클릭](/docs/webapp/main-page)한 다음 [기기 탭을 클릭](/docs/webapp/main-app-page)하여 접근할 수 있습니다. ![devices list](/devices.webp) ## 개발자 기기만 표시 덮어쓰기된 기기([사용자 정의 채널](/docs/plugin/api/#setchannel) 또는 사용자 정의 버전이 있는 기기)만 표시하고 싶을 수 있습니다. 이를 위해 `필터`를 클릭한 다음 `덮어쓰기`를 클릭하세요. 다음과 같이 보일 것입니다: ![filter devices](/overwrite-filter.webp) ## 기기 구성하기 특정 기기를 구성하려면 테이블에서 해당 기기를 클릭하세요. 그러면 다음과 같은 화면이 표시됩니다: ![show one device](/device-specific.webp) 먼저 `사용자 정의 ID`입니다. 이것은 실제로 그다지 유용하지 않으며 현재는 아무 기능도 하지 않습니다. 무시하셔도 됩니다. 다음으로 강제 버전입니다. 이것이 설정되면 이 기기는 **항상** 이 버전을 받게 됩니다. 이는 채널보다 우선순위가 높습니다. 마지막으로 사용자 정의 채널입니다. 이것이 설정되면 이 기기는 공개(기본) 채널을 무시하고 이 채널만 사용합니다. # ログ > 로그 페이지 사용 방법 알아보기 ## 모든 로그 표시 먼저, 로그 페이지를 살펴보겠습니다. [앱을 클릭](/docs/webapp/main-page)한 다음 [업데이트 탭을 클릭](/docs/webapp/main-app-page)하여 접근할 수 있습니다. 그러면 다음과 같은 페이지가 표시됩니다: ![show logs](/logs.webp) ## 로그에 대한 자세한 정보 확인 로그를 클릭하면 [디바이스 페이지](/docs/webapp/devices/)로 이동합니다. # 메인 앱 페이지 > 메인 페이지에서는 무엇이 표시되나요? ## 메인 페이지는 무엇을 보여주나요? 먼저, 앱의 메인 페이지를 살펴보겠습니다: ![Main page screeshot](/main-app-page.webp) 자세히 살펴보겠습니다. 먼저 통계입니다. 통계는 현재 재작업 중이어서 지금은 문서화할 수 없습니다. 완전히 작동하게 되면 통계 섹션을 추가할 예정입니다. 두 번째로, 사용 가능한 모든 메뉴와 그 기능을 살펴보겠습니다. ![Multiple sections screeshot](/app-multiple-sections.webp) 첫 번째 버튼은 [채널](/docs/webapp/channels/) 페이지로 이동합니다. 여기서 앱의 채널을 생성/삭제/구성할 수 있습니다. 두 번째 버튼은 [번들](/docs/webapp/bundles/) 페이지로 이동합니다. 여기서 앱의 모든 버전을 볼 수 있습니다. 세 번째 버튼은 [디바이스](/docs/webapp/devices/) 페이지로 이동합니다. 여기서 모든 디바이스를 볼 수 있습니다. 또한 여기서 디바이스별 특정 오버라이드를 설정할 수 있습니다. 네 번째 버튼은 [업데이트](/docs/webapp/logs/) 페이지로 이동합니다. 여기서 앱이 겪고 있는 자세한 통계(로그)와 오류를 볼 수 있습니다. # Page principale > 이 페이지는 웹 애플리케이션의 메인 페이지를 설명합니다 ## 메인 페이지는 무엇을 보여주나요? 먼저, 메인 페이지를 살펴보겠습니다: ![Main page screeshot](/main-page.webp) 처음부터 시작해보겠습니다. 가장 먼저 보이는 것은 **통계**입니다. 이는 앱별 통계를 포함하고 있으며, 앱 사용량에 따라 업데이트됩니다. 두 번째로 보이는 것은 사용 가능한 모든 앱의 목록입니다. 이는 생성한 앱의 수에 따라 변경됩니다. 각 앱을 클릭하여 자세한 정보를 볼 수 있습니다. 세 번째로 보이는 것은 **API 키** 버튼입니다. 이 버튼을 누르면 [API 키](/docs/webapp/api-keys/) 페이지로 이동합니다. 다음으로 보이는 것은 **Capgo 테스트** 버튼입니다. 이 버튼은 사용자의 이름과 성에 따라 변경되며, [설정](/docs/webapp/settings/) 또는 지원 페이지로 이동합니다. 마지막으로, 다른 앱을 추가하는 버튼이 있습니다. 이 버튼을 누르면 capgo에 새로운 앱을 추가할 수 있는 페이지로 이동합니다. # 二要素認証 > capgo 계정을 더욱 안전하게 보호하기 위한 이중 인증 관리 ## 2FA란 무엇인가요? 2FA는 악의적인 사용자가 여러분의 capgo 계정을 탈취하는 것을 방지하기 위해 설계된 보안 조치입니다\ 추가 코드를 요구함으로써 이를 달성합니다. 이 코드는 휴대폰이나 하드웨어 2FA 키에 저장되며 30초마다 변경되어 추측이 불가능합니다 ## 이 가이드의 요구사항 * Android 또는 IOS 휴대폰 * 인터넷 연결 ## 이 가이드에서 다룰 내용은? 이 가이드는 `Google Authenticator`를 사용하여 2FA를 설정하는 방법을 보여줍니다. 비슷한 목적을 가진 다른 앱들도 있지만, 이 가이드에서 2FA의 모든 내용을 다룰 수는 없습니다 ## 2FA 설정 방법 먼저 `Google Authenticator` 앱을 다운로드하세요. Android를 사용 중이라면 [play store](https://play.google.com/store/apps/details/?id=comgoogleandroidappsauthenticator2)에서 다운로드할 수 있습니다. IOS에서는 [App store](https://appsapplecom/us/app/google-authenticator/id388497605/)에서 다운로드할 수 있습니다 두 번째로, [capgo의 계정 설정](https://web.capgo.app/dashboard/settings/account/)으로 이동하세요. 다음과 같은 초록색 버튼이 보일 것입니다 ![Button MFA](/button-mfa.webp) 클릭하면 QR 코드가 나타날 것입니다 ![Enable MFA](/enable-mfa.webp) Danger ⚠️ 중요 안내:\ 이 QR 코드를 절대 다른 사람과 공유하지 마세요. 계정에서 로그아웃될 수 있습니다 다음으로, 휴대폰에서 `Google Authenticator`를 열어주세요. 열었다면 다음 단계를 따르세요: 플러스 버튼을 클릭하세요 ![MFA auth plus](/mfa-auth-plus.webp) 그 다음, 카메라 버튼을 클릭하세요 ![MFA scan QR](/mfa-scan-qr.webp) 카메라 미리보기가 열릴 것입니다. PC에 표시된 QR 코드를 스캔하세요. 스캔 후에는 다음과 같은 화면이 보일 것입니다: ![MFA final code](/mfa-final-code.webp) 그런 다음 PC로 돌아가서 확인 버튼을 클릭하세요 ![Verify MFA](/enable-mfa-verify.webp) 2FA 코드를 입력하는 창이 열릴 것입니다. 제 경우에는 코드가 `095101`이지만 여러분의 코드는 다를 것입니다\ 이 코드를 입력한 후 `verify` 버튼을 클릭하세요 ![MFA verify code final](/mfa-verify-final-code.webp) 올바른 코드를 입력하고 `verify`를 누르면 다음과 같은 팝업이 표시됩니다 ![MFA enabled](/mfa-enabled.webp) 축하합니다!\ 2FA 인증을 활성화했습니다 🎉 ## 2FA를 사용하여 로그인하는 방법 다음에 계정에 로그인할 때는 다음과 같은 창이 표시됩니다 ![MFA required](/mfa-required.webp) 인증기를 열고 인증 코드를 복사하세요 ![MFA login](/mfa-login.webp) Danger ⚠️ 중요 안내:\ 코드가 새로고침되기 전에 `verify`를 누르세요. 그렇지 않으면 코드가 변경되어 이전 코드는 더 이상 유효하지 않습니다 그런 다음 로그인 양식에 코드를 입력하고 `verify`를 누르세요 ![MFA login](/mfa-final-login-verify.webp) 올바른 코드를 입력하면 capgo 대시보드가 표시됩니다 ## 2FA 비활성화 방법 2FA를 비활성화하려면 [capgo의 계정 설정](https://web.capgo.app/dashboard/settings/account/)으로 이동하세요. 다음과 같은 빨간색 버튼이 보일 것입니다: ![MFA disable button](/mfa-disable-button.webp) 클릭하면 다음과 같은 화면이 표시됩니다 ![MFA disabled](/mfa-disable-2.webp) `disable` 버튼을 누르면 됩니다. 이게 전부입니다 # 조직 시스템 > 계정에서 조직 관리하기 ## 조직 시스템이란 무엇인가요? 조직 시스템은 capgo에서 팀 멤버들과 앱을 안전하게 공유할 수 있게 해주는 시스템입니다. ### Q: 조직 정보에 어떻게 접근할 수 있나요? 조직 정보에 접근하려면 [설정](/docs/webapp/settings/#how-to-get-to-the-settings-page)으로 이동한 다음 `Organization settings`를 클릭하세요. ![Org settings](/orgs-settings.webp) ### Q: 보고 있는 조직을 어떻게 변경할 수 있나요? 다른 조직의 설정을 보려면 이름 옆에 있는 조직 선택기를 클릭하세요. ![Org selector](/org-selector.webp) 이것이 보이지 않는다면 설정 페이지에 있지 않을 수 있습니다. ### Q: 조직의 멤버를 어떻게 볼 수 있나요? `members`를 클릭하세요. ![Org Show members](/org-show-members.webp) ### Q: 사용자를 조직에 어떻게 초대할 수 있나요? `Add member`를 클릭하세요. ![Org add member](/orgs-add-member.webp) 팝업이 표시되면 사용자의 이메일 주소를 입력하세요. ![Invite to org](/invite-to-org-email-enter.webp) `invite`를 클릭하면 다른 팝업이 표시되며, 이번에는 초대된 사용자가 가져야 할 권한에 대해 묻습니다. ![Select perm for org](/select-perm-orgs.webp) 모든 권한에 대한 설명은 다음과 같습니다: | 권한 | Read | Upload | Write | Admin | Super Admin | | ------------- | ---- | ------ | ----- | ----- | ----------- | | 앱 통계 보기 | ✅ | ✅ | ✅ | ✅ | ✅ | | 앱 채널 보기 | ✅ | ✅ | ✅ | ✅ | ✅ | | 디바이스 보기 | ✅ | ✅ | ✅ | ✅ | ✅ | | 로그 보기 | ✅ | ✅ | ✅ | ✅ | ✅ | | 번들 보기 | ✅ | ✅ | ✅ | ✅ | ✅ | | 앱 삭제 | ❌ | ❌ | ❌ | ❌ | ✅ | | 채널 삭제 | ❌ | ❌ | ❌ | ✅ | ✅ | | 버전 삭제 | ❌ | ❌ | ✅ | ✅ | ✅ | | 조직 설정 변경 | ❌ | ❌ | ❌ | ✅ | ✅ | | 조직 사용자 관리 | ❌ | ❌ | ❌ | ✅ | ✅ | | 채널 설정 변경 | ❌ | ❌ | ✅ | ✅ | ✅ | | 새 버전 업로드 | ❌ | ✅ | ✅ | ✅ | ✅ | | 디바이스 변경 | ❌ | ❌ | ✅ | ✅ | ✅ | | 채널의 현재 버전 변경 | ❌ | ❌ | ✅ | ✅ | ✅ | | 새 채널 생성 | ❌ | ❌ | ❌ | ✅ | ✅ | | 버전 수정 (메타데이터) | ❌ | ❌ | ✅ | ✅ | ✅ | | 결제 관리 | ❌ | ❌ | ❌ | ❌ | ✅ | | 버전 안전하지 않게 삭제 | ❌ | ❌ | ❌ | ❌ | ✅ | ### Q: 조직 내에서 결제는 어떻게 이루어지나요? **super admin** 권한이 있는 사용자는 주어진 조직의 결제를 관리할 수 있습니다. 플랜은 개인 계정이 아닌 조직에 연결됩니다. Danger ⚠️ 플랜 구매는 현재 선택한 조직에만 영향을 미칩니다. ### Q: 하나 이상의 조직을 만들 수 있나요? 아니요, 아직은 불가능합니다. # 결제 시스템 > capgo 계정에서 결제 관리 ## 이것은 무엇에 관한 것인가요? 이 페이지는 capgo의 결제 시스템에 대한 일부 질문에 답하는 것을 목표로 합니다. #### Q: capgo 플랜을 어떻게 업그레이드할 수 있나요? A: [설정](/docs/webapp/settings/#how-to-get-to-the-settings-page)으로 이동하여 **Plans** 버튼을 클릭하여 capgo 플랜을 업그레이드할 수 있습니다. ![Choose plan](/plans-button.webp) 그런 다음 귀하의 필요에 가장 적합한 플랜을 선택하고 **Subscribe**를 클릭하세요. ![Subscribe to plan](/plans-subscribe.webp) 그러면 stripe 페이지가 열립니다. 여기서 결제 정보를 입력할 수 있습니다. ![Stripe portal](/plans-stripe.webp) #### Q: 결제는 안전한가요? A: 네, 결제는 stripe에 의해 완전히 관리됩니다. Capgo는 절대 귀하의 신용카드 정보에 접근하지 않습니다. Stripe는 보안을 매우 중요하게 여깁니다. [Stripe 보안 정책에 대해 자세히 알아보기](https://stripecom/docs/security/) #### Q: 제가 한도를 초과하면 capgo가 자동으로 플랜을 업그레이드하나요? A: 아니요, capgo는 절대 귀하의 플랜을 변경하지 않습니다. #### Q: capgo가 제 플랜이 한도에 가까워지면 이메일을 보내주나요? A: 네, capgo는 사용량에 대해 알려주는 이메일을 보낼 것입니다. #### Q: 제가 구매한 플랜이 초대받은 조직에 영향을 미치나요? A: 아니요, 플랜은 현재 선택한 조직에만 영향을 미칩니다. [조직 문서](/docs/webapp/organization-system/#q-how-is-billing-done-within-orgs)를 참조해 주세요. #### Q: 더 맞춤화된 플랜이 필요하다면 어떻게 하나요? A: [capgo 지원팀에 직접 문의해 주세요](/docs/getting-help#support-by-chat) #### Q: capgo의 환불 정책은 어떻게 되나요? A: 환불 정책은 [여기](https://capgo.app/return/)에서 확인할 수 있습니다. # 설정 > 사용자 설정 변경 방법 ## 설정 페이지로 이동하는 방법 먼저 **이름 성**을 클릭하세요. 제 경우에는 **test Capgo**입니다. 귀하의 경우에는 귀하의 이름과 성이 됩니다. 그런 다음 **설정**을 클릭하세요. ![open settings](/settings-go.webp) ## 사용자 설정 변경하기 사용자 설정을 변경하려면 계정에서 양식을 작성한 후 **업데이트**를 클릭하면 됩니다. ![save change in account](/account-save.webp) 그러면 확인 메시지가 나타납니다. ![acount updated](/account-updated.webp) ## 비밀번호 변경하기 비밀번호를 변경하려면 설정 페이지로 이동하여 **비밀번호**를 클릭하세요. 그런 다음 양식을 작성하고 **업데이트**를 클릭하세요. ![update password](/update-passwd.webp) 비밀번호가 capgo 비밀번호 보안 규칙을 따르지 않으면 오류 메시지가 표시됩니다. ![wrong password](/passwd-error.webp)