Twilio REST update call error - rest

I followed this page to update a call to a conference room.
Everytime I try to call the update function, I get an error:
No 'To' number is specified.
Even if I go the standard Twiml where the call entered, it says that. Nowhere in the document is stated that you need a To number.
The code I used:
$call = $tokens['client']->account->calls->get($call_sid);
$call->update(array(
"Url" => $app["request"]->getSchemeAndHttpHost() . "/dial/api/assign_redirect?callsid=" . $call_sid,
"Method" => "POST"
));
The twiml where it is redirected to:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say voice="woman">Thank you for your patience. You are now connecting with an agent</Say>
<Dial record="true">
<Conference startConferenceOnEnter="false" endConferenceOnExit="true" eventCallbackUrl="{{ url('API-record') }}" record="record-from-start">{{ callsid }}</Conference>
</Dial>
The other Twiml where the call is accepted:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial record='record-from-answer' callerId='{{ callerId }}'>
{{ numberOrClient|raw }}
</Dial>
</Response>
Twilio support was no help, they pointed me at: https://www.twilio.com/docs/errors/21201 which makes no sense.
I tried a bunch of question on SO already like :
Twilio - How to move an existing call to a conference
Move Twilio call to a conference room
Twilio - How to dial third party number and add him to conference?
Only the last one worked for me. But that creates a third leg. I want to stick to the existing ones. Anyone has a clue how to fix this?
Thanks in advance!
Edit: I am using the v4 of the PHP library.

I fixed it by getting both call_sids of the legs and creating an iterator like in the docs. If you forward the result the To error is gone, it is a bit more extensive and is way slower then the get, but it works.

Related

Twilio - 12200 Schema validation warning Description Invalid content was found starting with element 'HangUp'. One of '{Play

I am getting the following error from Twilio.
12200 Schema validation warning Description Invalid content was found starting with element 'HangUp'. One of '{Play
POST URL:http://b0dd02a0.ngrok.io/MSservice/PostCall
The markup is formed like this.
<Response>
<Say>Hi</Say>
<HangUp/>
</Response>
There is no need to add the explicit hang up call.
Change your response to
<Response>
<Say>Hi</Say>
</Response>
The application will say Hi and then hang up because there are no more instructions.

Twilio not using the username / password defined on the xml

