MAGAZINE

ルーターマガジン

RPA

普段使いのGmailアカウントで一括メール送信するRubyスクリプト

2023.10.03
Pocket

セミナーなどを開いた後には「ありがとうございましたメール」を送るケースがあります。

弊社では以前はSendGridなどのメール送信APIを使っておりましたが、この手のメール送信APIはIPアドレス単位でブロックされるケースがあります。特にOutlookのメールサーバーは公開のIPアドレスブラックリストを使っており、IPアドレス単位でブロックされると迷惑メールフォルダにさえ入りません。「Outlook Spamhaus」で検索するとトラブル事例が多くでてきます。

またメール送信APIを使った場合には、普段のメールサーバーではないIPアドレスからメールを送っているけどなりすましではないですよということを示すためのSPFレコードをDNSに追加登録する必要があり、ひと手間かかります。そして忘れられがちです。運用ミスのポイントが一つ増えます。ここをミスると「迷惑メールフォルダに入りがち」という点でうまくいってるようにみえるケースもあってテストしづらいです。

回避策としてはBCCで一括メール送信するなどの方法もありますが、本文の変数差し込みができません。

Rubyを始めとするスクリプト言語の大半はメール送信のライブラリがあるのでそれを使ってみましょう。

サンプルソース

以下サンプルソースです。次のようなファイル構成です。

  • csv_mail.rb
    • 送信スクリプト本体です
  • template.erb
    • メール本文とタイトルのテンプレートです
  • meibo.csv
    • 送信先の名簿です
  • .bash_profile
    • 環境変数を設定します(環境変数が設定できればどのファイルでもいいです)

csv_mail.rb

#! /usr/bin/env ruby
require 'mail'
require 'csv'
require 'erb'

# 以下にGmailのアプリパスワードを設定 https://accounts.google.com/IssuedAuthSubTokens?hide_authsub=1
mail_passwd = ENV['GMAIL_PASS']
mail_account = ENV['GMAIL_ACCOUNT']
mail_from = ENV['GMAIL_FROM']

Mail.defaults do
  delivery_method :smtp, {
    address: 'smtp.gmail.com',
    port: 587,
    domain: 'example.com',
    user_name: mail_account,
    password: mail_passwd,
    authentication: :login,
    enable_starttls_auto: true
  }
end

def send_mail(mail_to,mail_from,mail_subject,mail_body)
  m = Mail.new do
    from     mail_from
    to       mail_to
    subject  mail_subject
    body     mail_body
  end
  m.charset = 'UTF-8'
  m.content_transfer_encoding = '8bit'
  m.deliver
end

# main

CSV.foreach(ARGV[0], headers: true) do |row|
  print('.')
  @r = row
  erb = ERB.new(File.read(ARGV[1])) # ERBテンプレートを読み込み
  mail_subject, mail_body = erb.result.split("\n", 2) # テンプレートの先頭行をSUBJECTに
  mail_to = row['mail']
  send_mail(mail_to, mail_from, mail_subject, mail_body)
end

template.erb

【株式会社ルーター】XX FORUMご参加のお礼
<%=@r['company']%> <%=@r['division']%>
<%=@r['post']%> <%=@r['name']%> 様

お世話になっております
ルーターの山本です。

XX Forumに出展していた株式会社ルーターです。
http://rooter.jp/
社内外のビッグデータ(オープンデータ)の収集、データ活用に関して
ニーズがあればお気軽にご相談下さい。
御社と今後何かご一緒できれば幸いです。

よろしくお願い致します

-- 
株式会社ルーター 取締役 CTO
山本有悟
〒151-0053 東京都渋谷区代々木4丁目28−8
代々木村田マンション 303

meibo.csv

mail,name,company,division,post
yugo.yamamoto@example.com,山本ゆうご,株式会社山本商店,社長室,CEO
yugo_yamamoto@example.com,山本ゆうご2,株式会社山本商店2,部署名2,CEO2

.bash_profile(環境変数が設定できればどこでもOK)

...
export GMAIL_PASS=xxx
export GMAIL_ACCOUNT=yugo.yamamoto@example.com
export GMAIL_FROM="株式会社ルーター 山本有悟 <yugo.yamamoto@example.com>"

実行方法

$ ruby csv_mail.rb meibo_test.csv tamplate.erb

これで身内にテストメールを送って大丈夫そうなら、名簿のCSVだけを差し替えて再度実行。

$ ruby csv_mail.rb meibo_honban.csv tamplate.erb

解説

メール送信認証に関して

GmailやGoogleWorksSpaceのメール機能には「アプリケーションパスワード」という概念があります。GoogleのAPIは基本はパスワード認証などは使わないのですが、メール送信だけはFAX機器のようなものであっても組み込まざるを得ないので、一部に別パスワードを発行することができます。用が済んだら削除するのがアプリケーションパスワードの運用方法です。

またメール送信APIを使ってるのではなく、本当のGmailも送信を使っているので送信済みフォルダにすべて残ります。

テンプレートに関して

Rubyの場合はRailsでもよくみられるerbテンプレートがメジャーです。Rails上でなくても単体でも使えます。 <%=変数%> で変数が埋め込めます

CSVに関して

Rubyに限らず多くの言語のCSVモジュールはCSVの一行目をフィールド名といて、各行をハッシュとして展開してくれる機能があります。CSVの一行目をハッシュのキーにしておくと、テンプレート上でも同じ名前でアクセスできるので揃えておくと便利です。

この方式の制約

Gmail送信なので一日に送れる件数に上限があります。またGmail送信と同じくらいのスピード感で送信します。1件あたり1秒以上かかります。

Pocket

CONTACT

お問い合わせ・ご依頼はこちらから