#!/usr/bin/perl # brunch-spam.pl, written by philg@mit.edu, william.crawford@gmail.com December 2004 # based on http://www.ocf.berkeley.edu/~ryantate/massmail.pl.txt # database format is # email|full name|affiliation note|keywords space-separated # everything optional except email # examples # george.w.bush@aya.yale.edu|George W. Bush|smartest Yale grad ever|politics drinking iraq iraq iraq # john.f.kerry@aya.yale.edu|||leisure rich-babes yachting mansions # billg@microsoft.com # parameters my $return_email_address = '*** put your email address here ***'; my $return_full_name = '*** put your name here ***'; my $debug = 0; ## # prompt for database file, message file, subject line, keywords printf "Enter database file name: "; my $address_file = ; chomp($address_file); printf "Enter message file name: "; my $message_file = ; chomp($$message_file); printf "Enter subject line: "; my $subject_line = ; chomp($subject_line); printf "Enter include-only keywords, space-separated (only those people flagged with at least one of these keywords will be invited): "; my $include_keyword_string = ; chomp($include_keyword_string); printf "Enter exclude keywords, space-separated (anyone flagged with this keyword will NOT be invited): "; my $exclude_keyword_string = ; chomp($exclude_keyword_string); my @include_keywords = split(" ",$include_keyword_string); my @exclude_keywords = split(" ",$exclude_keyword_string); # let's prepare regexps to make it easier to search for # these keywords in the database my $include_keywords_regexp = join("|",@include_keywords); my $exclude_keywords_regexp = join("|",@exclude_keywords); if ($debug) { print "include keywords regexp: $include_keywords_regexp\n"; }; if ($debug) { print "exclude keywords regexp: $exclude_keywords_regexp\n"; }; use strict; use Mail::Send; #Part of standard Perl distro my $sender = Mail::Send->new; #Our interface to sendmail et. al. $sender->subject($subject_line); open MESSAGE, "<$message_file" or die "Could not open messagefile: $!"; my $message = join('',); #Slurp in the whole message file close MESSAGE or die "Could not close messagefile: $!"; open ADDYS, "<$address_file" or die "Could not open addressfile: $!"; # first we build up a list of email addresses to send to, using the keywords as filters my @addresses; while () { chomp; # move to next line in file if blank next unless $_; #allow blank lines in addressfile # now must split by | to get the fields, backslash because | is special sep char for regexp my @email_record = split(/\|/,$_); my $email_addr = $email_record[0]; my $full_name = $email_record[1]; my $affiliation = $email_record[2]; my $keywords = $email_record[3]; my $candidate_for_push_flag = 0; if ($include_keywords_regexp) { if ($debug) { print "looking for include keywords in \"$keywords\" for $email_addr\n"; } if ($keywords =~ /$include_keywords_regexp/) { $candidate_for_push_flag = 1; } } else { # no keywords regexp so we put everything on $candidate_for_push_flag = 1; } if ($candidate_for_push_flag && $exclude_keywords_regexp) { if ($keywords =~ /$exclude_keywords_regexp/) { # take them off the list $candidate_for_push_flag = 0; } } if ($candidate_for_push_flag) { push(@addresses,$email_addr); } } close ADDYS or die "Could not close addressfile: $!"; # let's solicit confirmation from the user print "\n\nPreparing to send a message of the following form... Subject: $subject_line Message: $message ----------------- To the following folks "; foreach my $prospective_address (@addresses) { printf "$prospective_address, " } print "\n\nConfirm with y or abort with n: "; my $confirmation = ; chomp($confirmation); die "aborted" unless ($confirmation =~ /y/); #Send messages my $address_count = 0; foreach my $address (@addresses) { $sender->to($address); $sender->set('Reply-to', $return_email_address); # results in some ugliness in MSFT Outlook if you're not sending from your return address # $sender->set('From', "\"$return_full_name\" <$return_email_address>"); my $file_handle = $sender->open or die "Could not launch mailer: $!"; #Launch mailer print $file_handle $message; #Put message text in email $file_handle->close or die "Could not close mailer: $1"; #Send message $address_count++; } print "Sent $address_count messages.\n";