TwiML Exporting to Sinatra, but not actually sending SMS Messages - ruby

I am having an issue with outbound SMS thru TwiML Message functions. I am able to see my post on my Sinatra server session here:
== Sinatra (v2.0.0) has taken the stage on 4567 for development with backup from WEBrick
[2018-01-24 15:30:55] INFO WEBrick::HTTPServer#start: pid=67403 port=4567
<?xml version="1.0" encoding="UTF-8"?><Response><Message to="+1904XXXXXXX"><Body>Text Message Test for Devotional App. Please reply.</Body></Message><Message to="+1786XXXXXXX"><Body>Text Message Test for Devotional App. Please reply.</Body></Message><Message to="+1904XXXXXXX"><Body>Text Message Test for Devotional App. Please reply.</Body></Message></Response>
50.235.219.155 - - [24/Jan/2018:15:31:16 -0500] "POST /message HTTP/1.1" 200 - 0.0022
::1 - - [24/Jan/2018:15:31:16 EST] "POST /message HTTP/1.1" 200 0
- -> /message
I see the inbound logs here, but nothing outbound. I have even elevated this to a paid account to make sure it wasn't a trail thing.
This code is based on this walkthru.
My full ruby code for the app is here:
require 'yaml'
require 'open-uri'
require 'sinatra'
require 'twilio-ruby'
MY_NUMBER = '+1904XXXXXXXX'
def spreadsheet_url
'contacts.yml'
end
def sanitize(number)
"+1" + number.gsub(/^1|\D/, "")
end
def data_from_spreadsheet
file = open(spreadsheet_url).read
YAML.load(file)
end
def contacts_from_spreadsheet
contacts = {}
data_from_spreadsheet.each do |entry|
name = entry['name']
number = entry['phone_number'].to_s
contacts[sanitize(number)] = name
end
contacts
end
def contacts_numbers
contacts_from_spreadsheet.keys
end
def contact_name(number)
contacts_from_spreadsheet[number]
end
get '/' do
"Devotional Broadcast is Up & Running!"
end
get '/message' do
"Things are Working!"
end
post '/message' do
from = params['From']
body = params['Body']
media_url = params['MediaUrl0']
if from == MY_NUMBER
twiml = send_to_contacts(body, media_url)
else
twiml = send_to_me(from, body, media_url)
end
content_type 'text/xml'
puts twiml
end
def send_to_contacts(body, media_url = nil)
response = Twilio::TwiML::MessagingResponse.new do |r|
contacts_numbers.each do |num|
r.message to: num do |msg|
msg.body body
msg.media media_url unless media_url.nil?
end
end
end
puts response
end
def send_to_me(from, body, media_url = nil)
name = contact_name(from)
body = "#{name} (#{from}):\n#{body}"
response = Twilio::TwiML::MessagingResponse.new do |r|
r.message to: MY_NUMBER do |msg|
msg.body body
msg.media media_url unless media_url.nil?
end
end
puts response
end
Any help or insight would be great! Thanks!

I think I got it. Swapped out puts for .to_s Documentation Example here: Receive & Reply to SMS & MMS
post '/message' do
from = params['From']
body = params['Body']
media_url = params['MediaUrl0']
if from == MY_NUMBER
twiml = send_to_contacts(body, media_url)
else
twiml = send_to_me(from, body, media_url)
end
content_type 'text/xml'
twiml.to_s
end
def send_to_contacts(body, media_url = nil)
response = Twilio::TwiML::MessagingResponse.new do |r|
contacts_numbers.each do |num|
r.message to: num do |msg|
msg.body body
msg.media media_url unless media_url.nil?
end
end
end
response.to_s
end
def send_to_me(from, body, media_url = nil)
name = contact_name(from)
body = "#{name} (#{from}):\n#{body}"
response = Twilio::TwiML::MessagingResponse.new do |r|
r.message to: MY_NUMBER do |msg|
msg.body body
msg.media media_url unless media_url.nil?
end
end
response.to_s
end

Related

