ようこそゲストさん

Qdmail - PHP::Mail Library , Quick and Detailed for Multibyte

メッセージ欄

2008年8月の日記

SMTP送信について

SMTPサーバー送信は、実装としては2種類あるかと思います。ここではその解説です。

基礎知識

メールは一般的には以下のような配送ルートで送られます。

一般論
クライアント(Qdmail) → 配送元SMTPサーバー(A) → 配送先AMTPサーバー(B) → 相手のPC
最後の(B)→相手のPCはPOPプロトコルであり、その他はすべてSMTPプロトコルで配送されます。
ここでQdmailは、クライアントとなります。
PHPのmail関数を利用した場合は、以下のようなルートです。
クライアント(Qdmail) → mail関数 → sendmail・配送元SMTPサーバー(A) → 配送先AMTPサーバー(B) → 相手のPC
sendmailは、PostFixであったりQmailであることもあります。QmailとQdmailは違いますので、ご留意下さい。
sendmailというのは、ひとつのプログラムで、送信サーバー、中継サーバー、受信サーバーの1台3役のサーバーなので、よく理解がごっちゃになりやすいので気をつけて下さい。

mail関数とSMTP送信の違い

mail関数の方がSMTP送信の段取りをやってくれるため、PHPプログラムは簡単になります。一方で、mail関数そのものが、ちょっと改行コードの取り扱い等に難点があり、文字化けの原因になったりします。

SMTP送信は文字化けについては、mail関数より信頼性が高いものの、SMTPプロトコルでの送信をPHPプログラムが面倒見無ければならないので、面倒です。Qdsmtpは、その面倒さを引き受けて、ユーザーの負担を軽くするものです。

SMTP送信の種類

SMTP送信の中にも大きく2種類があります。

その1(中継サーバーに配送を委託する方法)---Qdsmtpはこの実装。
クライアント(Qdmail) → 配送元SMTPサーバー(A) → 配送先AMTPサーバー(B) → 相手のPC
                       (認証が必要)       (認証不要)

その2(直接相手先のSMTPサーバーに配送してしまう方法)
クライアント(Qdmail) → 配送先AMTPサーバー(B) → 相手のPC
             (認証不要)
一般的にSMTP送信と言った時にどちらを指すのはかは、私の経験不足でわかりません。どなたか、知っていたら教えて下さい。

認証について

過去のインターネットの世界では、SMTPは認証不要でした。しかし、それがスパムメールに悪用されるようになり、POP Before SMTPという疑似認証方式が多くで採用され、現在では、SMTP AUTHというIDとパスワードでの認証が必要になっています。
ただし、認証が必要なのは、他のSMTPサーバーに送信する中継サーバーだけです。
なぜなら、配信先のSMTPサーバー(B)は、どこのサーバーから接続されるのがわからないから、それを認証必須にしてしまうと、特定の相手先からしかメールを受け取れないことになっています。
したがって、多くのSMTPサーバーは、以下のような設定になっています。
自分が管理するメールボックス宛であれば、認証必要なく接続を許可し、他のサーバーへの中継要求は認証があれば許可するが、認証がなければ拒否する。
だから、配信元サーバーは通常認証が必要になります。そうでないとスパムの踏み台にされてしまうからです。もし、現状で認証の必要のない配信元サーバーを公開しているのであれば、即刻サーバー停止すべきものです。

2つの方法の違い

その1(中継サーバーに配送を委託する方法)
認証ありで第三者中継を許すサーバーにで接続し、各到達地点のSMTPサーバーに中継してもらう。

この方法の利点
  • 到達地点のSMTPサーバーになんらかの理由で接続できなかった場合でも、最初のSMTPサーバーが、メールを留保し、後で、送り直しをしてくれるため、到達確立が安心できるレベルにある
  • いつも同じSMTPサーバーに接続するだけでよいので、面倒がない
  • 安定した配送元SMTPサーバーであれば、しっかり配送してくれる
その代わりに、そのSMTPサーバーに自分がアカウントを持っていなければなりません。例えば、私はレンタルサーバーのSMTPサーバーやso-netのアカウントも持っていますので、たまにso-netのSMTPサーバーに認証ありで、中継してもらっています。

その2(直接、配送先のSMTPサーバーに接続する方法)
送り先のメールアドレスに合わせて、その都度異なる(当該メールを管理する)SMTPサーバーに認証なしで接続して送信することになります。

例えば、ドコモユーザー(***@docomo.ne.jp)に送信する場合には、mfsmax.docomo.ne.jpというSMTPサーバーをdocomo.ne.jpという情報からインターネット上で逆引きして探しだし、そこへ接続します。
gmailユーザー(***@gmail.com)であれば、gmail.comの受信サーバーたるASPMX.L.GOOGLE.COMを探しだし、そこへ接続します。

