[PHP] Twilioで留守電システムを構築

最近Twilioにハマってまして、その第1弾（続くとは言ってませんので続きを期待しないで下さい）ということで留守電サービスを作っちゃいました。
なので晒す。

##先にソースから
* pnc.php：国内の電話番号と国際電話番号を変換するもの。日本国内の電話番号のみに対応。
* mailSender.php：PHPMailを使用してSMTP越しにメールを送ります。詳細は後述。
* hello.php：本体。

```php:pnc.php
<?php
    
    class Phone_Number_Converter {
        
        public function toInternational($number) {
            
            if (preg_match('/^[0-9]+$/', $number) && (strlen($number) == 10 || strlen($number) == 11)) {
                return preg_replace( '/^0/', '+81', $number);
                
            } else if (preg_match('/^\+81[0-9]+$/', $number) && (strlen($number) == 12 || strlen($number) == 13)) {
                return $number;
                
            } else {
                return false;
            }
        }
        
        public function toDomestic($number) {
            
            if (preg_match('/^\+81[0-9]+$/', $number) && (strlen($number) == 12 || strlen($number) == 13)) {
                return preg_replace( '/^\+81/', '0', $number);
                
            } else if (preg_match('/^[0-9]+$/', $number) && (strlen($number) == 10 || strlen($number) == 11)) {
                return $number;
                
            } else {
                return false;
            }
        }
    }
```

```php:mailSender.php
<?php
    // 以下はGmail越しに接続したもの
    require_once dirname(__FILE__).'/PHPMailer/class.phpmailer.php';
    require_once dirname(__FILE__).'/PHPMailer/class.smtp.php';
    
    function mailSender($subject='', $body='') {
        
        mb_language("japanese");
        mb_internal_encoding("UTF-8");
        
        if ($subject === '' || $body === '') {return false;}
        
        $mail = new PHPMailer();
        $mail->IsSMTP();
        $mail->Host     = 'ssl://smtp.gmail.com:465';
        $mail->SMTPAuth = true;
        $mail->Username = '（アカウント@gmail.com）';
        $mail->Password = '（パスワード）';
        $mail->From     = '（アカウント@gmail.com）';
        $mail->FromName = '（アプリ名）';
        $mail->Subject  = mb_encode_mimeheader(mb_convert_encoding($subject, 'JIS','UTF-8'));
        $mail->Body     = mb_convert_encoding($body, 'JIS', 'UTF-8');
        $mail->AddAddress('（宛先）');
        
        return $mail;
    }
```

```php:hello.php
<?php
    
    require_once dirname(__FILE__).'/php/Twilio.php';
    require_once dirname(__FILE__).'/php/pnc.php';
    require_once dirname(__FILE__).'/php/mailSender.php';
    
    
    $response = new Services_Twilio_Twiml();
    $pnc = new Phone_Number_Converter();
    
    $datetime = date('Y-m-d H:i:s');
    $from = $pnc->toDomestic($_POST['From']);
    $black_list = array('05025252525');
    
    
    if ($from === '（認証済み電話番号）') {
        $response->say('認証済み電話番号です。', array('language' => 'ja-jp', 'voice' => 'alice'));
        
    } else if ($from === '+266696687') {
        $response->say('非通知着信はお断りしております。大変申し訳ありませんが発信番号を通知しておかけ直し下さい。', array('language' => 'ja-jp', 'voice' => 'alice'));
        
    } else if (in_array($from, $black_list)) {
        $response->say('迷惑電話はお断りしております。', array('language' => 'ja-jp', 'voice' => 'alice'));
        
    } else {
        $response->say('ただ今電話に出ることができません。ビープおんのあとにお名前とご用件をお願いいたします。', array('language' => 'ja-jp', 'voice' => 'alice'));
        $response->record(array('maxLength' => '120'));
    }
    
    
    if (isset($_POST['RecordingSid'])) {
        
        $rec_url = $_POST['RecordingUrl'].'.mp3';
        $subject = '【Twilio】留守電';
        $body = "{$datetime}に{$from}からの着信において新規留守電が登録されました。\n\n{$rec_url}";
        
        $mailsender = mailSender($subject, $body);
        $mailsender->Send();
        
    } else {
        
        $subject = '【Twilio】着信あり';
        $body = "{$datetime}に{$from}から着信がありました。";
        
        $mailsender = mailSender($subject, $body);
        $mailsender->Send();
    }
    
    
    header("Content-Type: text/xml; charset=UTF-8");
    echo $response;
```

##それぞれの説明
###pnc.php
正直なところ、相互変換だけでもいいかなとは思ったんですが、コード中でどっちに変換してるかわかりやすくさせるために関数2つにしました。
変換方向が正しくない場合は入力された番号をそのまま返します。
電話番号じゃないものが入力されたら、falseを返します。

###mailSender.php

[PHPMailer](https://github.com/Synchro/PHPMailer)を使用していますので、sendmailでなくてもSMTP設定がわかっていればpostfixだろうがgmailだろうが何でも使えるはずです。
日本語をもっと自然に使いたければ[JPHPMailer](http://techblog.ecstudio.jp/files/jphpmailer.zip)なるラッパーも存在するようです。
メールサーバー立てるの面倒くさいですし。

returnに関してはtrueかfalseではなくハンドラかfalseを返しますので気をつけて下さい。
ハンドラを返したほうが後々、`send()`だけでなく`ErrorInfo`も取り出せますのでそのほうが便利かなぁと・・・

###hello.php
TwilioがPOSTしたらTwiMLを返します。
どこかのサーバーにおいて下さい。
サーバーとかねぇよとなるとPaaSに置くことになるのかな？

black_listに関しては日本の電話番号を追加していって下さい。
必要かどうかわからなかったんですけど、つけちゃいました。

流れとしては、電話にでれなかったら着信メールを送って、さらに留守電があったらそのことを連絡するメールも送られてきます。
割とわかりやすく作ったつもりですが、気に入らなかったら改変して下さい。

##ライセンス？
あってないようなものですが、いつもどおり**MIT License**ですかね。