We've Moved! Please visit our new and improved forum over at our new portal: https://portal.plumvoice.com/hc/en-us/community/topics
Immediate callback with no response
Immediate callback with no response
I'm using outbound dialing to execute a pre-generated VXML script, invoking http://outbound.plumgroup.com/webservice/queuecall.php with the following POST variables:
[login] => tdh@zogo.com
[pin] => xxxxxxxx
[phone_number] => 12018359707
[start_url] => http://72.18.130.66/staging/calls/14.vxml
[result_url] => http://72.18.130.66/staging/svc_callresult.php
[message_reference] => 14
[call_parameters] =>
[max_retries] => 2
[retry_interval] => 30
[scheduled_timestamp] => 0
[expiration_timestamp] => 0
I get no response to the POST, but my result_url is invoked immediately, but also with no GET or POST variables. I expected an XML document in return to the HTTP POST, and something to be sent to my callback URL.
The start_url is a pre-generated VXML document, is that possibly the problem? Also, none of my requests appear in any of the reports, so it seems like I'm not getting past something basic that I don't see.
Thanks for your help,
[login] => tdh@zogo.com
[pin] => xxxxxxxx
[phone_number] => 12018359707
[start_url] => http://72.18.130.66/staging/calls/14.vxml
[result_url] => http://72.18.130.66/staging/svc_callresult.php
[message_reference] => 14
[call_parameters] =>
[max_retries] => 2
[retry_interval] => 30
[scheduled_timestamp] => 0
[expiration_timestamp] => 0
I get no response to the POST, but my result_url is invoked immediately, but also with no GET or POST variables. I expected an XML document in return to the HTTP POST, and something to be sent to my callback URL.
The start_url is a pre-generated VXML document, is that possibly the problem? Also, none of my requests appear in any of the reports, so it seems like I'm not getting past something basic that I don't see.
Thanks for your help,
I spent more time with this, and now get an XML response that includes a 'queued' status and a call_id value. I was also able to get the error return back that told me my retry_interval of 30 seconds was too small.
My return_url is now a php script that returns the VXML instead of the VXML script itself, but is invoked immediately and with no POST values.
I notice that my code that reads the socket for return values from queuecall.php doesn't receive an EOF after the request body is returned. I simply stopped reading after receiving the XML, but I don't think that's right - it should see EOF on the socket.
So, something is still wrong but I don't know what. My account still shows no activity, even with the 'queued' status several times.
My return_url is now a php script that returns the VXML instead of the VXML script itself, but is invoked immediately and with no POST values.
I notice that my code that reads the socket for return values from queuecall.php doesn't receive an EOF after the request body is returned. I simply stopped reading after receiving the XML, but I don't think that's right - it should see EOF on the socket.
So, something is still wrong but I don't know what. My account still shows no activity, even with the 'queued' status several times.
Dorsey
IVR outbound system
When you initially queue an IVR call, the outbound IVR system will do a quick check of the start_url to make sure it's a valid page -- that's the fetch that you refer to with no POST values.
As far as not receiving any IVR calls -- it appears your "default" campaign is not running. You should activate that IVR campaign in the IVR outbound configuration page.
As far as not receiving any IVR calls -- it appears your "default" campaign is not running. You should activate that IVR campaign in the IVR outbound configuration page.
Last edited by support on Wed Feb 24, 2010 5:26 pm, edited 3 times in total.
I didn't pick those two items up from the documentation. Now that I've started the default campaign, the script is executing. The call bridging is failing, but that's another topic that I'll start in another support thread.
How do I determine a real callback from the test callback? Is it safe to assume that the test callback with no POST values from your URL is always a probe and not an error?
Thanks for following up on this. I really had no idea what to do next and you've gotten me moving again.
Dorsey
How do I determine a real callback from the test callback? Is it safe to assume that the test callback with no POST values from your URL is always a probe and not an error?
Thanks for following up on this. I really had no idea what to do next and you've gotten me moving again.
Dorsey
Dorsey
no POST values, it's the IVR probing your web server
When there are no POST values, it's the IVR probing your web server.
And thanks for pointing out that IVR issue with our documentation. We'll follow up with our tech writer and have it addressed.
And thanks for pointing out that IVR issue with our documentation. We'll follow up with our tech writer and have it addressed.
Last edited by support on Fri Feb 19, 2010 5:59 pm, edited 2 times in total.
Each time the return_url script is executed, we create a log entry. After clearing the logs before a single test call, we see that the return_url is invoked 132 times.
The script itself fails during the transfer, but the return_url is invoked with the same (and correct) message_reference value each time over a 40 second period.
Regardless of the results, we're replying with the word "success" (no quotes) each time.
Any ideas as to why this is happening?
Dorsey
The script itself fails during the transfer, but the return_url is invoked with the same (and correct) message_reference value each time over a 40 second period.
Regardless of the results, we're replying with the word "success" (no quotes) each time.
Any ideas as to why this is happening?
Dorsey
Dorsey
IVR outbound system
As long as the IVR reaches someone, what happens internally within the VoiceXML script has no bearing on the status returned to result_url. That status merely indicates that an end-party was actually reached by the outbound IVR system.
Last edited by support on Wed Feb 24, 2010 5:27 pm, edited 3 times in total.
IVR outbound system
It shouldn't be. The return_url should only be hit once to validate and once at the end of an IVR call. We can't seem to reproduce this IVR problem here.
Last edited by support on Fri Feb 19, 2010 6:00 pm, edited 2 times in total.
It has to be coming from your end. When I "open" the script directly from a browser, I only get one log message as shown below. We log the following set of messages 132 times when we try to execute our script (some variables differ, of course):
<30-May-2007 12:37:41> [/svc_callresult.php] Called
<30-May-2007 12:37:41> [/svc_callresult.php] Illegal/Unexpected Callback Invocation received from:
Array
(
[DOCUMENT_ROOT] => /home/zogo/public_html/staging
[HTTP_ACCEPT] => text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
[HTTP_ACCEPT_CHARSET] => ISO-8859-1,utf-8;q=0.7,*;q=0.7
[HTTP_ACCEPT_ENCODING] => gzip,deflate
[HTTP_ACCEPT_LANGUAGE] => en-us,en;q=0.5
[HTTP_CONNECTION] => keep-alive
[HTTP_COOKIE] => __utma=28181502.1402288988.1179851638.1179921160.1179953724.5; __utmz=28181502.1179851638.1.1.utmccn=(direct)|utmcsr=(direct)|utmcmd=(none)
[HTTP_HOST] => staging.zogo.com
[HTTP_KEEP_ALIVE] => 300
[HTTP_USER_AGENT] => Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
[PATH] => /sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
[REMOTE_ADDR] => 71.251.212.37
[REMOTE_PORT] => 3236
[SCRIPT_FILENAME] => /home/zogo/public_html/staging/svc_callresult.php
[SERVER_ADDR] => 72.18.130.66
[SERVER_ADMIN] => webmaster@staging.zogo.com
[SERVER_NAME] => staging.zogo.com
[SERVER_PORT] => 80
[SERVER_SIGNATURE] =>
[SERVER_SOFTWARE] => Apache
[GATEWAY_INTERFACE] => CGI/1.1
[SERVER_PROTOCOL] => HTTP/1.1
[REQUEST_METHOD] => GET
[QUERY_STRING] =>
[REQUEST_URI] => /svc_callresult.php
[SCRIPT_NAME] => /svc_callresult.php
[PATH_TRANSLATED] => /home/zogo/public_html/staging/svc_callresult.php
[PHP_SELF] => /svc_callresult.php
[argv] => Array
(
)
[argc] => 0
)
<30-May-2007 12:37:41> [/svc_callresult.php] Called
<30-May-2007 12:37:41> [/svc_callresult.php] Illegal/Unexpected Callback Invocation received from:
Array
(
[DOCUMENT_ROOT] => /home/zogo/public_html/staging
[HTTP_ACCEPT] => text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
[HTTP_ACCEPT_CHARSET] => ISO-8859-1,utf-8;q=0.7,*;q=0.7
[HTTP_ACCEPT_ENCODING] => gzip,deflate
[HTTP_ACCEPT_LANGUAGE] => en-us,en;q=0.5
[HTTP_CONNECTION] => keep-alive
[HTTP_COOKIE] => __utma=28181502.1402288988.1179851638.1179921160.1179953724.5; __utmz=28181502.1179851638.1.1.utmccn=(direct)|utmcsr=(direct)|utmcmd=(none)
[HTTP_HOST] => staging.zogo.com
[HTTP_KEEP_ALIVE] => 300
[HTTP_USER_AGENT] => Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
[PATH] => /sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
[REMOTE_ADDR] => 71.251.212.37
[REMOTE_PORT] => 3236
[SCRIPT_FILENAME] => /home/zogo/public_html/staging/svc_callresult.php
[SERVER_ADDR] => 72.18.130.66
[SERVER_ADMIN] => webmaster@staging.zogo.com
[SERVER_NAME] => staging.zogo.com
[SERVER_PORT] => 80
[SERVER_SIGNATURE] =>
[SERVER_SOFTWARE] => Apache
[GATEWAY_INTERFACE] => CGI/1.1
[SERVER_PROTOCOL] => HTTP/1.1
[REQUEST_METHOD] => GET
[QUERY_STRING] =>
[REQUEST_URI] => /svc_callresult.php
[SCRIPT_NAME] => /svc_callresult.php
[PATH_TRANSLATED] => /home/zogo/public_html/staging/svc_callresult.php
[PHP_SELF] => /svc_callresult.php
[argv] => Array
(
)
[argc] => 0
)
Dorsey
As it turns out, we were both correct. Our script used the submit tag to deliver call results, but we also specified a return_url when starting the call. So, once we removed the return_url parameter, we get one and only one result set.
I apologize for taking up your time on what turned out to be a misunderstanding on our part, and thank you for your help in getting our application running on your server.
Dorsey
I apologize for taking up your time on what turned out to be a misunderstanding on our part, and thank you for your help in getting our application running on your server.
Dorsey
Dorsey
We've just moved to a production system, and it works very well other than the following inconsistency between development and production.
After POSTing to http://outbound.plumgroup.com/webservice/queuecall.php,
we don't read any response from your server. The script is executing correctly, however, including our subdialog script.
During development, we received an XML response that included the queuecall element, among others. Are we posting to the correct URL now that we're no longer using your development system? There doesn't seem to be any error in the call log, and as I said, the script executes perfectly.
Thanks for your help,
Dorsey
After POSTing to http://outbound.plumgroup.com/webservice/queuecall.php,
we don't read any response from your server. The script is executing correctly, however, including our subdialog script.
During development, we received an XML response that included the queuecall element, among others. Are we posting to the correct URL now that we're no longer using your development system? There doesn't seem to be any error in the call log, and as I said, the script executes perfectly.
Thanks for your help,
Dorsey
Dorsey
IVR outbound calling
Hello,
The front end of the IVR call queue does not differentiate between "production" vs "development" accounts. We just double checked and the queuecall.php script is returning XML data for us, so it seems like this must be something specific to your IVR script. If you can find a specific IVR example that is not returning an XML response please post it here. If you are not comfortable posting here you can send the information to support@plumvoice.com and place your customer ID in the subject line of the email. Please reference this support post in your email so that we know what post your email is referring to.
Regards,
Plum Support
The front end of the IVR call queue does not differentiate between "production" vs "development" accounts. We just double checked and the queuecall.php script is returning XML data for us, so it seems like this must be something specific to your IVR script. If you can find a specific IVR example that is not returning an XML response please post it here. If you are not comfortable posting here you can send the information to support@plumvoice.com and place your customer ID in the subject line of the email. Please reference this support post in your email so that we know what post your email is referring to.
Regards,
Plum Support
Last edited by support on Fri Feb 19, 2010 6:01 pm, edited 3 times in total.
I've included some code snippets that demonstrate the problem.
The first is the PHP code that initiates the POST:
$retVal['login'] = PLUM_LOGIN;
$retVal['pin'] = PLUM_PIN;
$retVal['phone_number'] = '1'.$from; // phone number to be dialed -- be sure to include the 1 before the area code
$retVal['start_url'] = SVC_CALL_VXMLURL;
$retVal['login'] = PLUM_LOGIN;
//$retVal['result_url'] = SVC_CALL_RESULTURL; // URL for post-call processing. We don't use this because our VXML invokes a sub-dialog to receive call results
$retVal['message_reference'] = $reqId; // The message_reference string is POSTed to the URL specified by start_url
$retVal['call_parameters' ] = $call_parameters; // The call_parameters string is POSTed to the URL specified by start_url (up to 255 characters)
$retVal['max_retries'] = 2; // an integer from 1 to 10 for the number of failed call attempts before giving up
$retVal['retry_interval'] = 60 * 5; // an integer from 60 to 172800 indicating the number of seconds between retries
$retVal['scheduled_timestamp' ] = 0; // 0 to start immediately or a UNIX-time integer indicating when to start attempting the call (scheduled_time can be used instead -- see below for details)6
$retVal['expiration_timestamp'] = 0; // 0 to never expire or a UNIX-time integer indicating when the system should give up attempting to complete an uncompleted call (expiration_time can be used instead -- see below for details) //
$post = new HTTPPost( $url, $retVal );
// We're logging this just for the record. The subdialog will handle the call results.
//_RPCLogMsg( "Posting to $url", $sessionid );
if( $result = $post->post() ) {
...}
The second snippet is the code that writes to the URL and reads the results:
$request = "POST " . $this->uri . " HTTP/1.1\r\n".
"Host: " . $this->url . "\r\n".
"User-Agent: HTTPPost\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n".
($this->authInfo ? "Authorization: Basic $auth\r\n" : '') .
"Content-Length: $contentLength\r\n\r\n".
"$requestBody\r\n";
$socket = fsockopen($this->url, 80, &$errno, &$errstr);
if(!$socket) {
$this->error['errno'] = $errno;
$this->error['errstr'] = $errstr;
_RPCLogMsg( "Can't open socket to $url: $errno/$errstr", __FILE__ );
return $this->getResponseBody();
}
_RPCLogMsg( "Opened socket to " . $this->url . ", writing $request", __FILE__ );
fputs($socket, $request);
_RPCLogMsg( "After writing", __FILE__ );
$isHeader = true;
$blockSize = 0;
while (!feof($socket)) {
_RPCLogMsg( "In read loop", __FILE__ );
if($isHeader){
_RPCLogMsg( "Getting header", __FILE__ );
$line = fgets($socket, 1024);
_RPCLogMsg( "Got header, length = " . strlen( $line ), __FILE__ );
$this->responseHeaders .= $line;
if('' == trim($line)){
$isHeader = false;
}
} else {
if(!$blockSize){
$line = fgets($socket, 1024);
if($blockSizeHex = trim($line)){
$blockSize = hexdec($blockSizeHex);
_RPCLogMsg( "Got blocksize = $blockSize", __FILE__ );
}
} else {
$this->responseBody .= fread($socket,$blockSize);
_RPCLogMsg( "Got body: " . $this->responseBody, __FILE__ );
$blockSize = 0;
break;
}
}
}
_RPCLogMsg( "Closing socket", __FILE__ );
fclose($socket);
I hope that the above is not too confusing. The request is written OK because the script begins to execute. The first read on the socket returns zero length, and then the code stops due to EOF. This is the exact code we used to "prove" Plum Voice, but it's likely something was missed in moving the code to production.
You've confirmed that the URL doesn't change from dev to production, so we'll continue to look at our end. The good news is that the calls are taking place, which means that our customers are not losing service.
By the way, I really appreciate your not assuming that the problem is on our end, or at least not making that assumption obvious. You are real professionals.
Dorsey
The first is the PHP code that initiates the POST:
$retVal['login'] = PLUM_LOGIN;
$retVal['pin'] = PLUM_PIN;
$retVal['phone_number'] = '1'.$from; // phone number to be dialed -- be sure to include the 1 before the area code
$retVal['start_url'] = SVC_CALL_VXMLURL;
$retVal['login'] = PLUM_LOGIN;
//$retVal['result_url'] = SVC_CALL_RESULTURL; // URL for post-call processing. We don't use this because our VXML invokes a sub-dialog to receive call results
$retVal['message_reference'] = $reqId; // The message_reference string is POSTed to the URL specified by start_url
$retVal['call_parameters' ] = $call_parameters; // The call_parameters string is POSTed to the URL specified by start_url (up to 255 characters)
$retVal['max_retries'] = 2; // an integer from 1 to 10 for the number of failed call attempts before giving up
$retVal['retry_interval'] = 60 * 5; // an integer from 60 to 172800 indicating the number of seconds between retries
$retVal['scheduled_timestamp' ] = 0; // 0 to start immediately or a UNIX-time integer indicating when to start attempting the call (scheduled_time can be used instead -- see below for details)6
$retVal['expiration_timestamp'] = 0; // 0 to never expire or a UNIX-time integer indicating when the system should give up attempting to complete an uncompleted call (expiration_time can be used instead -- see below for details) //
$post = new HTTPPost( $url, $retVal );
// We're logging this just for the record. The subdialog will handle the call results.
//_RPCLogMsg( "Posting to $url", $sessionid );
if( $result = $post->post() ) {
...}
The second snippet is the code that writes to the URL and reads the results:
$request = "POST " . $this->uri . " HTTP/1.1\r\n".
"Host: " . $this->url . "\r\n".
"User-Agent: HTTPPost\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n".
($this->authInfo ? "Authorization: Basic $auth\r\n" : '') .
"Content-Length: $contentLength\r\n\r\n".
"$requestBody\r\n";
$socket = fsockopen($this->url, 80, &$errno, &$errstr);
if(!$socket) {
$this->error['errno'] = $errno;
$this->error['errstr'] = $errstr;
_RPCLogMsg( "Can't open socket to $url: $errno/$errstr", __FILE__ );
return $this->getResponseBody();
}
_RPCLogMsg( "Opened socket to " . $this->url . ", writing $request", __FILE__ );
fputs($socket, $request);
_RPCLogMsg( "After writing", __FILE__ );
$isHeader = true;
$blockSize = 0;
while (!feof($socket)) {
_RPCLogMsg( "In read loop", __FILE__ );
if($isHeader){
_RPCLogMsg( "Getting header", __FILE__ );
$line = fgets($socket, 1024);
_RPCLogMsg( "Got header, length = " . strlen( $line ), __FILE__ );
$this->responseHeaders .= $line;
if('' == trim($line)){
$isHeader = false;
}
} else {
if(!$blockSize){
$line = fgets($socket, 1024);
if($blockSizeHex = trim($line)){
$blockSize = hexdec($blockSizeHex);
_RPCLogMsg( "Got blocksize = $blockSize", __FILE__ );
}
} else {
$this->responseBody .= fread($socket,$blockSize);
_RPCLogMsg( "Got body: " . $this->responseBody, __FILE__ );
$blockSize = 0;
break;
}
}
}
_RPCLogMsg( "Closing socket", __FILE__ );
fclose($socket);
I hope that the above is not too confusing. The request is written OK because the script begins to execute. The first read on the socket returns zero length, and then the code stops due to EOF. This is the exact code we used to "prove" Plum Voice, but it's likely something was missed in moving the code to production.
You've confirmed that the URL doesn't change from dev to production, so we'll continue to look at our end. The good news is that the calls are taking place, which means that our customers are not losing service.
By the way, I really appreciate your not assuming that the problem is on our end, or at least not making that assumption obvious. You are real professionals.
Dorsey
Discrepancy in IVR code causing problem
Hello,
We did some testing with your IVR code and there is one discrepancy we have noticed. What value are you using for $contentLength? In our tests if you fail to match the $contentLength with the actual length of the request (including any trailing \n\r values) and then attempt to read off of the socket no headers or body are returned. We changed the line:
Removing the "\r\n" so that our $contentLength properly matched the length of $requestBody:
After removing the trailing whitespace we started getting proper HTTP response headers and content. Please try this in your IVR code and let us know if it works for you. Out of curiosity, why did you choose to write your own HTTP access system instead of using the CURL functions available in PHP? We use CURL at Plum for pretty much every HTTP request we make in PHP.
Regards,
Plum Support
We did some testing with your IVR code and there is one discrepancy we have noticed. What value are you using for $contentLength? In our tests if you fail to match the $contentLength with the actual length of the request (including any trailing \n\r values) and then attempt to read off of the socket no headers or body are returned. We changed the line:
Code: Select all
"$requestBody\r\n";
Code: Select all
"$requestBody";
Regards,
Plum Support
Last edited by support on Fri Feb 19, 2010 6:01 pm, edited 2 times in total.