PHP: เรียกใช้สคริปต์เพื่อโหลดภาพที่ฝังอยู่ในอีเมล์

สิ่งนี้จะเป็นประโยชน์สำหรับทุกคนที่อยากรู้ว่าถ้าคุณส่งอีเมล์ได้ถูกอ่าน. ในกรณีนี้, แทรกรูปภาพในเนื้อหาของข้อความอีเมล, เมื่อมีเปิด, จะทำสคริปต์บนเซิร์ฟเวอร์ระยะไกล.

งานนำเสนอ

Essa técnica é muito utilizada em e-mail marketing, de modo que o remetente envia centenas ou milhares de e-mails para destinatários de sua mala-direta visando atingir um público-alvo, e quer saber o feedback (retorno) da campanha, IE, se o destinatário leu ou não a propaganda embutida no e-mail.

วิธีการทำงาน?
O raciocínio é simples, basta você colocar no corpo do e-mail (conteúdo) uma Tag HTML de IMAGEM, com o atributo SRC apontando, não diretamente para uma imagem como normalmente é feito, mas para um script personalizado hospedado em um servidor remoto, onde você consegue executar alguma rotina e, aí sim, renderizar uma imagem (หรือไม่). Complicou? Que nada, veja o exemplo:

1
2
3
<?PHP
  <img src="http://seuservidor.com/script.php?email=pessoa@gmail.com&destinatario=Taylor+Lopes" />
?>

Para que serve?
Note que quando o usuário abrir o e-mail, automaticamente será carregada a suposta imagem, que na verdade é um script. Isso é útil para fazer estatística de e-mail que foram visualizados, inclusive determinando QUEM abriu (destinatário) e QUANDO (data/hora). แน่นอน, isso não é nenhumaadivinhação”, sabemos quem abriu o e-mail, pois atrelamos esses dados na URL da imagem no momento de enviá-lo.

Inconveniente
Para isso funcionar, o destinatário necessariamente precisa ter configurado para que seu e-mail seja lido no formato HTML, embora isso já seja um padrão aceito pela maioria do usuários. Na pior das hipóteses, o provedor de e-mail vai exibir uma mensagem dizendo que bloqueou as imagens, mas perguntando se o usuário quer exibir, o que também normalmente é aceito, já que poucas pessoas veem malícia nessa prática. No caso do Google, aparece uma mensagem em forma de link, แบบนี้:

1
2
3
...
  Imagens não exibidas - Exibir imagens abaixo - Sempre exibir imagens de suport@อีเมล.microsoft.ด้วย
...

Vou comentar duas formas de fazer isto; ambas funcionam igualmente, sendo que a segunda é mais discreta por não exibir dados na URL, embora exija mais recurso de armazenamento. ไม่เอาน่า!

วิธีการแก้ไขปัญหา 1

ในทางปฏิบัติ
Você precisa de apenas dois códigos PHP:
(1) um para enviar o e-mail no formato HTML com a tag IMG embutida
(2) e outro para captar as informações no momento que o e-mail for aberto

ขั้นตอนที่ 1Enviar e-mail

sendmail.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?PHP
  // *** อีเมลของคุณ (e-mail de quem envia)
  $remetente_nome     = 'Anônimo';
  $remetente_email    = 'anonimo@email.com';
 
  // *** Seu alvo (e-mail para quem envia) 
  $destinatario_nome  = 'Mario Bross';
  $destinatario_email = 'mariobross@email.com';
 
  // *** Assunto e corpo da mensagem
  $assunto      = 'Testando a execução de script ao carregar imagem.';
  $mensagem     = '
    <html lang="pt-br">
      <หัว>
        <meta charset="iso-8859-1" />    
        <ชื่อเรื่อง>'.$assunto.'</ชื่อเรื่อง>
      </หัว>
      <ร่างกาย>
        <img src="http://seuservidor.com/script.php?email='.urlencode($destinatario_email).'&destinatario='.urlencode($destinatario_nome).'&assunto='.urlencode($assunto).'" />
      </ร่างกาย>
    </HTML>';
 
  // Cabeçalho informando que o conteúdo é do tipo HTML (para poder ler a tag IMG e executar o script)
  $หัวข้อ       = "MIME-Version: 1.0\n"; 
  $หัวข้อ      .= "Content-type: ข้อ ความ/html; charset=iso-8859-1\n"; 
  $หัวข้อ      .= "From: ".(empty($remetente_nome) ? $remetente_email : '"'.$remetente_nome.'" <'.$remetente_email.'>')."\n";
 
  // Envia o e-mail
  $อีเมล = empty($destinatario_nome) ? $destinatario_email : '"'.$destinatario_nome.'" <'.$destinatario_email.'>';
  mail($อีเมล, $assunto, $mensagem, $หัวข้อ);
?>

ขั้นตอนที่ 2Captar informações

ดี, você notou que ao ler a TAG IMG será feita uma chamada para o arquivoscript.php”, ขวา? Então agora temos que criá-lo para pegar as informações e armazená-las, de preferência num banco de dados.

Criando TABELA
Já que precisamos persistir os dados do destinatário que abriu o e-mail, podemos criar uma tabela como esta abaixo. Veja o campo `datahora_visualizado`, que refere-se última data e hora em que o usuário visualizou o e-mail e o campo `contador`, que irá registrar a quantidade de vezes que o e-mail foi visto.

maladireta.sql
1
2
3
4
5
6
7
8
9
CREATE TABLE  `maladireta` (
  `id` INT NOT Null AUTO_INCREMENT PRIMARY คีย์ ,
  `email` VARCHAR( 100 ),
  `destinatario` VARCHAR( 100 ),
  `assunto` VARCHAR( 200 ),
  `datahora_envio` DATETIME NOT Null,
  `datahora_visualizado` DATETIME,
  `contador` INT DEFAULT 0
) เครื่องยนต์ = MYISAM ;

Script para captar informações e exibir uma imagem
จบ, vamos pegar dados como e-mail do destinatário, nome do destinatário, assunto da mensagem e a data/hora de quem abriu o e-mail, armazenando tudo no banco de dados que criamos, para caso futuramente precisarmos fazer uma estatística. No final do script, vamos de fato criar e exibir uma imagem, só para não ficar uma TAG IMG com crise existencial :), mas se não quiser exibir nada, crie pelo menos uma imagem em branco (1×1 pixel) para não ficar com a Tag quebrada.

script.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?PHP
  // Inicializa e trata os parâmetros de entrada
  $destinatario_email = ตัดแต่ง(strip_tags(addslashes($_ขอ['email'])));
  $destinatario_nome  = ตัดแต่ง(strip_tags(addslashes($_ขอ['destinatario'])));
  $assunto            = ตัดแต่ง(strip_tags(addslashes($_ขอ['assunto'])));       
 
  // Faz a conexão com o banco de dados (AJUSTE SUA CONEXÃO)
  $การเชื่อมโยง = mysql_connect('mysql.seuservidor.com', ราก, '***suasenha***') หรือ หรือ die('Falhou ao conectar ao banco de dados.'); 
  mysql_select_db('seubancodedados') หรือ หรือ die('Falhou ao selecionar o banco de dados');
 
  // Monta a SQL e insere no banco de dados, caso email ainda não exista, ou atualiza contador se existir
  $SQL = 'SELECT email FROM maladireta WHERE email="'.$destinatario_email.'"';
  $res = mysql_query($SQL);
  ถ้า (mysql_num_rows($res) > 0) {
    $SQL = 'UPDATE maladireta SET datahora_visualizado="'.วัน('Y-m-d H:(I):s').'", contador=contador+1 WHERE email="'.$destinatario_email.'"';    
  }
  อื่น {
    $SQL = 'INSERT INTO maladireta VALUES (null, "'.$destinatario_email.'", "'.$destinatario_nome.'", "'.$assunto.'", "'.วัน('Y-m-d H:(I):s').'", null, 0)';
  }
  mysql_query($SQL);
 
  // Cria e exibe a imagem embutida ao email
  หัวข้อ("Content-type: image/png");
  $IMG = imagecreatefrompng("imagem.png");
  imagepng($IMG);
  imagedestroy($IMG);
?>

หมายเหตุ: Não esqueça de colocar junto ao script uma imagem, ในกรณี, chamei deimagem.png”. Essa imagem irá aparecer no corpo do e-mail do destinatário, e é onde o pessoal de marketing coloca a propaganda, mas pode ser um logotipo ou o que você desejar. O Script foi testado e funciona!

วิธีการแก้ไขปัญหา 2

Outra possibilidade
Conforme sugerido pelo colega Leandro, uma opção mais discreta esegura” มันจะเป็น, ao invés de estampar na URL da imagem um monte de dados como email, assunto, ฯลฯ, criar um HASH no momento do envio do e-mail vinculando-o a esses dados, e enviar na URL somente o HASH. Quando o destinatário abrir o email e carregar a imagem, irá trafegar apenas o HASH que então será capturado pelo nosso script e vinculado aos dados que queremos saber.

Criando a tabela de hash e vínculo de dados
Vamos criar a tabela que será populada toda vez que enviarmos um e-mail. Note o campo `hash`, que servirá como vínculo do e-mail que foi enviado e os dados do destinatário que ficaram armazenados na tabela.

maladireta.sql
1
2
3
4
5
6
7
8
9
10
CREATE TABLE  `maladireta` (
  `id` INT NOT Null AUTO_INCREMENT PRIMARY คีย์ ,
  `hash` VARCHAR( 50 ) ไม่ฉัน Null,
  `email` VARCHAR( 100 ),
  `destinatario` VARCHAR( 100 ),
  `assunto` VARCHAR( 200 ),
  `datahora_envio` DATETIME NOT Null,
  `datahora_visualizado` DATETIME,
  `contador` INT DEFAULT 0
) เครื่องยนต์ = MYISAM

Enviando o e-mail

sendmail.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?PHP
  // *** อีเมลของคุณ (e-mail de quem envia)
  $remetente_nome     = 'Anônimo';
  $remetente_email    = 'anonimo@email.com';
 
  // *** Seu alvo (e-mail para quem envia) 
  $destinatario_nome  = 'Mario Bross';
  $destinatario_email = 'mariobross@email.com';
 
  // *** Outros dados a persistir e HASH (identificador)
  $hash               = md5(แรนด์());
  $assunto            = 'Testando a execução de script ao carregar imagem.';
  $datahora_envio     = วัน('Y-m-d H:(I):s');
 
  // Faz a conexão com o banco de dados
  $การเชื่อมโยง = mysql_connect('mysql.seuservidor.com', ราก, '***suasenha***') หรือ หรือ die('Falhou ao conectar ao banco de dados.'); 
  mysql_select_db('seubancodedados') หรือ หรือ die('Falhou ao selecionar o banco de dados');  
 
  // Monta a SQL e insere no banco de dados
  $SQL = 'INSERT INTO maladireta VALUES (null, "'.$hash.'", "'.$destinatario_email.'", "'.$destinatario_nome.'", "'.$assunto.'", "'.$datahora_envio.'", null, 0)';
  mysql_query($SQL);
 
  // *** Mensagem a ser enviada
  $mensagem     = '
    <html lang="pt-br">
      <หัว>
        <meta charset="iso-8859-1" />    
        <ชื่อเรื่อง>'.$assunto.'</ชื่อเรื่อง>
      </หัว>
      <ร่างกาย>
        <img src="http://seuservidor.com/script.php?hash='.$hash.'" />
      </ร่างกาย>
    </HTML>';
 
  // Cabeçalho informando que o conteúdo é do tipo HTML (para poder ler a tag IMG e executar o script)
  $หัวข้อ       = "MIME-Version: 1.0\n"; 
  $หัวข้อ      .= "Content-type: ข้อ ความ/html; charset=iso-8859-1\n"; 
  $หัวข้อ      .= "From: ".(empty($remetente_nome) ? $remetente_email : '"'.$remetente_nome.'" <'.$remetente_email.'>')."\n";
 
  // Envia o e-mail
  $อีเมล = empty($destinatario_nome) ? $destinatario_email : '"'.$destinatario_nome.'" <'.$destinatario_email.'>';
  mail($อีเมล, $assunto, $mensagem, $หัวข้อ);
?>

Perceba que, ในกรณีนี้, a URL (SRC) da imagem fica apenas com o HASH.

Contabilizando e-mail visualizado

