Escolha uma Página
(Last Updated On: 10/01/2021)

É muito fácil achar na Internet como mandar e-mails com a API do Sendgrid. Mas não existe quase nada sobre automação de campanhas de e-mail marketing usado a API v3 do SendGrid!

Campanhas de E-mail Marketing, automatizadas, como você sempre sonhou!

Se você já usa o SendGrid para enviar seus e-mails , já andou metade do caminho (veja meu artigo  Adicionando serviço de E-mail no Core MVC, usando SendGrid).

O fato é que há coisas muito chatas de se fazer no Core MVC. Uma delas é formatar e-mails para envio. Outra é tentar programar eventos para acontecer no tempo. Uma campanha de e-mail marketing essencialmente tem que ter e-mails muito bonitos, responsivos, realmente vendedores. E que possam ser mandados sequencialmente assim que a pessoa se inscreve no seu site (como usuária, como interessada em receber alguma coisa), evento este que “dispara” e-mails de tempos em tempo, dando boas vindas (por exemplo) e depois oferecendo seus serviços ou produtos. Com o SendGrid você tem de graça tudo isso, até 6 mil e-mails por mês.

O que (as novas) Campanhas de Marketing do SendGrid Oferecem

Ferramentas de Criação e Edição de Modelos de E-mails

  • Biblioteca de modelos responsivos (onde você pode guardar seus templates também);
  • Ferramentas de criação e edição dos seus próprios modelos, começando do “zero”. Você pode arrastar e soltar, escrever em HTML puro ou ambos.
  • Importação de imagens Na sua biblioteca particular).

Ferramenta de Automação

Voce cria automações de e-mail de alto impacto em horas ou minutos – e não dias – com gatilhos simples e uma visão centralizada das mensagens e do tempo de sua série de e-mails da Campanha.

O que vamos fazer?

Aqui vamos dar um exemplo completo que dispara uma campanhade e-mails em sequência no SendGrid quando alguém se inscreve no seu site montado em Core MVC.

O e-mail cadastrado pelo seu sistema (no nosso exemplo através do Registro de Usuários do Identity), assim que é validado pelo controlador (e é salvo na tabela ASPNETUsers), é mandado também para uma Lista de Contatos do SendGrid. A essa lista está associada uma Campanha de Marketing, com um cronograma de envios de quantos e-mails você quiser. A grande vantagem é que para cada e-mail enviado, você sabe quem recebeu, quem não recebeu, quem recebeu e abriu o email, quem abriu e clicou no e-mail (e quantaz vezes).Tudo isso de graça e dentro do SendGrid. Veja neste vídeo curto.

Antes de qualquer coisa

Abra uma conta no SendGrid (ou acesse a sua) e:

  • Crie uma API para a Campanha (anote a chave secreta da APIKey, porque ela nnunca mais será mostrada). Depois de criar (ou se você já tem API), certifique-se que ela tenha “plenos poderes” insclusive para marketing.
    • SETTINGS
      • API KEYS
      • CREATE API KEY (se não tiver ainda uma, se tiver pule)
      • CLIQUE NA ENGRENAGEM PARA EDITAR PODERES
      • ESCOLHA EDIT API KEY
      • ESCOLHA FULL ACCESS

Agora vamos para a (NOVA) área de Marketing. No menu esquerdo:

  • Clique em Marketing NEW
    • Clique em Contacts (Você vai ver uma lista chamada GLOBAL, que tem todos os contatos de todas as as listas. Esta lista não nos interessa)
    • Clique, no topo, em Create e escolha New List . De o nome de sua lista e salve. Logo abaixo da sua lista Global vai aparecer o nome de sua nova lista.

Agora que tem a sua lista, clique no nome dela (NAME). Vai aparecer a lista de todos seus e-mails (mas se a lista é nova, nenhum e-mail).

O importante neste momento é que a URL tem o endereço interno da identidade da lista no sistema, que vai ser usada na API. No meu caso, a URL está assim:

https://mc.sendgrid.com/contacts/lists/e8b61063-6f33-4963-b8fc-331723f21f6x

Guarde junto do segredo da chave de api SOMENTE a identidade da Lista:

e8b61063-6f33-4963-b8fc-331723f21f6x

Criando sua primeira Campanha

No menu esquerdo:

  • Marketing NEW 
    • Automations
    • No topo direiro, Create an Automation

Você poderia começar completamente do zero, selecionando a opção CUSTOM.

Escolha WELCOME. Já vem uma microcampanha pronta, que você pode editar e mudar o que quiser. Dê o nome para sua campanha (o default é Untitled Welcome Series)

IMPORTANTE:

  • Não se esqueça de salvar todas mudanças. clicando em SAVE no topo da página (nada intuitivo)
  • Clique em Automation Options e clique em Set Live (põe no ar!). Note que é aí que você pode duplicar uma campanha existente. Também nada intuitivo.

Clique em Automation, no topo da página à esquerda. A nossa campanha Teste vai aparecer como Draft (rascunho) e não como Live (Ao vivo!). É que a campanha não entra ao vivo se não:

  • Tiver um NOME
  • Tiver uma LISTA ESCOLHIDA
  • Ter definido um mode da pessoa sair da lista. Para simplificar, escolho i modo de saída global (válido para todas as listas): GLOBAL UNSUBSCRIBE
  • Em cada email que vai ser mandado, ter definido SUBJECT (ASSUNTO) e SENDER (e-mail de quem está mandando o e-mail). Se você não cadastrou, vai ter que ir em SENDERS PAGE e definir um e-mail de remetente (você vai ter que VERIFICAR esse e-mail para torná-lo válido para o SendGrid). Eu recomendo fazer a verificação do E-mail e do domínio de envio, assim as chances dos e-mails enviados caírem no SPAM dos destinatários caem praticamente a zero!.

Faça tudo que o SendGrid solicitar até que sua campanha, finalmente, saia de DRAFT para LIVE.

Finalmente, começando a programação no CORE MVC

Assim que conseguir isso, vamos finalmente para nosso velho Visual Studio. Para implementar o envio de e-mails, escolho o arquivo REGISTER.CSHMTL.CS, que é o controlador do registro de novos usuários na tabela ASPNETUSERS, do Identity.

Você pode escolher qualquer controlador seu que vai salvar um e-mail dentro da base de dados. Assim que a validação do modelo é feita dentro do controlador, você aproveita o embalo e envia o mesmo e-mail para a lista do SENDGRID, que está amarrada na sua campanha. Funciona que é uma chupeta.

Parte inicial do controlador

Você vai ter de instalar, aplicação, os seguintes pacotes (que inclusive substituem o newtowjson):

using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;

parte inicial do controlador (no caso register.cshtm.cs) em Areas/Identity/Pages/Account/
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using PoupaTempoDigital.Data;
using PoupaTempoDigital.Models;
using PoupaTempoDigital.Services;
using RestSharp;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
//pode ser necessário instalar os 4acima via Packate Manager

