how can I get details of a second leg call with twilio? - ruby

I want to get the call details, from a second leg call, and insert them into my database.
Here is the scenario: an inbound call to a toll-free number is routed to second phone. So there are 2 legs, 1) the inbound call to the toll-free number and then 2) connection to the second number.
The code for getting the call details for the FIRST leg is:
get '/hangup' do
user_key = numbers.where(:number => params["To"]).join(:credentials, :user_id => :user_id).get(:user_key)
user_token = numbers.where(:number => params["To"]).join(:credentials, :user_id => :user_id).get(:user_token)
call_sid = params["CallSid"]
call_parent_sid = ["ParentCallSid"]
#sub_account_client = Twilio::REST::Client.new(user_key, user_token)
#subaccount = #sub_account_client.account
call = #subaccount.calls.get(call_sid)
call_sid = call.sid,
call_parent_sid = call.parent_call_sid,
phone_number_id = call.phone_number_sid,
call_from = call.from,
call_to = call.to,
call_start = call.start_time,
call_end = call.end_time,
call_duration = call.duration,
charged_duration = ((call_duration.to_f)/60).ceil
call_price = call.price
call_charged_price = (charged_duration * 0.07)
call_logs.insert(:call_sid => call_sid, :call_parent_sid => call_parent_sid, :phone_number_id => phone_number_id, :call_from => call_from, :call_to => call_to, :call_start => call_start, :call_end => call_end, :call_duration => call_duration, :charged_duration => charged_duration, :call_price => call_price, :call_charged_price => call_charged_price)
end
This works after hangup and the status_callback_url is '/hangup'. But how can I get the same details for the second leg of the call. I have tried as follows:
get '/receive' do
destination_number = numbers.where(:number => params["To"]).join(:users, :id => :user_id).get(:primary_number)
user_id = numbers.where(:number => params["To"]).join(:users, :id => :user_id).get(:id)
greeting_url = voicemail.where(:user_id => user_id).get(:voicemail_play_url)
resp = Twilio::TwiML::Response.new do |r|
r.Dial destination_number, :status_callback => '/hangup_second_leg', :status_callback_method => 'GET'
etc..
This effectively attempts to create a second status_callback_url which, needless to say, did not work.
So, how can I get the details of the second (or even third) leg of a call and bung it into my DB?
Twilio evangelist .....
Many thanks in advance.

Twilio developer evangelist at your service!
I just ran a quick test and the parameters you get back from the hangup callback should include a "CallSid" and a "DialedCallSid" which are the two legs of your call. You can get hold of the data via normal calls to the REST api:
get '/hangup' do
call_sid = params["CallSid"]
dialed_call_sid = params["DialedCallSid"]
#sub_account_client = Twilio::REST::Client.new(user_key, user_token)
#subaccount = #sub_account_client.account
inbound = #subaccount.calls.get(call_sid)
outbound = #subaccount.calls.get(dialed_call_sid)
# Update calls in database
end
Alternatively, the inbound call is the parent of all the other calls that take part within the context of the call. So you can get the details on all the child calls with the following api calls:
#subaccount.calls.list parent_call_sid: params["CallSid"]
# => [<Twilio::REST::Call>, ...]
Also, if you are getting a ParentCallSid parameter in your hangup, then you can use the above code to look up the parent call and child calls from that too.
Hope this helps, let me know if there's anything else I can help with.

Related

how to amend a code to get query from external and save result to external

I have a code which looks like this
require 'net/http'
base = 'www.uniprot.org'
tool = 'mapping'
params = {
'from' => 'ACC+ID', 'to' => 'P_ENTREZGENEID', 'format' => 'tab',
'query' => 'A0A0K3AVS5 A0A0K3AVV4 A0A0K3AW32 A0A0K3AWP0'
}
http = Net::HTTP.new base
$stderr.puts "Submitting...\n";
response = http.request_post '/' + tool + '/',
params.keys.map {|key| key + '=' + params[key]}.join('&')
loc = nil
while response.code == '302'
loc = response['Location']
response = http.request_get loc
end
while loc
wait = response['Retry-After'] or break
$stderr.puts "Waiting (#{wait})...\n";
sleep wait.to_i
response = http.request_get loc
end
response.value # raises http error if not 2xx
puts response.body
which gives me what I need. however, I have two questions
1- How to load a query list instead I parse it into the code ? lets say I save a txt file with all the query i want to the desktop of a mac
2- How to export the output ?
If I have
B2D6P1
G5EC52
B2FDA8-2
B2MZB1
B3CJ34
B3CKG1
B3GWA1
what #tadman showed gives me the answer
however, I have the following
B2D6P1
G5EC52;B2D6P4
B2FDA8-2;B2FDA8
B2MZB1;P18834
B3CJ34
B3CKG1
B3GWA1;Q8I7K5
and the answer is like below
B2D6P1 rmd-2
G5EC52 tlf-1
B2D6P4 tlf-1
B2FDA8 smc-3
B2MZB1 col-14
P18834 col-14
B3CJ34 gcn-1
B3CKG1 urm-1
B3GWA1 nono-1
Q8I7K5 nono-1
what I want is that if I have two entries in each row (separated with ;) leading to the similar output , it gives me only one , otherwise give me as many as they have for example in above example , my desire output is
B2D6P1 rmd-2
G5EC52;B2D6P4 tlf-1
B2FDA8-2;B2FDA8 smc-3
B2MZB1;P18834 col-14
B3CJ34 gcn-1
B3CKG1 urm-1
B3GWA1;Q8I7K5 nono-1
is this possible ?
Reading query data:
query = File.readlines('ids.txt').map(&:chomp).join(' ')
That way you can have them on separate lines, easier to edit, and they're space separated when submitted.
That makes your params look like:
params = {
'query' => query,
...
}
Writing data:
File.open('output.txt', 'w') do |f|
f.write(response.body)
end
That's all there is to it. If it's a string, or can be converted to a string, you can write it to a file.

