Rails ActionMailer - định dạng tên người gửi và người nhận / địa chỉ email


112

Có cách nào để chỉ định email VÀ tên cho thông tin người gửi và người nhận khi sử dụng ActionMailer không?

Thông thường bạn sẽ làm:

@recipients   = "#{user.email}"
@from         = "info@mycompany.com"
@subject      = "Hi"
@content_type = "text/html"

Nhưng, tôi muốn xác định tên như well-- MyCompany <info@mycompany.com>, John Doe <john.doe@mycompany>.

Có cách nào làm được việc này không?


Hướng dẫn Rails có một ví dụ về cách thực hiện việc này: Guide.rubyonrails.org/… cũng xem một câu trả lời khác trong câu hỏi này stackoverflow.com/a/8106387/879854
BF4

Câu trả lời:


237

Nếu bạn đang sử dụng đầu vào của người dùng cho tên và email, thì trừ khi bạn xác thực rất cẩn thận hoặc loại bỏ tên và email, bạn có thể nhận được tiêu đề Từ không hợp lệ bằng cách chỉ cần nối các chuỗi. Đây là một cách an toàn:

require 'mail'
address = Mail::Address.new email # ex: "john@example.com"
address.display_name = name.dup   # ex: "John Doe"
# Set the From or Reply-To header to the following:
address.format # returns "John Doe <john@example.com>"

1
Cảm ơn bạn rất nhiều! Tôi đã tìm ra có một cách tốt hơn so với chuỗi nối, nhưng cách sử dụng Mail::Addresskhông rõ ràng trong bất kỳ tài liệu nào tôi đọc.
Tim Morgan,

10
address.display_namedường như đột biến mã hóa chuỗi trong một số trường hợp, vì vậy nếu bạn có kế hoạch sử dụng namesau này, ví dụ như trong đường ray quan điểm bưu phẩm, làmaddress.display_name = name.dup
Eero

7
Có vẻ như Mail gem hiện đã đánh lừa chuỗi được truyền vào, vì vậy name.dupdường như không cần thiết nữa. Nguồn đọc:@display_name = str.nil? ? nil : str.dup
philoye

Điều này thậm chí hoạt động trong trình khởi tạo Devise:config.mailer_sender = Proc.new { address = Mail::Address.new... }
Cimm

97
@recipients   = "\"#{user.name}\" <#{user.email}>"
@from         = "\"MyCompany\" <info@mycompany.com>"

2
Tôi không nghĩ vậy. Nó không thể chứa bất kỳ ký tự không phải ASCII nào cho một, không thể chứa chính ký tự trích dẫn và cũng có một số ký tự ASCII không được phép / không được khuyến nghị trong tiêu đề. Tôi thấy rằng RFC2047 cung cấp một cơ chế để mã hóa base64 các giá trị như vậy.
William Denniss

11
xem câu trả lời của tôi để biết cách thực hiện việc này mã hóa các chuỗi đúng cách.
James McKinney

8
Điều này rất hữu ích! FYI, nếu bạn đang cố gắng kiểm tra điều này, bạn sẽ cần phải xem @ email.header ['From']. To_s, không phải @ email.from. Sau đó chỉ chứa địa chỉ email chứ không phải tên.
sbleon

7
Đừng làm theo cách này. Thay vào đó, hãy xem câu trả lời của @ JamesMcKinney.
Matthew Ratzloff

5
Một lần nữa, không sử dụng cái này vì nó không an toàn. Thay vào đó, hãy xem câu trả lời của @ JamesMcKinney.
Jake Petroules

43

Trong rails3, tôi đặt những thứ sau trong mỗi môi trường. tức là sản xuất.rb

ActionMailer::Base.default :from => "Company Name <no-reply@production-server.ca>"

Đặt các trích dẫn xung quanh tên công ty không phù hợp với tôi trong Rails3.


Bạn cũng có thể đặt nó trực tiếp vào tệp mailer.rb của mình như thế này :from => "Company Name <no-reply@email.com>"nếu bạn không có giới hạn về môi trường.
Puce

8

trong Rails 2.3.3, một lỗi trong ActionMailer đã được giới thiệu. Bạn có thể xem vé ở đây. Vé # 2340 . Nó được giải quyết trong 2-3-ổn định và chính vì vậy nó sẽ được sửa trong 3.x và 2.3.6.

Để khắc phục sự cố trong vòng 2.3. * Bạn có thể sử dụng mã được cung cấp trong phần bình luận trên vé:

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

2
Đối với bất kỳ ai có câu hỏi của tôi, "tôi đặt mã này ở đâu?" câu trả lời là lưu nó dưới dạng tệp .rb trong thư mục [rails app root] / config / initializers.
JellicleCat

6

Phiên bản tôi thích sử dụng của cái này là

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

`<< là dấu gạch ngược.

Cập nhật

Bạn cũng có thể thay đổi điều đó thành

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

Đọc thêm về chuỗi ký tự.


1

Một khía cạnh khó chịu khác, ít nhất là với định dạng AR mới, là hãy nhớ rằng 'mặc định' được gọi ở cấp độ lớp. Tham chiếu các quy trình chỉ dành riêng cho phiên bản khiến nó âm thầm không thành công và đưa ra khi bạn cố gắng sử dụng nó:

 NoMethodError: undefined method `new_post' for Notifier:Class

Đây là những gì tôi đã sử dụng:

def self.named_email(name,email) "\"#{name}\" <#{email}>" end
default :from => named_email(user.name, user.email)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.