Product update validation
When an admin creates or updates a product, a third-party system is used to validate the product attributes. For example, a third-party system can validate the new product name.
Webhook name
observer.catalog_product_save_after
Payloads
The following observer.catalog_product_save_after payload was obtained from execution of the application code. Some data has been adjusted or deleted for brevity.
data-slots=heading, code
data-repeat=2
data-languages=JSON, JSON
Default payload
{
"eventName": "catalog_product_save_after",
"data": {
"product": {
"_edit_mode": true,
"store_id": 0,
"entity_id": "1",
"attribute_set_id": "16",
"type_id": "simple",
"sku": "Pr-1",
"name": "Product-1",
"tax_class_id": "0",
"description": "<p>Product 1 description</p>",
"price": "10.00",
"extension_attributes": {
...
},
"quantity_and_stock_status": {
...
},
"category_ids": {
...
},
"stock_data": {
...
},
"media_gallery": {
...
},
...
},
"data_object": {
...
}
}
}
Configured payload
{
"product": {
"name": "Product-1"
}
}
The third-party endpoint receives the following payload, which is based on the configured fields:
{
"product": {
"name": "Product 1"
}
}
Configuration
data-slots=heading, code
data-repeat=2
data-languages=XML, YAML
webhook.xml (PaaS)
<method name="observer.catalog_product_save_after" type="before">
<hooks>
<batch name="product_update">
<hook name="validate_name" url="{env:APP_BUILDER_URL}/validate-product-name" fallbackErrorMessage="The product name cannot be validated" method="POST" timeout="5000" softTimeout="1000">
<headers>
<header name="x-gw-ims-org-id">{env:APP_BUILDER_IMS_ORG_ID}</header>
<header name="Authorization">Bearer {env:APP_BUILDER_AUTH_TOKEN}</header>
</headers>
<fields>
<field name="product.name" source="data.product.name" />
</fields>
</hook>
</batch>
</hooks>
</method>
Admin (SaaS)
Hook Settings
Webhook method: observer.catalog_product_save_after
Webhook type: after
Batch name: product_update
Hook name: validate_name
URL: <Host>/validate-product-name
Timeout: 5000
Soft timeout: 1000
Fallback Error Message: The product name cannot be validated
Required: Required
Active: Yes
Method: POST
Developer Console OAuth
Client ID: The client ID for the OAuth credential.
Client Secret: The client secret for the OAuth credential.
Organization ID: The organization ID for the OAuth credential.
Hook Fields
Name: product.name
Source: data.product.name
Active: Yes
Endpoint code example
The following code example shows how to implement the webhook on your custom endpoint.
const fetch = require('node-fetch')
const { Core } = require('@adobe/aio-sdk')
const { errorResponse, stringParameters, checkMissingRequestInputs } = require('../utils')
// main function that will be executed by Adobe I/O Runtime
async function main (params) {
// create a Logger
const logger = Core.Logger('main', { level: params.LOG_LEVEL || 'info' })
try {
// 'info' is the default level if not set
logger.info('Calling the main action')
// log parameters, only if params.LOG_LEVEL === 'debug'
logger.debug(stringParameters(params))
//check for missing request input parameters and headers
const requiredParams = [/* add required params */]
const requiredHeaders = ['Authorization']
const errorMessage = checkMissingRequestInputs(params, requiredParams, requiredHeaders)
if (errorMessage) {
// return and log client errors
return errorResponse(400, errorMessage, logger)
}
// Place the real validation (calling 3rd party endpoints) here.
// In this example, we check if the name contains the word test.
// If it does, the request is considered invalid.
const response = {statusCode: 200}
if (/test/.test(params.product.name.toLowerCase())) {
response.body = JSON.stringify({
op: "exception",
message: "Invalid product name"
})
} else {
response.body = JSON.stringify({
op: "success"
})
}
return response
} catch (error) {
// log any server errors
logger.error(error)
// return with 500
return errorResponse(500, 'server error', logger)
}
}
exports.main = main
If validation fails, the runtime AppBuilder action returns an exception message. The message is visible to the customer.
response.body = JSON.stringify({
op: "exception",
message: "Invalid product name"
})