diff --git a/.env b/.env index 81114ea..90bc32a 100644 --- a/.env +++ b/.env @@ -13,4 +13,4 @@ KEEP_DIALOG_FLOW=false MULTI_DEVICE=true DIALOGFLOW_MEDIA_FOR_SLOT_FILLING=false GDRIVE_FOLDER_ID= -PROVIDER=baileys \ No newline at end of file +PROVIDER=wwebjs \ No newline at end of file diff --git a/controllers/handle.js b/controllers/handle.js index 7436e6b..8238179 100644 --- a/controllers/handle.js +++ b/controllers/handle.js @@ -50,8 +50,8 @@ const checkIsUrl = (path) => { } const generateImage = (base64, cb = () => {}) => { - let qr_svg = qr.image(base64, { type: 'svg', margin: 4 }); - qr_svg.pipe(require('fs').createWriteStream('./mediaSend/qr-code.svg')); + let qr_svg = qr.image(base64, { type: 'png', margin: 4 }); + qr_svg.pipe(require('fs').createWriteStream('./public/bot.qr.png')); console.log(`⚡ Recuerda que el QR se actualiza cada minuto ⚡'`); console.log(`⚡ Actualiza F5 el navegador para ver el QR mas reciente⚡`); cb() diff --git a/initBailey.js b/initBailey.js index ae4a9b1..2ef030c 100644 --- a/initBailey.js +++ b/initBailey.js @@ -15,8 +15,8 @@ var qr = require('qr-image'); * Hace promesa el write * @param {*} base64 */ -const baileyGenerateImage = async (base64, name = 'qr.png') => { - const PATH_QR = `${process.cwd()}/${name}`; +const baileyGenerateImage = async (base64, name = 'bot.qr.png') => { + const PATH_QR = `${process.cwd()}/public/${name}`; let qr_svg = qr.image(base64, { type: 'png', margin: 4 }); const writeFilePromise = () => @@ -87,14 +87,14 @@ initBailey = async () => { if (qr) { console.log('require_action', { instructions: [ - `Debes escanear el QR Code para iniciar ${globalVendorArgs.name}.qr.png`, + `Debes escanear el QR Code para iniciar bot.qr.png`, `Recuerda que el QR se actualiza cada minuto `, `Necesitas ayuda: https://link.codigoencasa.com/DISCORD`, ], }); await baileyGenerateImage( qr, - `${globalVendorArgs.name}.qr.png` + `bot.qr.png` ); } }); diff --git a/package-lock.json b/package-lock.json index d6c9b73..8bdeba9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "dotenv": "^16.0.1", "exceljs": "^4.3.0", "express": "^4.18.1", + "express-validator": "^6.15.0", "file-type": "^17.1.6", "google-spreadsheet": "^3.3.0", "googleapis": "^109.0.1", @@ -29,7 +30,7 @@ "socket.io": "^4.5.1", "stormdb": "^0.6.0", "util-tiempo": "^1.0.41", - "whatsapp-web.js": "github:cheveguerra/whatsapp-web.js#WaWJS2", + "whatsapp-web.js": "^1.19.4", "xlsx": "^0.18.5" }, "devDependencies": { @@ -89,9 +90,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.1.tgz", - "integrity": "sha512-JzhBFpkuhBNYUY7qs+wTzNmyCWUHEaAFpQQD2YfU1rPL38/L43Wvid0fFkiOCnHvsGncRZgEPyGnltABLcVDTg==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", + "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -127,9 +128,9 @@ } }, "node_modules/@google-cloud/dialogflow": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@google-cloud/dialogflow/-/dialogflow-5.5.1.tgz", - "integrity": "sha512-JVGohHEviAR7NM5X2Wt9SL5n6f1FJEkNllDInM9QO9FKX0d5aUp7Xi/Lk9U6OuflfoxWAj3hrap9MxUIjyrwVA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@google-cloud/dialogflow/-/dialogflow-5.6.0.tgz", + "integrity": "sha512-T63lyDjoGEZhKXLTjvjr9nFJ3L73+aHMaEKof3uiEmeqaSOBckFnI1dilzGEHwk7jJGpWXMV+eV5RJ1+kAG5Kg==", "dependencies": { "google-gax": "^3.5.2" }, @@ -138,9 +139,9 @@ } }, "node_modules/@grpc/grpc-js": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.9.tgz", - "integrity": "sha512-xzsl2HamhovnZddS/2pMF4Q+FgwINaBvxoFGQ+G54Lo7Xsge36VvfDO/TDkL7FofmrRK/X5weRvwlJh7rKwN4w==", + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.11.tgz", + "integrity": "sha512-f/xC+6Z2QKsRJ+VSSFlt4hA5KSRm+PKvMWV8kMPkMgGlFidR6PeIkXrOasIY2roe+WROM6GFQLlgDKfeEZo2YQ==", "dependencies": { "@grpc/proto-loader": "^0.7.0", "@types/node": ">=12.12.47" @@ -661,9 +662,9 @@ } }, "node_modules/@types/glob": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.0.1.tgz", - "integrity": "sha512-8bVUjXZvJacUFkJXHdyZ9iH1Eaj5V7I8c4NdH5sQJsdXkqT4CA5Dhb4yb4VE/3asyx4L9ayZr1NIhTsWHczmMw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", "dependencies": { "@types/minimatch": "^5.1.2", "@types/node": "*" @@ -924,9 +925,9 @@ } }, "node_modules/archiver-utils/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -1742,9 +1743,9 @@ } }, "node_modules/duplexer2/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -2118,6 +2119,18 @@ "node": ">= 0.10.0" } }, + "node_modules/express-validator": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.15.0.tgz", + "integrity": "sha512-r05VYoBL3i2pswuehoFSy+uM8NBuVaY7avp5qrYjQBDzagx2Z5A77FZqPT8/gNLF3HopWkIzaTFaC4JysWXLqg==", + "dependencies": { + "lodash": "^4.17.21", + "validator": "^13.9.0" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3499,9 +3512,9 @@ } }, "node_modules/jszip/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -3573,9 +3586,9 @@ } }, "node_modules/lazystream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -4200,9 +4213,9 @@ } }, "node_modules/node-webpmux": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/node-webpmux/-/node-webpmux-3.1.4.tgz", - "integrity": "sha512-EgKZEB+T5AG7rbs2i39W+HBqU6OmOTz1EvioPRq2LYW+fZen/l3EKTC5ekkU7cl4/OflTCFRPXy0kIhi+4FunQ==" + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/node-webpmux/-/node-webpmux-3.1.5.tgz", + "integrity": "sha512-yfZBMbISp425P8TGKEh2vrOafRBOatwQqiDYDQrEddBYork6gpKPXHbqSU3bOmoIc2fEJ8p+IXiqa1OP+mZPhg==" }, "node_modules/normalize-path": { "version": "3.0.0", @@ -5155,9 +5168,9 @@ } }, "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz", + "integrity": "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -5936,9 +5949,9 @@ } }, "node_modules/systeminformation": { - "version": "5.17.9", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.17.9.tgz", - "integrity": "sha512-inxwRLI/4qpx4o85R54/zdhNagdBGBgs0la7Vl3qBorRVKRDk0nNsDTCGzG4lOITsw1gl7LRWeG4Zsp1pC8nfg==", + "version": "5.17.10", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.17.10.tgz", + "integrity": "sha512-FUm264baeDpruTw4P50BRRmYHD39D3jkOQ0VpNIkp8CdNejQbsp4Me18jacGBc/mWSVxKdQw4wSHmcL7ERxrNg==", "dev": true, "optional": true, "os": [ @@ -6215,9 +6228,9 @@ } }, "node_modules/unzipper/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6291,6 +6304,14 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/validator": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", + "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -6359,8 +6380,8 @@ }, "node_modules/whatsapp-web.js": { "version": "1.19.4", - "resolved": "git+ssh://git@github.com/cheveguerra/whatsapp-web.js.git#83560a2b5647d3accd039ce1f663f908edcfc960", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/whatsapp-web.js/-/whatsapp-web.js-1.19.4.tgz", + "integrity": "sha512-qwfdauW3rKsI2gzRexFU5y+SumXjuZTidyZXFIXaWfPzMe4ejxAkVoj/u27wyNZDqK3Z8tI/Ac3ZJFG60VgA6w==", "dependencies": { "@pedroslopez/moduleraid": "^5.0.2", "fluent-ffmpeg": "^2.1.2", diff --git a/package.json b/package.json index 49b86bc..7265f00 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "dotenv": "^16.0.1", "exceljs": "^4.3.0", "express": "^4.18.1", + "express-validator": "^6.15.0", "file-type": "^17.1.6", "google-spreadsheet": "^3.3.0", "googleapis": "^109.0.1", @@ -31,7 +32,7 @@ "socket.io": "^4.5.1", "stormdb": "^0.6.0", "util-tiempo": "^1.0.41", - "whatsapp-web.js": "github:cheveguerra/whatsapp-web.js#WaWJS2", + "whatsapp-web.js": "^1.19.4", "xlsx": "^0.18.5" }, "devDependencies": { diff --git a/provider/baileys.js b/provider/baileys.js index 0c58528..ab0cb64 100644 --- a/provider/baileys.js +++ b/provider/baileys.js @@ -21,8 +21,8 @@ var qr = require('qr-image'); * Hace promesa el write * @param {*} base64 */ -const baileyGenerateImage = async (base64, name = 'qr.png') => { - const PATH_QR = `${process.cwd()}/${name}`; +const baileyGenerateImage = async (base64, name = 'bot.qr.png') => { + const PATH_QR = `${process.cwd()}/public/${name}`; let qr_svg = qr.image(base64, { type: 'png', margin: 4 }); const writeFilePromise = () => @@ -89,7 +89,7 @@ initBot = async () => { `Necesitas ayuda: https://link.codigoencasa.com/DISCORD`, ], }); - await baileyGenerateImage(qr, `${globalVendorArgs.name}.qr.png`); + await baileyGenerateImage(qr, `bot.qr.png`); } }); sock.ev.on('creds.update', async () => { await saveCreds() }); diff --git a/provider/wwebjs.js b/provider/wwebjs.js index b92027d..026096b 100644 --- a/provider/wwebjs.js +++ b/provider/wwebjs.js @@ -1,6 +1,7 @@ const { Client, LocalAuth, Buttons, List } = require('whatsapp-web.js'); require('dotenv').config() const express = require('express'); +const bodyParser = require("body-parser"); const cors = require('cors') const qrcode = require('qrcode-terminal'); const app = express(); @@ -10,8 +11,20 @@ const server = require('http').Server(app) const port = process.env.PORT || 3000 const { generateImage, checkEnvFile } = require('../controllers/handle') const { connectionReady } = require('../controllers/connection') +const { body, validationResult } = require('express-validator'); app.use('/', require('../routes/web')) + +const { Server } = require("socket.io"); +const io = new Server(server); + +// app.use(bodyParser.json({ limit: "50mb" })); +// app.use(cors()); +app.use(express.json()); +app.use(bodyParser.urlencoded({ extended: true })); + +let socks + initBot = async () => { console.log("WaWebJS Init") const client = new Client({ @@ -19,12 +32,6 @@ initBot = async () => { puppeteer: { headless: true, args: ['--no-sandbox','--disable-setuid-sandbox'] } }); - client.on('qr', qr => generateImage(qr, () => { - qrcode.generate(qr, { small: true }); - console.log(`Ver QR http://localhost:${port}/qr`) - socketEvents.sendQR(qr) - })) - client.on('ready', (a) => { connectionReady() // listenMessage(client) @@ -50,11 +57,133 @@ initBot = async () => { if (process.env.DATABASE === 'mysql') { mysqlConnection.connect() } + let waReady = false + // Socket IO + io.on('connection', async function (socket) { + console.log("Connecting ...") + socks = socket + + await socket.emit('message', 'Connecting...'); + + socket.on('checkConn', async function () { // Si recibe mensaje, regresa "connOk" + console.log("checking conn") + await socket.emit('connOk', 'Connected'); + }) + + try { + client.on('message', () => { + console.log(waReady) + socket.emit('incomming', 'Message In') + waReady = true + }) + client.on('qr', qr => generateImage(qr, async () => { + qrcode.generate(qr, { small: true }); + console.log(`Ver QR http://localhost:${port}/bot.qr.png`) + await socket.emit('qr', `http://localhost:${port}/bot.qr.png`); + await socket.emit('message', 'QR Code received, scan please!'); + })) + + client.on('ready', async () => { + await socket.emit('ready', 'Whatsapp is ready!'); + await socket.emit('message', 'Whatsapp is ready!'); + waReady = true + }); + + client.on('authenticated', async () => { + await socket.emit('authenticated', 'Whatsapp is authenticated!'); + await socket.emit('message', 'Whatsapp is authenticated!'); + // console.log('AUTHENTICATED'); + }); + + client.on('auth_failure', async function (session) { + await socket.emit('message', 'Auth failure, restarting...'); + waReady = false + }); + + client.on('disconnected', async (reason) => { + await socket.emit('message', 'Whatsapp is disconnected!'); + waReady = false + // client.destroy(); + // client.initialize(); + }) + } + catch (e) {waReady = false } + + }); server.listen(port, () => { console.log(`El server esta listo en el puerto ${port}`); }) + const phoneNumberFormatter = function (number) { + // 1. Menghilangkan karakter selain angka + let formatted = number.replace(/\D/g, ''); + + // 2. Menghilangkan angka 0 di depan (prefix) + // Kemudian diganti dengan 62 + if (formatted.startsWith('0')) { + formatted = '62' + formatted.substr(1); + } + + if (!formatted.endsWith('@c.us')) { + formatted += '@c.us'; + } + + return formatted; + } + + const checkRegisteredNumber = async function (number) { + const isRegistered = await client.isRegisteredUser(number); + return isRegistered; + } + + // Send message + app.post('/send-message', [ + body('number').notEmpty(), + body('message').notEmpty(), + ], async (req, res) => { + + console.log("xxxxxxxx", req.body) + + socks.emit('incomming', 'Message In') + + const errors = validationResult(req).formatWith(({ + msg + }) => { + return msg; + }); + + if (!errors.isEmpty()) { + return res.status(422).json({ + status: false, + message: errors.mapped() + }); + } + + const number = phoneNumberFormatter(req.body.number); + const message = req.body.message; + const isRegisteredNumber = await checkRegisteredNumber(number); + if (!isRegisteredNumber) { + return res.status(422).json({ + status: false, + message: 'The number is not registered' + }); + } + + client.sendMessage(number, message).then(response => { + res.status(200).json({ + status: true, + response: response + }); + }).catch(err => { + res.status(500).json({ + status: false, + response: err + }); + }); + }); + + checkEnvFile(); return client } diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..4933b87 --- /dev/null +++ b/public/index.html @@ -0,0 +1,188 @@ + + + + + Whatsapp API by Ngekoding + + + + + + + + +
+
+

Whatsapp API

+
+
+ QR Code +
+
+
+ + + + + + + + + + +
Número:
Mensaje:
+
+
+ +
+

Logs:

+ +
+ + + + + + + \ No newline at end of file diff --git a/routes/web.js b/routes/web.js index 32df0e5..d96f814 100644 --- a/routes/web.js +++ b/routes/web.js @@ -1,7 +1,15 @@ const express = require('express'); const router = express.Router() const { getQr } = require('../controllers/web') +var path = require('path'); -router.use('/qr', getQr) +// router.use('/qr', getQr) +var staticFilesPath0 = path.resolve('./', 'public'); +var staticFilesPath = path.resolve('./', 'public/index.html'); +console.log(staticFilesPath) +router.use(express.static(staticFilesPath0)); +router.get('/', (req, res) => { + res.sendFile(staticFilesPath) +}); module.exports = router \ No newline at end of file