# Wiki.js Webhook Setup Guide Complete guide to enable automatic processing of user-edited wiki pages. ## Overview When you manually edit pages in Wiki.js, the webhook system ensures they're processed identically to AI-generated content: - ✅ **Vectors updated** - Qdrant embeddings refreshed - ✅ **Graph updated** - Entities extracted, relationships created - ✅ **Bidirectional links** - Automatic entity linking both ways - ✅ **Deletions handled** - Clean removal from vectors + graph - ✅ **Moves processed** - Path updates propagated to graph ## Step 1: Configure Wiki.js Webhook ### Access Wiki.js Administration 1. Log into Wiki.js as administrator 2. Navigate to **Administration** → **Webhooks** 3. Click **Add New Webhook** ### Webhook Configuration | Field | Value | |-------|-------| | **Name** | Library Desk Integration | | **Endpoint URL** | `http://library-desk:8089/webhooks/wikijs` | | **Content Type** | `application/json` | | **Events** | ☑ page.create
☑ page.update
☑ page.delete
☑ page.rename | | **Status** | ✅ Active | ### Authentication Header Add custom header for API authentication: ``` Authorization: Bearer af88ed8f44bed81bdb20d0534f1c4547340b29e2aba4963f61a71b993d7eb6e5 ``` *(Use your actual Library Desk API key from `.env`)* ## Step 2: Verify Webhook Endpoint Test the webhook health endpoint: ```bash curl http://192.168.86.149:8089/webhooks/health ``` Expected response: ```json { "status": "ok", "service": "webhooks" } ``` ## Step 3: Test Webhook Integration ### Test 1: Page Creation 1. Create a new page in Wiki.js 2. Add content mentioning existing entities (e.g., "Docker", "Kubernetes") 3. Save the page **Expected Result:** - Vectors created in Qdrant - Document node created in Neo4j - Entities extracted and linked - Bidirectional links added (new page links to entities, entities' pages link back) ### Test 2: Page Update 1. Edit an existing page 2. Add new content with entity mentions 3. Save changes **Expected Result:** - Vectors updated in Qdrant (old removed, new added) - Graph updated with new entities - Entity links refreshed ### Test 3: Page Deletion 1. Delete a page from Wiki.js **Expected Result:** - Vectors removed from Qdrant - Document node removed from Neo4j - Orphaned entities cleaned up (entities only mentioned in this page) - Broken relationships removed ### Test 4: Page Move/Rename 1. Move a page to different location (e.g., `/tech/docker` → `/infrastructure/docker`) 2. Or rename the page **Expected Result:** - Document node path updated in Neo4j - Entity links updated if title changed - Vectors remain valid (no re-embedding needed unless content changed) ## Event Processing Details ### page.create ``` User creates page → Webhook → Library Desk ├─ Ingest page (vector + graph) ├─ Extract entities ├─ Forward linking (page → entities) └─ Backward linking (entities → page) ``` ### page.update ``` User edits page → Webhook → Library Desk ├─ Re-ingest page (force refresh) ├─ Update entities ├─ Refresh forward links └─ Refresh backward links ``` ### page.delete ``` User deletes page → Webhook → Library Desk ├─ Remove vectors from Qdrant ├─ Find orphaned entities ├─ Delete Document node ├─ Delete orphaned entities └─ Clean broken relationships ``` ### page.rename ``` User moves/renames page → Webhook → Library Desk ├─ Update Document node path ├─ Update title if changed ├─ Re-link entities if title changed └─ Update references ``` ## Monitoring Webhook Activity ### Check Logs ```bash # Library Desk logs docker logs library-desk --follow | grep webhook # Look for: # - "Received Wiki.js webhook: page.create" # - "Processing page.update for page 123" # - "Cleanup complete for deleted page 456" ``` ### Verify Processing After making changes in Wiki.js, verify: **1. Vectors Updated:** ```bash curl -X POST http://192.168.86.149:8089/query/hybrid \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"query": "your page content", "user": "jpmschweitzer"}' ``` **2. Graph Updated:** ```cypher // In Neo4j Browser MATCH (d:Document {page_id: 123}) OPTIONAL MATCH (d)-[:MENTIONS]->(e) RETURN d, collect(e.name) as entities ``` **3. Entity Links Added:** Visit the page in Wiki.js and verify entity names are hyperlinked. ## Troubleshooting ### Webhook Not Triggering **Problem:** Changes in Wiki.js don't trigger processing **Solutions:** 1. Check webhook configuration in Wiki.js Admin 2. Verify endpoint URL is correct: `http://library-desk:8089/webhooks/wikijs` 3. Check authorization header is set 4. Verify library-desk is running: `docker ps | grep library-desk` 5. Check library-desk logs: `docker logs library-desk --tail 50` ### Processing Failures **Problem:** Webhook triggers but processing fails **Solutions:** 1. Check library-desk logs for errors 2. Verify Neo4j is accessible 3. Verify Qdrant is accessible 4. Check Ollama is running (for embeddings) 5. Verify user mapping in `extract_user_from_email()` ### Orphaned Entities **Problem:** Deleted pages leave entities behind **Solution:** Manually clean orphaned entities: ```cypher // Find orphaned entities (no MENTIONS relationships) MATCH (e:User_Jpmschweitzer) WHERE NOT e:Document AND NOT EXISTS {(d:Document)-[:MENTIONS]->(e)} DETACH DELETE e RETURN count(e) as deleted ``` ### Broken Links **Problem:** Entity links broken after page moves **Solution:** Re-run entity linking on all pages: ```bash curl -X POST http://192.168.86.149:8089/entity-linking/link-all \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"user": "jpmschweitzer"}' ``` ## Performance Considerations ### Background Processing Webhook handler processes events in the background to avoid blocking Wiki.js: - Webhook response: <100ms (immediate acknowledgment) - Processing: 2-10s (runs asynchronously) - No impact on Wiki.js editing experience ### Rate Limiting For bulk operations (importing many pages): - Consider temporarily disabling webhook - Use batch ingestion endpoint instead: `/ingest/batch` - Re-enable webhook after bulk import ## Advanced Configuration ### Custom User Mapping By default, user is extracted from email (`user@domain` → `user`). Customize in `/services/library-desk/src/routers/webhooks.py`: ```python def extract_user_from_email(email: str) -> str: # Option 1: Map specific emails to users user_map = { "admin@example.com": "admin", "john.doe@example.com": "jpmschweitzer" } return user_map.get(email, email.split("@")[0]) ``` ### Event Filtering To process only certain pages, add filtering in webhook handler: ```python # Only process pages in /tech/ path if not payload.page.get("path", "").startswith("/tech/"): logger.info(f"Skipping page outside /tech/: {payload.page.get('path')}") return ``` ### Disable Bidirectional Linking To only do forward linking (page → entities) without backward linking: Edit `process_wiki_page_change()`: ```python # Comment out the bidirectional linking call # link_stats = await consolidation_service._apply_bidirectional_entity_linking(...) ``` ## Summary With webhooks configured: | User Action | Automatic Processing | |-------------|---------------------| | Create page | Ingest + entity link (bidirectional) | | Edit page | Re-ingest + refresh links | | Delete page | Clean vectors + graph + orphaned entities | | Move page | Update paths + refresh links | **Result:** User-edited and AI-generated pages are **indistinguishable** in the knowledge base!