認証なしサーバーは第三者中継は行わないものの、そのSMTPサーバーが管理するドメイン(サブドメイン)のメールボックス宛であれば、認証なしで受け入れます。

この方法の利点
  • 直接接続なので認証がいらない
という点です。

一方で、欠点もあります。
  • 送り先のメールアドレスから、IPアドレスなり、SMTPサーバーなりを逆引きしなければならず、また、接続エラーの場合の処理を自前で実装しなければならない
  • エラー処理は、PHPだけでは完結が難しく、必ず、サーバーの設定等も必要になることが多いので、可搬性のよくない(万人向けではない)ソフトになってしまう
  • そのPHPプログラムが動作するIPアドレスによっては、配送元から接続拒否をされる場合がある

配送元が接続拒否をする場合とは?

その2(配送先サーバーに直接送信)の場合によく問題となるのが、例えばdocomoユーザーへのメールが届かない、という問題です。参考<Radish3(Docomo対策編)>-パソコンおやじ
ドコモでは、スパム対策のために、「怪しいとドコモが判断した送信元サーバー」からは、接続を受け付けないか、極端に待たせるか、優先順位を下げるなどの設定にしているようです。
ここではドコモを取り上げましたが、このように送信元サーバーの制限をするプロバイダは他にもあるそうです(詳しくは調べていません。)
何を持って「怪しい」と判断するかは、そのサーバーの管理者のポリシーなのでなんともいえませんが、いわゆる「プロバイダ事業者」が管理するサーバーは特段の問題はないものの、ダイナミックDNSなどでIPアドレスが頻繁に変更となるサーバーや、これまでに大量送信が確認されたサーバー、もしくは見慣れない?サーバーなどは問題となることが多いようです。
これは、私たちが、PHPを使って直接配信先に接続しようとした時、配信先のサーバ-に、審査されることを意味します。
例えば、会社のテストサーバーから繋ぐと、「怪しい」と判断されるかも知れませんし、それを運用環境にもっていってIPアドレス等が変更になれば、「怪しくない」と判断されるかも知れません。その逆もあるかも知れません。このように、開発環境と運用環境で、接続確立がかわるため、開発は面倒です。

この問題は、配信先のサーバーの問題であるため、その1(中継サーバーに中継してもらう)方法でも、起こりえます。しかし、通常、その1の方法の場合は、かなり信頼性のあるプロバイダやレンタルサーバー事業者のSMTPサーバーを利用することが多いので、問題が表面化することは少ないといえます。
逆に、その1の方法でも、自社で立てたテストサーバーのようなものであれば、同様の問題がでてくる可能性はあります(あくまでも可能性)。

Qdsmtpの対処と今後

現状

現状では、その1の方法だけなので、いろんな所にメールを送りたければ、サーバー認証またはPOP Before SMTPにて、信頼性のあるSMTPサーバーをご利用ください。
ご自分でSMTPサーバーを構築する場合には、「配信先サーバーによる審査」という問題にご留意下さい。

今後

いずれは、Qdsmtpも、その2 の方法もサポートしたいとは思いますが。。。。時間があれば。
その時には、その2の方法を接続を試みて、接続負荷だった場合には、その1の中継サーバーにお願いする、というような方法になるでしょう。

2008/08/28(木) 2008-08-28

Qdmaiのダウンロードページはこちら
  • 2008-08-28
    • 1.0.8b
メール重要度の指定ができるようにした。priorityメソッドの追加。
version()メソッドの追加

重要度を設定する

Qdmailでは、メールの重要度を設定することができます(3段階)。Qdmail 1.0.8b以降の機能です。

重要度設定方法

パラメータの意味は以下のとおりです。
high重要
normal普通
low低い

qd_send_mail() 方式の場合(テキストメールの例)

$option = array(
    'type'=>'text',
    'option'=>array('priority'=>'high'),
);

qd_send_mail($option , $to , $subject ,$body );

OOP , easy~メソッド 方式の場合

$mailにはQdmailのインスタンス(オブジェクト)が入っているものとします。
$mail -> priority('high');
重要度をキャンセルするには
$mail -> priority('');
現在の重要度の設定を取得するには
$return_value = $mail -> priority( null );

予備知識

