Landscape トップページ | < 前の日 2004-10-08 2004-10-09 次の日 2004-10-10 >

Landscape - エンジニアのメモ 2004-10-09

添付ファイル付メールを送信する Ruby スクリプト


* 添付ファイル付メールを送信する Ruby スクリプト

この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [メール] [Ruby]

コマンドラインから添付ファイル付きメールを送信する Ruby スクリプト samail を作成した。Send Attachment MAIL の略で、samail。読み方は「さめいる」または「えすえーめいる」かなあ。

2003-12-12 の「添付ファイル付きメールをコマンドラインから送信」や 2004-07-02 の「添付ファイル付メールを送信する Perl/Rubyスクリプト」 でもいろいろ書いたけど、Ruby 1.8 が使えるなら今回書いたスクリプトの方がカスタマイズはしやすい。

- samail の概要

コマンドラインで動作する、SMTP を利用したメール送信プログラム。
Ruby 1.8 の標準ライブラリしか使っていないため、Ruby さえインストールしてあれば動作する。

- samail の機能

添付ファイルを好きな数だけ指定して送信できる。
To, From, Subject を指定可能。To には複数のアドレスを指定可能。
Cc と Bcc には未対応。
SMTP サーバが必要。ローカルの MDA を呼び出す機能は未実装。
SMTP 失敗時には自動的にリトライする。初期設定では3回までリトライ。

- samail の動作確認環境

ruby 1.8.1 (2003-12-25) [i586-linux]
ruby 1.8.1 (2003-12-25) [i386-cygwin]

- samil のインストール

後述する samail ソースをコピー & ペーストして、samail というファイル名を付けてパスの通ったディレクトリに保存。
ファイルの文字コードは ASCII しか使ってないので何でも良い。改行コードは LF が良い。
chmod 744 などどして、ファイル samail に実行権限を付与。
以上で完了。

- samail の使い方と動作例

以下のようにコマンドラインから必要なオプションを渡す。
to や attachment には複数の値を指定できる。その場合、ダブルクオートかシングルクオートで値をくくり、それぞれの値はカンマかスペースで区切る。

$ samail -v --to "sonic64@infoseek.jp example@example.com" --from sonic64@infoseek.jp --smtp smtp.example.com --attachment "logo.png /tmp/backup.tar.bz2"

-v オプションを指定していると、標準出力に To, From, 添付ファイルのパス, subject, 使用する SMTP サーバ名を表示する。"Try to connect ..." はメール本文の生成が完了し、SMTP サーバに接続しようとした時点で表示する。Send OK は SMTP サーバへの送信を完了したときに表示する。

To: sonic64@infoseek.jp, example@example.com
From: sonic64@infoseek.jp
Attachment file: logo.png, /tmp/backup.tar.bz2
Subject: Landscape Mailsender Sat, 09 Oct 2004 20:35:34 +0900]
SMTP Server: smtp.example.com
Try to connect smtp.example.com
Send OK

samail は X-Mailer などで Landscape Mailsender を名乗る。

- ライセンス

何が良いんだろう? とりあえず GPL2 と BSD のデュアルライセンスにしておけばいいのかな。

- samail ソース

#!/usr/local/bin/ruby

# Copyright (C) 2004 Saito Hiroaki <sonic64@infoseek.jp>
# http://sonic64.com/

require 'kconv'
require 'net/smtp'
require 'getopts'

def setup()
  $APPLICATION_NAME = 'Landscape Mailsender'
  $VERSION = '0.3'
  $BANNER_STRING = $APPLICATION_NAME + ' ' + $VERSION
  $X_MAILER_WEBSITE = "http://sonic64.com/2004-10-09.html"

  $smtp_server = $OPT_smtp? $OPT_smtp : 'localhost'
  $mail_from = $OPT_from ? $OPT_from : ENV['USER'] + '@' + ENV['HOSTNAME']
  $mail_to = $OPT_to.split(/,\s*|\s+/)
  $mail_subject = $OPT_subject ? $OPT_subject : $APPLICATION_NAME + ' [' + Time::now.strftime("%a, %d %b %Y %X %z") + ']'

  $mail_content = ''
  $boundary = 'boundary_string_by_landscape_mail'
  $attachment_file = $OPT_attachment ? $OPT_attachment.split(/,\s*|\s+/) : []
  $smtp_retry = 3

  if ($OPT_v) then
    puts 'To: ' + $mail_to.join(', ')
    puts 'From: ' + $mail_from
    puts 'Attachment file: ' + $attachment_file.join(", ")
    puts 'Subject: ' + $mail_subject
    puts 'SMTP Server: ' + $smtp_server
  end
end


