I'm likely missing something incredibly obvious, but in the project I'm working on I've got to send many jobs from a CSV of info to be processed asynchronously and Google App Engine's current way is through their new (beta) Cloud Tasks mechanism.
It will accept a payload as part of the task, so I was going to send a JSON array with each job's pertinent data... except that the only way to dictate the "Content-Type: application/json" header is during creation of the task object.
I'm using Google's own cloud-tasks 0.5.0 library.
Here is what I've been attempting, since it seems this is how most other non-cURL HTTP POST requests would accept the Content-Type header...
require_once 'vendor/autoload.php';
use Google\Cloud\Tasks\V2beta3\AppEngineHttpQueue;
use Google\Cloud\Tasks\V2beta3\CloudTasksClient;
use Google\Cloud\Tasks\V2beta3\Queue;
use Google\Cloud\Tasks\V2beta3\Task;
<<< ...lots of cruft omitted... >>>
$json_payload = json_encode(
array(
"batch" => $operation_time,
"order" => $csvln[0],
"customer" => $csvln[1],
"email" => $csvln[2],
"salesperson" => $csvln[3]
)
);
//Create each of the tasks in the queue
$options = [
'http' => [
'header' => "Content-type: application/json",
'method' => 'POST',
'content' => $json_payload
]
];
$task = new Task($options);
Any help would be immensely appreciated!
You can load a task into the Task Queue with a pre-defined payload using an App Engine HTTP Request from the Cloud Tasks PHP Client Library.
After you defined the Task, you can use the setter methods provided to you by AppEngineHttpRequest to construct your HTTP object with any required headers. This will also allow to assign the payload.
Below is a simple snippet showing how to attach a task with a payload to the default queue:
use Google\Cloud\Tasks\V2beta3\AppEngineHttpRequest;
use Google\Cloud\Tasks\V2beta3\HttpMethod;
use Google\Cloud\Tasks\V2beta3\Task;
//Preparing the payload
$json_payload = json_encode(
array(
"batch" => date("h:i:sa"),
"order" => "Payload-0000",
"customer" => "Payload-0001",
"email" => "Payload-0002",
"salesperson" => "Payload-0003"
)
);
//Create and configure the task
$httpR=new AppEngineHttpRequest();
$httpR->setBody($json_payload);
$httpR->setHeaders(['Content-type'=>'application/json']);
$httpR->setHttpMethod(HttpMethod::POST);
$httpR->setRelativeUri("/example_task_handler");
$task = new Task();
$task->setAppEngineHttpRequest($httpR);
Also consider updating your library as the current version is v0.86.0 which it will allow the assignation of headers even after the creation of the task object.
Related
I am developing an application that needs to access a SOAP api. The soap API should return a base64 encoded zip file, and it does so when being fired from SOAPUI. However I am trying to read this result programatically therefore I would need to get the file with a request fired from PHP.
$client = new MTOMSoapClient($url, array("soap_version" => SOAP_1_1,"trace" => 1));
$user_param = array (
'DealerCode' => "1234",
'Hash' => "asjdfasjda1231231231",
'Password' => "somerandompassword",
'UserName' => "somerandomusername"
);
var_dump(
$client->__soapCall(
"DownloadOffer",
array($user_param)
)
);
var_dump($client->__getLastRequest());
I also extended PHP's soap client like shown here without the proper results: https://gist.github.com/pkmishra/2243055
The same error is shown in postman:
SoapFault: Cannot process the message because the content type 'text/xml; charset=utf-8' was not the expected type 'multipart/related; type="application/xop+xml"'. in file /app/app/Http/Middleware/MTOMSoapClient.php on line 8
Any advice, library, way to get the response or at least the reason behind the error is greatly apreciated.
Good Afternooon all,
Please can someone give me a example of a PUT request? i have seen a couple online but i can not seam to get any to work.... I am trying to create an app for my live streaming channel, below is what i am trying to use PUT for.
Here is the DEV link to the API: https://dev.streamelements.com
So the URL would be: https://api.streamelements.com/kappa/v2
the PUT i need is the following
/points/{channel}/{user}/{amount}
Media type: application/json
so i understand the url in full if it was a get:
(api.streamelements.com/kappa/v2/points/channe id removed/username removed)
That gives me my points on a selected channel but to add or remove points it has to be a PUT and i have no idea on how to use it, so if anyone could give me some example of the above i could learn from it and do all the other requests myself
Many Thanks for your time
Kev (TADS)
You may need to be familiar with HTTP clients such as Guzzle or other clients that implements Psr7 interface.
In your case your code should looks like:
$client = new GuzzleHttp\Client();
$client->put('https://api.streamelements.com/kappa/v2/REST_OF_URL', [
'headers' => ['X-Foo' => 'Bar'],
'body' => [
'field1' => 'value1',
// ...
],
'timeout' => 10
]);
Obviously I'm assuming that you know how to include the Guzzle library to your project using Composer or standalone include.
I have the following code:
$client = new GuzzleHttp\Client(
array(
'base_uri' => 'https://somesite.com'
)
);
$response = $client->request('POST', '/api', [
'form_params' => array(
'action' => 'getusers',
'api_key' => $_POST['key'],
'id' => $_POST['id']
)
]);
When multiple users are accessing the same page with the following code above, other users waits for the first or recent request to finish before loading its request.
I'm not using any session.
I have tag curl because guzzle is built on top of it. Maybe it has something to do with it?
Any workaround for this?
using xhr won't fix it because the site I'm requesting for the API does not accept other origins.
Check available PHP processes if you are using PHP FPM. It has a status page (the setup is described there) to get this information.
If all the workers are busy, then client's requests will wait. You need to increase the amount of workers to be able to process more requests at once.
I'm writing a library to connect to Twitter that uses Requests for PHP. I'm not sure, but I don't think that I'm building the OAuth correctly because I can't authenticate. I've double-checked it, and checked it against another existing library but still can't seem to get it right.
The code is here.
The idea is you instantiate the service, send it config parameters, and before it does the request, it generates the 'Authorization: OAuth xxx' header and adds it to said request.
$twitter = array(
'consumer_key' => '',
'consumer_secret' => '',
'access_token' => '',
'access_token_secret' => '',
'screen_name' => '_hassankhan',
'api_url' => 'https://api.twitter.com/1.1/'
);
$service = new OAuth1AService('Twitter', $twitter['api_url']);
$service->config($twitter);
$service->doGet(
'statuses/user_timeline.json',
array(
'screen_name' => '_hassankhan',
'include_entities' => 'true'
),
array(),
'raw'
);
print($service->getResult());
I would really recommend you to use one of the already made libraries like tmhOAuth which make it really easy to interact with the twitter api.
As for your problem, seems you don't sign your request correctly. At least I could not easily find out if you include all request parameters to create the signature.
The oauth_signature parameter contains a value which is generated by
running all of the other request parameters and two secret values
through a signing algorithm.
Creating the signature is described in this document: https://dev.twitter.com/docs/auth/creating-signature .
I've written a Wordpress Plug-in that interacts with Salesforce via the REST API. It successfully gets an Instance URL and an Authentication Token using a username/password.
I'm able to submit queries and create objects using wp_remote_post with GET and POST respectively.
However, when creating objects, though successfully created in the Salesforce instance, I get the following in response to my POST:
{"message":"HTTP Method 'POST' not allowed. Allowed are HEAD,GET,PATCH,DELETE","errorCode":"METHOD_NOT_ALLOWED"}
Using the same json body content from these requests, I am able to submit and create via the Salesforce Workbench with no problems at all. I get a proper response that looks like this:
{
"id" : "003E000000OubjkIAB",
"success" : true,
"errors" : [ ]
}
Is there something in the Headers that I'm sending that Salesforce only partially disagrees with? Here are some other arguments that are getting sent as a result of using wp_remote_post - http://codex.wordpress.org/HTTP_API#Other_Arguments
Here's the php code that's calling it:
$connInfo['access_token'] = get_transient('npsf_access_token');
$connInfo['instance_url'] = get_transient('npsf_instance_url');
$url = $connInfo['instance_url'] . $service;
$sfResponse = wp_remote_post($url, array(
'method' => $method,
'timeout' => 5,
'redirection' => 5,
'httpversion' => 1.0,
'blocking' => true,
'headers' => array("Authorization" => "OAuth ". $connInfo['access_token'], "Content-type" => "application/json"),
'body' => $content,
'cookies' => array()
)
);
The $content is being encoded via json_encode before it gets to this point.
Update:
It is specific to one of the extra CURL options being sent by the WP_Http_Curl class. I haven't yet narrowed down which one Salesforce is having a problem with.
The solution is disable redirection in the request. You have it as 5 (the default) -- it needs to be set to 0 for this to work.
The initial request works but Salesforce sends a location header as a part of the response (the URL of the newly created object). WordPress thinks it is being told that the URL moved and that it should try again at this new URL. The response you're seeing is the result of that second request to the actual object you just created. That URL doesn't accept POST requests apparently.
It's a bit odd for Salesforce to be sending such a header, but there's also some discussion going on on the WordPress side that WordPress shouldn't follow location headers for non-301/302 responses which would solve this.
Thanks for posting this by the way. You update made me start debugging WP_Http_Curl which made me realize it was actually making a second HTTP request.