I'm placing a SIP call, and the xml looks like this
<Response>
<Dial>
<Sip username="myusername" password="mypass">sip:myext#mydomain.com</Sip>
</Dial>
</Response>
When I look into the SIP packets I see, on the second INVITE
From: "+1XXXXXXXXXX" <sip:+1XXXXXXXXXX#sip.twilio.com>;tag=78774647_6772d868_43fb2951-f4f9-4c80-8377-9bb50e9458ae
And no references to myusername... it looks like Twilio is just not sending it, and using the caller id on the from, which is obviously not recognised by my server. On the Asterisk side, I just see
[Oct 17 19:22:58] NOTICE[9150]: chan_sip.c:22614 handle_request_invite: Sending fake auth rejection for device "+1XXXXXXXXXX" <sip:+1XXXXXXXXXX#sip.twilio.com>;tag=78774647_6772d868_43fb2951-f4f9-4c80-8377-9bb50e9458ae
Which kind of makes sense... on my sip.conf, I have
[myusername]
context = somecontext
type = user
secret = mypass
permit=107.21.222.153
permit=107.21.211.20
permit=107.21.231.147
permit=54.236.81.101
permit=54.236.96.128
permit=54.236.97.29
permit=54.236.97.135
permit=54.232.85.81
permit=54.232.85.82
permit=54.232.85.84
permit=54.232.85.85
permit=54.228.219.168
permit=54.228.233.229
permit=176.34.236.224
permit=176.34.236.247
permit=46.137.219.1
permit=46.137.219.3
permit=46.137.219.35
permit=46.137.219.135
permit=54.249.244.21
permit=54.249.244.24
permit=54.249.244.27
permit=54.249.244.28
I'm kind of stuck here... if anyone could give me a hint I'd really appreciate it
Ok... I figured it out. As I guess lots of people will want to integrate twilio with their Asterisks, here's what happened.
The issue is that my server wasn't recognising the user, and it seems like the user/pass is sent after this (twilio doesn't send the user on the From). So, you need to make it type=peer and then use the host=ip to identify twilio. But... they have 23 ips... so, I used templates.
But for every new ip you add you're adding a new sip device, so you should know which IP twilio is going to use to know which username you need to send. The answer is using allowguest=yes on the template... what's good about this, is that it already recognized twilio's ip, so our guest is actually twilio.
This is the xml I'm passing to twilio now
<Response>
<Dial>
<Sip>sip:myext#mydomain.com</Sip>
</Dial>
</Response>
(loving the idea of not sending my username and password on it, hating that I bought an SSL cert just to protect them) and this is how my sip.conf ended up looking
[twiliocaller](!)
context = somecontext
type = peer
qualify=no
allowguest=yes
[twilioip-1](twiliocaller)
host=107.21.222.153
[twilioip-2](twiliocaller)
host=107.21.211.20
[twilioip-3](twiliocaller)
host=107.21.231.147
[twilioip-4](twiliocaller)
host=54.236.81.101
[twilioip-5](twiliocaller)
host=54.236.96.128
[twilioip-6](twiliocaller)
host=54.236.97.29
[twilioip-7](twiliocaller)
host=54.236.97.135
[twilioip-8](twiliocaller)
host=54.232.85.81
[twilioip-9](twiliocaller)
host=54.232.85.82
[twilioip-10](twiliocaller)
host=54.232.85.84
[twilioip-11](twiliocaller)
host=54.232.85.85
[twilioip-12](twiliocaller)
host=54.228.219.168
[twilioip-13](twiliocaller)
host=54.228.233.229
[twilioip-14](twiliocaller)
host=176.34.236.224
[twilioip-15](twiliocaller)
host=176.34.236.247
[twilioip-16](twiliocaller)
host=46.137.219.1
[twilioip-17](twiliocaller)
host=46.137.219.3
[twilioip-18](twiliocaller)
host=46.137.219.35
[twilioip-19](twiliocaller)
host=46.137.219.135
[twilioip-20](twiliocaller)
host=54.249.244.21
[twilioip-21](twiliocaller)
host=54.249.244.24
[twilioip-22](twiliocaller)
host=54.249.244.27
[twilioip-23](twiliocaller)
host=54.249.244.28
Hope it saves some of your time! I also wrote a blog post about this at http://blog.gmc.uy/2013/10/asterisk-twilio-receiving-calls-from.html

Customer Address Field is Mandatory?

A client of our IA app just reported a slew of IDS synch error messages like:
Error updating customer in Intuit Data Services. Error message was: empty addresses not allowed party_id = 679598
I looked at your new online docs and see that the Object Reference indicates that the customer address is "mandatory". Is this something new? If so, since when? Customers have been synching successfully with empty addresses up to now, this change took us completely unaware (if indeed it is a change). Is there some way you can apprise us of upcoming changes so we can act proactively? Also, what exactly qualifies as an "empty" address? What fields exactly, at a minimum, need to be non-empty? For example, if "State" is filled in is that enough?
BTW, what is party_id and how can I use it to identify the customer object?
Thanks in advance.
It's not a required field to add/update a customer but if you are including the XML address fields tag in your request, then you must enter a value for it. If you don't want to update the address then leave it out.
thanks,
Jarred
Example:
<?xml version="1.0" encoding="UTF-16"?>
<Mod xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" RequestId="7699faaff20f4e16987e26bddbbf9461" xmlns="http://www.intuit.com/sb/cdm/v2">
<ExternalRealmId>156234822</ExternalRealmId>
<Object xsi:type="Customer">
<Id>43497400</Id>
<SyncToken>1</SyncToken>
<MetaData>
<CreatedBy>app</CreatedBy>
<CreatedById>1</CreatedById>
<CreateTime>2010-06-18T03:48:36</CreateTime>
<LastModifiedBy>app</LastModifiedBy>
<LastModifiedById>1</LastModifiedById>
<LastUpdatedTime>2010-06-18T03:48:36</LastUpdatedTime>
<MetaData>
<Synchronized>false</Synchronized>
<PartyReferenceId>51077676</PartyReferenceId>
<TypeOf>Person</TypeOf>
<Name>Jane Doe</Name>
<ShowAs>Jane</ShowAs>
</Object>
</Mod>

