My code makes a curl request to an API that converts image formats e.g. png to jpg.
The API documentation offers a callback from the API which, when the conversion is finished, will send a GET request to a url on my server (hosted, not localhost). I provide this url to the API with the key/value pair:
"callback" => "12coins.net/cc_callback.php"
Unfortunately the API never calls back. Are my curl_setopt parameters wrong or what could be the problem?
$ch_start_process = curl_init();
$start_process_data = array(
"callback" => "https://12coins.com/cc_callback.php",
"input" => "download",
"file" => "https://12coins.com/photo_file.png",//the image I want converted
"tag" => "tag - unused for now",
"outputformat" => "jpg");
$process_url = "https:".$url_from_create;//prepend https to construct a valid endpoint.
//$url_from_create is a url returned by the API to a request immediately prior to this one
curl_setopt($ch_start_process, CURLOPT_URL, $process_url);
curl_setopt($ch_start_process, CURLOPT_POSTFIELDS, http_build_query ($start_process_data));
curl_setopt($ch_start_process, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch_start_process, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
$start_response=curl_exec($ch_start_process);//assign return value of curl_exec()
This is the script on my (remote) server 12coins.net/cc_callback.php to which the API should call back but doesn't:
<?php
header('Access-Control-Allow-Origin: *');
echo 'cc_callback has been called';
echo 'The GET request from CloudConvert is: '. $_GET;
?>
The API does in fact make a call back. It was just that with the code as shown in cc_callback.php there was no way for me to detect the callback. I had assumed that the echo statements would allow me to see the API's response in the (Chrome) network tab of my brower's dev tools. But of course the echo statements echo to the client that 'called' it with a GET request. In this case, that client is the API and not my browser/html page.
Realising this, I was then easily able to check that it had worked all along by adding
mail(myemailaddress#gmail.com, 'This is the url returned to the callback',$GET[url]); to my php script (shown in the question). This sent me an email when I sent an image to the API for processing and thus confirmed that the API was making the call back..
The curl code in the question is good. It makes a successful request to the API.
Lastly, the curl code is for a request to the CloudConvert API, version 1. There is a version 2 but the code above is not good for that. Also, there's an earlier curl request which must be used in conjunction with the one above which I'll post later for the sake of completeness.
Related
have a look at below snippet inside my PHP code :
function SMS(){
$msg1="".$bookingNo."\n".$guestName."\n".$guestEmail."\n".$guestPhone."\n".$guestAddress."\n".$place."\n".$account."\n".$reportingDate."\n".$reportingTime."";
file('http://sms.xxxxxxxxxxxxx.co.in/api/webxxxx.php?workingkey=76565xxxxxx&sender=ILUVU&to=9897xxxxxxx&message='.$msg1.'');}
The problem is this that this http link is sending SMS successfully when run on browser window,
with some dummy text in &message=.
But when I am assigning all defined and tested variables inside $msg1 & calling it in same url.
Woosh, it shows NO ERROR & nothing happens, on calling this function. NO SMS.
I wonder where m wrong ?
Thanks
UPDATED CODE :
function SMS(){
$bookingNo=$_REQUEST['bookingNo'];
$guestName=$_REQUEST['guestName'];
$guestEmail=$_REQUEST['guestEmail'];
$guestPhone=$_REQUEST['guestPhone'];
$guestAddress=$_REQUEST['guestAddress'];
$place=$_REQUEST['place'];
$account=$_REQUEST['account'];
$reportingDate=$_REQUEST['reportingDate'];
$reportingTime=$_REQUEST['reportingTime'];
$msg1="".$bookingNo."\n".$guestName."\n".$guestEmail."\n".$guestPhone."\n".$guestAddress."\n".$place."\n".$account."\n".$reportingDate."\n".$reportingTime."";
file('http://sms.xxxxxxxxxxxxx.co.in/api/webxxxx.php?workingkey=76565xxxxxx&sender=ILUVU&to=9897xxxxxxx&message='.$msg1.'');}
}
SMStoDriver();
Newline characters are not allowed in URLs. You need to encode the message:
function SMS(){
$bookingNo=$_REQUEST['bookingNo'];
$guestName=$_REQUEST['guestName'];
$guestEmail=$_REQUEST['guestEmail'];
$guestPhone=$_REQUEST['guestPhone'];
$guestAddress=$_REQUEST['guestAddress'];
$place=$_REQUEST['place'];
$account=$_REQUEST['account'];
$reportingDate=$_REQUEST['reportingDate'];
$reportingTime=$_REQUEST['reportingTime'];
$msg1=urlencode("Booking No: $bookingNo\nName: $guestName\n Email: $guestEmail\nPhone: $guestPhone\nAddress: $guestAddress\nPlace: $place\nAccount: $account\nDate: $reportingDate\nTime: $reportingTime");
file('http://sms.xxxxxxxxxxxxx.co.in/api/webxxxx.php?workingkey=76565xxxxxx&sender=ILUVU&to=9897xxxxxxx&message='.$msg1.'');}
}
It looks like you are trying to use the file method to make the web request. Perhaps your PHP ini is configured to not allow file I/O requests to URLs.
You would be better off making the web request with something like cURL.
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://sms.xxxxxxxxxxxxx.co.in/api/webxxxx.php?workingkey=76565xxxxxx&sender=ILUVU&to=9897xxxxxxx&message=test',
));
$resp = curl_exec($curl);
curl_close($curl);
I am looking for a way to make a post request from a controller to an external url. The data being posted is a php array. The url to recieve is an ecommerce API in an external url. The post has to be done from the controller method. The url should reply with 'success', 'error', 'failure' or 'trylater' string. I have tried the following with no success:
return Redirect::to("https://backoffice.host.iveri.com/Lite/Transactions/New/Authorise.aspx", compact($array));
I have tried curl too:
$url = 'https://backoffice.host.iveri.com/Lite/Transactions/New/Authorise.aspx';
//url-ify the data for the POST
$fields_string ='';
foreach($array as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string,'& ');
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($array));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
Part of the array being sent is the callbacks that the API uses to responds:
'Lite_Website_Successful_url' => 'https://mydomain.com/order/'.$order_id,
'Lite_Website_Fail_url' => 'https://mydomain.com/checkout/fail',
'Lite_Website_TryLater_url' => 'https://mydomain.com/checkout/trylater',
'Lite_Website_Error_url' => 'https://mydomain.com/checkout/error'
Please let me know how to do a POST request properly with data carried with it to an external url. An ajax post from the controller too would help but I have tried with no success. But I would prefer a laravel php answer more. Thank you.
We can use package Guzzle in Laravel, it is a PHP HTTP client to send HTTP requests.
You can install Guzzle through composer
composer require guzzlehttp/guzzle:~6.0
Or you can specify Guzzle as a dependency in your project's existing composer.json
{
"require": {
"guzzlehttp/guzzle": "~6.0"
}
}
Example code of POST Request in laravel, using Guzzle is as shown below,
use GuzzleHttp\Client;
class yourController extends Controller {
public function saveApiData()
{
$client = new Client();
$res = $client->request('POST', 'https://url_to_the_api', [
'form_params' => [
'client_id' => 'test_id',
'secret' => 'test_secret',
]
]);
$result= $res->getBody();
dd($result);
}
Let me clarify some stuff and try to point you in the right direction.
First, what you're attempting to do sounds like "making an API request from your web app". The difference in that wording in how I stated it vs yours is that it's more general.
You can make an API request anywhere in your application, not necessarily in your controller (Don't be afraid to make extra classes/models for things like API calls!)
I'm curious about why it "has to be" done in your controller? What's your use case?
AJAX doesn't exist on the server-side (in PHP). That's purely a javascript-specific "technology" that describes javascript making a request to a URL on the client-side.
Lastly, what are you trying to do? Do you need a user to be redirected? Or do you need to make an API call and parse the result within your application?
The cURL request you've attempted should work for making an API request. That's one of the main ways of making an API request within PHP code. It won't, however, allow a user on the front-end to see that request being made and processed. With cURL (and any API request), the processing is all happening behind the scenes in your PHP (which your users can't see).
Either use CURL the way you've been trying, or check this thread for a brief answer on doing it with the Guzzle http client. Guzzle seems to be the preferred client for use with Laravel...
Call external API function from controller, LARAVEL 4
My php/Yii application interacts with twilio. I know the sid of a queue. I want to get the current size of that queue. The thing is that I can't use the twilio php library (I don't want to get into the details). I'm using curl, but I keep getting 401 errors.
This is my code:
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://api.twilio.com/2010-04-01/Accounts/AccountId/Queues/QUeueID.json',
CURLOPT_USERPWD => 'token:{AuthToken}'));
curl_exec($curl);
I don't what I'm doing wrong. I'm trying to follow the documentation:
http://www.twilio.com/docs/api/rest/queue
EDIT: I turned it into a get request, from a post request.
Also, I got a 401 unauthorized error, not a 411. Sorry about that. Typo.
SECOND EDIT:
So, I figured it out in a conversation with Kevin. Turns out that I needed:
CURLOPT_USERPWD => 'AccountID:Token'
If you are just trying to retrieve the size of a queue, you want to make a GET request, not a POST. It looks like you are setting CURLOPT_POST in your curl request.
I have a PHP script that syncs data with a third party service, and I would like to, if possible, replace nuSOAP with cURL as I have heard cURL is faster. The web service I am calling just takes simple HTTP post and returns it, so the cURL parameters shouldn't be too involved.
I need to pass 4 things, a user id, password, organization id, and the name of the web service to receive data from.
Which part of the cURL options do I pass them? I was trying to pass them in the header, but I am not sure if that is correct. I kept receiving 'Bad Request (Invalid Number)' error.
Edit: I am setting the HTTPHEADER but it looks like its still setting it to text/html.
Since, i have a thought that you have some basic understanding of cURL. I am giving you some shallow information.
If you are just posting some information to a page make use of
curl_setopt($agent, CURLOPT_POST, true);
curl_setopt($agent, CURLOPT_POSTFIELDS, $post_data);
where $post_data will be the information you post to the page , something like
$post_data="name=stanley&feedback=good";
Or
If you are trying to make an authentication to a page, Just use
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt(CURLOPT_USERPWD, '[username]:[password]');
If you say 'The web service I am calling just takes simple HTTP post', assuming it doesn't use SOAP, you would do it by:
curl_setopt($handle,CURLOPT_POST,true);
curl_setopt($handle,CURLOPT_POSTFIELDS,array(
'user_id' => 'user',
'password' => 'pass' //etc, all the key/value pairs you need.
));
However, if it is a SOAP service, you would have to make a SOAP request, and which for it would take we cannot tell you without a WSDL. Any of the PHP XML packages would do to create it, possibly for simple things even normal string manipulation.
A help in the built-in soapclient (not nusoap) would be to do a request with SOAPClient and just examine the output of __getLastRequest().
I'm trying to use a web service REST API for which I need to add a parameter for authorization (with the appropriate key, of course) to get a XML result. I'm developing in PHP. How can I add a parameter to the request header in such a situation?
Edit: The way I'm doing the request right now is $xml = simplexml_load_file($query_string);
Are you using curl? (recommended)
I assume that you are using curl to do these requests towards the REST API, if you aren't; use it.
When using curl you can add a custom header by calling curl_setopt with the appropriate parameters, such as in below.
curl_setopt (
$curl_handle, CURLOPT_HTTPHEADER,
array ('Authentication-Key: foobar')
); // make curl send a HTTP header named 'Authentication-key'
// with the value 'foobar'
Documentation:
PHP: cURL - Manual
PHP: curl_setopt - Manual
Are you using file_get_contents or similar?
This method is not recommended, though it is functional.
Note: allow_url_fopen needs to be enabled for file_get_contents to be able to access resources over HTTP.
If you'd like to add a custom header to such request you'll need to create yourself a valid stream context, as in the below snippet:
$context_options = array(
'http' =>array (
'method' => 'GET',
'header' => 'Authentication-Key'
)
);
$context = stream_context_create ($context_options);
$response = file_get_contents (
'http://www.stackoverflow.com', false, $context_options
);
Documentation:
PHP: file_get_contents - Manual
PHP: stream_context_create - Manual
PHP: Runtime Configuration, allow_url_fopen
I'm using neither of the above solutions, what should I do?
[Post OP EDIT]
My recommendation is to fetch the data using curl and then pass it off to the parser in question when all the data is received. Separate data fetching from the processing of the returned data.
[/Post OP EDIT]
When you use $xml = simplexml_load_file($query_string);, the PHP interpreter invokes it's wrapper over fopen to open the contents of a file located at $query_string. If $query_string is a remote file, the PHP interpreter opens a stream to that remote URL and retrieves the contents of the file there (if the HTTP response code 200 OK). It uses the default stream context to do that.
There is a way to alter the headers sent by altering that stream context, however, in most cases, this is a bad idea. You're relying on PHP to always open all files, local or remote, using a function that was meant to take a local file name only. Not only is it a security problem but it also could be the source of a bug that is very hard to track down.
Instead, consider splitting the loading of the remote content using cURL (checking the returned HTTP status code and other sanity checks) and then parsing that content into a SimpleXMLElement object to use. When you use cURL, you can set any headers you want to send with the request by invoking something similar to curl_setopt($ch, CURLOPT_HTTPHEADER, array('HeaderName' => 'value');
Hope this helps.