オープンソースでマクロによる多機能、柔軟なメール環境構築が可能なQMail3についてご紹介します。

ホーム / Windows / Mailer / QMail3

更新: 11/10/05 | QMail3紹介 | QMail3

QMail3とは

QMail3はオープンソースの多機能メーラーです。
マイナーなメーラーの一つで、使い勝手も安定性も「とても良い」とは言い難いのですが(マクロでしくじると、デバッガが起動したりする)、高度なマクロ機能を提供しておりフラットファイルの編集で様々な設定やルール指定が可能なため、相当自由度の高いメーラーとなっています。

http://q3.snak.org/

例えば、メールの条件によってバッチファイル、JavaScript、VBScriptを起動できます。特定のタイトル、内容、送信者、ヘッダーのメールを受信した場合にローカルにファイルを作成したり、複雑な内部処理をしたり、IE経由でWebにポストしたりといったことが可能になるのです。
これは、クライアントというよりもサーバー再度のメールシステムとして利用するのにとてもありがたい機能と言えます。

QMail3のマクロで利用できる関数について、全文見渡して必要な関数の存在やリファレンスを検索したかったので、QMail3の本家サイトドキュメントQMail3の関数PDFとしたものを用意しました(2010年6月5日時点の内容をスナップショット)。

間違いやすい設定など

導入時に設定が分かりづらいところをまとめてみました。

  1. IMAP4/POPアカウントの指定
    インストール直後にデフォルトアカウントを作成しますかといったメッセージが表示されるのですが、何の気無しにYESを選択すると勝手にPOPアカウントを作成してくれます。IMAPアカウントの設定を念頭に置いているユーザーは、このデフォルトアカウントの設定を変更しようとしてもIMAP設定に変更することは出来ません。
    デフォルトアカウントは作成せずに、新規にマニュアルでアカウントを作成しIMAPを選択する必要があります。

  2. 自分宛にBccの解除
    デフォルト設定では、全てのメールはBccに自分を指定するようになっています。この設定を解除するには、オプションのその他2から変更します。QMail3でBcc設定を解除

  3. 巡回ポップアップの非表示
    巡回する度にポップアップが表示される場合は、オプションの「同期」から変更できます。アカウント設定のテスト中はポップアップさせて、設定が完了したらバックグラウンドで巡回させるのが良いでしょう。
    QMail3で巡回ポップアップを解除

  4. タスクトレイへの格納
    メニューバーの「ファイル>隠す」でタスクトレイに格納が可能です。「隠す」という表現が少し分かりづらいと思いました。
    また、起動時のオプションでも指定が可能で、「-q」とすることで起動時にタスクトレイに格納することが可能です。スタートアップなどに登録しておけば使いやすくなると思われます。

  5. メール送信時のエラー「送信に失敗しました」
    IMAPアカウントなどで多いのではないかと思いますが、フォルダの役割に「送信箱」指定がされていないと、例えSMTPの設定が正しく行われていたとしてもこのエラーが出て送信が出来ません。
    QMail3で送信に失敗しましたのエラー
    Outboxという名前のフォルダをリモート(サーバー側)に作成すると、自動的に送信箱と草稿箱の属性が付加されます。IMAP+SMTPでは、いったんこのOutboxにメールが配置され同期時にSMTP送信されるといったまどろっこしい動作が見受けられましたが、そういうものなのでしょう。

  6. 振り分け設定が実行されない
    デフォルトではメール着信時に設定された振り分けが実行されません。手作業で右クリック>「選択されたメッセージを振り分け」を選択すれば実行されるのに、メール着信時には実行されないと行った場合には設定>アカウント>高度タブから「自動で振り分ける」のチェックをオンにする必要があります。
    QMail3で着信時に振り分けが実行されない

 

QMail3を活用して、簡易メーリングリストを運用する

メーリングリストを運用する必要があり、一般のサービスなどを検討したのですが利用者の多くが携帯電話であることからドメイン拒否の設定を解除しなくてはならず、導入が面倒という課題がありました。

