Mit Rails E-Mails über Gmail senden

Hier beschreibe ich wie man mit Ruby on Rails E-Mails über den SMTP-Server seines eigenen Gmail-Kontos verschickt. Da Gmail es nur erlaubt, E-Mails über eine SSL-Verbindung zu senden, müssen wir das der Rails-Applikation erst einmal beibringen, denn von Haus aus kann sie das nicht.

Lerne mehr über Ruby on Rails mit Martin Labuschins
Ruby on Rails Link Library.

Plugin „installieren“

Für diesen Zweck gab es mal ein Plugin namens „Action_Mailer_TLS“, jedoch ist die Anbieter-Website längst offline. Glücklicherweise gibt es im Rails-Forum einen gewissen Lake, der den wichtigsten Teil des nötigen Codes gepostet hat. Daraus basteln wir uns also einfach selbst ein Plugin.

Ein Plugin lässt sich mit einem Generator anlegen:

script/generate plugin action_mailer_tls

Der letzte Parameter ist der Name des Plugins.

Nun legen wir im noch frischen lib-Verzeichnis des Plugins (zu finden im vendor/plugins-Verzeichnis) eine Datei namens smtp_tls.rb an. Dort kommt der Code aus dem Rails-Forum rein:

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 
		    @socket.debug_output = STDERR 

		    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 
		    @socket.debug_output = STDERR 
		    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
		    end
		  end
		end

Inhalt der Datei „smtp_tls.rb“

Zugang konfigurieren

Der Zugang kann entweder spezifisch in einer bestimmten Umgebung eingerichtet werden oder man gibt sie umgebungsunabhöngig in der environment.rb an:

require 'smtp_tls'

		ActionMailer::Base.delivery_method = :smtp
		ActionMailer::Base.smtp_settings = {
		  :address => "smtp.gmail.com",
		  :port => 587,
		  :domain => "DOMAIN",
		  :authentication => :plain,
		  :user_name => "USERNAME",
		  :password => "PASSWORD"
		}

Natürlich müssen die Begriffe in Versalien durch die eigenen Daten ersetzt werden.

Mailer-E-Mail einrichten

Für die E-Mail-Adresse, von der man senden möchte, muss man eine Berechtigung in seinem Gmail-Konto haben. Dazu gibt es genau eine Vorausseutzung: Man muss E-Mails an die E-Mail-Adresse empfangen können, um Gmail die Berechtigung zu ermöglichen. Folgendes ist zu tun:

  • In Gmail die Einstellungen „Konten“
  • Runterscrollen zu „Eine weitere E-Mail-Adresse hinzufügen“
  • Dort einen Namen eingeben (nicht so wichtig, wie der heisst, der lässt sich vom Rails-Mailer später noch anpassen)
  • Die E-Mail-Adresse sollte nun die gewünschte für den Mailer sein
  • Nun die „Änderungen speichern“
  • Jetzt muss diese neue E-Mail-Adresse auf neue E-Mails überprüft werden.
  • In der Bestätigungs-E-Mail auf den entsprechenden Link klicken
  • Jetzt sollte der Mailer auch mit dieser E-Mail-Adresse funktionieren

Falls diese E-Mail-Adresse nicht in Gmail eingerichtet ist, bevor man mit Rails (oder sonst wie) E-Mails versenden möchte, wird der Absender (FROM) in die Standard-E-Mail-Adresse des entsprechenden Kontos umgeschrieben.

Übrigens: Der technische Sender (SENDER) bleibt die Standard-E-Mail-Adresse, nur die tatsächliche Absender (FROM) lässt sich von Rails bestimmen. Für den Empfänger wird das aber nicht großartig auffallen, da die meisten E-Mail-Clients nur den Absender (FROM) anzeigen.

Wie man nun die eigentlichen Mailer und Templates einrichtet, wird bei Ryan Bates wunderbar erklärt: Sending Email.

Hinweis für Kleinkarierte: Mit „Gmail“ meine ich den E-Mail-Dienst von Google, der in Deutschland auch als „Google Mail“ bekannt ist. Ich habe der Einfachheit halber das oft genutzte Kürzel/Synonym „Gmail“ verwendet.

veröffentlicht am 01.03.2009 um 23:00 von Martin Labuschin in ,


Hey cooler Beitrag. Ich werd das mal nächstes Wochenende ausprobieren. Willst du vielleicht das plug-in in deinem GitHub-Account hochstellen?

Darf ich nicht, da der Code ja nicht rechtmäßig mir gehört. Oder geht das doch?

Hmm, ja die Frage stellt sich natrürlich. Unter welcher Lizens steht der Quelltext? Lässt sich im Forumsbeitrag schlecht ersehen.

Wobei du es hier ja auch veröffentlicht hast.

Ich habe vor ein paar Wochen auch einen Mailer auf GMail umgerüstet — das Plugin dazu jedoch wenn ich mich richtig erinnere schon auf GitHub gefunden.

http://schrader.me/items/view/1700/rob-seaman-adding-gmail-ssl-smtp-support-to-rails

Also, bei mir hat das nicht funktioniert. Ich habe wie beschrieben gemacht, aber das funktioniert leider nicht. Und blöderweise gibt es keine Fehlermeldung in logs. Die E-Mail wird abgeschickt (laut Ruby), aber in google wird die eMail nicht abgeschickt...Bin verzweifelt. Hat jemand eine Idee?

blog comments powered by Disqus
The Ruby on Rails Link Library Spanning Sync SEO-Dokumentation Gowalla
ProWebApps WellDone (β) Pinboard (α) Netzwerk Münsterland
Blogs Bücher Frameworks iPhone Mac Web-Apps