Logo
You
Code

Auto Responder con Postfix + PHP + MySql

Autor YouCode - http://www.youcode.com.ar/postfix/auto-responder-con-postfix-php-mysql-193

Script para crear respuestas automaticas para las cuentas de e-mail, usaremos MySql para guardar las respuestas, PHP se encargara de buscarlas en la base y enviara el mail de respuesta al REMITENTE. Debian Squeeze x64

Antes que nada, es valido aclarar que deberemos tener POSTFIX configurado correctamente, en mi caso tengo dominios virtuales, pero para este script no hace falta que POSFTIX este configurado para dominios virtuales.
No vamos a explicar como instalar y configurar POSTFIX, se asume que ya esta instalado.

Veamos como funciona la cuestion:

Cada vez que se recibe un e-mail, POSTFIX hace una serie de validaciones antes de entregarlo al destinatario (asumiendo que el destinatario somo nosotros, o sea, nos estan enviando un e-mail)

Lo "fabuloso" de POSTFIX es que el archivo de configuracion master.cf se indican todos los procesos que postfix correra y ahi es donde le diremos que al llegar un e-mail dispare o lance nuestro php.

Nuestro script PHP tomara ese mail que postfix le envia por la "tuberia unix" , lo procesamos y debemos devolverlo a postfix, sino el mail nuere en nuestro script , y eso es lo que no queremos. El devolver el mail a POSTFIX lo hacemos mediante SENDMAIL y el enviar la respuesta lo hacemos con la funcion MAIL de PHP.

Vamos al script php , como siempre..........los limites es la imaginacion de cada programador, mas adelante estaremos publicando un articulo completo para agregar disclaimer en cada mail y lo bueno es que no usaremos altermime ni el famoso script en bash "disclaimer" que esta por todos lados en la web, aunque ese script es muy bueno y yo lo usaba.

Primero deberiamos tener una tabla en una base de datos para almacenar las respuesta, la siguiente es la tabla que tengo en mis servers, aqui la DDL para crear la tabla:
 