namespace PoupaTempoDigital.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class RegisterModel : PageModel
    {
        private readonly SignInManager<AppUser> _signInManager;
        private readonly UserManager<AppUser> _userManager;
        private readonly ILogger<RegisterModel> _logger;
        //_emailSender;
        private readonly IEmailService _emailService;
        private readonly ApplicationDbContext _context;
        private readonly RoleManager<AppRole> _roleManager;
        private readonly IConfiguration _configuration;

        public RegisterModel(
            UserManager<AppUser> userManager,
            SignInManager<AppUser> signInManager,
            ILogger<RegisterModel> logger,
            IEmailService emailService,
            IOptions<EmailConfig> emailConfig,
            ApplicationDbContext context,
           RoleManager<AppRole> roleManager,
            IConfiguration configuration)

        {
            _userManager = userManager;
            _signInManager = signInManager;
            _logger = logger;
            _emailService = emailService;
            _context = context;
            _roleManager = roleManager;
            _configuration = configuration;
        }
          // continua controlador ....

Modelo de dados

Eu prentendo, além do e-mail, passar para a minha lista SENDGRID nome e sobrenome. O Sendgrig tem mais de uma dezena de campos prontos na lista – e você pode definir mais campos customizados, quantos ou quais quiser.

Para isso criei, dentro do próprio controller, uma classe de modelo bem simples, logo após a tarefa Task OnGetAsync; Os nomes da variáveis tem que bater com os nomes padrão que o SendGrid já tem (e/ou com os nomes de campos customizados que você vier a criar para todos e-mails da sua lista):

modelo de dados a serem passados pelo register.cshtm.cs) em Areas/Identity/Pages/Account/
//... 
public async Task OnGetAsync(string returnUrl = null)
        {

            ReturnUrl = returnUrl;
            ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();

        }
//MODELO DE DADOS
        public class EmailSendgrid
        {
            public string email { get; set; }
            public string first_name { get; set; }

            public string last_name { get; set; }
        }
//...

Dentro do método POST do seu controle, no meu caso:
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
assim que o modelo é VALIDADO:

logo depois de validar o envio do post, gravar o usu&amp;aacute;rio, colocamos a "conversa" com a API da SENDGRID
//o controle tenta criar o usuário
var result = await _userManager.CreateAsync(user, Input.Password);
                if (result.Succeeded)
								//sucesso!!!
                {
                    _logger.LogInformation("O usuário criou uma nova conta com senha.");


//COMEÇO****** COLOCANDO dados no sendgrid
                  
                    var NovoEmail = new EmailSendgrid
                    {
                        email = user.Email,
                        first_name = user.FirstName,
                        last_name = user.LastName
                    };
 //TROQUE PELOS DADOS DE ID DA SUA LISTA, CONFORME DICA NO COMEÇO DO ARTIGO
                    var lista_ID = "e8b61063-6f33-4963-b8fc-331723f2322D3";

                    string jsonString = "{" + ""list_ids":" + " ["" + lista_ID + ""]," + ""contacts":" + "[" + JsonSerializer.Serialize(NovoEmail) + "]}";
//PEGA A SEDRET KEY DA SUA API SEND GRID (QUE ESTA ARMAZENADA NO ARQUIVO APPSETTING.JSON)
                    var API = _configuration.GetSection("Sendgrid").GetSection("ApiKey").Value;
                    var json = JsonSerializer.Deserialize<Object>(jsonString);
                    jsonString = json.ToString();
                    var client = new RestClient("https://api.sendgrid.com/v3/marketing/contacts");
                    var requisicao = new RestRequest(Method.PUT);
                    requisicao.AddHeader("content-type", "application/json");
                    requisicao.AddHeader("authorization", "Bearer " + API);
                    //requisicao.AddHeader("on-behalf-of", "");
                    requisicao.AddParameter("application/json", jsonString, ParameterType.RequestBody);
                    IRestResponse response = client.Execute(requisicao);
//******fim

                    //cria papéis se ainda não existem
                    //admin
                    if (!await _roleManager.RoleExistsAsync(Papeis.AdminEndUser))
                    {
                        await _roleManager.CreateAsync(new AppRole(Papeis.AdminEndUser));
                    }
                    //cliente
                    if (!await _roleManager.RoleExistsAsync(Papeis.ClienteEndUser))
                    {
                        await _roleManager.CreateAsync(new AppRole(Papeis.ClienteEndUser));
                    }
                    //colaborador
                    if (!await _roleManager.RoleExistsAsync(Papeis.ColaboradorEndUser))
                    {
                        await _roleManager.CreateAsync(new AppRole(Papeis.ColaboradorEndUser));
                    }
                   
                      
                      
                      //cria papel padrao para cada novo inscrito = Cliente
                    await _userManager.AddToRoleAsync(user, Papeis.ClienteEndUser);
                    var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                    code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
                    var callbackUrl = Url.Page(
                        "/Account/ConfirmEmail",
                        pageHandler: null,
                        values: new { area = "Identity", userId = user.Id, code = code, returnUrl = returnUrl },
                        protocol: Request.Scheme);
//ENVIA EMAILS SE NECESSARIO (ISSO PODE ESTAR NA SUA CAMPANHA, MANDANDO E-MAILS BONITOS E RESPONSIVOS)
                    await _emailService.SendEmailAsync(Input.Email, "Confirme seu e-mail no Poupatempo Digital",
                        $"<h4><b>Por favor confime sua conta</b> <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicando aqui.</a>.</h4><h5> Obrigado. Confirmando sua conta, você já terá acesso à sua <b>Agenda Inteligente</b> de Tarefas. Você vai curtir!<h5>", "Html");

                    var mensagem = "O usuário " + Input.FirstName + " " + Input.LastName + "e-mail: " + Input.Email + "Telefone: " + Input.PhoneNumber + " acabou de abrir conta no Poupatempo Digital";
                    var assunto = "o usuário " + Input.FirstName + " " + Input.LastName + " acabou de entrar no Poupatempo Digital";
                    var destino = "xxxxx@clickstobricks.com";
                    await _emailService.SendEmailAsync(destino, assunto, mensagem, "Text");

                    if (_userManager.Options.SignIn.RequireConfirmedAccount)
                    {
                        return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl });
                    }
                    else
                    {
                        await _signInManager.SignInAsync(user, isPersistent: false);
                        return LocalRedirect(returnUrl);
                    }
                }
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError(string.Empty, error.Description);
                }
            }

