Archivo para la categoría "Ruby & Rails"

Enviar un correo usando el SMTP de Gmail, y Ruby + ActionMailer   3 comments

Desde hace muchos dias he estado buscando la manera de enviar correos usando Ruby, probe con varios ejemplos de internet, usando gemas y demas, ninguno funciono, hasta ahora.

El principal problema de usar Gmail, es que necesita autentificar por SSL/TLS, pero encontre un codigo en la lista de usuarios de Rails de Vancouver, lo modifique un poco, lo probe y voila! funciona de mil maravillas.

Aqui esta el archivo de correo (message.rb):

require action_mailer
require smtp_tls

class AnnounceMailer < ActionMailer::Base

def message(recipient)
from tu_correo@loquesea.com
recipients recipient
subject Aca va el subject
body <<EOS
Hola,

Este es un mensaje de muestra.

Saludos.
EOS
end
end

# Probar si se creo bien imprimiendo el mensaje.
puts AnnounceMailer.create_message( receptor@loquesea.com )

ActionMailer::Base.smtp_settings = {
:address => smtp.gmail.com,
:port => 587,
:authentication => :plain,
:user_name => tuUsuariode@gmail.com,
:password => secreto
}

# Enviar el mensaje
AnnounceMailer.deliver_message( receptor@loquesea.com )

Y aqui esta la libreria para manejar el SMTP con TLS (smtp_tls.rb):

