Rubyを使ってCSV/TSVファイルからGmail経由でメールを一括送信する方法

English version is available.

ひょんなことから
・Excelファイルに入っている名簿データを
・メールテンプレート化して
・Gmail経由で一括送信する
ということがやりたくなったので,その時のコードを晒します.

動作環境はRuby 1.8.7 + ActionMailer 3.0.3 + fastercsv 1.5.4 + tlsmail 0.0.1です.


Gemのインストール

まずは必要なGemをインストールします.

$ gem install rails
$ gem install fastercsv
$ gem install tlsmail

名簿データの作成
次に,メール元になる名簿データをExcelからTSV形式で出力します.「ファイル名を指定して保存」からデータ形式を「タブ区切りテキスト」にして保存すればOKです.
CSVではなくTSVなのは,経験上CSVよりTSVの方が読み込み時のトラブルが少ないからです.

更に,Excelから出力したままだと文字コードがShift-JIS(CP932とかSJIS-WINと言われるもの)になっているので,UTF-8に変換します.

$ brew install nkf

でnkf(Nihongo Kanji Filter)をインストールして,

$ nkf -w data.tsv > data-utf8.tsv

とすればOKです.Homebrewのインストールはこちらの記事を参照して下さい.

プログラム

以下がソースコードです.send_email.rbとか適当な名前で保存して下さい.後述しますが一部を自分の環境に合わせて変更して下さい.

# encoding: UTF-8
require 'rubygems'
require 'action_mailer'
require 'fastercsv'

# for Gmail SMTP
require 'tlsmail'
if ARGV.count != 2
  puts "usage: ruby send_email.rb [Gmail Account] [Gmail Password] < TSV"
  exit -1
end

Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.smtp_settings = {
   :enable_starttls_auto => true,
   :address        => 'smtp.gmail.com',
   :port           => 587,
   :domain         => 'gmail.com',
   :authentication => :plain,
   :user_name      => ARGV[0],
   :password       => ARGV[1]
}

class CustomMailer < ActionMailer::Base
    def createMessage(toAddress, mySubject, myBody)
        from 'your_email_address@your_domain.com'
        recipients toAddress
        subject mySubject
        body myBody
    end
end

FasterCSV.parse(
  STDIN.read(100000000).to_s,
  :col_sep => "\t",
  :headers => %w(email name a b c d e f g your file format here)
) do |h|
  to = h['email']
  body =<<EOS
#{h['name']} 様

ほげほげ

メール本文をなんか色々書きます.TSVのパラメータは#{h['header_name']}で取得できます.

-- 
署名とか

EOS
  puts to
  puts body
  CustomMailer.createMessage([to, "your_email_address@your_domain.com"], "メールタイトル #{h['name']}様", body).deliver
end

ハイライト表示した部分を自分用に修正して下さい.

29行目はメールのFromヘッダに設定されるメールアドレスになります.送信するGmailアカウントとは別のアドレスを使う場合,GmailでそのFromアドレスを使える設定にしておく必要があります.設定方法はこの辺りを参考にして下さい

39行目の:headersは#w()の括弧内に,TSVファイルに入っているフィールドを表すkey文字列をスペース区切りで入れていきます.例えば,元データが

hoge@example.com ほげ
huga@example.com ふが
foo@example.com  ふー

みたいに「メールアドレス,名前」の形式になっていれば,

  :headers => %w(email name)

とすることで,その後h[’email’]やh[‘name’]で参照できます.

43〜51行目は,送信するメールの本文を書きます.

55行目では,第一引数の配列に複数の文字列を指定することで,To欄に複数のメールアドレスをセットできます.第二引数はメールのサブジェクトです.

メール送信方法

ここまで設定すれば,あとは

$ ruby send_email.rb 'GMAIL_ACCOUNT@gmail.com' 'PASSWORD' < data-utf8.tsv

でごりごり送信されます.

Gmailのメールサーバは応答が遅いので,大体10通で1分くらいかかると見ておいたほうが良いです.
また,このプログラムで送信した場合,メール本文はUTF-8でエンコードされるので,ガラケーなんかだと文字化けするかもしれませんので,その辺は注意して下さい.

以上,使い捨てプログラムの紹介でした.

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

morimorihoge

高校卒業後,学生をやりながらずっとWebアプリ開発に携わってきました.2010くらいまではPHP/Symfonyプログラマでしたが,それ以降のWeb開発はRailsほぼ一本に宗旨替えしました.開発とは別にサーバ構築・運用も10年以上やってきているので,要件定義から設計・実装・環境構築・運用まで一通り何でもこなせます.開発以外では季節により大学でWebサービス開発やプログラミング関連の非常勤講師もしており,技術の啓蒙・教育にも積極的に関わっています.最近はPM的な仕事が増えていますが,現役開発者としていつでも動ける程度にはコードもサーバも弄る日々を送っています.AWS 認定ソリューションアーキテクト – アソシエイトレベル取りました

morimorihogeの書いた記事

開発
RubyのArray(配列)の使い方

2017年03月15日

週刊Railsウォッチ

インフラ

Rubyスタイルガイドを読む

BigBinary記事より

ActiveSupport探訪シリーズ