Can I use string interpolation in a Twilio verb? - ruby

When I receive a call, I output the CallSid parameter and save it as a variable #incoming_Cid to track the call throughout it's duration and manipulate it.
When I try to bridge the call in between a customer and an employee, I dial a conference. I'd like to use the #incoming_Cid as the friendly name to make the conference unique every time.
Example:
puts params['CallSid']
#incoming_Cid = params['CallSid']
Twilio::TwiML::Response.new do |r|
r.Dial :action => '/greeting/handle-gather/techsupp/conference', :method => 'get' do |d|
d.Say 'Please wait while we connect you to one of our operators. '
d.Conference "#{incoming_Cid}"
end
end
Normally, I have the friendly name in ' ', but string interpolation requires " ". So I'm not sure if what I'm trying to do is correct/allowed?
Also, how can I output the sid params of a dialed conference like described here.

You are definitely going in the right direction here.
There are a few suggestions I would make to accomplish what you are going for. Here is my modified snippet:
puts params['CallSid']
#incoming_Cid = params['CallSid']
response = Twilio::TwiML::Response.new do |r|
r.Dial :action => '/greeting/handle-gather/techsupp/conference', :method => 'get' do |d|
d.Say 'Please wait while we connect you to one of our operators. '
d.Conference #incoming_Cid
end
end
puts response.text
The changes I made are assigning your TwiML::Response to the response variable and outputting the TwiML text at the end which will be your generated XML response.
I also changed your d.Conference line to simply output #incoming_Cid without putting it in quotes, which in this case should work as valid Ruby.
Hope this helps!

Related

loop through json array and retrieve one attribute, gives errors also

i am new to programming in ruby, and i am trying to get the value of json['earning_rate_hr'] but i get an error, in '[]': no implicit conversion of String into Integer (TypeError)
i know and i understand the error, however this is not my main question here is my file :
checkingchecker.rb :
#require_relative '../lib/hackex/net/typhoeus'
require_relative '../lib/hackex'
require 'rubygems'
require 'json'
file = 'accounts1.txt'
f = File.open file, 'r'
puts "MADE BY THE PEOPLE, FOR THE PEOPLE #madebylorax"
puts ""
puts "--------------------------------------------------------"
puts ""
while line = f.gets
line = line.chomp.split(';')
email, password = line
puts "logging in as " + email
HackEx.LoginDo(email, password) do |http, auth_token, user|
puts "getting info..."
user = HackEx::Request.Do(http, HackEx::Request.UserInfo(auth_token))['user']
puts "receieved user info!"
bank = HackEx::Request.Do(http, HackEx::Request.UserBank(auth_token))['user_bank']
puts "recieved bank info!"
json = HackEx::Request.Do(http, HackEx::Request.UserSpam(auth_token))['spam']
puts "recieved spam info!"
puts json['earning_rate_hr'] #error line, the error is because this is an array, and it cant be turned into integer, i was wondering if there is a way to use puts on it without trying to make it an integer
userchecking = bank["checking"]
checking = userchecking.scan(/.{1,3}/).join(',')
puts email + " has in Checking: BTC #{checking}"
puts ""
puts "--------------------------------------------------------"
puts ""
end
end
i tried to do puts json, it puts items like this one :
{"id"=>"9867351", "user_id"=>"289108", "victim_user_id"=>"1512021",
"victim_ip"=
"86.60.226.175", "spam_level"=>"50", "earning_rate_hr"=>"24300", "total_earning s"=>"13267800", "started_at"=>"2015-11-01 07:46:59",
"last_collected_at"=>"2015- 11-24 01:46:59"}
what i want to do is select the earning_rate_hr for each one of them and add them together, however i do not have a clue on how to do that, since the error is not fixed and i cant get the value of it
ps : i tried turning it into a Hash, and i also tried using .first, but .first only shows the firs one, i want to show all of them, thank you
I know you from line messenger, I haven't used ruby codes in a long time and this one keeps giving me cloudflare errors, I'm not sure if its because of server downtime/maintainance or whatever but yeah anyway heres your script, enjoy farming ;) -LineOne
PS, I changed a few strings to make it look a lil cleaner so you can see the spam income easier, and added the sleep (1) because sleeping for one second before reconnecting helps to prevent cloudflare errors
also you don't need to require json or rubygems in your hackex scripts because its required in the library so its all covered pre-user-input/script
require_relative 'libv5/lib/hackex'
while 1<2
begin
print'Filename: '
fn=gets.chomp
file = fn+'.txt'
f = File.open file, 'r'
puts "MADE BY THE PEOPLE, FOR THE PEOPLE #madebylorax" #helped by lineone
puts ""
puts "--------------------------------------------------------"
puts ""
while line = f.gets
line = line.chomp.split(';')
email, password = line
HackEx.LoginDo(email, password) do |http, auth_token, user|
puts "Retrieving Info..."
puts''
user = HackEx::Request.Do(http, HackEx::Request.UserInfo(auth_token))['user']
bank = HackEx::Request.Do(http, HackEx::Request.UserBank(auth_token))['user_bank']
json = HackEx::Request.Do(http, HackEx::Request.UserSpam(auth_token))['spam']
cash_count=0
tot_count=0
json.each do |j|
earn_rate = j['earning_rate_hr']
total= j['total_earnings']
cash_count+=earn_rate.to_i
tot_count+=total.to_i
end
print "#{email}: current earnings: #{cash_count} per hour, Total earnings #{tot_count},"
userchecking = bank["checking"]
checking = userchecking.scan(/.{1,3}/).join(',')
puts " #{checking} BTC in Checking"
puts ""
puts "--------------------------------------------------------"
puts ""
sleep 1
end
end
rescue
puts"#{$!}"
end
end
Thats fine you can also calculate the total income of your farms by adding new variables at the top example a=0 then adding the number at the end a+=tot_count
This should help:
earning_rates = json.map{|e| e["earning_rate_hr"]}
puts "Earning rates per hour: #{earning_rates.join(" ")}"
puts "Sum of earning rates: #{earning_rates.map{|e| e.to_i}.inject{|sum, x| sum + x}}"