<font color=”#a020f0″>require</font>&nbsp;<font color=”#6a5acd”>&quot;</font><font color=”#ff00ff”>openssl</font><font color=”#6a5acd”>&quot;</font><br>
<font color=”#a020f0″>require</font>&nbsp;<font color=”#6a5acd”>&quot;</font><font color=”#ff00ff”>net/smtp</font><font color=”#6a5acd”>&quot;</font><br>
<br>
<font color=”#2e8b57″><b>Net</b></font>::<font color=”#2e8b57″><b>SMTP</b></font>.class_eval <font color=”#a52a2a”><b>do</b></font><br>
<font color=”#a52a2a”><b>private</b></font><br>
<font color=”#a020f0″>def</font>&nbsp;<font color=”#008b8b”>do_start</font>(helodomain, user, secret, authtype)<br>
<font color=”#a52a2a”><b>raise</b></font>&nbsp;<font color=”#2e8b57″><b>IOError</b></font>, <font color=”#6a5acd”>'</font><font color=”#ff00ff”>SMTP session already started</font><font color=”#6a5acd”>'</font>&nbsp;<font color=”#a52a2a”><b>if</b></font>&nbsp;<font color=”#008b8b”>@started</font><br>
check_auth_args user, secret, authtype <font color=”#a52a2a”><b>if</b></font>&nbsp;user <font color=”#a52a2a”><b>or</b></font>&nbsp;secret<br>
<br>
sock = timeout(<font color=”#008b8b”>@open_timeout</font>) { <font color=”#2e8b57″><b>TCPSocket</b></font>.open(<font color=”#008b8b”>@address</font>, <font color=”#008b8b”>@port</font>) }<br>
<font color=”#008b8b”>@socket</font>&nbsp;= <font color=”#2e8b57″><b>Net</b></font>::<font color=”#2e8b57″><b>InternetMessageIO</b></font>.new(sock)<br>
<font color=”#008b8b”>@socket</font>.read_timeout = <font color=”#ff00ff”>60</font>&nbsp;<font color=”#0000ff”>#@read_timeout</font><br>
<font color=”#0000ff”>#@socket.debug_output = STDERR #@debug_output</font><br>
<br>
check_response(critical { recv_response() })<br>
do_helo(helodomain)<br>
<br>
<font color=”#a52a2a”><b>if</b></font>&nbsp;starttls<br>
&nbsp;&nbsp;<font color=”#a52a2a”><b>raise</b></font>&nbsp;<font color=”#6a5acd”>'</font><font color=”#ff00ff”>openssl library not installed</font><font color=”#6a5acd”>'</font>&nbsp;<font color=”#a52a2a”><b>unless</b></font>&nbsp;<font color=”#a52a2a”><b>defined?</b></font>(<font color=”#2e8b57″><b>OpenSSL</b></font>)<br>
&nbsp;&nbsp;ssl = <font color=”#2e8b57″><b>OpenSSL</b></font>::<font color=”#2e8b57″><b>SSL</b></font>::<font color=”#2e8b57″><b>SSLSocket</b></font>.new(sock)<br>
&nbsp;&nbsp;ssl.sync_close = <font color=”#ff00ff”>true</font><br>
&nbsp;&nbsp;ssl.connect<br>
&nbsp;&nbsp;<font color=”#008b8b”>@socket</font>&nbsp;= <font color=”#2e8b57″><b>Net</b></font>::<font color=”#2e8b57″><b>InternetMessageIO</b></font>.new(ssl)<br>
&nbsp;&nbsp;<font color=”#008b8b”>@socket</font>.read_timeout = <font color=”#ff00ff”>60</font>&nbsp;<font color=”#0000ff”>#@read_timeout</font><br>
&nbsp;&nbsp;<font color=”#0000ff”>#@socket.debug_output = STDERR #@debug_output</font><br>
&nbsp;&nbsp;do_helo(helodomain)<br>
<font color=”#a52a2a”><b>end</b></font><br>
<br>
authenticate user, secret, authtype <font color=”#a52a2a”><b>if</b></font>&nbsp;user<br>
<font color=”#008b8b”>@started</font>&nbsp;= <font color=”#ff00ff”>true</font><br>
<font color=”#a52a2a”><b>ensure</b></font><br>
<font color=”#a52a2a”><b>unless</b></font>&nbsp;<font color=”#008b8b”>@started</font><br>
&nbsp;&nbsp;<font color=”#0000ff”># authentication failed, cancel connection.</font><br>
&nbsp;&nbsp;<font color=”#008b8b”>@socket</font>.close <font color=”#a52a2a”><b>if</b></font>&nbsp;<font color=”#a52a2a”><b>not</b></font>&nbsp;<font color=”#008b8b”>@started</font>&nbsp;<font color=”#a52a2a”><b>and</b></font>&nbsp;<font color=”#008b8b”>@socket</font>&nbsp;<font color=”#a52a2a”><b>and</b></font>&nbsp;<font color=”#a52a2a”><b>not</b></font>&nbsp;<font color=”#008b8b”>@socket</font>.closed?<br>
&nbsp;&nbsp;<font color=”#008b8b”>@socket</font>&nbsp;= <font color=”#ff00ff”>nil</font><br>
<font color=”#a52a2a”><b>end</b></font><br>
<font color=”#a020f0″>end</font><br>
<br>
<font color=”#a020f0″>def</font>&nbsp;<font color=”#008b8b”>do_helo</font>(helodomain)<br>
&nbsp;<font color=”#a52a2a”><b>begin</b></font><br>
&nbsp;&nbsp;<font color=”#a52a2a”><b>if</b></font>&nbsp;<font color=”#008b8b”>@esmtp</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;ehlo helodomain<br>
&nbsp;&nbsp;<font color=”#a52a2a”><b>else</b></font><br>
&nbsp;&nbsp;&nbsp;&nbsp;helo helodomain<br>
&nbsp;&nbsp;<font color=”#a52a2a”><b>end</b></font><br>
<font color=”#a52a2a”><b>rescue</b></font>&nbsp;<font color=”#2e8b57″><b>Net</b></font>::<font color=”#2e8b57″><b>ProtocolError</b></font><br>
&nbsp;&nbsp;<font color=”#a52a2a”><b>if</b></font>&nbsp;<font color=”#008b8b”>@esmtp</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;<font color=”#008b8b”>@esmtp</font>&nbsp;= <font color=”#ff00ff”>false</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;<font color=”#008b8b”>@error_occured</font>&nbsp;= <font color=”#ff00ff”>false</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;<font color=”#a52a2a”><b>retry</b></font><br>
&nbsp;&nbsp;<font color=”#a52a2a”><b>end</b></font><br>
&nbsp;&nbsp;<font color=”#a52a2a”><b>raise</b></font><br>
<font color=”#a52a2a”><b>end</b></font><br>
<font color=”#a020f0″>end</font><br>
<br>
<font color=”#a020f0″>def</font>&nbsp;<font color=”#008b8b”>starttls</font><br>
getok(<font color=”#6a5acd”>'</font><font color=”#ff00ff”>STARTTLS</font><font color=”#6a5acd”>'</font>) <font color=”#a52a2a”><b>rescue</b></font>&nbsp;<font color=”#a52a2a”><b>return</b></font>&nbsp;<font color=”#ff00ff”>false</font><br>
<font color=”#a52a2a”><b>return</b></font>&nbsp;<font color=”#ff00ff”>true</font><br>
<font color=”#a020f0″>end</font><br>
<br>
<font color=”#a020f0″>def</font>&nbsp;<font color=”#008b8b”>quit</font><br>
<font color=”#a52a2a”><b>begin</b></font><br>
&nbsp;&nbsp;getok(<font color=”#6a5acd”>'</font><font color=”#ff00ff”>QUIT</font><font color=”#6a5acd”>'</font>)<br>
<font color=”#a52a2a”><b>rescue</b></font>&nbsp;<font color=”#2e8b57″><b>EOFError</b></font>, <font color=”#2e8b57″><b>OpenSSL</b></font>::<font color=”#2e8b57″><b>SSL</b></font>::<font color=”#2e8b57″><b>SSLError</b></font><br>
<font color=”#a52a2a”><b>end</b></font><br>
<font color=”#a020f0″>end</font><br>
<font color=”#a52a2a”><b>end</b></font><br>
</font><

require openssl
require net/smtp

Net::SMTP.class_eval do
private
def do_start(helodomain, user, secret, authtype)
raise IOError, SMTP session already started if @started
check_auth_args user, secret, authtype if user or secret

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)
if starttls
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
do_helo(helodomain)
end
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) rescue return false
return true
end

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

Para que funcione, se necesita la libreria OpenSSL instalada y la gema ActionMailer o Ruby On Rails que la trae en el paquete, si se usa Windows podria probar con Cygwin.

Espero les sea de utilidad.

PD: Siento las faltas ortograficas estoy en teclado ingles y sin ganas de modificar las X a espaniol 😛

Codigo  original de  http://bit.ly/9r8cx1

Publicado enero 31, 2010 por Sergio D. Rodríguez Inclan en General, Open Source, Ruby & Rails

Etiquetado con

LDAP   Leave a comment

Ok… año nuevo, objetivos nuevos. Luego de probar VirtualBox gracias a sugerencia de David y Boris, y leyendo un poco más de documentación en Internet y algunos documentos es probable que cambiemos de rumbo nuestro actual desarrollo de la Intranet.

Para empezar le he dado un gran vistazo a LDAP (Lightweight Directory Access Protocol – Protocolo Ligero de Acceso a Directorios) que exíste desde hace mucho tiempo ya, entonces si exíste una base de datos jerárquica que nos brinda todos los datos necesarios de los usuarios, nos permita integrar sistemas con una sóla llave de acceso y además integrar plataformas distintas… ¿para qué programar una base de datos nueva que no tiene ni la mitad de la funcionalidad que ésto ofrece?

Debo pedir disculpas por mi ignorancia en éste rumbo, es la primera vez que tengo la oportunidad de probar sistemas en red ya que hasta hace poco no creía que una máquina virtual podría realizar el trabajo completamente, pero, he estado completamente equivocado (vamos que tonto) además LDAP <-> Active Directory era la propuesta más lógica antes de proponer un sistema diseñado completamente de cero. Todos las herramientas  que mencionaré de principio son sólo supuestas, a medida que vaya experimentando sabré cuales son las correctas y cómo organizarlas.

Para la programación:

  • Aplicaciones: Ruby On Rails + MySQL.
  • Integración de capas: Ruby-Net-LDAP.
  • Control de versiones: Git.

Para la prueba, 4 máquinas virtuales conectadas en una LAN simple o usando OpenVPN:

  • Gentoo Linux + LDAP servidor + Kerberos + Mongrel o Apache + Aplicaciones [Rails].
  • Gentoo Linux + X cliente.
  • Windows 2003 Server + controlador de dominio + Active Directory.
  • Windows XP cliente.

Principales inconvenientes de momento:

  • Hardware, mi pentium D no creo que soporte la carga de las 4 máquinas virtuales así que necesito adquirir una Quad Core lo más pronto posible.
  • Tiempo de instalación y configuración de servidores  y clientes.

Esta parte es sólo la de infraestructura, el desarrollo de las aplicaciones tiene iteraciones independientes y tiempos distintos, ya se calcularán en su momento.