http://www.perlmonks.org?node_id=146483
Category: PerlMonks Related Scripts
Author/Contact Info Zenon Zabinski | zdog | zdog@perlmonk.org
Description: This script checks to see if you have received any /msg's, emails them to you, and then provides an interface to handle replies (at least it's supposed to). When you get such an email, all you do is hit reply (making sure that the info within the brackets is still in the subject), type in your msg, and hit send. In order to set it up, you need a Un*x system running an SMTP server (at least I think you do). You run this script as a daemon using root and whoever wants to take advantage of the service just creates a configuration file in their home directory in the following form:

pm_username|pm_passwd|email_addy

It's that simple (at least I hope it is).

use strict;
use warnings;

use Unix::PasswdFile;
use HTTP::Cookies;
use XML::Simple;
use MIME::Lite;
use Mail::Box::Mbox;
use URI::Escape;
require LWP::UserAgent;
require HTTP::Request;

use vars qw ($username $host $maildir $msgsleep $usersleep 
  $configfile $cookiefile $pmurl %users);

### BEGINNING OF USER SETTINGS #######################################
+#########

$username = 'msgmail';            # Username of the daemon.
$host     = 'localhost';          # Host of the msgmail daemon.
$maildir  = '/var/spool/mail';    # Location of mbox mail "folders".
$msgsleep = 5;                    # Time (in minutes) between /msg che
+cks.
$usersleep  = 60;            # Time (in minutes) between checks for ne
+w users.
$configfile = '.msgmail';    # Name of config file in each user's home
+dir.
$cookiefile = '.msgmail_cookie';   # Name of cookie file in each user'
+s homedir.
$pmurl = 'http://www.perlmonks.org/';    # Url of PerlMonks.

### END OF USER SETTINGS #############################################
+#########

{
    init();

    my $i = 0;

    for ( ; ; ) {
        if ( $i == $usersleep ) {
            getUsers();
            $i = 0;
        }

        for my $user ( keys %users ) {
            my $msgreq = HTTP::Request->new( GET => "$pmurl?node_id=15
+848" );
            $users{$user}{ua}->cookie_jar->add_cookie_header($msgreq);
            ( my $xml =
              XMLin( $users{$user}{ua}->simple_request($msgreq)->{_con
+tent},
              forcearray => 1 ) ) || next();

            for my $msg ( @{ $$xml{message} } ) {
                if ( $$msg{content} =~ m/\[(.*?)\] announcement -- / )
+ {
                    my $temp_auth = $1;
                    $$msg{content} =~ s/--/-- [$$msg{author}] says:/;
                    $$msg{author} = $temp_auth;
                }

                my $mail = MIME::Lite->new(
                  From    => "$username\@$host",
                  To      => $users{$user}{email},
                  Subject => "/msgmail from $$msg{author} "
                  . "[$$msg{author}:$user:"
                  . crypt( $users{$user}{passwd}, $user ) . "]",
                  Data => $$msg{content}
                );

                if ( $mail->send ) {
                    my $delreq =
                      HTTP::Request->new( HEAD =>
                      "$pmurl?op=message&deletemsg_$$msg{message_id}=y
+up" );
                    $users{$user}{ua}->cookie_jar->add_cookie_header($
+delreq);
                    $users{$user}{ua}->simple_request($delreq);
                }
            }
        }

        my $folder =
          Mail::Box::Mbox->new( folder => "=$username", folderdir => $
+maildir,
          access => 'rw' );

        for (@$folder) {
            ( my ( $to, $from, $passwd ) =
              $_->subject() =~ m/\[(.*?):(.*?):(.*?)\]/ )
              || $_->delete() && next();

            if ( $passwd ne crypt( $users{$from}{passwd}, $from ) ) {
                $_->delete() && next();
            }

            my $text = $_->body();
            $text =~ s/\n/ /g;
            $text = uri_escape($text);

            my $sendreq =
              HTTP::Request->new( HEAD =>
              "$pmurl?op=message&message=/msg\%20$to\%20$text" );
            $users{$from}{ua}->cookie_jar->add_cookie_header($sendreq)
+;
            $users{$from}{ua}->simple_request($sendreq) && $_->delete(
+);
        }

        $folder->close();

        $i++;
        sleep($msgsleep);
    }
}

sub getUsers {
    my $pw = Unix::PasswdFile->new("/etc/passwd");

    foreach ( $pw->users() ) {
        open( FILE, "<" . $pw->home($_) . "/$configfile" ) || next();
        chomp( my $line = <FILE> );
        close(FILE);
        my ( $user, $passwd, $email ) = split ( /\|/, $line );

        my $ua = LWP::UserAgent->new();
        $ua->cookie_jar(
          HTTP::Cookies->new(
          File           => $pw->home($_) . "/$cookiefile",
          AutoSave       => 1,
          ignore_discard => 1 )
        );
        $ua->cookie_jar->load( $pw->home($_) . "/$cookiefile" );
        $ua->simple_request( HTTP::Request->new( GET =>
          "$pmurl?user=$user&passwd=$passwd&op=login" ) ) || next();
        $ua->cookie_jar->save() || next();

        $users{$_} = { ua => $ua, email => $email, passwd => $passwd }
+;
    }
}

sub init {  # Initializes stuff for the program to use.
    getUsers();

    $usersleep = int( $usersleep / $msgsleep );
    $msgsleep *= 60;

    MIME::Lite->send( 'smtp', 'localhost', Timeout => 60 );
}