~メールからテキストファイルを作成して電話でをかけて読むまで~
謝意
http://ll.just4fun.biz/Perl/CPAN/CPAN%E7%92%B0%E5%A2%83%E3%82%92%E6%A7%8B%E7%AF%89%E3%81%99%E3%82%8B.html
そのほか、前の記事で記載したサイトを参考にさせていただきました。
注意:
インストール手順の詳細については、ログファイル紛失のため不明です。
ここでは、mailread@local に届いたメールを SIP/1001 に電話をかけて読み上げるという設定で行っています。
また、Asterisk の AMI のユーザーを「mailreader」パスワードを「pass」としています。適時書き換えてください。
まず、Perl のモジュールをインストールするために cpan と expect をインストールします。
# yum groupinstall 'Development tools' # yum -y install cpan expect
あとは、エラーメッセージに合わせて Perl のモジュールを入れていく感じです。
インストール時のログが見つからないので、詳細は見つかった時に追記します。
# touch /usr/bin/mailAnalyse.pl # chmod a+x /usr/bin/mailAnalyse.pl # mkdir /tmp/mail # chmod a+rw /tmp/mail # vi /usr/bin/mailAnalyse.pl
中身は以下の通りです。
#!/usr/bin/perl
use File::Basename;
use MIME::Parser;
my $parser = MIME::Parser->new;
#デフォルトの送信先時間設定
my $exten = 'SIP/1001';
my $SendAt = 'now';
#ファイルの一時保存場所を指定
$parser->output_dir('/tmp');
#標準入力からメールを取得
my $entity = $parser->parse(*STDIN);
#FromとSubjectのみ取り出し
my $from = $entity->head->decode->get('From');
my $subject = $entity->head->decode->get('subject');
my $body = $entity->is_multipart ? $entity->parts(0) : $entity;
my $bodyHandle = $body->bodyhandle;
my $lines = $bodyHandle->as_string;
my $TextHead1 = "メールが届いています。今から読み上げます。";
$from =~ s/info/インフォ/;
$from =~ s/sip/シップ/;
if (length($body) > 3) {
my @strline = split(/\n/, $lines,2);
my $wardindex = index($strline[0],"To:");
if ($wardindex == 0) {
$lines = $strline[1];
$exten = substr($strline[0],3);
@strline = split(/\n/, $lines,2);
my $wardindex1 = $strline[0];
my $wardindex2 = index($strline[0],"At:");
if ($wardindex1 == 8 && $wardindex2 == 0) {
$SendAt = substr($strline[0],3);
$lines = $strline[1];
}
}
}
$lines =~ s/info/インフォ/;
$lines =~ s/sip/シップ/;
my $TextRead = $TextHead1;
$TextRead = $TextRead . "送信元は、$from です。";
$TextRead = $TextRead . "件名は、$subject です。";
$TextRead = $TextRead . "本文を読み上げます。$lines";
$TextRead = $TextRead . "以上で終了します。";
#改行を削除
$TextRead =~ s/\r//;
$TextRead =~ s/\n//;
open(DAT,">>/tmp/mail.dat");
print DAT "To:$exten\n";
print DAT "At:$SendAt\n";
print DAT "$TextRead";
close(DAT);
sleep 2;
system("cp /tmp/mail.dat /tmp/mail/mail.dat");
/tmp/mail にファイルが届いた場合は wav ファイルを作成する準備をします。
postfix ならば、 /etc/aliases に、
mailread: | "/usr/bin/mailAnalyse.pl"
を1行書き加え、変更を反映させます。
# newaliases
# touch /usr/bin/mailAnalyse2.pl # chmod a+x /usr/bin/mailAnalyse2.pl # vi /usr/bin/mailAnalyse2.pl
中身は以下の通りです。
#!/usr/bin/perl my $exten = 'SIP/1001'; my $SendAt = 'now'; my @data; open(IN,"/tmp/mail/mail.dat"); @data =; close(IN); if (@data > 2){ my $wardindex1 = index($data[0],"To:"); my $wardindex2 = index($data[0],"At:"); if ($wardindex1 == 0) { $exten = $data[0]; $data[0] = ''; $wardindex2 = index($data[1],"At:"); if ($wardindex2 == 0) { $SendAt = $data[1]; $data[1] = ''; } } else { if ($wardindex2 == 0) { $SendAt = $data[0]; $data[0] = ''; $wardindex1 = index($data[2],"At:"); if ($wardindex1 == 0) { $exten = $data[1]; $data[1] = ''; } } } } $exten =~ s/\r//; $exten =~ s/\n//; $exten =~ s/To://; $SendAt =~ s/\r//; $SendAt =~ s/\n//; $SendAt =~ s/At://; $SendAt =~ s/Now//; my $MailBody = ''; foreach $lines (@data) { my $tmp = $lines; $tmp =~ s/[[:cntrl:]]//g; $MailBody .= $tmp; } open(OUT,"> /tmp/mail/mail.dat") or die "$!"; print OUT $MailBody; close(OUT); system("/usr/local/bin/open_jtalk -m /var/lib/open_jtalk/nitech_jp_atr503_m001.htsvoice -x /usr/local/dic -ow /tmp/mail.tmp.wav /tmp/mail/mail.dat"); system("/usr/local/ffmpeg_build/bin/ffmpeg -i /tmp/mail.tmp.wav -ac 1 -ar 8000 -y /tmp/mail.wav"); system("rm -f /tmp/mail.tmp.wav"); system("rm -f /tmp/mail/mail.dat"); system("rm -f /tmp/mail.dat"); if ($SendAt == 'now'){ open(OUT,">> /tmp/mail.log") or die "$!"; print OUT "mailAnalyse3 $exten /tmp/mail\n"; close(OUT); system("/usr/bin/mailAnalyse3 $exten /tmp/mail"); } else { }
# touch /usr/bin/mailAnalyse3 # chmod a+x /usr/bin/mailAnalyse3 # vi /usr/bin/mailAnalyse3
中身は以下の通りです。
#!/usr/bin/expect
log_file /tmp/expect.log
set timeout 20
set hostname localhost
set port 5038
# AMI のマネージャーのユーザー名とパスワードの設定
# 適時書き換えてください
set username mailreader
set password pass
set WaveFile ../../../../tmp/mail
set Exten SIP/1001
if {$argc > 0} {
set Exten [lindex $argv 0];
if {$argc > 1} {
set WaveFile [lindex $argv 1];
}
}
spawn telnet $hostname $port
expect "Asterisk Call Manager"
send "Action: Login\n"
send "username: $username\n"
send "secret: $password\n\n"
expect "Status"
send "Action: Originate\n"
send "Application: Playback\n"
send "Data: ../../../..$WaveFile\n"
# ここでは直接チャンネルを指定していますが、RingGroup 等番号で指定する場合は
# ローカルのコンテキストが default なら
# send "channel: Local/$Exten@default\n"
# というように、Local/内線番号@コンテキスト\nというように書き換えます
send "channel: $Exten\n"
# タイムアウトをミリ秒で指定します。
send "Timeout: 40000\n"
send "Async: true\n\n";
expect "Response:"
# 成功不成功の解析は複雑なため、下の行は使用せず、送信したらそのまま切断しています
send "Action: Logoff\n\n"
expect "Response:"
interact
/tmp/mail にファイルが作られたときに、mailAnalyse2 を呼び出します。
postfix が nobody 権限で実行しており、スクリプトがうまく動かなかったので
incron を使用しました。
# incrontab -e
最後に以下の1行を追加します
/tmp/mail/ IN_CREATE perl /usr/bin/mailAnalyse2.pl
変更を反映させます
# incrontab -d