what's the difference between send email with "deliver" and without "deliver"? - ruby-on-rails

What's the difference between following two email invoke approach? One with deliver while another not.
mail(:to => 'test#gmail.com', :subject => "Test") do |format|
format.html { render layout: false }
end.deliver
mail(:to => 'test#gmail.com', :subject => "Test") do |format|
format.html { render layout: false }
end

.deliver actually send message, block without .deliver just create mail object but not send it. .deliver is operation for sending email like .deliver_later or custom created delivery method (example: you generate mail using method without .deliver and then your cron_job send this emails later).
You can find more information here:
http://guides.rubyonrails.org/action_mailer_basics.html#walkthrough-to-generating-a-mailer
or
good example working with emails:
http://railscasts.com/episodes/61-sending-email-revised?view=asciicast

As far as I can tell... just the flat mail function will send the email. If you construct a Mail::Message object, you need to call .deliver on it to get it to send, but the mail function seems to do that for you.
(At least, as far as I can tell. I have yet to test it, so I'm not sure)

Related

Action Mailer attachments.inline showing as normal attachment, not inline

def simple_mail(to, subject, body)
attachments.inline['Logo.png'] = File.read( Rails.root.join("public", "Logo.png"))
mail(:to => to, :subject => subject, :body => body)
end
I receive an attachment to the message, but it is not an "inline" image. How can I attach inline, and how can I choose where it goes?
I'm seeing examples that have views for their mailer.. looks like I may need to set those up. If so, how do I link Action Mailer views to a message?
As you see in guides.rubyonrails, you can link a view to your mailer the same way you link a view to a controller's action. if your mailer is called my_mailer, and your mailer action is called simple_mail, then create a view in app/views/my_mailer/ and call it "simple_mail.html.erb". As well, you can create a "simple_mail.text.erb" to make sure that if the recipient can't receive HTML e-mails, they get the plaintext version (see action_mailer_basics.html below).
As for inline attachments, a different question was raised previously regarding views (see this link) and scaney answered with a couple links. Check out this link and search the text for "inline" and you should find the answer you're looking for!
http://guides.rubyonrails.org/action_mailer_basics.html
api.rubyonrails.org/classes/ActionMailer/Base.html
1) To Setup action-mailer views for the mails, you can do it as follows:
Create a view file in app/views/mailer_name/ with the same name as your mailer action (which in this case is "simple_mail" )
Alternatively if you want to use a different view altogether you can also do it as :
def simple_mail(to, subject, body)
attachments.inline['Logo.png']=File.read( Rails.root.join("public", "Logo.png"))
mail(:to => to, :subject => subject, :body => body) do |format|
format.html { render :partial => "/path/to/partial"}
end
end
In the above case, the content of the partial will be rendered as the body of the mail.
2) To attach a inline image you will also need to mention the attachment in the mailer action view file as follows:
<%= image_tag attachments['Logo.png'].url %>

dynamic email subject and body from database

In my admin site, I want editable
Dynamic subject in database text.
mailer = MailTemplate.find_by_template_name('friend_request')
# mailer.subject = "#{#user.username} wants to be friend on site.com"
I have to use code like :
mail(:to => friend.email, :subject => mailer.subject) do |format|
format.text { render :inline => nl2br(mailer.body) }
format.html { render :inline => nl2br(mailer.body) }
end
Now, I found body is working properly with dynamic code. But SUBJECT is not working with
mailer.subject for value like "#{#user.username} wants to be friend on SportsPundit.com"
Please suggest. I tried with eval(mailer.subject) as well.
Consider using a different templating language so you're not exposing ruby to the user. Handlebars may be a good choice.
In your MailTemplate object, subject would be
"{{ user/username }} wants to be friend on site.com"
Then you would render it using handlebars-rails or some other lib, passing #user as user in the handlebars template. This is better for the average user to figure out, so they aren't looking at ruby.

PDF attachment in email is called 'Noname'

When I send an email with a attached pdf file the email only shows a file called 'Noname'. The file itself is the multipart section of the email with the base64 attached pdf. How can I send the PDF so it comes up as an attachment and doesn't corrupt the email?
Here is my code:
attachments['126539_statistics.pdf'] = File.read("app/assets/pdfs/126539_statistics.pdf")
mail(:to => email, :subject => subject, :body => message, :content_type => 'application/pdf')
I had face same problem. I have corrected it by following way
1) As per ActionMailer Guide, You need to make view file into app/views/[action_mailer_model_name]/[method_name]
Here is reference of guide: http://api.rubyonrails.org/classes/ActionMailer/Base.html
2) Action Mailer is smart enough that it identify content-type automatically while reading file. So there is no need to pass explicitly 'application/pdf' in your mail function.
Hope, this information helps to solve your problem
Also experienced the same problem
solution is :
set Attachments before sending mail function.
code is attached below:
attachments["invoice_#{invoice.bill_date.strftime('%B-%Y')}.pdf"] = WickedPdf.new.pdf_from_string(
render_to_string pdf: 'project_report.pdf',
template: 'users/_invoice.html.erb'
)
mail(to: email , from: from, subject: subject) do |format|
format.html
end

