Error calling Pho.to API - php

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>

Related

XML tags match but namespaces differ

I am trying to setup a Soap connection between a server in php and a client in C. My server is using a working wsdl file and a class to add these methods. I can confirm with Wireshark that my client request is well received and correctly processed.
My issue is that the values of the XML element sent by the server cannot be read because the namespaces differs. By adding debug log in my client I have found that the error is :
Tags 'state' and 'ns2:state' match but namespaces differ
Issue :
The issue seems to be that the server response does not contain any default namespace :
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://www.w3.org/2005/08/adressing"
xmlns:ns2="http://www.namespace1/">
<env:Body>
<ns2:HelloResponse>
<state>OK</state>
<intElement>123</intElement>
</ns2:HelloResponse>
</env:Body>
</env:Envelope>
It looks like <state> and <intElement> are not in any namespace, so it can't match one of the client. In my Wsdl file, these element belongs to xmlns:s="http://www.w3.org/2001/XMLSchema"
What I tried :
Obvious solution is to add an namespace to these element, but I can't find a way to do it.
In my php server, I can modify any request that comes in but can't affect any response that comes out (or at least i didn't find how to do it).
2nd solution : Adding the namespace that describe these element to the Namespace struct in my client and then use the set_namespace() function.
But I couldn't manage to put them to work, please keep in mind that I am still new to the XML/Soap world, any help is appreciated.
As said before, the solution was to add the corresponding namespace to these element.
I managed to do it using ob_get_contents() and adding the namespace to <ns2:HelloResponse>. Using Wireshark was really useful for this kind of stuff.

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)

XmlException: Data at the root level is invalid

I have a PHP client that has to query datasets from a service that uses .NET. So, I was trying to make a query by passing a POST field called 'query'. Inside this variable, I have a string version of XML document. What's happening now is that whenever I passed this 'query' to the server, it will throw an exception at me 'Data at the root level is invalid.' and point to the last line of my XML document.
Any tips?
Here's the XML
<?xml version="1.0" encoding="utf-8"?>
<Predicate>
<ComparisonPredicate name="like" isEnabled="True" id="" DistinctIndividualQueries="False">
<FacetOperand reference="TriggeredAlerts.Alert.Name"/>
<Comparison operation="like"/>
<ValueOperand type="System.String" value="Sample"/>
</ComparisonPredicate>
</Predicate>
Here's the var_dump()
string(335) "<?xml version="1.0" encoding="utf-8"?>
<Predicate>
<ComparisonPredicate name="like" isEnabled="True" id="" DistinctIndividualQueries="False">
<FacetOperand reference="TriggeredAlerts.Alert.Name"/>
<Comparison operation="like"/>
<ValueOperand type="System.String" value="TestAlert"/>
</ComparisonPredicate>
</Predicate>
"
I just figured it out and the solution was to use fsocksopen instead of curl. I do not have an accurate answer for that but when I was using curl, it added some extra stuffs to my content; my content length was significantly longer than it is actually supposed to be.

Unable to get twilio gather to work

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.

Process SOAP Headers in PHP

I am building (in PHP) a SOAP server that is configured by its WSDL to accept messages that look like this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="https://my.awesome.namespace/">
<SOAP-ENV:Header>
<ns1:Header>
<ns1:APIKey>E4C5BDE0-48DC-543C-1CA3-8E55C63F8E60</ns1:APIKey>
<ns1:SiteID>111</ns1:SiteID>
</ns1:Header>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:Heartbeat>
<ns1:Message>Hello world.</ns1:Message>
</ns1:Heartbeat>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I had no problem getting my SOAPServer to process Heartbeat messages - $server->addFunction("Heartbeat"); works fine. I want, however, to be able to process the contents of the <ns1:Header> enclosure - so I can validate the API key and Site ID to make sure they are what they should be.
I looked here, (and of course elsewhere) but the responder seems to have missed the point of the question. Does anyone know how I can access the header element to validate? Do I add a function for Header the way I would a method in the body? ($server->addFunction("Header");?)
Thanks very much in advance.
Found it! Here's what you do.
Create your SOAP server:
$server = new SoapServer($your_wsdl,$any_options);
$server->setClass($name_of_your_class);
$server->handle($location_of_request_data);
The class named in $name_of_your_class, in addition to containing functions for each service defined in $your_wsdl, should also contain a function named for whatever you have in your <SOAP-ENV:Header> tag enclosure. I have <ns1:Header>, so my function is named Header. Put whatever logic you need in there. For me, I wanted to validate the API key and site ID, so I created a private variable, and if the API key and site ID are correct, the variable is set to true. All of the other functions in the class check to see if that variable is true before proceeding, and if not, a SOAPFault is thrown.
Hope this helps anyone who comes across this question on Google.
P.S.: For the functions in the class defined in $server->setClass(), don't forget that they must accept arguments in the order defined in the WSDL. That tripped me up.
Good luck to all other PHP/SOAP developers - seems like we all need it.
Edit/P.P.S.: For whatever reason, simply calling $server->addFunction("Header") did not work for me - I tried that first before I tried the setClass approach above. Just a heads-up to folks.

Categories