How do I send two SMS messages in a chain to the same receiver with twilio?

I am working on a project that returns SMS messages to a user who has just sent a SMS message to the server.
The process is:
The user sends a SMS message to the server.
The server will send two SMS messages back to this user. Note that these are two separate short messages and will be sent pretty much at the same time.
I've got the sending part working, but just for sending one SMS message, not two. When I add more code to send another message only the second message part works, which means only the second message has been sent out, the first message has been ignored.
The code looks pretty much like:
else
sms = SMS.create(:body => params['Body'], :from => params['From'], :to => params['To'], :created_at => Time.now)
#return a random saved sms
return_secret = SMS.first(:offset => rand(SMS.count))
twiml = Twilio::TwiML::Response.new do |r|
r.Sms return_secret.body
#send another message to remind user for rating
ask_rating = remind_rating
if ask_rating
twiml = Twilio::TwiML::Response.new do |r|
r.Sms ask_rating
end
twiml.text
end
Does anyone know how to send two messages in Twilio?
You've got some variable shadowing going on with twiml. As you wrote it, the second message's code is inside of the first message's block. Yet, you refer to a variable with the same name as one outside of the block. I would try flattening your code so you aren't nesting like that.
I think the issue here is you're instantiating a second TwiML::Response object when you already have one, so you can just references the previous one which you assigned to r in the first block. You also called it r in the second block so you just remove the block that encloses it:
sms = SMS.create(:body => params['Body'], :from => params['From'], :to => params['To'], :created_at => Time.now)
#return a random saved sms
return_secret = SMS.first(:offset => rand(SMS.count))
twiml = Twilio::TwiML::Response.new do |r|
r.Sms return_secret.body
#send another message to remind user for rating
ask_rating = remind_rating
if ask_rating
r.Sms ask_rating
end
end
Also the blocks weren't balanced in the initial code snippet so I stripped out the else to make it syntactically accurate.
Thank you all, really appreciate your replies.
After consulting with twilio team, they gave me an example like this:
require 'rubygems'
require 'twilio-ruby'
require 'sinatra'
get '/sms-quickstart' do
twiml = Twilio::TwiML::Response.new do |r|
r.Message "Hey Monkey. Thanks for the message!"
r.Message "this is the 2nd message"
end
twiml.text
end
I just deleted
if ask_rating
twiml = Twilio::TwiML::Response.new do |r|
everything works...

Not all methods are getting called Sinatra

