feat: stop single session and auto start all sessions
This commit is contained in:
parent
1c0d1f63d1
commit
19797f4268
8 changed files with 162 additions and 7 deletions
|
|
@ -1,7 +1,8 @@
|
||||||
const app = require('./src/app')
|
const app = require('./src/app')
|
||||||
const { baseWebhookURL, enableWebHook, enableWebSocket } = require('./src/config')
|
const { baseWebhookURL, enableWebHook, enableWebSocket, autoStartSessions } = require('./src/config')
|
||||||
const { logger } = require('./src/logger')
|
const { logger } = require('./src/logger')
|
||||||
const { handleUpgrade } = require('./src/websocket')
|
const { handleUpgrade } = require('./src/websocket')
|
||||||
|
const { restoreSessions } = require('./src/sessions')
|
||||||
|
|
||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
|
||||||
|
|
@ -17,6 +18,10 @@ if (!baseWebhookURL && enableWebHook) {
|
||||||
const server = app.listen(port, () => {
|
const server = app.listen(port, () => {
|
||||||
logger.info(`Server running on port ${port}`)
|
logger.info(`Server running on port ${port}`)
|
||||||
logger.debug({ configuration: require('./src/config') }, 'Service configuration')
|
logger.debug({ configuration: require('./src/config') }, 'Service configuration')
|
||||||
|
if (autoStartSessions) {
|
||||||
|
logger.info('Starting all sessions')
|
||||||
|
restoreSessions()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (enableWebSocket) {
|
if (enableWebSocket) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
require('./routes')
|
require('./routes')
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
const { restoreSessions } = require('./sessions')
|
|
||||||
const { routes } = require('./routes')
|
const { routes } = require('./routes')
|
||||||
const { maxAttachmentSize } = require('./config')
|
const { maxAttachmentSize } = require('./config')
|
||||||
|
|
||||||
|
|
@ -12,6 +11,4 @@ app.use(express.json({ limit: maxAttachmentSize + 1000000 }))
|
||||||
app.use(express.urlencoded({ limit: maxAttachmentSize + 1000000, extended: true }))
|
app.use(express.urlencoded({ limit: maxAttachmentSize + 1000000, extended: true }))
|
||||||
app.use('/', routes)
|
app.use('/', routes)
|
||||||
|
|
||||||
restoreSessions()
|
|
||||||
|
|
||||||
module.exports = app
|
module.exports = app
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ const releaseBrowserLock = process.env.RELEASE_BROWSER_LOCK ? (process.env.RELEA
|
||||||
const logLevel = process.env.LOG_LEVEL || 'info'
|
const logLevel = process.env.LOG_LEVEL || 'info'
|
||||||
const enableWebHook = process.env.ENABLE_WEBHOOK ? (process.env.ENABLE_WEBHOOK).toLowerCase() === 'true' : true
|
const enableWebHook = process.env.ENABLE_WEBHOOK ? (process.env.ENABLE_WEBHOOK).toLowerCase() === 'true' : true
|
||||||
const enableWebSocket = process.env.ENABLE_WEBSOCKET ? (process.env.ENABLE_WEBSOCKET).toLowerCase() === 'true' : false
|
const enableWebSocket = process.env.ENABLE_WEBSOCKET ? (process.env.ENABLE_WEBSOCKET).toLowerCase() === 'true' : false
|
||||||
|
const autoStartSessions = process.env.AUTO_START_SESSIONS ? (process.env.AUTO_START_SESSIONS).toLowerCase() === 'true' : true
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
sessionFolderPath,
|
sessionFolderPath,
|
||||||
|
|
@ -41,5 +42,6 @@ module.exports = {
|
||||||
releaseBrowserLock,
|
releaseBrowserLock,
|
||||||
logLevel,
|
logLevel,
|
||||||
enableWebHook,
|
enableWebHook,
|
||||||
enableWebSocket
|
enableWebSocket,
|
||||||
|
autoStartSessions
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const qr = require('qr-image')
|
const qr = require('qr-image')
|
||||||
const { setupSession, deleteSession, reloadSession, validateSession, flushSessions, sessions } = require('../sessions')
|
const { setupSession, deleteSession, reloadSession, validateSession, flushSessions, destroySession, sessions } = require('../sessions')
|
||||||
const { sendErrorResponse, waitForNestedObject } = require('../utils')
|
const { sendErrorResponse, waitForNestedObject } = require('../utils')
|
||||||
const { logger } = require('../logger')
|
const { logger } = require('../logger')
|
||||||
|
|
||||||
|
|
@ -51,6 +51,39 @@ const startSession = async (req, res) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops a session for the given session ID.
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @async
|
||||||
|
* @param {Object} req - The HTTP request object.
|
||||||
|
* @param {Object} res - The HTTP response object.
|
||||||
|
* @param {string} req.params.sessionId - The session ID to stop.
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
* @throws {Error} If there was an error stopping the session.
|
||||||
|
*/
|
||||||
|
const stopSession = async (req, res) => {
|
||||||
|
// #swagger.summary = 'Stop session'
|
||||||
|
// #swagger.description = 'Stops a session for the given session ID.'
|
||||||
|
const sessionId = req.params.sessionId
|
||||||
|
try {
|
||||||
|
await destroySession(sessionId)
|
||||||
|
/* #swagger.responses[200] = {
|
||||||
|
description: "Status of the stopped session.",
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: { "$ref": "#/definitions/StopSessionResponse" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
res.json({ success: true, message: 'Session stopped successfully' })
|
||||||
|
} catch (error) {
|
||||||
|
logger.error({ sessionId, err: error }, 'Failed to stop session')
|
||||||
|
sendErrorResponse(res, 500, error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Status of the session with the given session ID.
|
* Status of the session with the given session ID.
|
||||||
*
|
*
|
||||||
|
|
@ -417,6 +450,7 @@ const getPageScreenshot = async (req, res) => {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
startSession,
|
startSession,
|
||||||
|
stopSession,
|
||||||
statusSession,
|
statusSession,
|
||||||
sessionQrCode,
|
sessionQrCode,
|
||||||
sessionQrCodeImage,
|
sessionQrCodeImage,
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ routes.use('/session', sessionRouter)
|
||||||
|
|
||||||
sessionRouter.get('/getSessions', sessionController.getSessions)
|
sessionRouter.get('/getSessions', sessionController.getSessions)
|
||||||
sessionRouter.get('/start/:sessionId', middleware.sessionNameValidation, sessionController.startSession)
|
sessionRouter.get('/start/:sessionId', middleware.sessionNameValidation, sessionController.startSession)
|
||||||
|
sessionRouter.get('/stop/:sessionId', middleware.sessionNameValidation, sessionController.stopSession)
|
||||||
sessionRouter.get('/status/:sessionId', middleware.sessionNameValidation, sessionController.statusSession)
|
sessionRouter.get('/status/:sessionId', middleware.sessionNameValidation, sessionController.statusSession)
|
||||||
sessionRouter.get('/qr/:sessionId', middleware.sessionNameValidation, sessionController.sessionQrCode)
|
sessionRouter.get('/qr/:sessionId', middleware.sessionNameValidation, sessionController.sessionQrCode)
|
||||||
sessionRouter.get('/qr/:sessionId/image', middleware.sessionNameValidation, sessionController.sessionQrCodeImage)
|
sessionRouter.get('/qr/:sessionId/image', middleware.sessionNameValidation, sessionController.sessionQrCodeImage)
|
||||||
|
|
|
||||||
|
|
@ -488,6 +488,33 @@ const reloadSession = async (sessionId) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const destroySession = async (sessionId) => {
|
||||||
|
try {
|
||||||
|
const client = sessions.get(sessionId)
|
||||||
|
if (!client) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
client.pupPage?.removeAllListeners('close')
|
||||||
|
client.pupPage?.removeAllListeners('error')
|
||||||
|
try {
|
||||||
|
await terminateWebSocketServer(sessionId)
|
||||||
|
} catch (error) {
|
||||||
|
logger.error({ sessionId, err: error }, 'Failed to terminate WebSocket server')
|
||||||
|
}
|
||||||
|
await client.destroy()
|
||||||
|
// Wait 10 secs for client.pupBrowser to be disconnected
|
||||||
|
let maxDelay = 0
|
||||||
|
while (client.pupBrowser?.isConnected() && (maxDelay < 10)) {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||||
|
maxDelay++
|
||||||
|
}
|
||||||
|
sessions.delete(sessionId)
|
||||||
|
} catch (error) {
|
||||||
|
logger.error({ sessionId, err: error }, 'Failed to stop session')
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const deleteSession = async (sessionId, validation) => {
|
const deleteSession = async (sessionId, validation) => {
|
||||||
try {
|
try {
|
||||||
const client = sessions.get(sessionId)
|
const client = sessions.get(sessionId)
|
||||||
|
|
@ -554,5 +581,6 @@ module.exports = {
|
||||||
validateSession,
|
validateSession,
|
||||||
deleteSession,
|
deleteSession,
|
||||||
reloadSession,
|
reloadSession,
|
||||||
flushSessions
|
flushSessions,
|
||||||
|
destroySession
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,10 @@ const doc = {
|
||||||
success: true,
|
success: true,
|
||||||
message: 'Session initiated successfully'
|
message: 'Session initiated successfully'
|
||||||
},
|
},
|
||||||
|
StopSessionResponse: {
|
||||||
|
success: true,
|
||||||
|
message: 'Session stopped successfully'
|
||||||
|
},
|
||||||
StatusSessionResponse: {
|
StatusSessionResponse: {
|
||||||
success: true,
|
success: true,
|
||||||
state: 'CONNECTED',
|
state: 'CONNECTED',
|
||||||
|
|
|
||||||
84
swagger.json
84
swagger.json
|
|
@ -220,6 +220,74 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/session/stop/{sessionId}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Session"
|
||||||
|
],
|
||||||
|
"summary": "Stop session",
|
||||||
|
"description": "Stops a session for the given session ID.",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "sessionId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "Unique identifier for the session (alphanumeric and - allowed)",
|
||||||
|
"example": "f8377d8d-a589-4242-9ba6-9486a04ef80c"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Status of the stopped session.",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/StopSessionResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden.",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ForbiddenResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"description": "Unprocessable Entity.",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Server failure.",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/session/status/{sessionId}": {
|
"/session/status/{sessionId}": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
|
|
@ -11571,6 +11639,22 @@
|
||||||
"name": "StartSessionResponse"
|
"name": "StartSessionResponse"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"StopSessionResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"success": {
|
||||||
|
"type": "boolean",
|
||||||
|
"example": true
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Session stopped successfully"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"xml": {
|
||||||
|
"name": "StopSessionResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
"StatusSessionResponse": {
|
"StatusSessionResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue