Perl Email Fwd: STDIN --> smtp

XioniX

Member
Hallo zusammen,

ich möchte mir ich kleines Emailverteilerscript in Perl schreiben, das von Postfix eine Mail bekommt (Pipe) und diese unverändert an alle Empfänger schickt, die ich mir per SQL-Query hole (Ca. 50 Empfänger, mehrere Gruppen mit Überschneidungen). Gesendet werden soll per SMTP an localhost.

Code:
#!/usr/bin/perl -w
use strict;

use Mail::Internet;
use Net::SMTP;
use Net::Domain;

my $message;
$message = Mail::Internet->new(\*STDIN);

#Hier kommt die Mysql Query für die Empfängerliste

#Foreach Empfänger
$message->smtpsend(Host => 'localhost', To => 'empfänger@email.de');

exit(0);

Das funktionniert soweit schon ganz gut, nur bleibt die Mail nicht unverändert. Es wird beispielsweise einige Header nicht übernommen (Return-Path, etc..) und Perl fügt ein "X-Mailer: Perl5 Mail::Internet v2.03" usw. zu, was ich nicht möchte. Vllt geht das ja auch ohne SMTP und mit Unix Sockets. Mir ist lediglich wichtig, dass die Mail unverändert bleibt und dass ich die Empfänger ändern kann.

Vielleicht kann mir da jemand auf die Sprünge helfen.
 
Wenn du statt Mail::Internet direkt mit Net:SMTP arbeitest, dann hast mehr Kontrolle über die Header.

Wie du dir das unverändert vorstellst ist mir auch nicht ganz klar. Der Return-Path ist während der Übertragung zwischen den MTAs überhaupt nicht vorhanden. Der wird erst bei der Auslieferung an den Empfänger vom Delivery Agent hinzugefügt und enthält den Absender, wie er sich im SMTP-Dialog mit dem MAIL FROM vorgestellt hat. Erstmal ist es also korrekt, dass dieser Header nicht angenommen wird. Der Header wird beim Empfänger generiert, wenn du den Wert aus der eingelesenen Mail extrahierst und im SMTP-Dialog wieder als Absender verwendest.

Weiterhin wird dein Postfix einen zusätzlichen Received from localhost einfügen, den es in der Orginalmail nicht gibt (und jedes weitere System auf dem Weg zum Empfänger wird das auch tun). Daraus kann ein routinierter Admin schon erkennen, dass an der Stelle mit der Mail was angestellt wurde.

Von der Performance wird es übrigens deutlich besser laufen, wenn du nicht jede Mail einzeln generierst, sondern die Mail einmal an alle Empfänger gleichzeitig schickst. Die Empfänger werden im SMTP-Dialog mit RCPT TO gesetzt, während der To-Header in der Mail selber sonstwas enthalten kann. So sehen die Empfänger sich gegenseitig in der ausgelieferten Mail nicht.
 
Hallo Cenic,

danke für deine Antwort, das mit NET::SMTP hab ich kurze Zeit später auch rausgefunden.

Vielleicht hab ich mich da etwas ungeschickt ausgedrückt, aber mit 'unverändert' meinte ich, dass alle bisherigen Header erhalten bleiben sollten. Zusätzliche Received müssen ja unvermeidlich beim erneuten Zustellen hinzugefügt werden.

Da ich das Skript in die /etc/aliases eingefügt hab, war der Return-Path natürlich vorhanden (Postfix denkt ja, die Mail wird nun zugestellt), wird aber neu gesetzt, wenn ich die Mail dann nochmal einliefere.

Mittlerweile sieht das Script folgendermaßen aus und funktionniert genauso wie es soll.
Code:
#!/usr/bin/perl -w
use strict;
use DBI;
use Net::SMTP;

my $tmp;
my $database ="mail";
my $user = "mail";
my $pass = "***";
my $host="localhost";
my $query = "SELECT `Email` FROM `verteiler` WHERE `Vorstandschaft` = 1";
 
my $db = DBI->connect("DBI:mysql:$database:$host", $user, $pass);
$query = $db->prepare($query) or die "Can't prepare $query: $db->errstr\n";
$query->execute or die "can't execute the query: $query->errstr\n";

my $smtp = Net::SMTP->new(Host => 'localhost:25', ExactAddresses => 1, Timeout => 60) or die "Couldn't connect to server\n";
 
$smtp->mail("owner-list\@mydomain.de");

while ($tmp = $query->fetchrow_array()) {$smtp->to($tmp)}

$smtp->data();

while (defined($tmp = <stdin>)) {$smtp->datasend($tmp)}

$smtp->datasend("\n");
$smtp->dataend();
 
$smtp->quit();

exit(0);

Vielleicht gibts ja trotzdem noch Optimierungsmöglichkeiten :-)

Was jetzt noch ganz nützlich wäre die Möglichkeit einen Footer in den Emailtext einzufügen, was mit aber mit multipart messages irgendwie schwer fällt :-S
 
Last edited by a moderator:
Back
Top