feat: Add endpoint for optimizing products based on clicks, including client identification and response examples in documentation
This commit is contained in:
10
.vscode/ftp-kr.sync.cache.json
vendored
10
.vscode/ftp-kr.sync.cache.json
vendored
@@ -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
86
api.php
@@ -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' )
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user