Unable to get twilio gather to work - php

I'm using twilio to call a user and am having trouble collecting the users input. The initial call works fine, but when I press 1 or 3, nothing appears to happen, and after the 3 second pause, it keeps going.
//This works fine, I can call and hear the options being read.
<?php
header("content-type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
?>
<Response>
<Gather action="https://mydomain.com/twilio/process_response.php" method="post" numDigits="1" timeout="3">
<Say>I can hear this.</Say>
<Say>Press 1.</Say>
<Say>Press 3.</Say>
</Gather>
<Say>It looks like you didn't select an option.</Say>
</Response>
The response - https://mydomain.com/twilio/process_response.php
<?php
header("content-type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
?>
<Response>
<Say>I should hear this, but I dont...</Say>
</Response>
Thanks!

The issue was caused by the cordless phone I was using to test not recognising the input. Changing phones "solved" this issue.

<Gather> works by listening to the DTMF sounds that your phone or device produces. Things that would make it difficult for you to hear what a person on the other end is saying can also make it difficult for Twilio to recognize DTMF tones. Poor mobile phone reception, excessive background noise, or connection that has lots of static can all make it difficult for <Gather> to recognize digit presses.
In addition, VoIP phones can be installed with a non-standard DTMF tones as the default, which Twilio will also have difficulty recognizing. VoIP phones might also be using pretty strong compression which can interfere with DTMF. In either case, consulting the phone's manual or the person who installed the phone is usually a good next step.
Browser or application based VoIP, like Skype or Google Voice, sometimes also have trouble with <Gather> for the same reasons VoIP phones have trouble.
Twilio's <Gather> troubleshooting link: http://www.twilio.com/docs/api/twiml/gather#troubleshooting

The 'action' attribute takes an absolute or relative URL as a value.
From looking in their documentation, it appears that the action attribute can only contain "/page.php" or "page.php". You'll need to drop the protocol and host portion. So:
<Gather action="/twilio/process_response.php" method="post" numDigits="1" timeout="3">

I have faced the same issue.
Later, I found this issue disappeared after appending finishOnKey ie #
or any other 'custom finishOnKey'

Faced the same issue.
Appending finishOnKey didn't work either.
My solution was to use speech recognition (input="speech"), i.e. not using DTMF, which is not reliable enough.

Related

Twilio Whitepages Pro Phone Reputation addon use with PHP

This is my first touch with Twilio Add-ons.
I want to use the addon "Whitepages Pro Phone Reputation" to return the relative results of a +ZZZZZZZ phone number. I have install the addon on the account (for the client id) and checked the use on Lookups on the control panel.
My PHP code is the following:
require_once(__DIR__ . '/includes/Twilio/autoload.php');
use Twilio\Rest\Client;
$client = new Client('XXXXXXX', 'YYYYYY');
$number = $client->lookups
->phoneNumbers("+ZZZZZZZ")
->fetch(
array("type" => "carrier", "AddOns" => "whitepages_pro_phone_rep")
);
var_dump($number->addOns['results']['whitepages_pro_phone_rep']);
But it returns the following:
array(5) { ["request_sid"]=> string(34) "XRcfbbe6fc969c3d20f5f0a95913a22cde" ["status"]=> string(6) "failed" ["message"]=> string(47) "Requirements to invoke AddOns have not been met" ["code"]=> int(61003) ["result"]=> array(0) { } }
What's the wrong with my code?
Twilio developer evangelist here.
You are receiving an error there, the code is 61003. You can always search for error codes for Twilio and there is normally an explanatory page. Here is the explanation for Error 61003.
Sadly, that explanation doesn't have many solutions!
To me, it looks as though your code is correct, but I wonder whether you have installed and enabled the Add-on in your account for lookups. Go here to install the Add-on, then make sure you have lookups selected.
Let me know if that helps at all.
I work for Whitepages and have some experience working within the Twilio environment. I've been the lead engineer for a couple of joint Twilio / Whitepages webinars and put together the app we used this year at Signal.
Have you tried testing it through a browser? Might be easy to see if it's the code or account / sub account. The mixing up the sid / token between a main account and a sub account has happened to me once.
https://lookups.twilio.com/v1/PhoneNumbers/+XXXXXXXXXXX/?AddOns=whitepages_pro_phone_rep
This will ask you for your account sid and auth token. Make sure you're getting a response there. Then at least we've narrowed it down.
Also when using the + Twilio expects E.169 formatted number numbers so make sure the country code is there.
Side note: It does look like you have "type" which should be "Type" for your carrier response but I don't think that will have an effect on AddOns.
Disclaimer: I've never worked in PHP.
We'll get it sorted out for you. Thanks for your support!
EDIT: Just noticed...would '$number->addOns' need to be '$number->add_ons'?
I detected the problem. ohhh I was so stupid!
I did my tests using my own phone number (Vodafone Greece) but the service did not supports Greek phone numbers.
I do a test with a number from U.S.A. and it works as expected!

Error calling Pho.to API

I am trying to call the Pho.to API to edit photos, and every time I try to POST I get the same error. I've double and triple checked my app_id and my key, and I can't figure out what I'm doing wrong. I'm currently using the ARC Chrome Extension to call this api, so I haven't even started coding that part yet, I'm just trying to get a real response back from the api to make sure it even works.
I followed the instructions in their docs as well as I could. Here's the link for reference: http://developers.pho.to/documentation/sending-requests
Here is my api call:
http://opeapi.ws.pho.to/addtask?APP_ID=<my-app-id>&KEY=<my-key>&SIGN_DATA=910ceb5bdb238b9248a34cce8b29ba64d5f239df
And here is the response I get back (don't be deceived by the 200):
Status: 200 OK
<?xml version="1.0" ?>
<image_process_response>
<status>SecurityError</status>
<err_code>614</err_code>
<description>Error in POST parameters: one or more parameters (DATA , SIGN_DATA or APP_ID) are empty</description>
</image_process_response>
Here's the PHP code I use to create the SHA1 for SIGN_DATA:
<?php
echo hash_hmac('SHA1', '<image_process_call><lang>en</lang><image_url order="1">http://www.w3schools.com/html/pic_mountain.jpg</image_url><methods_list><method order="1"><name>desaturation</name></method><method order="2"><name>cartoon</name><params>fill_solid_color=1;target_color=(255,255,255);border_strength=20;border_width=3</params></method></methods_list><result_format>png</result_format><result_size>600</result_size></image_process_call>','<my-key>');
?>
Here is the xml from above, formatted for readability:
<image_process_call>
<lang>en</lang>
<image_url order="1">http://www.w3schools.com/html/pic_mountain.jpg</image_url>
<methods_list>
<method order="1">
<name>desaturation</name>
</method>
<method order="2">
<name>cartoon</name>
<params>fill_solid_color=1;target_color=(255,255,255);border_strength=20;border_width=3</params>
</method>
</methods_list>
<result_format>png</result_format>
<result_size>600</result_size>
</image_process_call>
Any help would be appreciated. Thanks in advance!
So I figured out what was wrong. Here is my detailed solution for anyone else that may run into similar problems with this api (regardless of platform):
Part of the problem (as #u_mulder pointed out) is that DATA needs to be sent up along with SIGNED_DATA so that the SHA1 can be decoded on the other end.
The other piece that fixed my problem was removing <lang>en</lang>. For whatever reason, that was returning Error 613: Invalid SIGN_DATA parameter. English is the default language anyway, so it was unnecessary.
So after fixing those things, here's my final url:
http://opeapi.ws.pho.to/addtask/?app_id=<my-app-id>&key=<my-key>9&sign_data=e456c393d11797c1a2945a85dd49ba2208cc66de&data=%3Cimage_process_call%3E%3Cimage_url+order%3D%221%22%3Ehttp%3A%2F%2Fwww.heroesandheartbreakers.com%2Fimages%2Fstories%2Fblogarticles%2F2016%2FJanuary2016%2FTV-Recap-Arrow-4x11-Olicity-is-home-470.jpg%3C%2Fimage_url%3E%3Cmethods_list%3E%3Cmethod+order%3D%221%22%3E%3Cname%3Ecartoon%3C%2Fname%3E%3Cparams%3Efill_solid_color%3D1%3Btarget_color%3D%28255%2C255%2C255%29%3Bborder_strength%3D20%3Bborder_width%3D1%3C%2Fparams%3E%3C%2Fmethod%3E%3C%2Fmethods_list%3E%3Cresult_format%3Epng%3C%2Fresult_format%3E%3Cresult_size%3E1500%3C%2Fresult_size%3E%3C%2Fimage_process_call%3E
Notice that the url is encoded. This may or may not be necessary, I just encoded it to be safe.
This returns:
<?xml version="1.0" ?>
<image_process_response>
<request_id>010afc13-6bba-44dd-b278-4f3bd1e41946</request_id>
<status>OK</status>
<description />
<err_code>0</err_code>
</image_process_response>
And I can now use request_id to get the url of the edited image:
http://opeapi.ws.pho.to/getresult?request_id=010afc13-6bba-44dd-b278-4f3bd1e41946
Which returns the following xml:
<image_process_response>
<request_id>010afc13-6bba-44dd-b278-4f3bd1e41946</request_id>
<status>OK</status>
<result_url>http://worker-images.ws.pho.to/i1/3BCB160A-691A-458B-9161-67AFA8A9EAA0.png</result_url>
<result_url_alt>http://worker-images.ws.pho.to.s3.amazonaws.com/i1/3BCB160A-691A-458B-9161-67AFA8A9EAA0.png</result_url_alt>
<nowm_image_url>http://worker-images.ws.pho.to/i1/3BCB160A-691A-458B-9161-67AFA8A9EAA0.png</nowm_image_url>
</image_process_response>
So the url of the final edited image is http://worker-images.ws.pho.to/i1/3BCB160A-691A-458B-9161-67AFA8A9EAA0.png (I believe links expire after 24 hours)
And we're done!
If you'd like to check out how I implemented this api in a simple Android app, here's the github link: https://github.com/youravgjoe/ColoringPageGenerator
Before:
After:
For me the error was fixed by (A) making sure to use SHA1 rather than SHA256 (my own fault) and (B) for some reason the sign_data value has to be lowercase.
Remove all new lines(Enter) in XML and try again.
<image_process_call>
<lang>en</lang>
<image_url order="1">http://www.w3schools.com/html/pic_mountain.jpg</image_url>
<methods_list>
<method order="1">
<name>desaturation</name>
</method>
<method order="2">
<name>cartoon</name>
<params>fill_solid_color=1;target_color=(255,255,255);border_strength=20;border_width=3</params>
</method>
</methods_list>
<result_format>png</result_format>
<result_size>600</result_size>
</image_process_call>
To
<image_process_call><lang>en</lang><image_url order="1">http://www.w3schools.com/html/pic_mountain.jpg</image_url><methods_list><method order="1"><name>desaturation</name></method><method order="2"><name>cartoon</name><params>fill_solid_color=1;target_color=(255,255,255);border_strength=20;border_width=3</params></method></methods_list><result_format>png</result_format><result_size>600</result_size></image_process_call>

Geocoding a specific address fails from PHP, works from browser using the same URL

I'm using this code snippet to geocode an address using Google Geolocation API:
<?php
$address = "Frazione LevĂ  - 16030 Sori (GE)";
$url = 'http://maps.google.com/maps/api/geocode/xml?address='.urlencode($address).'&sensor=false';
echo $url."\n";
$xml = file_get_contents($url);
var_dump($xml);
?>
The echo command shows the URL called is:
http://maps.google.com/maps/api/geocode/xml?address=Frazione+Lev%C3%A0+-+16030+Sori+%28GE%29&sensor=false
and the var_dump command shows the result is:
string(107) "<?xml version="1.0" encoding="UTF-8"?>
<GeocodeResponse>
<status>ZERO_RESULTS</status>
</GeocodeResponse>
"
So it seems the address cannot be geolocated.
If I call exactly the same URL above ( http://maps.google.com/maps/api/geocode/xml?address=Frazione+Lev%C3%A0+-+16030+Sori+%28GE%29&sensor=false) from my browser, I get a totally different result (the address is correctly geolocated):
<?xml version="1.0" encoding="UTF-8"?>
<GeocodeResponse>
<status>OK</status>
...
How this is possible and how I can fix it? I need to geolocate addresses from PHP.
Please note I'm using the same code snippet in a loop to geolocate hundreds of addresses every day, and it works fine on most of them; only on some addresses it shows issues like that.
Found the solution here https://stackoverflow.com/a/10302440/2717254 thread found thanks to the StackOverflow related questions suggested in the sidebar :-)
Issue was the Region Biasing. I added ?region=it to the URL and results are now coherent.
Before adding that param, probably Google guessed it me when I loaded the page in the web browser because of headers sent by my browsers (in italian Language on Win7 italian). When I make the request from PHP, less headers are sent and probably Google thinks this is an en-US PC or something similar... :)
Also removing the ZIP code from the address also gives me coherent result across my PHP script and my web browser, but I think the ?region=it is the most clean and logically correct solution.
In my case I solved it with language instead of region: language=it (https://developers.google.com/maps/faq#languagesupport)

how to retrieve number of trackbacks for a URL

As far as i know a trackback it's a recognised standard ping for a custom URL, right?
so, according to this how can i retrieve how many trackbacks for http://example.com/article/22/name-article ?? and the URL of those 'trackbacks' ?
I never worked with those before, if posible i'd like to know howto in PHP or, if posible, in js,
any tip or clue would be wellcome
You must define an entry point, in all your pages, that will recieve all the trackback requests. The Trackback specification do it like this:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
rdf:about="http://www.foo.com/archive.html#foo"
dc:identifier="http://www.foo.com/archive.html#foo"
dc:title="Foo Bar"
trackback:ping="http://www.foo.com/tb.cgi/5" />
</rdf:RDF>
Where <rdf:RDF></rdf:RDF> is where you declare that this page uses Trackbacks and the parameters inside <rdf:Description /> are specific to your page. dc:identifier is your exact page URL and trackback:ping is the Trackback entry point.
There is no way in JS, as a client side language, to store the trackback count for each page, so the trackback:ping should be a PHP script that check the title from the request query and store it somewhere (DB, file, log...)
I made this VERY simplified Trackback entry point:
<?php
$theUrl = $_GET['url'];
if (!$theUrl) {
printError(NO_URL);
die();
}
$theUrl = Sanitize::clean($theUrl, SQL) // Your anti-SQL injection method
$theId = getIdFromUrl($theUrl);
countIntoDataBase($theId);
?>
And, last but not least, is important to bear in mind that Trackback protocol is very prone to SPAM, as this answer states: Trackbacks in PHP

Can't send content-type: text/xml header from PHP at the same time getting the data from MYSQL

i hope you can cast some light on my problem. I need to do an AJAX / PHP / MYSQL application to display posts and stuff on the page i'm writing.
I only discovered how to do some simple stuff in PHP after taking some mushrooms but that was years ago and now i don't have mushrooms and i'm just stuck!
So here's the problem:
i think i need to send a proper "xml" file through php so the ajax part can take it but: when i try to put the header on top of the php it displays this error:
" Extra content at the end of the document "
When i looked at some tutorials people were using the "header" fearlesly to do such stuff as i want to do and no comments suggested that it didn't work. so why it doesn't work on my local server?
I'm running:
WAMP
Apache 2.2.11
PHP 5.3.0
It also doesn't work on a remote server (PHP 5.3.0) :/
I read all the stuff i could find till 5am and decided to ask you for help for the first time :)
Thank you!
header('content-type: application/xhtml+xml; charset=utf-8');
require_once("allyouneed.php");
require_once("bazingablob.php");
$category=$_GET["category"];
$post_tags=$_GET["post_tags"];
$language=$_GET["language"];
$author=$_GET["author"];
$posts_per_page=$_GET["posts_per_page"];
$current_page=$_GET["current_page"];
$order=$_GET["order"];
$hard_limit=$_GET["hard_limit"];
$show_hidden=$_GET["show_hidden"];*/
$wypluj="";
$wypluj="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
$bazinga_blob = new bazingablob;
if (!$bazinga_blob->connect_to_database())
{
$wypluj.="<IsOK>0</IsOK>";
echo $wypluj;
exit;
}
else
{
$wypluj.="<IsOK>jedziem</IsOK>";
}
$bb_result=$bazinga_blob->get_all_posts($category,$post_tags,$language,$author,$posts_per_page,$current_page,$order,$hard_limit,$show_hidden);
if ($bb_result) //udalo sie cos znalezc w bazie wedlug kryteriow
{
$wypluj.="<Pagination>";
$wypluj.="<CurrentPage>";
$wypluj.=$bazinga_blob->posts_pagination["current_page"];
$wypluj.="</CurrentPage>";
$wypluj.="<LastPage>";
$wypluj.=$bazinga_blob->posts_pagination["last_page"];
$wypluj.="</LastPage>";
$wypluj.="<PostsCount>";
$wypluj.=$bazinga_blob->posts_pagination["posts_count"];
$wypluj.="</PostsCount>";
$wypluj.="</Pagination>";
$wypluj.="<Posts>";
foreach ($bb_result as $item)
{
$wypluj.="<Post>";
$wypluj.="<PostId>".$item->post_id."</PostId>";
$wypluj.="<PostAuthor>".$item->post_author."</PostAuthor>";
$wypluj.="<PostLangId>".$item->post_langid."</PostLangId>";
$wypluj.="<PostSlug>".$item->post_slug."</PostSlug>";
$wypluj.="<PostTitle>".$item->post_title."</PostTitle>";
$wypluj.="<PostGreetingPicture>".$item->post_greeting_picture."</PostGreetingPicture>";
$wypluj.="<PostGreetingVideo>".$item->post_greeting_video."</PostGreetingVideo>";
$wypluj.="<PostGreetingSound>".$item->post_greeting_sound."</PostGreetingSound>";
$wypluj.="<PostShort>".$item->post_short."</PostShort>";
$wypluj.="<PostBody>".$item->post_body."</PostBody>";
$wypluj.="<PostDate>".$item->post_date."</PostDate>";
$wypluj.="<PostPublished>".$item->post_published."</PostPublished>";
$wypluj.="<PostSticky>".$item->post_sticky."</PostSticky>";
$wypluj.="<PostComments>".$item->post_comments."</PostComments>";
$wypluj.="<PostProtected>".$item->post_protected."</PostProtected>";
$wypluj.="</Post>";
}
$wypluj.="</Posts>";
}
echo $wypluj;
The error comes from your browser and indicates that your XML is malformed.
Setting the application/xhtml+xml header tells the browser to process the document as serious XML. XML needs to be "well-formed", i.e. it must not contain any syntax errors. Apparently you do have a syntax error on line 1 at column 73, which makes the browser abort the attempt to process the document.
For this reason it's a pain to hand-code XML, you should really look into a library that takes care of the well-formedness for you, like PHP's own XMLWriter.
Have you validated your XML?
http://friendsofed.infopop.net/4/OpenTopic?a=tpc&s=989094322&f=5283032876&m=4521066061
I'm honestly not sure what you're trying to do with the header, it's not any Ajax method I've ever been taught. The header method you're doing looks just a few lines short of outputting the XML to a download prompt.
Here's my favorite way to do AJAX. Simple, understandable, and quick.
Include Jquery.
Setup your data--whether by form with a Serialize (gets form data into a Javascript Variable) or by just setting some variables as it seems you're doing above.
Send via Jquery Ajax to a separate processing page. The page will receive the data you setup as a $_REQUEST variable, with the method depending on whether you defined it as a POST or not (defaults to a GET)
The processing page --does-- stuff with the REQUEST data and may or may not respond back to the page. This is where you can do stuff like update divs, alert that it worked, etc.
Here's a great tutorial. Focus on the code under "Hello Ajax, Meet Jquery"
If you get yourself any more of those mushrooms, a PHP familiar way to do AJAX is with XAJAX. It allows you to do asynchronous calls to PHP functions. Be aware, though, that the forums are not the most english-friendly and documentation is a bit cryptic.

Categories