0

I'm not sure if I'm asking the right question, so here is the context.

I'm making a POST to an API (The api is to a Google Sheets Script - so there are some unusual limitations). When I use postman the data is returned in a json file. In order to get it to work in postman I have to send the parameters via the body and I have to select the raw option. Selecting any other option(i.e. x-www-form-urlencoded or form-data) results in an html error page.

I've followed the steps for wp_remote_post($api_url , $body ); in the WordPress documentation - but I'm getting the html error instead of the expected data.

How do I send the body as "raw" just like it's being sent in Postman?

UPDATE - To add code.

$api_url = 'https://script.google.com/macros/s/UNIQUE_KEYw/exec';
// $body = array(
//  "method"=>"GET",
//  "sheet"=>"date",
//  "key"=>"PASSWORD");

$body = ('{\n"method": "GET",\n"sheet": "date",\n"key": "PASSWORD"\n}');

$request =  wp_remote_post($api_url , array(
    'method'      => 'POST',
    'headers'     => ["Content-Type" => "raw"],
    'body'        => $body,
    'data_format' => 'body'
    )
                          );

The HTTP_Request2 snippet from postman that I'm trying to recreate.

<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('https://script.google.com/macros/s/UNIQUE_KEY/exec');
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
$request->setHeader(array(
  'Content-Type' => 'text/plain'
));
$request->setBody('{\n"method": "GET",\n"sheet": "date",\n"key": "PASSWORD"\n}');
try {
  $response = $request->send();
  if ($response->getStatus() == 200) {
    echo $response->getBody();
  }
  else {
    echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
    $response->getReasonPhrase();
  }
}
catch(HTTP_Request2_Exception $e) {
  echo 'Error: ' . $e->getMessage();
}

2 Answers 2

2

I got this one working, you have to pass the json_encoded array on the body parameter of the request.

 $customer_details = [
            'first_name' => $first_name,
            'last_name' => $last_name,
            'email' => $email,
        ];

        $customer_details['body'] = json_encode($customer_details);

        $customer = $api->createUpdateCustomer($customer_details);

public function createUpdateCustomer($customer_details) {
        $response = $this->apiCall( "2.0/customers", 'POST', $customer_details);
        $result = json_decode($response);
        return $result;
    }

public function apiCall($baseUrl = null, $method = 'GET', $args = array()) {
        if ( !is_null( $baseUrl ) ) {
            $url = $this->baseUrl . $baseUrl;
        }
        else {
            $url = $this->baseUrl;
        }

        // Populate the args for use in the wp_remote_request call
        $wp_args = array_merge($args, $this->args);
        $wp_args['method']  = $method;
        $wp_args['timeout'] = 30;        

        // Make the call and store the response in $res
        $res = wp_remote_request( $url, $wp_args );        

        // Check for success
        if ( ! is_wp_error( $res ) && ( 200 == $res['response']['code'] || 201 == $res['response']['code'] ) ) {
            return $res['body'];
        } else {
            throw new Exception( "API call didn't go well :(. Either VendHQ Connect Settings are incorrect or VendHQ server is not responding as expected." );
        }
    }
0

You should be able to set headers to use content-type: application/json:

$api_url = 'https://script.google.com/macros/s/UNIQUE_KEYw/exec';
$body = wp_json_encode( array(
    "method" => "GET",
    "sheet" => "date",
    "key" => "PASSWORD"
) );

wp_remote_post( $api_url, [
    'headers'   => [ 'Content-Type' => 'application/json' ],
    'body'       => $body,
    'data_format' => 'body'
] );
3
  • Ok I was trying text/plain. How would I format the body then? - I've updated the question with my code. Feb 10, 2020 at 15:25
  • I updated based on the code you provided - you should be able to just use json_encode() on the body array you have commented out. In WP there's wp_json_encode(). Also you might mean to set headers to 'content-type': 'application/json'?
    – Tim Elsass
    Feb 10, 2020 at 15:51
  • I spent some time on this, unfortunately I don't think it's working properly. I do think the request is being sent, but I think the request needs to be very specific. I've added the working HTTP_request2 snippet from Postman that I'm trying to recreate with WP to the original post. Feb 10, 2020 at 20:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.