I am building a Ruby app using Sinatra and the Twilio api.
Over a phone call to my assigned Twilio number, the user gets prompted to record an audio message. Once that message is recored the user gets redirected to the following route where if the user dials 1 (or anything else), they should get redirected to their feed of msgs, but if the user dials 2, then the user's message gets deleted and should get redirected to a route where they can record a new message.
Here is my route:
get '/playback/handle-recording/:recordingSID' do
if params['Digits'] = '2'
delete(params['recordingSID'])
deletedMsg = "Audio deleted."
getRecord(deletedMsg)
else
getFeed()
end
end
helper methods:
helpers do
def delete(recording)
recording = client().account.recordings.get(recording)
recording.delete
end
def getFeed()
redirect '/feed'
end
def getRecord(appendMsg)
Twilio::TwiML::Response.new do |response|
if appendMsg
response.Say appendMsg
end
response.Say "Record your message."
response.Record :maxLength => '5', :trim => "trim-silence", :playBeep => "true", :action => '/playback', :method => 'get'
end.text
end
end
My issue is that whether the user lands in the "if" or the "else" the first method, getRecord(deletedMsg) is the one that gets called, and not the getFeed().
How can I fix my route so that if the user lands in the else he does get redirected to his feed page and not to the getRecords method.
Are you sure they're actually making it into the else? Ruby won't just randomly not execute what's in there for no good reason.
One thing you may want to look at is you are assigning, not comparing the params value:
if params['Digits'] = '2'
You'll want to do:
if params['Digits'] == '2'
That could definitely lead to some strange behavior in an if statement, like, for instance always executing one path.

Retrieving CallSid for incoming call

When my ruby script makes outgoing calls through Twilio, it's a piece of cake for me to find, output, and reuse the Call Sid for later as such :
#client = Twilio::REST:Client.new account_sid, auth_token
call = #client.account.calls.create({ :from=>'INC', :to=>'OUT', :url=>'URL', :method=>'GET'})
puts call.sid
This works fine for outgoing calls that I make myself.
The issue is when I try to get the call SID for incoming calls.
get '/greeting' do
Twilio::TwiML::Response.new do |r|
r.Say 'Hello. Welcome.'
r.Gather :numDigits => '1', :action => '/greeting/handle-gather', :method => 'get' do |g|
g.Say 'For X, press 1. For Y, press 2. For Z, press 3.'
end
end.text
puts Twilio::TwiML::Request.CallSid
CallSid = incoming_Cid
end
The incoming_Cid is then stored in a MYSQL database for later. I'm not sure if Twilio::TwiML::Request.CallSid is the correct way to get the request parameters that Twilio passes to my application.
How would I properly retrieve the CallSid for incoming calls?
Nevermind, the issue was been solved by simply using Ruby's params instead of the Twilio HTTP Request object:
puts params['CallSid']

Better way to assert that all user.name in an array of user start with a prefix using rspec?

Here is what I have. And that kind of work.
it "should filter by name" do
users = users.search(:name => "s")
users.each {|u|
u.name.should be_starts_with("s")
}
end
However, the error message returned by rspec is really poor...
expected starts_with?("s") to return true, got false
Is there a way to get a more precise message, showing the element that failed, or at least its index?
In a binary test like this, I would create two users, one that starts with an s, the other without. I would then check that only the expected element was returned.
like
set up a user(:name => "Sam") and user(:name => "Fred")
filtered_users.map(&:name).should =~ ["Sam"]
In the case of failure, you will see something like
expected ["Sam"]
got ["Fred", "Sam"]
This is much more explicit about what you are doing
The reason you are only getting expected true but got false is because the starts_with methods returns true or false and not the actual value.
I'm not sure that this is the best way, but you can output it yourself.
users.each {|u|
p u.name if !u.name.starts_with?("s")
u.name.should be_starts_with("s")
}
Here is the way I used few times in cases like this:
describe 'user' do
before :each do
#users = users.search(:name => "s")
end
#users.each do |u|
it "should filter user with name '#{u.name}'" do
u.name.should be_starts_with("s")
end
end
end
You will have failed user name in you example description.
I found here an interesting extension to the matchers from Rspec concerning each :
http://xtargets.com/2011/08/12/rspec-meta-expectations-over-collections
So I sticked that helper into my spec_helper
RSpec::Matchers.define :each do |meta|
match do |actual|
actual.each_with_index do |i, j|
#elem = j
i.should meta
end
end
failure_message_for_should do |actual|
"at[#{#elem}] #{meta.failure_message_for_should}"
end
that allows me to write
users.should each satisfy {|u| u.name.should be_starts_with 's'}
and the error message is then :
at[1] expected #User to satisfy block
which give me the first index of failure.
With some addition to the error message, I'm sure I could output the details of that object that didn't match, and that seem a pretty good solution.
Any thoughts? I'm not a rubyist, just getting started with rails. Would be nice to get more input from
This should provide you with far better failure messages
it "should filter by name" do
users = users.search(:name => "s")
users.each do |u|
u.name.should match /^s/
end
end
I agree with Corey that calling "be_starts_with" is rough. RSpec expectations are intended to be read fluidly as a sentence. They don't all have to use "be".

Resources