# JW Library Sync System **Date:** 2026-03-31 **Status:** Working — E2E Verified (Tablet) **Stack:** Android (Tablet/Phone), Tasker, AutoInput, GitSync, Gitea, n8n, jwlFusion --- ## System Overview Syncs JW Library backups (`.jwlibrary`) across multiple Android devices via a central server-side merge. Each device exports its backup, pushes it to Gitea, the server merges everything into a single `master.jwlibrary`, and each device restores from that master. --- ## Daily Sequence (4:30 AM) | Time | Device | Action | |------|--------|--------| | 04:30 | Tablet | Backup → GitSync push → trigger n8n merge | | 04:35 | Phone | Backup → GitSync push | | 04:45 | Tablet | (after n8n responds) GitSync pull → restore master | --- ## Tasker Tasks ### JWL_Backup_To_Git 1. **Kill App** — `org.jw.jwlibrary.mobile` 2. **Wait** — 2s 3. **Launch App** — JW Library 4. **Wait** — 3s 5. **AutoInput** — `nav_personal_study` → `action_backup_restore` → `Create Backup` 6. **Wait** — 3s 7. **AutoInput** — `Save Locally` → confirm (`android:id/button1`) 8. **Perform Task** — `Git Sync` ### Git Sync 1. **AutoInput** — `openApp(com.viscouspot.gitsync)` → `click(text,SYNC CHANGES)` → `backOutOfApp()` 2. **Perform Task** — `JWL_Merge` (wait for return) ### JWL_Merge 1. **HTTP POST** — `http://n8n.bunny-wyvern.ts.net:5678/webhook/sync-jw-backup` - Body: `{"device": "Samsung-Tablet-S10+"}` - Timeout: 60s 2. **Wait** — 2s 3. **If** `%http_data` matches `*Successful*`: - **Wait** — 3s - **Perform Task** — `JWL_Restore_From_Git` 4. **End If** - *(Discord notification fires on n8n side if merge fails)* ### JWL_Restore_From_Git 1. **Kill App** — `org.jw.jwlibrary.mobile` 2. **Wait** — 2s 3. **Launch App** — JW Library 4. **Wait** — 3s 5. **AutoInput** — `nav_personal_study` → `action_backup_restore` → `Restore Backup` 6. **Wait** — 3s 7. **Open File** (Tasker) — `/storage/emulated/0/vault/JW_Backups/master.jwlibrary` - JW Library intercepts the file directly — no file picker navigation needed --- ## n8n Workflow **Webhook** → **SSH (Execute command)** → success: **Respond "Merge Successful"** / error: **Discord notification** → **Respond "Merge Failed"** - Webhook path: `POST /webhook/sync-jw-backup` - SSH credential: `Homelab Login` - Script: `bash /home/artanis/Documents/JW_Backup_Sync_Engine.sh` - No Wait node between SSH and response — removed, was causing indefinite hang --- ## Server Script — JW_Backup_Sync_Engine.sh **Path:** `/home/artanis/Documents/JW_Backup_Sync_Engine.sh` **Source copy:** `stacks/n8n/JW_Backup/JW_Backup_Sync_Engine.sh` **What it does:** 1. `git pull origin main` — fetch latest device backups 2. Rename all `.jwlibrary` files (except `master.jwlibrary`) to `incoming_N.jwlibrary` 3. Run `jwlFusion` to merge all incoming files into `master_tmp.jwlibrary` - If only one file and no master exists: promotes it directly 4. Delete all `incoming_*.jwlibrary` files 5. Rename `master_tmp.jwlibrary` → `master.jwlibrary` 6. `git add -A` → commit → `git push origin main` - `git add -A` is critical — stages deletions of old device files so they don't reappear on next pull **After script runs:** only `master.jwlibrary` remains in the repo. --- ## Reference | Item | Value | |------|-------| | Vault (device) | `/storage/emulated/0/vault` | | JW_Backups (device) | `/storage/emulated/0/vault/JW_Backups` | | JW_Backups (server) | `/home/artanis/Inanis_Vault/JW_Backups` | | n8n Webhook | `http://n8n.bunny-wyvern.ts.net:5678/webhook/sync-jw-backup` | | Sync script | `/home/artanis/Documents/JW_Backup_Sync_Engine.sh` | --- ## Known Issues & Workarounds | Issue | Workaround | |-------|-----------| | Termux:Tasker fails ("Missing/Disabled Receiver") | Use AutoInput to physically click GitSync UI instead | | GitSync doesn't respond to `com.viscouspot.gitsync.action.SYNC` intents | AutoInput clicks "SYNC CHANGES" button directly | | JW Library `android.intent.action.VIEW` intent does nothing | Tasker **Open File** action works instead | | JW Library on wrong screen breaks AutoInput | Force-stop app before every launch | | Old device backups persisted in repo across runs | `git add -A` instead of `git add master.jwlibrary` | --- ## Open Items - [ ] **Screen-off handling** — verify AutoInput sequence works when device screen is off (may need `Turn On Display` + `Dismiss Keyguard` actions before AutoInput steps) - [ ] **Phone e2e test** — tablet verified, phone not yet tested end-to-end - [ ] **Stagger validation** — confirm 5-min gap between phone push (04:35) and tablet n8n trigger (04:45) is sufficient on slow networks - [ ] **`.gitignore`** — verify temp `.tmp` files from JW Library export are ignored in the vault repo