ようこそゲストさん

CPA-LABテクニカル

2008/05/15(木) CakePHPコントローラーをメール受信をきっかけに起動する

はてブ情報 はてブに登録 はてブ数 cakephpspok

CakePHPシェル機能を使用せずに、空メールを実現する-さくらインターネット編

CakePHPにはシェル機能というものがあり、コマンドラインからCakePHPを利用できる。
この機能を利用して、CakePHPをメール受信をきっかけにリアルタイム処理することもできる。
例えばこちらの記事はそう。Writing Some Code-メール受信からのシェル機能実行
しかし、学習の量は少なければ少ないほど効率がいい。
あることを実現するのに、別の事柄を学ぶよりも、これまでの延長線上で可能な方がいい。
(ただし、WEBブラウザから直接叩かれることも想定されるのでご注意を 参考:CakePHPシェルの使い方)
というわけでここでは、CakePHPのシェル機能は使わずに、普通のControllerを、メール受信をきっかけに起動することをやってみたい。
1.2betaで動作確認をしていますが、1.1でも動作するはずです。
これはさくらインターネットで試していますが、".mailfilter"の部分さえ、ご自分の環境に合わせて設定できれば、後は同じです。さくらインターネットと同じ環境ではない人は、こちらの阿部辰也のブログ――人生はひまつぶし。-メール受信時に perl スクリプトを起動して自動処理させる方法が参考になるでしょう*1

.mailfilterの設定

まず、.mailfilterに以下のように記述する。
mailfilterについては、さくらインターネットでメール受信をリアルタイムに処理する、を参照。

ここでは、receivers_contoroller.php に記述された ReceiversContorollerを起動することを意図してみよう。
cc "| /usr/local/php-5.2.6/bin/php-cgi -q /home/user_name/hogehoge/app/webroot/index.php url=receivers/index"
サーバーにメールを残す必要がない場合は、cc を to に変更する。
注意点 パラメーターの渡し方
urlのパラメーターは、次のように'?'を使用して記述した場合には失敗する。
index.php?url=receivers/index
次のように、index.phpとurl=の間には、半角空白を挟んで指定する。
index.php url=receivers/index
なお、
/usr/local/php-5.2.6/bin/php-cgi
は起動するPHPの本体プログラムの指定である。これについては、さくらインターネットでメール受信をリアルタイムに処理する を参照のこと。
-q は、httpヘッダーを出力しないようにする設定である。

次に、receivers_contoroller.php に記述された ReceiversContorollerを起動してみよう。
<?php

class ReceiversController extends AppController{

    var $uses = null;

    function index(){

        $fp=fopen("php://stdin",'r');
        $content = null;
        while( !feof( $fp ) ){
           $content .= fgets( $fp , 4096 );
        }
        fclose( $fp );

        $this->render('void','void');
    }
}
?>
これで、$contentにメールの中身が入ることになる。あとは自由に料理しよう。
ここで、メールの中身とは、いわゆる本文のことではなく、メールヘッダーも含めたメール全体のことを示すことに留意すること。
Pear::MIMEでも解析できるが、簡単なものであれば、preg_matchで十分だろう。
また、いずれPearを使用しない方式でのメールデコードを紹介したい。

なお
        $this->render('void','void');
としたのは、メール起動の場合、画面出力は意味がないからである。
しかるべき場所に、layoutのvoid.ctp、viewのvoid.ctpを何も記述しない空ファイルとして配置しておこう。(CakePHP1.1の場合は、void.thtmlとなる。)

*1 : perlの話ですが、参考になるはずです。

Qdmailと組み合わせて空メール処理をCakePHPのコントローラーで処理する

recevers_controller.phpを以下のようにする。*2
<?php

class ReceiversController extends AppController{

  var $uses = null;
  var $components = array('Qdmail');

  function index(){

    $fp=fopen("php://stdin",'r');
    $content=null;
    while( !feof($fp) ){
      $content .= fgets($fp,4096);
    }
    fclose($fp);

    $header = preg_split( '/\r?\n\r?\n/is' , $content );

    if( 0 !== preg_match('/from:\s*<?([^<>@ ]+@[^<>@ ]+)>?[^<>@\r\n\s,]*\r?\n/is',$header[0],$matches)){

    //---------------------------
    // 本来はその他にも、携帯端末からの
     // メールであることを確かめる
     // ルーチンを置いたほうがよい。
     // いたずら、迷惑メールの発信元に
     // ならないようにするためである。
     // mail address varidationも必要だろう
     //--------------------------

    $to = str_replace( array("\r","\n") , '' , $matches[1] );
    $this->Qdmail->to($to);
    $this->Qdmail->from('from@example.com');
    $this->Qdmail->subject('空メールのテストです。');
    $this->Qdmail->cakeText( $to ,  'index' , 'default' );
    $this->Qdmail->send();
    }
    $this->render('void','void');
  }
}
?>
view,layoutの置き場は、QdmailをCakePHPで使うをご参照下さい。

以下のQRコードを読み取って、空メールを送ってみて下さい。
上記のコードでもって実現した*3返信メールをお送りします。
qr_caketest.png
(あえてメールアドレスは書いていません。)
貴方のメールアドレスは保存しないのでご安心ください。信用できない方はメールを送らないでください。

*2 : セキュリティは自己責任で

*3 : 実際にはもう少し手が入っている

1: 開発者 2009年12月22日(火) 午前10時56分

この方法だと、さくらでPHPのバージョンアップがあると、PHPの実行パスが変わってしまうため、その度に修正しなければならなくなります。


名前:  非公開コメント   

  • TB-URL  http://www.cpa-lab.com/tech/0139/tb/
  • CakePHPのシェルコマンドをさくらインターネットで使う CPA-LABテクニカル spok
    メール受信をきっかけにCakePHPコントローラーを起動する では、その名の通り、コントローラーをメール受信で起動させた。ここでは、CakePHP1.2で導入されたシェル機能(shell)を利用し、CakePHPのシェルをメール受信をきっかけに起動させてみ...