File: /home4/cca63905/public_html/nueva/modules/btecommercecopilot/lib/clientAi.php
<?php
/**
* Ecommerce copilot
*
* @author businesstech.fr <modules@businesstech.fr> - https://www.businesstech.fr/
* @copyright https://www.businesstech.fr/
* @license see file: LICENSE.txt
*
* ____ _______
* | _ \ |__ __|
* | |_) | | |
* | _ < | |
* | |_) | | |
* |____/ |_|
*/
namespace btecommercecopilot\ModuleLib;
if (!defined('_PS_VERSION_')) {
exit;
}
use btecommercecopilot\Configuration\moduleConfiguration;
class clientAi
{
/**
* The action to use to authentify action to make
*
* @var string
*/
private $action;
/**
* The temperature to use
*
* @var float
*/
private $temperature = 1;
/**
* The presence penality to use
*
* @var int
*/
private $presence_penalty = 0;
/**
* The frequency penality to use
*
* @var int
*/
private $frequency_penalty = 0;
/**
* The shopName
*
* @var string
*/
private $shopName = '';
/**
* The shop url
*
* @var string
*/
private $shopUrl = '';
/**
* construct
*
* @param string $action
*/
public function __construct(string $action)
{
$this->action = $action;
$this->temperature = moduleTools::getTemperature();
$this->presence_penalty = 0;
$this->frequency_penalty = 0;
$this->shopName = \Configuration::get('PS_SHOP_NAME');
$this->shopUrl = rtrim((string) \Context::getContext()->link->getBaseLink(), '/');
}
/**
* Generate the the long description with chat GPT
*
* @param string $productName
* @param string $lang
* @param int $idProduct
* @param int $idLang
*
*/
public function generateProductDescription($productName, $lang, $idProduct, $idLang)
{
try {
if ($this->action != 'completions') {
return false;
}
$productDescription = '';
$response = '';
$brand = moduleTools::handleProductBrands($idProduct);
$features = moduleTools::handleProductFeature($idProduct, $idLang);
$featureList = '';
$customPrompt = \Configuration::get('ECOP_CUSTOM_LONG_DESC_PROMPT');
if (!empty($features)) {
foreach ($features as $key => $feature) {
$featureList .= ' ' . $feature;
}
}
if (!empty($customPrompt)) {
$modulePromptOption = str_replace('{product_name}', $productName, \Configuration::get('ECOP_LONG_DESC_PROMPT'));
} else {
$modulePromptOption = $productName;
}
$IaCall['apiCallConf'] = [
'temperature' => $this->temperature,
'ai' => 'gpt',
'frequency_penalty' => $this->frequency_penalty,
'presence_penalty' => $this->presence_penalty,
'PsAccountCurrentShop' => \Configuration::get('ECOP_SHOP_UUID'),
'PsShopName' => $this->shopName,
'PsShopUrl' => $this->shopUrl,
'promptData' => [
'useCustomPrompt' => $customPrompt,
'typeOfDataToGenerate' => 'long-description',
'modulePromptOption' => $modulePromptOption,
'maxSize' => moduleConfiguration::getLimitOfSize()['long-description'],
'brand' => !empty($brand) ? $brand : '',
'feature' => !empty($featureList) ? $featureList : '',
'language' => $lang,
],
];
$response = self::getResponse('api/businesstechIa/generate', 'POST', $IaCall);
if (isset($response->result)) {
if ($response->result == 'true') {
return $response->data;
}
} else {
return false;
}
} catch (\Exception $e) {
\PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
}
}
/**
* Generate the the short description with chat GPT
*
* @param string $productName
* @param string $lang
* @param int $idProduct
*
*/
public function generateProductShortDescription($productName, $lang, $idProduct)
{
try {
if ($this->action != 'completions') {
return false;
}
$response = '';
$brand = moduleTools::handleProductBrands($idProduct);
$customPrompt = \Configuration::get('ECOP_CUSTOM_SHORT_DESC_PROMPT');
if (!empty($customPrompt)) {
$modulePromptOption = str_replace('{product_name}', $productName, \Configuration::get('ECOP_LONG_DESC_PROMPT'));
} else {
$modulePromptOption = $productName;
}
$IaCall['apiCallConf'] = [
'temperature' => $this->temperature,
'ai' => 'gpt',
'frequency_penalty' => $this->frequency_penalty,
'presence_penalty' => $this->presence_penalty,
'PsAccountCurrentShop' => \Configuration::get('ECOP_SHOP_UUID'),
'PsShopName' => $this->shopName,
'PsShopUrl' => $this->shopUrl,
'promptData' => [
'useCustomPrompt' => $customPrompt,
'typeOfDataToGenerate' => 'short-description',
'modulePromptOption' => $modulePromptOption,
'maxSize' => moduleConfiguration::getLimitOfSize()['short-description'],
'brand' => !empty($brand) ? $brand : '',
'language' => $lang,
],
];
$response = self::getResponse('api/businesstechIa/generate', 'POST', $IaCall);
if (isset($response->result)) {
if ($response->result == 'true') {
return $response->data;
}
} else {
return false;
}
} catch (\Exception $e) {
\PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
}
}
/**
* Generate the the meta description with chat GPT
*
* @param string $productName
* @param string $lang
* @param int $idProduct
*
*/
public function generateProductMetaDescription($productName, $lang, $idProduct)
{
try {
if ($this->action != 'completions') {
return false;
}
$productDescription = '';
$response = '';
$brand = moduleTools::handleProductBrands($idProduct);
$customPrompt = \Configuration::get('ECOP_CUSTOM_META_DESC_PROMPT');
if (!empty($customPrompt)) {
$modulePromptOption = str_replace('{product_name}', $productName, \Configuration::get('ECOP_META_DESC_PROMPT'));
} else {
$modulePromptOption = $productName;
}
$IaCall['apiCallConf'] = [
'temperature' => $this->temperature,
'ai' => 'gpt',
'frequency_penalty' => $this->frequency_penalty,
'presence_penalty' => $this->presence_penalty,
'PsAccountCurrentShop' => \Configuration::get('ECOP_SHOP_UUID'),
'PsShopName' => $this->shopName,
'PsShopUrl' => $this->shopUrl,
'promptData' => [
'useCustomPrompt' => $customPrompt,
'typeOfDataToGenerate' => 'meta-description',
'modulePromptOption' => $modulePromptOption,
'maxSize' => moduleConfiguration::getLimitOfSize()['meta-description'],
'brand' => !empty($brand) ? $brand : '',
'language' => $lang,
],
];
$response = self::getResponse('api/businesstechIa/generate', 'POST', $IaCall);
if (isset($response->result)) {
if ($response->result == 'true') {
return $response->data;
}
} else {
return false;
}
} catch (\Exception $e) {
\PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
}
}
/**
* Generate the category description
*
* @param string $categoryName
* @param string $lang
*
*/
public function generateCategoryDescription($categoryName, $lang)
{
try {
if ($this->action != 'completions') {
return false;
}
$categoryDescription = '';
$response = '';
$customPrompt = \Configuration::get('ECOP_CUSTOM_CAT_LONG_DESC_PROMPT');
if (!empty($customPrompt)) {
$modulePromptOption = str_replace('{category_name}', $categoryName, \Configuration::get('ECOP_CAT_DESC_PROMPT'));
} else {
$modulePromptOption = $categoryName;
}
$IaCall['apiCallConf'] = [
'temperature' => $this->temperature,
'ai' => 'gpt',
'frequency_penalty' => $this->frequency_penalty,
'presence_penalty' => $this->presence_penalty,
'PsAccountCurrentShop' => \Configuration::get('ECOP_SHOP_UUID'),
'PsShopName' => $this->shopName,
'PsShopUrl' => $this->shopUrl,
'promptData' => [
'useCustomPrompt' => $customPrompt,
'typeOfDataToGenerate' => 'category-description',
'modulePromptOption' => $modulePromptOption,
'maxSize' => moduleConfiguration::getLimitOfSize()['category-description'],
'language' => $lang,
],
];
$response = self::getResponse('api/businesstechIa/generate', 'POST', $IaCall);
if (isset($response->result)) {
if ($response->result == 'true') {
return $response->data;
}
} else {
return false;
}
} catch (\Exception $e) {
\PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
}
}
/**
* Generate the category addtionnal description
*
* @param string $categoryName
* @param string $lang
*
*/
public function generateCategoryAdditionnalDescription($categoryName, $lang)
{
try {
if ($this->action != 'completions') {
return false;
}
$response = '';
$customPrompt = \Configuration::get('ECOP_CUSTOM_CAT_ADD_DESC_PROMPT');
if (!empty($customPrompt)) {
$modulePromptOption = str_replace('{category_name}', $categoryName, \Configuration::get('ECOP_CAT_ADD_DESC_PROMPT'));
} else {
$modulePromptOption = $categoryName;
}
$IaCall['apiCallConf'] = [
'temperature' => $this->temperature,
'ai' => 'gpt',
'frequency_penalty' => $this->frequency_penalty,
'presence_penalty' => $this->presence_penalty,
'PsAccountCurrentShop' => \Configuration::get('ECOP_SHOP_UUID'),
'PsShopName' => $this->shopName,
'PsShopUrl' => $this->shopUrl,
'promptData' => [
'useCustomPrompt' => $customPrompt,
'typeOfDataToGenerate' => 'category-additional-description',
'modulePromptOption' => $modulePromptOption,
'maxSize' => moduleConfiguration::getLimitOfSize()['category-additional-description'],
'language' => $lang,
],
];
$response = self::getResponse('api/businesstechIa/generate', 'POST', $IaCall);
if (isset($response->result)) {
if ($response->result == 'true') {
return $response->data;
}
} else {
return false;
}
} catch (\Exception $e) {
\PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
}
}
/**
* Generate the category addtionnal description
*
* @param string $categoryName
* @param string $lang
*
*/
public function generateCategoryMetaDescription($categoryName, $lang)
{
try {
if ($this->action != 'completions') {
return false;
}
$response = '';
$customPrompt = \Configuration::get('ECOP_CUSTOM_CAT_META_DESC_PROMPT');
if (!empty($customPrompt)) {
$modulePromptOption = str_replace('{category_name}', $categoryName, \Configuration::get('ECOP_META_CAT_DESC_PROMPT'));
} else {
$modulePromptOption = $categoryName;
}
$IaCall['apiCallConf'] = [
'temperature' => $this->temperature,
'ai' => 'gpt',
'frequency_penalty' => $this->frequency_penalty,
'presence_penalty' => $this->presence_penalty,
'PsAccountCurrentShop' => \Configuration::get('ECOP_SHOP_UUID'),
'PsShopName' => $this->shopName,
'PsShopUrl' => $this->shopUrl,
'promptData' => [
'useCustomPrompt' => $customPrompt,
'typeOfDataToGenerate' => 'category-meta-description',
'modulePromptOption' => $modulePromptOption,
'maxSize' => moduleConfiguration::getLimitOfSize()['category-meta-description'],
'language' => $lang,
],
];
$response = self::getResponse('api/businesstechIa/generate', 'POST', $IaCall);
if (isset($response->result)) {
if ($response->result == 'true') {
return $response->data;
}
} else {
return false;
}
} catch (\Exception $e) {
\PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
}
}
/**
* Generate the cms page content
*
* @param string $cmsPageName
* @param string $lang
*
*/
public function generateCmsContent($cmsPageName, $lang)
{
try {
if ($this->action != 'completions') {
return false;
}
$response = '';
$customPrompt = \Configuration::get('ECOP_CUSTOM_CMS_PROMPT');
if (!empty($customPrompt)) {
$modulePromptOption = str_replace('{cms_name}', $cmsPageName, \Configuration::get('ECOP_CMS_CONTENT'));
} else {
$modulePromptOption = $cmsPageName;
}
$IaCall['apiCallConf'] = [
'temperature' => $this->temperature,
'ai' => 'gpt',
'frequency_penalty' => $this->frequency_penalty,
'presence_penalty' => $this->presence_penalty,
'PsAccountCurrentShop' => \Configuration::get('ECOP_SHOP_UUID'),
'PsShopName' => $this->shopName,
'PsShopUrl' => $this->shopUrl,
'promptData' => [
'useCustomPrompt' => $customPrompt,
'typeOfDataToGenerate' => 'cms-page-content',
'modulePromptOption' => $modulePromptOption,
'maxSize' => moduleConfiguration::getLimitOfSize()['cms-page-content'],
'language' => $lang,
],
];
$response = self::getResponse('api/businesstechIa/generate', 'POST', $IaCall);
if (isset($response->result)) {
if ($response->result == 'true') {
return $response->data;
}
} else {
return false;
}
} catch (\Exception $e) {
\PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
}
}
/**
* Generate the product translate data
*
* @param int $productId
* @param int $langFromId
* @param mixed $targetLanguage
* @param string $generateType
*
*/
public function translateProductData($productId, $langFromId, $targetLanguage, $generateType)
{
try {
if ($this->action != 'completions' || empty($generateType) || empty($langFromId)) {
return false;
}
$tranlatedData = '';
$response = '';
$productDescription = '';
$product = new \Product((int) $productId, false, (int) $langFromId);
if ($generateType == 'long-description') {
if (empty($product->description)) {
return false;
}
$productDescription .= $product->description;
} elseif ($generateType == 'short-description') {
if (empty($product->description_short)) {
return false;
}
$productDescription .= $product->description_short;
} elseif ($generateType == 'meta-description') {
if (empty($product->meta_description)) {
return false;
}
$productDescription .= $product->meta_description;
} else {
return false;
}
$IaCall['apiCallConf'] = [
'temperature' => $this->temperature,
'ai' => 'gpt',
'frequency_penalty' => $this->frequency_penalty,
'presence_penalty' => $this->presence_penalty,
'PsAccountCurrentShop' => \Configuration::get('ECOP_SHOP_UUID'),
'PsShopName' => $this->shopName,
'PsShopUrl' => $this->shopUrl,
'promptData' => [
'targetLanguage' => $targetLanguage->name,
'elementDescription' => $productDescription,
],
];
$response = self::getResponse('api/businesstechIa/translate', 'POST', $IaCall);
if (isset($response->result)) {
if ($response->result == 'true') {
$tranlatedData = $response->data;
$tranlatedData = str_replace($targetLanguage->name . ':', '', $tranlatedData);
return $tranlatedData;
}
} else {
return false;
}
} catch (\Exception $e) {
\PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
}
}
/**
* Check the subscription status
*
*/
public static function checkSubscriptionStatus()
{
if (empty(\Configuration::get('ECOP_HAS_BF_SUB'))) {
return false;
}
try {
$params = [
'PsAccountCurrentShop' => \Configuration::get('ECOP_SHOP_UUID'),
'PsShopName' => \Configuration::get('PS_SHOP_NAME'),
'PsShopUrl' => rtrim((string) \Context::getContext()->link->getBaseLink(), '/'),
];
return self::getResponse('api/businesstechIa/checkSubscription', 'POST', $params);
} catch (\Exception $e) {
\PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
}
}
/**
* Check the consumption on period
*/
public static function checkSubscriptionConsumption()
{
if (empty(\Configuration::get('ECOP_HAS_BF_SUB'))) {
return false;
}
try {
$params = [
'PsAccountCurrentShop' => \Configuration::get('ECOP_SHOP_UUID'),
'PsShopName' => \Configuration::get('PS_SHOP_NAME'),
'PsShopUrl' => rtrim((string) \Context::getContext()->link->getBaseLink(), '/'),
];
return self::getResponse('api/businesstechIa/checkSubscriptionConsumptionPeriod', 'POST', $params);
} catch (\Exception $e) {
\PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
}
}
/**
* Generate the category translate data
*
* @param int $categoryId
* @param int $langFromId
* @param mixed $targetLanguage
* @param string $generateType
*/
public function translateCategoryData($categoryId, $langFromId, $targetLanguage, $generateType)
{
try {
if ($this->action != 'completions' || empty($generateType) || empty($langFromId)) {
return false;
}
$tranlatedData = '';
$response = '';
$categoryDescription = '';
$category = new \Category((int) $categoryId);
if ($generateType == 'category-description') {
if (empty($category->description[$langFromId])) {
return false;
}
$categoryDescription .= $category->description[$langFromId];
} elseif ($generateType == 'category-additional-description') {
if (empty($category->additional_description[$langFromId])) {
return false;
}
$categoryDescription .= $category->additional_description[$langFromId];
} elseif ($generateType == 'category-meta-description') {
if (empty($category->meta_description[$langFromId])) {
return false;
}
$categoryDescription .= $category->meta_description[$langFromId];
} else {
return false;
}
$IaCall['apiCallConf'] = [
'temperature' => $this->temperature,
'ai' => 'gpt',
'frequency_penalty' => $this->frequency_penalty,
'presence_penalty' => $this->presence_penalty,
'PsAccountCurrentShop' => \Configuration::get('ECOP_SHOP_UUID'),
'PsShopName' => $this->shopName,
'PsShopUrl' => $this->shopUrl,
'promptData' => [
'targetLanguage' => $targetLanguage->name,
'elementDescription' => $categoryDescription,
],
];
$response = self::getResponse('api/businesstechIa/translate', 'POST', $IaCall);
if (isset($response->result)) {
if ($response->result == 'true') {
$tranlatedData = $response->data;
$tranlatedData = str_replace($targetLanguage->name . ':', '', $tranlatedData);
return $tranlatedData;
}
} else {
return false;
}
} catch (\Exception $e) {
\PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
}
}
/**
* Generate cms content translation data
*
* @param string $cmsContent
* @param int $langFromId
* @param mixed $targetLanguage
*
*/
public function translateCmsContentData($cmsContent, $langFromId, $targetLanguage)
{
try {
if ($this->action != 'completions' || empty($cmsContent) || empty($langFromId)) {
return false;
}
$tranlatedData = '';
$response = null;
$IaCall['apiCallConf'] = [
'temperature' => $this->temperature,
'ai' => 'gpt',
'frequency_penalty' => $this->frequency_penalty,
'presence_penalty' => $this->presence_penalty,
'PsAccountCurrentShop' => \Configuration::get('ECOP_SHOP_UUID'),
'PsShopName' => $this->shopName,
'PsShopUrl' => $this->shopUrl,
'promptData' => [
'targetLanguage' => $targetLanguage->name,
'elementDescription' => $cmsContent,
],
];
$response = self::getResponse('api/businesstechIa/translate', 'POST', $IaCall);
if (isset($response->result)) {
if ($response->result == 'true') {
$tranlatedData = $response->data;
$tranlatedData = str_replace($targetLanguage->name . ':', '', $tranlatedData);
return $tranlatedData;
}
} else {
return false;
}
} catch (\Exception $e) {
\PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
}
}
/**
* Retrieve CURL Handle
*
* @param string $url
* @param string $method
* @param array $params
* @param array $addHeaders
*
* @return resource
*/
public static function getCurlHandle($url, $method = 'POST', $params = [], $addHeaders = [])
{
// initialize curl library
$curlHandle = curl_init();
$headers = [
'Accept' => 'application/json',
'Content-type' => 'application/json',
'X-MODULE-COP-TOKEN' => 'OdcJAlG2F7gaM537fXUTmDzdhJztwDAd',
];
// Combine headers, prevent override of original headers
$headers = ($headers + $addHeaders);
$curlHeaders = [];
foreach ($headers as $key => $value) {
$curlHeaders[] = $key . ': ' . $value;
}
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, $curlHeaders);
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlHandle, CURLOPT_ENCODING, '');
curl_setopt($curlHandle, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($curlHandle, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curlHandle, CURLOPT_URL, $url);
curl_setopt($curlHandle, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curlHandle, CURLOPT_TIMEOUT, 5000);
curl_setopt($curlHandle, CURLOPT_NOSIGNAL, 1);
curl_setopt($curlHandle, CURLOPT_FAILONERROR, false);
curl_setopt($curlHandle, CURLOPT_FRESH_CONNECT, true);
if ($method == 'GET') {
curl_setopt($curlHandle, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($curlHandle, CURLOPT_HTTPGET, true);
curl_setopt($curlHandle, CURLOPT_POST, false);
} elseif ($method == 'POST') {
curl_setopt($curlHandle, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($curlHandle, CURLOPT_POST, true);
// Content type is set to JSON so we can encode our form data this way
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, json_encode($params));
}
return $curlHandle;
}
/**
* Retrieve response regarding a query
*
* @param string $path
* @param array $params
* @param array $addHeaders
*
* @return mixed
*/
public static function getResponse($path, $method = 'GET', $params = [], $addHeaders = [])
{
$url = \btecommercecopilot::$apiUrl . $path;
if (count($params) && $method == 'GET') {
$url .= '?' . http_build_query($params);
}
// Retrieve CURL handle
$curlHandle = self::getCurlHandle($url, $method, $params, $addHeaders);
$errorNb = $errorMessage = null;
$response = curl_exec($curlHandle);
$httpCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
if ($response === false) {
$errorNb = curl_errno($curlHandle);
$errorMessage = curl_error($curlHandle);
curl_close($curlHandle);
} else {
$response = json_decode($response);
}
if ($httpCode == 200) {
return $response;
} elseif ($httpCode == 429) {
throw new \Exception('Error Processing Request - Too many requests', 2);
} elseif ($httpCode == 403) {
return $httpCode;
} elseif ($httpCode == 419) {
throw new \Exception('Error Processing CSRF Token Request - Server error', 4);
} elseif ($httpCode == 500) {
throw new \Exception('Error Processing Request - Server error', 5);
} elseif ($httpCode == 504) {
throw new \Exception('Error Processing Request - Timeout', 6);
} elseif (empty($httpCode)) {
throw new \Exception(sprintf('Error Processing Request - Unknown - %s', $errorMessage), 7);
} elseif ($httpCode == 401) { // Happen when the Oauth didn't work
return \Tools::redirectAdmin(\Context::getContext()->link->getAdminLink('AdminModules') . '&configure=btecommercecopilot');
}
throw new \Exception("Error Processing Request - HTTP Code $httpCode", 1);
}
}