Procurei na internet e vi que muitas pessoas também tinham essa necessidade. Nessas buscas pela internet eu achei um post do Sr Nick Jeffries (http://tech.jeffri.es/2010/09/automatic-ripping-and-saving-email-attachments-with-postfix/) e partindo desse post adaptei a solução dele à nossa necessidade.
O script original remove os arquivos PDF e descarta a mensagem, o script foi alterado para remover os arquivos PDF/XML e devolver a mensagem pro postfix, afim de evitarmos perdas de e-mails.
Muitas pessoas utilizam scripts no crontab com munpack, o que também é uma boa opção quando seu hardware é mais antigo e não tem tanto desempenho. O desempenho depende do hardware que você utiliza, utilizamos um servidor Dell com 2 processadores Intel(R) Xeon(R) CPU E5504 @ 2.00GHz 4 Cores, com 16GB RAM, HD SAS 500GB em raid 1.
Aparentemente a utilização do script dentro do postfix como um "filtro" não fez nem cócegas no servidor.
A solução implantada aqui utliza: postfix (www.postfix.org) e ripmime (http://www.pldaniels.com/ripmime/).
Nesse post estamos nos baseando que já há um postfix instalado, configurado e funcionando.
Utilizamos o Ubuntu 10.x mas esse filtro funciona em qualquer distribuição, basta ajustá-lo.
A solução segue o original do Jeffries e está dividida nos passos:
- Instalação do ripMIME
- Configurando o postfix para executar um filtro na chegada dos e-mails (incoming mail)
- Criando o script de filtro
- Ajustes finais
Instalação do ripMIME
Primeiro de tudo, nós precisamos instalar o ripMIME, que é um utilitário para extrair o anexo de um e-mail e salvá-lo em algum lugar. Vamos precisar efetuar o download, compilação e instalação, uma coisa bem simples e fácil.
Antes de mais nada você precisa do compilador gcc instalado em seu sistema, caso você não o tenha instale-o. Para instalar o gcc utilize o aptitude ou o yum para instalar (aptitude install gcc / yum install gcc).
Aconselho criar um diretório e baixar o ripMIME para esse diretório.
No prompt do servidor digite:
mkdir temp
cd temp
wget http://www.pldaniels.com/ripmime/ripmime-1.4.0.9.tar.gz
tar zxvf ripmime-1.4.0.9.tar.gz
rm -f rip*.gz
cd ripmime-1.4.0.9/
make
sudo make install
Por padrão o ripmime se instala em /usr/local/bin , você pode alterar o local de instalação dele mas vamos utilizar o padrão.
Configurando o postfix para executar um filtro na chegada dos e-mails (incoming mail)
Vamos criar um script para executar com o postfix, o postfix vai "chamar" o script para verificar o e-mail que chegou, esse script vai fazer o papel de filtro e devolver a mensagem pro MTA.
O que precisamos no momento é adicionar as linhas abaixo no final "master.cf" do postfix (/etc/postfix/master.cf)
# Inserido por fulano : fulano@mail.com data: dd/mm/aaaa
# Begin
saveattachment unix - n n - 10 pipe
flags=Rq user=mail argv=/usr/bin/saveattachment -f ${sender} -- ${recipient}
# End
Essa linha diz ao postfix que o filtro chamado "saveattachment" é um script unix. Os e-mails de entrada (incoming) que utilizam esse filtro serão desviados para o script que está localizado em "/usr/bin/saveattachment"
Utilizamos esse filtro somente para os e-mails que chegam (incoming), procure a linha abaixo e adicione essa linha também ao "master.cf":
#
smtp inet n - - - - smtpd
#alterado por fulano: fulano@mail.com data DD/MM/AAAA
# Begin
-o content_filter=saveattachment:dummy
# End
Utilizei o usuário "mail" para execução do script, será com o id/gid desse usuário que os arquivos serão salvos, logo o usuário deverá ter permissão rwx no diretório que utilizaremos para deixar os arquivos extraídos.
Criando o script de filtro
O script utilizado é derivado do exemplo existente na documentação do Postfix (http://www.postfix.org/FILTER_README.html#simple_filter) .
O script salva os anexos e copia qualquer pdf/xml para um diretório, renomeando o anexo.
O script pode ser alterado facilmente ajustado conforme a necessidade.
--- Inicio do arquivo ---
#!/bin/bash
# Version 1.0 of script to save mail attachments
# Requires ripmime
# Original script http://tech.jeffri.es/wp-content/uploads/2010/09/saveattachment.txt
# Original script by Nick Jeffries
# Adjusted by Murilo Vitorino http;//mgvitorino.blogspot.com/
# alterar variavel "INSPECT_DIR" para o diretorio temporario que sera utilizado para extrair o arquivo
INSPECT_DIR=/maildir/temp/
# alterar variavel "TARGET_DIR" para diretorio onde serao colocados arquivos pdf/xml
TARGET_DIR=/maildir/server/
SN="saveattachment:"
# linha para reenvio da msg ao postfix
SENDMAIL="/usr/sbin/sendmail -G -i" # NEVER NEVER NEVER use "-t" here.
# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
EX_UNAVAILABLE=69
# Clean up when done or when aborting.
trap "rm -f in.$$ *textfile*" 0 1 2 3 15
echo "$SN Starting scan of incoming email"
# Start processing.
cd $INSPECT_DIR || {
echo "$SN $INSPECT_DIR does not exist"; exit $EX_TEMPFAIL; }
cat >in.$$ || {
echo "$SN: Cannot save mail to file"; exit $EX_TEMPFAIL; }
# Now invoke ripmime to process the temporary file
echo "$SN Invoking ripmime"
/usr/local/bin/ripmime -v --prefix -i in.$$ || {
echo "$SN Ripmime failed"; exit $EX_TEMPFAIL; }
NUM_SOURCE_FILES=`ls -1 *.pdf | wc -l`
# Adicionado ao script original para filtrar arquivos xml
#
NUM_SOURCE_FILES1=`ls -1 *.xml | wc -l`
#
#
if [ $NUM_SOURCE_FILES -gt 0 ]; then
for f in *.pdf
do
TARGET_FILE=${TARGET_DIR}$$_$f
echo "$SN Setting perms and copying $f to $TARGET_FILE"
chmod 775 $f
mv $f $TARGET_FILE
done
else
echo "$SN No PDF files to copy"
fi
# adicionado para pegar arquivos xml de nf-e
#
if [ $NUM_SOURCE_FILES1 -gt 0 ]; then
for f in *.xml
do
TARGET_FILE=${TARGET_DIR}$$_$f
echo "$SN Setting perms and copying $f to $TARGET_FILE"
chmod 775 $f
mv $f $TARGET_FILE
done
else
echo "$SN No XML files to copy"
fi
#
#
# linha para reinject da msg no postfix
$SENDMAIL "$@" <in.$$
exit $?
--- Fim do arquivo ---
Ajustes Finais
Precisamos criar os diretórios para que o script funcione:
sudo chmod 755 /usr/bin/saveattachment
sudo mkdir -p /maildir/temp
sudo mkdir /maildir/server
sudo chown -R postfix: /maildir
sudo chmod 770 /maildir/temp
sudo chmod 770/maildir/server
sudo chown mail:postfix /maildir/server
sudo chown mail:postfix /maildir/temp
Para testar o script você pode criar um arquivo de mensagem com xml/pdf, enviar via telnet ou através do próprio script saveattachment. Primeiro vamos criar uma mensagem em formato mime com um pequeno xml dentro:
vi ~/mensagem
--- Inicio do arquivo---
Content-Type: multipart/mixed; boundary=00032555b4663d720b04ababfe2e
--00032555b4663d720b04ababfe2e
Content-Type: multipart/alternative; boundary=00032555b4663d720304ababfe2c
--00032555b4663d720304ababfe2c
Content-Type: text/plain; charset=ISO-8859-1
--
Atenciosamente,
--00032555b4663d720304ababfe2c
Content-Type: text/html; charset=ISO-8859-1
--00032555b4663d720304ababfe2c--
--00032555b4663d720b04ababfe2e
Content-Type: text/xml; charset=US-ASCII; name="teste.xml"
Content-Disposition: attachment; filename="teste.xml"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_grxzndh50
PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8YXZpc28+DQo8cGFyYT5QYXJhIFhNTCAiMDEvMDQvMjAw
MCI8L3BhcmE+DQo8ZGU+VGVzdGU8L2RlPg0KPGNhYmVjYWxobz5MZW1icmUtc2U8L2NhYmVjYWxo
bz4NCjxjb3Jwbz5BbWFuaGEgdm9jZSB0ZW0gcHJvdmEgZGUgbWF0ZW1hdGljYTwvY29ycG8+DQo8
L2F2aXNvPiANCg==
--00032555b4663d720b04ababfe2e--
--- Fim do Arquivo ---
Agora vamos usar o script para enviar essa mensagem:
/usr/bin/saveattachment -f remetente@dominio.com -- destinatario@dominio.com < mensagem
Verifique o diretorio escolhido para os arquivos XML onde deve conter um arquivo xml com o nome $idmsg_teste.xml .
Qualquer dúvida, estou à disposição.