そこで、iPhone(一応携帯)のi.softbank.jpアカウントであれば、多くの携帯電話のデフォルト設定が携帯同士はOKという設定と思われるためドメイン拒否の設定を変更しなくてもメーリングリストに参加できると考えました。

i.softbank.jpアカウントはIMAP+SMTPでPCやMacからも利用できるため、一般のサービスで指定されたアカウントを介したメーリングリストサービスの提供が出来れば良かったのですが、いくら探してもそうしたサービスはありませんでした。(基本的にサービサーが提供するアカウントを使わなくてはならない=ドメイン拒否の設定問題がつきまとう)

Shurikenそのため、自前のサーバー上で一般のメーラーを稼働させて簡易的なメーリングリストを運用することを考えたのです。最初は普段から使っているShurikenシリーズを検討しました。ところが、IMAPの場合には丸投げ転送(メーリングリストに展開)が出来ないという仕様が分かり断念しました。

Thunderbird続いてThunderbird2、3にて実現しようとしましたが、こちらはIMAPでも自動転送が出来るものの丸投げが出来ず、つまりOriginal Message〜といった引用情報を割愛できませんでした。Version2ではアドインを使って実現できるのですが、転送元メールが添付になってしまう(インラインに出来ない)というバグがあり、携帯端末では表示できないという有様でした。

最終的に、QMail3をカスタマイズすることで概ねやりたいことを実現することが出来ました。その方法などについてまとめておきます。

メーリングリストの判定はタイトルで

i.softbank.jpを利用するということは、個人のメールとメーリングリスト宛のメールが混在することになります。
個人宛のメールがメーリングリストに展開されてしまったりしないように、厳密にタイトルでメーリングリストを判別しなくてはなりません。

この判定は、振り分け設定の条件で行いました。どのような決め方でも構わないのですが「ジョイナー:」のようなタイトルが含まれている場合にはメーリングリストと判定することにしました。
この時、人によっては半角を利用したり、「ジヨイナァ」などと難解なタイトルを指定する場合があるかも知れません。ということで、QMail3が得意としている正規表現を使うことにしました。

[ジシ]゙?[ョヨョョ][イイィィ][ナナ][ーアアァァ][::]

これで常識的な(それを若干逸脱した)表現に対応できるようになりました。注意が必要なのは「ジ」です。二つの文字で構成されているのでジ?で対応しました。?は言わずもがな0〜1回の繰り返しですので、あっても1回登場でもOKということになります。

送信者の判定

誰でもメーリングリストに投稿できるようになっていると、スパムメールなどが展開されてしまいます。通常のメーリングリストでは特定の内容でメールを送信すると、承認されて自動的にメーリングリストに参加できるものなのですが今回は手作業での登録となります。

新たな条件に次のような条件を指定します。

@Contain(From,'a@a.com')

ここから先はカスタム指定でないと表現できなくなってしまうので、rules.xmlを直接編集してしまっても良いと思います。QMail3の偉いところは編集してもQMail3を再起動しなくても良い点です。Thunderbirdなどでは再起動しないと認識してくれません。

複数のアドレスを指定する場合には@Orを利用します。

@Or(@Contain(From,'a@a.com'), @Contain(From,'b@b.com'))

これら2つの条件(タイトルと送信者)でメーリングリストに展開するかどうかを判定することが出来ました。

実際のメーリングリスト展開

メーリングリストへの展開はTo指定で各人に展開する方法と、Bccで一括配信する方法の両方が可能ですが、今回はBccを採用しました。

ここで、前述のOutboxが登場します。

振り分けのアクションとして、Outboxへのコピーを指定し、同時にテンプレートと引数として「Mytoaddress=a@a.com, b@b.com」などと配信先の指定をします。
テンプレートは

C:\Documents and Settings\アカウント名\Application Data\QMAIL3\templates\mail

に新たに作成し、拡張子を除いた名前を指定します。名前は何でも良いのですが、テンプレートの内容は以下のようにしました。
引数として渡されたMytoaddress変数をBccに利用していることが分かると思います。

