Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 129 additions & 4 deletions src/controllers/sessionController.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const qr = require('qr-image')
const { setupSession, deleteSession, reloadSession, validateSession, flushSessions, destroySession, sessions } = require('../sessions')
const { setupSession, deleteSession, reloadSession, validateSession, flushSessions, destroySession, sessions, setSessionWebhook, getSessionWebhook } = require('../sessions')
const { sendErrorResponse, waitForNestedObject, exposeFunctionIfAbsent } = require('../utils')
const { logger } = require('../logger')

Expand All @@ -11,15 +11,37 @@ const { logger } = require('../logger')
* @param {Object} req - The HTTP request object.
* @param {Object} res - The HTTP response object.
* @param {string} req.params.sessionId - The session ID to start.
* @param {string} [req.body.webhookUrl] - Optional webhook URL for this session.
* @returns {Promise<void>}
* @throws {Error} If there was an error starting the session.
*/
const startSession = async (req, res) => {
// #swagger.summary = 'Start new session'
// #swagger.description = 'Starts a session for the given session ID.'
// #swagger.description = 'Starts a session for the given session ID. Optionally accepts a webhookUrl in the request body (POST) to configure a per-session webhook.'
/*
#swagger.requestBody = {
required: false,
schema: {
type: 'object',
properties: {
webhookUrl: {
type: 'string',
description: 'Optional webhook URL for this session. Overrides BASE_WEBHOOK_URL and session env var.',
example: 'https://your-server.com/webhook/my-session'
}
}
}
}
*/
const sessionId = req.params.sessionId
try {
const setupSessionReturn = await setupSession(sessionId)
// 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 setupSessionReturn = await setupSession(sessionId, options)
if (!setupSessionReturn.success) {
/* #swagger.responses[422] = {
description: "Unprocessable Entity.",
Expand Down Expand Up @@ -51,6 +73,107 @@ const startSession = async (req, res) => {
}
}

/**
* Set or update the webhook URL for an active session.
*
* @function
* @async
* @param {Object} req - The HTTP request object.
* @param {Object} res - The HTTP response object.
* @param {string} req.params.sessionId - The session ID.
* @param {string} req.body.webhookUrl - The new webhook URL (or null/empty to clear).
* @returns {Promise<void>}
*/
const setWebhook = async (req, res) => {
// #swagger.summary = 'Set session webhook URL'
// #swagger.description = 'Set or update the webhook URL for an active session at runtime. Send an empty webhookUrl or null to clear and fall back to environment variables.'
/*
#swagger.requestBody = {
required: true,
schema: {
type: 'object',
properties: {
webhookUrl: {
type: 'string',
description: 'The webhook URL to set for this session. Send empty string or null to clear.',
example: 'https://your-server.com/webhook/my-session'
}
}
}
}
*/
const sessionId = req.params.sessionId
try {
const { webhookUrl } = req.body || {}
const result = setSessionWebhook(sessionId, webhookUrl)
if (!result.success) {
return sendErrorResponse(res, 404, result.message)
}
/* #swagger.responses[200] = {
description: "Webhook URL updated.",
content: {
"application/json": {
schema: {
type: 'object',
properties: {
success: { type: 'boolean' },
message: { type: 'string' },
webhookUrl: { type: 'string' }
}
}
}
}
}
*/
res.json(result)
} catch (error) {
logger.error({ sessionId, err: error }, 'Failed to set session webhook')
sendErrorResponse(res, 500, error.message)
}
}

/**
* Get the current webhook URL for a session.
*
* @function
* @async
* @param {Object} req - The HTTP request object.
* @param {Object} res - The HTTP response object.
* @param {string} req.params.sessionId - The session ID.
* @returns {Promise<void>}
*/
const getWebhook = async (req, res) => {
// #swagger.summary = 'Get session webhook URL'
// #swagger.description = 'Get the current webhook URL for a session, including the source (runtime, env_session, env_global, or none).'
const sessionId = req.params.sessionId
try {
const result = getSessionWebhook(sessionId)
if (!result.success) {
return sendErrorResponse(res, 404, result.message)
}
/* #swagger.responses[200] = {
description: "Current webhook URL and source.",
content: {
"application/json": {
schema: {
type: 'object',
properties: {
success: { type: 'boolean' },
webhookUrl: { type: 'string' },
source: { type: 'string', enum: ['runtime', 'env_session', 'env_global', 'none'] }
}
}
}
}
}
*/
res.json(result)
} catch (error) {
logger.error({ sessionId, err: error }, 'Failed to get session webhook')
sendErrorResponse(res, 500, error.message)
}
}

/**
* Stops a session for the given session ID.
*
Expand Down Expand Up @@ -465,5 +588,7 @@ module.exports = {
terminateInactiveSessions,
terminateAllSessions,
getSessions,
getPageScreenshot
getPageScreenshot,
setWebhook,
getWebhook
}
3 changes: 3 additions & 0 deletions src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ routes.use('/session', sessionRouter)

sessionRouter.get('/getSessions', sessionController.getSessions)
sessionRouter.get('/start/:sessionId', middleware.sessionNameValidation, sessionController.startSession)
sessionRouter.post('/start/:sessionId', middleware.sessionNameValidation, sessionController.startSession)
sessionRouter.get('/stop/:sessionId', middleware.sessionNameValidation, sessionController.stopSession)
sessionRouter.get('/status/:sessionId', middleware.sessionNameValidation, sessionController.statusSession)
sessionRouter.get('/qr/:sessionId', middleware.sessionNameValidation, sessionController.sessionQrCode)
Expand All @@ -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)

/**
* ================
Expand Down
Loading