How to retrieve entire cost for a SoftLayer machine, including any extra costs such as bandwidth overages?

I've been retrieving monthly invoice cost information on our SoftLayer accounts for quite some time using the Ruby softlayer gem. However, there is a concern in the team that we may be missing certain costs, such as any overages on network utilization. I'd like to have some piece of mind that what I'm doing is correctly gathering all costs and we are not missing anything. Here is my code/query:
account = SoftLayer::Service.new("SoftLayer_Account",:username => user, :api_key => api_key, :timeout => 999999999)
softlayer_client = SoftLayer::Client.new(:username => user, :api_key => api_key, :timeout => 999999999)
billing_invoice_service = softlayer_client.service_named("Billing_Invoice")
object_filter = SoftLayer::ObjectFilter.new
object_filter.set_criteria_for_key_path('invoices.createDate', 'operation' => 'betweenDate', 'options' => [{'name' => 'startDate', 'value' => ["#{startTime}"]}, {'name' => 'endDate', 'value' => ["#{endTime}"]}])
# Set startDate and endDate around the beginning of the month in search of the "Recurring" invoice that should appear on the 1st.
invoices = account.result_limit(0,10000).object_filter(object_filter).object_mask("mask[id,typeCode,itemCount,invoiceTotalAmount,closedDate,createDate]").getInvoices
invoices.each do | invoice |
if invoice["typeCode"] == "RECURRING"
invoice_reference = billing_invoice_service.object_with_id(invoice["id"])
invoice_object = invoice_reference.object_mask("mask[itemCount]").getObject
billing_items_count = invoice_object["itemCount"]
billing_machines_map = Hash.new
all_billing_items = Array.new
# Search for billing items containing a hostName value.
# The corresponding billing item ID will become the key of a new hash.
# Child costs will be added to the existing costs.
billing_items_retrieval_operation = proc {
for i in 0..(billing_items_count/8000.0).ceil - 1
billing_items = invoice_reference.result_limit(i*8000, 8000).object_mask("mask[id,resourceTableId,billingItemId,parentId,categoryCode,hostName,domainName,hourlyRecurringFee,laborFee,oneTimeFee,recurringFee,recurringTaxAmount,setupFee,setupTaxAmount,location[name]]").getItems()
billing_items.each do | billing_item |
if billing_item["hostName"]
billing_machines_map[billing_item["id"]] = billing_item
end
end
all_billing_items.concat(billing_items)
end
}
# Look for items with parentIds or resourceTableIds.
# Both Ids represent a "parent" of the item.
# Give higher importance to parentId.
billing_items_retrieval_callback = proc {
cost_of_billing_items_without_parent = BigDecimal.new("0.00")
all_billing_items.each do | billing_item |
if billing_item["parentId"] != ""
parent_billing_machine = billing_machines_map[billing_item["parentId"]]
if parent_billing_machine parent_billing_machine["recurringFee"] = (BigDecimal.new(parent_billing_machine["recurringFee"]) + BigDecimal.new(billing_item["recurringFee"])).to_s('F')
parent_billing_machine["setupFee"] = (BigDecimal.new(parent_billing_machine["setupFee"]) + BigDecimal.new(billing_item["setupFee"])).to_s('F')
parent_billing_machine["laborFee"] = (BigDecimal.new(parent_billing_machine["laborFee"]) + BigDecimal.new(billing_item["laborFee"])).to_s('F')
parent_billing_machine["oneTimeFee"] = (BigDecimal.new(parent_billing_machine["oneTimeFee"]) + BigDecimal.new(billing_item["oneTimeFee"])).to_s('F')
end
elsif billing_item["resourceTableId"] != ""
parent_billing_machine = billing_machines_map[billing_item["resourceTableId"]]
if parent_billing_machine
parent_billing_machine["recurringFee"] = (BigDecimal.new(parent_billing_machine["recurringFee"]) + BigDecimal.new(billing_item["recurringFee"])).to_s('F')
parent_billing_machine["setupFee"] = (BigDecimal.new(parent_billing_machine["setupFee"]) + BigDecimal.new(billing_item["setupFee"])).to_s('F')
parent_billing_machine["laborFee"] = (BigDecimal.new(parent_billing_machine["laborFee"]) + BigDecimal.new(billing_item["laborFee"])).to_s('F')
parent_billing_machine["oneTimeFee"] = (BigDecimal.new(parent_billing_machine["oneTimeFee"]) + BigDecimal.new(billing_item["oneTimeFee"])).to_s('F')
end
else
cost_of_billing_items_without_parent = (BigDecimal.new(cost_of_billing_items_without_parent) + BigDecimal.new(billing_item["recurringFee"])).to_s('F')
cost_of_billing_items_without_parent = (BigDecimal.new(cost_of_billing_items_without_parent) + BigDecimal.new(billing_item["setupFee"])).to_s('F')
cost_of_billing_items_without_parent = (BigDecimal.new(cost_of_billing_items_without_parent) + BigDecimal.new(billing_item["laborFee"])).to_s('F')
cost_of_billing_items_without_parent = (BigDecimal.new(cost_of_billing_items_without_parent) + BigDecimal.new(billing_item["oneTimeFee"])).to_s('F')
end
end
pp "INVOICE: Total cost of devices for account without a parent is:"
pp cost_of_billing_items_without_parent
end
end
end
After the above I make calls to getVirtualGuests and getHardware to get some additional meta information for each machine (I tie them together based on billingItem.id. Example:
billingItemId = billing_machine["billingItemId"]
account_service = softlayer_client.service_named("Account")
filter = SoftLayer::ObjectFilter.new {|f| f.accept("virtualGuests.billingItem.id").when_it is(billingItemId)}
virtual_guests_array = account_service.object_filter(filter).object_mask("mask[id, hostname, datacenter[name], billingItem[orderItem[order[userRecord[username]]]], tagReferences[tagId, tag[name]], primaryIpAddress, primaryBackendIpAddress]").getVirtualGuests()
As you can see I don't make any calls to capture bandwith overage charges. I have printed out the various "category" values I get from the above query but I am not seeing anything specific to network utilization (it's possible there are no extra network utilization costs but I am not certain).
Thank you.
Any extra costs such as bandwidth overages will be included in the billing item from the server. So you don't need to make any other call to the api to get it.

How calculate the number prorated day with Stripe API?

i am using Stripe. I would like to know how can calculate number of day prorated
I want display something like that
1 additional seat ($9/month each - prorated for 26 days)
in the api i don't see any item prorate_day
Bolo
subscription_proration_date what you are looking for? Then it will calculate it for you.
See more at https://stripe.com/docs/subscriptions/guide
The example of pro-rated subscription in ruby is as follows
# Set your secret key: remember to change this to your live secret key in production
# See your keys here https://dashboard.stripe.com/account/apikeys
Stripe.api_key = "sk_test_9OkpsFpKa1HDHaZa7e0BeGaO"
proration_date = Time.now.to_i
invoice = Stripe::Invoice.upcoming(:customer => "cus_3R1W8PG2DmsmM9", :subscription => "sub_3R3PlB2YlJe84a",
:subscription_plan => "premium_monthly", :subscription_proration_date => proration_date)
current_prorations = invoice.lines.data.select { |ii| ii.period.start == proration_date }
cost = 0
current_prorations.each do |p|
cost += p.amount
end
# Display the cost of these prorations invoice items to the end user,
# and actually do the update when they agree.
# To make sure that the proration is calculated the same as when it was previewed,
# you need to pass in the proration_date parameter
# later...
subscription = Stripe::Subscription.retrieve("sub_3R3PlB2YlJe84a")
subscription.plan = "premium_monthly"
subscription.proration_date = proration_date
subscription.save

CodeIgniter ActiveRecord adding a random id field

$updatedOrder = array(
'ship_status' => 'shipped',
'shipped_carrier' => (string)$selectedShipper->shipper->name,
'base_rate' => (float)$selectedShipper->rate,
'discount_rate' => (float)$selectedShipper->rate,
'tracking_number' => '123',
);
$this->orders_m->where('id', $tmpOrder->id)
->update('orders', $updatedOrder);
This yields the following SQL query: UPDATE default_orders SET ship_status = 'shipped', shipped_carrier = 'UPS Next Day Air', base_rate = 22.85, discount_rate = 22.85, tracking_number = '123' WHERE id = '1' AND id = 'orders'
Where did that last bit come from? id='orders'?
Just make sure that $tmpOrder->id is a variable and not an array.
var_dump($tmpOrder->id);
Maybe there is an error somewhere where you are getting the $tmpOrder and it returns an array for that.

LINQ DataLoadOptions.loadwith

This is the code I have for loading my data entities.
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<msPlaylistItem>(m => m.tbMedia);
dlo.LoadWith<tbMedia>(a => a.tbArtists);
dlo.LoadWith<msNote>(n => n.tbMedia.msNotes);
db.LoadOptions = dlo;
dlo.LoadWith(n => n.tbMedia.msNotes); This is the line I am having a problem with. This is the error "The expression specified must be of the form p.A, where p is the parameter and A is a property or field member."
What I am trying to do is load the notes that are related to the each tbMedia object.
this is the correct line
dlo.AssociateWith <tbMedia>(t => t.msNotes.Where(n => n.MediaId == n.tbMedia.id));

Resources