Is it possible to add an attribute to an XML Root using nusoap's call() function?

I am creating a class that will be utilizing the Fedex Web Services. I am attempting to communicate through the nusoap php class's nosoapclient() function, passing it a wsdl file. It seems Fedex requires a namespace attribute in the document root of a request.
I can use nusoap's call() function and pass it an XML string as the PARAMETER agrument which WILL WORK properly. I would rather pass an array through as the PARAMETER argument, and this is where I am running into an issue.
Is it possible to pass an array through nusoap's call() function and also include a namespace attribute in the root?
FEDEX RateRequest PHP exerpt
The following is to give an idea of what I am trying to do and not actual code
$client = new nusoapclient('RateRequest_v9.wsdl',true);
//Thought this would work but to no avail.
//$request_array is a multi-associative array with keys as required XML tag names and values as the tags inner value, did not include as it is irrelevant to this problem
//$root_attr = array('xmlns'=>'http://fedex.com/ws/rate/v9');
//$parameters = array('RateRequest'=>new soapval('RateRequest',false,$request_array,false,false,$root_attr));
$parameters = array('RateRequest'=>$request_array);
//Have tried with and without the third argument - which is the for the namespace
$response = $client->call('getRates',$parameters,'http://fedex.com/ws/rate/v9');
FEDEX RateRequest XML excerpt
The following is not the full XML (look at the RateRequest tag toward the end to see the difference)
INCORRECT FORMAT
<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns="http://fedex.com/ws/rate/v9"><SOAP-ENV:Body><RateRequest>...</RateRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>
CORRECT FORMAT
<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns="http://fedex.com/ws/rate/v9"><SOAP-ENV:Body><RateRequest xmlns="http://fedex.com/ws/rate/v9">...</RateRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>
My apologies in advance if I have missed this conversation elsewhere but I have been scouring the net and trying everything I could think of to make it work, if its not possible any suggestions? Thank you in advance for your assistance.

SOAP Action WSDL