Pronto, é isso. Registre um novo usuário com sufixo mailinator.com

Exemplo: maria@mailinator.com

Acesse https://mailinator.com

Digite maria e dê enter. Se você definiu que o primeiro e-mail de sua campanha é enviado imediatamente após a inscrição do e-mail na lista, Maria já terá recebido seu primeiro e-mail .

Importante

Não se esqueça de ter a chave de sua API SendGrid no arquivo appsettings.json, conforme modelo abaixo.

chave secreta da API da SENDGRID, no arquivo appsettings.json
{
  "Email": {
    "FromName": "Site Poupatempo Digital",
    "FromAddress": "atendimento@poupatempodigital.com.br",
    "LocalDomain": "poupatempodigital.com.br",
    "MailServerAddress": "mail.poupatempodigital.com.br",
    "MailServerPort": "25", //SMTP Port:  25 "or" 8889:,
    "UserId": "atendimento@poupatempodigital.com.br",
    "UserPassword": "xxxxxxxxxxxxxxxxxxxxxxxx"
  },
  "Sendgrid": {
    "ApiKey": "xptodfde7WI5ZzpMinesA.blm98jwSobPj1enFAd2a7kQQrAYULi0-csraFJ0NzRs" //poupatempo digital 09/01 full access
  },
  "Twilio": {
    "accountSid": "ACewrewrwere1b43d312b7601",
    "authToken": "1710ewerewrewrw6c0f589b968cfc5",
    "whatsAppFrom": "whatsapp:+14155238886" //número de saída Twilio
  },
  "reCaptcha": {
    "chaveDeSite": "6Le0jCQaAAAAAHMSbanWiWoZrewrewrewGB4FWZET",
    "chaveSecreta": "6Le0jCQaAAAAAPSNwZeRYywrewrwerwe8wSUSj"
  },
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=SQL.site.net;Initial Catalog=DB_A2A240;User Id=DB_user;Password=password;;Connect Timeout=20000;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Referências que vão de ajudar

  1. API Sendkey, como obter e usar
  2. Guia de Parametrização para enviar e-mails pelo SendGrid
  3. Documentação completa, com exemplos – inclusive c#, da API SendGrid V3 (tipo: tudo o que você pode fazer)

Gostou? Deixe sugestões e comentários!

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 aqui no final da página.