Joyner{
@Progn(
@Concat('From: Joyner<Joyner@i.softbank.jp>\nTo: Joyner<Joyner@i.softbank.jp>\nBcc: ',$Mytoaddress,'\n')
)
}Subject: {@Subject(@True(), @True())}
X-QMAIL-Account: {@Account()}{
@If(X-QMAIL-SubAccount,
@Concat('\nX-QMAIL-SubAccount: ', X-QMAIL-SubAccount),
'')
}
{
@Catch(@Concat('X-QMAIL-Macro: @ForEach(@Messages(\'',
@Concat('//', @Account(), '/', @Folder()),
'\', ',
@Id(),
'), @Forwarded(@True()))\n'),
'')
}{
@If(@Equal(@Profile('', 'Global', 'ForwardRfc822', '0'), '1'),
@Concat('X-QMAIL-Attachment: ', @URI(), '\n\n'),
@Concat('X-QMAIL-Attachment: ',
@Attachment(',', @True()),
'\n\n',
From,
' さんの投稿です\n',
'---------------',
'\n',
@Body('', :BODY-INLINE)))
}

メーリングリストらしく「〜さんの投稿です」と、シンプルに引用するのみにしてあります。引用はBODY-INLINEを指定しており、携帯電話で受信しても違和感なく内容を参照することが出来ます。

※ Joyner@i.softbank.jpは説明の便宜上(主にタイトルの説明で、多様性を求めた流れで)採用した架空のアドレスです。よく考えたら実在しそうなアドレスですが、故意や悪意はありませんのであしからずご了承くださいませ。

マクロに関する問題・トラブル

code=8エラーが発生する

「選択されたメッセージを振り分け」では正常動作するが、同期時にcode=8エラーが発生する」という問題が起きました。色々試して解決しなかったので、QMail3の掲示板に報告だけはしておきましたが、JScriptを使わずに内部関数だけで実装するように修正するのが最短の道の気がしました。

正規表現で[]をエスケープできない

報告などはしていないのですが、標準関数内での正規表現で[]を指定することが出来ません。[]は本来[a-z]などのように範囲を指定するものですが、範囲の中に[]自身を指定できません。¥でエスケープしようとしても正常動作しませんでした。
とりあえず、JScriptの正規表現に¥でエスケープして動作はしましたが、前述の問題のためJScriptが使えないとなると、いよいよ手詰まりです。

デバッガが起動する

マクロの記述でしくじると、場合によってはデバッガが起動してQMail3ごとストールします。主な原因については次のパターンを疑って下さい。

QMail3のマクロ関数だけでは四則演算ができない

QMail3のマクロ関数には標準で@Addと@Subtractという加算、減算の関数が用意されています。とろころがかけ算(積算)や割り算(除算)(もちろん商余も)に該当する関数が用意されていないのです。
これらを必要とする場合には、JScript内で演算させたり自前で@Add,@Subtractを使った関数を作成する必要があります。ドキュメントにはサンプルとしてかけ算を@Defunで定義する再帰呼び出し関数が記述されています。

@Defun('multiplySub',

@If(@Equal($1, 0), 0, @Equal($1, 1), $2, @Add($2, @Multiply(@Subtract($1, 1), $2)))),

こんな感じです。一見単純で実用的に見えますが、大きな数字になると手に負えません。Debugログ出力などしていると、あっという間にログファイルが数十メガになります。

通常は@Script関数によりJavaScriptなどを使って演算してしまえばよいのですが、複雑なマクロの入れ子である場合に、後述のエラーが発生するため@Scriptが使えない場合があります。このような場合には、自分で実装しなくてはならなくなります。

その際にちょっとしたアルゴリズムが必要となりますがビットのシフトが使えると、かけ算、割り算は比較的容易に実装が可能なのです。因みにアルゴリズムという言葉は、アラビアの数学者アル=コワリズムの名にちなんで付けられたそうです。

QMail3のマクロ関数にはシフト演算などという高級(低級?)機能が備わっているわけもありません。因みに、シフト演算が可能である場合、次のように記述できます。

かけ算(JavaScript)

「ロシア農民のかけ算」と呼ばれる手法をプログラミング言語仕様に乗っ取って実装するのが一般的なようです。「ロシア農民のかけ算」とは、

