MAIL

June 26, 2008

Quoted-Printable Encode/Decode

phpにquoted_printable_decode()関数はあるけど、quoted_printable_encode()関数はないので、エンコードは次のように行う(mb拡張があればmb_encode_mimeheader()でQエンコーディング使えば良い)。
$fp = fopen("php://temp", "r+");

stream_filter_appand($fp, "convert.quoted-printable-encode",
                     STREAM_FILTER_READ,
                     array("line-length" => 74,
                           "line-break-chars" => "\r\n")
                    );

fputs($fp, $str);
rewind($fp);
$encoded = stream_get_contents($fp);
fclose($fp);
多くのMUAがヘッダに含まれるアンダースコアをスペースに変換する(ボディのアンダースコアはそのまま)。変換するMUAは、確認したところで、Outlook Express6, Thunderbird, Mail, Becky, Sylpheed, Eudora, Entourage。変換しないMUAはShuriken。

変換したりしなかったりなので、ヘッダでもボディでも、とにかくアンダースコアは=5Fに変換しておけば良い。
$encoded = str_replace("_", "=5F", $encoded);
デコード時は、先程挙げた多くのMUAと同様、ヘッダの場合にのみアンダースコアをスペースに変換する。=5Fはquoted_printable_decode()関数がアンダースコアに変換するので、気にしなくて良い。
if ($isHeader) {
  $str = str_replace("_", " ", $str);
}

$decoded = quoted_printable_decode($str);


June 20, 2008

mailtoを使用する際のスパム対策

HTMLでメールアドレスを素で書くとスパムロボットに拾われるため、JavaScriptを使ったスパム対策をする。

今回利用したスクリプトがこちらで、ほんの少し改造して使いやすくした。

使い方はCryptMailto.jsを読み込み、idを振った空のタグを用意し、popup_mailer()関数にアカウント名・ドメイン名・idを渡す。

例えばHTMLは次のようになる(ソース上にメールアドレスが現れない)。
<p>
  お問い合わせ先: <span id="info"></span>
</p>

<script type="text/javascript" src="/js/CryptMailto.js"></script>
<script type="text/javascript">
  popup_mailer("info", "example.com", "info");
</script>
サンプルはこちらで。

June 11, 2008

Thunderbird - Sorting messages by Thread

Thunderbirdでスレッド表示すると、同じ件名だと全く関係ないメールでもスレッド化してしまうので、それの対処。

以下の作業をする前に、Thunderbirdを閉じておく。

ホームディレクトリ以下のどこかにある、prefs.jsを変更する。
Windowsだと次のようなパスにある。
C:\Documents and Settings\user\Application Data\Thunderbird\Profiles\xxxxx.default\prefs.js
Linuxだと次のようなパスにある。
/home/user/.thunderbird/xxxxx.default/prefs.js
prefs.jsに以下の一行を追加。
user_pref("mail.thread_without_re", false);
この"xxxxx.default"ディレクトリの下の、MailやImapMailディレクトリ内の*.msfファイル(インデックスファイル)を削除する。


June 10, 2008

Postfix - pass a mail to the php script

ある特定のユーザ、もしくはドメイン宛のメールをPHPに渡す場合のPostfixの設定。

まず、transportの設定をする。全ユーザの場合はドメイン名だけで良い。
$ vi /etc/postfix/transport

user@example.com phpscript:
# example.com phpscript:
main.cfでこのファイルを指定する。
$ vi /etc/postfix/transport

transport_maps = hash:/etc/postfix/transport
postmapコマンドでtransport.dbを更新する。
$ /usr/sbin/postmap /etc/postfix/transport
master.cfで"phpscript"サービスの設定をする。
$ vi /etc/postfix/master.cf

phpscript unix  -      n      n      -      -      pipe
  flags= user=nobody argv=/path/to/php /path/to/script.php
postfixを再起動する。
$ /etc/init.d/postfix restart
phpではstdinからメールのソースを取得できる。
$ vi /path/to/script.php

<?php

$mail = file_get_contents("php://stdin");


May 30, 2008

Sabel 1.1 - Mail, MimeDecode

Sabel 1.1でSabel_Mail_MimeDecodeが追加されます。PEARのMail_mimeDecodeと同じようなものですが、PEARではマルチパートの場合にpartオブジェクトの再帰構造で結果が返されるため、どこに本文があるのか、どこにHTML本文があるのかの判断が面倒です。同じ内容でもThunderbirdとOutlook Expressで送信すると構造が異なることがあるため、厄介です。

Sabel_Mail_MimeDecodeでは常に同じように本文やHTML本文などを取得できます。一般的なメールに限られますが、以下の形式に対応しています。

・本文
[本文]
・HTMLメール
[HTML本文]
・HTMLメール(インライン画像有)
multipart/related
    [HTML本文]
    [インライン画像]
    ...
・HTMLメール + 添付ファイル
multipart/mixed
    multipart/related
        [HTML本文]
        [インライン画像]
        ...