def build_mail_header()
  $mail_content << 'Date: ' + Time::now.strftime("%a, %d %b %Y %X %z") + "\n"
  $mail_content << 'From: ' + $mail_from + "\n"
  $mail_content << 'To: ' + $mail_to.join(', ') + "\n"
  $mail_content << 'Subject: ' + $mail_subject + "\n"
  $mail_content << "MIME-Version: 1.0\n"
  $mail_content << 'Content-Type: multipart/mixed; boundary="' + $boundary  + "\"\n"
  $mail_content << 'X-Mailer: ' + $BANNER_STRING + "\n"
  $mail_content << 'X-Mailer-WebSite: ' + $X_MAILER_WEBSITE + "\n"
  $mail_content << "\n"
end


def add_attchment(file_name)
  if file_name == '' then
    return
  end

  attachment_file = File.open(file_name).readlines.join('')
  encoded_attachment = [attachment_file].pack('m')
  $mail_content <<  '--' + $boundary + "\n"
  $mail_content << "Content-Type: application/octet-stream;\n"
  $mail_content << ' name="' + File.basename(file_name) + '"' + "\n"
  $mail_content << 'Content-Transfer-Encoding: base64' + "\n"
  $mail_content << "Content-Disposition: attachment;\n"
  $mail_content << ' filename="' + File.basename(file_name) + "\"\n\n"
  $mail_content << encoded_attachment + "\n"
end

def send_mail(retry_count)
  begin
    puts "Try to connect " + $smtp_server if $OPT_v
    Net::SMTP.start($smtp_server) do |smtp|
      smtp.sendmail($mail_content, $mail_from, $mail_to)
    end
    puts 'Send OK' if $OPT_v
  rescue
    puts 'smtp error occurred'
    if retry_count  != 0 then
      retry_count  -= 1
      send_mail(retry_count)
    else
      puts 'abort: Over retry count'
      raise
    end
  end
end


# main
unless getopts('v', 'from:', 'to:', 'subject:', 'attachment:', 'smtp:')
  abort "usage: #$0 [-v] --to TO_EMAIL_ADDRESS [--from FROM_EMAIL_ADDRESS] [--smtp SMTP_SERVER] [--attachment ATTACHMENT_FILE]"
end

setup()
build_mail_header()
$mail_content <<  '--' + $boundary + "\n"
$mail_content << "Content-Type: text/plain; charset=iso-2022-jp\n"
$mail_content << "Content-Transfer-Encoding: 7bit\n"
$mail_content << "\n"
$mail_content << "-- \n"
$mail_content << 'Powered by ' + $BANNER_STRING + "\n"
$mail_content <<  $X_MAILER_WEBSITE + "\n"
$mail_content << "\n"

$attachment_file.each do |file|
  add_attchment(file)
end

$mail_content <<  '--' + $boundary + "--\n"
send_mail($smtp_retry)

- 参考にしたもの

TMail
http://www.loveruby.net/ja/prog/tmail.html

vCard ファイルを添付したメールを作る
http://namazu.org/~satoru/attic/vcardmail.rb

SSTP Bottle メール送信クライアント
http://www.tenchi.ne.jp/~yoko/haruna/

- 2004年11月1日追記 2004-11-01 に samail 0.4 について書いた。



すべての記事の見出し (全1029件)
全カテゴリの一覧と記事の数
カテゴリごとに記事をまとめ読みできます。記事の表題だけを見たい場合は、すべての記事の見出し (カテゴリ別表示) へ。

直近30日分の記事
2007-04-23 (Mon)
2007-03-07 (Wed)
2007-02-27 (Tue)
2007-01-17 (Wed)
2007-01-15 (Mon)
2007-01-14 (Sun)
2007-01-08 (Mon)
2006-12-01 (Fri)
2006-11-22 (Wed)
2006-11-20 (Mon)
2006-11-19 (Sun)
2006-09-30 (Sat)
2006-08-29 (Tue)
2006-08-04 (Fri)
2006-07-27 (Thu)
2006-07-23 (Sun)
2006-07-17 (Mon)
2006-07-10 (Mon)
2006-07-06 (Thu)
2006-07-03 (Mon)
2006-06-29 (Thu)
2006-06-28 (Wed)
2006-06-27 (Tue)
2006-06-25 (Sun)
2006-06-19 (Mon)
2006-06-18 (Sun)
2006-06-15 (Thu)
2006-06-11 (Sun)
2006-06-01 (Thu)
2006-05-30 (Tue)
プロファイル
斎藤 宏明。エンジニアです。宇都宮市に住んでいます。
リンク
RSS
スポンサードリンク
Powered by
さくらインターネット

© 斎藤 宏明 Saito Hiroaki Gmail Address
Landscape - エンジニアのメモ http://sonic64.com/
Landscape はランドスケープと読みます。
ひらがなだと らんどすけーぷ です。