I just started to build my own web service for alexa skill.
My web service support HTTPS, and the endpoint was hit when I used the alexa simulator for testing, but I got the error 'INVALID_SKILL_RESPONSE'.
This is the simple response from my php code:
return response(
[
'version' => '1.0',
'response' => [
'outputSpeech' => [
'type' => 'PlainText',
'text' => 'Hello world',
]
]
],
200,
[
'Content-Type' => 'application/json',
]
);
What could cause the problem?
I'm not sure where this response function is coming from.
Try something like this:
<?php
$responseArray = [
'version' => '1.0',
'response' => [
'outputSpeech' => [
'type' => 'PlainText',
'text' => 'Hello World'
],
'shouldEndSession' => true
]
];
header( 'Content-Type: application/json' );
echo json_encode( $responseArray );
?>
Related
I have created a custom endpoint using API Platform:
#[ApiResource(
collectionOperations: [
'get' => [
'normalization_context' => ['groups' => ['product:list']]
],
'post' => [
'denormalization_context' => ['groups' => ['product:list']]
]
],
itemOperations: [
'get_by_user' => [
'method' => 'GET',
'path' => '/products/user/{id}',
'read' => 'false',
'controller' => ProductController::class,
'normalization_context' => ['groups' => ['product:list']],
'openapi_context' => [
'summary' => 'Retrieves the Product collection for a specific user ID',
'description' => 'Retrieves the Product collection for a specific user ID'
]
],
], )]
and the controller method:
public function __invoke(int $id): array
{
$prod = $this->productRepository
->findBy(
['user' => $id],
);
return $prod;
}
And the error when I try to call this endpoint is:
Not Found - api/vendor/api-platform/core/src/EventListener/ReadListener.php
Has anyone any ideas what might be the issue?
I am using wp_remote_post() to post products to a third party site. First I get these products via API from a site called Mercado Libre. But when I carry out the mass publication, the products are published without a name, without a price, and without respecting the parameters provided. They only have the name "Product".
function publish_products_in_woocommerce()
{
$respuesta = wp_remote_get('https://api.mercadolibre.com/sites/MLA/search?q=Motorola%20G6', array(
'headers' => array(
'Authorization' => 'Bearer APP_USR-2778915669536100-052221-0f3a39361bdcea9bc3de0df8ab619f66-370993848'
)
));
$respuesta = json_decode($respuesta['body'], true);
print_r($respuesta);
foreach ($respuesta['results'] as $value) {
$product_data = array(
'name' => $value['title'],
'status' => 'draft',
'type' => 'simple',
'regular_price' => $value['price'],
'description' => $value['title'],
'short_description' => $value['title'],
'categories' => [
[
'id' => $value['category_id'],
]
],
'images' => [
[
'src' => $value['thumbnail']
]
]
);
$woocommerce_api_ck = 'ck_b2a0f58d07590e8283302eca04fbc1b66a9ff653';
$woocommerce_api_cs = 'cs_b4d91662590be47416f663fc9f0d1c49f600e394';
$url = 'http://nuevo.labisbal.com.ar/wp-json/wc/v3/products';
wp_remote_post('http://nuevo.labisbal.com.ar/wp-json/wc/v3/products', array(
'headers' => array(
'Authorization ' => 'Basic ' . base64_encode($woocommerce_api_ck . ':' . $woocommerce_api_cs),
),
'body' => $ProductToWooCommerce = json_encode($product_data),
'method' => 'POST',
'timeout' => 145,
'blocking' => false,
'sslverify' => false,
'stream' => true,
'data_format' => 'json'
));
print_r($ProductToWooCommerce);
if (wp_remote_retrieve_response_message($respuesta) === 'Created') {
echo 'The product has been created';
}
}
}
publish_products_in_woocommerce();
?>
It's strange because when I display the json already converted (using json_encode) the data is displayed correctly... (using print_r)
I take a look at this and the issue is on how you sent the data to the API, when you use wp_remote_post you need to send the body as an array, and the method handles that information for you, so you don't need to convert it to JSON.
Below is a small test plugin that saves products using the WC REST API, the plugin adds a new endpoint to your site to trigger the scrapper https://yoursite.com/wp-json/wpapi/v1/fetch, I hope that helps.
Note: Please double check the code, is not fully tested.
<?php
/**
* Plugin Name: A WC API test
* Plugin URI: https://enriquechavez.co
* Description: Just a test.
* Version: 1.0.0
* Requires at least: 5.2
* Requires PHP: 7.4
* Author: Enrique Chavez
* Author URI: https://enriquechavez.co/
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Update URI: https://example.com/my-plugin/
* Text Domain: my-basics-plugin
* Domain Path: /languages
*/
add_action('rest_api_init', function () {
register_rest_route('wpapi/v1', 'fetch', [
'methods' => WP_REST_Server::READABLE,
'callback' => 'fetch_ml_products',
'permissions_callback' => '__return_true',
]);
});
function fetch_ml_products(WP_REST_Request $request)
{
$ml_api = 'https://api.mercadolibre.com/sites/MLM/search?q=Motorola%20G6&limit=5';
$wc_ck = 'ck_1f2e32852403a1701c1adxxxxxxxxxxxxxxxxxxx';
$wc_cs = 'cs_6fd5feedd2a25b73eebc9xxxxxxxxxxxxxxxxxxx';
$request = wp_safe_remote_get($ml_api);
if (is_wp_error($request)) {
return $request;
}
$response = json_decode(wp_remote_retrieve_body($request));
$new_products = [];
foreach ($response->results as $product) {
$wc_api_url = 'https://wp.test/wp-json/wc/v3/products/';
$request_data = [
'headers' => [
'Authorization' => 'Basic ' . base64_encode($wc_ck . ':' . $wc_cs),
],
'body' => [
'name' => $product->title,
'status' => 'draft',
'regular_price' => $product->price,
],
'sslverify' => false,
];
$request = wp_remote_post($wc_api_url, $request_data);
if (is_wp_error($request)) {
// TODO: validate the error.
print_r($request);
die('Something is wrong');
}
$new_products[] = json_decode(wp_remote_retrieve_body($request));
}
return $new_products;
}
I want to add Response code(400,404, 500) for each route in swagger UI using , so that user know in advance what will be the response for these error code.
I am following following link but not sure how can I modify the Response object and can add the response for 400, 404, 401 so on.
https://api-platform.com/docs/core/openapi/#overriding-the-openapi-specification
I am using symfony 5.2 and apiplatfrom 2.6 while writing this question.
When you are using decorators, you are essentially extending existing service code.
First you are getting path and then set your custom operation in swagger context with the given code.
If you notice the code block:
$openApi->getPaths()->addPath('/api/grumpy_pizzas/{id}', $pathItem->withGet(
$operation->withParameters(array_merge(
$operation->getParameters(),
[new Model\Parameter('fields', 'query', 'Fields to remove of the output')]
))
));
The path item take Operation object as an argument which has withResponses method that can be used to modify any responses that your path generates.
Take this as per-cursor and you can check whole source and see what fits your requirements best. Check source : PathItem.php
You can build response according to Response object and add it to Operation and to path.
Tip: Any editor with good linter would make your coding easier as it will be able to show you available methods.
Its late to post but I got the solutions for adding response code in my Swagger Ui, it can help some looking for solution.
private function setErrorResponseDescriptions(OpenApi $openApi): OpenApi
{
$schemas = $openApi->getComponents()->getSchemas();
$schemas['Error'] = [
'type' => 'object',
'properties' => [
'type' => [
'type' => 'string',
'readOnly' => true,
],
'title' => [
'type' => 'string',
'readOnly' => true,
],
'detail' => [
'type' => 'string',
'readOnly' => true,
],
],
];
$schemas['ValidationError'] = [
'type' => 'object',
'properties' => [
'type' => [
'type' => 'string',
'readOnly' => true,
],
'title' => [
'type' => 'string',
'readOnly' => true,
],
'detail' => [
'type' => 'string',
'readOnly' => true,
],
'validations' => [
'type' => 'array',
'readOnly' => true,
'items' => [
'type' => 'object',
'properties' => [
'propertyPath' => [
'type' => 'string',
'readOnly' => true,
],
'message' => [
'type' => 'string',
'readOnly' => true,
],
]
]
]
],
];
foreach ($openApi->getPaths()->getPaths() as $path => $pathItem) {
foreach (['PUT', 'POST', 'PATCH', 'GET'] as $method) {
$item = $pathItem->{'get' . ucfirst($method)}();
if ($item) {
$item->addResponse(
new Model\Response(
description: 'Unauthorized',
content: new \ArrayObject([
'application/problem+json' => [
'schema' => [
'$ref' => '#/components/schemas/Error',
],
],
])
),
'401'
);
if ('GET' !== $method) {
$item->addResponse(
new Model\Response(
description: 'Bad request',
content: new \ArrayObject([
'application/problem+json' => [
'schema' => [
'$ref' => '#/components/schemas/ValidationError',
],
],
])
),
'400'
);
} else {
$item->addResponse(
new Model\Response(
description: 'Not Found',
content: new \ArrayObject([
'application/problem+json' => [
'schema' => [
'$ref' => '#/components/schemas/Error',
],
],
])
),
'404'
);
}
}
}
}
return $openApi;
}
I want to post info to external api but I get error 422 all the time. Geting info and authorization works fine. I'm using Symfony Http Client, authorization and headers are defined in framework.yaml for now.
Api documentation fragment:
curl "https://business.untappd.com/api/v1/locations/3/custom_menus"
-X POST
-H "Authorization: Basic bmlja0BuZXh0Z2xhc3MuY286OW5kTWZESEJGcWJKeTJXdDlCeC0="
-H "Content-Type: application/json"
-d '{ "custom_menu": { "name": "Wine selection" } }'
My service fragment:
public function customMenu(): int
{
$response = $this->client->request(
'POST',
'https://business.untappd.com/api/v1/locations/'.$this->getLocationId().'/custom_menus',
[
'json' => [
['custom_menu' => ['name' => 'Wine selection']],
],
]
);
Try to encode json "manualy", before send. Just like that
//$jsonData = '{ "custom_menu": { "name": "Wine selection" } }';
$jsonData = json_encode(["custom_menu" => ["name" => "Wine selection"]]);
$response = $client->request(
'POST',
'https://business.untappd.com/api/v1/locations/'.$this->getLocationId().'/custom_menus',
[
'headers' => [
'Content-Type' => 'application/json',
],
'body' => $jsonData,
]
);
There are an error and some missing parameters you didn't include:
The most important : Authorization (if you didn't add it to your framework.yaml file under 'http_client' parameter).
Your link ends with 'custom_menus' not 'menus'.
The content-type.
You can test this correction:
public function customMenu(): int
{
$response = $this->client->request(
'POST',
'https://business.untappd.com/api/v1/locations/'.$this->getLocationId().'/custom_menus', //corrected '/custom_menus'
[
'auth_basic' => ['bmlja0BuZXh0Z2xhc3MuY286OW5kTWZESEJGcWJKeTJXdDlCeC0='], // To add
'headers' => [ // To add
'Content-Type' => 'application/json',
],
'json' => [
['custom_menu' => ['name' => 'Wine selection']],
],
]
);
// .....
}
I want to store all outgoing http request from my wordpress site. I want to store all internal and external http request and response also request made with curl. Any help should be useful to me.
Hook into WP_Http::_dispatch_request()
function fn_log_http_request_response( $wp_http_response, $request, $url ) {
$request = [
'method' => $request['method'],
'url' => $url,
'headers' => $request['headers'],
'body' => $request['body'],
];
if($wp_http_response instanceof WP_Error) {
$response = [
'errors' => $wp_http_response->errors,
'error_data' => $wp_http_response->error_data,
];
} else {
$response = [
'status' => [
'code' => wp_remote_retrieve_response_code($wp_http_response),
'message' => wp_remote_retrieve_response_message($wp_http_response),
],
'headers' => wp_remote_retrieve_headers($wp_http_response)->getAll(),
'body' => wp_remote_retrieve_body($wp_http_response),
];
}
error_log(print_r([
'request' => $request,
'response' => $response,
], true));
return $wp_http_response;
}
// hook into WP_Http::_dispatch_request()
add_filter('http_response', 'fn_log_http_request_response', 10, 3 );
Adopted from hinnerk-a
You can also try the following plugin as well
https://wordpress.org/plugins/log-http-requests