IT & Engineering
Ein datengesteuerter Ansatz, um die E-Mails von Nutzern aktuell zu halten
Dieser Blog wurde von Roy Young verfasst. Roy ist ein Ruby-Entwickler, der seine Skills an der Tealeaf Academy weiterentwickelt.
Ah, die Tabelle „users“.
Dieser Blog wurde verfasst von Roy Young. Roy, ein Ruby-Entwickler, der seine Skills weiterentwickelt an der Tealeaf Academy.
Ah, die Tabelle „users“.
Man könnte behaupten, dass sie eines der wichtigsten Assets eines Start-ups ist. Zynische Stimmen da draußen können nicht glauben, dass Instagram (eine Foto-Sharing-App!) gekauft wurde für 715 Millionen $ von Facebook oder dass Mailbox, ein mobiler E-Mail-Client für Gmail (der in vielerlei Hinsicht noch in der Beta-Phase steckte), Gerüchten zufolge für bis zu 100 Millionen $ von Dropbox gekauft wurde.
Diese zynische Sichtweise resultiert oft aus einem kurzsichtigen Fokus nur auf das Produkt oder die Technologie. Das macht es leicht, solche Bewertungen als absurd abzutun. Es muss jedoch auch der Wert all dieser Nutzer und das Wachstum dieser Nutzerbasis berücksichtigt werden. Diese astronomischen Bewertungen gehen immer mit einem Produkt einher, das eine große und schnell wachsende Nutzerbasis hat. Daher liegt es auf der Hand, dass es eine gute Investition für Ihr Unternehmen ist, Ihre Nutzertabelle mit den korrekten Kontaktinformationen auf dem neuesten Stand zu halten. Der schwierige Teil ist natürlich, dieses Wachstum zu generieren … Sie müssen also für diese Informationen bezahlen.
Dieser Ratschlag zum „einfachen Teil“ ist jedoch kostenlos. In diesem Beitrag spreche ich über eine bewährte Methodik, um die E-Mails Ihrer Nutzer in einer Zeit aktuell zu halten, in der viele Menschen mehrere E-Mail-Adressen und Wegwerf-E-Mail-Adressen für viele ihrer Dienste haben.
Anwendungslogik zur Aufforderung von Nutzern, ihre E-Mail-Adresse zu aktualisieren
Wenn Sie eine E-Mail an eine E-Mail-Adresse senden, die nicht mehr existiert, sendet die Empfängerseite (z. B. Gmail oder Yahoo) diese als Bounce an Sie zurück. Wenn Sie diese Bounces erfassen, kann Ihre App entsprechend reagieren. So entsteht eine großartige Nutzererfahrung, während Ihre Kundendatenbank aktuell bleibt. Dieser Blog skizziert eine auf Heroku erstellte Beispielanwendung. Sie nutzt Mailgun, um diese E-Mail-Bounces zu erfassen, damit Nutzer mit fehlerhaften E-Mail-Adressen weiterhin monatliche E-Mails mit Rechnungen erhalten können. Die gleiche Logik lässt sich jedoch auf all Ihre E-Mails anwenden, um sicherzustellen, dass Ihre Nutzer engagiert bleiben und per E-Mail über Ihr Unternehmen auf dem Laufenden gehalten werden.

