doručenky/dorucenky.pl
author František Kučera <franta-hg@frantovo.cz>
Wed, 30 Nov 2011 15:44:34 +0100
changeset 21 a5c8edf14f82
child 23 c78f71bda340
permissions -rwxr-xr-x
Doručenky: sieve přesměrování + skript v perlu (přes aliasy) místo milteru.
franta-hg@21
     1
#!/usr/bin/env perl
franta-hg@21
     2
franta-hg@21
     3
use strict;
franta-hg@21
     4
use MIME::Parser;
franta-hg@21
     5
use Net::SMTP;
franta-hg@21
     6
franta-hg@21
     7
# K doručenkám typu:
franta-hg@21
     8
#	Content-Type: multipart/report; report-type=delivery-status; ~ Delivery Status Notification (DSN)
franta-hg@21
     9
# doplňujeme hlavičku References, 
franta-hg@21
    10
# aby si je e-mailový klient mohl zařadit do vlákna pod zprávu, ke které doručenka patří.
franta-hg@21
    11
franta-hg@21
    12
# viz http://search.cpan.org/~dskoll/MIME-tools-5.502/lib/MIME/Entity.pm
franta-hg@21
    13
# viz http://search.cpan.org/~dskoll/MIME-tools-5.502/lib/MIME/Head.pm
franta-hg@21
    14
# viz http://search.cpan.org/~gbarr/libnet-1.21/Net/SMTP.pm
franta-hg@21
    15
franta-hg@21
    16
franta-hg@21
    17
# Nastavení --------------------------------------------------------------------
franta-hg@21
    18
my $komu = 'noreply@example.com'; # adresa správce – sem pošleme zprávy, pokud nevíme, kam je poslat (chybí Delivered-To), nebo máme podezření na zacyklení
franta-hg@21
    19
# ------------------------------------------------------------------------------
franta-hg@21
    20
franta-hg@21
    21
my $znacka = "X-DSN-Pridej-References"; # hlavička, kterou si poznačíme, že zpráva prošla tímto programem
franta-hg@21
    22
my $stav = "chyba - nedefinovano"; # výchozí hodnota naší hlavičky
franta-hg@21
    23
franta-hg@21
    24
franta-hg@21
    25
# Načteme zprávu
franta-hg@21
    26
my $parser = new MIME::Parser;
franta-hg@21
    27
$parser->output_to_core(1);
franta-hg@21
    28
my $dorucenka = $parser->parse(\*STDIN);
franta-hg@21
    29
franta-hg@21
    30
franta-hg@21
    31
# Kontrola, že se zpráva nezacyklila (chybí naše značka)
franta-hg@21
    32
if ($dorucenka->head->count($znacka) == 0) {
franta-hg@21
    33
	
franta-hg@21
    34
	# Podle hlavičky Delivered-To zjistíme, kam máme zprávu poslat zpátky	
franta-hg@21
    35
	my $deliveredTo = $dorucenka->head->get("Delivered-To", 1); # [0] = adresa tohoto skriptu, [1] = předchozí adresa – původní příjemce doručenky 
franta-hg@21
    36
	if ($deliveredTo) {
franta-hg@21
    37
		$deliveredTo =~ s/\s+$//; # zbavíme se přebytečného konce řádku
franta-hg@21
    38
		$komu = $deliveredTo;
franta-hg@21
    39
		$dorucenka->head->delete("Delivered-To", 1); # aby si poštovní server nemyslel, že se zpráva zacyklila 
franta-hg@21
    40
		
franta-hg@21
    41
		# Pokud hlavička References chybí, doplníme ji
franta-hg@21
    42
		if ($dorucenka->head->count("References") == 0) {
franta-hg@21
    43
			
franta-hg@21
    44
			# Zjistíme Message-ID původní zprávy
franta-hg@21
    45
			my $messageID;
franta-hg@21
    46
			my @casti = $dorucenka->parts;
franta-hg@21
    47
			for my $cast (@casti) {
franta-hg@21
    48
				if ($cast->mime_type eq "text/rfc822-headers") {
franta-hg@21
    49
					my @radky = $cast->bodyhandle->as_lines;
franta-hg@21
    50
					for my $radek (@radky) {
franta-hg@21
    51
						if ($radek =~ /^Message-ID:\s*(<.*>)$/) {
franta-hg@21
    52
							$messageID = $1;
franta-hg@21
    53
						}
franta-hg@21
    54
					}
franta-hg@21
    55
				}			
franta-hg@21
    56
			}		
franta-hg@21
    57
			
franta-hg@21
    58
			# Nastavíme nalezené Message-ID do References hlavičky
franta-hg@21
    59
			if ($messageID) {
franta-hg@21
    60
				$stav = "ok";
franta-hg@21
    61
				$dorucenka->head->add("References", $messageID);
franta-hg@21
    62
			} else {
franta-hg@21
    63
				$stav = "chyba - Message-ID nenalezeno";
franta-hg@21
    64
			}
franta-hg@21
    65
			
franta-hg@21
    66
		} else {
franta-hg@21
    67
			$stav = "hlavicka References uz byla nastavena drive";
franta-hg@21
    68
		}		
franta-hg@21
    69
	} else {
franta-hg@21
    70
		$stav = "chyba - nevime, kam zpravu poslat zpet";
franta-hg@21
    71
	}	
franta-hg@21
    72
} else {
franta-hg@21
    73
	# Zpráva se zacyklila → pouze přidáme svoji značku
franta-hg@21
    74
	# a pošleme správci (nezměníme $komu)
franta-hg@21
    75
	$stav = "chyba - cyklus";
franta-hg@21
    76
}
franta-hg@21
    77
franta-hg@21
    78
franta-hg@21
    79
$stav .= " [pid=$$,uid=$>]"; # přidáme PID a UID
franta-hg@21
    80
$dorucenka->head->add($znacka, $stav);
franta-hg@21
    81
franta-hg@21
    82
# Výpis (nepotřebujeme, jen pro ladění)
franta-hg@21
    83
#$dorucenka->print(\*STDOUT);
franta-hg@21
    84
#print "Pošleme komu: $komu\n";
franta-hg@21
    85
franta-hg@21
    86
# Odeslání přes SMTP (pro ostrý provoz):
franta-hg@21
    87
my $smtp = Net::SMTP->new("localhost");
franta-hg@21
    88
$smtp->mail('<>');
franta-hg@21
    89
$smtp->to($komu);
franta-hg@21
    90
$smtp->data();
franta-hg@21
    91
$dorucenka->print($smtp);
franta-hg@21
    92
$smtp->dataend();
franta-hg@21
    93
$smtp->quit;