FreePBX に届いたメールを音声読み上げさせる その2 ~メールからテキストファイルを作成して電話でをかけて読むまで~

謝意
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:$extenn";
print DAT "At:$SendAtn";
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 = <IN&gt;;
close(IN);

if (@data > 2){
	my $wardindex1 = index($data[0],&quot;To:&quot;);
	my $wardindex2 = index($data[0],&quot;At:&quot;);
	if ($wardindex1 == 0) {
		$exten = $data[0];
		$data[0] = '';
		$wardindex2 = index($data[1],&quot;At:&quot;);
		if ($wardindex2 == 0) {
			$SendAt = $data[1];
			$data[1] = '';
		}
	} else {
		if ($wardindex2 == 0) {
	                $SendAt = $data[0];
        	        $data[0] = '';
                	$wardindex1 = index($data[2],&quot;At:&quot;);
                	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,&quot;> /tmp/mail/mail.dat&quot;) or die &quot;$!&quot;;
print OUT $MailBody;
close(OUT);


system(&quot;/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&quot;);
system(&quot;/usr/local/ffmpeg_build/bin/ffmpeg -i /tmp/mail.tmp.wav -ac 1 -ar 8000 -y /tmp/mail.wav&quot;);
system(&quot;rm -f /tmp/mail.tmp.wav&quot;);
system(&quot;rm -f /tmp/mail/mail.dat&quot;);
system(&quot;rm -f /tmp/mail.dat&quot;);
if ($SendAt == 'now'){
	open(OUT,&quot;>> /tmp/mail.log&quot;) or die &quot;$!&quot;;
	print OUT &quot;mailAnalyse3 $exten /tmp/mailn&quot;;
	close(OUT);
	system(&quot;/usr/bin/mailAnalyse3 $exten /tmp/mail&quot;);
} 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: Loginn"
send "username: $usernamen"
send "secret: $passwordnn"
expect "Status"
send "Action: Originaten"
send "Application: Playbackn"
send "Data: ../../../..$WaveFilen"
# ここでは直接チャンネルを指定していますが、RingGroup 等番号で指定する場合は
# ローカルのコンテキストが default なら
# send "channel: Local/$Exten@defaultn"
# というように、Local/内線番号@コンテキストnというように書き換えます
send "channel: $Extenn"
# タイムアウトをミリ秒で指定します。
send "Timeout: 40000n"
send "Async: truenn";
expect "Response:"
# 成功不成功の解析は複雑なため、下の行は使用せず、送信したらそのまま切断しています
send "Action: Logoffnn"
expect "Response:"
interact

/tmp/mail にファイルが作られたときに、mailAnalyse2 を呼び出します。
postfix が nobody 権限で実行しており、スクリプトがうまく動かなかったので
incron を使用しました。

# incrontab -e 

最後に以下の1行を追加します

/tmp/mail/ IN_CREATE perl /usr/bin/mailAnalyse2.pl

変更を反映させます

# incrontab -d

コメントを残す

メールアドレスが公開されることはありません。