what is the best way to make a newsletter in rails3 - ruby-on-rails

Is there a gem to do this, and if not, what is the best approach. I'm assuming i'd store the emails in a newsletter database, and would want a form that emails everyone at once. thanks!

No gem for this that I know of.
Actually, due to processing issues, the best way would be to use external bulk email service provider via provider's API.
However, building your own newsletter system is no different from building your regular MVC. Only addition are mailers and mailer views.
(1) So you create model that deals with registration data (:name, :email, :etc...) and model that deals with newsletter itself.
(2) Controller that deals with it (CRUD) + (:send). Send takes each recipient, sends data to mailer which creates email and then sends it.
def send
#newsletter = Newsletter.find(:params['id'])
#recipients = Recipient.all
#recipients.each do |recipient|
Newsletter.newsletter_email(recipient, #newsletter).deliver
end
end
(3) Mailer builds an email, makes some changes in each email if you want to do something like that and returns it to controller action send for delivery.
class Newsletter < ActionMailer::Base
default :from => "my_email#example.com", :content_type => "multipart/mixed"
def newsletter_email(recipient, newsletter)
# these are instance variables for newsletter view
#newsletter = newsletter
#recipient = recipient
mail(:to => recipient.email, :subject => newsletter.subject)
end
end
(4) Ofc, you need mailer views which are just like regular views. Well in multipart there is:
newsletter_email.html.erb (or haml)
newsletter_email.txt.erb
When you want to send both html and text only emails. Instance variables are defined in mailer ofc.
And... that is it. Well you could use delayed job to send them since sending more than several hundred emails can take a while. Several ms times n can be a lot of time.
Have fun.

Please check the maktoub gem there is a blog post over it.

No gem that I know of too and building on #Krule's answer, here's a screencast of setting up mailers in Rails.
How to create, preview and send email from your rails app
I was looking for something similar when I found this. I think with a bit of customization, it can easily be used to create newsletter emails too.
Save money! Spend somewhere else.

Related

Why do I need to require 'mail' on top of controller to use it outside ActionMailer?

I noticed that Mail gem doesn't get loaded outside ActionMailer context, but the gem is present in the proper gem group of Gemfile and then "loaded" upon Rails initialization.
To create a Mail object in a controller using Mail.new I need to put
require 'mail'
at the top of example_controller.rb, before
class ExampleController < ApplicationController
Could someone explain to me why?
Background:
I need to build an app whose functionality is primarily based on receiving emails of various types. I need to expose only one email address, where people will send all of these emails.
My mail server will pipe the raw email to a ruby script that sends the raw email as a POST request to my app.
Then, I need to identify which kind of email has arrived inferring that from its content (primarily attachments).
For example, let's have emails of types A, B and C. My email processing function will call one of three methods once it identifies the type of the email.
Where should I put the processing function?
You shouldn't be creating mail objects in your controllers. You should create a mailer and then call that mailer from your controller to send any emails you need to.
For example, say you have the following mailer in app/mailers/customer_mailer.rb:
class CustomerMailer < ActionMailer::Base
def send_reminder(user)
#user = user
mail to: user.email, subject: 'Reminder'
end
end
You can then call this from your controller as needed:
class ExampleController < ApplicationController
def some_action
#user = User.find(params[:id])
CustomerMailer.send_reminder(#user).deliver_now
end
end
This way your controller can focus on the implementations specific to controlling the request, and leave the mailer to worry about how to send email.
It's worth noting you also have access to a deliver_later method if you're using a background job runner.
Take a look at the documentation for more details: http://guides.rubyonrails.org/action_mailer_basics.html

RubyOnbRails - Render mail to string

I have a RubyOnRails 3.2.x application that sends out mails using Actionmailer.
The code goes something like this:
class Mymailer < ActionMailer::Base
def sendout
mail(:to->"someone#somewhere.com", :from ...........
end
end
Instead of sending out that email, I want it to be rendered to a string which I then plan to process differently
PS: In my specific case I want to pass that string to a Node.JS server who will do the actual sending of the mail, I am using RubyOnRails to handle the multi language support and number formatting (yes I have multiple templates for the different languages that I support).
Since Ruby won't be doing the email sending, there's no need to use the Mailer.
Ideally you could generate a JSON string representation of the email like:
# at the top of the file
require 'json'
# then in your method
json_string = {
:to => "email#example.com",
:from =>"sender#example.com",
:body => "this is the body"
}.to_json
Then post this string to your node.js server from (for example) your controller or whatever is currently calling your mailer.
However, since you want to render the email using templates which pull in DB fields and use the i18n functionality of Rails, you could use the Mailer but render the result to a string like follows:
mail(to: "mail#example.com") do |format|
format.html do
string = render_to_string("your_template")
call_node_js(string)
end
end
If what you want is getting the whole mail representation, including headers, then you might want to browse the source code to see what happens behind the curtain.
A good starting point is the ActionMailer::Base method #mail (Rails 4):
http://api.rubyonrails.org/classes/ActionMailer/Base.html#method-i-mail
Anyway, if the sending is handled by Node.js, you don't need to do it. Just build a JSON object like Olly suggested and pass it through.

How to block email to certain email addresses or domain?

We have an application built in rails 3.2.8. We are sending emails to customers. I want to block certain emails addressses. Basically mailer just ignore those particular email addresses.
For example: My company name is abc and I dont want to send emails to all my employees ie john#abc.com or rayn#abc.com ie *#abc.com
How can I do this?
PS: I am using sendgrid, they are not providing anything like this.
EDIT:
Placing this code in initializers directory:
class EmailAddressFilter
def self.delivering_email(message)
message.perform_deliveries = false
end
end
ActionMailer::Base.register_interceptor(EmailAddressFilter)
Should block all the emails. But still I can see emails in my development log.
PS: I have restarted my server.
In a file in config/initializers you can add something like this
class EmailAddressFilter
def self.delivering_email(message)
# permit or deny the message using its "to", "body" etc properties
# note message.to is an array (multiple emails)
message.perform_deliveries = Email.whitelisted?(message.to)
end
end
ActionMailer::Base.register_interceptor(EmailAddressFilter)

Ruby on rails super simple signup page

How would I be able to make a signup page with ruby on rails?
Like, I have a beta page and a user enters their email address and then I can add it to the database.
Also, I could send them an email confirming their signup
EDIT: I want something real simple. Like, just plain adding a row in a database simple. I don't need a password box and a username box because that just further complicates things. I'm a beginner so I like to have things simple.
At the terminal:
$ rails new foobar
$ rm public/index.html
$ git init
$ git commit -m "Initial commit"
$ rails g scaffold subscription email:string
Open up your editor:
# app/models/subscription.rb
class Subscription < ActiveRecord::Base
validates :email, :presence => true # optionally validate format of email
end
# app/controllers/subscriptions_controller.rb
class SubscriptionsController < ApplicationController
def new
#subscription = Subscription.new
end
def create
#subscription = Subscription.new params[:subscription]
if #subscription.save
# queue a task to send a confirmation email (see below)
Resque.enqueue(SendConfirmationEmail, #subscription.email)
redirect_to root_path, :notice => 'Thanks for signing up.'
else
render :new
end
end
end
You can delete all of the other methods/actions from your SubscriptionsController, and you can cleanup routes.rb by restricting the actions available on the subscriptions resource with resources :subscriptions, :only => [:new, :create].
This doesn't really cover how to send the email. There are a lot of ways to do it, and the best practice is to not send it in the request/response flow for performance/responsiveness. I've got a line in there queuing a Resque job to do it, but you could easily add DelayedJob or another deferred/async process tool there instead.
This is the kind of thing that is very easy to do in Rails and you shouldn't need any extra gems. Here are the steps you will need to do:
Use a migration to create a model (i.e. database table) called Signup with a string field called "email".
Create an action that can be called with a "GET" request. This action will return the sign up form.
Create the view that serves as the signup form. It should have an HTML form element (<form method="POST">...</form>) that contains a text box (<input type="text" .../>) in it and a submit button (<input type="submit" />). Rails has all sorts of helper methods that will help you make those HTML tags, but you don't have to use them if you don't want to.
Create an action that can be called with a "POST" request that processes the form and adds the info to the database.
The action can be very simple:
def create_signup
Signups.create! :email => params[:email]
end
Does this make sense? Now that I have given you the general guide, you should be able to ask new questions that are more focussed on specific parts that you don't know how to do. You should also search the web because there are probably tutorials available for all of these steps.
This question is too broad to answer with the code itself, but here are some great links to point you in the right direction:
Devise (most common Rails auth & signup plugin):
https://github.com/plataformatec/devise
Devise tutorial:
http://railscasts.com/episodes/209-introducing-devise
Mailer tutorial:
http://railscasts.com/episodes/206-action-mailer-in-rails-3
Other Auth tutorials:
http://railscasts.com/episodes/250-authentication-from-scratch
http://railscasts.com/episodes/270-authentication-in-rails-3-1
I made an app for this. Launchrock offers a good solution, but if you have two types of users then you are hosed. Our future site will have multiple types of users and we wanted to record which type they were. So we made an app and it's on Github for the world to use and change. :D Fork and clone the repo to make it your own. I included social plugin's as well. It's not styled and you'll have to change a few things to fit your needs, but I tried to make note of those in the README.rd.
Launchpage-rails
You could have a look at the 'Devise' gem -
https://github.com/plataformatec/devise
Railscasts episode on 'Devise'
http://railscasts.com/episodes/209-introducing-devise
The excellent 'Rails Tutorial' also takes you through building a sign-up/authentication system from scratch -
http://ruby.railstutorial.org/ruby-on-rails-tutorial-book

How to stop from view being rendered while sending email

I am using Rails 3.0.9 and I have following code to send an email when a comment is posted.
class Mailer < ActionMailer::Base
def comment_notification(comment)
User.active.each do |user|
#user = user
mail(:to => #user.email, :subject => subject)
end
end
end
If there are not active users then User.active is empty and the code inside does not get executed. However the view is rendered and view fails because #user is missing.
The above code is invoked by observer
Mailer.comment_notification(comment).deliver
One way to fix this problem would be to change the code in observer to something like this
User.active.each do |recipient|
Mailer.comment_notification(comment, recipient).deliver
end
Is this the right way to fix this way. I would like my observer to be as thin as possible.
Yes, your observer fix is correct. You should loop through and send emails one by one. The mailer should just send one email at a time. This is a job best left to Delayed Job though. You don't want to waiting around while an email sends.
Here is a tutorial on Delayed Job: http://railscasts.com/episodes/171-delayed-job
Be sure to check the Readme for Delayed Job as well, paying special attention to the "Rails 3 Mailers" section: http://github.com/collectiveidea/delayed_job

Resources