Merge pull request #570 from codigoencasa/545-cuando-se-activa-fallback-dentro-de-un-addanswer-con-capture-true-no-espera-el-capture-true-y-se-salta-al-siguiente-addanswer

fix(cli):  refactor fallback in child flow
This commit is contained in:
Leifer Mendez
2023-01-28 16:53:52 +01:00
committed by GitHub
10 changed files with 345 additions and 140 deletions

View File

@@ -34,6 +34,13 @@ Entiende más a fondo sus funcionalidades explicadas en nuestra documentación.
<!-- readme: collaborators,contributors -start --> <!-- readme: collaborators,contributors -start -->
<table> <table>
<tr> <tr>
<td align="center">
<a href="https://github.com/cheveguerra">
<img src="https://avatars.githubusercontent.com/u/5891114?v=4" width="50;" alt="cheveguerra"/>
<br />
<sub><b>Jose Alberto Guerra Ugalde</b></sub>
</a>
</td>
<td align="center"> <td align="center">
<a href="https://github.com/leifermendez"> <a href="https://github.com/leifermendez">
<img src="https://avatars.githubusercontent.com/u/15802366?v=4" width="50;" alt="leifermendez"/> <img src="https://avatars.githubusercontent.com/u/15802366?v=4" width="50;" alt="leifermendez"/>
@@ -62,6 +69,21 @@ Entiende más a fondo sus funcionalidades explicadas en nuestra documentación.
<sub><b>Leifer Mendez</b></sub> <sub><b>Leifer Mendez</b></sub>
</a> </a>
</td> </td>
<td align="center">
<a href="https://github.com/danielcasta0398">
<img src="https://avatars.githubusercontent.com/u/98791147?v=4" width="50;" alt="danielcasta0398"/>
<br />
<sub><b>Juan Daniel Castaño</b></sub>
</a>
</td></tr>
<tr>
<td align="center">
<a href="https://github.com/marianarolfo">
<img src="https://avatars.githubusercontent.com/u/68322254?v=4" width="50;" alt="marianarolfo"/>
<br />
<sub><b>Null</b></sub>
</a>
</td>
<td align="center"> <td align="center">
<a href="https://github.com/HKong31"> <a href="https://github.com/HKong31">
<img src="https://avatars.githubusercontent.com/u/113340082?v=4" width="50;" alt="HKong31"/> <img src="https://avatars.githubusercontent.com/u/113340082?v=4" width="50;" alt="HKong31"/>
@@ -75,8 +97,14 @@ Entiende más a fondo sus funcionalidades explicadas en nuestra documentación.
<br /> <br />
<sub><b>Zvi</b></sub> <sub><b>Zvi</b></sub>
</a> </a>
</td></tr> </td>
<tr> <td align="center">
<a href="https://github.com/JosephVTX">
<img src="https://avatars.githubusercontent.com/u/91026290?v=4" width="50;" alt="JosephVTX"/>
<br />
<sub><b>Joseph Vega Callupe</b></sub>
</a>
</td>
<td align="center"> <td align="center">
<a href="https://github.com/Gonzalito87"> <a href="https://github.com/Gonzalito87">
<img src="https://avatars.githubusercontent.com/u/100331586?v=4" width="50;" alt="Gonzalito87"/> <img src="https://avatars.githubusercontent.com/u/100331586?v=4" width="50;" alt="Gonzalito87"/>
@@ -84,6 +112,21 @@ Entiende más a fondo sus funcionalidades explicadas en nuestra documentación.
<sub><b>Null</b></sub> <sub><b>Null</b></sub>
</a> </a>
</td> </td>
<td align="center">
<a href="https://github.com/jlferrete">
<img src="https://avatars.githubusercontent.com/u/36698913?v=4" width="50;" alt="jlferrete"/>
<br />
<sub><b>Jose Luis Ferrete Olarte</b></sub>
</a>
</td></tr>
<tr>
<td align="center">
<a href="https://github.com/6rak0">
<img src="https://avatars.githubusercontent.com/u/12260031?v=4" width="50;" alt="6rak0"/>
<br />
<sub><b>Null</b></sub>
</a>
</td>
<td align="center"> <td align="center">
<a href="https://github.com/tonyvazgar"> <a href="https://github.com/tonyvazgar">
<img src="https://avatars.githubusercontent.com/u/21047090?v=4" width="50;" alt="tonyvazgar"/> <img src="https://avatars.githubusercontent.com/u/21047090?v=4" width="50;" alt="tonyvazgar"/>
@@ -91,13 +134,6 @@ Entiende más a fondo sus funcionalidades explicadas en nuestra documentación.
<sub><b>Luis Antonio Vázquez García</b></sub> <sub><b>Luis Antonio Vázquez García</b></sub>
</a> </a>
</td> </td>
<td align="center">
<a href="https://github.com/ulisesvina">
<img src="https://avatars.githubusercontent.com/u/20508563?v=4" width="50;" alt="ulisesvina"/>
<br />
<sub><b>Ulises Viña</b></sub>
</a>
</td>
<td align="center"> <td align="center">
<a href="https://github.com/rrruuuyyy"> <a href="https://github.com/rrruuuyyy">
<img src="https://avatars.githubusercontent.com/u/33061671?v=4" width="50;" alt="rrruuuyyy"/> <img src="https://avatars.githubusercontent.com/u/33061671?v=4" width="50;" alt="rrruuuyyy"/>