Tracking SMS conversation using Rails and Twilio

I am using Twilio in my rails 3.1.3 app and I have got everything basically set up, i.e. a controller for sms and xml builders for the views depending on the response. The only thing I can't figure out is how to keep track of the conversation. The Twilio docs are pretty bad for using anything other than PHP to do this. I have tried using the Rails session hash, session[:variable], but it doesn't seem to be saving the session, as I tried redirecting and printing it out and got nothing. Below is the code of the controller.
def receive
# Check for session variable and redirect if necessary
#sms_state = session[:sms_state]
if #sms_state == 'confirmation'
redirect_to 'confirm'
end
if condition
#sms_state = 'confirmation'
session[:sms_state] = #sms_state
render :action => "view.xml.builder", :layout => false
else
#sms_state = 'new_state'
session[:sms_state] = #sms_state
render :action => "error.xml.builder", :layout => false
end
end
# method that should be called after user deals with first part
def confirm
if condition
#sms_state = session[:sms_state] = nil
render :action => "confirm_view.xml.builder", :layout => false
else
#sms_state = 'confirmation'
session[:sms_state] = #sms_state
render :action => "error.xml.builder", :layout => false
end
end
I have now set up a database table to track the current conversation state depending on the phone number contacting my app. The only thing now that I need to do is set an expiration for this conversation, just like a session or cookie. I am not sure how to do this or if its even possible.
This depends on how you define "conversation", but in general, you are better off using some sort of persistance (would recommend database over a file), and build the structure in accordance with your definition of a conversation.
Suppose the conversation is defined as text messages between two 10-digit phone numbers without a time limit, you can setup a db with a sender and recipient attributes, so if you need to output something in a user interface, you can look for sender and recipient phone numbers, and display all messages coming to them or going from them.
SMS is different from a phone call, since you can set cookies for the session of a phone call. SMS is done when either delivered or sent. When you receive an SMS to a phone number or short code, Twilio will make a request to the URL you provided for SMS, and your app can then respond. If you receive another response, it's a brand new request, so you have to construct the notion of "conversation".

Did I do this correctly - Call an action from controller with link_to

Please excuse the simplicity and length of this, but I have a little test app that has a users table, with name, email, and salary attributes. I created a mailer that will send out a report of this data to a specific user at my discretion, in other words, when I click a button. My button is created using link_to, and calls an action in my main users_controller, which then calls the mailer action. (I hope that just made sense). It looks like the following and is working just as I hoped; I'm just looking to know if this is the right way to do something like this:
In my users_controller (created by the scaffold generator):
def sendemail
#user = User.find(params[:id])
UserMailer.welcome_email(#user).deliver
redirect_to user_path(#user)
flash[:notice] = 'Email has been sent!'
end
In the user_mailer.rb file:
def welcome_email(user)
#user = user
#url = "http://example.com/login"
mail(:to => user.email,
:subject => "Welcome to My Awesome Site")
end
In the User's show.html.erb page, this is how the email gets sent:
<%= link_to "Send Email", sendemail_user_path(#user) %>
In my routes.rb file, so that everything executes properly (which it does):
resources :users do
member do
get 'sendemail'
end
So, having said all this, it works just like it should. I click on the user's show.html.erb page where I would have the data and charts that I want to eventually display, and at my discretion, I can kick out an email to that user with this data, or whatever I put in the mailer.html.erb file. When it is sent, it flashes the message I specified in the controller, and leaves me on that page, just as I specified; so it's working. I just want to know, is this the right and most ruby/railsy way to do things?
This code looks very similar to the Rails Guides Action Mailer example, so suffice it to say you are creating railsy code.
Also, if your application evolved into a much grander scale you would want to consider delivering emails via a background job to avoid email deliveries from blocking the current thread.
Otherwise the code looks great. Of course, you would most likely send an email after doing something successful in a controller, rather than have a dedicated action for emailing directly. For instance, you might have a welcome action that sends an email on a successful user record save.

Resources