I'm trying to implement a client for National Rail Enquiries' SOAP Service (http://www.livedepartureboards.co.uk/ldbws/).
I stick the WSDL (http://realtime.nationalrail.co.uk/ldbws/wsdl.aspx) into http://soapclient.com/soaptest.html, but I get back the error message "Unable to handle request without a valid action parameter. Please supply a valid soap action."; what on earth should the action be?
Thanks,
Stewart
edit:
I just used soapclient.com as a quick example. In my software, I send the following XML; I still get that I'm missing an action.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://thalesgroup.com/RTTI/2008-02-20/ldb/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:ldbt2="http://thalesgroup.com/RTTI/2008-02-20/ldb/types" xmlns:ldbt="http://thalesgroup.com/RTTI/2007-10-10/ldb/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ct="http://thalesgroup.com/RTTI/2007-10-10/ldb/commontypes" >
<SOAP-ENV:Body>
<ldbt2:GetDepartureBoardRequest xmlns:ldbt2="http://thalesgroup.com/RTTI/2008-02-20/ldb/" >
<ldbt2:numRows>5</ldbt2:numRows>
<ldbt2:crs>WAT</ldbt2:crs>
<ldbt2:filterCrs>GLD</ldbt2:filterCrs>
<ldbt2:filterType>to</ldbt2:filterType>
<ldbt2:timeOffset>0</ldbt2:timeOffset>
</ldbt2:GetDepartureBoardRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
If its a SOAP 1.1 service then you will also need to include a SOAPAction HTTP header field:
http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383528
I have come across exactly the same problem when trying to write a client for the National Rail SOAP service with Perl.
The problem was caused because the Perl module that I'm using 'SOAP::Lite' inserts a '#' in the SOAPAction header ...
SOAPAction: "http://thalesgroup.com/RTTI/2008-02-20/ldb/#GetDepartureBoard"
This is not interpreted correctly by .NET servers. I found this out from Example 3-19 in O'Reilly's Programming Web Services with SOAP . The solution was given below in section 3-20, namely you need to explicitly specify the format of the header with the 'on_action' method.
print SOAP::Lite
-> uri('urn:Example1')
-> on_action(sub{sprintf '%s/%s', #_ })
-> proxy('http://localhost:8080/helloworld/example1.asmx')
-> sayHello($name)
-> result . "\n\n";
My guess is that soapclient.com is using SOAP::Lite behind the scenes and so are hitting the same problem when talking to National Rail.
The solution is to write your own client so that you have control over the format of the SOAPAction header ... but you've probably done that already.
SOAPAction is required in SOAP 1.1 but can be empty ("").
See https://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383528
"The header field value of empty string ("") means that the intent of the SOAP message is provided by the HTTP Request-URI."
Try setting SOAPAction=""
When soapAction is missing in the SOAP 1.2 request (and many clients do not set it, even when it is specified in WSDL), some app servers (eg. jboss) infer the "actual" soapAction from {xsd:import namespace}+{wsdl:operation name}.
So, to make the inferred "actual" soapAction match the expected soapAction, you can set the expected soapAction to {xsd:import namespace}+{wsdl:operation name} in your WS definition (#WebMethod(action=...) for Java EE)
Eg. for a typical Java EE case, this helps (not the Stewart's case, National Rail WS has 'soapAction' set):
#WebMethod(action = "http://packagename.of.your.webservice.class.com/methodName")
If you cannot change the server, you will have to force client to fill soapAction.
I've just spent a while trying to get this to work an have a written a Ruby gem that accesses the API. You can read more on it's project page.
This is working code in Ruby:
require 'savon'
client = Savon::Client.new do
wsdl.document = "http://realtime.nationalrail.co.uk/LDBWS/wsdl.aspx"
end
response = client.request 'http://thalesgroup.com/RTTI/2012-01-13/ldb/GetDepartureBoard' do
namespaces = {
"xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/",
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema"
}
soap.xml do |xml|
xml.soap(:Envelope, namespaces) do |xml|
xml.soap(:Header) do |xml|
xml.AccessToken do |xml|
xml.TokenValue('ENTER YOUR TOKEN HERE')
end
end
xml.soap(:Body) do |xml|
xml.GetDepartureBoardRequest(xmlns: "http://thalesgroup.com/RTTI/2012-01-13/ldb/types") do |xml|
xml.numRows(10)
xml.crs("BHM")
xml.filterCrs("BHM")
xml.filterType("to")
end
end
end
end
end
p response.body
Hope that's helpful for someone!
We put together Web Services on Windows Server and were trying to connect with PHP on Apache. We got the same error. The issue ended up being different versions of the Soap client on the different servers. Matching the SOAP versions in the options on both servers solved the issue in our case.
the service have 4 operations:
1. GetServiceDetails
2. GetArrivalBoard
3. GetDepartureBoard
4. GetArrivalDepartureBoard
I have solved this problem, in Java Code, adding:
MimeHeaders headers = message.getMimeHeaders();
headers.addHeader("SOAPAction", endpointURL);