如何使用ssl通过smtp发送带有ruby的邮件(不带有rails,没有用于gmail的TLS)

时间:2021-01-09 18:11:52

All I want is to send emails from my ruby scripts, over SMTP using SSL.

我想要的只是使用SSL通过SMTP发送来自我的ruby脚本的电子邮件。

I only find examples of doing it from Rails, or for Gmail with TLS.

我只找到从Rails或使用TLS的Gmail中执行此操作的示例。

I found people talking about SMTPS support with ruby 1.8.5, but the libdoc doesn't mention it.

我发现有人在讨论使用ruby 1.8.5的SMTPS支持,但是libdoc没有提到它。

Anyone with an example of sending mail over SMTP with SSL, on port 465?

有人通过端口465通过SMTP发送邮件的例子吗?

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

6 个解决方案

#1


9  

I solve this issue with this configuration below :

我通过以下配置解决了这个问题:

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@yourdomain.com',
    :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.
}

It works very well for me.

它对我很有用。

#2


3  

How about pony ?
gem install pony.
http://github.com/adamwiggins/pony/tree/master
or I did not understand your question ?

I hope it help you.
Thanks
tknv/

小马怎么样?宝石安装小马。 http://github.com/adamwiggins/pony/tree/master或者我不明白你的问题?我希望它可以帮到你。谢谢tknv /

#3


0  

You probably already know about the Net::SMTP standard library

您可能已经了解Net :: SMTP标准库

Regarding the SSL part, which doesn't seem to be supported out of the box, I found a couple of possible pointers:

关于SSL部分,似乎不支持开箱即用,我找到了几个可能的指针:

#4


0  

The only interesting thing I've heard of in programmatic email recently is Lamson: http://lamsonproject.org/

我最近在程序化电子邮件中听到的唯一有趣的事情是Lamson:http://lamsonproject.org/

It's Python, not Ruby, but you can call Python from Ruby if you want to (here's one way: http://www.goto.info.waseda.ac.jp/~fukusima/ruby/python-e.html)

它是Python,而不是Ruby,但如果你愿意,可以从Ruby调用Python(这里有一种方式:http://www.goto.info.waseda.ac.jp/~fukusima/ruby/python-e.html)

#5


0  

You could use a third party open source command line program like mailsend (http://www.muquit.com/muquit/software/mailsend/mailsend.html) to do your dirty work for you. Just pipe some output to it in the format it expects.

您可以使用第三方开源命令行程序(如mailsend(http://www.muquit.com/muquit/software/mailsend/mailsend.html))为您完成脏活。只需以预期的格式输出一些输出。

#6


0  

If you have to use SSL instead of TLS you can monkey-patch Net::SMTP like this:

如果你必须使用SSL而不是TLS,你可以像这样使用网络补丁Net :: SMTP:

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

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

#1


9  

I solve this issue with this configuration below :

我通过以下配置解决了这个问题:

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@yourdomain.com',
    :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.
}

It works very well for me.

它对我很有用。

#2


3  

How about pony ?
gem install pony.
http://github.com/adamwiggins/pony/tree/master
or I did not understand your question ?

I hope it help you.
Thanks
tknv/

小马怎么样?宝石安装小马。 http://github.com/adamwiggins/pony/tree/master或者我不明白你的问题?我希望它可以帮到你。谢谢tknv /

#3


0  

You probably already know about the Net::SMTP standard library

您可能已经了解Net :: SMTP标准库

Regarding the SSL part, which doesn't seem to be supported out of the box, I found a couple of possible pointers:

关于SSL部分,似乎不支持开箱即用,我找到了几个可能的指针:

#4


0  

The only interesting thing I've heard of in programmatic email recently is Lamson: http://lamsonproject.org/

我最近在程序化电子邮件中听到的唯一有趣的事情是Lamson:http://lamsonproject.org/

It's Python, not Ruby, but you can call Python from Ruby if you want to (here's one way: http://www.goto.info.waseda.ac.jp/~fukusima/ruby/python-e.html)

它是Python,而不是Ruby,但如果你愿意,可以从Ruby调用Python(这里有一种方式:http://www.goto.info.waseda.ac.jp/~fukusima/ruby/python-e.html)

#5


0  

You could use a third party open source command line program like mailsend (http://www.muquit.com/muquit/software/mailsend/mailsend.html) to do your dirty work for you. Just pipe some output to it in the format it expects.

您可以使用第三方开源命令行程序(如mailsend(http://www.muquit.com/muquit/software/mailsend/mailsend.html))为您完成脏活。只需以预期的格式输出一些输出。

#6


0  

If you have to use SSL instead of TLS you can monkey-patch Net::SMTP like this:

如果你必须使用SSL而不是TLS,你可以像这样使用网络补丁Net :: SMTP:

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

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