TYPEBOT + BOTÕES
100% Grátis

TYPEBOT + BOTÕES
 
1- INSTALAR GIT E NODE
2- INSTALAR A API
a. criar pasta e arquivos (js, html, package.json e icones)
b. npm install
c. node botzdg_typebot_botoes.js

index.html

				
					<!DOCTYPE html>
<html>
<head>
	<title>WPP API by Pedrinho da NASA</title>
</head>
<body>

	<div id="app">
		<h1>WPP API</h1>
		<h3>Entre agora para comunidade ZDG: <a href="https://comunidadezdg.com.br/">clique aqui</a></h3>
		<p>ZDG MOD</p>
		<img decoding="async" src="" alt="QR Code" id="qrcode">
		<h3>Logs:</h3>
		<ul class="logs"></ul>
	</div>

	<script type="rocketlazyloadscript" data-minify="1" src="https://comunidadezdg.com.br/wp-content/cache/min/1/ajax/libs/jquery/3.5.1/jquery.min.js?ver=1736924062" crossorigin="anonymous" defer></script>
	<script type="rocketlazyloadscript" data-minify="1" src="https://comunidadezdg.com.br/wp-content/cache/min/1/ajax/libs/socket.io/2.3.0/socket.io.js?ver=1736924062" crossorigin="anonymous" defer></script>
	<script type="rocketlazyloadscript">window.addEventListener('DOMContentLoaded', function() {
		$(document).ready(function() {
			var socket = io();

			socket.on('message', function(msg) {
				$('.logs').append($('<li>').text(msg));
			});

			socket.on('qr', function(src) {
				$('#qrcode').attr('src', src);
				$('#qrcode').show();
			});

			socket.on('ready', function(data) {
				$('#qrcode').hide();
			});

			socket.on('authenticated', function(data) {
				$('#qrcode').hide();
			});
		});
	});</script>
