Devise email confirmation not working on Heroku - ruby-on-rails

When I click on the link in my confirmation email that devise sends, it seems to go to a path that is not recognized by my application.
The url looks something like this:
http://glowing-flower-855.heroku.com/users/confirmation?confirmation_token=lIUuOINyxfTW3TBPPI
which looks correct, but it seems to go to my 500.html file.
It has something to do with this code in my user model that overrides Devise's confirm! method:
def confirm!
UserMailer.welcome_message(self).deliver
super
end
According to my logs, this is the error:
2011-06-10T03:48:11+00:00 app[web.1]: ArgumentError (A sender (Return-Path, Sender or From) required to send a message):
2011-06-10T03:48:11+00:00 app[web.1]: app/models/user.rb:52:in `confirm!'
which points to this line: UserMailer.welcome_message(self).deliver
Here's my user mailer class:
class UserMailer < ActionMailer::Base
def welcome_message(user)
#user = user
mail(:to => user.email, :subject => "Welcome to DreamStill")
end
end

You are missing the "from:" value, it's a must for SMTP handling:
class UserMailer < ActionMailer::Base
# Option 1
#default_from "bob#dylan.com"
def welcome_message(user)
#user = user
mail(
# Option 2
:from => "paul#mccarthy.com",
:to => user.email,
:subject => "Welcome to DreamStill"
)
end
end

Related

Issue with ActionMailer Mandrill in Rails

I have a cab booking platform created in Rails. I am using the Mandrill smtp settings in production to send booking confirmation mails to users of my platform. Then I generated a mailer called user_mailer with the following code:
class UserMailer < ActionMailer::Base
default :from => "my_company_email"
def booking_confirmation(user)
#user = user
mail(:to => user.email, :subject => "Booking Confirmation")
end
end
Then I created booking_confirmation.html.erb page in user_mailer views with some generic content inside. Finally I called the user_mailer in one of my controllers as follows:
UserMailer.booking_confirmation(current_user).deliver
My problem is that when I want to include more details (such as Travel date, Travel time, etc.) within the mail delivered to my customer. I am trying this within my booking_confirmation.html.erb page: <%= #user.bookings.last.date %> to display the Travel Date to the customer. But this doesn't get displayed. Why is it so?
I would pass in the booking like
UserMailer.booking_confirmation(current_user, booking.id).deliver
then in the class UserMailer I would do
class UserMailer < ActionMailer::Base
default :from => "my_company_email"
def booking_confirmation(user, booking)
#user = user
#booking = Booking.find(booking)
mail(:to => user.email, :subject => "Booking Confirmation")
end
end
now on your erb you should have #booking.date to use
Its not a mandrill issue.something wrong with application code.
Check whether your following code has the date value present for last bookings.
#user.bookings.last.date

Emailing multiple users using ActionMailer

This is a total newbie question, but I wonder if someone could assist with setting up a mailer. I have a model 'users' and nested underneath it a 'contacts' model, (with a has_many/belongs_to relationship).
I am now trying to create a mailer which will be triggered by a specific action (create post) on a user page, and will email all the contacts belonging to that user. But I can't crack the syntax required on the mailer - I've tried setting recipients to #user.contacts.all and I've tried looping through them as with this solution. Can anybody advise on the cleanest way to do it?
Here's the code I have so far:
Posts controller:
after_create :send_contact_email
private
def send_contact_email
ContactMailer.contact_email(self).deliver
end
contact_mailer (this is my latest attempt, taken from the RoR site - I suspect this is NOT the best way to do it...)
class ContactMailer < ActionMailer::Base
def contact_email(user)
recipients #user.contacts.all
from "My Awesome Site Notifications <notifications#example.com>"
subject "Welcome to My Awesome Site"
sent_on Time.now
body {}
end
end
And then a basic message for the contact_email.html.erb.
The current error is:
NoMethodError in UsersController#create_post
undefined method `contacts' for nil:NilClass.
Any advice you can offer would be really gratefully received!
* Update *
Following Baldrick's advice, the contact_email method is now:
class ContactMailer < ActionMailer::Base
default :to => Contact.all.map(&:contact_email),
:from => "notification#example.com"
def contact_email(user)
#user = user
mail(:subject => "Post added")
end
end
There's a typo: you are using #user instead of user in the contact_email method.
It may not be the only problem, but at least it's the cause of the error message "undefined method 'contacts' for nil:NilClass "
Update
So with the right syntax, remove the :to from default options, and set it in the contact_emailmethod, with the contacts of your user:
class ContactMailer < ActionMailer::Base
default :from => "notification#example.com"
def contact_email(user)
#user = user
mail(:subject => "Post added", :to => user.contacts.map(&:contact_email),)
end
end
class ContactMailer < ActionMailer::Base
default :to => Contact.all.map(&:contact_email),
:from => "notification#example.com"
def contact_email(user)
recipients = user.contacts.collect(&:contact_email).join(',')
mail(:subject => "Post added", :to => recipients)
end
end

rails 3 + devise: how to modify the mailer method for confirmation emails to add user's second email address

