WindowsNT系にはCDOSYSというライブラリが存在する。これはSMTPやNMTPに基づいたメッセージングアプリケーションの標準APIだ。これを使うことでいとも簡単にIISに標準で付属されるSMTPサーバを利用してメッセージングができる。まぁ別にIISのSMTPでなくともいいのだけれど、IISをインストールするとSMTPももれなくインストールされるので、今回はIISのSMTPサーバを利用する。

極力難しい単語や特殊なテクニックは使わずに、IISがインストールできる環境だけでユーザーライセンスを増やすことなくメールアドレスをバツンバツン作成してみたいと思う。
まぁメールアドレスを増やすと言っても実際に増やすのではなく「example.comドメイン宛のメールをRCPTで判断するスクリプトでもって無理やりキャプチャする」というシロモノだ。いきなりワケのわからない説明かと思うが、最後まで読んでいただければSMTPの基礎知識やメールヘッダ、VBScriptの書き方などの理解が多少なりとも深まるであろうと思う。

デーモンだとかサービスだとかトランスポートではなじみが薄いため、表記は全てサーバに統一する。細かいこと言わなくてもいいじゃん。プロトコルなんて言葉も使わずに「やり方」で通す。スクリプトとは言わば「台本」である。 要するに「メールが届いた時の動きを決める台本」を書こうというのだ。

まず、メールが届く仕組みから説明しようと思うのだけど、技術的な専門用語を使って説明してもそこらへんの技術系フォーラムと大差なくなってしまうので、ものっそい簡単に説明しよう。

あなたがメーラーでメールを送受信しようとしたら、メールアドレスやアカウント、パスワード、SMTPサーバのアドレスとPOP3サーバのアドレスを設定しなければならないだろう。
よく「受信はPOP3、送信はSMTP」とか言う人がいるけれどこれは間違い。POP3とは「メールサーバに届いた自分宛のメールをサーバから取り出すためのやり方」でSMTPとは「メールをメールサーバ間でやり取りするためのやり方」である。
今回はSMTPに焦点を絞って話しを進めるのでPOP3について言及はしない。と言うか強引に言ってしまえば今回のエントリのキモは「仮想的にPOP3のような働きをするスクリプトを書く」ことなのでPOP3の説明しちゃったらこのエントリの存在意義が問われてしまうので頼まれたってするもんか。

さて、SMTPがメールサーバ同士でメールのやり取りをするためのやり方であることから、SMTPサーバとは「SMTPを使ってメールをやり取りするサーバ」と言うことがわかる。さぁ、ここまでわかったらとりあえずIISをインストールしてみよう。Windows98やMeなんて言うなよ。XPHomeもやめてくれ。と言うか説明が面倒なのでここではWindows2000serverだとする。
WindowsNTだとCDOのバージョンが古いのであんま使えないけど、Windows2000以降ならば新しいCDO 2.0つうのが標準で用意されている。IISも同じような感覚でかまわない。ただXPHomeはダメだ。ありゃMeみたいなもんだ。5000円も違わないんだからWindowsXPを買うんだったらProfessionalにしよう。
まぁバージョンだとかなんだとか難しい話はおいといて。

IISをインストールして管理ツールのインターネットインフォメーションサービスで新しいSMTPサーバをぶったてよう。
とりあえずここらへんを事細かに説明されなければわかんねぇってヤツにはこの先もちょっと難しくなってくる。そんなキミはとりあえず「IIS SMTP」などでググって調べると共に、副産物的に得られる知識を取り込もう。
IIS導入についても説明しようかと思ったけど、俺の狭い説明ではセキュリティなどに甘さがでるのでやめておく。

で、IISの導入が滞りなく完了したとしよう。お次はプライドの高いSMTPサーバをこっちに振り向かせるための文句を考えなければならない。うそだ、実は既に用意されている。
MSDN(smtpreg.vbs)
リンク先のCopycodeをクリックすれば、クリップボードに必要な口説き文句がコピーされるので、そいつをメモ帳にでも貼り付けてsmtpreg.vbsと言う名前で適当なディレクトリに保存しよう。
SMTPサーバを起動させると、SMTPサーバはメールが届くのを、今か今かと両手を広げて待っている。
んで、そのSMTPサーバにメールが届くとSMTPは「あ、メールが届いたわ。受け取らなきゃ」と腰を浮かせるわけだ。
その腰が浮いた瞬間に横からそのメールをかっさらうために必要なのが今のsmtpreg.vbsってワケだ。

