postfixでメールをフックしてSNSを実行する

なぜこんな狂ったことをやるかというと、Windows版のServerProtectがsmtp_authに対応していないのとなぜかQmailがエラーを出して受け取れないことがあるからです。

ひとまずPostfixを立ち上げ、信頼されたサーバーからのみメールリレー可能にしておきます。

sns実行用にユーザーsnsを作ります

useradd sns

awscli を使えるように aws configure などをおこなっておきます。

フックするように設定します。

vim /etc/aliases
---
nmp:            "|/home/sns/scripts/sns.sh > /home/sns/tmp/sns.log 2>&1"
---

newaliases

フック処理の実行ユーザーの変更をおこないます。

vim /etc/postfix/main.cf
---
default_privs = sns
---

フックの内容を作成します。

mkdir /home/sns/scripts
mkdir /home/sns/tmp

vim sns.sh
---
#!/bin/sh

MAILPATH=/home/sns/tmp/mail.txt
DECODETEXT=/home/sns/tmp/text.txt
DECODERPATH=/home/sns/scripts/body_parse.pl

if [ -p /dev/stdin ] ; then
    echo -n > $MAILPATH
    cat - > $MAILPATH
    $DECODERPATH > $DECODETEXT
    /usr/bin/aws sns publish --topic-arn "{arn}" --message fileb://$DECODETEXT
else
    echo "mail stdin not found"
fi
---

vim /home/sns/scripts/body_parse.pl
---
#!/usr/bin/perl

use Email::MIME;
use File::Slurp;
use Encode;
use Data::Dumper;

my $message = read_file("/home/sns/tmp/mail.txt");
my $parsed = Email::MIME->new($message);

my $header = $parsed->header("Subject");
print "[件名] \n" . $header;
print "\n\n";
print "[内容] \n";

my $isMultiPart = "false";
my @parts = $parsed->parts;
for my $part (@parts) {
    my $content_type = $part->content_type;
    #print $content_type;
    if ($content_type =~/text\/plain/) {
        #print $part->body;
        my $_body = $part->body_str;
        if ( utf8::is_utf8($_body) ) {
            print encode('utf-8', $_body);
        } else {
            print $_body;
        }
    }
    $isMultiPart = "true";
}

if ( $isMultiPart eq "false" ) {
    my $__body = $parsed->body;
    if ( utf8::is_utf8($__body) ) {
        print encode('utf-8', $__body);
    } else {
        print $__body;
    }
}
---

ServerProtectの方から

sns@localhost.localdomain

宛に送信すればSNSから送信されます。