NameError - uninitialized constant Twilio::TwiML::Response (Possibly from old API Code?)

I am in need of some help with setting up a Twilio SMS Broadcast App running on Sinatra. They build is based off this tutorial: Send Mass SMS Broadcasts in Ruby
When I make an HTTP POST I get this message in my Terminal when running Sinatra & Ngrok.
NameError - uninitialized constant Twilio::TwiML::Response
Did you mean? Twilio::Response:
broadcast.rb:75:in `send_to_me'
broadcast.rb:53:in `block in <main>'
The code it is having an issue with is:
def send_to_contacts(body, media_url = nil)
response = Twilio::TwiML::Response.new do |r|
contacts_numbers.each do |num|
r.Message to: num do |msg|
msg.Body body
msg.Media media_url unless media_url.nil?
end
end
end
response.text
end
def send_to_me(from, body, media_url = nil)
name = contact_name(from)
body = "#{name} (#{from}):\n#{body}"
response = Twilio::TwiML::Response.new do |r|
r.Message to: MY_NUMBER do |msg|
msg.Body body
msg.Media media_url unless media_url.nil?
end
end
response.text
end
I have noticed most new Twilio walkthrus are now using API Auths & Tokens with an
#client = Twilio::REST::Client.new account_sid, auth_token
Is this something I need to be implementing? Any guidance on how I can migrate these two methods to that type of format and keep my features?
Thanks!
Update:
Twilio::TwiML::Response has been replaced by Twilio::TwiML::VoiceResponse & Twilio::TwiML::MessagingResponse. It worked when I changed the code to this:
def send_to_contacts(body, media_url = nil)
response = Twilio::TwiML::MessagingResponse.new do |r|
contacts_numbers.each do |num|
r.message to: num do |msg|
msg.body body
msg.media media_url unless media_url.nil?
end
end
end
puts response
end
def send_to_me(from, body, media_url = nil)
name = contact_name(from)
body = "#{name} (#{from}):\n#{body}"
response = Twilio::TwiML::MessagingResponse.new do |r|
r.message to: MY_NUMBER do |msg|
msg.body body
msg.media media_url unless media_url.nil?
end
end
puts response
end

Net::HTTP follow maximum of three redirects?

I have this method in my class:
def self.get(url)
#TODO We could test with https too
if url.match(/^http/)
correct_url = url
else
correct_url = "http://#{url}"
end
uri = URI.parse(correct_url)
if uri.respond_to? 'request_uri'
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
http.request(request)
else
puts "Incorrect URI"
end
end
Unfortunately it's not following the redirects.
Can someone tell me how to make this method allow a maximum of three redirects?
Try this:
def self.get(url)
# TODO: test with https too
url = "http://#{url}" unless url.match(/^http/)
3.times do
uri = URI.parse(url)
if uri.respond_to?(:request_uri)
response = Net::HTTP.get_response(uri)
case response.code
when '301', '302'
url = response.header['location']
else
return response
end
end
end
end

Ruby making a web request

