How to get email open notification in rails? - ruby

In my rails application i am using action mailer to send mails to users. I want to give some bonus points to user if he opens the mail. For that i want to get notification when the email got opened in user end. Is there any idea to achieve this?
I tried as below.
I added one image tag in the mail template like below:
<%= image_tag tracking_image_url(1)%>
And in controller
def image
file_path=File.dirname(::Rails.root.join('public','assets','customer_ads','2','medium','medium')) + "/Huawei.jpg"
send_file file_path, :type => 'image/jpeg'
end
I am not getting any notification from this. It's just downloading the image.

I achieved through ahoy email gem.

Related

Adding custom form actions in ActiveAdmin

I'm using ActiveAdmin to add google OAuth credentials to a record. The client ID and Client Secret are added via record/1/edit, and I use those to generate a link to allow access. This link appears in record/view. I am trynig to find a way for the Administrator to enter the code returned by google oauth into the portal so that I can use it to generate credentials.
My current attempt looks something like this
row "Code from Google OAuth" do
form do |f|
label "Google Auth Code:"
input :code, :label => "Code", :hint => "Code returned by google auth"
f.action :submit
end
I get an "undefined method: action" error form this code. Any ideas on how to return user input as a parameter?
form is an Arbre tag that maps directly to HTML, in which case action is an attribute, eg.
form(action: '/someroute', method: :patch) do ... end
If you want to embed a Rails or Formtastic form you would use form_for or active_admin_form_for respectively.

How to visit link in email opened with letter_opener gem

I am working on some QA automation using Cucumber and Capybara and have a step:
When(/^I follow the reset password link in the email$/) do
last_email = ActionMailer::Base.deliveries.last
password_reset_url = last_email.body.match(/http.*\/users\/password\/edit.*$/)
visit password_reset_url
end
The step fails with:
undefined method `body' for nil:NilClass (NoMethodError)
Additionally, dropping binding.pry after the first line results in nil for last_email which is weird.
Does anyone have advice or thoughts on why that may be happening here?
If you're using letter_opener then emails aren't going to ActionMailer deliveries and are being opened in a browser not controlled by Capybara. If you want to work with emails in capybara you should probably be looking at the capybara-email gem rather than letter_opener. Letter_opener is aimed more at the dev environment rather than test
Tom Walpole's answer is absolutely correct in content and pointing you in the direction of the capybara-email gem.
Here's a potential example of how you could change your code sample, assuming that you have another Cucumber step that has clicked a button/link to send reset password instructions:
When(/^I follow the reset password link in the email (.*)$/) do |email|
# finds the last email sent to the passed in email address.
# This also sets the `current_email` object, which you can think
# of as similar to Capybara's `page` object, but for an email.
open_email(email)
# Assuming the email link to change your password is called
# 'Change my password', you can just click it, just as you would
# on a Capybara `page`.
current_email.click_link 'Change my password'
end
After clicking the link, you will be taken to whatever page where you can continue on to fill_in 'New password', with: 'foobar' etc, which I'm assuming you've got covered in another Cucumber step.

Rails 3 - MP3 files in public folder

I added mp3 files to the /public folder and I found a bit issue.
In my view I added the links:
= link_to "Interview 1", "/interview_01.mp3"
When I see the link from the page, everything appears normal until I click on it. The browser hangs on for a minute or more, the tile changes to "undefined" and my Google Chrome freezes.
What's wrong with it? How can I make it so people can just download the file?
Edit: More context for my answer since someone down voted me
When you link to an mp3 file, most modern browsers will attempt to play that file directly in the browser. Your browser is likely freezing because whatever plugin your browser is using to begin playing the file is broken. My guess would be you are running windows and it is attempting to use a quicktime plugin or something along those lines.
If you don't want the browser to play the file and you actually want the file to begin downloading, you need to add a few extra headers to the HTTP response. The most important being:
Content-Disposition: attachment; filename="filenamehere.mp3"
My original answer provides instructions for accomplishing this. If this is not what you were hoping to achieve then you can disregard it.
If you want the file embedded directly into the page with the new HTML5 audio tag, you can follow the advice given in the comment to your question by #Alen.
Original answer:
You should try sending the file from a controller action using the #send_file controller helper method.
= link_to "Inteview 1", :controller => 'files', :action => 'send_file', :filename => 'interview_01.mp3'
Then
class FilesController
def send_file
file_path = "#{Rails.root}/public/#{params[:filename]}"
send_file file_path, :filename => params[:filename], :disposition => 'attachment'
end
end
Reference Rails Api: http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_file
The send_file method sets the HTTP headers correctly to tell the browser to download the file instead of attempting to render it.

Rails 3.2.8 / Carrierwave - Image upload receiving multipart not as a normal form

I have an api and I need to receive image files from a mobile device or some other device but server without a form. And I want to check which user based on the mac_address variable.
The model has the following code:
class Image < ActiveRecord::Base
attr_accessible :mac_address, :superclass_id, :user_id, :file_path, :file_size
belongs_to :mac_address
mount_uploader :file_path, FileUploader
end
The file uploader is just:
class FileUploader < CarrierWave::Uploader::Base
storage :fog
include CarrierWave::MimeTypes
process :set_content_type
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
It already works if I save the file as JSON base64 base. But my colleague wants to send as multipart.
I tried the following suggestion but it doesn't work: Uploading a raw file to Rails using Carrierwave
Ideally, I want my colleague to send the image to:
http://localhost:3000/api/v1/images/MAC_ADDRESS?filename=something.png
So what should I do in he controller to receive that file? It's easy to do a form from rails but this way seems to be impossible to do.
How should I proceed?
If the image is hosted on a remote server, and this server is available from where you are trying to save the image. You can try this https://stackoverflow.com/a/5007665/1822298 .

Using Cucumber to test controller without a view in Rails

I'm a ruby/rails newbie and the application I'm developing starts with a HTTP post from another website which passes in some data and then displays some data capture screens before calling a web service.
I want to start this project using an outside in approach using Cucumber for integration tests and rspec for functional/unit testing.
Using Cucumber how do I simulate the post from the external website so that I can test the flows with the application.
It doesn't really matter to the application where the call originated; only that the parameters supplied match the expected ones from the referring page. If you depend on a specific HTTP_REFERER being set, check out this answer on how to set a header in Cucumber.
add_headers({'HTTP_REFERER' => 'http://referringsite.com'})
Since you already know which query parameters/headers your app expects from the referring site you can create a setup block that will set these appropriately for each cuke.
If you are using Cucumber with Capybara you can do a HTTP POST like this.
When /^I sign in$/ do
#user = Factory(:user)
get "/login"
page.driver.post sessions_path, :username => #user.username, :password => #user.password
end
Alternatively if you have a view it would be something like this.
When /^I sign in$/ do
#user = Factory(:user)
visit "/login"
fill_in "Username", :with => #user.username
fill_in "Password", :with => #user.password
click_button "Log in"
end

Resources