じゃあ、どうやってその「腰が浮いた瞬間」を捉えるかを今から説明するので、各自わからないことはググるように。
まずSMTPサーバが起動されるとSMTPサーバは両手を広げると言ったが、これがいわゆる「ソケットを初期化して受信接続要求を待機している状態」になるわけだけど、よくわかんないよね。だから別に理解する必要はない。とりあえずSMTPサーバが起動したらSMTPサーバは「メールがくるのを待つ状態」になるわけだ。
んで、メールが届いたりメールを送ったりすることを「イベント」という。で、そのイベントに目印をつけておいて、イベントが動いたらわかるようにすることを「イベントにバインドする」という。単語の大まかな意味でなんとなくわかるよね?その「バインド」をするためにsmtpreg.vbsがある。
「なにをイベントにバインドするの?」と思ったキミ、中々筋がいい。その「なにを」が今回書くスクリプトそのものだ。

要するに、SMTPサーバがメールを受信するイベントに対して、自作したスクリプトをバインドするってわけだ。
専門用語無しで行くなら「サーバにメールが届いたら俺が作った台本どおりの動きをしてくれ」ってこと。
どんな台本が実用的か色々考えた結果、今回は「転送メール」の仕組みを作ってみようと思う。
abc@hoge.jpに届いたメールをabc@example.comに自動的に転送するっていうアレだ。
恐らく簡単すぎて拍子抜けするだろう。もしかしたらアゴもはずれるかもしれない。はずれたら早いとこ病院に行くべきだ。それではいきなりソースをべろんちょしてみる。アゴおさえておけよ。

Sub ISMTPOnArrival_OnArrival(ByVal Msg, EventStatus)
Dim FwMsg
Set FwMsg = Msg
FwMsg.To = "abc@example.com"
FwMsg.Send
End Sub

うぉう6行だ。まぁ最初っからフガフガをしてモゴモゴができちゃうようなスクリプトは理解不能だと思うので、このくらいで十分。と言うかこれがVBScriptってヤツだ。こいつをfw.vbsとでもして適当なディレクトリに保存しよう。

の前に、一応スクリプトの説明をしよう。

Sub ISMTPOnArrival_OnArrival(ByVal Msg, EventStatus)

こいつがさっき出てきた「イベントへのバインド」の正体だ。OnArrivalっつうのはまぁ細かく説明するとアレなので乱暴に言うと「メールを受信した」時に発生するイベントだ。括弧の中のByValっつうのは値渡しっつって引数内部の値だけをプロシージャに渡すっつうような意味だ。要するにMsg自体は変化しない。乱暴に言えば読み込み専用みたいなもんだ。さっきから俺乱暴者だな。まぁいいか。
あぁ、プロシージャってのはスクリプト内の一幕とでも言うかな、ワンシーンて感じのもの。このプロシージャが集まってスクリプトを形成するわけだ。Msgってのは届いたメールそのものだ。EventStatusってのは今回は使わないのではしょる。
Dim FwMsg
Set FwMsg = Msg

で、DimってのがFwMsgっつう変数を定義している。Setっつうのはオブジェクトをオブジェクト変数に代入するためのコマンドなのだけれど、オブジェクトの話を始めたら腱鞘炎になりそうなので割愛。とりあえずオブジェクトってのは「ひとつのカタチを形成する定義の塊」とでも捉えてもらって結構。
要するにMsgっつうオブジェクトをFwMsgに代入してるってことだ。
FwMsg.To = "abc@example.com"
FwMsg.Send

オブジェクトにはプロパティとメソッドがある。プロパティってのはそのオブジェクトを形作る、いわば"特徴"みたいなもんだ。メソッドはそのオブジェクトが"できること"を指し示している。FwMsg.ToってのはメールオブジェクトのTo(あて先)だ。こいつに目的地のabc@example.comを代入する。そしてFwMsg.Sendとは、メールオブジェクトを送信するためのメソッドである。ようするに「メールを送信しろ」ってことね。

さて、スクリプトの説明が終わったところで今度は、作ったスクリプトをSMTPサーバのイベントにバインドさせるためのバッチファイルを作ろう。バッチファイルってのがなんなのかわからないって人はたぶんここまで読んでいないと思うので、説明ははしょる。DOSのシェルスクリプトだ。
で、さっそくソースだ。

