Receiving a text message in Rails app (Twilio SMS) - ruby-on-rails

Does anybody have any example code on how this would work? Seems like it should be pretty straightforward, but the Twilio documentation is sparse for SMS/Rails.
I have a simple "post" model with a "body" column and "from" column. I just want to display the SMS messages in a list. The closest thing I got to work was something like this:
#posts_controller.rb
class PostsController < ApplicationController
def new
#post = Post.new(:body=>"?",:from=>"?")
#post.save
end
end
#twilio sms url: ...myappurl/posts/new
This creates a new post, but the 'from' and 'body' values are "?", obviously. How do I pass the Twilio SMS 'From' and 'Body' values into the rails controller?
Any ideas or a nudge in the right direction? Thanks!

Just solved it! It was as simple as I thought it was.
In my posts_controller.rb file:
def twilio_create
#post = Post.new(:body => params[:Body], :from => params[:From])
#post.save
end
This effectively pulls the Body and From params from Twilio. The same can be applied for other params (SmsMessageSid, AccountSid, etc).
You can see the full list of parameters sent with Twilio's request here.

Related

Is there another way to refactor after adding new column: Sinatra Web App

I am still new to using the Sinatra Framework. I was asked to add a new column :description, and to refactor this current line of code in my POST request for editing a new list to include the :description column: #list.update(params.select{|k|k== "name"})
I am unsure of not only refactoring it to include the :description but to make it shorter.
Here is the full POST request block
post "/lists/:id" do
redirect_if_not_logged_in
#list = List.find(params[:id])
unless List.valid_params?(params)
redirect "/lists/#{#list.id}/edit?error=invalid list"
end
#list.update(params.select{|k|k== "name"})
redirect "/lists/#{#list.id}"
end
I did add the new column without issue and have an idea of what to put in my Edit & New forms, the controller action is where I am stuck.
Update:
I found the answer to my own question.
I refactored my original post request to reflect this change:
post "/lists/:id" do
#list = List.find(params[:id])
if #list.update(params)
redirect "/lists/#{#list.id}"
else
redirect "/lists/edit"
end
end

Twilio can't find xml on rails

I am integrating twilio click to call into my rails project.
Everything works fine however the url: in my twilio controller cannot be found on heroku. However, it can be found if you navigate to it in a browser. The phone dials but the voice says "Sorry a problem has occurred, good bye." If I change the url to an external xml file it works fine, just doesn't recognize this particular one. So I'm lead to believe that the controller etc works fine.
twillio_controller.rb
def call
#full_phone = current_user.phone
#partial_phone = #full_phone.last(-1)
#connected_number = "+61" + #partial_phone
#client = Twilio::REST::Client.new ##twilio_sid, ##twilio_token
# Connect an outbound call to the number submitted
#call = #client.calls.create(
:from => ##twilio_number,
:to => #connected_number,
:url => 'http://besttradies.herokuapp.com/mytradies/connect.xml', # Fetch instructions from this URL when the call connects
)
#msg = { :message => 'Phone call incoming!', :status => 'ok' }
end
def connect
# Our response to this request will be an XML document in the "TwiML"
# format. Our Ruby library provides a helper for generating one
# of these documents
response = Twilio::TwiML::Response.new do |r|
r.Say 'If this were a real click to call implementation, you would be connected to an agent at this point.', :voice => 'alice'
end
render text: response.text
end
The OP solved in the comments above:
Figured it out. Routes for connect needed to be POST and I also had to
add skip_before_action :verify_authenticity_token to the twilio
controller as it was behind membership doors.

Setting Up Rails to Receive HTTP POST Request

Is setting up Rails to receive a HTTP POST request that sends information encoded in JSON form as easy as adding the following code to the sessions_controller? Or are there other steps involved?
def create
if user = User.authenticate(params["email"], params["password"])
session[:user_id] = user.id
render:json => "{\"r\": \"t\"}" + req
else
render :json => "{\"r\": \"f\"}"
end
end
Should be that easy, though you will need to add a route to your routes.rb file as well specifying POST as the HTTP verb and pointing it to sessions#create. You also might want to use strong parameters just to validate what parameters are required and which you'll accept. As a heads up, I'm not entirely sure what "{\"r\": \"t\"}" + req is supposed to represent. It looks like req would be undefined in this case, but perhaps you're just omitting some code. Lastly, render :json => ... is sort of the old way of including a hash. I believe as of Ruby 2 the standard is something more like render json: .... Hopefully that helps.

Does the twilio-ruby gem handle SMS responses?

The only reference to SMS on the readme file is regarding sending SMS messages.
# send an sms
#client.account.sms.messages.create(
:from => '+14159341234',
:to => '+16105557069',
:body => 'Hey there!'
)
I'm wondering if the twilio-ruby gem provides visibility to SMS responses? I want to do some keyword response logic like the example they give here in PHP.
For others who may have this issue, I found this example application from this question to be very useful. What you need to do is:
Setup your Twilio Number SMS URL to Post to a certain controller in your application (e.g., myapp.com/twilio/process-sms)
Add a route to match that URL to the correct action in your Twilio controller
Write some simple logic like below to process responses/messages to your number according to your custom business logic
Respond, if necessary, using a .xml.erb file like the one below
class TwilioController < ApplicationController
def process_sms
#city = params[:FromCity].capitalize
#state = params[:FromState]
#from = params[:From]
u = User.find_by_phone_number(#from)
#user = u.name
b = params[:Body]
if b.downcase.include?("question")
#type = "Question"
#question = u.questions.build(:description => b)
#question.save!
render 'new_question.xml.erb', :content_type => 'text/xml'
elsif b.downcase.include?("contact")
#type = "Contact"
#contact = u.contacts.build(:name => b)
#contact.save!
render 'new_contact.xml.erb', :content_type => 'text/xml'
else
#type = "Not sure"
render 'not_sure.xml.erb', :content_type => 'text/xml'
end
The .build will create the object and the .save will save the object. Then you just return to Twilio the TWIML that you want to respond to the user. such as:
app/views/twilio/new_contact.xml.erb
<Response>
<Sms>We added a new contact for you.</Sms>
</Response>
When you get an SMS on your Twilio number, Twilio will make an HTTP request to your server. You can respond to the incoming SMS by responding to the request with XML, like this:
<Response>
<Sms>This is my response</Sms>
</Response>
You can either generate the XML response yourself, or the helper libraries contain methods that help you return XML to the client. I would suggest taking a look at the Twilio Ruby SMS quickstart for a simple example, and then going from there.

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