Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
[Store Customization] AI-generated store name (#11878)
Browse files Browse the repository at this point in the history
* Add new ai/store-title endpoint to update the store title with an AI generated one

* Add StoreTitle schema

* Fix error to response param

* Fix var name and tweak prompt

* Update comment

* Replace it by Ai generated if it's the default title

* Return error if AI failed

* Return false if the title is not updated with an AI one
  • Loading branch information
albarin authored Nov 24, 2023
1 parent 434c0e3 commit 9d234fc
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 5 deletions.
1 change: 0 additions & 1 deletion src/StoreApi/Routes/V1/AI/BusinessDescription.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Automattic\WooCommerce\StoreApi\Routes\V1\AI;

use Automattic\WooCommerce\Blocks\Patterns\ProductUpdater;
use Automattic\WooCommerce\StoreApi\Routes\V1\AbstractRoute;

/**
Expand Down
146 changes: 146 additions & 0 deletions src/StoreApi/Routes/V1/AI/StoreTitle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<?php

namespace Automattic\WooCommerce\StoreApi\Routes\V1\AI;

use Automattic\WooCommerce\Blocks\AI\Connection;
use Automattic\WooCommerce\StoreApi\Routes\V1\AbstractRoute;

/**
* StoreTitle class.
*
* @internal
*/
class StoreTitle extends AbstractRoute {
/**
* The route identifier.
*
* @var string
*/
const IDENTIFIER = 'ai/store-title';

/**
* The schema item identifier.
*
* @var string
*/
const SCHEMA_TYPE = 'ai/store-title';

/**
* The store title option name.
*
* @var string
*/
const STORE_TITLE_OPTION_NAME = 'blogname';

/**
* The default store title.
*
* @var string
*/
const DEFAULT_TITLE = 'Site Title';

/**
* Get the path of this REST route.
*
* @return string
*/
public function get_path() {
return '/ai/store-title';
}

/**
* Get method arguments for this REST route.
*
* @return array An array of endpoints.
*/
public function get_args() {
return [
[
'methods' => \WP_REST_Server::CREATABLE,
'callback' => [ $this, 'get_response' ],
'permission_callback' => [ Middleware::class, 'is_authorized' ],
'args' => [
'business_description' => [
'description' => __( 'The business description for a given store.', 'woo-gutenberg-products-block' ),
'type' => 'string',
],
],
],
'schema' => [ $this->schema, 'get_public_item_schema' ],
'allow_batch' => [ 'v1' => true ],
];
}

/**
* Update the store title powered by AI.
*
* @param \WP_REST_Request $request Request object.
*
* @return bool|string|\WP_Error|\WP_REST_Response
*/
protected function get_route_post_response( \WP_REST_Request $request ) {

$business_description = $request->get_param( 'business_description' );

if ( ! $business_description ) {
return $this->error_to_response(
new \WP_Error(
'invalid_business_description',
__( 'Invalid business description.', 'woo-gutenberg-products-block' )
)
);
}

$store_title = get_option( 'blogname' );
if ( ! ( empty( $store_title ) || self::DEFAULT_TITLE === $store_title ) ) {
return rest_ensure_response( array( 'ai_content_generated' => false ) );
}

$ai_generated_title = $this->generate_ai_title( $business_description );
if ( is_wp_error( $ai_generated_title ) ) {
return $this->error_to_response( $ai_generated_title );
}

update_option( self::STORE_TITLE_OPTION_NAME, $ai_generated_title );

return rest_ensure_response(
array(
'ai_content_generated' => true,
)
);
}

/**
* Generate the store title powered by AI.
*
* @param string $business_description The business description for a given store.
*
* @return string|\WP_Error|\WP_REST_Response The store title generated by AI.
*/
private function generate_ai_title( $business_description ) {
$ai_connection = new Connection();

$site_id = $ai_connection->get_site_id();
if ( is_wp_error( $site_id ) ) {
return $this->error_to_response( $site_id );
}

$token = $ai_connection->get_jwt_token( $site_id );
if ( is_wp_error( $token ) ) {
return $this->error_to_response( $token );
}

$prompt = "Generate a store title for a store that has the following: '$business_description'. The length of the title should be 1 and 3 words. The result should include only the store title without any other explanation, number or punctuation marks";

$ai_response = $ai_connection->fetch_ai_response( $token, $prompt );
if ( is_wp_error( $ai_response ) ) {
return $this->error_to_response( $ai_response );
}

if ( ! isset( $ai_response['completion'] ) ) {
return '';
}

return $ai_response['completion'];
}
}
9 changes: 5 additions & 4 deletions src/StoreApi/RoutesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,11 @@ public function __construct( SchemaController $schema_controller ) {
],
// @todo Migrate internal AI routes to WooCommerce Core codebase.
'private' => [
Routes\V1\AI\Images::IDENTIFIER => Routes\V1\AI\Images::class,
Routes\V1\AI\Patterns::IDENTIFIER => Routes\V1\AI\Patterns::class,
Routes\V1\AI\Product::IDENTIFIER => Routes\V1\AI\Product::class,
Routes\V1\AI\Products::IDENTIFIER => Routes\V1\AI\Products::class,
Routes\V1\AI\StoreTitle::IDENTIFIER => Routes\V1\AI\StoreTitle::class,
Routes\V1\AI\Images::IDENTIFIER => Routes\V1\AI\Images::class,
Routes\V1\AI\Patterns::IDENTIFIER => Routes\V1\AI\Patterns::class,
Routes\V1\AI\Product::IDENTIFIER => Routes\V1\AI\Product::class,
Routes\V1\AI\Products::IDENTIFIER => Routes\V1\AI\Products::class,
Routes\V1\AI\BusinessDescription::IDENTIFIER => Routes\V1\AI\BusinessDescription::class,
],
];
Expand Down
1 change: 1 addition & 0 deletions src/StoreApi/SchemaController.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public function __construct( ExtendSchema $extend ) {
Schemas\V1\ProductCategorySchema::IDENTIFIER => Schemas\V1\ProductCategorySchema::class,
Schemas\V1\ProductCollectionDataSchema::IDENTIFIER => Schemas\V1\ProductCollectionDataSchema::class,
Schemas\V1\ProductReviewSchema::IDENTIFIER => Schemas\V1\ProductReviewSchema::class,
Schemas\V1\AI\StoreTitleSchema::IDENTIFIER => Schemas\V1\AI\StoreTitleSchema::class,
Schemas\V1\AI\ImagesSchema::IDENTIFIER => Schemas\V1\AI\ImagesSchema::class,
Schemas\V1\AI\PatternsSchema::IDENTIFIER => Schemas\V1\AI\PatternsSchema::class,
Schemas\V1\AI\ProductSchema::IDENTIFIER => Schemas\V1\AI\ProductSchema::class,
Expand Down
47 changes: 47 additions & 0 deletions src/StoreApi/Schemas/V1/AI/StoreTitleSchema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
namespace Automattic\WooCommerce\StoreApi\Schemas\V1\AI;

use Automattic\WooCommerce\StoreApi\Schemas\V1\AbstractSchema;

/**
* StoreTitleSchema class.
*
* @internal
*/
class StoreTitleSchema extends AbstractSchema {
/**
* The schema item name.
*
* @var string
*/
protected $title = 'ai/store-title';

/**
* The schema item identifier.
*
* @var string
*/
const IDENTIFIER = 'ai/store-title';

/**
* Business Description schema properties.
*
* @return array
*/
public function get_properties() {
return [];
}

/**
* Get the Business Description response.
*
* @param array $item Item to get response for.
*
* @return array
*/
public function get_item_response( $item ) {
return [
'ai_content_generated' => true,
];
}
}

0 comments on commit 9d234fc

Please sign in to comment.