Hi this is my very first Ruby program.
I'm trying to write a simple ruby app to make a request to a URL and see if it's available. If it is, it'll print OK and else it'll print false.
This is what I've got so far, can you please assist, do I need to import any libs?
class WebRequest
def initialize(name)
#name = name.capitalize
end
def makeRequest
puts "Hello #{#name}!"
#uri = URI.parse("https://example.com/some/path")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # read into this
#data = http.get(uri.request_uri)
end
end
req = WebRequest.new("Archie")
req.makeRequest
Here is sample code to do any request:
require 'net/http'
require 'uri'
url = URI.parse('http://www.example.com/index.html')
req = Net::HTTP::Get.new(url.path)
res = Net::HTTP.start(url.host, url.port) do |http|
http.request(req)
end
puts res.body
gem install httparty
then
require 'httparty'
response = HTTParty.get('https://example.com/some/pathm')
puts response.body
Something simpler:
[1] pry(main)> require 'open-uri'
=> true
[2] pry(main)> payload = open('http://www.google.com')
=> #<File:/var/folders/2p/24pztc5s63d69hhx81002bq80000gn/T/open-uri20131217-84948-ttwnho>
[3] pry(main)> payload.inspect
=> "#<Tempfile:/var/folders/2p/24pztc5s63d69hhx81002bq80000gn/T/open-uri20131217-84948-ttwnho>"
[4] pry(main)> payload.read
payload.read would return the response body and you can easy use payload as File object since it is an instance of Tempfile
This is what I've ended up with
require 'net/http'
class WebRequest
def initialize()
#url_addr = 'http://www.google.com/'
end
def makeRequest
puts ""
begin
url = URI.parse(#url_addr)
req = Net::HTTP::Get.new(url.path)
res = Net::HTTP.start(url.host, url.port) {|http|
http.request(req)
}
puts "OK Connected to #{#url_addr} with status code #{res.code}"
rescue
puts "Failed to connect to #{#url_addr}"
end
end
end
req = WebRequest.new()
req.makeRequest

In Mechanize how do I determine response type for a post_connect_hook

I am following Jimm Stout's suggestion for websites that don't set content-type.
agent = Mechanize.new do |a|
a.post_connect_hooks << ->(_,_,response,_) do
if response.content_type.empty?
response.content_type = 'text/html'
end
end
end
How do I avoid setting the Content-Type if I get a redirect, a 40x or a 50x.
You can make sure the response class is Net::HTTPOK.
agent = Mechanize.new do |a|
a.post_connect_hooks << ->(_,_,response,_) do
break unless response.class == Net::HTTPOK
if response.content_type.empty?
response.content_type = 'text/html'
end
end
end

Same request sent twice has two different responses

Please consider this test:
def test_ok_on_second_request
bad_response = #request.get "/bad-response"
assert_equal 404, bad_response.status
good_response = #request.get "/test-title"
assert_equal 200, good_response.status
assert_equal "text/html", good_response.content_type
end
I have assured that /test-title is a valid path. The assertion that's supposed to return 200 is in fact returning 404. How is Rack behaving in order to return two different results for the same request?
This is the code for the Server class inside the project:
module Blogrite
class Server
attr_accessor :status, :mimetype, :body, :provider
def initialize *args, &block
#status, #mimetype = 200, "text/html"
provider = args[0][:with].nil? ? :filesystem : args[0][:with]
#provider = Blogrite.const_get(provider.capitalize).new
# p "Server is running with #{#provider.class}."
end
def call env
begin
article = go env['PATH_INFO'].delete("/")
rescue Blogrite::Article::NoBodyError
#status = 404
end
#status = 404 if !article
#status = 403 if env["REQUEST_METHOD"] == 'POST'
#mimetype = "text/css" if env["PATH_INFO"].include?("css")
#body = if article then article.render
elsif env.respond_to?(:to_yaml) then "<pre>#{env.to_yaml}</pre>"
else "oops"
end
[#status,{ "Content-Type" => #mimetype},[#body]]
end
def go path
f = #provider.fetch path
Article.parse f unless f.nil?
end
end
end
The whole workflow is too big for me to paste it in but you can check the project out on Github. I appreciate your help, thank you.
The solution for the problem is as simple as initializing #status inside the call function.
class Server
attr_accessor :status, :mimetype, :body, :provider
def initialize *args, &block
- #status, #mimetype = 200, "text/html"
provider = args[0][:with].nil? ? :filesystem : args[0][:with]
#provider = Blogrite.const_get(provider.capitalize).new
# p "Server is running with #{#provider.class}."
end
def call env
begin
- article = go env['PATH_INFO'].delete("/")
+ #status, #mimetype = 200, "text/html"
+ article = go env['PATH_INFO'].delete("/")
rescue Blogrite::Article::NoBodyError
#status = 404
end
That way the rack instance – that is called only once – stays out of the request's way. Every call function should have its own defaults, not the server class.
Thanks to #rubenfonseca for helping me out.

Resources