118
__test__/05-case.test.js Normal file
View File

@@ -0,0 +1,118 @@
const { test } = require('uvu')
const assert = require('uvu/assert')
const MOCK_DB = require('../packages/database/src/mock')
const PROVIDER_DB = require('../packages/provider/src/mock')
const {
addKeyword,
createBot,
createFlow,
createProvider,
} = require('../packages/bot/index')
/**
* Falsear peticion async
* @param {*} fakeData
* @returns
*/
const fakeHTTP = async (fakeData = []) => {
await delay(5)
const data = fakeData.map((u, i) => ({ body: `${i + 1} ${u}` }))
return Promise.resolve(data)
}
test(`[Caso - 05] Continuar Flujo (continueFlow)`, async () => {
const MOCK_VALUES = [
'¿CUal es tu email?',
'Continuamos....',
'¿Cual es tu edad?',
]
const provider = createProvider(PROVIDER_DB)
const database = new MOCK_DB()
const flujoPrincipal = addKeyword(['hola'])
.addAnswer(
MOCK_VALUES[0],
{
capture: true,
},
async (ctx, { flowDynamic, fallBack }) => {
const validation = ctx.body.includes('@')
if (validation) {
const getDataFromApi = await fakeHTTP([
'Gracias por tu email se ha validado de manera correcta',
])
return flowDynamic(getDataFromApi)
}
return fallBack(validation)
}
)
.addAnswer(MOCK_VALUES[1])
.addAnswer(
MOCK_VALUES[2],
{ capture: true },
async (ctx, { flowDynamic, fallBack }) => {
if (ctx.body !== '18') {
await delay(50)
return fallBack(false, 'Ups creo que no eres mayor de edad')
}
return flowDynamic('Bien tu edad es correcta!')
}
)
.addAnswer('Puedes pasar')
createBot({
database,
flow: createFlow([flujoPrincipal]),
provider,
})
provider.delaySendMessage(0, 'message', {
from: '000',
body: 'hola',
})
provider.delaySendMessage(10, 'message', {
from: '000',
body: 'this is not email value',
})
provider.delaySendMessage(20, 'message', {
from: '000',
body: 'test@test.com',
})
provider.delaySendMessage(90, 'message', {
from: '000',
body: '20',
})
provider.delaySendMessage(200, 'message', {
from: '000',
body: '18',
})
await delay(1200)
const getHistory = database.listHistory.map((i) => i.answer)
assert.is(MOCK_VALUES[0], getHistory[0])
assert.is('this is not email value', getHistory[1])
assert.is(MOCK_VALUES[0], getHistory[2])
assert.is('test@test.com', getHistory[3])
assert.is(
'1 Gracias por tu email se ha validado de manera correcta',
getHistory[4]
)
assert.is(MOCK_VALUES[1], getHistory[5])
assert.is(MOCK_VALUES[2], getHistory[6])
assert.is('20', getHistory[7])
assert.is('Ups creo que no eres mayor de edad', getHistory[8])
assert.is('18', getHistory[9])
assert.is('Bien tu edad es correcta!', getHistory[10])
assert.is('Puedes pasar', getHistory[11])
})
test.run()
function delay(ms) {
return new Promise((res) => setTimeout(res, ms))
}