<script>class RocketElementorAnimation{constructor(){this.deviceMode=document.createElement("span"),this.deviceMode.id="elementor-device-mode",this.deviceMode.setAttribute("class","elementor-screen-only"),document.body.appendChild(this.deviceMode)}_detectAnimations(){let t=getComputedStyle(this.deviceMode,":after").content.replace(/"/g,"");this.animationSettingKeys=this._listAnimationSettingsKeys(t),document.querySelectorAll(".elementor-invisible[data-settings]").forEach(t=>{const e=t.getBoundingClientRect();if(e.bottom>=0&&e.top<=window.innerHeight)try{this._animateElement(t)}catch(t){}})}_animateElement(t){const e=JSON.parse(t.dataset.settings),i=e._animation_delay||e.animation_delay||0,n=e[this.animationSettingKeys.find(t=>e[t])];if("none"===n)return void t.classList.remove("elementor-invisible");t.classList.remove(n),this.currentAnimation&&t.classList.remove(this.currentAnimation),this.currentAnimation=n;let s=setTimeout(()=>{t.classList.remove("elementor-invisible"),t.classList.add("animated",n),this._removeAnimationSettings(t,e)},i);window.addEventListener("rocket-startLoading",function(){clearTimeout(s)})}_listAnimationSettingsKeys(t="mobile"){const e=[""];switch(t){case"mobile":e.unshift("_mobile");case"tablet":e.unshift("_tablet");case"desktop":e.unshift("_desktop")}const i=[];return["animation","_animation"].forEach(t=>{e.forEach(e=>{i.push(t+e)})}),i}_removeAnimationSettings(t,e){this._listAnimationSettingsKeys().forEach(t=>delete e[t]),t.dataset.settings=JSON.stringify(e)}static run(){const t=new RocketElementorAnimation;requestAnimationFrame(t._detectAnimations.bind(t))}}document.addEventListener("DOMContentLoaded",RocketElementorAnimation.run);</script></body>
</html>

				
			

package.json

				
					{"name":"bot-zdg","version":"1.0.0","description":"bot-zdg: based on Whatsapp API","main":"app.js","scripts":{"start":"node .\botzdg_typebot_stop.js","start:dev":"nodemon app.js","test":"echo \"Error: no test specified\" && exit 1"},"keywords":["whatsapp-api","node.js"],"author":"Pedro","license":"MIT","dependencies":{"axios":"^1.5.0","express":"^4.17.1","express-fileupload":"^1.2.0","express-validator":"^6.9.2","http":"0.0.1-security","qrcode":"^1.4.4","qrcode-terminal":"^0.12.0","socket.io":"2.3.0","whatsapp-web.js":"github:alechkos\/whatsapp-web.js#polls-ext"},"devDependencies":{"nodemon":"^2.0.19"}}
				
			

botzdg_typebot_botoes.js

				
					// BACKEND DA API
// BIBLIOTECAS UTILIZADAS PARA COMPOSIÇÃO DA API
const { Client, LocalAuth, MessageMedia, Poll } = require('whatsapp-web.js');
const express = require('express');
const socketIO = require('socket.io');
const qrcode = require('qrcode');
const http = require('http');
const fileUpload = require('express-fileupload');
const app = express();
const server = http.createServer(app);
const io = socketIO(server);
const axios = require('axios');
const fs = require('fs');
const path = require('path');

// PORTA ONDE O SERVIÇO SERÁ INICIADO
const port = 8000;
const idClient = 'bot-zdg';

// DADOS TYPEBOT
const url = 'https://botzdgtype.comunidadezdg.com.br/api/v1/sendMessage';
const typebot = 'zdg2';
const dirBot = './typebot';
if (!fs.existsSync(dirBot)){
    fs.mkdirSync(dirBot)
}

// SERVIÇO EXPRESS
app.use(express.json());
app.use(express.urlencoded({
  extended: true
}));
app.use(fileUpload({
  debug: true
}));
app.use("/", express.static(__dirname + "/"))
app.get('/', (req, res) => {
  res.sendFile('index.html', {
    root: __dirname
  });
});

// PARÂMETROS DO CLIENT DO WPP
const client = new Client({
  authStrategy: new LocalAuth({ clientId: idClient }),
  puppeteer: { headless: true,
    // CAMINHO DO CHROME PARA WINDOWS (REMOVER O COMENTÁRIO ABAIXO)
    //executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
    //===================================================================================
    // CAMINHO DO CHROME PARA MAC (REMOVER O COMENTÁRIO ABAIXO)
    //executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
    //===================================================================================
    // CAMINHO DO CHROME PARA LINUX (REMOVER O COMENTÁRIO ABAIXO)
    //executablePath: '/usr/bin/google-chrome-stable',
    //===================================================================================
    args: [
      '--no-sandbox',
      '--disable-setuid-sandbox',
      '--disable-dev-shm-usage',
      '--disable-accelerated-2d-canvas',
      '--no-first-run',
      '--no-zygote',
      '--single-process', // <- this one doesn't works in Windows
      '--disable-gpu'
    ] }
});

// INITIALIZE DO CLIENT DO WPP
client.initialize();

// EVENTOS DE CONEXÃO EXPORTADOS PARA O INDEX.HTML VIA SOCKET
io.on('connection', function(socket) {
  socket.emit('message', '© BOT-ZDG - Iniciado');
  socket.emit('qr', './icon.svg');

client.on('qr', (qr) => {
    console.log('QR RECEIVED', qr);
    qrcode.toDataURL(qr, (err, url) => {
      socket.emit('qr', url);
      socket.emit('message', '© BOT-ZDG QRCode recebido, aponte a câmera  seu celular!');
    });
});

client.on('ready', async () => {
    socket.emit('ready', '© BOT-ZDG Dispositivo pronto!');
    socket.emit('message', '© BOT-ZDG Dispositivo pronto!');
    socket.emit('qr', './check.svg')	
    console.log('© BOT-ZDG Dispositivo pronto');
});

client.on('authenticated', () => {
    socket.emit('authenticated', '© BOT-ZDG Autenticado!');
    socket.emit('message', '© BOT-ZDG Autenticado!');
    console.log('© BOT-ZDG Autenticado');
});

client.on('auth_failure', function() {
    socket.emit('message', '© BOT-ZDG Falha na autenticação, reiniciando...');
    console.error('© BOT-ZDG Falha na autenticação');
});

client.on('change_state', state => {
  console.log('© BOT-ZDG Status de conexão: ', state );
});

client.on('disconnected', (reason) => {
  socket.emit('message', '© BOT-ZDG Cliente desconectado!');
  console.log('© BOT-ZDG Cliente desconectado', reason);
  client.initialize();
});
});

// INTEGRAÇÃO TYPEBOT
function deleteDirectory(dirPath) {
  if (fs.existsSync(dirPath)) {
    const files = fs.readdirSync(dirPath);
    files.forEach((file) => {
      const filePath = path.join(dirPath, file);
      if (fs.statSync(filePath).isDirectory()) {
        deleteDirectory(filePath);
      } else {
        fs.unlinkSync(filePath);
      }
    });
    try {
      fs.rmdirSync(dirPath);
      console.log(`Diretório ${dirPath} deletado com sucesso.`);
    } catch (error) {
      console.error(`Erro ao deletar diretório ${dirPath}:`, error);
    }
  } else {
    console.log(`O diretório ${dirPath} não existe.`);
  }
}

async function readWriteFileJson(sessionId, from) {
  let dataFile = [];
  fs.writeFileSync("./typebot/" + from + "/typebot.json", JSON.stringify(dataFile));
  var data = fs.readFileSync("./typebot/" + from + "/typebot.json");
  var myObject = JSON.parse(data);
  let newData = {
    id: sessionId,
  };
  await myObject.push(newData);
  fs.writeFileSync("./typebot/" + from + "/typebot.json", JSON.stringify(myObject));
}

async function createSession(data){
  const reqData = {
    sessionId: data.from,
    startParams: {
      typebot: typebot,
      prefilledVariables: {
        number: data.from.split('@')[0],
        name: data.notifyName
      },
    },
  };
  const request = await axios.post(url, reqData);
  const dirFrom = './typebot/' + data.from.replace(/\D/g,'');
  if (!fs.existsSync(dirFrom)){
    fs.mkdirSync(dirFrom);
    await readWriteFileJson(request.data.sessionId, data.from.replace(/\D/g,''));
  }
}

// EVENTO DE ESCUTA/ENVIO DE MENSAGENS RECEBIDAS PELA API
client.on('message', async msg => {
  const dirFrom = './typebot/' + msg.from.replace(/\D/g,'');
  if (!fs.existsSync(dirFrom)){
    await createSession(msg);
  }
  if (msg.body !== 'sair'){
    const from = msg.from.replace(/\D/g,'');
    const sessionId = fs.readFileSync("./typebot/" + from + "/typebot.json","utf8").split(':')[1].replace(/\W/g, '');
    const content = msg.body;
    const reqData = {
        message: content,
        sessionId: sessionId,
    };
    const request = await axios.post(url, reqData);
    const messages = request.data.messages
    for (const message of messages){
      if (message.type === 'text') {
        let formattedText = '';
        for (const richText of message.content.richText){
          for (const element of richText.children){
            let text = '';
            if (element.text) {
                text = element.text;
            }
            if (element.bold) {
                text = `*${text}*`;
            }
            if (element.italic) {
                text = `_${text}_`;
            }
            if (element.underline) {
                text = `~${text}~`;
            }
            formattedText += text;          
          }
          formattedText += '\n';
        }
        formattedText = formattedText.replace(/\n$/, '');
        await client.sendMessage(msg.from, formattedText);
      }
      if (message.type === 'image' || message.type === 'video') {
        console.log(message)
        try{
          const media = await MessageMedia.fromUrl(message.content.url)
          await client.sendMessage(msg.from, media, {caption: 'Comunidade ZDG'})
        }catch(e){}
      }
      if (message.type === 'audio') {
        console.log(message)
        try{
          const media = await MessageMedia.fromUrl(message.content.url)
          await client.sendMessage(msg.from, media, {sendAudioAsVoice: true})
        }catch(e){}
      }
    }
    const input = request.data.input
    if (input) {
      if (input.type === 'choice input') {
        let formattedText = '';
        const items = input.items;
        let arrayoptions = [];
        for (const item of items) {
          formattedText += `▶️ ${item.content}\n`;
          arrayoptions.push(item.content);
        }
        console.log(arrayoptions)
          // await msg.reply(new Poll('Winter or Summer?', [arrayoptions]));
          // formattedText = formattedText.replace(/\n$/, '');
          await client.sendMessage(msg.from, new Poll('Escolha uma opção:', arrayoptions));
        }
    }
  }
  if (msg.body === 'sair'){
    deleteDirectory(dirFrom)
    await client.sendMessage(msg.from, 'Atendimento automático reiniciado.')
  }
});

// EVENTO DE ESCUTA DAS RESPOSTAS DO BOTÃO
client.on('vote_update', async (vote) => {
  console.log(vote.selectedOptions.map(option => option.name))
  const from = vote.voter.replace(/\D/g,'');
  const sessionId = fs.readFileSync("./typebot/" + from + "/typebot.json","utf8").split(':')[1].replace(/\W/g, '');
  const content = vote.selectedOptions.map(option => option.name);
  client.sendMessage(vote.voter, 'Você escolheu a opção: ' + content.toString() + '... aguarde!')
  const reqData = {
    message: content.toString(),
    sessionId: sessionId,
  };
  const request = await axios.post(url, reqData);
  const messages = request.data.messages
  for (const message of messages){
      if (message.type === 'text') {
        let formattedText = '';
        for (const richText of message.content.richText){
          for (const element of richText.children){
            let text = '';
            if (element.text) {
                text = element.text;
            }
            if (element.bold) {
                text = `*${text}*`;
            }
            if (element.italic) {
                text = `_${text}_`;
            }
            if (element.underline) {
                text = `~${text}~`;
            }
            formattedText += text;          
          }
          formattedText += '\n';
        }
        formattedText = formattedText.replace(/\n$/, '');
        await client.sendMessage(vote.voter, formattedText);
      }
      if (message.type === 'image' || message.type === 'video') {
        console.log(message)
        try{
          const media = await MessageMedia.fromUrl(message.content.url)
          await client.sendMessage(vote.voter, media, {caption: 'Comunidade ZDG'})
        }catch(e){}
      }
      if (message.type === 'audio') {
        console.log(message)
        try{
          const media = await MessageMedia.fromUrl(message.content.url)
          await client.sendMessage(vote.voter, media, {sendAudioAsVoice: true})
        }catch(e){}
      }
  }
  const input = request.data.input
  if (input) {
      if (input.type === 'choice input') {
        let formattedText = '';
        const items = input.items;
        let arrayoptions = [];
        for (const item of items) {
          formattedText += `▶️ ${item.content}\n`;
          arrayoptions.push(item.content);
        }
        console.log(arrayoptions)
          // await msg.reply(new Poll('Winter or Summer?', [arrayoptions]));
          // formattedText = formattedText.replace(/\n$/, '');
          await client.sendMessage(vote.voter, new Poll('Escolha uma opção:', arrayoptions));
        }
  }
  console.log(vote)
  const msgToEdit = vote.parentMessage
  // await msgToEdit.delete(true)
  msgToEdit.body.replace('Escolha uma opção:', 'Resposta armazenada')
  await msgToEdit.delete(true)
  // await client.sendMessage(vote.voter, 'Você escolheu a opção: ' + content.toString())
  // await msgToEdit.pollOptions.replace(msgToEdit.pollOptions, [''])
});

// INITIALIZE DO SERVIÇO    
server.listen(port, function() {
  console.log('© Comunidade ZDG - Aplicativo rodando na porta *: ' + port);
});
				
			

Um poderoso sistema de blocos integrado ao whatsapp do seu negócio

 

🔗 Conector API para WhatsApp

🧩Blocos de bolha (texto, áudio, vídeo e imagens) – usados para exibir informações ao usuário.

🧩 Blocos de entrada – usados para solicitar entrada do usuário. Isso interromperá a conversa e o usuário fornecerá informações.

🧩Os blocos lógicos – usados para realizar operações em segundo plano. Eles não são visíveis para os usuários.

🧩 Os blocos de integração – usados para acionar operações de serviços externos.

Conheça alguns dos alunos da melhor comunidade de marketing de conversa do Brasil

E entenda porque tanta gente está economizando tempo e ganhando dinheiro explorando robôs e automações, mesmo sem nunca antes ter tido contato com uma API.

"O Pedrinho pega na nossa mão. Se eu consegui, você também consegue."

"Eu sou desenvolvedor de sistemas, e venho utilizando as soluções do Pedrinho para integrar nos meus sistemas, e o ganho de tempo é excepcional."

"O Pedrinho tem uma didática excelente e com o curso dele, consegui colocar minha API para rodar 24 horas e estou fazendo vendas todos os dias."

"A estratégia mais eficiente e totalmente escalável."

Comunidade ZDG © 2023 | CNPJ: 35.617.749/0001-67 | Razão Social: BIANCA SANT ANA PEREIRA 10398514607
Rua Alaor Ferreira da Fonseca, 295, CEP 37.136-132, Alfenas – MG | Tel: (35) 9 8875-4197 | E-mail: [email protected] | Política de Privacidade | Termos de Uso
Art. 49 do Código de Defesa do Consumidor | GARANTIA TOTAL DE 7 DIAS | Este produto não garante a obtenção de resultados. Qualquer referência ao desempenho de uma estratégia não deve ser interpretada como uma garantia de resultados.