CREATE TABLE `sm_autorespuestas` (
  `email` varchar(50) NOT NULL,
  `nombre` varchar(50) DEFAULT NULL,
  `mensaje` varchar(255) DEFAULT NULL,
  `desde` date DEFAULT NULL,
  `hasta` date DEFAULT NULL,
  `activo` int(11) DEFAULT '0',
  PRIMARY KEY (`email`),
  KEY `email` (`email`,`desde`,`hasta`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Donde:
email es la direccion de email de la persona que quiere tener la respuesta automatica
nombre es el nombre de la persona para que aparezca en el From
mensaje es el mensaje concretamente que se enviara al remitente
desde es la fecha de inicio del periodo
hasta es la fecha de fin del periodo
activo se usa como un flag, para indicar si esta activo o no el envio de respuesta, esto es porque sino se usa la respuesta, el registro quedara en la base, con activo=1 asumimos que se debe enviar (siempre que estemos en el rango de fechas) y si activo=0 no se envia por mas que estemos en el rango de fecha.

El script (va por partes para que sea mas entendible, pero esta claro que estara todo junto):

Parte 1

Leemos el mail que nos manda POSTFIX travez de la "tuberia unix"
#Abrimos el "tunel unix stdin como lectura"
$fd=fopen("php://stdin","r");
$email=array();
#Leemos el email a medida que lo recibimos desde postfix
while($line=fgets($fd,1024))
{
    $email[]=$line;	
    }
fclose($fd);

Parte 2

Esta porcion de codigo la usaremos para tomar el FROM que viene desde POSTFIX (ya veremos como) y tambien toma todas las posibles direcciones de e-mail, esto es porque puede pasar que el mail este dirijido a mas personas y no deberiamos perder estos datos.
 
#Leemos los argumentos que le llegan a este script cuando postfix nos
#envia el mail.
$i=0;
#Si $i es mayor a 2, significa que tenemos mas de una direccion de e-mail.
foreach($argv as $arg)
{
    if($i==1)
    {
	$fromaddress=$arg;
    }elseif($i==2){
	$sendlist=$arg;	
    }elseif($i>2){
	$sendlist=$sendlist." ".$arg;
    }
    $i++;
}

Parte 3

Quiza confunda un poco esta parte, pero aqui devolvemos el E-Mail a POSTFIX para que continue su camio, esto es asi porque sino lo hacemos, el mail muere en nuestro script, luego de devolverlo vemos si tenemos o no que madar la respuesta automatica.
 

#Preparamos los datos para darcelos a SENDMAIL
#a la vez, creamos un archivo txt para guardar los errores que pudieran aparecer
$descriptorspec=array(
    0=> array("pipe","r"),
    1=> array("pipe","w"),
    2=> array("file","/etc/postfix/filtermail/error-postfix.txt","a")
);

$sendmailcmd='/usr/sbin/sendmail -G -i -f ' . $fromaddress . ' -- ' .$sendlist;
$process=proc_open($sendmailcmd,$descriptorspec,$pipes);
if(is_resource($process))
{
    foreach($email as $line)
    {
	fwrite($pipes[0],$line);
    }
    fclose($pipes[0]);
    $stream=stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    proc_close($process);
    
    #Una yapita, vamos guardando las direcciones de mails en un archivo por
    #si algun dia queremos hacer algo ..... :)
    $file = fopen("/etc/postfix/filtermail/capturamails.txt", "a");
    fwrite($file,$fromaddress."\n");
    fwrite($file,$sendlist."\n");
    fclose($file);
}

Parte 4
Verificaremos si debemos enviar o no la respuesta automatica.

$conn=@mysql_connect('localhost','user','user_password');

#Veremos si se realizo la conexion a MySql
if(is_resource($conn))
{
  #Seleccionamos la base de datos
  @mysql_select_db('mi_base',$conn);

  #Si estamos conectados, hacemos la consulta
  #$sendlist es donde estara el TO , o sea, nosotros
  $sql="select email,nombre,mensaje from sm_autorespuestas 
        where 
        estado=1 and 
        curdate() between desde and hasta 
        and email='$sendlist' limit 1";

  #Ejecutamos la consulta
  if($r=@mysql_query($sql,$conn))
  {
     #Vemos si hay registro
     if(@mysql_num_rows($r)>0)
     {
       #Preparamos el mail de respuesa       
       $header="MIME-Version: 1.0\r\n";
       $header.="Content-type: text/plain;character=iso-8859-1\r\n";
       $header.="From:".@mysql_result($r,0,1)." <".@mysql_result($r,0,0).">\r\n";
       $Asunto="RESPUESTA AUTOMATICA";
       $Body=@mysql_result($r,0,2);
       #Enviamos la respuesta
       @mail($EmailFrom,$Asunto,$Body,$header);
       }
      @mysql_free_result($r);
      @mysql_close($conn);
    }
}

Parte 5

Configurando POSTFIX para que nos evie el e-mail.
ATENCION, para esta parte he creado en linux el usuario filtermail para que POSTFIX lance nuestro script con este usuario, el script php debemos darle los permiso correspondientes para que sea ejecutado.
El usuario lo he creado sin HOME

Muy bien! ahora en la carpeta postfix debemos crear una carpeta mas llamada filtermail donde se guardaran los archivos txt
quedaria /etc/postfix/filtermail

Vamos a decirle a POSTFIX que use nuestro script en cada llegada de mail, para esto hacemos:
cp master.cf master.cf.original
vi /etc/postfix/master.cf
La primera linea es para hacer un respaldo del archivo antes de que lo modifiquemos y la segunda para editarlo.
Muy bien! en la siguiente linea, debemos agregar -o content_filter=captura
smtp      inet  n       -       -       -       10       smtpd 
   -o content_filter=captura
lo que esto hace, es decirle a postfix que hay un filtro llamado captura, ahora "declaremos" el filtro captura en el mismo master.cf
captura unix - n n - - pipe
  flags=R user=filtermail null_sender= argv=/etc/postfix/respuesta.php ${sender} ${recipient}
ATENCION respuesta.php es justamente nuestro archivo php y este fragmento de "codigo" lo pondremos en el master.cf al final de todo.

Vamos a las pruebas!!!!
postfix reload
insertemos en la tabla un e-mail, el nombre, el mensaje, el periodo, estado=1 y enviemos un mail desde gmail o hotmail por ej a esta cuenta que insertamos, si todo salio bien, inmediatamante deberiamos recibir la respuesta automatica.

SI NUESTRA IMAGINACION SE ACTIVA, PUEDEN PROCESAR EL MAIL (EL MIME) Y AGREGAR DISCLAIMERS !!!! , pero para esto estamos preparando otro articulo como dije antes.

Fin!!!! ya tenemos un responderor (si vale decirlo asi) para cada cuenta de mail, y lo mejor es que se hace inmediato!!!!
 
http://www.youcode.com.ar/postfix/auto-responder-con-postfix-php-mysql-193