├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── README.md ├── assets ├── address.png ├── assistant.png ├── bill.png ├── menu.png ├── order.png └── welcome.png ├── package.json ├── src ├── menu.js ├── server.js ├── stages.js ├── stages │ ├── 0.js │ ├── 1.js │ ├── 2.js │ ├── 3.js │ ├── 4.js │ ├── 5.js │ ├── index.js │ └── neighborhoods.js ├── storage.js └── venom.js └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "@rocketseat/eslint-config/node" 4 | ] 5 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | tokens -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Whatsapp Bot with VENOM-BOT 2 | 3 | ## Descrição do Projeto 4 | 5 |

6 |

7 | 🔗 NodeJS 8 | 🧠 Venom Bot 9 |

10 |

🚀 Projeto criado com o intuito de auxiliar nas demandas de pedidos da empresa "Delícias da Neide" via WhatsApp.

11 |
12 |

13 | Welcome 14 | Welcome 15 | Menu 16 | Menu 17 | Order 18 | Order 19 | Address 20 | Address 21 | Bill 22 | Bill 23 | Assistant 24 | Assistant 25 |

26 | 27 | ### Pré-requisitos 28 | 29 | Antes de começar, você vai precisar ter instalado em sua máquina as seguintes ferramentas: 30 | [Git](https://git-scm.com), [Node.js](https://nodejs.org/en/). 31 | Além disto, é bom ter um editor para trabalhar com o código como [VSCode](https://code.visualstudio.com/). 32 | 33 | ### 🎲 Rodando nossa aplicação 34 | 35 | ```bash 36 | # Clone este repositório 37 | $ git clone git@github.com:juniorwmr/botwhatsapp-venom.git 38 | 39 | # Acesse a pasta do projeto no terminal/cmd 40 | $ cd botwhatsapp-venom 41 | 42 | # Instale as dependências 43 | $ npm install 44 | 45 | # Execute a aplicação em modo de desenvolvimento 46 | $ yarn dev 47 | 48 | ## Pronto, escaneie o código QR do Whatsapp e Voilà, aproveite! 49 | ``` 50 | 51 | ### 🛠 Tecnologias 52 | 53 | As seguintes ferramentas foram usadas na construção do projeto: 54 | 55 | - [Node.js](https://nodejs.org/en/) 56 | 57 | ### Autor 58 | 59 | --- 60 | 61 | 62 | 63 |
64 | 65 | Done with ❤️ by Washington Muniz 👋🏽 ! 66 | 67 | [![Twitter Badge](https://img.shields.io/badge/-@juniorwmr-1ca0f1?style=flat-square&labelColor=1ca0f1&logo=twitter&logoColor=white&link=https://twitter.com/juniorwmr)](https://twitter.com/juniorwmr) [![Linkedin Badge](https://img.shields.io/badge/-Washington-blue?style=flat-square&logo=Linkedin&logoColor=white&link=https://www.linkedin.com/in/juniorwmr/)](https://www.linkedin.com/in/juniorwmr/) 68 | [![Gmail Badge](https://img.shields.io/badge/-juniorwmr@gmail.com-c14438?style=flat-square&logo=Gmail&logoColor=white&link=mailto:juniorripardo@gmail.com)](mailto:juniorripardo@gmail.com) 69 | -------------------------------------------------------------------------------- /assets/address.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juniorwmr/botwhatsapp-venom/d01033177a37d153b566bb72bb2d7baf1865df9b/assets/address.png -------------------------------------------------------------------------------- /assets/assistant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juniorwmr/botwhatsapp-venom/d01033177a37d153b566bb72bb2d7baf1865df9b/assets/assistant.png -------------------------------------------------------------------------------- /assets/bill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juniorwmr/botwhatsapp-venom/d01033177a37d153b566bb72bb2d7baf1865df9b/assets/bill.png -------------------------------------------------------------------------------- /assets/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juniorwmr/botwhatsapp-venom/d01033177a37d153b566bb72bb2d7baf1865df9b/assets/menu.png -------------------------------------------------------------------------------- /assets/order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juniorwmr/botwhatsapp-venom/d01033177a37d153b566bb72bb2d7baf1865df9b/assets/order.png -------------------------------------------------------------------------------- /assets/welcome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juniorwmr/botwhatsapp-venom/d01033177a37d153b566bb72bb2d7baf1865df9b/assets/welcome.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "botwhatsapp", 3 | "type": "module", 4 | "version": "1.0.0", 5 | "main": "index.js", 6 | "license": "MIT", 7 | "scripts": { 8 | "start": "node src/server.js", 9 | "dev": "nodemon src/server.js" 10 | }, 11 | "devDependencies": { 12 | "@rocketseat/eslint-config": "^1.2.0", 13 | "nodemon": "^2.0.22" 14 | }, 15 | "dependencies": { 16 | "venom-bot": "^5.0.20" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/menu.js: -------------------------------------------------------------------------------- 1 | export const menu = { 2 | 1: { 3 | description: 'Leite Ninho', 4 | price: 6, 5 | }, 6 | 2: { 7 | description: 'Alpino', 8 | price: 6, 9 | }, 10 | 3: { 11 | description: 'Prestígio', 12 | price: 6, 13 | }, 14 | 4: { 15 | description: 'Abacaxi', 16 | price: 6, 17 | }, 18 | 5: { 19 | description: 'Dois Amores', 20 | price: 6, 21 | }, 22 | } 23 | -------------------------------------------------------------------------------- /src/server.js: -------------------------------------------------------------------------------- 1 | import { VenomBot } from './venom.js' 2 | import { stages, getStage } from './stages.js' 3 | 4 | const main = async () => { 5 | try { 6 | const venombot = await VenomBot.getInstance().init({ 7 | session: 'Delícias da Neide', 8 | headless: true, 9 | useChrome: false, 10 | }) 11 | 12 | venombot.onMessage(async (message) => { 13 | if (message.isGroupMsg) return 14 | 15 | const currentStage = getStage({ from: message.from }) 16 | 17 | await stages[currentStage].stage.exec({ 18 | from: message.from, 19 | message: message.body, 20 | }) 21 | }) 22 | } catch (error) { 23 | console.error(error) 24 | } 25 | } 26 | 27 | main() 28 | -------------------------------------------------------------------------------- /src/stages.js: -------------------------------------------------------------------------------- 1 | import { 2 | initialStage, 3 | stageOne, 4 | stageTwo, 5 | stageThree, 6 | stageFour, 7 | finalStage, 8 | } from './stages/index.js' 9 | 10 | import { storage } from './storage.js' 11 | 12 | export const stages = [ 13 | { 14 | descricao: 'Welcome', 15 | stage: initialStage, 16 | }, 17 | { 18 | descricao: 'Menu', 19 | stage: stageOne, 20 | }, 21 | { 22 | descricao: 'Address', 23 | stage: stageTwo, 24 | }, 25 | { 26 | descricao: 'Bill', 27 | stage: stageThree, 28 | }, 29 | { 30 | descricao: 'New Order', 31 | stage: stageFour, 32 | }, 33 | { 34 | descricao: 'Assistent', 35 | stage: finalStage, 36 | }, 37 | ] 38 | 39 | export function getStage({ from }) { 40 | if (storage[from]) { 41 | return storage[from].stage 42 | } 43 | 44 | storage[from] = { 45 | stage: 0, 46 | itens: [], 47 | address: '', 48 | } 49 | 50 | return storage[from].stage 51 | } 52 | -------------------------------------------------------------------------------- /src/stages/0.js: -------------------------------------------------------------------------------- 1 | import { storage } from '../storage.js' 2 | import { VenomBot } from '../venom.js' 3 | import { STAGES } from './index.js' 4 | 5 | export const initialStage = { 6 | async exec({ from }) { 7 | storage[from].stage = STAGES.MENU 8 | 9 | const venombot = await VenomBot.getInstance() 10 | 11 | const message = ` 12 | 👋 Olá, como vai? 13 | Eu sou Carlos, o *assistente virtual* da ${venombot.getSessionName}. 14 | *Posso te ajudar?* 🙋‍♂️ 15 | ----------------------------------- 16 | 1️⃣ - FAZER PEDIDO 17 | 2️⃣ - VERIFICAR TAXA DE ENTREGA 18 | 0️⃣ - FALAR COM ATENDENTE 19 | ` 20 | await venombot.sendText({ to: from, message }) 21 | }, 22 | } 23 | -------------------------------------------------------------------------------- /src/stages/1.js: -------------------------------------------------------------------------------- 1 | import { VenomBot } from '../venom.js' 2 | import { menu } from '../menu.js' 3 | import { storage } from '../storage.js' 4 | import { neighborhoods } from './neighborhoods.js' 5 | import { initialStage } from './0.js' 6 | import { STAGES } from './index.js' 7 | 8 | export const stageOne = { 9 | async exec(params) { 10 | const message = params.message.trim() 11 | const isMsgValid = /[0|1|2]/.test(message) 12 | 13 | let msg = 14 | '❌ *Digite uma opção válida, por favor.* \n⚠️ ```APENAS UMA OPÇÃO POR VEZ``` ⚠️' 15 | 16 | if (isMsgValid) { 17 | const option = options[Number(message)]() 18 | msg = option.message 19 | storage[params.from].stage = option.nextStage || STAGES.INICIAL 20 | } 21 | 22 | await VenomBot.getInstance().sendText({ to: params.from, message: msg }) 23 | 24 | if (storage[params.from].stage === STAGES.INICIAL) { 25 | await initialStage.exec(params) 26 | } else if (storage[params.from].stage === STAGES.FALAR_COM_ATENDENTE) { 27 | storage[params.from].finalStage = { 28 | startsIn: new Date().getTime(), 29 | endsIn: new Date().setSeconds(60), // 1 minute of inactivity 30 | } 31 | } 32 | }, 33 | } 34 | 35 | const options = { 36 | 1: () => { 37 | let message = '🚨 CARDÁPIO 🚨\n\n' 38 | 39 | Object.keys(menu).forEach((value) => { 40 | message += `${numbers[value]} - _${menu[value].description}_ \n` 41 | }) 42 | 43 | return { 44 | message, 45 | nextStage: STAGES.CARRINHO, 46 | } 47 | }, 48 | 2: () => { 49 | const message = 50 | '\n-----------------------------------\n1️⃣ - ```FAZER PEDIDO``` \n0️⃣ - ```FALAR COM ATENDENTE```\n\n' + 51 | neighborhoods + 52 | '\n-----------------------------------\n1️⃣ - ```FAZER PEDIDO``` \n0️⃣ - ```FALAR COM ATENDENTE``` ' 53 | 54 | return { 55 | message, 56 | nextStage: null, 57 | } 58 | }, 59 | 0: () => { 60 | return { 61 | message: 62 | '🔃 Encaminhando você para um atendente. \n⏳ *Aguarde um instante*.\n \n⚠️ A qualquer momento, digite *ENCERRAR* para encerrar o atendimento. ⚠️', 63 | nextStage: STAGES.FALAR_COM_ATENDENTE, 64 | } 65 | }, 66 | } 67 | 68 | const numbers = { 69 | 1: '1️⃣', 70 | 2: '2️⃣', 71 | 3: '3️⃣', 72 | 4: '4️⃣', 73 | 5: '5️⃣', 74 | } 75 | -------------------------------------------------------------------------------- /src/stages/2.js: -------------------------------------------------------------------------------- 1 | import { VenomBot } from '../venom.js' 2 | import { menu } from '../menu.js' 3 | import { storage } from '../storage.js' 4 | import { STAGES } from './index.js' 5 | 6 | export const stageTwo = { 7 | async exec(params) { 8 | const message = params.message.trim() 9 | const isMsgValid = /[1|2|3|4|5|#|*]/.test(message) 10 | 11 | let msg = 12 | '❌ *Digite uma opção válida, por favor.* \n⚠️ ```APENAS UMA OPÇÃO POR VEZ``` ⚠️' 13 | 14 | if (isMsgValid) { 15 | if (['#', '*'].includes(message)) { 16 | const option = options[message]() 17 | msg = option.message 18 | storage[params.from].stage = option.nextStage 19 | } else { 20 | msg = 21 | `✅ *${menu[message].description}* adicionado com sucesso! \n\n` + 22 | '```Digite outra opção```: \n\n' + 23 | '\n-----------------------------------\n#️⃣ - ```FINALIZAR pedido``` \n*️⃣ - ```CANCELAR pedido```' 24 | storage[params.from].itens.push(menu[message]) 25 | } 26 | 27 | if (storage[params.from].stage === STAGES.INICIAL) { 28 | storage[params.from].itens = [] 29 | } 30 | } 31 | 32 | await VenomBot.getInstance().sendText({ to: params.from, message: msg }) 33 | }, 34 | } 35 | 36 | const options = { 37 | '*': () => { 38 | const message = 39 | '🔴 Pedido *CANCELADO* com sucesso. \n\n ```Volte Sempre!```' 40 | 41 | return { 42 | message, 43 | nextStage: STAGES.INICIAL, 44 | } 45 | }, 46 | '#': () => { 47 | const message = 48 | '🗺️ Agora, informe o *ENDEREÇO*. \n ( ```Rua, Número, Bairro``` ) \n\n ' + 49 | '\n-----------------------------------\n*️⃣ - ```CANCELAR pedido```' 50 | 51 | return { 52 | message, 53 | nextStage: STAGES.RESUMO, 54 | } 55 | }, 56 | } 57 | -------------------------------------------------------------------------------- /src/stages/3.js: -------------------------------------------------------------------------------- 1 | import { VenomBot } from '../venom.js' 2 | import { storage } from '../storage.js' 3 | import { STAGES } from './index.js' 4 | 5 | export const stageThree = { 6 | async exec({ from, message }) { 7 | storage[from].address = message 8 | storage[from].stage = STAGES.PEDIDO 9 | 10 | let msg = 'Pedido *CANCELADO* com sucesso. \n Volte Sempre!' 11 | if (message === '*') { 12 | storage[from].stage = STAGES.INICIAL 13 | } else { 14 | const itens = storage[from].itens 15 | const desserts = itens.map((item) => item.description).join(', ') 16 | 17 | const total = storage[from].itens.length 18 | 19 | msg = 20 | `🗒️ *RESUMO DO PEDIDO*: \n\n🧁 Sabores: *${desserts}* \n🚚 Taxa de entrega: *a confirmar*. \n📍 Endereço: *${message}* \n💰 Valor dos bolos: *${ 21 | total * 6 22 | },00 reais*. \n⏳ Tempo de entrega: *50 minutos*. \n\n` + 23 | '🔊 ```Agora, informe a forma de pagamento e se vai precisar de troco, por gentileza.```' 24 | } 25 | 26 | await VenomBot.getInstance().sendText({ to: from, message: msg }) 27 | 28 | // return '✅ *Prontinho, pedido feito!* \n\nAgora, se você ainda não sabe o valor da taxa de entrega para sua região, vou te passar para um atendente para que ele verique o valor da *taxa de entrega*. \n\n⏳ *Aguarde um instante*.' 29 | }, 30 | } 31 | -------------------------------------------------------------------------------- /src/stages/4.js: -------------------------------------------------------------------------------- 1 | import { VenomBot } from '../venom.js' 2 | import { storage } from '../storage.js' 3 | import { STAGES } from './index.js' 4 | 5 | export const stageFour = { 6 | async exec({ from, message }) { 7 | const address = storage[from].address 8 | const phone = from.split('@') 9 | 10 | storage[from].stage = STAGES.FALAR_COM_ATENDENTE 11 | 12 | storage[from].finalStage = { 13 | startsIn: new Date().getTime(), 14 | endsIn: new Date().setSeconds(60), // 1 minute of inactivity 15 | } 16 | 17 | const itens = storage[from].itens 18 | const desserts = itens.map((item) => item.description).join(', ') 19 | const total = storage[from].itens.length 20 | 21 | const msg = `🔔 *NOVO PEDIDO* 🔔: \n\n📞 Cliente: +${ 22 | phone[0] 23 | } \n🧁 Sabores: *${desserts}* \n📍 Endereço: *${address}* \n🚚 Taxa de entrega: *a confirmar*. \n💰 Valor dos bolos: *${ 24 | total * 6 25 | },00 reais*. \n⏳ Tempo de entrega: *50 minutos*. \n🛑 Detalhes: *${message}*` 26 | 27 | await VenomBot.getInstance().sendText({ to: from, message: msg }) 28 | }, 29 | } 30 | -------------------------------------------------------------------------------- /src/stages/5.js: -------------------------------------------------------------------------------- 1 | import { VenomBot } from '../venom.js' 2 | import { storage } from '../storage.js' 3 | import { STAGES } from './index.js' 4 | 5 | export const finalStage = { 6 | async exec({ from, message }) { 7 | const msg = message.trim().toUpperCase() 8 | 9 | const currentDate = new Date() 10 | const history = storage[from].finalStage 11 | 12 | if (history.endsIn < currentDate.getTime() || msg === 'ENCERRAR') { 13 | storage[from].stage = STAGES.INICIAL 14 | return VenomBot.getInstance().sendText({ 15 | to: from, 16 | message: '🔚 *Atendimento encerrado* 🔚', 17 | }) 18 | } 19 | 20 | storage[from].finalStage.endsIn = new Date().setSeconds(60) // more 1 minute of inactivity 21 | }, 22 | } 23 | -------------------------------------------------------------------------------- /src/stages/index.js: -------------------------------------------------------------------------------- 1 | export * from './0.js' 2 | export * from './1.js' 3 | export * from './2.js' 4 | export * from './3.js' 5 | export * from './4.js' 6 | export * from './5.js' 7 | 8 | export const STAGES = { 9 | INICIAL: '0', 10 | MENU: '1', 11 | CARRINHO: '2', 12 | RESUMO: '3', 13 | PEDIDO: '4', 14 | FALAR_COM_ATENDENTE: '5', 15 | } 16 | -------------------------------------------------------------------------------- /src/stages/neighborhoods.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-multi-str */ 2 | export const neighborhoods = 3 | 'Abraão Alab --> *5 reais* \ 4 | \nAdalberto Aragão --> *5 reais* \ 5 | \nAeroporto Velho --> *5 reais* \ 6 | \nAreial --> *6 reais* \ 7 | \nAviário --> *5 reais* \ 8 | \nAyrton Senna --> *7 reais* \ 9 | \nBahia Nova --> *7 reais* \ 10 | \nBahia Velha --> *7 reais* \ 11 | \nBairro XV --> *5 reais* \ 12 | \nBairro da Base --> *5 reais* \ 13 | \nBairro da Paz --> *5 reais* \ 14 | \nBoa União --> *7 reais* \ 15 | \nBosque --> *5 reais* \ 16 | \nCadeia Velha --> *5 reais* \ 17 | \nCaladinho --> *7 reais* \ 18 | \nCalafate --> *8 reais* \ 19 | \nCapoeira --> *5 reais* \ 20 | \nCentro --> *5 reais* \ 21 | \nCerâmica --> *5 reais* \ 22 | \nChico Mendes --> *5 reais* \ 23 | \nCidade Nova --> *5 reais* \ 24 | \nConjunto Adalberto Sena --> *5 reais* \ 25 | \nConjunto Bela Vista --> *5 reais* \ 26 | \nConjunto Castelo Branco --> *5 reais* \ 27 | \nConjunto Esperança I e II --> *5 reais* \ 28 | \nConjunto Guiomard Santos --> *5 reais* \ 29 | \nConjunto Mariana --> *6 reais* \ 30 | \nConjunto Mascarenha de Morais --> *5 reais* \ 31 | \nConjunto Rui Lino --> *6 reais* \ 32 | \nConjunto Tancredo Neves --> *5 reais* \ 33 | \nConjunto Tangará --> *5 reais* \ 34 | \nConjunto Tucumã I --> *7 reais* \ 35 | \nConjunto Tucumã II --> *7 reais* \ 36 | \nConjunto Xavier Maia --> *5 reais* \ 37 | \nConquista --> *5 reais* \ 38 | \nDefesa Civil --> *5 reais* \ 39 | \nDoca Furtado --> *5 reais* \ 40 | \nEldorado --> *5 reais* \ 41 | \nEstação Experimental --> *5 reais* \ 42 | \nFloresta --> *6 reais* \ 43 | \nFloresta Sul --> *8 reais* \ 44 | \nGeraldo Fleming --> *5 reais* \ 45 | \nHabitasa --> *6 reais* \ 46 | \nIpase --> *5 reais* \ 47 | \nIpê --> *8 reais* \ 48 | \nIrineu Serra --> *7 reais* \ 49 | \nIvete Vargas --> *5 reais* \ 50 | \nIsaura Parente --> *5 reais* \ 51 | \nJardim Brasil --> *5 reais* \ 52 | \nJardim Europa --> *5 reais* \ 53 | \nJardim Primavera --> *6 reais* \ 54 | \nJoão Eduardo I --> *5 reais* \ 55 | \nJoão Eduardo II --> *5 reais*\ 56 | \nJorge Lavocat --> *5 reais* \ 57 | \nLoteamento Novo Horizonte --> *5 reais* \ 58 | \nManoel Julião --> *5 reais* \ 59 | \nMocinha Magalhães --> *7 reais* \ 60 | \nMontanhês --> *5 reais* \ 61 | \nMorada do Sol --> *5 reais* \ 62 | \nNova Estação --> *5 reais* \ 63 | \nPalheiral --> *6 reais* \ 64 | \nPapouco --> *5 reais* \ 65 | \nParque dos Sabiás --> *5 reais* \ 66 | \nPista --> *5 reais* \ 67 | \nPlacas --> *5 reais* \ 68 | \nPortal da Amazônia Placas --> *8 reais* \ 69 | \nRaimundo Melo --> *5 reais* \ 70 | \nResidencial Ouricuri --> *5 reais* \ 71 | \nSanta Inês --> *8 reais* \ 72 | \nSão Francisco --> *5 reais* \ 73 | \nSeis de Agosto --> *5 reais* \ 74 | \nSobral --> *5 reais* \ 75 | \nTropical --> *5 reais* \ 76 | \nVila Ivonete --> *5 reais* \ 77 | \nVila Nova --> *5 reais* \ 78 | \nVillage --> *5 reais* \ 79 | \nVitória --> *5 reais* \ 80 | \nVolta Seca --> *5 reais* \ 81 | \nWanderley Dantas --> *5 reais*' 82 | -------------------------------------------------------------------------------- /src/storage.js: -------------------------------------------------------------------------------- 1 | export const storage = Object.create({}) 2 | -------------------------------------------------------------------------------- /src/venom.js: -------------------------------------------------------------------------------- 1 | import { create } from 'venom-bot' 2 | 3 | export class VenomBot { 4 | #venombot 5 | 6 | #session 7 | 8 | static getInstance() { 9 | if (VenomBot.instance === undefined) VenomBot.instance = new VenomBot() 10 | return VenomBot.instance 11 | } 12 | 13 | async init({ session, headless, useChrome }) { 14 | this.#session = session 15 | this.#venombot = await create({ 16 | session, 17 | headless, 18 | useChrome, 19 | multidevice: false, 20 | }) 21 | 22 | return this 23 | } 24 | 25 | get getSessionName() { 26 | return this.#session 27 | } 28 | 29 | async onMessage(callback) { 30 | if (!this.#venombot) throw new Error('VenomBot not initialized.') 31 | return await this.#venombot.onMessage(callback) 32 | } 33 | 34 | async sendText({ to, message }) { 35 | if (!this.#venombot) throw new Error('VenomBot not initialized.') 36 | return await this.#venombot.sendText(to, message) 37 | } 38 | 39 | // Is not working 40 | // async sendButtons({ to, title, buttons, description }) { 41 | // if (!this.#venombot) throw new Error('VenomBot not initialized.') 42 | 43 | // return await this.#venombot.sendButtons( 44 | // to, 45 | // title, 46 | // buttons, 47 | // description, 48 | // ) 49 | // } 50 | 51 | async markUnseenMessage({ to }) { 52 | if (!this.#venombot) throw new Error('VenomBot not initialized.') 53 | return await this.#venombot.markUnseenMessage(to) 54 | } 55 | } 56 | --------------------------------------------------------------------------------