From b422374639f4c98fb4f22fd2c6918c4c6e365e72 Mon Sep 17 00:00:00 2001 From: Anton Voylenko Date: Sun, 23 Mar 2025 01:19:20 +0200 Subject: [PATCH] feat: support puppage screenshots --- src/controllers/sessionController.js | 51 +++++++++++++++++++++- src/routes.js | 1 + swagger.json | 64 ++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/src/controllers/sessionController.js b/src/controllers/sessionController.js index 8131624..61c2fe0 100644 --- a/src/controllers/sessionController.js +++ b/src/controllers/sessionController.js @@ -363,6 +363,54 @@ const getSessions = async (req, res) => { return res.json({ success: true, result: Array.from(sessions.keys()) }) } +/** + * Get pupPage screenshot image + * + * @function + * @async + * @param {Object} req - The request object. + * @param {Object} res - The response object. + * @returns {Promise} - A Promise that resolves with a JSON object containing a success flag and the result of the operation. + * @throws {Error} If there is an issue setting the profile picture, an error will be thrown. + */ +const getPageScreenshot = async (req, res) => { + // #swagger.summary = 'Get page screenshot' + // #swagger.description = 'Screenshot of the client with the given session ID.' + const sessionId = req.params.sessionId + try { + const session = sessions.get(sessionId) + if (!session) { + return res.json({ success: false, message: 'session_not_found' }) + } + + if (!session.pupPage) { + return res.json({ success: false, message: 'page_not_ready' }) + } + + const pngBase64String = await session.pupPage.screenshot({ + fullPage: true, + encoding: 'base64', + type: 'png' + }) + + /* #swagger.responses[200] = { + description: "Screenshot image.", + content: { + "image/png": {} + } + } + */ + res.writeHead(200, { + 'Content-Type': 'image/png' + }) + res.write(Buffer.from(pngBase64String, 'base64')) + res.end() + } catch (error) { + logger.error({ sessionId, err: error }, 'Failed to get page screenshot') + sendErrorResponse(res, 500, error.message) + } +} + module.exports = { startSession, statusSession, @@ -373,5 +421,6 @@ module.exports = { terminateSession, terminateInactiveSessions, terminateAllSessions, - getSessions + getSessions, + getPageScreenshot } diff --git a/src/routes.js b/src/routes.js index fc63b84..ab58957 100644 --- a/src/routes.js +++ b/src/routes.js @@ -46,6 +46,7 @@ sessionRouter.get('/restart/:sessionId', middleware.sessionNameValidation, sessi sessionRouter.get('/terminate/:sessionId', middleware.sessionNameValidation, sessionController.terminateSession) sessionRouter.get('/terminateInactive', sessionController.terminateInactiveSessions) sessionRouter.get('/terminateAll', sessionController.terminateAllSessions) +sessionRouter.get('/getPageScreenshot/:sessionId', middleware.sessionNameValidation, sessionController.getPageScreenshot) /** * ================ diff --git a/swagger.json b/swagger.json index 5c258ed..8545632 100644 --- a/swagger.json +++ b/swagger.json @@ -741,6 +741,70 @@ ] } }, + "/session/getPageScreenshot/{sessionId}": { + "get": { + "tags": [ + "Session" + ], + "summary": "Get page screenshot", + "description": "Screenshot of the client with 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": "Screenshot image.", + "content": { + "image/png": {} + } + }, + "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": [] + } + ] + } + }, "/client/getClassInfo/{sessionId}": { "get": { "tags": [