2009-04-02 33 views
8

Tất cả những gì tôi muốn là gửi email từ tập lệnh ruby, qua SMTP bằng SSL.Cách gửi thư bằng ruby ​​qua smtp với ssl (không phải với đường ray, không có TLS cho gmail)

Tôi chỉ tìm thấy các ví dụ về cách thực hiện từ Rails hoặc cho Gmail với TLS.

Tôi đã tìm thấy mọi người nói về sự hỗ trợ SMTPS với ruby ​​1.8.5, nhưng libdoc không đề cập đến nó.

Bất kỳ ai có ví dụ gửi thư qua SMTP với SSL, trên cổng 465?

ruby -v 
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux] 

Trả lời

0

Bạn có thể đã biết về Net::SMTP standard library

Về phần SSL, mà dường như không được hỗ trợ ra khỏi hộp, tôi tìm thấy một vài gợi ý có thể:

+0

Tôi đã thử các ví dụ đó và làm việc tốt với gmail, nhưng tôi không thể làm cho chúng hoạt động với SMTP thông thường qua SSL trên tài khoản ISP của tôi. –

0

Nếu bạn phải sử dụng SSL thay vì TLS bạn có thể khỉ vá Net :: SMTP như thế này:

require "openssl" 
require "net/smtp" 

Net::SMTP.class_eval do 

    def self.start(address, port = nil, 
        helo = 'localhost.localdomain', 
        user = nil, secret = nil, authtype = nil, use_tls = false, 
        use_ssl = false, &block) # :yield: smtp 
    new(address, port).start(helo, user, secret, authtype, use_tls, use_ssl, &block) 
    end 

    def start(helo = 'localhost.localdomain', 
      user = nil, secret = nil, authtype = nil, use_tls = false, use_ssl = false) # :yield: smtp 
    start_method = use_tls ? :do_tls_start : use_ssl ? :do_ssl_start : :do_start 
    if block_given? 
     begin 
     send start_method, helo, user, secret, authtype 
     return yield(self) 
     ensure 
     do_finish 
     end 
    else 
     send start_method, helo, user, secret, authtype 
     return self 
    end 
    end 

    private 

    def do_tls_start(helodomain, user, secret, authtype) 
    raise IOError, 'SMTP session already started' if @started 

    if VERSION == '1.8.6' 
     check_auth_args user, secret, authtype if user or secret 
    elsif VERSION == '1.8.7' 
     check_auth_args user, secret 
    end 

    sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) } 
    @socket = Net::InternetMessageIO.new(sock) 
    @socket.read_timeout = 60 #@read_timeout 
    @socket.debug_output = STDERR #@debug_output 

    check_response(critical { recv_response() }) 
    do_helo(helodomain) 

    raise 'openssl library not installed' unless defined?(OpenSSL) 
    starttls 
    ssl = OpenSSL::SSL::SSLSocket.new(sock) 
    ssl.sync_close = true 
    ssl.connect 
    @socket = Net::InternetMessageIO.new(ssl) 
    @socket.read_timeout = 60 #@read_timeout 
    @socket.debug_output = STDERR #@debug_output 
    do_helo(helodomain) 

    authenticate user, secret, authtype if user 
    @started = true 
    ensure 
    unless @started 
     # authentication failed, cancel connection. 
     @socket.close if not @started and @socket and not @socket.closed? 
     @socket = nil 
    end 
    end 

    def do_ssl_start(helodomain, user, secret, authtype) 
    raise IOError, 'SMTP session already started' if @started 

    if VERSION == '1.8.6' 
     check_auth_args user, secret, authtype if user or secret 
    elsif VERSION == '1.8.7' 
     check_auth_args user, secret 
    end 

    sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) } 
    raise 'openssl library not installed' unless defined?(OpenSSL) 
    ssl = OpenSSL::SSL::SSLSocket.new(sock) 
    ssl.sync_close = true 
    ssl.connect 
    @socket = Net::InternetMessageIO.new(ssl) 
    @socket.read_timeout = 60 #@read_timeout 
    @socket.debug_output = STDERR #@debug_output 

    check_response(critical { recv_response() }) 
    do_helo(helodomain) 

    do_helo(helodomain) 

    authenticate user, secret, authtype if user 
    @started = true 
    ensure 
    unless @started 
     # authentication failed, cancel connection. 
     @socket.close if not @started and @socket and not @socket.closed? 
     @socket = nil 
    end 
    end 

    def do_helo(helodomain) 
    begin 
     if @esmtp 
     ehlo helodomain 
     else 
     helo helodomain 
     end 
    rescue Net::ProtocolError 
     if @esmtp 
     @esmtp = false 
     @error_occured = false 
     retry 
     end 
     raise 
    end 
    end 

    def starttls 
    getok('STARTTLS') 
    end 

    def quit 
    begin 
     getok('QUIT') 
    rescue EOFError, OpenSSL::SSL::SSLError 
    end 
    end 
end 

Xem http://github.com/collectiveidea/action_mailer_optional_tls/blob/master/lib/smtp_tls.rb

9

tôi giải quyết vấn đề này với cấu hình này bên dưới:

config.action_mailer.perform_deliveries = true 
config.action_mailer.raise_delivery_errors = false 
config.action_mailer.delivery_method = :smtp 
config.action_mailer.smtp_settings = { 
    :address    => 'mail.domain.com', 
    :port     => '465', 
    :domain    => 'yourdomain.com', 
    :user_name   => '[email protected]', 
    :password    => 'yourpassword', 
    :authentication  => :login, 
    :ssl     => true, 
    :openssl_verify_mode => 'none' #Use this because ssl is activated but we have no certificate installed. So clients need to confirm to use the untrusted url. 
} 

Nó hoạt động rất tốt cho tôi.

+1

Đã chiến đấu với thông báo gitlab/mail -: ssl => true đã làm việc cho tôi. –

+0

tài liệu README.md (https://github.com/mikel/mail#getting-emails-from-a-pop-server) cho Mail Gem thực sự cũ, vì vậy ': enable_ssl => true' không còn hoạt động nữa, thay vào đó hãy sử dụng ': ssl => true', một nỗi đau 〒_〒 – DiveInto

Các vấn đề liên quan