ようこそゲストさん

CPA-LABテクニカル

2008/05/13(火) さくらインターネットでリアルタイムメール処理

空メールや転送メールなどで、メールの受信をきっかけにPHPプログラムを実行させたいときがあるかと思います。
メールサーバーによって設定が異なるので、ここでは、さくらインターネット(sakura internet)での設定を覚書。

手順:

まず、受信用のメールアドレスを管理画面から作成する。
ここでは、
catch@example.com
とする。
管理画面から、メール転送設定を行う。すぐに消去するので、転送するアドレスは何でもよい。
いったん設定したら、すぐに転送設定を消去する。

FTPでサーバーに接続する。
/home/user_name/MailBox/catch/

.mailfilter
をローカルにダウンロードする。このファイルは空のはずです。
もし、このファイルが存在しなかったら、作ってしまいましょう。

.mailfilterの中身を以下のようにする。
cc "| /home/user_name/hogehoge/example.php"
これをサーバーの元の場所にアップロードする。念のためパーミッション(属性)を600であることを確認する。600でなければ、600に変更しておく。
これで、メールを受信したら、/home/user_name/hogehoge/example.phpのPHPプログラムが実行されることになる。
CCの後、|の後には半角スペースが入るので注意。

なお、現在の指定の仕方は、サーバーにずっと残す設定である。PHPプログラムにさえ中身を渡せば消えてしまっていいのであれば、CC を to に変更する。

example.phpには、次のようにPHPプログラムを記述する。
#!/usr/local/php-5.2.6/bin/php-cgi

<?php

(PHP SCRIPT)

?>

かならず、#!/usr/local/php-5.2.6/bin/php-cgi は第1行目にいれること。
これで動作するPHP本体プログラムを指定する。

パーミッションは、744に変更する。これを忘れると動かない。

注意点1 PHP本体プログラムは3種類ある。

PHP本体プログラムには、様々な種類があり、主なものは以下の3種類。
モジュール版mod_phpサーバーのモジュールとして動作
cgi版cgiとして動作
cli版シェル、コマンドライン用
今回の、受信メールリアルタイム処理に関しては、cgi版かcli版のどちらかの選択肢が考えられる。
cgi版の場合は、次の通り。
#!/usr/local/php-5.2.6/bin/php-cgi
cli版の場合は次の通り。
#!/usr/local/php-5.2.6/bin/php
ただし、時間がたてばバージョンが変わってくる可能性があるので、php-5.2.6の部分については、ご自分の環境で確かめて下さい。
たぶん、PHP4も入っているはずなので、PHP4で動かしたければ、そのパスに変えればいいはずです。

CGI版とCLI版の違い

こちらが詳しい。
とみぞーノート-PHP CLI/CGI SAPI

注意点2 パーミッション

ファイルのパーミッションは、次のようにしておくこと。
ファイルパーミッション(属性)
.mailfilter600
PHPスクリプト744 (他の組み合わせも考えられる)

メールの中身を取得する

メールの中身は、.mailfilterに記述したスクリプトでもって、標準入力にパイプされます。
したがって、PHPプログラムの方では、標準入力をつかまえれば、メールの内容を知ることができます。

例)
$content = null;
$fp=fopen("php://stdin",'r') or die('File Open Error');

 while( !feof($fp) ){
    $content .= fgets( $fp ,1024);
 }
メールのヘッダーも含めた本文であることに注意しましょう。
単純にfromを抜き出す程度でよいのであれば、strposやpreg_matchなどで十分に対応できるでしょう。
しかし、もっと複雑な処理は。。。。またのお楽しみ。

デバッグの方法

最終段階はともかく、初期の段階のデバッグ時に、メールを何度も送りつけるのも面倒です。
そこで、まるでメールが送りつけられたかのように偽装する方法でデバッグしてみましょう。

telnetでサーバーにログイン。telnetの仕方は、さくらインターネットオンラインマニュアルTELNETについてを参照。

telnetクライアントはたくさんありますが、私が使っているのは次の2つです*1
UTF-8 TeraTerm Pro
Poderosa(ポデローサ)

コマンドラインで次のようにファイルを指定する。(シェルスクリプトとして指定したことになる)
/home/user_name/hogehoge/example.php
とすれば、動くでしょう。

ただしこのままでは、標準入力は空です。
テストのためのメール内容を作り、test.txtに入れておきましょう
そして次のようにしてみましょう。
cat /home/user_name/hogehoge/test.txt | /home/user_name/hogehoge/example.php
これで、/home/user_name/hogehoge/test.txtの内容を標準出力し、その内容を標準入力として、example.phpが受け取る、というパイプ(パイプライン)の処理となります。

