1 package Promulger::Dispatch;
3 use Method::Signatures::Simple;
8 use Email::Sender::Simple ();
9 # XXX not yet -- apeiron, 2010-06-25
12 use Promulger::Config;
19 $proto->can('does') and
20 $proto->does('Email::Sender::Transport')
21 or die "transport must do Email::Sender::Transport role";
24 Email::Sender::Transport::Sendmail->new
28 # XXX no bounce parsing yet -- apeiron, 2010-03-13
29 method dispatch ($message) {
30 my $config = Promulger::Config->config;
32 my $email = Email::MIME->new($message);
33 my $recipient = $email->header('To');
34 my $local_user = $self->user_for_address($recipient);
35 my $sender = $email->header('From');
36 my $subject = $email->header('Subject');
38 my $list = Promulger::List->resolve($local_user);
40 $self->reject($recipient, $sender);
44 if($local_user =~ /-request$/) {
45 $self->handle_request($list, $sender, $local_user, $subject, $config);
49 # they don't have a request for us, so they want to post a message
50 $self->post_message($list, $email, $config);
54 method handle_request ($list, $sender, $recipient, $subject) {
55 my $sender_address = $self->bare_address($sender);
56 if($subject =~ /^\s*subscribe/i) {
57 $list->subscribe($sender_address)
58 or $self->already_subscribed($list, $recipient, $sender_address);
59 } elsif($subject =~ /^\s*unsubscribe/i) {
60 $list->unsubscribe($sender_address)
61 or $self->not_subscribed($list, $recipient, $sender_address);
65 method post_message ($list, $email, $config) {
66 my $sender = $email->header('From');
67 my $sender_address = $self->bare_address($sender);
68 my $recipient = $email->header('To');
70 unless($list->accept_posts_from($sender_address) && $list->active) {
71 $self->reject($recipient, $sender);
75 # XXX no MIME or other fancy handling for now -- apeiron, 2010-03-13
76 my $body = $email->body_str;
77 for my $subscriber (keys %{$list->subscribers}) {
78 # my $verped_from = Mail::Verp->encode($recipient, $subscriber);
80 # XXX we let the MTA create the message-id for us for now -- apeiron,
82 my $new_message = Email::MIME->create(
84 From => $sender_address,
86 Subject => $email->header('Subject'),
87 'Reply-to' => $recipient,
91 # XXX no queuing or job distribution for now beyond what the MTA provides
92 # -- apeiron, 2010-03-13
93 $self->send_message($new_message);
97 method send_message ($message) {
98 my $config = Promulger::Config->config;
99 my ($class, $transport);
100 if($class = $config->{mailer}) {
102 $class = "Email::Sender::Transport::${class}";
105 $class = 'Email::Sender::Transport::Sendmail';
107 Class::MOP::load_class($class);
108 $transport = $class->new;
109 Email::Sender::Simple::sendmail(
112 transport => $self->transport,
117 # XXX make this actually not suck -- apeiron, 2010-03-13
118 method reject ($recipient, $sender) {
119 my $email = Email::MIME->create(
123 Subject => 'Rejected',
126 Sorry, your message to $recipient has been denied.
129 $self->send_message($email);
132 method not_subscribed ($list, $recipient, $sender) {
133 my $email = Email::MIME->create(
134 # XXX need admin address
138 Subject => 'Not subscribed',
141 Sorry, you are not subscribed to $list.
144 $self->send_message($email);
147 method already_subscribed ($list, $recipient, $sender) {
148 my $email = Email::MIME->create(
152 Subject => 'Already subscribed',
155 Sorry, you are already subscribed to $list.
158 $self->send_message($email);
161 method bare_address ($full_addr) {
162 my ($addr_obj) = Email::Address->parse($full_addr);
163 return $addr_obj->address;
166 method user_for_address ($full_addr) {
167 my ($addr_obj) = Email::Address->parse($full_addr);
168 return $addr_obj->user;
171 'http://www.shadowcat.co.uk/blog/matt-s-trout/oh-subdispatch-oh-subdispatch/';