View File

@@ -80,7 +80,6 @@
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^8.5.0",
"fs-extra": "^11.1.0", "fs-extra": "^11.1.0",
"git-cz": "^4.9.0", "git-cz": "^4.9.0",
"got": "11.8.3",
"husky": "^8.0.2", "husky": "^8.0.2",
"mime-types": "^2.1.35", "mime-types": "^2.1.35",
"only-allow": "^1.1.1", "only-allow": "^1.1.1",

View File

@@ -71,8 +71,8 @@ class CoreClass {
logger.log(`[handleMsg]: `, messageCtxInComming) logger.log(`[handleMsg]: `, messageCtxInComming)
const { body, from } = messageCtxInComming const { body, from } = messageCtxInComming
let msgToSend = [] let msgToSend = []
let fallBackFlag = false
let endFlowFlag = false let endFlowFlag = false
let fallBackFlag = false
if (this.generalArgs.blackList.includes(from)) return if (this.generalArgs.blackList.includes(from)) return
if (!body) return if (!body) return
if (!body.length) return if (!body.length) return
@@ -105,11 +105,23 @@ class CoreClass {
return return
} }
// 📄 Esta funcion se encarga de enviar un array de mensajes dentro de este ctx // 📄 Continuar con el siguiente flujo
const sendFlow = async (messageToSend, numberOrId) => { const continueFlow = async () => {
// [1 Paso] esto esta bien! const cotinueMessage =
this.flowClass.find(refToContinue?.ref, true) || []
sendFlow(cotinueMessage, from, { continue: true })
return
}
// 📄 Esta funcion se encarga de enviar un array de mensajes dentro de este ctx
const sendFlow = async (
messageToSend,
numberOrId,
options = { continue: false }
) => {
if (!options.continue && prevMsg?.options?.capture)
await cbEveryCtx(prevMsg?.ref)
if (prevMsg?.options?.capture) await cbEveryCtx(prevMsg?.ref)
const queue = [] const queue = []
for (const ctxMessage of messageToSend) { for (const ctxMessage of messageToSend) {
if (endFlowFlag) return if (endFlowFlag) return
@@ -127,11 +139,13 @@ class CoreClass {
} }
// 📄 [options: fallBack]: esta funcion se encarga de repetir el ultimo mensaje // 📄 [options: fallBack]: esta funcion se encarga de repetir el ultimo mensaje
const fallBack = async () => { const fallBack = async (next = false, message = null) => {
fallBackFlag = true
await this.sendProviderAndSave(from, refToContinue)
QueuePrincipal.queue = [] QueuePrincipal.queue = []
return refToContinue if (next) return continueFlow()
return this.sendProviderAndSave(from, {
...prevMsg,
answer: message ?? prevMsg.answer,
})
} }
// 📄 [options: flowDynamic]: esta funcion se encarga de responder un array de respuesta esta limitado a 5 mensajes // 📄 [options: flowDynamic]: esta funcion se encarga de responder un array de respuesta esta limitado a 5 mensajes
@@ -141,8 +155,7 @@ class CoreClass {
listMsg = [], listMsg = [],
optListMsg = { limit: 5, fallback: false } optListMsg = { limit: 5, fallback: false }
) => { ) => {
if (!Array.isArray(listMsg)) if (!Array.isArray(listMsg)) listMsg = [listMsg]
throw new Error('Esto debe ser un ARRAY')
fallBackFlag = optListMsg.fallback fallBackFlag = optListMsg.fallback
const parseListMsg = listMsg const parseListMsg = listMsg
@@ -165,7 +178,7 @@ class CoreClass {
for (const msg of parseListMsg) { for (const msg of parseListMsg) {
await this.sendProviderAndSave(from, msg) await this.sendProviderAndSave(from, msg)
} }
return return continueFlow()
} }
// 📄 Se encarga de revisar si el contexto del mensaje tiene callback o fallback // 📄 Se encarga de revisar si el contexto del mensaje tiene callback o fallback
@@ -181,11 +194,12 @@ class CoreClass {
fallBack, fallBack,
flowDynamic, flowDynamic,
endFlow, endFlow,
continueFlow,
}) })
} }
// 📄🤘(tiene return) [options: nested(array)]: Si se tiene flujos hijos los implementa // 📄🤘(tiene return) [options: nested(array)]: Si se tiene flujos hijos los implementa
if (!fallBackFlag && prevMsg?.options?.nested?.length) { if (prevMsg?.options?.nested?.length) {
const nestedRef = prevMsg.options.nested const nestedRef = prevMsg.options.nested
const flowStandalone = nestedRef.map((f) => ({ const flowStandalone = nestedRef.map((f) => ({
...nestedRef.find((r) => r.refSerialize === f.refSerialize), ...nestedRef.find((r) => r.refSerialize === f.refSerialize),
@@ -197,12 +211,11 @@ class CoreClass {
return return
} }
// 📄🤘(tiene return) [options: capture (boolean)]: Si se tiene option boolean // 📄🤘(tiene return) Si el mensaje previo implementa capture
if (!fallBackFlag && !prevMsg?.options?.nested?.length) { if (!prevMsg?.options?.nested?.length) {
const typeCapture = typeof prevMsg?.options?.capture const typeCapture = typeof prevMsg?.options?.capture
const valueCapture = prevMsg?.options?.capture
if (['string', 'boolean'].includes(typeCapture) && valueCapture) { if (typeCapture === 'boolean' && fallBackFlag) {
msgToSend = this.flowClass.find(refToContinue?.ref, true) || [] msgToSend = this.flowClass.find(refToContinue?.ref, true) || []
sendFlow(msgToSend, from) sendFlow(msgToSend, from)
return return
@@ -228,6 +241,7 @@ class CoreClass {
} }
/** /**
* @deprecated
* @private * @private
* @param {*} message * @param {*} message
* @param {*} ref * @param {*} ref

View File

@@ -1,6 +1,6 @@
{ {
"name": "@bot-whatsapp/bot", "name": "@bot-whatsapp/bot",
"version": "0.0.73-alpha.0", "version": "0.0.84-alpha.0",
"description": "", "description": "",
"main": "./lib/bundle.bot.cjs", "main": "./lib/bundle.bot.cjs",
"scripts": { "scripts": {

View File

@@ -29,13 +29,16 @@ const flowPrincipal = addKeyword(['hola', 'alo'])
Es importante que el número **vaya acompañado de su prefijo**, en el caso de España "34". Es importante que el número **vaya acompañado de su prefijo**, en el caso de España "34".
```js ```js
createBot({ createBot(
{
flow: adapterFlow, flow: adapterFlow,
provider: adapterProvider, provider: adapterProvider,
database: adapterDB, database: adapterDB,
},{ },
blackList:['34XXXXXXXXX','34XXXXXXXXX','34XXXXXXXXX','34XXXXXXXXX'] {
}) blackList: ['34XXXXXXXXX', '34XXXXXXXXX', '34XXXXXXXXX', '34XXXXXXXXX'],
}
)
``` ```
--- ---
@@ -175,66 +178,75 @@ const flowString = addKeyword('hola')
``` ```
--- ---
## endFlow() ## endFlow()
Esta funcion se utliza para finalizar un flujo con dos o más addAnswer. Un ejemplo de uso sería registrar 3 datos de un usuario en 3 preguntas distinas y Esta funcion se utliza para finalizar un flujo con dos o más addAnswer. Un ejemplo de uso sería registrar 3 datos de un usuario en 3 preguntas distinas y
que el usuario pueda finalizar por él mismo el flujo. que el usuario pueda finalizar por él mismo el flujo.
Como podrás comprobar en el ejemplo siguiente, se puede vincular flowDynamic y todas sus funciones; como por ejemplo botones. Como podrás comprobar en el ejemplo siguiente, se puede vincular flowDynamic y todas sus funciones; como por ejemplo botones.
```js ```js
const flowFormulario = addKeyword(['Hola']) const flowFormulario = addKeyword(['Hola'])
.addAnswer(
.addAnswer(['Hola!','Escriba su *Nombre* para generar su solicitud'], ['Hola!', 'Escriba su *Nombre* para generar su solicitud'],
{capture: true,buttons:[{body:'❌ Cancelar solicitud'}]}, { capture: true, buttons: [{ body: '❌ Cancelar solicitud' }] },
async (ctx,{flowDynamic, endFlow})=>{ async (ctx, { flowDynamic, endFlow }) => {
if(ctx.body == '❌ Cancelar solicitud'){ if (ctx.body == '❌ Cancelar solicitud') {
await flowDynamic([{body: "❌ *Su solicitud de cita ha sido cancelada* ❌", buttons:[{body:'⬅️ Volver al Inicio'}]}]) await flowDynamic([
return endFlow() {
} body: '❌ *Su solicitud de cita ha sido cancelada* ❌',
}) buttons: [{ body: '⬅️ Volver al Inicio' }],
.addAnswer(['También necesito tus dos apellidos'], },
{capture: true,buttons:[{body:'❌ Cancelar solicitud'}]}, ])
async (ctx,{flowDynamic, endFlow})=>{ return endFlow()
if(ctx.body == '❌ Cancelar solicitud'){ }
await flowDynamic([{body: "❌ *Su solicitud de cita ha sido cancelada* ❌", buttons:[{body:'⬅️ Volver al Inicio'}]}]) }
return endFlow() )
} .addAnswer(
}) ['También necesito tus dos apellidos'],
.addAnswer(['Dejeme su número de teléfono y le llamaré lo antes posible.'], { capture: true, buttons: [{ body: '❌ Cancelar solicitud' }] },
{capture: true,buttons:[{body:'❌ Cancelar solicitud'}]}, async (ctx, { flowDynamic, endFlow }) => {
async (ctx,{flowDynamic, endFlow})=>{ if (ctx.body == '❌ Cancelar solicitud') {
if(ctx.body == '❌ Cancelar solicitud'){ await flowDynamic([
await flowDynamic([{body: "❌ *Su solicitud de cita ha sido cancelada* ❌", buttons:[{body:'⬅️ Volver al Inicio'}]}]) {
return endFlow() body: '❌ *Su solicitud de cita ha sido cancelada* ❌',
} buttons: [{ body: '⬅️ Volver al Inicio' }],
}) },
])
return endFlow()
}
}
)
.addAnswer(
['Dejeme su número de teléfono y le llamaré lo antes posible.'],
{ capture: true, buttons: [{ body: '❌ Cancelar solicitud' }] },
async (ctx, { flowDynamic, endFlow }) => {
if (ctx.body == '❌ Cancelar solicitud') {
await flowDynamic([
{
body: '❌ *Su solicitud de cita ha sido cancelada* ❌',
buttons: [{ body: '⬅️ Volver al Inicio' }],
},
])
return endFlow()
}
}
)
``` ```
--- ---
# QRPortalWeb # QRPortalWeb
Argumento para asignar nombre y puerto al BOT Argumento para asignar nombre y puerto al BOT
```js ```js
const BOTNAME = 'bot'; const BOTNAME = 'bot'
QRPortalWeb({name:BOTNAME, port:3005 }); QRPortalWeb({ name: BOTNAME, port: 3005 })
``` ```
--- ---
<Navigation <Navigation
pages={[ pages={[
{ name: 'Conceptos', link: '/docs/essential' }, { name: 'Conceptos', link: '/docs/essential' },

View File

@@ -145,7 +145,7 @@ class VenomProvider extends ProviderClass {
* @example await sendMessage('+XXXXXXXXXXX', 'audio.mp3') * @example await sendMessage('+XXXXXXXXXXX', 'audio.mp3')
*/ */
sendAudio = async (number, audioPath, voiceNote = false) => { sendAudio = async (number, audioPath) => {
return this.vendor.sendVoice(number, audioPath) return this.vendor.sendVoice(number, audioPath)
} }

View File

@@ -1,10 +1,9 @@
const { Client, LocalAuth, MessageMedia, Buttons } = require('whatsapp-web.js') const { Client, LocalAuth, MessageMedia, Buttons } = require('whatsapp-web.js')
const { ProviderClass } = require('@bot-whatsapp/bot') const { ProviderClass } = require('@bot-whatsapp/bot')
const { Console } = require('console') const { Console } = require('console')
const { createWriteStream } = require('fs') const { createWriteStream, readFileSync } = require('fs')
const { const {
wwebCleanNumber, wwebCleanNumber,
wwebDownloadMedia,
wwebGenerateImage, wwebGenerateImage,
wwebIsValidNumber, wwebIsValidNumber,
} = require('./utils') } = require('./utils')
@@ -13,6 +12,9 @@ const logger = new Console({
stdout: createWriteStream('./log'), stdout: createWriteStream('./log'),
}) })
const { generalDownload } = require('../../common/download')
const mime = require('mime-types')
/** /**
* ⚙️ WebWhatsappProvider: Es una clase tipo adaptor * ⚙️ WebWhatsappProvider: Es una clase tipo adaptor
* que extiende clases de ProviderClass (la cual es como interfaz para sber que funciones rqueridas) * que extiende clases de ProviderClass (la cual es como interfaz para sber que funciones rqueridas)
@@ -35,6 +37,7 @@ class WebWhatsappProvider extends ProviderClass {
'--disable-setuid-sandbox', '--disable-setuid-sandbox',
'--unhandled-rejections=strict', '--unhandled-rejections=strict',
], ],
//executablePath: 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
}, },
}) })
@@ -103,23 +106,6 @@ class WebWhatsappProvider extends ProviderClass {
}, },
] ]
/**
* Enviar un archivo multimedia
* https://docs.wwebjs.dev/MessageMedia.html
* @private
* @param {*} number
* @param {*} mediaInput
* @returns
*/
sendMedia = async (number, mediaInput = null) => {
if (!mediaInput) throw new Error(`NO_SE_ENCONTRO: ${mediaInput}`)
const fileDownloaded = await wwebDownloadMedia(mediaInput)
const media = MessageMedia.fromFilePath(fileDownloaded)
return this.vendor.sendMessage(number, media, {
sendAudioAsVoice: true,
})
}
/** /**
* Enviar botones * Enviar botones
* https://docs.wwebjs.dev/Buttons.html * https://docs.wwebjs.dev/Buttons.html
@@ -170,6 +156,90 @@ class WebWhatsappProvider extends ProviderClass {
return this.vendor.sendMessage(number, message) return this.vendor.sendMessage(number, message)
} }
/**
* Enviar imagen
* @param {*} number
* @param {*} imageUrl
* @param {*} text
* @returns
*/
sendImage = async (number, filePath) => {
const base64 = readFileSync(filePath, { encoding: 'base64' })
const mimeType = mime.lookup(filePath)
const media = new MessageMedia(mimeType, base64)
return this.vendor.sendMessage(number, media, {
caption: 'soy una imagen',
})
}
/**
* Enviar audio
* @param {*} number
* @param {*} imageUrl
* @param {*} text
* @returns
*/
sendAudio = async (number, filePath) => {
const base64 = readFileSync(filePath, { encoding: 'base64' })
const mimeType = mime.lookup(filePath)
const media = new MessageMedia(mimeType, base64)
return this.vendor.sendMessage(number, media, {
caption: 'soy un audio',
})
}
/**
* Enviar video
* @param {*} number
* @param {*} imageUrl
* @param {*} text
* @returns
*/
sendVideo = async (number, filePath) => {
const base64 = readFileSync(filePath, { encoding: 'base64' })
const mimeType = mime.lookup(filePath)
const media = new MessageMedia(mimeType, base64)
return this.vendor.sendMessage(number, media, {
sendMediaAsDocument: true,
})
}
/**
* Enviar Arhivos/pdf
* @param {*} number
* @param {*} imageUrl
* @param {*} text
* @returns
*/
sendFile = async (number, filePath) => {
const base64 = readFileSync(filePath, { encoding: 'base64' })
const mimeType = mime.lookup(filePath)
const media = new MessageMedia(mimeType, base64)
return this.vendor.sendMessage(number, media)
}
/**
* Enviar imagen o multimedia
* @param {*} number
* @param {*} mediaInput
* @param {*} message
* @returns
*/
sendMedia = async (number, mediaUrl, text) => {
const fileDownloaded = await generalDownload(mediaUrl)
const mimeType = mime.lookup(fileDownloaded)
if (mimeType.includes('image'))
return this.sendImage(number, fileDownloaded, text)
if (mimeType.includes('video'))
return this.sendVideo(number, fileDownloaded)
if (mimeType.includes('audio'))
return this.sendAudio(number, fileDownloaded)
return this.sendFile(number, fileDownloaded)
}
/** /**
* *
* @param {*} userId * @param {*} userId

View File

@@ -1,5 +1,5 @@
{ {
"dependencies": { "dependencies": {
"whatsapp-web.js": "1.19.2" "whatsapp-web.js": "1.19.3"
} }
} }

View File

@@ -1112,7 +1112,6 @@ __metadata:
eslint-config-prettier: ^8.5.0 eslint-config-prettier: ^8.5.0
fs-extra: ^11.1.0 fs-extra: ^11.1.0
git-cz: ^4.9.0 git-cz: ^4.9.0
got: 11.8.3
husky: ^8.0.2 husky: ^8.0.2
mime-types: ^2.1.35 mime-types: ^2.1.35
only-allow: ^1.1.1 only-allow: ^1.1.1
@@ -2935,13 +2934,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@sindresorhus/is@npm:^4.0.0":
version: 4.6.0
resolution: "@sindresorhus/is@npm:4.6.0"
checksum: 83839f13da2c29d55c97abc3bc2c55b250d33a0447554997a85c539e058e57b8da092da396e252b11ec24a0279a0bed1f537fa26302209327060643e327f81d2
languageName: node
linkType: hard
"@sindresorhus/is@npm:^5.2.0": "@sindresorhus/is@npm:^5.2.0":
version: 5.3.0 version: 5.3.0
resolution: "@sindresorhus/is@npm:5.3.0" resolution: "@sindresorhus/is@npm:5.3.0"
@@ -2986,7 +2978,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@szmarczak/http-timer@npm:^4.0.0, @szmarczak/http-timer@npm:^4.0.5": "@szmarczak/http-timer@npm:^4.0.0":
version: 4.0.6 version: 4.0.6
resolution: "@szmarczak/http-timer@npm:4.0.6" resolution: "@szmarczak/http-timer@npm:4.0.6"
dependencies: dependencies:
@@ -5082,13 +5074,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"cacheable-lookup@npm:^5.0.3":
version: 5.0.4
resolution: "cacheable-lookup@npm:5.0.4"
checksum: 763e02cf9196bc9afccacd8c418d942fc2677f22261969a4c2c2e760fa44a2351a81557bd908291c3921fe9beb10b976ba8fa50c5ca837c5a0dd945f16468f2d
languageName: node
linkType: hard
"cacheable-lookup@npm:^7.0.0": "cacheable-lookup@npm:^7.0.0":
version: 7.0.0 version: 7.0.0
resolution: "cacheable-lookup@npm:7.0.0" resolution: "cacheable-lookup@npm:7.0.0"
@@ -5141,7 +5126,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"cacheable-request@npm:^7.0.1, cacheable-request@npm:^7.0.2": "cacheable-request@npm:^7.0.1":
version: 7.0.2 version: 7.0.2
resolution: "cacheable-request@npm:7.0.2" resolution: "cacheable-request@npm:7.0.2"
dependencies: dependencies:
@@ -9915,25 +9900,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"got@npm:11.8.3":
version: 11.8.3
resolution: "got@npm:11.8.3"
dependencies:
"@sindresorhus/is": ^4.0.0
"@szmarczak/http-timer": ^4.0.5
"@types/cacheable-request": ^6.0.1
"@types/responselike": ^1.0.0
cacheable-lookup: ^5.0.3
cacheable-request: ^7.0.2
decompress-response: ^6.0.0
http2-wrapper: ^1.0.0-beta.5.2
lowercase-keys: ^2.0.0
p-cancelable: ^2.0.0
responselike: ^2.0.0
checksum: 3b6db107d9765470b18e4cb22f7c7400381be7425b9be5823f0168d6c21b5d6b28b023c0b3ee208f73f6638c3ce251948ca9b54a1e8f936d3691139ac202d01b
languageName: node
linkType: hard
"got@npm:^10.0.0, got@npm:^10.7.0": "got@npm:^10.0.0, got@npm:^10.7.0":
version: 10.7.0 version: 10.7.0
resolution: "got@npm:10.7.0" resolution: "got@npm:10.7.0"
@@ -10481,16 +10447,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"http2-wrapper@npm:^1.0.0-beta.5.2":
version: 1.0.3
resolution: "http2-wrapper@npm:1.0.3"
dependencies:
quick-lru: ^5.1.1
resolve-alpn: ^1.0.0
checksum: 74160b862ec699e3f859739101ff592d52ce1cb207b7950295bf7962e4aa1597ef709b4292c673bece9c9b300efad0559fc86c71b1409c7a1e02b7229456003e
languageName: node
linkType: hard
"http2-wrapper@npm:^2.1.10": "http2-wrapper@npm:^2.1.10":
version: 2.2.0 version: 2.2.0
resolution: "http2-wrapper@npm:2.2.0" resolution: "http2-wrapper@npm:2.2.0"
@@ -16865,7 +16821,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"resolve-alpn@npm:^1.0.0, resolve-alpn@npm:^1.2.0": "resolve-alpn@npm:^1.2.0":
version: 1.2.1 version: 1.2.1
resolution: "resolve-alpn@npm:1.2.1" resolution: "resolve-alpn@npm:1.2.1"
checksum: f558071fcb2c60b04054c99aebd572a2af97ef64128d59bef7ab73bd50d896a222a056de40ffc545b633d99b304c259ea9d0c06830d5c867c34f0bfa60b8eae0 checksum: f558071fcb2c60b04054c99aebd572a2af97ef64128d59bef7ab73bd50d896a222a056de40ffc545b633d99b304c259ea9d0c06830d5c867c34f0bfa60b8eae0