Neste artigo veremos como é possível cadastrar um usuário no seu database e, ao mesmo tempo, inserir esse usuário numa lista do MailingBoss, onde é possível automatizar uma sequência de ações de marketing via E-mails. Ou seja, você põe um “robô” digital para interagir com seus leads até conseguir efetuar uma venda… ou o que você imaginar.
O problema
Usando o MailingBoss, que é a ferramenta de e-mail marketing da BuilderAll, é possível trabalhar com Funis de Venda, capturando Leads para uma determinada lista. O fantástico dessa ferramenta é que ela permite montar WORKFLOWS com ações a serem tomadas DEPOIS que o lead se inscreve na lista. Tipicamente essas ações são envios de novos e-mails, contendo conteúdos diferentes e levando o lead a tomar uma decisão de compra. Esses e-mais são programáveis no tempo. E mais: se a pessoa clicar no link de um e-mail, o WORKFLOW permite transferir o lead de uma lista original – onde o e-mail entrou pela primeira vez – para qualquer outra lista (retirando-o, se você quiser, da lista original).
Essencialmente, toda lista é associada a um único formulário que tem em geral poucos campos. O mínimo que pode ter é o campo de e-mail, que é obrigatório. O típico pede um nome e o e-mail. O problema: assim que a pessoa submete o formulário, clicando no botão de submit, é muito complicado passar esses dados para uma outra aplicação e – até o momento em que escrevo este post – o jeito que eles recomendam fazer isso não funcionou e é ainda impraticável passar dados “hidden”, embora isso seja teoricamente possível.
A solução
Bem, se Maomé não vai à montanha, a montanha vai a Maomé. O jeito que encontrei é cadastrar o lead na minha própria aplicação CORE MVC, num formulário simples que simplesmente injeta o LEAD no database da minha aplicação. Ao completar essa operação, eu emulo um submit para o MailingBoss, como se os dados tivessem saído de um formulário deles – e não da minha aplicação. Assim que o MailingBoss “engole” os dados, ele mesmo dispara e-mail pedindo confirmação de e-mail (se a lista é double opt in) ou um e-mail de confirmação do cadastramento.
Funciona. Se você quiser fazer um teste, pode se inscrever para ter 7 dias de acesso gratuíto ao MailingBoss e mais 17 ferramentas de marketing digital – além de diversos treinamentos sobre tudo quanto é assunto para fazer marketing na WEB.
A aplicação em ASP.NET CORE MVC
A ideia é ter uma aplicação muito simples que permitirá fazer um cadastro de pessoas interessadas em fazer um teste, na WEB, sem custos, do seu grau de empreendedorismo.
Assim que a pessoa se cadastra, a aplicação manda um e-mail para o e-mail cadastrado, solicitando a CONFIRMAÇÃO (da veracidade) do mesmo. PAra não complicar a programação do aplicativo, vamos deixar por conta do MailingBoss o envio do e-mail pedindo a Confirmação.
Assim que a pessoa cadastrada clica no link desse e-mail de confirmação, ocorrem duas coisas:
- Ela é remetida para uma página tipo parabéns, está tudo certo, ‘clique no link abaixo para fazer o teste‘;
- O sistema muda o status do cadastrado para confirmado;
- O MailingBoss envia um e-mail de agradecimento.
Modelo de Dados
Crie uma classe de dados no diretório model, tendo como chave o e-mail (para evitar e-mails duplicados).
MODEL->Empreendedor.cs
modelo de dados ( //Troque a palavra Coaching pelo nome da sua aplicação, por exemplo, AplicacaoTeste))using System;
using System.ComponentModel.DataAnnotations;
namespace Coaching.Models
{
public class Empreendedor //Model
{
[Key]
[Display(Name = "E-mail")]
[Required(ErrorMessage = "Favor entrar com seu e-mail ou com um e-mail válido.")]
[EmailAddress(ErrorMessage = "O campo de e-mail tem que ter um e-mail válido.")]
[RegularExpression(@"^[\w\.-]{1,}\@([\da-zA-Z-]{1,}\.){1,}[\da-zA-Z-]+$", ErrorMessage = "Este não é um e-mail válido, corrija")]
[StringLength(256, MinimumLength = 7, ErrorMessage = "O {0} tem que ter pelo menos {2} caracteres de comprimento")]
public string Email { get; set; }
[Display(Name = "Nome Completo")]
[Required(ErrorMessage = "Favor entrar com seu nome completo.")]
public string Nome { get; set; }
[Display(Name = "Senha")]
[Required(ErrorMessage = "Favor entrar com sua senha pessoal. Anote para não esquecê-la")]
public string Senha { get; set; }
[DataType(DataType.PhoneNumber, ErrorMessage = "Não é um telefone válido")]
[Display(Name = "WhatsApp com código de país e DDD, formato +PAIS DDD NÚMERO")]
[Required(ErrorMessage = "Favor entrar com seu WhatsApp / Celular. Não deixe de colocar o DDD. Obrigado.")]
public string FoneComercial { get; set; }
[Display(Name = "Consultoria (id)")]
public int IdConsultoria { get; set; }
[Range(0, 1, ErrorMessage = "Tem de ter um valor 0 ou 100")]
[Display(Name = "Flag E-mail Confirmado: 0 -> não, 1 -> sim")]
public int flagEmailConfirmado { get; set; }
[Range(0,100,ErrorMessage ="Tem de ter um valor menor ou igual a 100")]
[Display(Name = "Quantidade de Avaliadores: 0 -> nenhum")]
public int quantidadeDeAvaliadores { get; set; }
//valores default
public Empreendedor()
{
IdConsultoria = 4; // id da minha consultoria no sistema de avaliações, externo
flagEmailConfirmado = 0; //email não confirmado
quantidadeDeAvaliadores = 0; // nenhum avaliador, somente pessoa inscrita se avalia
}
}
}
Gerando a tabela no banco de dados – Contexto
Uma vez que seu modelo já está gravado com Empreendedor.cs, você precisa precisa acrescentar essa tabela na lista de tabelas – que no meu caso está no arquivo ContextoPrimario.cs, dentro da pasta models. Se você não tem ainda na aplicação nenhuma especificação de contexto, crie uma ContextoPrimario.cs na pasta de models e insira o seguinte conteúdo
arquivo de contexto ContextoPrimario.cs (coloque os dados da SUA conexão com SEU banco de dados)using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Internal;
using System;
using Microsoft.EntityFrameworkCore.Design;
using Coaching.Models;
namespace Coaching.Models
{
//Troque a palavra Coaching pelo nome da sua aplicação, por exemplo, AplicacaoTeste)
//Depois de atualizar este arquivo rode:
//Build Project (Na menu superior. Tem de dar zero erros)
//Depos, na janela do Package Manager console (embaixo), troque [nomedamigracao] por qualquer nome, como PrimeiraMigracao
//PM> Add-Migration [nomedamigracao] -Context ContextoPrimario
//PM> update-database -context ContextoPrimario
public partial class ContextoPrimario : DbContext
//public class ContextoPrimario : DbContext
{
public virtual DbSet<Empreendedor> Empreendedores { get; set; } // banco de Empreendedores
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// #warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
optionsBuilder.UseSqlServer(@"Data Source=enderecowebdoservidorsql;Initial Catalog=nomeDoDatabase;User Id=nomeDoUsuarioDoDatabase;Password=senhaDoUsuario;MultipleActiveResultSets=True;");
}
public ContextoPrimario(DbContextOptions<ContextoPrimario> options)
: base(options)
{ }
//https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext
public class ContextoPrimarioFactory : IDesignTimeDbContextFactory<ContextoPrimario>
{
public ContextoPrimario CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<ContextoPrimario>();
optionsBuilder.UseSqlServer(@"Data Source=enderecowebdoservidorsql;Initial Catalog=nomeDoDatabase;User Id=nomeDoUsuarioDoDatabase;Password=senhaDoUsuario;MultipleActiveResultSets=True;");
return new ContextoPrimario(optionsBuilder.Options);
}
}
}
}
Se você já tem seu arquivo de Contexto, por ter criado o banco de dados anteriormente (ou por estar aproveitando uma solução de teste criada anteriormente, e somente quer ter a tabela do modelo empreendedor lá dentro), simplesmente acrescente à relação de arquivos já existentes a seguinte linha (dentro de public partial class ContextoPrimario : DbContext:):
public virtual DbSet<Empreendedor> Empreendedores { get; set; } // banco de Empreendedores
Feito isso, vá no menu superior e rode BUILD->BUILD SOLUTION. Tem que dar zero erros, se não der acerte o que estiver errado, até rodar e dar zero erros.
Feito isso, precisamos agora gerar o arquivo que vai de fato implementar a tabela de EMpreendedores na sua aplicação. Na janela do Package Manager Console, embaixo, temos de adicionar essa primeira migração. Digite, trocando [nomedamigracao] por qualquer nome, como PrimeiraMigracao:
//PM> Add-Migration [nomedamigracao] -Context ContextoPrimario:
Add-Migration [nomedamigracao] -Context ContextoPrimario
Se rodar certinho, ele vai gerar um arquivo com um númerogrande_nomedasuamigracao. No meu caso, 20190131213948_Empreendedor3.
conteudo do arquivo de migração (no meu caso, 20190131213948_Empreendedor3)using Microsoft.EntityFrameworkCore.Migrations;
namespace Coaching.Migrations
{
public partial class Empreendedor3 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Empreendedores",
columns: table => new
{
Email = table.Column<string>(maxLength: 256, nullable: false),
Nome = table.Column<string>(nullable: false),
Senha = table.Column<string>(nullable: false),
FoneComercial = table.Column<string>(nullable: false),
IdConsultoria = table.Column<int>(nullable: false),
flagEmailConfirmado = table.Column<int>(nullable: false),
quantidadeDeAvaliadores = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Empreendedores", x => x.Email);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Empreendedores");
}
}
}
Agora temos de rodar a Migração, gerando a tabela de Empreendedores no seu banco de dados.Novamente na janela de Package Management Console (PM, embaixo), rode o seguinte comando (troque ContextoPrimario pelo nome do seu contexto, se tiver um outro):
update-database -context ContextoPrimario
Entre no seu gerenciador de banco de dados, você vai ver que a tabela está lá. No meu caso, como uso SQL, entro no MIcrosoft SQL Server Management Studio (MSSMS). Coloco a tabela no modo de edição e vejo o seguinte:

tabela empreendedores
Nada é perfeito, suspirou a raposa. Na migração a tabela foi criada mas, a despeito de ter definido no modelo valores default para idConsultoria (4), flagEmailConfirmado (0) e quantidadeDeAvaliadores (0), estes valores não estão no Binding da tabela, quando todos os campos estão definidos como “não permitindo nulos”. Isso significa que, se deixar assim, vou ter de especificar todos esses valores no meu form, como hidden. Até aí tudo bem. Ocorre que algumas vezes uso procedures e gosto de ter a certeza que se eu não enviar algum desses campos, eles vão assumir valores padrão.
Assim, ajusto o o DEFAULT VALUE OR BINDING para os valores padrão que quero e salvo a tabela (que ainda está vazia).
Gerando o Controller as as Views, com Scaffolding
Agora precisamos criar o controlador (controller) e os formulários (views). Clicks sobre o nome do seu projeto e com o botão da direita escolha ADD-> NEW SCAFFOLDED ITEM. Escolha o template MVC COntroller with Views, using Entity Framework. Click em ADD.
Em Model Class, escolha Empreendedor. Em Data Context Class, escolha ContextoPrimario (ou o nome do seu contexto). Deixe clicado: Generate Views, Reference Script Libraries e Use a lay-out page. Em Controller name, mude o nome de EmpreendedorsController para EmpreendedoresController. Click em ADD.
Legal. Vamos fazer um check básico. No menu superior clique em IIS EXpress. Sua aplicação vai ter um endereço básico de entrada, definido em startup;cs. No meu caso é http://localhost:50628/.
No NAVEGADOR, altere para o seu endereço localhost + Empreendedores/Create.
No meu caso fica assim: http://localhost:50628/Empreendedores/Create
Que chato, Fernandinho. O formulário fica pedindo coisas que não deveriam e.se tento gravar, dá um monte de erros, E, pior que tudo, não tem o e-mail que considero chave:

a view de criação original create.cshtml@model Coaching.Models.Empreendedor
@{
ViewData[“Title”] = “Create”;
}
<h2>Create</h2>
<h4>Empreendedor</h4>
<hr />
<div class=”row”>
<div class=”col-md-4″>
<form asp-action=”Create”>
<div asp-validation-summary=”ModelOnly” class=”text-danger”></div>
<div class=”form-group”>
<label asp-for=”Nome” class=”control-label”></label>
<input asp-for=”Nome” class=”form-control” />
<span asp-validation-for=”Nome” class=”text-danger”></span>
</div>
<div class=”form-group”>
<label asp-for=”Senha” class=”control-label”></label>
<input asp-for=”Senha” class=”form-control” />
<span asp-validation-for=”Senha” class=”text-danger”></span>
</div>
<div class=”form-group”>
<label asp-for=”FoneComercial” class=”control-label”></label>
<input asp-for=”FoneComercial” class=”form-control” />
<span asp-validation-for=”FoneComercial” class=”text-danger”></span>
</div>
<div class=”form-group”>
<label asp-for=”IdConsultoria” class=”control-label”></label>
<input asp-for=”IdConsultoria” class=”form-control” />
<span asp-validation-for=”IdConsultoria” class=”text-danger”></span>
</div>
<div class=”form-group”>
<label asp-for=”flagEmailConfirmado” class=”control-label”></label>
<input asp-for=”flagEmailConfirmado” class=”form-control” />
<span asp-validation-for=”flagEmailConfirmado” class=”text-danger”></span>
</div>
<div class=”form-group”>
<label asp-for=”quantidadeDeAvaliadores” class=”control-label”></label>
<input asp-for=”quantidadeDeAvaliadores” class=”form-control” />
<span asp-validation-for=”quantidadeDeAvaliadores” class=”text-danger”></span>
</div>
<div class=”form-group”>
<input type=”submit” value=”Create” class=”btn btn-default” />
</div>
</form>
</div>
</div>
<div>
<a asp-action=”Index”>Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync(“_ValidationScriptsPartial”);}
}
É necessário que os campos idConsultoria, quantidadeDeAvaliadores e flagEmailConfirmado fiquem em hidden e com valores pré determinados. Além disso:
- vou mudar a cor do botão para vermelho usando “btn-danger” no lugar de “btn-default”;
- tirar o link “Back to List”;
- No títutlo, colocar um texto promocional com a classe “jumbotron” do bootstrap (que é usado na minha aplicação);
- acrescentar o campo de e-mail que, por ser chave, o CORE assumiu que não precisaria ter porque seria gerado automaticamente – o que não é o nosso caso.
a view de criação modificada create.cshtml@model Coaching.Models.Empreendedor
@{
ViewData["Title"] = "Create";
}
<div class="jumbotron">
<div class="container">
<h2>Inscreva-se aqui para fazer o teste de <b>Empreendedor</b></h2>
<h3><i>Você reberá um e-mail para confirmar sua inscrição</i></h3>
</div>
</div>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Email" class="control-label"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Nome" class="control-label"></label>
<input asp-for="Nome" class="form-control" />
<span asp-validation-for="Nome" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Senha" class="control-label"></label>
<input asp-for="Senha" class="form-control" />
<span asp-validation-for="Senha" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="FoneComercial" class="control-label"></label>
<input asp-for="FoneComercial" class="form-control" />
<span asp-validation-for="FoneComercial" class="text-danger"></span>
</div>
<input hidden asp-for="IdConsultoria" value="4" />
<input hidden asp-for="flagEmailConfirmado" value="0" />
<input hidden asp-for="quantidadeDeAvaliadores" value="0" />
<div class="form-group">
<input type="submit" value="Cadastre-se aqui" class="btn btn-danger" />
</div>
</form>
</div>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Rodando a aplicação no localhost, nossa telinha de entrada fica assim:

Fazendo um cadastramento o sistema manda para a página Index ferada pelo Core MVC:

Ou conferindo na base de dadosse está tudo OK:

Agora vamos criar um espelho dessa tabela no MailingBoss. Se você não tem uma conta na BuilderAll, crie uma conta de 7 dias grátis.
Entre no MailingBoss Autoresponder->Acessar MailingBoss e preencha os dados em CRIAR NOVA LISTA DE CONTATOS. Dê o nome à lista de EMPREENDEDOR DIGITAL. No topo, clique em LISTAS e clique na engrenagem da Lista de Empreendedor Digital Abra o seletor LINKS RÁPIDOS e escolha a opção VER CAMPOS CUSTOMIZADOS.
Aqui vamos inserir os campos que nos interessam, todos como texto, além do e-mail: senha, nome, idconsultoria e telefone (que chamei de whatsap):

Não esqueça de salvar. Depois selecione em LINKS RÁPIDOS -> formulários de interação. Copie todo contéudo numa janela de texto, para podermos retirar dela as informações que nos interessam para o controlador do core mvc,
formulário de interação MailingBoss (pegar o primeiro formulário e não o do iframe)<form action="https://member.mailingboss.com/index.php/lists/zw93898d6db44/subscribe" method="post" accept-charset="utf-8" target="_blank">
<div class="form-group" style="display:none">
<label>IdConsultoria</label>
<input type="text" class="form-control" name="IDCONSULTORIA" placeholder="" value=""4""/>
</div>
<div class="form-group">
<label>Seu melhor E-mail
<span class="required">*</span>
</label>
<input type="text" class="form-control" name="EMAIL" placeholder="" value="" required />
</div>
<div class="form-group">
<label>Seu nome com sobrenome
<span class="required">*</span>
</label>
<input type="text" class="form-control" name="FNAME" placeholder="" value="" required />
</div>
<div class="form-group">
<label>WhatsApp</label>
<input type="text" class="form-control" name="WHATSAPP" placeholder="" value=""/>
</div>
<div class="form-group">
<label>Sua senha
<span class="required">*</span>
</label>
<input type="text" class="form-control" name="SENHA" placeholder="" value="" required />
</div>
<div class="form-group" style="display:none">
<label>Últimos cliques</label>
<input type="text" class="form-control" name="MBOSSLASTCLICKS" placeholder="" value=""/>
</div>
<div class="clearfix">
<!-- -->
</div>
<div class="actions">
<button type="submit" class="btn btn-primary btn-submit">Inscrever</button>
</div>
<div class="clearfix">
<!-- -->
</div>
</form>
Podemos ver que a lista esta vazia:

Precisamos alterar o controlador para além de submeter ao database, também “”emular” o submit para o MailingBoss.
Vejamos o código original do POST do CREATE do CORE MVC:
post CREATE do controlador EmpreendedoresController.cs // POST: Empreendedores/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Email,Nome,Senha,FoneComercial,IdConsultoria,flagEmailConfirmado,quantidadeDeAvaliadores")] Empreendedor empreendedor)
{
if (ModelState.IsValid)
{
_context.Add(empreendedor);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(empreendedor);
}
Acrescente ao controlador:
using System.Net.Http;
using System.Net.Http.Headers;
e altere seu código post conforme abaixo. Não se esqueça de incluir a rotina privada para inserir os pares de valores do form e de trocar – no post – o código para o código de sua lista que você guardou no arquivo texto (no meu caso, o código zw93898d6db44 (que é o “cpf” da lista).
NOVO post CREATE do controlador EmpreendedoresController.cs // POST: Empreendedores/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Email,Nome,Senha,FoneComercial,IdConsultoria,flagEmailConfirmado,quantidadeDeAvaliadores")] Empreendedor empreendedor)
{
if (ModelState.IsValid)
{
_context.Add(empreendedor);
await _context.SaveChangesAsync();
//ENVIO DE EMAIL PARA BUILDER ALL - MAILING BOSS
//======================================
await PostToMailingBossAsync(Convert.ToString(empreendedor.IdConsultoria), empreendedor.Email, empreendedor.Nome, empreendedor.FoneComercial,empreendedor.Senha);
//======================================
return RedirectToAction(nameof(Index));
}
return View(empreendedor);
}
//ROTINA AUXILIAR PARA MAILING BOSS
[HttpPost]
private async Task<HttpResponseMessage> PostToMailingBossAsync(String idConsultoria, String email, String nome, String whatsapp, String senha)
{
HttpClient client = new HttpClient();
var content = new FormUrlEncodedContent(new[]
{
//new KeyValuePair<string, string>("someField", "value")
//TEMOS QUE DAR EXATAMENTE OS MESMOS NOMES QUE ESTAO NO MAILINGBOSS
//NAS TAGS, QUE SÃO SEMPRE EM MAIÚSCULO
new KeyValuePair<string, string>("IDCONSULTORIA", idConsultoria),
new KeyValuePair<string, string>("EMAIL", email),
new KeyValuePair<string, string>("FNAME", nome),
new KeyValuePair<string, string>("WHATSAPP", whatsapp),
new KeyValuePair<string, string>("SENHA", senha),
new KeyValuePair<string, string>("MBOSSLASTCLICKS","1")
});
content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
return await client.PostAsync("https://member.mailingboss.com/index.php/lists/zw93898d6db44/subscribe", content);
}
Testando a aplicação
No formulário original aparecia o campo MBOSSLASTCLICKS, que não documentado em lugar algum. Simplesmente pedi sua inserção com valor 1:
new KeyValuePair<string, string>(“MBOSSLASTCLICKS”,”1″)

Solicitei o cadastramento com email alcides2@mailinator.com.
O email entrou:

Listando os contatos do MailingBoss, cuja lista estava vazia:

Observe que ele entrou como não confirmado, o que significa que a aplicação funcionou direitinho, emulando o post para o MailingBoss. Vendo os detalhes do contato:

Olhando no Mailinator. vemos que foi remetido um e-mail de confirmação:

Abrindo e e-mail e clicando no link de confirmação:

A confirmação leva para uma tela de confirmação no MailingBoss. Não é o que queremos, mas vamos refinar isso mais adiante:

Voltando aos contatos do MailingBoss, vemos que agora o e-mail está com status confirmado.

No MailingBoss você pode ajeitar o e-mail de confirmação de inscrição, colocando sua arca e acertado oo texto. No meu caso:

Se o usuário clicar no link, vai cair na página de inscrição confirmada do MailingBoss. Como eu quero que ele caiana minha aplicação, tenho de configurar isso clicando no AVANÇADO.

Aí eu defino para onde quero remeter o usuário na minha aplicação e o tempo que isso demora. Deixei com zero segundos.

Não esqueça de clicar em Salvar e próximo. Volto para a aplicação e registro um novo e-mail (alcides3@mailinator.com), vou nos e-mails recebidos (mailinator.com) e clico no link de confirmação. Imediatamente vai para a MINHA tela de confirmação:

Agora é embelezar a tela e mudar o FlagEmailConfirmado na minha aplicação, alterando o valor de 0 para 1. Outra coisa a fazer, uma vez que sei que o e-mail é quente, é inserir o usuário na aplicação de testes, para que ele possa fazer o teste prometido usando os mesmos dados com que se cadastrou na minha lista,
Nova tela de Detalhes

Observe que já passo os parâmetros no link para evitar que o usuário tenha de redigitar o que acabou de cadastrar. O que é bem chato especialmente em celular,
arquivo de detalhes Details.cshtml@model Coaching.Models.Empreendedor
@{
ViewData["Title"] = "Confirmação de Inscriçãpo";
}
<div class="jumbotron">
<div class="container">
<h2>Tudo Pronto, @Html.DisplayFor(model => model.Nome) </h2>
<h3><i>Você já pode fazer seu teste de Empreendedor. Use os dados de email com que se cadastrou, abaixo:</i></h3>
</div>
</div>
<div>
<h4><u>Seus dados de Empreendedor</u></h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Email)
</dt>
<dd>
@Html.DisplayFor(model => model.Email)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Senha)
</dt>
<dd>
@Html.DisplayFor(model => model.Senha)
</dd>
</dl>
</div>@{var email = @Html.DisplayFor(model => model.Email); }
<div class="text-center">
<a href="http://360coaching.azurewebsites.net/acredepessoas/login?Email=@Html.DisplayTextFor(model => model.Email)&Senha=@Html.DisplayTextFor(model => model.Senha)" class="btn btn-danger btn-lg" target="_blank">Vai para o teste</a>
</div>
Acertando o Controlador
Assim que o usuário vê a tela de detalhes o controlador atualiza o flag de confirmação e chama uma procedure para inserir a pessoa confirmada no sistema de Avaliação e cria uma autoavaliação para ela preencher.
Esta é uma ISCA DIGITAL gratuíta e dá para o interessado, sem custos, sua autoavaliação como empreendedor. Ela poderá ver os resultados em tela, na forma gráfica e em tabelas.
Se ela gostar e quiser que outras pessoas a avaliem (amigos, parentes, pessoal de networking, etc), ela poderá comprar avaliações adicionais por um preço módico. Este seria um UP SELL . Se o resultado dela for muito bom, já na autoavaliação, no MailingBoss, vou colocá-la num FUNIL para ela juntar-se à CAMPANHA DE UM MILHÃO DE EMPREENDEDORES
detlahes do controlador EmpreendedorController.cs // GET: Empreendedores/Details/5
public async Task<IActionResult> Details(string id)
{
if (id == null)
{
return NotFound();
}
var empreendedor = await _context.Empreendedores
.FirstOrDefaultAsync(m => m.Email == id);
if (empreendedor == null)
{
return NotFound();
}
//acerto do Flag
empreendedor.flagEmailConfirmado = 1; // 1 = confirmado
//salva flag
await _context.SaveChangesAsync();
//insere a pessoa na aplicação de testes, para que ela possa fazer o login
//imediatamente após ver esta tela
await _context.Database.ExecuteSqlCommandAsync("insere_empreendedor @p0",
parameters: new[] {
empreendedor.Email});
//visualiza tela
return View(empreendedor);
}
detalhes do da procedure que insere a pessoa na aplicação e gera a autoavaliaçãoSET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alcides Soares Filho
-- Create date: Janeiro 2019
-- Description: insere empreendedor na aplicação coaching e gera a autoavaliação
-- =============================================
CREATE PROCEDURE insere_empreendedor
-- Add the parameters for the stored procedure here
@emailEmpreendedor as nvarchar(150)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
declare @nome as nvarchar(150)
declare @senha as nvarchar(50)
declare @fone as nvarchar(50)
declare @idConsultoria as int
declare @flagEmailConfirmado as int
declare @quantidadeDeAvaliadores as int
declare @ultimoId as int
-- captura dados do empreendedor
select @nome = nome, @senha = senha,
@fone = FoneComercial , @idConsultoria = idConsultoria,
@flagEmailConfirmado = flagEmailConfirmado, @quantidadeDeAvaliadores = 0
from Empreendedores
where Email=@emailEmpreendedor
-- idTipoQuestionario == 99 (empreendedores)
declare @idTeste as int
set @idTeste = 99
-- insere na aplicação se usuário não existe
declare @contador as int
SELECT @contador = count(*) from ac_redepessoas where email = @emailEmpreendedor and NiveldeAcesso = 5
if @contador = 0
begin -- insere
INSERT INTO [dbo].[ac_redepessoas]
(
[Nome]
,[Email]
,[Senha]
,[idConsultoria]
,[idTipoQuestionario]
,[NiveldeAcesso]
)
VALUES
(@nome
,@emailEmpreendedor
,@senha
,@idConsultoria
,@idTeste
,5
)
select @ultimoId=max(idUsuario) from ac_redepessoas
end
else
begin
select top (1) @ultimoId=idUsuario from ac_redepessoas where email = @emailEmpreendedor and NiveldeAcesso = 5
end
-- outras variaveis
declare @primeiroConsultor as int
select top (1) @primeiroConsultor = idUsuario from ac_redepessoas where IdConsultoria = @idConsultoria and NivelDeAcesso = 3
declare @primeiraEmpresa as int
select top (1) @primeiraEmpresa = idEmpresa from Empresas where idConsultoria = @idConsultoria
declare @minimoAmigos as int = 0
declare @minimoClientes as int = 0
declare @minimoFornecedores as int = 0
declare @minimoGestores as int = 0
declare @minimoParentes as int = 0
declare @minimoPares as int = 0
declare @minimoSubordinados as int = 0
declare @minimoNetworking as int = 0
-- atualiza usuarios
UPDATE [dbo].[ac_redepessoas]
SET [NiveldeAcesso] = 5
,[DataCadastro] = getdate()
,[Situacao] = 'ativo'
,[idAvaliado] = 1
,[FlagMostraRelatorioAvaliado] = 1
,[DataAltera] = getdate()
,[FlagManut] = 0
,[idEmpresa] = @primeiraEmpresa
,[idConsultoria] = @idConsultoria
,[idConsultor] = @primeiroConsultor
,[DataInicioAplicacao] = getdate()
,[DataTerminoAplicacao] = DATEADD(DAY,30,getdate())
,[idTipoQuestionario] = @idTeste
,[minimoGestores] = @minimoGestores
,[minimoSubordinados] = @minimoSubordinados
,[minimoPares] = @minimoPares
,[minimoFornecedores] = @minimoFornecedores
,[minimoClientes] = @minimoClientes
,[minimoParentes] = @minimoParentes
,[minimoAmigos] = @minimoAmigos
,[minimoNetworking] = @minimoNetworking
,[CodigoPromocional] = 'EMPREENDEDOR' + cast(@idConsultoria as nvarchar(10))
WHERE idUsuario = @ultimoId
-- INSERE AUTOAVALIAÇÃO
declare @idAvaliador int
declare @tipoDeQuestionario int
declare @totalPerguntas int
set @idAvaliador = @ultimoId
Select @tipoDeQuestionario = idTipoQuestionario from ac_redepessoas where idUsuario = @idAvaliador
select @totalPerguntas = count(*) from questionarios_modelos where idTipoQuestionario = @tipoDeQuestionario
-- declare @contador as int
select @contador = count(*) from avaliacoes where idAvaliado = @idAvaliador and idAvaliador = @idAvaliador and idCicloDaAvaliacao = 1
if @contador = 0
begin
-- insere avaliação
INSERT INTO [dbo].[avaliacoes]
([idAvaliado]
,[idAvaliador]
,[tipoDeAvaliador]
,[idTipoQuestionario]
,[flagFim]
,[Comentario]
,[flagComentario]
,[dataFim]
,[numRespostas]
,[dataAltera]
,[numPerguntas])
VALUES
(@idAvaliador
,@idAvaliador
,'auto'
,@tipoDeQuestionario
,0
,null
,0
,null
,0
,null
,@totalPerguntas)
--- atualiza codigo promocional
-- declare @idConsultoria int
--declare @idConsultor int
--declare @CodigoPromocional nvarchar(100)
--select @idConsultor = idConsultor from ac_redepessoas where idUsuario = @idAvaliador
--select @CodigoPromocional = CodigoPromocional from ac_redepessoas where idUsuario = @idConsultor
--update ac_redepessoas set CodigoPromocional = @CodigoPromocional where idUsuario = @idAvaliador
end
END
GO
Ajustes Finais
Quando o usuário se cadastra, o sistema está ainda mandando o usuário para a página Index, que dá a relação de todos os cadastrado Não é isso que queremos: precisamos remetê-lo a uma página dizendo “Que legal, estamos quase lá, Por favor confirme sua inscrição clicando no link recebido por e-mail (veja se não caiu no SPAM”. Assim, o controlador no final do POST do create tem de redirecionar não para Index, e sim para uma pagina diferente. Vamos nos basear na própria página de details.cshtml, criando uma chamada details_confirma_email.cshtml.
arquivo Detail_confirma_emails.cshtml@model Coaching.Models.Empreendedor
@{
ViewData["Title"] = "Confirmação do seu E-mail";
}
<div class="jumbotron">
<div class="container">
<h2>Estamos quase lá, @Html.DisplayFor(model => model.Nome) </h2>
<h3><i>Agora só falta ir na sua caixa de e-mails e clicar no link que confirma que seu e-mail existe (se não achar, dá uma olhadinha para ver se não caiu no SPAM!!!)</i></h3>
</div>
</div>
mudanças no controlador EmpreendedoresController.cs // GET: Empreendedores/Details_confirma_email/5
public async Task<IActionResult> Details_confirma_email(string id)
{
if (id == null)
{
return NotFound();
}
var empreendedor = await _context.Empreendedores
.FirstOrDefaultAsync(m => m.Email == id);
if (empreendedor == null)
{
return NotFound();
}
//visualiza tela
return View(empreendedor);
}
//mudanças no POST
// POST: Empreendedores/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Email,Nome,Senha,FoneComercial,IdConsultoria,flagEmailConfirmado,quantidadeDeAvaliadores")] Empreendedor empreendedor)
{
if (ModelState.IsValid)
{
_context.Add(empreendedor);
await _context.SaveChangesAsync();
//ENVIO DE EMAIL PARA BUILDER ALL - MAILING BOSS
//======================================
await PostToMailingBossAsync(Convert.ToString(empreendedor.IdConsultoria), empreendedor.Email, empreendedor.Nome, empreendedor.FoneComercial,empreendedor.Senha);
//======================================
// return RedirectToAction(nameof(Index));
return RedirectToRoute(new
{
controller = "Empreendedores",
action = "Details_confirma_email",
id = empreendedor.Email
});
}
return View(empreendedor);
}
Logo após cadastrar um novo e-mail (alcides6@mailinator.com) , aparece a tela do “estamos quase lá”.

O e-mail foi enviado para o Mailinator.com
Depois de clicar no link de confirmação do E-mail, a tela para pré-acessar o teste.

Clicando no botão “Vai para o teste”, a tela já é pré-preenchida

Clicando em entrar a pessoa já pode responder o questionário (no caso sobre seu grau de empreendedorismo).

Todos e-mails ficaram registrados no MailingBoss e com status confirmados.

Obrigado pela sua leitura. Continue visitando este blog e compartilhe artigos em sua rede de relacionamento. Por favor, se quiser, registre sugestões e comentários ao final da página.