English Korean Chinese

RubyでCGI・入門編

今野 滋

UNIXコマンドを実行する(メール送信)

ページ毎に読者に感想を書いてもらったり、掲示板に投稿があったことをケータイに知らせたりする等々、メール送信機能はいろいろ重宝します。 ここでは、サーバーに用意されている rmail コマンドを使ってメールを発信する方法を紹介します。

注意: rmail コマンドを悪用・誤用しないでください。
◆ 発信元を偽装してはいけません(とくにFrom:欄)。発信の記録が残りますので、事件が起きた際には必ずバレます。
◆ スパム行為(=予め同意を得てはいない相手多数に広告等をばらまくこと)は絶対にしてはいけません。 商用に関しては当然厳禁ですが、「神のお告げ」などもご遠慮ください。
◆ 連続で送信するのは、最大20件程度までにしてください。(プログラムの作りようによっては、10件程以上連続で発信すると、あふれてエラーが発生します。)過去、大量発信をしようとしてサーバーに障害を与え、処罰された学生がいるそうです。
◆ 宛先につき、なるべく自分宛の用途に限定してください。 他人宛のメールを出すことを可能にして、それを悪用された場合は、理由の如何を問わず、そのサイトを管理している人(あなた)の責任となります。

このセクションでの、技術的なポイントは、以下の2点となります

ステップ1: rmail コマンドを使ってみよう

Terminal を立ち上げログインし、以下のコマンドを打ってください。
x040999x の部分には、自分のユーザーIDを書いてください。これは送信先のメールアドレスで、@ec.hokudai.ac.jp が省略されています。

rmail x040999x

続けて、メールの中身を書きます。メールはヘッダと本文から構成され、ヘッダと本文の区切りとして、空行が入ります。

Subject: TestMail01

This is a test mail.

コピーして貼付けたら、ctrl+d (ctrlキーを押しながら、dキーを押す)。これでメールが自分宛に送信されました。受信して確かめてみてください。

次に、自分のケータイに出してみましょう。再び以下のコマンドを打ちます。 hoge@docomo.co.test の部分には自分のアドレスを書いてください。 アドレスを書き間違えるといけないので、一度ケータイから学校のアドレス宛にメールを送信して、そこに表示されたアドレスをコピーする等すると確実です。

rmail hoge@docomo.co.test

続けて、メールの中身を書きます。今度は発信元アドレスも明記しましょう。(コピーして貼付ける場合は、hoge@docomo.co.testを予め自分のアドレスに書き直すこと。)

Subject: TestMail02
From: hoge@docomo.co.test

This is a test mail.

ctrl+dします。これでメールが自分のケータイ宛に送信されました。受信して確かめてみてください。

届いたメールに返信すると、From:欄に記入したアドレスに宛ててメールが届きます。

なお、このやり方で、日本語のメッセージを送ることはできません。文字化けしてしまいます。

ステップ2:Rubyを使って発信を自動化しよう

下記をコピーしてTerapadに貼付け、x040999xを送り先のアドレス(自分のユーザーID又は、自分の携帯電話のアドレス)に書き換え、改行コードLFにて保存。ファイル名は例えばtestmail.rbとします。

#!/usr/local/bin/ruby
m = open("|rmail x040999x", "w+")
m.print <<EOF
Subject: TestMail03

This is a test mail powered by ruby.
EOF
m.close_read

このtestmail.rbを、FTPにて、workの中にコピーします。

Terminalを立ち上げてログインし、以下のコマンドを入力します。

cd work
chmod 700 testmail.rb
ls -al

testmail.rbが確かに存在して、パーミッションが-rwx------になっていることを確認したら、さらに続けて、

./testmail.rb

enter↵を押した段階で、メールが送信されます。発信に時間がかかる場合があるので、すぐにはログアウトしないで、そのまま少なくとも10秒ぐらい待ってください。少し間を置いてからメールを受信して届いているかどうか確かめてください。

日本語の扱いについて

日本で電子メールに使われている文字コードは古い順に、JIS, Shift_JIS, UTF-8 があります。UTF-8 は、世界中の文字が統一されたコードで表されるユニコードですが、残念ながらこの用途ではまだ普及していません。Shift_JIS は主に携帯電話のメールで使われています。そして、パソコン等でやり取りされている電子メールのほとんどには、いまだにJIS(iso-2022-jp)が使われています。これは、メッセージがレガシーなインフラを経由したときに壊れない様にするためです。つまり、信頼できます。その反面、半角カタカナが使えない等の不便さがあります。