'|'の記号は、左手のコマンドの標準出力を右手のコマンドの標準入力にそのまま流す、という処理を表す記号です。左右に半角空白が必要なので注意しましょう。
(似たような記号は、.mailfilterの中にもでてきましたよね)

cat は、指定されたファイルの中身を標準出力に出力するコマンドです。
これで上記の1行が何をしているかわかりましたね。

プログラム例)
#!/usr/local/php-5.2.6/bin/php

<?php
$content = null;
$fp=fopen("php://stdin",'r') or die('File Open Error');

 while( !feof($fp) ){
    $content .= fgets( $fp ,1024);
 }
?>
これで標準入力から受け取った内容をすべて $content に代入することができました。

*1 : TeraTerm Proの方が個人的には好きですが、どちらも使い勝手は似ています。

注意点3 PHP本体のオプション、php.ini

cgi,cli版は、サーバーモジュール版のPHPと異なる初期設定である場合があります。
つまり、普段使っている設定と異なっている可能性が大いにあります。

代表例)*2
  • マルチバイト関数 mb_* が含まれていない可能性
  • php.ini のパスが異なる可能性
これらの設定については、telnetログインして次のコマンドを実行します。
php -i
または
実行したいPHP本体のパス -i
これで、phpinfo(); を実行した場合と内容的には同じデータを得られます。
よく分析しましょう。

*2 : これ以外にもある可能性があります

1: 検証調査 2011年08月10日(水) 午前10時01分

2011/8/10現在も、「2008/05/13(火)さくらインターネットでリアルタイムメール処理」の手法は、実現するのでしょうか?
手順に従い実施しても、プログラム起動しません。
「#! /usr/local/php-5.2.17/bin/php-cgi」
または、
「#! /usr/local/php/5.2.17/bin/php-cgi」
で試しても起動しません。

2: 実施報告(ymf) 2012年08月07日(火) 午後1時28分

さくらインターネットで、空メール受信処理を実現するに当たり、本ブログの記事が一番参考になりましたのでご報告します。
さくらインターネットでの、本件の難しさは、Webから実行する場合に読み込むphp.iniとメール受信時の.mailfilterから起動されたときに読み込むphp.iniが異なる事が原因でした。web用のphp.iniは、たいていの場合、カスタマイズして、独自にインストールしたPEARへのパスが入っていたり、デバッグ用にエラー表示を設定したりしていると思いますが、メール受信時のphp.iniは、サーバー共通のものしか読み込めず、個別にカスタマイズできないようです。よって、例えばPEARの種類によっては、動作したり(デフォルトでインストールされているため)、しなかったり(独自インストールのため、共通のphp.iniでパスが通っていないため)する訳です。
作業完了までのステップは、以下となりました。
1)webからアクセスして、文法エラー等をつぶし、動作を確認
2)本記事の方法により、コマンドラインからメールファイルを流し込み、動作を確認
3)メール送信により、.mailfilterからスクリプトを起動し、ファイルにログを書き出しながら動作を確認(コマンドラインとメール起動では、環境変数で読めるものが異なる様で動作が微妙に異なりました。)
なお、今後の工夫としては、スクリプトの最初にini_set()を活用して、なるべくWeb用のphp.iniと同じ環境設定をしておくことが近道かと。
以上、ご参考になればと思いご報告します。


名前:  非公開コメント   

  • TB-URL  http://www.cpa-lab.com/tech/0143/tb/
  • CakePHPコントローラーをメール受信をきっかけに起動する CPA-LABテクニカル spok
    ■CakePHPシェル機能を使用せずに、空メールを実現するCakePHPにはシェル機能というものがあり、コマンドラインからCakePHPを利用できる。この機能を利用して、CakePHPをメール受信をきっかけにリアルタイム処理することもできる。例えばこちらの...
  • 10行で空メール処理を実現する CPA-LABテクニカル spok
    あるメールを受け取って、自動的に差出人に対してメールを返す、という動作の代表例として空メールがあるかと思います。Qdmail,QdmailReceiverを利用すれば、たった10行で空メールを実現することができます。#!/usr/local/php-5.2...
  • CakePHPのシェルコマンドをさくらインターネットで使う CPA-LABテクニカル spok
    メール受信をきっかけにCakePHPコントローラーを起動する では、その名の通り、コントローラーをメール受信で起動させた。ここでは、CakePHP1.2で導入されたシェル機能(shell)を利用し、CakePHPのシェルをメール受信をきっかけに起動させてみ...
  • デコメテンプレート変換はじめてガイド CPA-LABテクニカル spok
    デコメ(デコメール)のテンプレートはキャリア毎に仕様が異なる。今回のqdmailバージョンアップでは、デコメテンプレート変換をできるようにした。しかもテンプレート変換だけでなく、通常のメールや受け取ったデコメデータから、テンプレートを作成してくれるスグレモ...