Ich habe eine Demo-Website für diesen Artikel erstellt und den Quellcode hier zur Verfügung gestellt: GitHub. Diese Demo führt Neulinge durch den gesamten Prozess, um diese Funktionalität einzurichten. Klicken Sie hier wenn Sie direkt zur Integration von Bounce-Webhooks in Ihre App springen möchten.
Versand von monatlichen Rechnungs-E-Mails mit dem Heroku Scheduler
Um monatliche Rechnungen an Ihre Nutzer zu senden, müssen Sie Code schreiben, um:
- Individuelle Rechnungs-E-Mails an Hunderte, Tausende oder Millionen Personen aus Ihrer Kundschaft zu versenden.
- Den tatsächlichen Versand dieser E-Mails zu planen.
Lassen Sie uns dies der Reihe nach im Detail betrachten.
Individuelle Rechnungs-E-Mails bereitstellen
Für die Zwecke dieses Tutorials gehe ich davon aus, dass Sie bereits über ein Mailgun-Konto verfügen. Von dort aus senden Sie die Liste Ihrer Kundschaft an Mailgun, zusammen mit allen Variablen, die Sie als JSON-Datei dynamisch in die E-Mails einfügen möchten, sowie dem HTML- oder Text-Body der E-Mail. Hier ist der Code.
class MailgunGateway include Rails.application.routes.url_helpers def send_batch_message(users) RestClient.post(messaging_api_end_point, from: "Mailgun Demo ", to: users.map(&:email).join(", "), subject: "Monthly Billing Info", html: billing_info_text, :"h:Reply-To" => "billing@#{ENV["mailgun_domain_name"]}", :"recipient-variables" => recipient_variables(billing_recipients) ) end private def api_key @api_key ||= ENV["mailgun_api_key"] end def messaging_api_end_point @messaging_api_end_piont ||= "https://api:#{api_key}@api.mailgun.net/v2/#{ENV["mailgun_domain_name"]}/messages" end def billing_recipients @users ||= User.where(locked: false) end def recipient_variables(recipients) vars = recipients.map do |recipient| ""#{recipient.email}": {"name":"#{recipient.fullname}"}" end "{#{vars.join(', ')}}" end def billing_info_text <<-EMAIL Hi %recipient.name%, <p> Your bill for the current month is now available, please click on <br /> #{billing_url} <br /> to see details. </p> <p>Reply to this email directly</p> EMAIL end end
Sehen wir uns an, was wir gemacht haben.
In der Methode sendbatchmessages verwenden wir Empfängervariablen, damit wir Variablen definieren können, um jede E-Mail individuell anzupassen. Sie werden feststellen, dass wir den Vornamen des Nutzers in die E-Mail einfügen. Sie könnten eine Rechnungs-E-Mail verfassen, die Details wie Kontonummer, Rechnungskonto oder Ähnliches enthält, aber ich halte es hier einfach.
Automatischer Versand monatlicher Abrechnungs-E-Mails mit dem Heroku Scheduler
Sobald wir unsere Methode zur Erstellung und zum Versand von E-Mails über Mailgun haben, müssen wir Code schreiben, der diese Methode über einen Trigger automatisch auslöst. Ich habe mich entschieden, diese App auf Heroku bereitzustellen, und verwende den Heroku Scheduler, weil er seinen Zweck erfüllt, ein kostenloses Add-on ist und sich leicht integrieren lässt.
Der Heroku Scheduler führt einen bestimmten Rake-Task zu einer festgelegten Zeit aus. Hier müssen wir also einen Rake-Task erstellen, um Abrechnungs-E-Mails über Mailgun in lib/tasks/scheduler.rake zu versenden.
Erstens: Wenn wir Abrechnungsrechnungen an Nutzer senden, müssen wir die E-Mail-Adressen der Kundschaft finden, der wir die Rechnung stellen.
Im sehr einfachen Datenbankschema dieser Beispiel-App gibt es das Attribut :locked, das auf „True“ gesetzt wird, wenn eine E-Mail zuvor einen Bounce verursacht hat (dazu unten mehr). Unsere Abfrage ruft also einfach alle Nutzer ab, bei denen dieses Feld auf „False“ steht.
Um die E-Mail tatsächlich zu versenden, verwende ich Mailgun Batch-Versand. Da die maximal zulässige Anzahl der Empfänger pro API-Aufruf 1.000 beträgt, verwenden wir findinbatches, um Abrechnungs-E-Mails in Batches von 1.000 Empfängern an Mailgun zu senden.
desc "This task is called by the Heroku scheduler add-on"
task :send_billing_info => :environment do
if DateTime.now.mday == 1
User.where(locked: false).find_in_batches(batch_size: 1000) do |group|
MailgunGateway.new.send_batch_message(group)
end
end
end
Da die Einstellung „FREQUENCY“ im Heroku Scheduler nur drei Optionen bietet – „täglich, stündlich, alle 10 Minuten“ –, müssen wir prüfen, ob der aktuelle Tag der erste Tag des Monats ist. Das tun wir mit if DateTime.now.mday == 1. Wenn ja, wird die E-Mail versendet. Wenn nicht, keine E-Mail.
Benachrichtigung über E-Mail-Bounces erhalten
Wenn eine E-Mail einen Bounce verursacht, sendet Mailgun über den Bounce-Webhook einen POST an unsere App. Sie müssen die Callback-URL unter „Bounces“ im Mailgun Control Panel festlegen. In dieser Demo lautet meine Callback-URL „http://mailgun-demo.herokuapp.com/api/bounced_mails“
Wenn die App die Bounce-Benachrichtigung erhält, sucht sie die E-Mail-Adresse in der Kundendatenbank und setzt den Status des Nutzers auf „locked“. Dadurch sendet die App keine Abrechnungs-E-Mail mehr an diesen Nutzer, bis er seine E-Mail-Adresse aktualisiert hat.
class Api::BouncedMailsController < ApplicationController
skip_before_filter :verify_authenticity_token
def create
if verify(ENV["mailgun_api_key"], params[:token], params[:timestamp], params[:signature])
user = User.find_by_email(params[:recipient])
if user && params[:event] == "bounced"
user.lock!
end
head(200)
end
end
private
def verify(api_key, token, timestamp, signature)
signature == OpenSSL::HMAC.hexdigest(
OpenSSL::Digest::Digest.new('sha256'),
api_key,
'%s%s' % [timestamp, token])
end
end
Das user.lock! setzt den Nutzerstatus auf „locked“, sodass unser Rake-Task niemals E-Mails an diesen Nutzer sendet. Diese Methode ist im User-Modell festgelegt.
class User < ActiveRecord::Base
…
def lock!
self.locked = true
save(validate: false)
end
end
Die Methode verify dient zur Überprüfung, ob der Webhook von Mailgun stammt. Andernfalls könnten Dritte einen gefälschten POST senden, um die Nutzer in Ihrer App zu sperren.
Weitere Details zur Konfiguration von Webhooks finden Sie in der Mailgun-Dokumentation – Events/Webhooks.
Am Ende geben wir eine 200-Kopfzeile zurück, um Mailgun mitzuteilen, dass diese Interaktion erfolgreich war. Andernfalls geht Mailgun davon aus, dass unser Server offline ist, und versucht weiterhin, unseren Webhook aufzurufen.
Sobald die App weiß, welche Nutzer eine fehlerhafte E-Mail-Adresse haben, müssen wir bei ihrer nächsten Anmeldung einen Flash-Screen anzeigen. Dieser fordert sie auf, die hinterlegten Kontaktinformationen zu überprüfen.
class SessionsController < ApplicationController
def new
redirect_to home_path if current_user
end
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
if user.locked
flash[:error] = "Your Email Address is invalid, please update it."
redirect_to edit_user_path(current_user)
else
redirect_to home_path
end
else
flash[:error] = "Incorrect email or password. Please try again."
redirect_to sign_in_path
end
end
def destroy
session[:user_id] = nil
redirect_to root_path
end
end
Nachdem sie ihre E-Mail-Adresse aktualisiert haben, setzen wir das Attribut „locked“ wieder auf „false“, damit sie weiterhin E-Mails erhalten.
Das war’s. Wenn nun die E-Mails Ihrer Nutzer einen Bounce verursachen, können Sie sie auffordern, ihre Informationen zu aktualisieren. Dies bietet eine großartige Nutzererfahrung mit dem zusätzlichen Vorteil, dass Ihre Kundendaten aktuell bleiben.