script.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?PHP
  // Captura o HASH do e-mail visualizado
  $hash = ตัดแต่ง(strip_tags(addslashes($_ขอ['hash'])));
 
  // Faz a conexão com o banco de dados
  $การเชื่อมโยง = mysql_connect('mysql.seuservidor.com', ราก, '***suasenha***') หรือ หรือ die('Falhou ao conectar ao banco de dados.'); 
  mysql_select_db('seubancodedados') หรือ หรือ die('Falhou ao selecionar o banco de dados');
 
  // Monta a SQL e atualiza data de visualização do email e contador no banco de dados
  $SQL = 'SELECT hash FROM maladireta WHERE hash="'.$hash.'"';
  $res = mysql_query($SQL);
  ถ้า (mysql_num_rows($res) > 0) {
    $SQL = 'UPDATE maladireta SET datahora_visualizado="'.วัน('Y-m-d H:(I):s').'", contador=contador+1 WHERE hash="'.$hash.'"';
    mysql_query($SQL);
  }
 
  // Cria e exibe a imagem embutida ao email
  หัวข้อ("Content-type: image/png");
  $IMG = imagecreatefrompng("imagem.png");
  imagepng($IMG);
  imagedestroy($IMG);
?>

โอ้, se você quiser consultar os e-mails que foram visualizados a partir de uma data, poderia fazer um script com uma SQL tipo essa que, ในกรณี, busca todos os registros recentes de e-mail vistos a partir de 27 มกราคม 2013. Fica a dica

1
2
3
4
5
6
7
8
 
  เลือก * 
  FROM 
      `maladireta` 
  WHERE 
      contador > 0 AND 
      วันที่, ใหม่(datahora_visualizado) >= วันที่, ใหม่("2013-01-27")
;
จำนวนผู้เข้าชม: 34898

8 comentários sobre “PHP: เรียกใช้สคริปต์เพื่อโหลดภาพที่ฝังอยู่ในอีเมล์

  1. Leandro Chaves กล่าวว่า:

    เทย์เลอร์,
    Não é uma boa prática colocar o email do usuário no link da imagem. O ideal é inserir os dados no banco na hora do envio e colocar um hash ou o id da tabela no link, para assim identificar quem abriu o e-mail.

    • Oi Leandro, obrigado pelo comentário. Isso é discutível. Pensando em Segurança da Informação você tem razão, mas na prática seria certo preciosismo, pois o link de e-mail (รูปภาพ) que você considera importante proteger estará disponível apenas na caixa de entrada do próprio destinatário. É o mesmo que esconder algo de mim que já sei! นอกจากนี้, você teria que manter no seu banco uma outra tabela com os milhares de registros da sua mala-direta, mesmo sem saber se os e-mails ali contidos são válidos. Aí se você quisesseenchugarseu banco, não poderia, pois por uma questão de integridade referencial entre as tabelas, seria obrigado a manter os registros, sob pena de nunca saber quem abriu o e-mail. Mas já que estamos falando de segurança, para evitar ter o e-mail interceptado por um Wireshark da vida, o que poderia ser feito é usar SSL (HTTPS) tanto no envio do e-mail, quanto no link da imagem. Mas gostei da sua proposta, vou publicar uma solução assim, ขอบคุณ!

  2. Régis กล่าวว่า:

    Estranho As vezes funciona e as vezes não funciona usando o Chrome, Opera e Fire Fox no gmail e hotmaillimpo o cache e cookies, mas as vezes não faz a gravação no BD se o email foi aberto ou não !!

  3. diego กล่าวว่า:

    Galera..tenho um script de cadastro com nome..emailcpfrgqueria que depois que usuario cadastrar tudo e enviasse pro meu banco de dadosretorna algo pro email dele automatico..tipo
    EXEMPLO:”informações cadastrada com sucesso..aguarde nosso contato

    Teria como??

    • ดารา, como disse no Post: “Para isso funcionar, o destinatário necessariamente precisa ter configurado para que seu e-mail seja lido no formato HTML”. Por padrão o HTML é renderizado, mas mesmo o Gmail se mudar a renderização para TEXTO, daí não vai funcionar, pois ele vai simplesmente exibir as TAGs HTML como texto ao invés de renderizá-las.

ทิ้งคำตอบไว้

อีเมลของคุณจะไม่ถูกเผยแพร่. ฟิลด์ต้องมีเครื่องหมาย *