Skip to content

Commit

Permalink
Merge pull request #91 from avoylenko/qr-endpoints
Browse files Browse the repository at this point in the history
Add QR endpoints
  • Loading branch information
chrishubert authored Sep 21, 2023
2 parents fa889b4 + d43b033 commit b64c4f0
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 5 deletions.
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"dotenv": "^16.3.1",
"express": "^4.18.2",
"express-rate-limit": "^6.9.0",
"qr-image": "^3.2.0",
"qrcode-terminal": "^0.12.0",
"swagger-ui-express": "^4.6.3",
"whatsapp-web.js": "https://github.com/Julzk/whatsapp-web.js/tarball/jkr_hotfix_8"
Expand Down
94 changes: 93 additions & 1 deletion src/controllers/sessionController.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

const { setupSession, deleteSession, validateSession, flushSessions } = require('../sessions')
const qr = require('qr-image')
const { setupSession, deleteSession, validateSession, flushSessions, sessions } = require('../sessions')
const { sendErrorResponse, waitForNestedObject } = require('../utils')

/**
Expand Down Expand Up @@ -102,6 +103,95 @@ const statusSession = async (req, res) => {
}
}

/**
* QR code of the session with 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 start.
* @returns {Promise<void>}
* @throws {Error} If there was an error getting status of the session.
*/
const sessionQrCode = async (req, res) => {
// #swagger.summary = 'Get session QR code'
// #swagger.description = 'QR code of the session with the given session ID.'
try {
const sessionId = req.params.sessionId
const session = sessions.get(sessionId)
if (!session) {
return res.json({ success: false, message: 'session_not_found' })
}
if (session.qr) {
return res.json({ success: true, qr: session.qr })
}
return res.json({ success: false, message: 'qr code not ready or already scanned' })
} catch (error) {
console.log('sessionQrCode ERROR', error)
/* #swagger.responses[500] = {
description: "Server Failure.",
content: {
"application/json": {
schema: { "$ref": "#/definitions/ErrorResponse" }
}
}
}
*/
sendErrorResponse(res, 500, error.message)
}
}

/**
* QR code as image of the session with 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 start.
* @returns {Promise<void>}
* @throws {Error} If there was an error getting status of the session.
*/
const sessionQrCodeImage = async (req, res) => {
// #swagger.summary = 'Get session QR code as image'
// #swagger.description = 'QR code as image of the session with the given session ID.'
try {
const sessionId = req.params.sessionId
const session = sessions.get(sessionId)
if (!session) {
return res.json({ success: false, message: 'session_not_found' })
}
if (session.qr) {
const qrImage = qr.image(session.qr)
/* #swagger.responses[200] = {
description: "QR image.",
content: {
"image/png": {}
}
}
*/
res.writeHead(200, {
'Content-Type': 'image/png'
})
return qrImage.pipe(res)
}
return res.json({ success: false, message: 'qr code not ready or already scanned' })
} catch (error) {
console.log('sessionQrCodeImage ERROR', error)
/* #swagger.responses[500] = {
description: "Server Failure.",
content: {
"application/json": {
schema: { "$ref": "#/definitions/ErrorResponse" }
}
}
}
*/
sendErrorResponse(res, 500, error.message)
}
}

/**
* Terminates the session with the given session ID.
*
Expand Down Expand Up @@ -228,6 +318,8 @@ const terminateAllSessions = async (req, res) => {
module.exports = {
startSession,
statusSession,
sessionQrCode,
sessionQrCodeImage,
terminateSession,
terminateInactiveSessions,
terminateAllSessions
Expand Down
2 changes: 2 additions & 0 deletions src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ routes.use('/session', sessionRouter)

sessionRouter.get('/start/:sessionId', middleware.sessionNameValidation, sessionController.startSession)
sessionRouter.get('/status/:sessionId', middleware.sessionNameValidation, sessionController.statusSession)
sessionRouter.get('/qr/:sessionId', middleware.sessionNameValidation, sessionController.sessionQrCode)
sessionRouter.get('/qr/:sessionId/image', middleware.sessionNameValidation, sessionController.sessionQrCodeImage)
sessionRouter.get('/terminate/:sessionId', middleware.sessionNameValidation, sessionController.terminateSession)
sessionRouter.get('/terminateInactive', sessionController.terminateInactiveSessions)
sessionRouter.get('/terminateAll', sessionController.terminateAllSessions)
Expand Down
10 changes: 6 additions & 4 deletions src/sessions.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,12 +259,14 @@ const initializeEvents = (client, sessionId) => {
})
})

checkIfEventisEnabled('qr')
.then(_ => {
client.on('qr', (qr) => {
client.on('qr', (qr) => {
// inject qr code into session
client.qr = qr
checkIfEventisEnabled('qr')
.then(_ => {
triggerWebhook(sessionWebhook, sessionId, 'qr', { qr })
})
})
})

checkIfEventisEnabled('ready')
.then(_ => {
Expand Down
125 changes: 125 additions & 0 deletions swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,131 @@
]
}
},
"/session/qr/{sessionId}": {
"get": {
"tags": [
"Session"
],
"summary": "Get session QR code",
"description": "QR code of the session 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": "OK"
},
"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/qr/{sessionId}/image": {
"get": {
"tags": [
"Session"
],
"summary": "Get session QR code as image",
"description": "QR code as image of the session 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": "QR 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": []
}
]
}
},
"/session/terminate/{sessionId}": {
"get": {
"tags": [
Expand Down

0 comments on commit b64c4f0

Please sign in to comment.