ようこそゲストさん

CPA-LABテクニカル

2008/05/21(水) CakePHPのシェルコマンドをさくらインターネットで使う

メール受信をきっかけにCakePHPコントローラーを起動する では、その名の通り、コントローラーをメール受信で起動させた。
ここでは、CakePHP1.2で導入されたシェル機能(shell)を利用し、CakePHPのシェルをメール受信をきっかけに起動させてみる。

順番としては次のようになる。
  1. .mailfilterの設定 (メールデータをOSシェルスクリプトに渡す設定)
  2. OSのシェルスクリプトの記述・設定 (メールデータをCakePHPシェルスクリプトに渡す設定)
  3. CakePHPのシェル機能によるshellsの作成
実際の制作においては、3→2→1 の順番でやることの方が多いとは思うが、ここでは、データの流れに沿って、1→2→3 の順番で説明する。
なお、さくらインターネットにおいては、受信メールを他のスクリプトに渡すには、.mailfilterを利用するが、それ以外の環境の場合は、これを応用して試して欲しい。
ここで、OSのシェルスクリプトと、CakePHPのシェルスクリプトの違いを理解しよう
  • OSのシェルスクリプト OSの種類によって記述の方法が違うので留意すること。ここでは、さくらインターネットのFreeBSDを例にしている。
  • CakePHPのシェルスクリプト 1.2であれば、共通。通常のWEB起動で起動されるcakePHP本体とは別物なので留意すること。

データの流れ

.mailfilter (メールサーバーの種類によって異なる。ファイル名は固定だが、中身はユーザー(私)が設定する。)
   ↓
catchmail.sh (OSのシェルスクリプト。ユーザー(私)が作る。)
   ↓
cake (OSのシェルスクリプト。CakePHPのデフォルトでは、/home/user_name/hogehoge/cake/console/ にあるはず 1.2beta。)
   ↓
cake.php (CakePHPのシェル本体。/home/user_name/hogehoge/cake/console/ )
   ↓
catchmail.php (CakePHPのシェルスクリプト、ユーザー(私)が作る)

なお、catchmail.shを作成せずに起動させることも可能である。
その場合は、.mailfilter に、cake(OSシェルスクリプト)を起動するスクリプトを直接記述することになる。(要は、.mailfilterにcatchmail.shの内容を書くわけだ。)

さらにいえば、
catchmail.sh、cakeの両方を記述せず、ショートカットすることも可能である。
その場合は .mailfilterに直接 cake.php をパラメータ付きで起動するように記述すればよい。

ここでは、拡張が容易なように、catchmail.shというクッションを置く方法で説明する。

.mailfilterの設定

基本的なことは、さくらインターネットでリアルタイムメール処理を参照のこと。
cc "| /home/user_name/hogehoge/app/vendors/shells/catchmail.sh"
ではなぜかダメで、下記のようにする。
ただし、さくらインターネット以外の環境では、上記で動作する場合もあるだろう。
cc "| sh /home/user_name/hogehoge/app/vendors/shells/catchmail.sh"
"|" の後に 半角空白sh半角空白があるのがミソである。
sh とは OSのシェルスクリプトを起動させるコマンドである。
さくらインターネットは、FreeBSDなのでshだが、一般的なlinux環境では、bash の場合もあろう。
catchmail.shは、この後に設定するOSシェルスクリプトのファイル名であり、任意の名前でよい。

OSシェルスクリプトの設定

catchmail.sh の設定。
/home/user_name/hogehoge/app/vendors/shells/
に、catchmail.shというファイルを作成し、以下のようにする。
#!/bin/sh
/home/user_name/hogehoge/cake/console/cake -app /home/user_name/hogehoge/app catchmail run 
一般的なlinux環境であれば、最初の1行は、#!/bin/bash となろう。
最後の「catchmail run」について説明する。
catchmail は、CakePHPシェルの名前であり、ユーザー(私)が名付ける。
run は、CakePHPシェルの中で使用する function 名 であり、ユーザー(私)が名付ける。
どちらも任意に設定できる。

 -appのすぐ後につづくパスは、appまでの絶対パスを記述する。

なお、同じようにみえるが、次のコードはうまく動かない。
home/user_name/hogehoge/cake/console/cake catchmail run -app /home/user_name/hogehoge/app
パラメータの順番が違うということだけども、要注意。

cakeの設定

cake はOSのシェルスクリプトで、CakePHPのデフォルトでは、/home/user_name/hogehoge/cake/console/ にあるはず。拡張子が何もついていないやつである。

さくらインターネットでCakePHPコンソールを参考に、cakeを書き換えてみて下さい。
環境によっては、書き換えず、そのままいける場合もあるかも知れない。

catchmail.php

catchmail.phpは、
/home/user_name/hogehoge/app/vendors/shells/
の中に設置するCakePHPのシェルスクリプトである。
考え方は、コントローラー(Controller)と全く同じである。
<?php
    vendor('qdmail_receiver');
    vendor('qdmail');

 class CatchmailShell extends Shell {

    function run(){

        qd_receive_mail( 'stdin' );

        $address = qd_receive_mail( 'header' ,array('from','mail'));
        preg_match('/[^@\s]+@[^@\s]+\.[^@\s]+/',$address) or die();
        $name = qd_receive_mail( 'header' ,array('from','name'));
        $name = empty($name) ? $address : $name ;
        qd_send_mail('text', $address , null , "空メール","このメールに見覚えがない場合は破棄してください。\r\n-------\r\nこんにちは".$name."さん",'from@example.com');
    }
 }
?>

ここでは、10行で空メール処理を実現するを同じコードを置いた。
この代わりに、ユーザーが自由に処理コードをかけばよい。

vendor() は、ただファイルをインクルードするだけのもの。
以下のディレクトリに、qdmail.php と qdmail_receiver.php をコピーしておきましょう。

/home/user_name/hogehoge/app/vendors/

メールデータを取得する

メールのデータが欲しければ、STDINから読み込む。*1
メールの中身を取得するを参考して欲しいけれども、注意点があるので、要は下記のとおり。

CakePHPのシェルでのSTDINの注意点。
  $stdin=$this->Dispatch->stdin;
  while( !feof($stdin) ){
    $mail .= fgets($stdin,4096);
  }
これは、Writing Some Code-メール受信からのシェル機能実行 からの引用です。有用な情報をありがとうございました。私もはまるところでした。

なお、CakePHPでのシェルでの話であり、通常のコントローラーでは、このようなことはない。

コントローラーを起動させるか、シェルを起動させるか

このエントリーでは、CakePHPのシェルをメール受信をきっかけに起動させたが、実現したことは、メール受信をきっかけにCakePHPコントローラーを起動すると同じである。

私がみる限りでは、今回のような使い方の場合、CakePHPシェルもコントローラーも機能的には変わるところはない。

最大の違いは。。。。
  • セキュリティ....shellで作れば、webブラウザから叩かれる心配はない。
  • コマンドライン...shellで作ったほうが、楽かな
  • 他のプログラムからの呼びだし....手間は同じかな
  • ハイブリッド...ブラウザからも呼びだしOK,サーバー内部からも呼びだしOKのコードならコントローラーを使うべし

*1 : この例の場合は、その機能はqdmail_receiverの中にあるのでそれを利用している。


名前:  非公開コメント   

  • TB-URL  http://www.cpa-lab.com/tech/0138/tb/