[添付ファイル]
...
・本文 + HTMLメール
multipart/alternative
    [本文]
    [HTML本文]
・本文 + HTMLメール(インライン画像有)
multipart/alternative
    [本文]
    multipart/related
        [HTML本文]
        [インライン画像]
        ...
・本文 + HTMLメール(インライン画像有)
multipart/related
    multipart/alternative
        [本文]
        [HTML本文]

[インライン画像]
...
・本文 + HTMLメール + 添付ファイル
multipart/mixed
    multipart/alternative
        [本文]
        [HTML本文]

[添付ファイル]
...
・本文 + HTMLメール(インライン画像有) + 添付ファイル
multipart/mixed
    multipart/alternative
        [本文]
        multipart/related
            [HTML本文]
            [インライン画像]
            ...

[添付ファイル]
...
・本文 + HTMLメール(インライン画像有) + 添付ファイル
multipart/mixed
    multipart/related
        multipart/alternative
            [本文]
            [HTML本文]

    [インライン画像]
    ...

[添付ファイル]
...
・ダイジェスト
multipart/digest
    message/rfc822
        [上記のいずれかの形式]
    ...
・本文 + ダイジェストメール
multipart/mixed
    [本文]
    multipart/digest
        message/rfc822
            [上記のいずれかの形式]
        ...
・本文 + ダイジェストメール + 添付ファイル
multipart/mixed
    [本文]
    multipart/digest
        message/rfc822
            [上記のいずれかの形式]
        ...

[添付ファイル]
...

使い方は以下のようになります。
$decoder = new Sabel_Mail_MimeDecode();
$decoded = $decoder->decode(file_get_contents("/path/to/mail.eml"));

if ($decoded->body) {
  echo $decoded->body->getContent();  // 本文
}

if ($decoded->html) {  // HTMLメール
  echo $decoded->html->getContent();  // HTML本文
  if ($images = $decoded->html->getImages()) {  // インライン画像
    foreach ($images as $image) {
      echo $image["cid"];       // コンテンツID
      echo $image["mimetype"];  // MIMEタイプ
      echo $image["data"];      // 画像データ
    }
  }
}

if ($decoded->attachments) {  // 添付ファイル
  foreach ($decoded->attachments as $attachement) {
    echo $attachment->getName();     // ファイル名
    echo $attachment->getType();     // MIMEタイプ
    echo $attachment->getContent();  // 添付ファイルデータ
  }
}

if ($decoded->mails) {  // ダイジェスト
  foreach ($decoded->mails as $mail) {
    // $decodedと$mailは同じように扱える
  }
}

1.1の最新版はSVNでチェックアウトできます。
http://svn.sabel.jp/branches/1_1

Sabel PHP Framework



May 02, 2008

mail - attachment file

日本語名のファイルを添付するときのヘッダ。
$format = <<<FORMAT
Content-Disposition: attachment; filename="%1\$s"
Content-Transfer-Encoding: %2\$s
Content-Type: %3$s; name="%1\$s"
FORMAT;

$fileName = mb_encode_mimeheader("日本語.gif", "ISO-2022-JP", "UTF-8");
$header = sprintf($format, $fileName, "base64", "image/gif");
ちなみにこのエンコードされたファイル名はRFC2231に準拠していない。が、確認したところで、WindowsのOutlook Express・Window/LinuxのThunderbird・MacOSXのMail・Gmailで正しく扱うことができる。

RFC2231に準拠するとOutlookが駄目なようなので、シェアを考慮すると準拠できない。Docomoのメールアドレスと同じ類の問題。


April 17, 2008

mail function

phpでメール送信。毎回微妙に忘れるのでメモ。

Message-Idのドメインは引けるものであること。
また、パラメータのアドレスはメールが届くものであること。
function sendmail($from, $to, $subject, $body)
{
  $headers = "MIME-Version: 1.0\r\n"
           . "Content-Transfer-Encoding: 7bit\r\n"
           . "Content-Type: text/plain; charset=ISO-2022-JP\r\n"
           . "Message-Id: <" . md5(uniqid(microtime())) . ">@mail.example.com\r\n"
           . "From: $from";
  
  $parameter = "-f admin@example.com";
  
  $subject = mb_encode_mimeheader($subject, "ISO-2022-JP");
  $body = mb_convert_encoding($body, "ISO-2022-JP");
  
  mail($to, $subject, $body, $headers, $parameter);
}
エンベロープのsenderアドレスを設定するために第5引数(additional_parameters)を指定すること。しかし、X-Warningヘッダが付加されてしまうので、それを回避するためにpostfixの設定が必要。これをしないとスパム扱いされたりする。
vi /path/to/main.cf

...

header_checks = regexp:/path/to/header_checks

...
vi /path/to/header_checks

...

/^X-Authentication-Warning:/ IGNORE


Sabel

Sabel PHP Frameworkを開発しています。
http://www.sabel.jp/

Search
Categories
Tags
Recent Articles
Archives