ちょっと個人的な用事があって、CDOでメール送信するスクリプトをかなり本気でやりました。
CDOはドキュメントが少なくていつも苦労するので、未来の自分のためにもメモしておく。
まずは基本形。どこかのSMTPサーバにつないでメールを1通送る例。JavaScriptで書きましたが、WSHなので言語は問いません。
var mail = new ActiveXObject('CDO.Message');
mail.From = 'from@example.com';
mail.To = 'to1@example.com,to2@example.com';
mail.Cc = 'cc@example.com';
mail.Bcc = 'bcc@example.com';
mail.Subject = 'メールの件名';
mail.TextBody = 'メールの本文。\n改行もできるよ';
mail.TextBodyPart.Charset = 'ISO-2022-JP';
var schemas = 'http://schemas.microsoft.com/cdo/configuration/';
mail.Configuration.Fields.Item(schemas + 'sendusing') = 2;
mail.Configuration.Fields.Item(schemas + 'smtpconnectiontimeout') = 30;
mail.Configuration.Fields.Item(schemas + 'smtpserver') = 'smtp.example.com';
mail.Configuration.Fields.Item(schemas + 'smtpserverport') = '25';
mail.Configuration.Fields.Update();
mail.Send();
こんな感じ。基本的にはメールの送信に必要な項目を入れていくだけです。
Toなどは、カンマ区切りで複数のアドレスを指定できます。sendusingが2だと外部のSMTPサーバを使う設定なんだそうです。あとは、まあ分りますよね。
「schemas」という変数にURIらしきものを入れていますが、これは名前空間の指定。パラメータ名が短いと、他の何かと重複してしまうかも知れないので、こうやって長い名前にしてるんだそうです。別にこのURIに対して接続したりするわけではないのでご安心を。そして、あまりに長い名前なので私はschemasという変数に入れましたが、こうしなきゃいけないわけではありません。
以下のいろんな説明は、全てこの基本形の中に追加していくことになります。
ファイルを添付することもできます。
mail.AddAttachment('c:\\files\\hoge.zip');
mail.AddAttachment('c:\\files\\fuga.zip');
こんな感じでフルパスをAddAttachmentすれば、いくつでもファイルを添付できます。簡単ですね。
GmailなどはSMTP認証も必要としてる。つまりユーザ名とパスワードで認証しないとSMTPサーバが利用できないのです。CDOではこれにも対応できます。
mail.Configuration.Fields.Item(schemas + 'smtpauthenticate') = true; mail.Configuration.Fields.Item(schemas + 'sendusername') = 'username'; mail.Configuration.Fields.Item(schemas + 'sendpassword') = 'p@ssw0rd';
こんな感じ。まあ見ればわかりますよね。trueにしてユーザ名とパスワードを入れる。
SMTP認証を必要とする場合、パスワードをやりとりするわけですから、SSLを適用して通信を保護するのが一般的。例えばGmailでも導入されています。
mail.Configuration.Fields.Item(schemas + 'smtpusessl') = true;
これだけ。簡単。
X-Mailerというメールヘッダがあって、一般にここにはメールソフトの名前が入ります。
デフォルトだと「Microsoft CDO for Windows 2000」となりますが、これを自由に変更することができます。
mail.Fields.Item('urn:schemas:mailheader:X-Mailer') = 'sample mailer';
mail.Fields.Update();
今まで出てきたConfiguration.Fieldsではないので注意。そして設定を変更した場合は、メール送信前に Update() を呼ぶのをお忘れ無く。
SMTPサーバが無関係の人に利用されるのを防ぐため、POPで認証したIPアドレスに対して一定時間(20分間など)だけSMTPの通信を許可する仕組みがあります。これがPOP before SMTP。本来はSMTP認証を使うのが望ましいと思いますが、SMTP認証に対応していないメールソフトもあるため、こっちの方が広まってる気がします。
しかし、これはどうしても無理でした。CDOはあくまでSMTPクライアントなので、POP接続はできません。POP before SMTPを採用しているSMTPサーバを使ってWSHだけでメール送信したい場合、CDOとは別なメールコンポーネントを併用する必要があります。
とりあえず、一番有名だと思うBASP21を使った例を載せておきます。
var basp21 = new ActiveXObject('basp21');
var result = basp21.RcvMail(
'pop.example.com' + '\t' + '110',
'username',
'p@ssw0rd',
'STAT',
'c:\\'
);
basp21オブジェクトを生成して、RcvMailメソッドを呼びます。
最初の引数は、POPサーバ名とポート番号をTAB文字で区切ったもの。次がPOPのユーザ名、次がPOPのパスワード。ここまではわかると思います。
その次のSTATというのは、POPサーバ上のメール数を取得するときのコマンド名です。今回はPOP before SMTPが目的であり、実際にメールを受信する必要はないため、このコマンドを使いました。
最後の引数はメールを保存するフォルダ名ですが、今回はメールを受信するわけではないので、実在する適当なフォルダを指定しておけば良い。
この処理をメール送信よりも前にやっておくことで、POP before SMTPのサーバでもメールが送信できます。
当然、これを動かすにはBASP21がPCにインストールされている必要があります。
これらを使えばメール送信でやりたいことは大抵できると思います。
欲を言えば、BASP21のような別途インストールが必要なコンポーネントは避けたかった。
ActiveScriptRubyやActivePerlを入れた環境で、RubyやPerlでWSHを書けば、POPアクセスのライブラリが利用できるのでいいかも知れません。まあそれだとCDOの出番もなくなりますけど。