メールの重要度は、各メーラーなどが独自に実装している面があり、ひとつのヘッダーを設定すればそれでOKとはいきません。Qdmailでは、4つのヘッダーを設定しています。たぶんこれでほとんどのメーラーは大丈夫だと思います。
設定しているヘッダー
X-Priority135
Priorityurgentnormalnon-urgent
X-MsMail-PriotiryHighNormalLow
ImportanceHighNormalLow
priorityメソッドは addHeader()メソッドを利用して、これら4つのヘッダーを設定しているだけです。

参考URL

メールの重要度を設定する-Shin x blog

デコメテンプレート変換サービス

下記のQRコードを読み取って、携帯電話からメールを送ってみて下さい。
その際には、ご自分のPCメールアドレスにCCしてください(しなくてもいいけど)。

すると。。。。

携帯アドレスとCcアドレスに、その送ったデコメが、ドコモ(Docomo)、au、ソフトバンク(Softbank)の3つのキャリアのデコメテンプレートに変換され、その変換されたファイルが添付されたメールが送られてくるはずです。

お試しあれ。
decotest987.jpg
うまく読み取れない方は、decotest987  あっとまーく hal456 ドット netまでデコメを送ってみて下さい。


ちなみに、デコメでなくても、普通のメールを送っても、デコメテンプレートになって返ってきます。

続きを読む

デコメテンプレート変換プログラムサンプル

デコメテンプレート変換はじめてガイド  デコメテンプレート変換サービス
にて、Qdmail + QdReceiverを利用した、デコメテンプレ3種盛り自動作成サービスを紹介しています。
ここでは、そのプログラムをご紹介しましょう。

レンタルサーバー:さくらインターネット スタンダード
なお、受信したメールでリアルタイムでPHPプログラムを動かすには、さくらインターネットでリアルタイムメール処理をご参照下さい。
#!/usr/local/php-5.2.6/bin/php-cgi

<?php

include('inc/qdmail.php');
include('inc/qdmail_receiver.php');

//
//標準入力からメール内容の取り込み
//
$content = '';
$fp=fopen("php://stdin",'r') or die('File Open Error');
 while( !feof($fp) ){
    $content .= fgets( $fp );
 }
//
//メールのデコード(Qdreceiver)
//
$DECODE = QdmailReceiver::start('direct',$content);
$from = $DECODE -> header(array('from','mail'));
$subject_summary = mb_substr(
    $DECODE -> header( array('subject','name') ) , 0 , 10
);

if(empty($subject_summary)){
    $subject_summary = 'Qdmail';
}else{
    $subject_summary .= 'tpl';
}

$cc = $DECODE -> header(array('cc','mail'));

//
//デコメテンプレートへの変換(3キャリア)
//
$kinds = array('TPL_DC','TPL_AU','TPL_SB');
$carrier = array(
    'TPL_DC'=>'Docomo',
    'TPL_AU'=>'au',
    'TPL_SB'=>'SoftBankMobile'
);
$mime = array(
    'TPL_DC'=>'application/x-decomail-template',
    'TPL_AU'=>'application/x-kddi-htmlmail',
    'TPL_SB'=>'application/x-htmlmail-template'
);
$kakuchou = array('TPL_DC'=>'dmt','TPL_AU'=>'khm','TPL_SB'=>'hmt');

$ct = 0;
$mail = Qdmail::getInstance();

foreach($kinds as $kind){
    $attach[$ct]['DIRECT'] = $mail -> makeDecoTemplate($kind,$content);
    $attach[$ct]['PATH'] = $subject_summary.'_'.$carrier[$kind].'.'.$kakuchou[$kind];
    $attach[$ct]['MIME_TYPE'] = $mime[$kind];
    $ct++;
}
//
//結果の送信
//
$add_header['From']='*****@*****.net';
$add_header['Reply-To']='****@*****.jp';

$to = array();
if(!empty($from)){
    $to[]=array($from);
}
if(!empty($cc)){
    $to[]=array($cc);
}

// ループ防止
foreach($to as $key => $ad){
    if( false !== strpos($ad[0],'@****.****') ){
        unset($to[$key]);
    }
}


if(0===count($to)){
    die('Illegal Mail');
}


$mail -> reset();//いったんQdmailのすべてをリセット(念のため)
$body=<<<EOF
テンプレートをお届けします
役に立ったと思われたら、ぜひネット上でご紹介ください。

auテンプレートは、クセがあるので気をつけてください。
お気づきの点、ご意見、ご感想を、ぜひ以下のサイトまでお寄せ下さい。

Spok
http://hal456.net/
http://hal456.net/qdmail/decomail_base
http://www.cpa-lab.com/tech/
EOF;

$fg=qd_send_mail(
    'text',
    $to,
    'デコメ3種テンプレート(試験運用)',
    $body,
    $add_header,
    $attach
);