Rails 3 XML Builder / Twilio API
-
28-09-2019 - |
문제
This Twilio API Sample code isn't working in Rails 3:
#voice_controller.rb
def reminder
@postto = BASE_URL + '/directions'
respond_to do |format|
format.xml { @postto }
end
end
#reminder.xml.builder
xml.instruct!
xml.Response do
xml.Gather(:action => @postto, :numDigits => 1) do
xml.Say "Hello this is a call from Twilio. You have an appointment
tomorrow at 9 AM."
xml.Say "Please press 1 to repeat this menu. Press 2 for directions.
Or press 3 if you are done."
end
end
Any ideas?
Twilio seems to successfully make the phone call (I can see the params with my phone number, location, etc.) but then return this vague response code:
Completed 406 Not Acceptable in 0ms
해결책
Twilio doesn't send an Accept HTTP header in its requests, which causes Rails 3 to decide that it can't respond with an appropriate content type. I think the following will get around that for you though:
# voice_controller.rb def reminder @postto = BASE_URL + '/directions' render :content_type => 'application/xml' end
다른 팁
Twilio employee here. There have been a bunch of changes to Rails since this original question was posted, and I wanted to share how you might tackle this problem using Rails 4, Concerns and the Twilio Ruby gem.
In the code sample below, I define the controller in /controllers/voice_controller.rb
and include a Concern called Webhookable. The Webhookable Concern lets us encapsulate logic related to Twilio webhooks (setting the HTTP response header to text/xml, rendering TwiML, validating that requests originate from Twilio, etc) into a single module.
require 'twilio-ruby'
class VoiceController < ApplicationController
include Webhookable
after_filter :set_header
# controller code here
end
The Concern itself lives in /controllers/concerns/webhookable.rb
and is fairly simple. Right now it simply sets the Content-Type to text/xml for all action and provides a method to render the TwiML object. I haven't included the code to validate that requests are originating from Twilio, but that would be easy to add:
module Webhookable
extend ActiveSupport::Concern
def set_header
response.headers["Content-Type"] = "text/xml"
end
def render_twiml(response)
render text: response.text
end
end
Finally, here's what your reminder
action might look like using the Twilio gem to generate TwiML and using the Concern to render this object as text:
def reminder
response = Twilio::TwiML::Response.new do |r|
r.Gather :action => BASE_URL + '/directions', :numDigits => 1 do |g|
g.Say 'Hello this is a call from Twilio. You have an appointment
tomorrow at 9 AM.'
g.Say 'Please press 1 to repeat this menu. Press 2 for directions.
Or press 3 if you are done.'
end
end
render_twiml response
end