canove / whaticket-community

A very simple Ticket System based on WhatsApp messages, that allow multi-users in same WhatsApp account.
MIT License
1.67k stars 845 forks source link

[Feature Suggestion] Recurso de Cadastramento na primeira interação. #47

Closed andersondeoliveiramachado closed 4 years ago

andersondeoliveiramachado commented 4 years ago

Seria possível , quando receber a primeira mensagem , colocar o número que fez contato em um estado de "Questionário" aonde ele deve responder perguntas , como :

Qual seu Nome ? Qual Idade ? Qual Cidade ?

Algumas respostas necessitam de validação e algumas de confirmação.

Um exemplo :

image

image

srgoogle23 commented 4 years ago

you can do this with a bot and make the users answer just after that

andersondeoliveiramachado commented 4 years ago

O Código a baixo já está funcionando. Mas sou bem iniciante em Nodejs, então não sei se é a melhor forma de fazer o recurso. image

`wbot.on("message_create", async msg => {

if (!isValidMsg(msg)) {
  return;
}

try {
  let msgContact: WbotContact;
  let groupContact: Contact | undefined;

  if (msg.fromMe) {

    msgContact = await wbot.getContactById(msg.to);

    // return if it's a media message, it will be handled by media_uploaded event

    if (!msg.hasMedia && msg.type !== "chat" && msg.type !== "vcard")
      return;
  } else {

    msgContact = await msg.getContact();

    if(msg.body.toLowerCase()=='oi') {
      wbot.sendMessage(msg.from,'Olá');
      console.log('automatic response oi -> olá');
      return;
    }

  }

  const chat = await msg.getChat();

  if (chat.isGroup) {
    let msgGroupContact;

    if (msg.fromMe) {
      msgGroupContact = await wbot.getContactById(msg.to);
    } else {
      msgGroupContact = await wbot.getContactById(msg.from);
    }

    groupContact = await verifyGroup(msgGroupContact);
  }

  const profilePicUrl = await msgContact.getProfilePicUrl();
  const contact = await verifyContact(msgContact,profilePicUrl);
  const ticket = await verifyTicket(contact, whatsappId, groupContact);

  if (msg.fromMe) {

    // mensagem enviada pelo bot

  } else {

    console.log('DEBUG - contact - inicio');
    //console.log(contact);
    console.log(contact.phase+' '+contact.stage);
    console.log('DEBUG - contact - fim');

    if(contact.phase=='registered') {

      if(contact.stage=='main.menu') {
          wbot.sendMessage(msg.from,'Apresentar o menu principal do sistema.');
      } // fim - if(contact.stage=='main.menu') {

    } // fim - if(contact.phase=='registered') {

    if(contact.phase=='register') {

      if(contact.stage=='name.ask') {

        var welcome = '';

        if(contact.welcome) {

        } else { 
          welcome = 'Seja muito bem vindo ao sistema.\n';
        }

        const contactToUpdate = await Contact.findOne({
          where: { id: contact.id }
        });
        if (contactToUpdate) {  
          await contactToUpdate.update({
            phase:'register',
            stage: 'name.response',
            welcome: 1
          });
          wbot.sendMessage(msg.from,'(1)'+welcome+'Qual o seu nome e sobrenome ?');
        }

      } // fim - if(contact.stage=='name.ask') {

      if(contact.stage=='name.response.confirm') {

        var resposta = msg.body;
        var log = 'Confirmar se resposta=['+resposta+'] está dentro das respostas';
        log += 'válidas=['+contact.validresponses+']';

        console.log(log);

        // validar se a resposta da pergunta é valida
        var valida = false;
        if( (String(resposta).toUpperCase()=='SIM') || 
            (String(resposta).toUpperCase()=='NAO') ||
            (String(resposta).toUpperCase()=='NÃO') 
        ) {
          valida = true;
        } else {
          valida = false;  
        }

        if(valida==true) {

          // resposta válida

          if(String(resposta).toUpperCase()=='SIM') {

            //  grava a resposta anterior no campo indicado

            const contactToUpdate = await Contact.findOne({
              where: { id: contact.id }
            });
            if (contactToUpdate) {  
              await contactToUpdate.update({
                name: contactToUpdate.previousanswer, 
                phase:'registered',
                stage:'main.menu',                  
                isAsking: false, 
                previousanswer: '',
                question: '',
                validresponses: ''
              });
              wbot.sendMessage(msg.from,'Apresentar o menu principal do sistema.');
            }
          } else if( 
              (String(resposta).toUpperCase()=='NAO') ||
              (String(resposta).toUpperCase()=='NÃO') 
          ) {

            // apresenta novamente a pergunta do nome
            const contactToUpdate = await Contact.findOne({
              where: { id: contact.id }
            });
            if (contactToUpdate) {  
              await contactToUpdate.update({
                phase:'register',
                stage: 'name.response',
                welcome: 1
              });
              wbot.sendMessage(msg.from,'(1-confirmation) Qual o seu nome e sobrenome ?');
            }
          }

        } else {

          // resposta inválida , repete a pergunta 
          var message = 'Resposta Inválida.\n';
          message += contact.question;
          wbot.sendMessage(msg.from,message);

        }

      } // fim - if(contact.stage=='name.response.confirm') {

      if(contact.stage=='name.response') {

        var valido = false;
        var regName = /^[a-zA-Z]+ [a-zA-Z]+$/;
        var name = msg.body;
        if(!regName.test(name)){
          valido = false;
        }else{
          valido = true;
        }

        if(valido==true) {

          // válido , salva a resposta e coloca em confirmação
          var question = `Você informou : ${name}`;
          question+= 'O seu nome está correto ( Sim ou Não ) ?';
          var validresponses = 'SIM|NÃO|NAO';

          const contactToUpdate = await Contact.findOne({
            where: { id: contact.id }
          });
          if (contactToUpdate) {  
            await contactToUpdate.update({
              stage: 'name.response.confirm',
              isAsking: true, 
              previousanswer: name,
              question: question,
              validresponses: validresponses
            });
            wbot.sendMessage(msg.from,question);
          }

        } else {
          // inválido perguntar novamente o nome
          const contactToUpdate = await Contact.findOne({
            where: { id: contact.id }
          });
          if (contactToUpdate) {  
            await contactToUpdate.update({ 
              phase:'register',
              stage:'name.response'
            });
            wbot.sendMessage(msg.from,'(2)Nome Inválido.\nInforme : Nome Sobrenome\nQual o seu nome ?');
          }
        }
      } // fim - if(contact.stage=='name.response') {

    } // fim if(contact.phase=='register') {

  }

  await handleMessage(msg, ticket, contact);

} catch (err) {
  Sentry.captureException(err);
  console.log(err);
}

});`

srgoogle23 commented 4 years ago

where did u put this code on whaticket and why u dont make it a bot with dialogflow and integrate with whatsapp directly and make the whaticket receive the a specific message after signup the client with the bot?

srgoogle23 commented 4 years ago

but yes, this is not the best method, but it is the most symple

canove commented 4 years ago

Hey guys! Its a great ideia to add some automated messages to Whaticket, but it's not on my roadmap.

I think the right implementation should let the user (or some admin user) create the messages tree, and not having it hardcoded on backend.

Since its not going to be implemented soon, I'm closing this issue.

maxivane commented 3 years ago

Up, estou implementando este recurso