Sending Information Through Twilio Using Rails - ruby-on-rails-3

I have a Rails 3.2.18 app where I want to ship details of a call (includes name, age, and other information) to a recipient's phone that is already a field in the database.
So for instance a call has a unit assigned, and each unit has a medic (employee) assigned. In the medic model there's a phone field 281-444-555 (example number). What I want to be able to do in the calls controller is to send a SMS on create and update with the details of that call so it arrives on their phone as SMS.
I'm currently doing notifications to phones by using Email to SMS gateway 2813334444#vtext.com (example) using ActionMailer and it works "ok". But I really want to leverage Twilio.
Here's how I'm doing the mailer action to notify the medics of calls on create/update
calls_controller
def create
parse_times!
#call = Call.new(params[:call])
#call.dispatched_by = current_user.username
if #call.save
#call.send_mail(:new_call)
redirect_to calls_path, notice: "Call #{#call.incident_number} was successfully created.".html_safe
else
render :new
end
end
def update
parse_times!
#call = Call.find(params[:id])
respond_to do |format|
if #call.update_attributes(params[:call])
unless #call.call_status == "close"
#call.send_mail(:update_call)
end
format.html { redirect_to #call, notice: "Call #{#call.incident_number} was successfully updated.".html_safe }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #call.errors, status: :unprocessable_entity }
end
end
end
call_mailer
def new_call(medic, call)
#call = call
#medic = medic
mail to: [#medic.medic_sms, #medic.medic_email], :cc => "noreply#company.com", subject: "New Call: #{#call.incident_number}"
end
def update_call(medic, call)
#call = call
#medic = medic
mail to: [#medic.medic_sms, #medic.medic_email], subject: "Updated Call: #{#call.incident_number}"
end
call model (mailer method)
def send_mail(mail_type)
units.each do |unit|
CallMailer.send(mail_type, unit.incharge, self).deliver
CallMailer.send(mail_type, unit.attendant, self).deliver
end
end
end
This is working just fine for mailing the phones and emails of the medics, but I would like to add something similar using Twilio where I can ship the call details to them via SMS in the create and update action.
If anyone can point me in the right direction, I'd appreciate it. I have a Twilio account already and would like to put it to good use.
Update 08/03/14
I think I figured this out and got it working in a basic fashion. But I'd like to see if there's someway to cleanly pass #call object data into the :body => section. Right now I'm having to iterate over the specific fields I want to send (which are about 10 different fields). It would be nice if I could create a partial or template and pass it to :body => similar to how ActionMailer works. Any thoughts?
calls_controller.rb (working)
def update
parse_times!
#call = Call.find(params[:id])
respond_to do |format|
if #call.update_attributes(params[:call])
unless #call.call_status == "close"
unless #call.unit_ids.empty?
send_sms
end
#call.send_mail(:update_call)
end
format.html { redirect_to #call, notice: "Call #{#call.incident_number} was successfully updated.".html_safe }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #call.errors, status: :unprocessable_entity }
end
end
end
private
def send_sms
account_sid = 'AC5CCCCC'
auth_token = 'ATTTTT'
#client = Twilio::REST::Client.new account_sid, auth_token
#client.account.messages.create(
:from => '2814084444',
:to => #call.units.first.incharge.medic_phone,
:body => "incident_number #{#call.incident_number} patient name #{#call.patient_name}"
)
#client.account.messages.create(
:from => '2814084444',
:to => #call.units.first.attendant.medic_phone,
:body => "incident_number #{#call.incident_number} patient name #{#call.patient_name}"
)
end
end

Ok, I have this figured out now. I needed to do string interpolation in the :body element for Twilio to send the information out. Here is my final code and it's working and updated with a conditional to only fire Twilio if certain conditions are met.
calls_controller.rb
def update
parse_times!
#call = Call.find(params[:id])
respond_to do |format|
if #call.update_attributes(params[:call])
if !(#call.call_status == "close") && !(#call.unit_ids.empty?)
send_update_sms
#call.send_mail(:update_call)
end
format.html { redirect_to #call, notice: "Call #{#call.incident_number} was successfully updated.".html_safe }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #call.errors, status: :unprocessable_entity }
end
end
end
def send_update_sms
account_sid = 'AC5CCCC'
auth_token = 'ATTTT'
#client = Twilio::REST::Client.new account_sid, auth_token
#client.account.messages.create(
:from => '28140844444',
:to => #call.units.first.incharge.medic_phone,
:body => "Updated: #{#call.incident_number}/#{#call.units.map(&:unit_name).join(", ")}/#{#call.patient_name}/#{#call.patient_age}/#{#call.patient_sex.try(:sex)}/#{#call.nature.try(:determinant)}/#{#call.special_equipments.map(&:name).join(", ")}/#{#call.traffic_type}/#{transfer_from_address}/#{transfer_to_address} CHECK EMAIL FOR FULL CALL INFO"
)
#client.account.messages.create(
:from => '2814084444',
:to => #call.units.first.attendant.medic_phone,
:body => "Updated: #{#call.incident_number}/#{#call.units.map(&:unit_name).join(", ")}/#{#call.patient_name}/#{#call.patient_age}/#{#call.patient_sex.try(:sex)}/#{#call.nature.try(:determinant)}/#{#call.special_equipments.map(&:name).join(", ")}/#{#call.traffic_type}/#{transfer_from_address}/#{transfer_to_address} CHECK EMAIL FOR FULL CALL INFO"
)
end
def transfer_from_address
if #call.transferred_from.nil?
#call.transfer_from_other
else
#call.transferred_from.try(:facility_name) + ' ' + #call.transferred_from.try(:facility_address)
end
end
def transfer_to_address
if #call.transferred_to.nil?
#call.transfer_to_other
else
#call.transferred_to.try(:facility_name) + ' ' + #call.transferred_to.try(:facility_address)
end
end

Related

Devise: after_sign_in_path_for(resource) not working

I am using devise for user sign up/in. But when user signs in from public accessible pages, devise redirects to root_path.
I tried to use this:
def after_sign_in_path_for(resource)
request.referrer
end
When user tries to sign in, it gives error 'not redirected properly'.
Can anybody tell how to do it?
I believe if I am right what you want to do is override the redirect when a user sign in is to change the following method inside controllers/devise/sessions_controller.rb If you haven't generated devises controllers you generate devise controller. Having done that you will want to have something like the following inside your devise/sessions_controller.rb
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
# respond_with resource, :location => after_sign_in_path_for(resource)
if current_user.role? :administrator
redirect_to dashboard_path
else
redirect_to rota_days_path
end
end
In the above example by default the sessions_controller - create method uses the following: # respond_with resource, :location => after_sign_in_path_for(resource) which I have commented out. By adding a if statement that checks if the current_users role is an administrator. If they then they are redirected to the dashboard page. If not then they are redirected to the rota page.
Alternatively the devise helpers state that you could also do something like:
def after_sign_in_path_for(resource)
stored_location_for(resource) ||
if resource.is_a?(User) && resource.can_publish?
publisher_url
else
super
end
end
Hope this helps.
Update
def create
#hospital_booking = HospitalBooking.new(params[:hospital_booking])
respond_to do |format|
if #hospital_booking.save
format.html { redirect_to :back, notice: 'Photographer Shift was successfully created.' }
format.json { render json: #hospital_booking, status: :created, location: #hospital_booking }
else
format.html { render action: 'new' }
format.json { render json: #hospital_booking.errors, status: :unprocessable_entity }
end
end
end
What happens here is when the hospital_booking is saved it redirects back to the issue page instead of redirecting to another page. Further reading here: api dock- redirect_to

Rails 3 send mailer if user attribute is true?

I am sending an email whenever a new record is created in my Rails 3 application.
def new_resource_notification(resource)
#resource = resource
mail(:to => "admin#domain.com", :bcc => User.all.map(&:email), :subject => "New item added")
end
Resource Controller
# POST /resources
# POST /resources.json
def create
#resource = Resource.create( params[:resource] )
#resource.uploadedip_string = request.env['REMOTE_ADDR']
respond_to do |format|
if #resource.save
UserMailer.new_resource_notification(#resource).deliver
format.html { redirect_to #resource, notice: 'Resource was successfully created.' }
format.json { render json: #resource, status: :created, location: #resource }
else
format.html { render action: "new" }
format.json { render json: #resource.errors, status: :unprocessable_entity }
end
end
end
I am using Devise for the user authentication an have added a field called email_subscribe. I've also added a simple checkbox in the user profile view to enable and disable the subscription.
Everything is working correctly at the moment. All users receive an email when a new record is created and users can set and unset their subscription. What I am trying to do now is make the two work together.
How do I only send an email to the users who's email_subscribe is true?
mails = User.where(:email_subscriber => true)
mail(:to => "admin#domain.com", :bcc => mails, subject => "New item added")

Rails 3 basic validation not working with :prompt or :include_blank?

I have the following code in my view:
<%= f.select :user_id, user_all_select_options, :include_blank => '--Select a name-----' %>
It displays a list of users with --Select a name----- at the top. When a user doesn't select a name from the list and leaves --Select a name----- selected I get errors because the user_id is blank.
For reference the helper method code looks like this:
def user_all_select_options
User.all.map{ |user| [user.name, user.id] }
end
My model is as follows:
class Parcel < ActiveRecord::Base
attr_accessible :parcel, :received_at, :received_by, :chilled, :courier, :location, :passed_to, :user_id, :user, :content, :localip
validates :user_id, :presence => true
belongs_to :user
end
For some reason the validation doesn't appear to be running, however if I select a user from the drop down and add a validation for an other field input the application correctly shows the user a message stating which field is incorrectly empty.
Interestingly if I leave the select drop down as --Select a name----- and keep the additional validation, an exception is thrown. It doesn't prompt for the missing fields it just errors.
Here is the record during an error (this record was from when I had a validates presence check on the location field:
{"utf8"=>"✓", "authenticity_token"=>"wM4KPtoswp3xdv8uU4UasdadNsZi9yFZmk=", "parcel"=>{"user_id"=>"", "received_by"=>"dan", "content"=>"", "chilled"=>"0", "courier"=>"", "location"=>"", "passed_to"=>"", "received_at(3i)"=>"9", "received_at(2i)"=>"2", "received_at(1i)"=>"2013", "received_at(4i)"=>"22", "received_at(5i)"=>"59"}, "commit"=>"Receive this Parcel", "action"=>"create", "controller"=>"parcels"}
Where should I start looking? The errors that show are when the controller does an unless check against the user.
The parcel controller create method looks like this:
def create
#parcel = Parcel.new(params[:parcel])
#parcel.localip = request.env['REMOTE_ADDR']
#parcel.received_by = #parcel.received_by.upcase
unless #parcel.user.mobilenumber.blank?
UserMailer.parcel_notification(#parcel).deliver
end
respond_to do |format|
if #parcel.save
format.html { redirect_to #parcel, notice: 'Parcel was successfully created.' }
format.json { render json: #parcel, status: :created, location: #parcel }
else
format.html { render action: "new" }
format.json { render json: #parcel.errors, status: :unprocessable_entity }
end
end
end
the reason why you're getting an exception when you don't select a user is this line
unless #parcel.user.mobilenumber.blank?
since the user_id is not set, #parcel.user is nil which causes the exception.
I suggest you move that inside the #parcel.save block.
def create
#parcel = Parcel.new(params[:parcel])
#parcel.localip = request.env['REMOTE_ADDR']
#parcel.received_by = #parcel.received_by.upcase
respond_to do |format|
if #parcel.save
unless #parcel.user.mobilenumber.blank?
UserMailer.parcel_notification(#parcel).deliver
end
format.html { redirect_to #parcel, notice: 'Parcel was successfully created.' }
format.json { render json: #parcel, status: :created, location: #parcel }
else
format.html { render action: "new" }
format.json { render json: #parcel.errors, status: :unprocessable_entity }
end
end
end

Avoid index url after failing create

When you create a User in rails through the create action, the url is changed to
http://myapplication.com/users with POST
before being redirected elsewhere. If validation fails, it appears that the above URL is retained. If you then refresh, you end up on the index page (as it's now a GET).
I would expect if validation was failed the url would remain as
http://myapplication.com/users/new
As i don't have an index page, this is causing me problems. Is there a way to resolve this please?
This depends on the logic in the respond_to block in your controller.
This is a typical example of the create action in users_controller.rb:
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: "new" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
So if the save fails, the new action is rendered again.
In your UsersController, do like this:
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to root_url # save success will return to root page
else
render 'new'
end
end

rails 3 route redirect error :id => "routename"

So I'm trying to have a link look up a method in my controller then redirect to a custom page with the path /trials/my_plays
I'm getting the error:
"Couldn't find Trail with id=my_plays" in the "app/controllers/trails_controller.rb:48:in `show'"
route:
match '/trails/my_plays', :to => "trails#my_plays", :as => :my_plays
link:
<%= link_to "Your Trails", trails_my_plays_path %>
controller:
def show
#trail = Trail.find(params[:id]) #48
#member = Member.find(current_user.member_id)
respond_to do |format|
format.html # show.html.erb
format.json { render :json => #trail }
end
end
def my_plays
#trails = Trail.all # once status is working, need to change to where(:publish => true)
#follower = Play.where(:member_id => current_user.member_id)
#member = Member.find(current_user.member_id)
#followed = [] #all trails followed by current user
#follows = [] #the play record for that trail
#trails.each do |trail|
if #follower.count > 0
#follower.each do |followr|
if (followr.trail_id == trail.id)
#followed << trail
#follows << followr
end
end
end
end
respond_to do |format|
format.html { redirect_to "trails/my_plays" }
end
end
Your match route is being superseded by a /trails routing that sets the id parameter.
A resource routing for trails (or other matching route, like :controller/:id) needs to come after your route matcher, otherwise the routing won't get past the first route match.