Rails ActionMailer - format nama pengirim dan penerima / alamat email

112

Apakah ada cara untuk menentukan email DAN nama untuk pengirim dan penerima info saat menggunakan ActionMailer?

Biasanya Anda akan melakukan:

@recipients   = "#{user.email}"
@from         = "[email protected]"
@subject      = "Hi"
@content_type = "text/html"

Tapi, saya ingin menentukan nama seperti baik MyCompany <[email protected]>, John Doe <john.doe@mycompany>.

Apakah ada cara untuk melakukannya?

Grnbeagle
sumber
Panduan Rails memiliki contoh bagaimana melakukan ini: Guideline.rubyonrails.org/… juga lihat jawaban lain dalam pertanyaan ini stackoverflow.com/a/8106387/879854
BF4

Jawaban:

237

Jika Anda mengambil masukan pengguna untuk nama dan email, maka kecuali Anda dengan sangat hati-hati memvalidasi atau melepaskan nama dan email, Anda dapat berakhir dengan tajuk Dari yang tidak valid hanya dengan menggabungkan string. Inilah cara yang aman:

require 'mail'
address = Mail::Address.new email # ex: "[email protected]"
address.display_name = name.dup   # ex: "John Doe"
# Set the From or Reply-To header to the following:
address.format # returns "John Doe <[email protected]>"
James McKinney
sumber
1
Terima kasih banyak! Saya pikir ada cara yang lebih baik daripada string concat, tetapi penggunaannya Mail::Addresstidak jelas dalam dokumentasi mana pun yang saya baca.
Tim Morgan
10
address.display_nametampaknya mengubah pengkodean string dalam beberapa kasus, jadi jika Anda berencana untuk menggunakan namenanti, misalnya di tampilan mailer rails, lakukanaddress.display_name = name.dup
Eero
7
Sepertinya permata Mail sekarang menipu string yang diteruskan, jadi name.dupsepertinya tidak diperlukan lagi. Sumber berbunyi:@display_name = str.nil? ? nil : str.dup
philoye
Ini bahkan bekerja di config.mailer_sender = Proc.new { address = Mail::Address.new... }
Rancang
97
@recipients   = "\"#{user.name}\" <#{user.email}>"
@from         = "\"MyCompany\" <[email protected]>"
Eduardo Scoz
sumber
2
Saya rasa tidak. Tidak boleh berisi karakter non-ASCII untuk satu karakter, tidak boleh berisi karakter kutipan itu sendiri, dan ada beberapa karakter ASCII yang tidak diizinkan / juga tidak direkomendasikan di header. Saya menemukan bahwa RFC2047 menyediakan mekanisme untuk pengkodean base64 nilai-nilai tersebut.
William Denniss
11
lihat jawaban saya untuk cara melakukan ini yang mengkodekan string dengan benar.
James McKinney
8
Ini sangat membantu! FYI, jika Anda mencoba untuk menguji ini, Anda harus melihat @ email.header ['From']. To_s, bukan @ email.from. Yang terakhir hanya berisi alamat email dan bukan namanya.
sbleon
7
Jangan lakukan dengan cara ini. Lihat jawaban @ JamesMcKinney sebagai gantinya.
Matthew Ratzloff
5
Sekali lagi, jangan gunakan ini karena tidak aman. Lihat jawaban @ JamesMcKinney sebagai gantinya.
Jake Petroules
43

Di rails3 saya menempatkan yang berikut ini di setiap lingkungan. yaitu production.rb

ActionMailer::Base.default :from => "Company Name <[email protected]>"

Menempatkan kutipan di sekitar nama perusahaan tidak berhasil untuk saya di Rails3.

astjohn
sumber
Anda juga dapat meletakkannya langsung di file mailer.rb Anda seperti ini :from => "Company Name <[email protected]>"jika Anda tidak memiliki batasan lingkungan.
Puce
8

dalam Rails 2.3.3 bug di dalam ActionMailer telah diperkenalkan. Anda dapat melihat tiketnya di sini Tiket # 2340 . Ini diselesaikan dalam 2-3-stable dan master sehingga akan diperbaiki dalam 3.x dan 2.3.6.

Untuk memperbaiki masalah dalam 2.3. * Anda dapat menggunakan kode yang disediakan dalam komentar tiket:

module ActionMailer
  class Base
    def perform_delivery_smtp(mail)
      destinations = mail.destinations
      mail.ready_to_send
      sender = (mail['return-path'] && mail['return-path'].spec) || Array(mail.from).first

      smtp = Net::SMTP.new(smtp_settings[:address], smtp_settings[:port])
      smtp.enable_starttls_auto if smtp_settings[:enable_starttls_auto] && smtp.respond_to?(:enable_starttls_auto)
      smtp.start(smtp_settings[:domain], smtp_settings[:user_name], smtp_settings[:password],
                 smtp_settings[:authentication]) do |smtp|
        smtp.sendmail(mail.encoded, sender, destinations)
      end
    end
  end
end
anka
sumber
2
Untuk siapa saja yang memiliki pertanyaan saya, "di mana saya meletakkan kode ini?" jawabannya adalah menyimpannya sebagai file .rb di direktori [rails app root] / config / initializers Anda.
JellicleCat
6

Versi yang saya suka gunakan ini adalah

%`"#{account.full_name}" <#{account.email}>`

`<< adalah backtick.

Memperbarui

Anda juga bisa mengubahnya menjadi

%|"#{account.full_name}" <#{account.email}>|
%\"#{account.full_name}" <#{account.email}>\
%^"#{account.full_name}" <#{account.email}>^
%["#{account.full_name}" <#{account.email}>]

Baca lebih lanjut tentang string literal.

Marc
sumber
1

Aspek lain yang menjengkelkan, setidaknya dengan format AR baru, adalah mengingat bahwa 'default' dipanggil di tingkat kelas. Merujuk rutinitas yang hanya instance menyebabkannya gagal secara diam-diam dan menyerah saat Anda mencoba menggunakannya:

 NoMethodError: undefined method `new_post' for Notifier:Class

Inilah yang akhirnya saya gunakan:

def self.named_email(name,email) "\"#{name}\" <#{email}>" end
default :from => named_email(user.name, user.email)
Kevin
sumber