携帯電話で Shift_JIS を使っていますが、「半角カタカナ」の扱いには注意が必要です。この中には、半角の空白(「直接入力」の空白とはコードが違う)と、半角の ©, …, ™ が含まれていますが、化ける可能性が高いので使えません。半角で使える日本語文字はカタカナに限られます。ケータイ各社が独自に用意した絵文字についても、互いに相当する絵文字同士でコード(番号)がバラバラなので、その都度翻訳して使う必要があります。

Subject(件名)に関しては、日本語は使えません。もし日本語の文字コードを使った場合は、メールソフトが解釈を試みますが、多くの場合は文字化けしてしまいます。対策としては、いったん半角英数[a-zA-Z0-9+/=]に翻訳(=base64エンコード)してしまいます。たとえば、「こんにちは」は、「GyRCJDMkcyRLJEEkTxsoQg==」になります。

#!ruby -Ks
puts ["こんにちは"].pack("m").chomp
puts "grGC8YLJgr+CzQ==".unpack("m").join

ステップ3:文字コードの変換

Kconv と呼ばれる道具を使って、Shift_JIS → JIS の変換をやります。例えば、本文に半角カタカナが使われていたら、この変換はやらないことにします。例えば、件名に半角カタカナが使われていたら、送信しないことにします。以上の仕様で、サンプルを用意しました。⇒ダウンロード

ダウンロードしたら、送信先と発信元のアドレスを自分のに書き換えてください。先ほどと同様に、FTPでアップロードし、Treminalにてモード変更、送信し、各自メールソフトにて受信を確かめてください。

chmod 700 testmail.rb
./testmail.rb

ステップ4:CGIとして使う

今度はCGIに送信プログラムを生かしてみてください。送信用フォームのページの文字コードは Shift_JIS にしください。フォームを含んだページは、Nvuを使うと簡単に作れます。送信者がいろいろなミスをすることを想定して、使いやすいプログラムにしてください。

添付書類を含んだメールを送信することも可能です。メールファイルの書式を調べてトライしてみてください。最初は添付書類なし。次に文面を変えずに、添付書類ありで試してみてください。調べかたは、

  1. OutlookExpress等のメールソフトで、センターに接続し、メッセージ振り分け先のフォルダーを一個作ります。ここに、仮にフォルダー名をhogehogeとします。(名前に日本語や記号の使用不可)
  2. わかりやすい単純な(できれば日本語は使わない)メッセージを自分宛に送信し、受信して、先ほど作ったフォルダーに移します。
  3. Terminalログインし、ファイルの中身を覗いてみます。
  4. cd .imap
    more hogehoge
    
  5. ついでだから、ファイルを取り出してみましょう。FTPでも見ることができる場所にコピーします。
  6. cp hogehoge ../
    
  7. FTP接続すると、ファイルhogehogeがあるので、ダウンロードします。ダウンロードが済んだらhogehogeは消去しておきます。
  8. これでいつでも参照できます。本文に日本語が書かれたメッセージも、文字コードjisで開くと、読むことができます。
  9. この受信ファイルは、送信時に送り出された内容に対してヘッダの上下にいろいろ付け加わった状態になっています。 おそらくは、Message-Id: の行よりも下、Status: の行よりも上の部分が、送信時に送り出された内容です。
  10. 例えば、添付書類付きのメールはこんな感じで送れます。サンプルをお試しください。まず、中身を開いて確認し、x090999x(3カ所あります)を自分のユーザーIDに書き直してください。例によって、FTP転送して、Terminalにて呪文。そして、メールを受信します。testfile.txtという名前のファイルが内容「This is a test file. 」にて添付されているはずです。⇒サンプル
  11. 上記サンプルの中に出てくる「VGhpcyBpcyBhIHRlc3QgZmlsZS4K」はファイルの内容をbase64エンコーディング(=直接入力モードでの[a-zA-Z0-9+/=]の65文字での表現に翻訳)したもので、
    [ "This is a test file.\n" ].pack('m').chomp
    として得られます。 ⇒詳細:packテンプレート文字列・m
    最後の .chomp は末尾に現れる改行コードを削除するためにつけてあります。
    なお、文字列を配列に格納させるためには .split(//,1) を使うと便利です。

更新日:2005年01月

© 2004-2005 S.Konno, all rights reserved. [ 質問 ] [ TOP ] [ J2J ] [<<戻る ] [ 目次 ]