refactor message sending to use a custom transport
[p5sagit/Promulger.git] / lib / Promulger / Dispatch.pm
CommitLineData
f5baca29 1package Promulger::Dispatch;
2use strict;
3use warnings;
4
8ad89cb2 5use Email::Address;
b179831b 6use Email::MIME;
f5baca29 7# XXX allow the user to specify their own Email::Sender::Transport -- apeiron,
8# 2010-03-13
9use Email::Sender::Simple qw(sendmail);
9f8395b9 10# XXX not yet -- apeiron, 2010-06-25
11#use Mail::Verp;
f5baca29 12
21baaef0 13use Promulger::Config;
14
15# XXX no bounce parsing yet -- apeiron, 2010-03-13
f5baca29 16sub dispatch {
8ad89cb2 17 my ($message) = @_;
21baaef0 18 my $config = Promulger::Config->config;
f5baca29 19
b179831b 20 my $email = Email::MIME->new($message);
f7a55eac 21 my $recipient = $email->header('To');
8ad89cb2 22 my $local_user = user_for_address($recipient);
f7a55eac 23 my $sender = $email->header('From');
24 my $subject = $email->header('Subject');
f5baca29 25
8ad89cb2 26 my $list = Promulger::List->resolve($local_user);
f5baca29 27 unless($list) {
28 reject($recipient, $sender);
8ad89cb2 29 return;
f5baca29 30 }
31
8ad89cb2 32 if($local_user =~ /-request$/) {
33 handle_request($list, $sender, $local_user, $subject, $config);
34 return;
f5baca29 35 }
36
37 # they don't have a request for us, so they want to post a message
38 post_message($list, $email, $config);
8ad89cb2 39 return;
f5baca29 40}
41
42sub handle_request {
21baaef0 43 my ($list, $sender, $recipient, $subject) = @_;
f5baca29 44
8ad89cb2 45 my $sender_address = bare_address($sender);
46 if($subject =~ /^\s*subscribe/i) {
f7a55eac 47 print "going to subscribe $sender to " . $list->listname . "\n";
8ad89cb2 48 $list->subscribe($sender_address)
49 or already_subscribed($list, $recipient, $sender_address);
50 } elsif($subject =~ /^\s*unsubscribe/i) {
51 $list->unsubscribe($sender_address)
52 or not_subscribed($list, $recipient, $sender_address);
f5baca29 53 }
54}
55
56sub post_message {
8ad89cb2 57 my ($list, $email, $config) = @_;
f5baca29 58
f7a55eac 59 my $sender = $email->header('From');
8ad89cb2 60 my $sender_address = bare_address($sender);
f7a55eac 61 my $recipient = $email->header('To');
f5baca29 62
8ad89cb2 63 unless($list->accept_posts_from($sender_address) && $list->active) {
64 reject($recipient, $sender);
65 return;
66 }
f5baca29 67
68 # they're allowed to post (subscribed or not), the list is active. let's do
69 # this thing.
70
71 # XXX no MIME or other fancy handling for now -- apeiron, 2010-03-13
b179831b 72 my $body = $email->body_str;
8ad89cb2 73 for my $subscriber (keys %{$list->subscribers}) {
f7a55eac 74 # my $verped_from = Mail::Verp->encode($recipient, $subscriber);
75
f5baca29 76 # XXX we let the MTA create the message-id for us for now -- apeiron,
77 # 2010-03-13
b179831b 78 my $new_message = Email::MIME->create(
f5baca29 79 header => [
e9b4d3bc 80 From => $sender_address,
81 To => $subscriber,
f7a55eac 82 Subject => $email->header('Subject'),
e9b4d3bc 83 'Reply-to' => $recipient,
f5baca29 84 ],
85 body => $body,
86 );
87 # XXX no queuing or job distribution for now beyond what the MTA provides
88 # -- apeiron, 2010-03-13
f7a55eac 89 send_message($new_message);
f5baca29 90 }
91}
92
f7a55eac 93sub send_message {
94 my ($message) = @_;
95 my $config = Promulger::Config->config;
96 my ($class, $transport);
97 if($class = $config->{transport}) {
98 if($class !~ /::/) {
99 $class = "Email::Sender::Transport::${class}";
100 }
101 } else {
102 $class = 'Email::Sender::Transport::Sendmail';
103 }
104 Class::MOP::load_class($class);
105 $transport = $class->new;
106 sendmail(
107 $message,
108 {
109 transport => $transport,
110 }
111 );
112}
113
21baaef0 114# XXX make this actually not suck -- apeiron, 2010-03-13
115sub reject {
8ad89cb2 116 my ($recipient, $sender) = @_;
b179831b 117 my $email = Email::MIME->create(
21baaef0 118 header => [
119 From => $recipient,
120 To => $sender,
121 Subject => 'Rejected',
122 ],
123 body => <<BODY,
124Sorry, your message to $recipient has been denied.
125BODY
126 );
f7a55eac 127 send_message($email);
21baaef0 128}
129
130sub not_subscribed {
8ad89cb2 131 my ($list, $recipient, $sender) = @_;
b179831b 132 my $email = Email::MIME->create(
8ad89cb2 133 # XXX need admin address
21baaef0 134 header => [
8ad89cb2 135 From => $recipient,
21baaef0 136 To => $sender,
137 Subject => 'Not subscribed',
138 ],
139 body => <<BODY,
8ad89cb2 140Sorry, you are not subscribed to $list.
21baaef0 141BODY
142 );
f7a55eac 143 send_message($email);
21baaef0 144}
145
146sub already_subscribed {
8ad89cb2 147 my ($list, $recipient, $sender) = @_;
b179831b 148 my $email = Email::MIME->create(
21baaef0 149 header => [
8ad89cb2 150 From => $recipient,
21baaef0 151 To => $sender,
152 Subject => 'Already subscribed',
153 ],
154 body => <<BODY,
8ad89cb2 155Sorry, you are already subscribed to $list.
21baaef0 156BODY
157 );
f7a55eac 158 send_message($email);
21baaef0 159}
f5baca29 160
8ad89cb2 161sub bare_address {
162 my ($full_addr) = @_;
163 my ($addr_obj) = Email::Address->parse($full_addr);
164 return $addr_obj->address;
165}
166
167sub user_for_address {
168 my ($full_addr) = @_;
169 my ($addr_obj) = Email::Address->parse($full_addr);
170 return $addr_obj->user;
171}
172
f5baca29 173'http://www.shadowcat.co.uk/blog/matt-s-trout/oh-subdispatch-oh-subdispatch/';