feat: dynamic webhook URL per session#107
Conversation
- setupSession now accepts an optional webhookUrl parameter - Store webhookUrl on client object for runtime access - initializeEvents uses client.webhookUrl with fallback to env vars - Add setSessionWebhook function to update webhook URL at runtime - Add getSessionWebhook function to retrieve current webhook URL Closes avoylenko#34
- startSession now reads optional webhookUrl from request body - Accepts both GET (backward compat) and POST with JSON body - Add setWebhook endpoint to update webhook URL at runtime - Add getWebhook endpoint to retrieve current webhook URL and source
- Add POST /session/start/:sessionId (accepts webhookUrl in body) - Keep GET /session/start/:sessionId for backward compatibility - Add PUT /session/setWebhook/:sessionId - Add GET /session/getWebhook/:sessionId
- Save webhookUrl to session-{id}/webhook_config.json on set
- Load webhookUrl from disk on session restore (restoreSessions)
- Delete webhook_config.json when session folder is deleted
- Webhook URL survives server restarts when AUTO_START_SESSIONS=true
- Add 'Set Webhook' operation: configure webhook URL for active session at runtime - Add 'Get Webhook' operation: retrieve current webhook URL and its source - Add optional 'Webhook URL' option to 'Start' session operation - Start uses POST when webhookUrl provided (requires wwebjs-api v1.35+) - Graceful fallback: Start uses GET when no webhookUrl (backward compat) These operations correspond to the upstream PR avoylenko/wwebjs-api#107 which adds dynamic webhook URL support to the REST API. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
n8n Integration — How we plan to use this featureWe maintain n8n-nodes-wwebjs-api, a community n8n node that integrates with this API. We've already prepared a PR on our side that adds webhook management operations using the endpoints proposed here. Usage from n8nOnce this PR is merged, n8n users will be able to: 1. Start a session with a webhook URL This eliminates the need to configure 2. Update the webhook at runtime Useful when n8n webhook URLs change (e.g., after redeployment) — no server restart needed. 3. Query the current webhook configuration Helps users debug and verify their webhook setup directly from n8n. Why this matters for n8n usersCurrently, connecting n8n ↔ wwebjs-api requires manually setting environment variables and restarting the API server whenever webhook URLs change. This PR enables a fully self-service workflow where the n8n node handles webhook registration automatically, significantly reducing setup friction. The persistence feature (webhook_config.json) is especially important — it means that after a server restart, sessions automatically reconnect with the correct webhook URL without user intervention. Looking forward to seeing this merged! 🙌 |
|
Correction: the link to our n8n-side PR is vgpastor/n8n-nodes-wwebjs-api#4. |
|
@avoylenko can you see this PR? Thanks!! |
|
@vgpastor thank you for your work. Gonna do that next week, at this time main occupation takes all free time. |
There was a problem hiding this comment.
Pull request overview
Adds per-session webhook URL configuration so sessions can be started and updated with a webhook URL at runtime, with persistence across restarts (via a session-scoped config file), addressing the “set webhook during session creation” request from #34.
Changes:
- Extends session setup to accept an optional
webhookUrl, stores it on the client, and resolves webhook destination dynamically at event-trigger time. - Persists/restores per-session webhook configuration to/from
session-{id}/webhook_config.json. - Adds/extends HTTP endpoints to start sessions via POST with JSON body and to set/get webhook URL at runtime.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
src/sessions.js |
Adds webhook config persistence helpers, runtime get/set helpers, and updates event dispatch to resolve webhook URL dynamically. |
src/controllers/sessionController.js |
Accepts webhookUrl during session start and adds controllers to set/get webhook configuration at runtime. |
src/routes.js |
Adds routes for POST start, setWebhook, and getWebhook endpoints. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (fs.existsSync(configPath)) { | ||
| const data = JSON.parse(fs.readFileSync(configPath, 'utf8')) | ||
| if (data && data.webhookUrl) { | ||
| logger.info({ sessionId, webhookUrl: data.webhookUrl }, 'Webhook config loaded from disk') |
| // Store custom webhook URL on client if provided via API or loaded from disk | ||
| if (options.webhookUrl) { | ||
| client.webhookUrl = options.webhookUrl | ||
| logger.info({ sessionId, webhookUrl: options.webhookUrl }, 'Custom webhook URL configured for session') |
| client.webhookUrl = webhookUrl || null | ||
| // Persist to disk so it survives server restarts | ||
| saveWebhookConfig(sessionId, webhookUrl) | ||
| logger.info({ sessionId, webhookUrl: webhookUrl || '(cleared, using default)' }, 'Session webhook URL updated') |
| // Read optional webhookUrl from body (works for both GET with empty body and POST with JSON) | ||
| const options = {} | ||
| if (req.body && req.body.webhookUrl) { | ||
| options.webhookUrl = req.body.webhookUrl | ||
| } |
| const { webhookUrl } = req.body || {} | ||
| const result = setSessionWebhook(sessionId, webhookUrl) | ||
| if (!result.success) { |
| @@ -49,6 +50,8 @@ sessionRouter.get('/terminate/:sessionId', middleware.sessionNameValidation, ses | |||
| sessionRouter.get('/terminateInactive', sessionController.terminateInactiveSessions) | |||
| sessionRouter.get('/terminateAll', sessionController.terminateAllSessions) | |||
| sessionRouter.get('/getPageScreenshot/:sessionId', middleware.sessionNameValidation, sessionController.getPageScreenshot) | |||
| sessionRouter.put('/setWebhook/:sessionId', middleware.sessionNameValidation, sessionController.setWebhook) | |||
| sessionRouter.get('/getWebhook/:sessionId', middleware.sessionNameValidation, sessionController.getWebhook) | |||
|
@vgpastor lease take a look when you have free time. Copilot suggestions seems legit. |
Summary
Implements the feature proposed in #34 — dynamic webhook URL configuration per session, without requiring environment variables or server restarts.
Changes
src/sessions.jssetupSession(sessionId, options)now accepts an optionaloptions.webhookUrlparameterclient.webhookUrl)initializeEventsuses agetWebhookUrl()closure that resolves at call time:client.webhookUrl → env session var → BASE_WEBHOOK_URLsession-{id}/webhook_config.json) so it survives server restartsrestoreSessionsloads persisted webhook config when restoring sessionssetSessionWebhook(),getSessionWebhook()src/controllers/sessionController.jsstartSessionreads optionalwebhookUrlfromreq.body(works with both GET for backward compat and POST with JSON body)setWebhookcontroller to update webhook URL at runtimegetWebhookcontroller to retrieve current webhook URL and its source (runtime,env_session,env_global,none)src/routes.jsPOST /session/start/:sessionId(acceptswebhookUrlin body) alongside existingGETroutePUT /session/setWebhook/:sessionId— update webhook URL at runtimeGET /session/getWebhook/:sessionId— get current webhook URL and sourceBackward Compatibility
GET /session/start/:sessionIdstill works exactly as beforewebhookUrlis provided, behavior is identical to current: env session var →BASE_WEBHOOK_URLPersistence
Webhook URLs configured via API are persisted to
session-{id}/webhook_config.jsoninside the session folder. This means:AUTO_START_SESSIONS=true, restored sessions will reload their webhook URLs from diskwebhook_config.jsonis deleted along with the session folderwebhookUrlremoves the config file, falling back to env varsUsage Examples
Start session with webhook:
Update webhook URL at runtime:
Check current webhook:
curl http://localhost:3000/session/getWebhook/my-session # {"success":true,"webhookUrl":"https://...","source":"runtime"}Priority Resolution
Closes #34