Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[鈿 Api para envio de mensajes #670

Closed
eduardolat opened this issue Feb 25, 2023 · 19 comments
Closed

[鈿 Api para envio de mensajes #670

eduardolat opened this issue Feb 25, 2023 · 19 comments
Labels
documentation Improvements or additions to documentation enhancement New feature or request

Comments

@eduardolat
Copy link

Antes que nada, muchas gracias por el buen trabajo al hacer esta biblioteca 馃

Describe tu problema

Ser铆a muy bueno que la funci贸n createBot retornara un objeto con funciones para poder aprovechar la abstracci贸n de env铆o de mensajes y poder reutilizar las implementaciones con los distintos proveedores que la biblioteca ya de por s铆 ofrece.

Esto nos permitir铆a extender la funcionalidad de la biblioteca haciendo nuestras propias funciones sin necesidad de crear nuestras propias abstracciones sobre los proveedores, por ejemplo, podr铆amos tener un chatbot y un api de WhatsApp en el mismo proyecto, podr铆amos configurar webhooks, enviar a clientes notificaciones de su cuenta, pedidos, etc.

Es genial como bot-whatsapp puede intercambiar entre proveedores, ser铆a genial poder combinar esa funci贸n con la propuesta

Informaci贸n Adicional

Adjunto imagen con un ejemplo de como puede ser 煤til. No propongo agregar endpoints (驴o si?), solamente tener las funciones para poder hacerlo por cuenta propia.

image

@leifermendez
Copy link
Member

leifermendez commented Feb 25, 2023

@eduardolat Buenas interesante tu enfoque afortunadamente ya puedes aprovechar esas funcionalidades te dejo un ejemplo

const express = require('express')
const { createBot, createProvider, createFlow, addKeyword } = require('@bot-whatsapp/bot')

const BaileysProvider = require('@bot-whatsapp/provider/baileys')
const MockAdapter = require('@bot-whatsapp/database/mock')

const app = express()
const main = async () => {
    const adapterDB = new MockAdapter()
    const adapterFlow = createFlow([flowPrincipal])
    const adapterProvider = createProvider(BaileysProvider)

    createBot({
        flow: adapterFlow,
        provider: adapterProvider,
        database: adapterDB,
    })

    /**
     * Enviar mensaje con metodos propios del provider del bot
     */
    app.post('/send-message-bot', async (req, res) => {
        await adapterProvider.sendText('[email protected]', 'Mensaje desde API')
        res.send({ data: 'enviado!' })
    })
    /**
     * Enviar mensajes con metodos nativos del provider
     */
    app.post('/send-message-provider', async (req, res) => {
        const id = '[email protected]'
        const templateButtons = [
            {
                index: 1,
                urlButton: {
                    displayText: ':star: Star Baileys on GitHub!',
                    url: 'https://github.com/adiwajshing/Baileys',
                },
            },
            { index: 2, callButton: { displayText: 'Call me!', phoneNumber: '+1 (234) 5678-901' } },
            {
                index: 3,
                quickReplyButton: {
                    displayText: 'This is a reply, just like normal buttons!',
                    id: 'id-like-buttons-message',
                },
            },
        ]

        const templateMessage = {
            text: "Hi it's a template message",
            footer: 'Hello World',
            templateButtons: templateButtons,
        }

        const abc = await adapterProvider.getInstance()
        await abc.sendMessage(id, templateMessage)

        res.send({ data: 'enviado!' })
    })
    const PORT = 4000
    app.listen(PORT, () => console.log(`http://localhost:${PORT}`))
}

main()

@ramonbello
Copy link

Hola, @leifermendez como puedo validar que exista una session activa antes de enviar el mensaje, intente enviar el mensaje sin ninguna session y me sale este error

image

@ramonbello
Copy link

ramonbello commented Feb 26, 2023

Lo solucione de esta forma:

Cree esta validaci贸n para verificar si la sesi贸n estaba creada

async function sesionCreada() {
    try {
        const files = await readdirAsync('bot_sessions');
        return files.length !== 0;
    } catch (err) {
        console.error(err);
        return false;
    }
}

Luego la utilizo antes de llamar a la funci贸n del envi贸 del mensaje:


app.post('/enviar-mensaje', async (req, res) => {
        const numero = req.body.numero;
        const media = req.body.url_media;
        const mensaje = req.body.mensaje;

        if (!validarCelular(numero)) {
            return res.send({
                transaccion: false,
                mensaje: 'N煤mero de celular no v谩lido'
            });
        }

        const existeSesion = await sesionCreada();
        if (!existeSesion) {
            return res.send({
                transaccion: false,
                mensaje: 'Sesion no creada, por favor escane el codigo qr'
            });
        }
        
        try {
            if (req.body?.hasOwnProperty('url_media')) {
                await adapterProvider.sendMedia(numero, media, mensaje);
            } else {
                await adapterProvider.sendText(numero, mensaje);
            }
            return res.send({
                transaccion: true,
                mensaje: 'enviado!'
            });

        } catch (error) {
            return res.send({
                transaccion: false,
                mensaje: 'error!'
            });
        }
    });


@eduardolat
Copy link
Author

@leifermendez Muchas gracias por tu respuesta, tiene mucho sentido, 驴Crees que ser铆a bueno documentarlo?, yo me puedo encargar de eso, tal vez en la secci贸n, Avanzado > Providers API
Si me das el ok lo escribo y pongo un par de ejemplos

@leifermendez leifermendez pinned this issue Mar 9, 2023
@asenawritescode
Copy link

@leifermendez
On deployment their is an outlying issue around port allocation for the express app.

This works on local machine but fails on deployment

@mastercodelatam
Copy link

y para el archivo principal
const main = async () => {
//const adapterDB = new MockAdapter()
const adapterFlow = DepenBot.createFlow([flowPrincipal]);
const adapterProvider = DepenBot.createProvider(BaileysProvider);

const bot = await DepenBot.createBot({
    flow: adapterFlow,
    provider: adapterProvider,
    database: adapterDB,
})
 //await bot.providerClass.sendText('[email protected]', 'hola este es un mensaje automatico');
     //await bot.providerClass.sendMedia('[email protected]', 'https://Electronicos/2/6436c570e9646dd4ac88e4fc');

lo he resulto de esta manera para el archivo Bundle.bot.cjs
```
// 馃搫 Esta funcion se encarga de enviar un array de mensajes dentro de este ctx
const sendFlow = async (messageToSend, numberOrId, options = { prev: prevMsg }) => {
if (options.prev?.options?.capture) await cbEveryCtx(options.prev?.ref);
const queue = [];
for (const ctxMessage of messageToSend) {
if (endFlowFlag) return
const delayMs = ctxMessage?.options?.delay ?? this.generalArgs.delay ?? 0;
if (delayMs) await delay(delayMs);
await QueuePrincipal.enqueue(() =>
this.sendProviderAndSave(numberOrId, ctxMessage).then(() => resolveCbEveryCtx(ctxMessage)).catch((e)=>{
console.log('Ocurrio un error al obtener el cxt')
})
);
}
return Promise.all(queue)

@mastercodelatam
Copy link

mastercodelatam commented Apr 12, 2023

y para escuchar si el cliente esta listo utilice este

bot.providerClass.on('ready', () => {
        console.log('Bot de WhatsApp conectado y listo');
});

@colcodec
Copy link

colcodec commented May 5, 2023

hola
estoy tratando de responder por medio de el
flowDynamic({ body: mensaje, from: usuario2 })
pero solo me funciona para el primer mensaje q respondi, hay alguna forma de hacer uso de el sin necesidad q intervenga en un flujo, utilizarlo fuera del flujo

@colcodec
Copy link

colcodec commented May 5, 2023

quisiera enviar, a cualquier numero, sin imporetar si la seccion esta activa

@sotile
Copy link

sotile commented May 6, 2023

me parece super interesante esto, pero si bien tengo algunos conocimientos de javascript y php no estoy familiarizado con express y node.js, de que manera podria agregar la funcionalidad de enviar mensajes con el bot a clientes que no iniciaron una conversacion? hay algun ejemplo funcional que sepueda probar con postman? gracias desde ya.

@mdestafadilah
Copy link

hola estoy tratando de responder por medio de el flowDynamic({ body: mensaje, from: usuario2 }) pero solo me funciona para el primer mensaje q respondi, hay alguna forma de hacer uso de el sin necesidad q intervenga en un flujo, utilizarlo fuera del flujo

maybe you can save the messsage to database, tthen catch by the number sender to reply again.

@mdestafadilah
Copy link

@leifermendez Muchas gracias por tu respuesta, tiene mucho sentido, 驴Crees que ser铆a bueno documentarlo?, yo me puedo encargar de eso, tal vez en la secci贸n, Avanzado > Providers API Si me das el ok lo escribo y pongo un par de ejemplos

any update then?

@colcodec
Copy link

hola estoy tratando de responder por medio de el flowDynamic({ body: mensaje, from: usuario2 }) pero solo me funciona para el primer mensaje q respondi, hay alguna forma de hacer uso de el sin necesidad q intervenga en un flujo, utilizarlo fuera del flujo

maybe you can save the messsage to database, tthen catch by the number sender to reply again.

I am doing the same thing, I capture it, but it does not send me to the established number

@leifermendez leifermendez added documentation Improvements or additions to documentation enhancement New feature or request labels May 25, 2023
@jsantacruze
Copy link

@eduardolat Buenas interesante tu enfoque afortunadamente ya puedes aprovechar esas funcionalidades te dejo un ejemplo

const express = require('express')
const { createBot, createProvider, createFlow, addKeyword } = require('@bot-whatsapp/bot')

const BaileysProvider = require('@bot-whatsapp/provider/baileys')
const MockAdapter = require('@bot-whatsapp/database/mock')

const app = express()
const main = async () => {
    const adapterDB = new MockAdapter()
    const adapterFlow = createFlow([flowPrincipal])
    const adapterProvider = createProvider(BaileysProvider)

    createBot({
        flow: adapterFlow,
        provider: adapterProvider,
        database: adapterDB,
    })

    /**
     * Enviar mensaje con metodos propios del provider del bot
     */
    app.post('/send-message-bot', async (req, res) => {
        await adapterProvider.sendText('[email protected]', 'Mensaje desde API')
        res.send({ data: 'enviado!' })
    })
    /**
     * Enviar mensajes con metodos nativos del provider
     */
    app.post('/send-message-provider', async (req, res) => {
        const id = '[email protected]'
        const templateButtons = [
            {
                index: 1,
                urlButton: {
                    displayText: ':star: Star Baileys on GitHub!',
                    url: 'https://github.com/adiwajshing/Baileys',
                },
            },
            { index: 2, callButton: { displayText: 'Call me!', phoneNumber: '+1 (234) 5678-901' } },
            {
                index: 3,
                quickReplyButton: {
                    displayText: 'This is a reply, just like normal buttons!',
                    id: 'id-like-buttons-message',
                },
            },
        ]

        const templateMessage = {
            text: "Hi it's a template message",
            footer: 'Hello World',
            templateButtons: templateButtons,
        }

        const abc = await adapterProvider.getInstance()
        await abc.sendMessage(id, templateMessage)

        res.send({ data: 'enviado!' })
    })
    const PORT = 4000
    app.listen(PORT, () => console.log(`http://localhost:${PORT}`))
}

main()

Saludos @leifermendez he intentado replicar ese ejemplo, pero obtengo el siguiente error>
sendTextMesage is not a function

No reconoce la funci贸n de env铆o.... Podr铆as orientarme mejor?? Gracias de antemano por la ayuda

@Nixomart
Copy link

Nixomart commented Jun 4, 2023

@eduardolat Buenas interesante tu enfoque afortunadamente ya puedes aprovechar esas funcionalidades te dejo un ejemplo

const express = require('express')
const { createBot, createProvider, createFlow, addKeyword } = require('@bot-whatsapp/bot')

const BaileysProvider = require('@bot-whatsapp/provider/baileys')
const MockAdapter = require('@bot-whatsapp/database/mock')

const app = express()
const main = async () => {
    const adapterDB = new MockAdapter()
    const adapterFlow = createFlow([flowPrincipal])
    const adapterProvider = createProvider(BaileysProvider)

    createBot({
        flow: adapterFlow,
        provider: adapterProvider,
        database: adapterDB,
    })

    /**
     * Enviar mensaje con metodos propios del provider del bot
     */
    app.post('/send-message-bot', async (req, res) => {
        await adapterProvider.sendText('[email protected]', 'Mensaje desde API')
        res.send({ data: 'enviado!' })
    })
    /**
     * Enviar mensajes con metodos nativos del provider
     */
    app.post('/send-message-provider', async (req, res) => {
        const id = '[email protected]'
        const templateButtons = [
            {
                index: 1,
                urlButton: {
                    displayText: ':star: Star Baileys on GitHub!',
                    url: 'https://github.com/adiwajshing/Baileys',
                },
            },
            { index: 2, callButton: { displayText: 'Call me!', phoneNumber: '+1 (234) 5678-901' } },
            {
                index: 3,
                quickReplyButton: {
                    displayText: 'This is a reply, just like normal buttons!',
                    id: 'id-like-buttons-message',
                },
            },
        ]

        const templateMessage = {
            text: "Hi it's a template message",
            footer: 'Hello World',
            templateButtons: templateButtons,
        }

        const abc = await adapterProvider.getInstance()
        await abc.sendMessage(id, templateMessage)

        res.send({ data: 'enviado!' })
    })
    const PORT = 4000
    app.listen(PORT, () => console.log(`http://localhost:${PORT}`))
}

main()

Como puedo hacer que esto funcione en el deploy de railway? cree las endpoint en local funciona localhost:4000/sendMessge pero en railwind creando un dominio e ingresando al endpoint /sendMessage me dice que no existe la pagina :/

@Nixomart
Copy link

Nixomart commented Jun 4, 2023

sendTextMesage

lo resolvi const PORT = process.env.PORT || 4000;
app.listen(PORT, () => console.log(TU APP ESTA EN EL http://localhost:${PORT})); y en railway tenes que crear una variable PORT jaja

@mdestafadilah
Copy link

@eduardolat Buenas interesante tu enfoque afortunadamente ya puedes aprovechar esas funcionalidades te dejo un ejemplo

const express = require('express')
const { createBot, createProvider, createFlow, addKeyword } = require('@bot-whatsapp/bot')

const BaileysProvider = require('@bot-whatsapp/provider/baileys')
const MockAdapter = require('@bot-whatsapp/database/mock')

const app = express()
const main = async () => {
    const adapterDB = new MockAdapter()
    const adapterFlow = createFlow([flowPrincipal])
    const adapterProvider = createProvider(BaileysProvider)

    createBot({
        flow: adapterFlow,
        provider: adapterProvider,
        database: adapterDB,
    })

    /**
     * Enviar mensaje con metodos propios del provider del bot
     */
    app.post('/send-message-bot', async (req, res) => {
        await adapterProvider.sendText('[email protected]', 'Mensaje desde API')
        res.send({ data: 'enviado!' })
    })
    /**
     * Enviar mensajes con metodos nativos del provider
     */
    app.post('/send-message-provider', async (req, res) => {
        const id = '[email protected]'
        const templateButtons = [
            {
                index: 1,
                urlButton: {
                    displayText: ':star: Star Baileys on GitHub!',
                    url: 'https://github.com/adiwajshing/Baileys',
                },
            },
            { index: 2, callButton: { displayText: 'Call me!', phoneNumber: '+1 (234) 5678-901' } },
            {
                index: 3,
                quickReplyButton: {
                    displayText: 'This is a reply, just like normal buttons!',
                    id: 'id-like-buttons-message',
                },
            },
        ]

        const templateMessage = {
            text: "Hi it's a template message",
            footer: 'Hello World',
            templateButtons: templateButtons,
        }

        const abc = await adapterProvider.getInstance()
        await abc.sendMessage(id, templateMessage)

        res.send({ data: 'enviado!' })
    })
    const PORT = 4000
    app.listen(PORT, () => console.log(`http://localhost:${PORT}`))
}

main()

Como puedo hacer que esto funcione en el deploy de railway? cree las endpoint en local funciona localhost:4000/sendMessge pero en railwind creando un dominio e ingresando al endpoint /sendMessage me dice que no existe la pagina :/

realy need clear documentation about this. any update then?

@sotile
Copy link

sotile commented Jun 8, 2023

@leifermendez podrias crear un tutorial para implementar lo del envio de mensajes y templates de mensajes?

@sotile
Copy link

sotile commented Jun 13, 2023

app.post('/enviar-mensaje', async (req, res) => {
const numero = req.body.numero;
const media = req.body.url_media;
const mensaje = req.body.mensaje;

    if (!validarCelular(numero)) {
        return res.send({
            transaccion: false,
            mensaje: 'N煤mero de celular no v谩lido'
        });
    }

    const existeSesion = await sesionCreada();
    if (!existeSesion) {
        return res.send({
            transaccion: false,
            mensaje: 'Sesion no creada, por favor escane el codigo qr'
        });
    }
    
    try {
        if (req.body?.hasOwnProperty('url_media')) {
            await adapterProvider.sendMedia(numero, media, mensaje);
        } else {
            await adapterProvider.sendText(numero, mensaje);
        }
        return res.send({
            transaccion: true,
            mensaje: 'enviado!'
        });

    } catch (error) {
        return res.send({
            transaccion: false,
            mensaje: 'error!'
        });
    }
});

leifer, como recibir parametros del numero y del mensaje desde postman? aunque pase los valors en el body no logro que los tome el bot

@codigoencasa codigoencasa locked and limited conversation to collaborators Jun 23, 2023
@leifermendez leifermendez converted this issue into discussion #774 Jun 23, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

10 participants