Background: In our app, we often have a sales rep do the setup for our customer using the salesperson's computer (often customers don't have access to their email at the time we set them up). So we're thinking to add a field to the devise registration form for the sales rep's email address and have the confirm link ALSO go to that email address.
Question: Is there a way to tell devise to bcc (or cc) the initial confirmation email (only the initial confirmation email) to an (optional) "backup_email" email address that is also provided on the new user registration form?
Alternatively, is there a way to 'disable' the confirmation email process but ONLY when a certain code is entered into the registration field?
I know how to add another field to the devise registration form, but I don't see how/where to modify the devise mailer code so when a confirmation email is sent to the "email" address it ALSO goes to the "backup_email" address (if any, sometimes it's blank).
Thanks to Johnny Grass!
I did rails generate mailer CustomerUserMailer
and added
#config/initializers/devise.rb
config.mailer = "CustomUserMailer"
my custom mailer looks like:
# app/mailers/customer_user_mailer.rb
class CustomUserMailer < Devise::Mailer
def headers_for(action)
headers = {
:subject => translate(devise_mapping, action),
:from => mailer_sender(devise_mapping),
:to => resource.email,
:cc => resource.backup_user_email(action),
:template_path => template_paths
}
end
end
Then I moved the 3 mailer templates FROM views/devise/mailer to views/customer_user_mailer (otherwise the emails are empty)
Then I added a method to my User model called backup_user_email() that returns the 'backup' email address (if any) based on the data in the user record and the action. The only "trick" there is that when testing the action it is not action == "confirmation_instructions" it is action == :confirmation_instructions.
Just in case anyone got here through Google - in the latest version of Devise, header_for takes two parameters. So your code would need to be:
class MyMailer < Devise::Mailer
backup_email = "..."
def headers_for(action, opts)
headers = {
:subject => subject_for(action),
:to => resource.email,
:from => mailer_sender(devise_mapping),
:bcc => backup_email,
:reply_to => mailer_reply_to(devise_mapping),
:template_path => template_paths,
:template_name => action
}.merge(opts)
end
end
That might not be the best way to do it, but at least it avoids errors.
One way to do it would be to override the headers_for action in Devise::Mailer
class MyMailer < Devise::Mailer
backup_email = "..."
def headers_for(action)
headers = {
:subject => translate(devise_mapping, action),
:from => mailer_sender(devise_mapping),
:to => resource.email,
:bcc => backup_email
:template_path => template_paths
}
end
And tell devise to use your mailer:
#config/initializers/devise.rb
config.mailer = "MyMailer"
You can use this code which is much cleaner and simpler
# app/mailers/my_mailer.rb
class MyMailer < Devise::Mailer
def headers_for(action, opts)
backup_email = "..."
super.merge!({bcc: backup_email})
end
end
# config/initializers/devise.rb
...
config.mailer = MyMailer
...
With Hash passed to merge! method you can add or modify any email headers you'd like.
Your answer worked for me. Thank you so much.
I had a scenario wherein, i was required to customize devise to:
1) send signup confirmation emails in BCC to different emails based on environment.
2) emails should be added to BCC only for signup confirmation mails.
To achieve that, i compared values for action argument, like shown in the code snippet below:
def headers_for(action)
if action == :confirmation_instructions
if Rails.env.production?
recipient_email = "user1#example.com"
else
recipient_email = "user2#example.com"
end
headers = {
:subject => translate(devise_mapping, action),
:from => mailer_sender(devise_mapping),
:to => resource.email,
:bcc => recipient_email,
:template_path => template_paths
}
else
super
end
end

How can I access #user or user from a mailer using Devise and Rails 3?

class JobMailer < ActionMailer::Base
default :from => "emailer#email.com"
def new_job_email_for_client
#
#
#url = "http://simplesite.com/users/login"
mail(:to => #???,
:subject => "You have created a new case on simplesite.")
end
end
I would like each user to receive an email each and every time he/she creates a "job." In other parts of the application, I can access #user and user.email and such, but in the mailer I'm getting "undefined errors."
How can I access the current users email address in the mailer (taking into consideration that Devise is in control of Users)?
I'm not sure if this is a great way of doing it, but this is how I got it working:
def new_job_email_for_client(user_email)
#url = "http://simplesite.com/users/login"
mail(:to => user_email,
:subject => "You have created a new case.")
end

Rails - ActionMailer - How to send an attachment that you create?

In rails3 w ActionMailer, I want to send a .txt file attachment. The challenge is this txt file does not exist but rather I want to create the txt file given a large block of text that I have.
Possible? Ideas? Thanks
It's described for files in the API documentation of ActionMailer::Base
class ApplicationMailer < ActionMailer::Base
def welcome(recipient)
attachments['free_book.pdf'] = File.read('path/to/file.pdf')
mail(:to => recipient, :subject => "New account information")
end
end
But that doesn't have to be a File, it can be a string too. So you could do something like (I'm also using the longer Hash-based form where you can specify your own mimetype too, you can find documentation for this in ActionMailer::Base#attachments):
class ApplicationMailer < ActionMailer::Base
def welcome(recipient)
attachments['filename.jpg'] = {:mime_type => 'application/mymimetype',
:content => some_string }
mail(:to => recipient, :subject => "New account information")
end
end
First the method to send email
class ApplicationMailer < ActionMailer::Base
def welcome(user, filename, path)
attachments[filename] = File.read(path)
mail(:to => user.email, :subject => "New account information")
end
end
Call the method with the params
UserMailer.welcome(user, filename, path).deliver

Resources