feat: Add endpoint for optimizing products based on clicks, including client identification and response examples in documentation

This commit is contained in:
2026-03-09 15:42:24 +01:00
parent 17a9665cf2
commit ba90f22904
3 changed files with 193 additions and 7 deletions

View File

@@ -9,8 +9,8 @@
},
"api.php": {
"type": "-",
"size": 5529,
"lmtime": 1772790264251,
"size": 10947,
"lmtime": 1772982639016,
"modified": false
},
"autoload": {
@@ -341,6 +341,12 @@
"size": 657,
"lmtime": 1772115859276,
"modified": false
},
"api-public-product-management.md": {
"type": "-",
"size": 6206,
"lmtime": 1772982690134,
"modified": false
}
},
"feeds": {

86
api.php
View File

@@ -340,6 +340,92 @@ if ( \S::get( 'action' ) == 'product_google_category_get' )
] );
}
// Pobranie 10 produktow do optymalizacji (wg klikniec, bez nowego tytulu lub kategorii Google)
if ( \S::get( 'action' ) == 'products_to_optimize' )
{
api_validate_api_key( $mdb );
$client_id = trim( (string) \S::get( 'client_id' ) );
$google_ads_id = trim( (string) \S::get( 'google_ads_id' ) );
$merchant_id = trim( (string) \S::get( 'merchant_id' ) );
$limit = (int) \S::get( 'limit' );
if ( $limit <= 0 || $limit > 100 )
{
$limit = 10;
}
// Resolve client_id from whichever parameter was provided
$resolved_client_id = null;
if ( $client_id !== '' )
{
$resolved_client_id = (int) $mdb -> get( 'clients', 'id', [ 'id' => (int) $client_id ] );
}
elseif ( $google_ads_id !== '' )
{
$google_ads_id_clean = str_replace( '-', '', $google_ads_id );
$resolved_client_id = (int) $mdb -> query(
'SELECT id FROM clients WHERE REPLACE( google_ads_customer_id, \'-\', \'\' ) = :gid LIMIT 1',
[ ':gid' => $google_ads_id_clean ]
) -> fetchColumn();
}
elseif ( $merchant_id !== '' )
{
$merchant_id_clean = str_replace( '-', '', $merchant_id );
$resolved_client_id = (int) $mdb -> query(
'SELECT id FROM clients WHERE REPLACE( google_merchant_account_id, \'-\', \'\' ) = :mid LIMIT 1',
[ ':mid' => $merchant_id_clean ]
) -> fetchColumn();
}
else
{
api_json_response( [ 'result' => 'error', 'message' => 'Missing required param: client_id, google_ads_id or merchant_id' ], 422 );
}
if ( !$resolved_client_id )
{
api_json_response( [ 'result' => 'error', 'message' => 'Client not found' ], 404 );
}
$products = $mdb -> query(
'SELECT p.id,
p.offer_id,
p.name AS original_name,
p.title AS custom_title,
p.google_product_category,
p.product_url,
SUM( pa.clicks_30 ) AS clicks_30,
SUM( pa.clicks_all_time ) AS clicks_all_time,
SUM( pa.impressions_30 ) AS impressions_30,
SUM( pa.cost_30 ) AS cost_30,
SUM( pa.conversions_30 ) AS conversions_30,
SUM( pa.conversion_value_30 ) AS conversion_value_30
FROM products AS p
INNER JOIN products_aggregate AS pa ON pa.product_id = p.id
WHERE p.client_id = :client_id
AND (
TRIM( COALESCE( p.title, \'\' ) ) = \'\'
OR TRIM( COALESCE( p.google_product_category, \'\' ) ) = \'\'
)
GROUP BY p.id
HAVING clicks_all_time > 0
ORDER BY clicks_all_time DESC
LIMIT :limit',
[
':client_id' => $resolved_client_id,
':limit' => $limit
]
) -> fetchAll( \PDO::FETCH_ASSOC );
api_json_response( [
'result' => 'ok',
'client_id' => $resolved_client_id,
'count' => count( $products ),
'products' => $products
] );
}
// Open Page Rank - zapis
if ( \S::get( 'action' ) == 'domain_opr_save' )
{

View File

@@ -212,7 +212,99 @@ Jesli kategoria nie jest ustawiona:
}
```
### 4.5 Ustawienie custom_label_4 (istniejacy endpoint)
### 4.5 Pobranie produktow do optymalizacji
- `action=products_to_optimize`
- Cel: zwraca liste produktow posortowanych wg klikniec (malejaco), ktore nie maja ustawionego custom tytulu (`title`) lub kategorii Google (`google_product_category`)
Identyfikacja klienta (wymagany dokladnie jeden z trzech):
- `client_id` (int) - lokalny identyfikator klienta w adsPRO
- `google_ads_id` (string) - ID konta Google Ads (z myslnikami lub bez, np. `123-456-7890` lub `1234567890`)
- `merchant_id` (string) - ID konta Google Merchant Center (z myslnikami lub bez)
Parametry dodatkowe:
- `api_key` (string, wymagany)
- `limit` (int, opcjonalny) - liczba produktow do zwrocenia (domyslnie 10, max 100)
Logika:
- Wybiera produkty, ktorych `title` jest pusty/NULL **lub** `google_product_category` jest pusty/NULL
- Pomija produkty z 0 klikniec (all-time)
- Sortuje po `clicks_all_time` malejaco (produkty z najwiekszym ruchem na gorze)
- Agreguje dane z `products_aggregate` (suma klikniec ze wszystkich kampanii/grup reklam)
Przyklad z `client_id`:
```bash
curl -G "https://example.com/api.php" \
--data-urlencode "action=products_to_optimize" \
--data-urlencode "api_key=YOUR_API_KEY" \
--data-urlencode "client_id=12" \
--data-urlencode "limit=10"
```
Przyklad z `google_ads_id`:
```bash
curl -G "https://example.com/api.php" \
--data-urlencode "action=products_to_optimize" \
--data-urlencode "api_key=YOUR_API_KEY" \
--data-urlencode "google_ads_id=123-456-7890"
```
Przyklad z `merchant_id`:
```bash
curl -G "https://example.com/api.php" \
--data-urlencode "action=products_to_optimize" \
--data-urlencode "api_key=YOUR_API_KEY" \
--data-urlencode "merchant_id=987654321"
```
Przyklad odpowiedzi:
```json
{
"result": "ok",
"client_id": 12,
"count": 3,
"products": [
{
"id": 987,
"offer_id": "SKU-123",
"original_name": "Buty sportowe Nike Air",
"custom_title": null,
"google_product_category": null,
"product_url": "https://example.com/buty-nike-air",
"clicks_30": 45,
"clicks_all_time": 312,
"impressions_30": 1200,
"cost_30": "89.500000",
"conversions_30": "3.000000",
"conversion_value_30": "450.000000"
},
{
"id": 654,
"offer_id": "SKU-456",
"original_name": "Koszulka Adidas",
"custom_title": "Koszulka sportowa Adidas Originals",
"google_product_category": null,
"product_url": "https://example.com/koszulka-adidas",
"clicks_30": 22,
"clicks_all_time": 198,
"impressions_30": 800,
"cost_30": "45.200000",
"conversions_30": "1.000000",
"conversion_value_30": "120.000000"
}
]
}
```
Bledy specyficzne:
- Brak parametru identyfikujacego klienta: `422` z `"Missing required param: client_id, google_ads_id or merchant_id"`
- Klient nie znaleziony: `404` z `"Client not found"`
### 4.6 Ustawienie custom_label_4 (istniejacy endpoint)
- `action=product_custom_label_4_set`
- Cel: zapisuje `products.custom_label_4`
@@ -270,9 +362,11 @@ Przy integracji AI zawsze ustawiaj jawnie `action` i weryfikuj, czy odpowiedz to
## 7. Minimalny scenariusz end-to-end
1. Ustaw tytul (`product_title_set`)
2. Potwierdz zmiane (`product_title_changed_check`)
3. Ustaw kategorie (`product_google_category_set`)
4. Odczytaj kategorie (`product_google_category_get`)
1. Pobierz liste produktow do optymalizacji (`products_to_optimize`)
2. Dla kazdego produktu z listy:
a. Jesli `custom_title` jest `null` - ustaw tytul (`product_title_set`)
b. Potwierdz zmiane tytulu (`product_title_changed_check`)
c. Jesli `google_product_category` jest `null` - ustaw kategorie (`product_google_category_set`)
d. Odczytaj kategorie (`product_google_category_get`)
To daje prosty, deterministyczny przeplyw dla automatyzacji AI.