feat: add ability to run any method

This commit is contained in:
Anton Voylenko 2025-08-10 15:19:07 +03:00
commit b7d1e21739
6 changed files with 798 additions and 22 deletions

View file

@ -448,6 +448,66 @@ const changeLabels = async (req, res) => {
} }
} }
/**
* Executes a method on the chat associated with the given sessionId.
*
* @async
* @function
* @param {Object} req - The HTTP request object containing the chatId and sessionId.
* @param {string} req.body.chatId - The unique identifier of the chat.
* @param {string} req.params.sessionId - The unique identifier of the session associated with the client to use.
* @param {Object} res - The HTTP response object.
* @returns {Promise<Object>} - A Promise that resolves with a JSON object containing a success flag and the result of the operation.
* @throws {Error} - If an error occurs during the operation, it is thrown and handled by the catch block.
*/
const runMethod = async (req, res) => {
/*
#swagger.summary = 'Execute a method on the chat'
#swagger.description = 'Execute a method on the chat and return the result'
#swagger.requestBody = {
required: true,
schema: {
type: 'object',
properties: {
chatId: {
type: 'string',
description: 'The chat id which contains the message',
example: '6281288888888@c.us'
},
method: {
type: 'string',
description: 'The name of the method to execute',
example: 'getLabels'
},
options: {
anyOf: [
{ type: 'object' },
{ type: 'string' }
],
description: 'The options to pass to the method',
}
}
},
}
*/
try {
const { chatId, method, options } = req.body
const client = sessions.get(req.params.sessionId)
const chat = await client.getChatById(chatId)
if (!chat) {
sendErrorResponse(res, 404, 'Chat not Found')
return
}
if (typeof chat[method] !== 'function') {
throw new Error('Method is not implemented')
}
const result = options ? await chat[method](options) : await chat[method]()
res.json({ success: true, data: result })
} catch (error) {
sendErrorResponse(res, 500, error.message)
}
}
module.exports = { module.exports = {
getClassInfo, getClassInfo,
clearMessages, clearMessages,
@ -461,5 +521,6 @@ module.exports = {
markUnread, markUnread,
syncHistory, syncHistory,
getLabels, getLabels,
changeLabels changeLabels,
runMethod
} }

View file

@ -1855,6 +1855,55 @@ const getContactLidAndPhone = async (req, res) => {
} }
} }
/**
* Executes a method on the client associated with the given sessionId.
*
* @async
* @function
* @param {Object} req - The HTTP request object containing the chatId and sessionId.
* @param {string} req.params.sessionId - The unique identifier of the session associated with the client to use.
* @param {Object} res - The HTTP response object.
* @returns {Promise<Object>} - A Promise that resolves with a JSON object containing a success flag and the result of the operation.
* @throws {Error} - If an error occurs during the operation, it is thrown and handled by the catch block.
*/
const runMethod = async (req, res) => {
/*
#swagger.summary = 'Execute a method on the client'
#swagger.description = 'Execute a method on the client and return the result'
#swagger.requestBody = {
required: true,
schema: {
type: 'object',
properties: {
method: {
type: 'string',
description: 'The name of the method to execute',
example: 'getLabels'
},
options: {
anyOf: [
{ type: 'object' },
{ type: 'string' }
],
description: 'The options to pass to the method',
}
}
},
}
*/
try {
const { method, options } = req.body
const client = sessions.get(req.params.sessionId)
if (typeof client[method] !== 'function') {
throw new Error('Method is not implemented')
}
const result = options ? await client[method](options) : await client[method]()
res.json({ success: true, data: result })
} catch (error) {
sendErrorResponse(res, 500, error.message)
}
}
module.exports = { module.exports = {
getClassInfo, getClassInfo,
acceptInvite, acceptInvite,
@ -1904,5 +1953,6 @@ module.exports = {
openChatWindowAt, openChatWindowAt,
resetState, resetState,
setBackgroundSync, setBackgroundSync,
getContactLidAndPhone getContactLidAndPhone,
runMethod
} }

View file

@ -680,6 +680,63 @@ const rejectGroupMembershipRequests = async (req, res) => {
} }
} }
/**
* Executes a method on the group associated with the given sessionId.
*
* @async
* @function
* @param {Object} req - The HTTP request object containing the chatId and sessionId.
* @param {string} req.body.chatId - The unique identifier of the chat.
* @param {string} req.params.sessionId - The unique identifier of the session associated with the client to use.
* @param {Object} res - The HTTP response object.
* @returns {Promise<Object>} - A Promise that resolves with a JSON object containing a success flag and the result of the operation.
* @throws {Error} - If an error occurs during the operation, it is thrown and handled by the catch block.
*/
const runMethod = async (req, res) => {
/*
#swagger.summary = 'Execute a method on the group'
#swagger.description = 'Execute a method on the group and return the result'
#swagger.requestBody = {
required: true,
schema: {
type: 'object',
properties: {
chatId: {
type: 'string',
description: 'Unique WhatsApp id for the given chat group',
example: 'XXXXXXXXXX@g.us'
},
method: {
type: 'string',
description: 'The name of the method to execute',
example: 'getLabels'
},
options: {
anyOf: [
{ type: 'object' },
{ type: 'string' }
],
description: 'The options to pass to the method',
}
}
},
}
*/
try {
const { chatId, method, options } = req.body
const client = sessions.get(req.params.sessionId)
const chat = await client.getChatById(chatId)
if (!chat.isGroup) { throw new Error('The chat is not a group') }
if (typeof chat[method] !== 'function') {
throw new Error('Method is not implemented')
}
const result = options ? await chat[method](options) : await chat[method]()
res.json({ success: true, data: result })
} catch (error) {
sendErrorResponse(res, 500, error.message)
}
}
module.exports = { module.exports = {
getClassInfo, getClassInfo,
addParticipants, addParticipants,
@ -697,5 +754,6 @@ module.exports = {
deletePicture, deletePicture,
getGroupMembershipRequests, getGroupMembershipRequests,
approveGroupMembershipRequests, approveGroupMembershipRequests,
rejectGroupMembershipRequests rejectGroupMembershipRequests,
runMethod
} }

View file

@ -735,6 +735,68 @@ const getContact = async (req, res) => {
} }
} }
/**
* Executes a method on the message associated with the given sessionId.
*
* @async
* @function
* @param {Object} req - The HTTP request object containing the chatId and sessionId.
* @param {string} req.body.chatId - The unique identifier of the chat.
* @param {string} req.params.sessionId - The unique identifier of the session associated with the client to use.
* @param {Object} res - The HTTP response object.
* @returns {Promise<Object>} - A Promise that resolves with a JSON object containing a success flag and the result of the operation.
* @throws {Error} - If an error occurs during the operation, it is thrown and handled by the catch block.
*/
const runMethod = async (req, res) => {
/*
#swagger.summary = 'Execute a method on the message'
#swagger.description = 'Execute a method on the message and return the result'
#swagger.requestBody = {
required: true,
schema: {
type: 'object',
properties: {
chatId: {
type: 'string',
description: 'The chat id which contains the message',
example: '6281288888888@c.us'
},
messageId: {
type: 'string',
description: 'Unique WhatsApp identifier for the message',
example: 'ABCDEF999999999'
},
method: {
type: 'string',
description: 'The name of the method to execute',
example: 'getInfo'
},
options: {
anyOf: [
{ type: 'object' },
{ type: 'string' }
],
description: 'The options to pass to the method',
}
}
},
}
*/
try {
const { messageId, chatId, method, options } = req.body
const client = sessions.get(req.params.sessionId)
const message = await _getMessageById(client, messageId, chatId)
if (!message) { throw new Error('Message not found') }
if (typeof message[method] !== 'function') {
throw new Error('Method is not implemented')
}
const result = options ? await message[method](options) : await message[method]()
res.json({ success: true, data: result })
} catch (error) {
sendErrorResponse(res, 500, error.message)
}
}
module.exports = { module.exports = {
getClassInfo, getClassInfo,
deleteMessage, deleteMessage,
@ -753,5 +815,6 @@ module.exports = {
getReactions, getReactions,
getGroupMentions, getGroupMentions,
edit, edit,
getContact getContact,
runMethod
} }

View file

@ -109,6 +109,7 @@ clientRouter.post('/openChatWindowAt/:sessionId', [middleware.sessionNameValidat
clientRouter.post('/resetState/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], clientController.resetState) clientRouter.post('/resetState/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], clientController.resetState)
clientRouter.post('/setBackgroundSync/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], clientController.setBackgroundSync) clientRouter.post('/setBackgroundSync/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], clientController.setBackgroundSync)
clientRouter.post('/getContactLidAndPhone/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], clientController.getContactLidAndPhone) clientRouter.post('/getContactLidAndPhone/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], clientController.getContactLidAndPhone)
clientRouter.post('/runMethod/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], clientController.runMethod)
/** /**
* ================ * ================
@ -133,6 +134,7 @@ chatRouter.post('/markUnread/:sessionId', [middleware.sessionNameValidation, mid
chatRouter.post('/syncHistory/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], chatController.syncHistory) chatRouter.post('/syncHistory/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], chatController.syncHistory)
chatRouter.post('/getLabels/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], chatController.getLabels) chatRouter.post('/getLabels/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], chatController.getLabels)
chatRouter.post('/changeLabels/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], chatController.changeLabels) chatRouter.post('/changeLabels/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], chatController.changeLabels)
chatRouter.post('/runMethod/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], chatController.runMethod)
/** /**
* ================ * ================
@ -161,6 +163,7 @@ groupChatRouter.post('/deletePicture/:sessionId', [middleware.sessionNameValidat
groupChatRouter.post('/getGroupMembershipRequests/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], groupChatController.getGroupMembershipRequests) groupChatRouter.post('/getGroupMembershipRequests/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], groupChatController.getGroupMembershipRequests)
groupChatRouter.post('/approveGroupMembershipRequests/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], groupChatController.approveGroupMembershipRequests) groupChatRouter.post('/approveGroupMembershipRequests/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], groupChatController.approveGroupMembershipRequests)
groupChatRouter.post('/rejectGroupMembershipRequests/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], groupChatController.rejectGroupMembershipRequests) groupChatRouter.post('/rejectGroupMembershipRequests/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], groupChatController.rejectGroupMembershipRequests)
groupChatRouter.post('/runMethod/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], groupChatController.runMethod)
/** /**
* ================ * ================
@ -190,6 +193,7 @@ messageRouter.post('/getReactions/:sessionId', [middleware.sessionNameValidation
messageRouter.post('/getGroupMentions/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.getGroupMentions) messageRouter.post('/getGroupMentions/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.getGroupMentions)
messageRouter.post('/edit/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.edit) messageRouter.post('/edit/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.edit)
messageRouter.post('/getContact/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.getContact) messageRouter.post('/getContact/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.getContact)
messageRouter.post('/runMethod/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.runMethod)
/** /**
* ================ * ================

View file

@ -3732,15 +3732,21 @@
"schema": { "schema": {
"type": "object", "type": "object",
"properties": { "properties": {
"userIds": { "method": {
"type": "array", "type": "string",
"items": { "description": "The name of the method to execute",
"type": "string", "example": "getLabels"
"description": "The unique identifier of the user" },
}, "options": {
"example": [ "anyOf": [
"6281288888888@c.us" {
] "type": "object"
},
{
"type": "string"
}
],
"description": "The options to pass to the method"
} }
} }
} }
@ -3749,15 +3755,21 @@
"schema": { "schema": {
"type": "object", "type": "object",
"properties": { "properties": {
"userIds": { "method": {
"type": "array", "type": "string",
"items": { "description": "The name of the method to execute",
"type": "string", "example": "getLabels"
"description": "The unique identifier of the user" },
}, "options": {
"example": [ "anyOf": [
"6281288888888@c.us" {
] "type": "object"
},
{
"type": "string"
}
],
"description": "The options to pass to the method"
} }
} }
} }
@ -5589,6 +5601,128 @@
} }
} }
}, },
"/client/runMethod/{sessionId}": {
"post": {
"tags": [
"Client"
],
"summary": "Execute a method on the client",
"description": "Execute a method on the client and return the result",
"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"
}
}
}
},
"404": {
"description": "Not Found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NotFoundResponse"
}
}
}
},
"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": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"method": {
"type": "string",
"description": "The name of the method to execute",
"example": "getLabels"
},
"options": {
"anyOf": [
{
"type": "object"
},
{
"type": "string"
}
],
"description": "The options to pass to the method"
}
}
}
},
"application/xml": {
"schema": {
"type": "object",
"properties": {
"method": {
"type": "string",
"description": "The name of the method to execute",
"example": "getLabels"
},
"options": {
"anyOf": [
{
"type": "object"
},
{
"type": "string"
}
],
"description": "The options to pass to the method"
}
}
}
}
}
}
}
},
"/chat/getClassInfo/{sessionId}": { "/chat/getClassInfo/{sessionId}": {
"post": { "post": {
"tags": [ "tags": [
@ -6921,6 +7055,138 @@
} }
} }
}, },
"/chat/runMethod/{sessionId}": {
"post": {
"tags": [
"Chat"
],
"summary": "Execute a method on the chat",
"description": "Execute a method on the chat and return the result",
"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"
}
}
}
},
"404": {
"description": "Not Found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NotFoundResponse"
}
}
}
},
"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": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "The chat id which contains the message",
"example": "6281288888888@c.us"
},
"method": {
"type": "string",
"description": "The name of the method to execute",
"example": "getLabels"
},
"options": {
"anyOf": [
{
"type": "object"
},
{
"type": "string"
}
],
"description": "The options to pass to the method"
}
}
}
},
"application/xml": {
"schema": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "The chat id which contains the message",
"example": "6281288888888@c.us"
},
"method": {
"type": "string",
"description": "The name of the method to execute",
"example": "getLabels"
},
"options": {
"anyOf": [
{
"type": "object"
},
{
"type": "string"
}
],
"description": "The options to pass to the method"
}
}
}
}
}
}
}
},
"/groupChat/getClassInfo/{sessionId}": { "/groupChat/getClassInfo/{sessionId}": {
"post": { "post": {
"tags": [ "tags": [
@ -8799,6 +9065,138 @@
} }
} }
}, },
"/groupChat/runMethod/{sessionId}": {
"post": {
"tags": [
"Group Chat"
],
"summary": "Execute a method on the group",
"description": "Execute a method on the group and return the result",
"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"
}
}
}
},
"404": {
"description": "Not Found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NotFoundResponse"
}
}
}
},
"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": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "Unique WhatsApp id for the given chat group",
"example": "XXXXXXXXXX@g.us"
},
"method": {
"type": "string",
"description": "The name of the method to execute",
"example": "getLabels"
},
"options": {
"anyOf": [
{
"type": "object"
},
{
"type": "string"
}
],
"description": "The options to pass to the method"
}
}
}
},
"application/xml": {
"schema": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "Unique WhatsApp id for the given chat group",
"example": "XXXXXXXXXX@g.us"
},
"method": {
"type": "string",
"description": "The name of the method to execute",
"example": "getLabels"
},
"options": {
"anyOf": [
{
"type": "object"
},
{
"type": "string"
}
],
"description": "The options to pass to the method"
}
}
}
}
}
}
}
},
"/message/getClassInfo/{sessionId}": { "/message/getClassInfo/{sessionId}": {
"post": { "post": {
"tags": [ "tags": [
@ -10840,6 +11238,148 @@
} }
} }
}, },
"/message/runMethod/{sessionId}": {
"post": {
"tags": [
"Message"
],
"summary": "Execute a method on the message",
"description": "Execute a method on the message and return the result",
"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"
}
}
}
},
"404": {
"description": "Not Found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NotFoundResponse"
}
}
}
},
"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": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "The chat id which contains the message",
"example": "6281288888888@c.us"
},
"messageId": {
"type": "string",
"description": "Unique WhatsApp identifier for the message",
"example": "ABCDEF999999999"
},
"method": {
"type": "string",
"description": "The name of the method to execute",
"example": "getInfo"
},
"options": {
"anyOf": [
{
"type": "object"
},
{
"type": "string"
}
],
"description": "The options to pass to the method"
}
}
}
},
"application/xml": {
"schema": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "The chat id which contains the message",
"example": "6281288888888@c.us"
},
"messageId": {
"type": "string",
"description": "Unique WhatsApp identifier for the message",
"example": "ABCDEF999999999"
},
"method": {
"type": "string",
"description": "The name of the method to execute",
"example": "getInfo"
},
"options": {
"anyOf": [
{
"type": "object"
},
{
"type": "string"
}
],
"description": "The options to pass to the method"
}
}
}
}
}
}
}
},
"/contact/getClassInfo/{sessionId}": { "/contact/getClassInfo/{sessionId}": {
"post": { "post": {
"tags": [ "tags": [