cscript C:\InetPub\lib\smtpreg.vbs /remove 1 onarrival SMTPScriptingHost
cscript C:\InetPub\lib\smtpreg.vbs /add 1 onarrival SMTPScriptingHost CDO.SS_SMTPOnArrivalSink "RCPT TO=abc"
cscript C:\InetPub\lib\smtpreg.vbs /setprop 1 onarrival SMTPScriptingHost Sink ScriptName "C:\InetPub\Scripts\fw.vbs"

どっかで改行されてたら、cscriptを行頭に3行に構成しなおしてくれ。まぁキミのモニタの解像度が640*480くらいじゃこんな長い文章1行で表示できないよな。すまない、言い過ぎた。
cscriptっつうのはコマンドラインでVBScriptを走らせるためのコマンドだ。で、今回はsmtpreg.vbsをC:\InetPub\libにfw.vbsをC:\InetPub\Scriptsに保存したと仮定して記述した。別に任意の場所に保存してもいいけど、そのときはパスを間違えるなんて初歩的なミスはしないように。
1行目で一応、以前同じイベントシンクに登録されていた場合に備えてイベントシンクを削除している。/removeってのが削除するためのオプションだ。イベントシンクっつうのはイベントにバインドさせた「仕掛け」みたいなものだ。既に登録されてたらエラーになっちゃうからね。そのイベントシンクのIDにあたるのが数字の1だ。要するに1番目のイベントシンクってワケ。
で、2行目に/addとあるので、これはそのままイベントシンクの登録だ。"RCPT TO=abc"がabc@hoge.jpに届いた場合と言う意味。要するにローカルパートの指定ね。ローカルパート以外にも指定できるトリガはあるけど、今回は割愛。ちなみにローカルパートっつうのはメールアドレスの@より前の部分、要するにドメインの中でキミのメールアドレスだということをアピールしている部分だ。
そして3行目が、イベントが発生した場合に走らせるスクリプトの指定だ。/setpropで指定する。このたった3行で、あの正体不明なSMTPがいとも簡単に言うことを聞いてくれるのだ。で、install.batとでもして適当なディレクトリに保存しよう。

これで準備は全て整った。後はバッチファイルを走らせたら完了だ。試しにabc@hoge.jpへ送信したメールが、abc@example.comへFwではなく純粋に転送されているのが確認できるだろう。これを元に自動返信スクリプトや、電車の中刷り広告などで見かける「このメールアドレスに空メールを送ってください!」みたいなシステムを作り上げることも可能だ。

それ以外にも、あんなことやこんなこともできたりする。詳しく知りたければMSDNにCDOライブラリに関する全ての資料がそろっている。
俺が実際に使ってシステムをくみ上げていた頃は、こんな豊富なリファレンスなんてなかったのに・・・
MSDNライブラリ


どうだろう「プログラムって作るの大変なんじゃない?」とか「迷惑メールってどうやって送ってるの?」などといった素朴な疑問に対し、あなたの中でいくらかでも知性の光が差し込んできたのならば、このエントリを書いた甲斐があったというものである。
ちなみに今回のスクリプトはテストしていないので、実際のところ動作確認は取れていない。でもまぁ理論的にかつなるべく専門用語を使わずにインフォメーションテクノロジの端っこをめくってみるのが目的であり、プログラミングテクニックなんてのは手段に過ぎないので、俺としては動こうが動くまいが別にどちらでもいい。
問題はあなた自身が作ってみて、でも全く動かなくてそれを何とか動くようにまで昇華したらいろんな技術を知ることができた!と言う「知的探究心をどれだけ満足させられるか」という部分に尽きる。

トラックバック

このエントリーのトラックバックURL:
http://o29.s1.xrea.com/spais/mt-tb.cgi/36

このリストは、次のエントリーを参照しています: SMTPで遊ぼう:

» 魔術師たるべき仕事 from 魔術師の特訓
魔術師ならば、錬金術師のごとく、お金もバシバシ生成しなければならないと思う。生成しなければ終わりかな、と思ってる。いや本当に。 そんなわけで、今回はサイドビジ... [続きを読む]

トラックバック時刻: 2006年12月21日 23:57