14×15の場合、片側を半分(余りは切り捨て)、もう一方を倍にしていきます。

14 15
7(=14/2) 30(=15*2)
3(=7/2) 60(=30*2)
1(=3/2) 120(=60*2)
0 240

前者(2で除算していく方)が2の倍数以外である場合(判定)の右辺のみを総和すると解が求まるという方法論です。この方法は積算、除算、判定の全てが2である点で非常にコンピューター(2進法)に適したアルゴリズムと言えます。

これはひとえに2進法における積算、除算はビットシフト、偶数かどうかの判定は1ビット目が0であるかどうかをチェックすれば良いという特性によるものです。因みにJavaScriptで実装すると以下のようになります。ビットシフトの演算が可能であればどのような言語であってもかけ算を容易に実装できそうです。

function multiply(a, b){
// multiply=a*bとなる
var multiply = 0;
while(a > 0){
// 1ビット目が1ということは、奇数なので解に加算
if (a & 1 == 1) multiply += b;
// 前者はビットシフトして半減
a >>= 1;
// 後者はビットシフトして倍増
b <<= 1;
}
return multiply;
}

ブースの乗算アルゴリズムにしても結局は2進数のシフト演算が出来ないと実装できない。
古代エジプトの2倍法というものもあるが、これも2、4、8とビットをシフトするかのように倍々ゲームで掛けていき、掛けた回数とシフトした数を合わせ込むという方法。結局、ビットシフト自体をエミュレート(実装)しないといけないということになりそうです。倍増だけで済むのであればa×2=a+aで簡単に済みそうな気がします。

結局、大きな数字の計算自体をしないように心がけ(運用回避)、必要最低限の演算が出来るように次のような関数を用意しました。

かけ算

@Defun('multiply',@If(@moreThan($1,$2),@multiplySub($2,$1),@multiplySub($1,$2))), @Defun('multiplySub',
@If(@Equal($1, 0), 0, @Equal($1, 1), $2, @Add($2, @Multiply(@Subtract($1, 1), $2)))),

足し算を繰り返すため、その回数を出来るだけ少なくできるように小さい値をLoopで採用するように二段構えになっています。

割り算

@Defun('division',@Progn( @Set('Quotient',0,:GLOBAL), @Set('Numerator',$1,:GLOBAL), @Set('Denominator',$2,:GLOBAL), @While(@moreThan($Numerator,$Numerator),@Progn(
@Set('Quotient',@Add($Quotient,1),:GLOBAL), @Set($Numerator,@Subtract($Numerator,$Numerator),:GLOBAL) )),
$Quotient
)),

こちらは、引き算で実装しています。@SutractをWhileでひたすら繰り返します。副産物として剰余$Numeratorが得られるので後で利用できるようにグローバル変数としています。

その他のQMail3で使える便利なユーザー関数

指定文字列($1)を、指定回数($2)繰り返した文字列を返却する関数

@Defun('string',@Progn( @Set('counter',0),
@Set('ret',''), @While(@Not(@Or(@Equal($counter,$2),@Equal($counter,10))),@Progn( @Set('ret',@Concat($ret,$1)), @Set('counter',@Add($counter,1))
)),
$ret
)),

 

携帯電話アドレスの仕様について

携帯電話(KDDIのau、Softbank MobileのiPhone、NTT docomoなど)の携帯電子メールアドレスには、送信数、宛先数などの細かな制限が設けられています。
こうした制限を把握しておかないと、メールがエラーで送れなかったり、規制を欠けられたりしますので注意が必要です。
詳細は、携帯電話メールアドレスの仕様についてで紹介しています。

 

 
お勧めリンク
ダウンロード
ストリーミング関連
Macintosh関連
Windows関連
メディアなど
 
ハードウェア
ソフトウェア/サービス/開発SDK
デジタル一眼レフカメラ
テクニカル記事
趣味関連
ゲーム 〜楽しいゲームの紹介や攻略法
RoverMNI(ローバーミニ) 
雑記
その他
コメント・フィードバック
©1998 CNXGROUP. このページの全部あるいは一部を無断で利用(コピー)することを禁じます。
>