Skip to content

Commit 78e7b5b

Browse files
committed
refactor!: удалены устаревшие методы рекламы, обновлены BASKETS
Методы getSearchAds() и getCarouselAds() удалены — эндпоинты catalog-ads и carousel-ads выведены из эксплуатации WB. BASKETS расширены с 44 до 47 корзин по обновлённой карте volHostV2. BASKETS и VIDEO_BASKETS переведены на хранение только верхних границ. BREAKING CHANGE: удалены getSearchAds(), getCarouselAds(), SEARCH.ADS, SEARCH.CAROUSEL_ADS.
1 parent 0e85e93 commit 78e7b5b

9 files changed

Lines changed: 75 additions & 143 deletions

File tree

.github/workflows/release.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ jobs:
2424
env:
2525
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
2626

27+
- name: Get release notes
28+
id: notes
29+
run: |
30+
echo "body<<EOF" >> $GITHUB_OUTPUT
31+
git log -1 --pretty=format:'%B' >> $GITHUB_OUTPUT
32+
echo "EOF" >> $GITHUB_OUTPUT
33+
2734
- uses: softprops/action-gh-release@v3
2835
with:
29-
generate_release_notes: true
36+
body: ${{ steps.notes.outputs.body }}

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ WBPrivateAPI (src/WBPrivateAPI.js)
5252

5353
- `src/Constants.js` — единственный источник истины для URL, складов (`WAREHOUSES`), направлений доставки (`DESTINATIONS`), типов приложений, валют, локалей. При добавлении нового URL — добавлять сюда.
5454
- `src/SessionBuilder.js` — фабрика HTTP-клиента на `undici`. Экспоненциальный backoff, retry, общие заголовки. Не создавать `fetch`/HTTP-клиенты вне него. `SessionBuilder.setAntibotToken(session, token)` устанавливает токен в Cookie.
55-
- `src/WBPrivateAPI.js` — основной класс. Конструктор `{ destination, wbaasToken }` — токен можно передать явно или он читается из `.wbaas_token`. При наличии токена переключается на `__internal` URL. Методы: `search()`, `getSearchAds()`, `getCarouselAds()`, `keyHint()`, `searchSimilarByNm()`, `getDeliveryDataByNms()`, `getPromos()`, `getListOfProducts()`, `getSupplierInfo()`, `getSupplierShipment()`, `getSupplierCatalog()`, `getSupplierCatalogAll()`, `getSupplierCatalogPage()`, `SupplierTotalProducts()`, `setToken()`.
55+
- `src/WBPrivateAPI.js` — основной класс. Конструктор `{ destination, wbaasToken }` — токен можно передать явно или он читается из `.wbaas_token`. При наличии токена переключается на `__internal` URL. Методы: `search()`, `keyHint()`, `searchSimilarByNm()`, `getDeliveryDataByNms()`, `getPromos()`, `getListOfProducts()`, `getSupplierInfo()`, `getSupplierShipment()`, `getSupplierCatalog()`, `getSupplierCatalogAll()`, `getSupplierCatalogPage()`, `getSupplierProductCount()`, `setToken()`.
5656
- `src/Utils.js` — вспомогательные функции: построение URL изображений (`Utils.Card.imageURL()`), вычисление номера корзины, генерация query ID.
5757

5858
**Инициализация:**

README.md

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ NodeJS модуль. Работает через приватное API Wildberr
44

55
![GitHub package.json version](https://img.shields.io/github/package-json/v/rrrublev/wb-private-api) ![npm](https://img.shields.io/npm/v/@rrrublev/wb-private-api) ![GitHub last commit](https://img.shields.io/github/last-commit/rrrublev/wb-private-api) ![GitHub commit activity](https://img.shields.io/github/commit-activity/m/rrrublev/wb-private-api)
66

7-
[![NPM](https://nodei.co/npm/@rrrublev/wb-private-api.png)](https://nodei.co/npm/@rrrublev/wb-private-api/)
7+
[![NPM](https://nodei.co/npm/@rrrublev/wb-private-api.png)](https://www.npmjs.com/package/@rrrublev/wb-private-api)
88

99
## Установка
1010

@@ -62,23 +62,6 @@ const { items: questions } = await product.getQuestions();
6262

6363
</details>
6464

65-
<details>
66-
<summary>Вывод рекламодателей из поисковой выдачи</summary>
67-
68-
```js
69-
import { WBPrivateAPI, Constants } from "@rrrublev/wb-private-api";
70-
71-
const wbapi = new WBPrivateAPI({ destination: Constants.DESTINATIONS.MOSCOW });
72-
73-
const { pages, prioritySubjects, adverts } = await wbapi.getSearchAds("Менструальные чаши");
74-
75-
console.log(pages); // позиции рекламы на страницах
76-
console.log(prioritySubjects); // темы по приоритету
77-
console.log(adverts); // рекламодатели с CPM
78-
```
79-
80-
</details>
81-
8265
<details>
8366
<summary>Получение всех товаров поставщика</summary>
8467

@@ -118,8 +101,6 @@ new WBPrivateAPI({ destination, wbaasToken? })
118101
| Метод | Возвращает | Описание |
119102
|-------|-----------|----------|
120103
| `search(keyword, pageCount?, retries?, filters?)` | `WBCatalog` | Поиск товаров по ключевому слову. `pageCount = 0` — все страницы (до 100) |
121-
| `getSearchAds(keyword)` | `object` | Рекламодатели в поисковой выдаче |
122-
| `getCarouselAds(productId)` | `array` | Реклама в карусели внутри карточки товара |
123104
| `keyHint(query)` | `array` | Поисковые подсказки WB |
124105
| `searchSimilarByNm(productId)` | `object` | Похожие товары (как в разделе «Похожие товары» на WB) |
125106

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rrrublev/wb-private-api",
3-
"version": "0.8.5",
3+
"version": "0.8.6",
44
"description": "Node.js wrapper for Wildberries private API",
55
"main": "index.js",
66
"files": [

src/Constants.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ module.exports = {
4343
EXACTMATCH: "https://search.wb.ru/exactmatch/ru/common/v18/search",
4444
EXACTMATCH_INTERNAL: "https://www.wildberries.ru/__internal/search/exactmatch/ru/common/v18/search",
4545
CATALOG: "https://wbxcatalog-ru.wildberries.ru/{}/catalog",
46-
ADS: "https://catalog-ads.wildberries.ru/api/v5/search",
47-
CAROUSEL_ADS: "https://carousel-ads.wildberries.ru/api/v4/carousel",
4846
HINT: "https://suggests.wb.ru/suggests/api/v7/hint",
4947
HINT_INTERNAL: "https://www.wildberries.ru/__internal/suggests/suggests/api/v7/hint",
5048
LIST: "https://card.wb.ru/cards/v4/list",

src/Utils.js

Lines changed: 64 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2,81 +2,83 @@
22
const format = require("string-format");
33
const Constants = require("./Constants");
44

5-
// vol = Math.floor(nm_id / 100000); basket number = index + 1 (zero-padded).
5+
// vol = Math.floor(nm_id / 100000); верхняя граница корзины (индекс + 1).
66
// Source: WB JS volHostV2() in product_dist JS (staticbasket_route_map).
77
const BASKETS = [
8-
[0, 143], // basket-01
9-
[144, 287], // basket-02
10-
[288, 431], // basket-03
11-
[432, 719], // basket-04
12-
[720, 1007], // basket-05
13-
[1008, 1061], // basket-06
14-
[1062, 1115], // basket-07
15-
[1116, 1169], // basket-08
16-
[1170, 1313], // basket-09
17-
[1314, 1601], // basket-10
18-
[1602, 1655], // basket-11
19-
[1656, 1919], // basket-12
20-
[1920, 2045], // basket-13
21-
[2046, 2189], // basket-14
22-
[2190, 2405], // basket-15
23-
[2406, 2621], // basket-16
24-
[2622, 2837], // basket-17
25-
[2838, 3053], // basket-18
26-
[3054, 3269], // basket-19
27-
[3270, 3485], // basket-20
28-
[3486, 3701], // basket-21
29-
[3702, 3917], // basket-22
30-
[3918, 4133], // basket-23
31-
[4134, 4349], // basket-24
32-
[4350, 4565], // basket-25
33-
[4566, 4877], // basket-26
34-
[4878, 5189], // basket-27
35-
[5190, 5501], // basket-28
36-
[5502, 5813], // basket-29
37-
[5814, 6125], // basket-30
38-
[6126, 6437], // basket-31
39-
[6438, 6749], // basket-32
40-
[6750, 7061], // basket-33
41-
[7062, 7373], // basket-34
42-
[7374, 7685], // basket-35
43-
[7686, 7997], // basket-36
44-
[7998, 8309], // basket-37
45-
[8310, 8741], // basket-38
46-
[8742, 9173], // basket-39
47-
[9174, 9605], // basket-40
48-
[9606, 10373], // basket-41
49-
[10374, 11141], // basket-42
50-
[11142, 11909], // basket-43
51-
[11910, Infinity], // basket-44
8+
143, // basket-01
9+
287, // basket-02
10+
431, // basket-03
11+
719, // basket-04
12+
1007, // basket-05
13+
1061, // basket-06
14+
1115, // basket-07
15+
1169, // basket-08
16+
1313, // basket-09
17+
1601, // basket-10
18+
1655, // basket-11
19+
1919, // basket-12
20+
2045, // basket-13
21+
2189, // basket-14
22+
2405, // basket-15
23+
2621, // basket-16
24+
2837, // basket-17
25+
3053, // basket-18
26+
3269, // basket-19
27+
3485, // basket-20
28+
3701, // basket-21
29+
3917, // basket-22
30+
4133, // basket-23
31+
4349, // basket-24
32+
4565, // basket-25
33+
4877, // basket-26
34+
5189, // basket-27
35+
5501, // basket-28
36+
5813, // basket-29
37+
6125, // basket-30
38+
6437, // basket-31
39+
6749, // basket-32
40+
7061, // basket-33
41+
7373, // basket-34
42+
7685, // basket-35
43+
7997, // basket-36
44+
8309, // basket-37
45+
8741, // basket-38
46+
9173, // basket-39
47+
9605, // basket-40
48+
10373, // basket-41
49+
11141, // basket-42
50+
11909, // basket-43
51+
12677, // basket-44
52+
13445, // basket-45
53+
14213, // basket-46
54+
Infinity, // basket-47
5255
];
5356

54-
// vol = nm_id % 144; basket number = index + 1 (zero-padded).
57+
// vol = nm_id % 144; верхняя граница корзины (индекс + 1).
5558
// Source: WB JS videonme_route_map switch statement in volVideoHost().
5659
const VIDEO_BASKETS = [
57-
[0, 11], // basket-01
58-
[12, 23], // basket-02
59-
[24, 35], // basket-03
60-
[36, 47], // basket-04
61-
[48, 59], // basket-05
62-
[60, 71], // basket-06
63-
[72, 83], // basket-07
64-
[84, 95], // basket-08
65-
[96, 107], // basket-09
66-
[108, 119], // basket-10
67-
[120, 131], // basket-11
68-
[132, 143], // basket-12
60+
11, // basket-01
61+
23, // basket-02
62+
35, // basket-03
63+
47, // basket-04
64+
59, // basket-05
65+
71, // basket-06
66+
83, // basket-07
67+
95, // basket-08
68+
107, // basket-09
69+
119, // basket-10
70+
131, // basket-11
71+
143, // basket-12
72+
Infinity, // basket-13 (default)
6973
];
7074

7175
const getBasketNumber = (productId) => {
7276
const vol = Math.floor(productId / 100000);
73-
const index = BASKETS.findIndex(([from, to]) => vol >= from && vol <= to);
74-
return String(index + 1).padStart(2, "0");
77+
return String(BASKETS.findIndex(top => vol <= top) + 1).padStart(2, "0");
7578
};
7679

7780
const getVideoBasket = (vol) => {
78-
const index = VIDEO_BASKETS.findIndex(([from, to]) => vol >= from && vol <= to);
79-
return String(index >= 0 ? index + 1 : VIDEO_BASKETS.length + 1).padStart(2, "0");
81+
return String(VIDEO_BASKETS.findIndex(top => vol <= top) + 1).padStart(2, "0");
8082
};
8183

8284
const imageURL = (productId, imageType = "SMALL", order = 1) => {

src/WBPrivateAPI.js

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -300,29 +300,6 @@ class WBPrivateAPI {
300300
return res.data.data?.products ?? res.data.products;
301301
}
302302

303-
/**
304-
* Search for adverts and their ads form specified keyword
305-
* @param {string} keyword - the search query
306-
* @returns {object} - An object with adverts and their ads
307-
*/
308-
async getSearchAds(keyword) {
309-
const options = { params: { keyword } };
310-
const res = await this.session.get(Constants.URLS.SEARCH.ADS, options);
311-
return res.data;
312-
}
313-
314-
/**
315-
* Search for carousel ads inside product card
316-
* @param {number} productId - product id
317-
* @returns {array} - An array with ads
318-
*/
319-
async getCarouselAds(productId) {
320-
const res = await this.session.get(Constants.URLS.SEARCH.CAROUSEL_ADS, {
321-
params: { nm: productId },
322-
});
323-
return res.data;
324-
}
325-
326303
/**
327304
* It takes a query string and returns a list of suggestions that match the query
328305
* @param {string} query - the search query

tests/Constants.URLs.integration.test.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,6 @@ describe("Интеграционное тестирование URL с мето
176176
"SUPPLIER.CATALOG": { url: Constants.URLS.SUPPLIER.CATALOG, expectedVersion: "v4" },
177177
"PRODUCT.DETAILS": { url: Constants.URLS.PRODUCT.DETAILS, expectedVersion: "v4" },
178178
"PRODUCT.FEEDBACKS": { url: Constants.URLS.PRODUCT.FEEDBACKS, expectedVersion: "v2" },
179-
"SEARCH.ADS": { url: Constants.URLS.SEARCH.ADS, expectedVersion: "v5" },
180-
"SEARCH.CAROUSEL_ADS": { url: Constants.URLS.SEARCH.CAROUSEL_ADS, expectedVersion: "v4" },
181179
"SEARCH.HINT": { url: Constants.URLS.SEARCH.HINT, expectedVersion: "v7" }
182180
};
183181

@@ -198,8 +196,6 @@ describe("Интеграционное тестирование URL с мето
198196
"SUPPLIER.SHIPMENT",
199197
"SEARCH.EXACTMATCH_INTERNAL",
200198
"SEARCH.CATALOG",
201-
"SEARCH.ADS",
202-
"SEARCH.CAROUSEL_ADS",
203199
"SEARCH.SIMILAR_BY_NM"
204200
],
205201
"search.wb.ru": ["SEARCH.EXACTMATCH"],

tests/Constants.URLs.test.js

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -331,35 +331,6 @@ describe("Тестирование URL из Constants.js", () => {
331331
console.log(`✅ SEARCH.SIMILAR_BY_NM: ${url} (${result.status})`);
332332
}, 15000);
333333

334-
// catalog-ads.wildberries.ru и carousel-ads.wildberries.ru недоступны с данного IP
335-
// (ENOTFOUND — геоблок или хосты выведены из эксплуатации).
336-
// Тесты проверяют только что URL прописан корректно в Constants.
337-
test("Проверка URL рекламы в поиске", async () => {
338-
const url = Constants.URLS.SEARCH.ADS;
339-
expect(url).toMatch(/^https:\/\//);
340-
let result;
341-
try {
342-
result = await httpGet(url, { params: { keyword: TEST_DATA.keywords[0] } });
343-
expect([200, 400, 403, 404]).toContain(result.status);
344-
console.log(`✅ SEARCH.ADS: ${url} (${result.status})`);
345-
} catch (error) {
346-
console.log(`⚠️ SEARCH.ADS недоступен (сеть): ${error.message}`);
347-
}
348-
}, 15000);
349-
350-
test("Проверка URL карусельной рекламы", async () => {
351-
const url = Constants.URLS.SEARCH.CAROUSEL_ADS;
352-
expect(url).toMatch(/^https:\/\//);
353-
let result;
354-
try {
355-
result = await httpGet(url, { params: { nm: TEST_DATA.products.valid[0] } });
356-
expect([200, 400, 403, 404]).toContain(result.status);
357-
console.log(`✅ SEARCH.CAROUSEL_ADS: ${url} (${result.status})`);
358-
} catch (error) {
359-
console.log(`⚠️ SEARCH.CAROUSEL_ADS недоступен (сеть): ${error.message}`);
360-
}
361-
}, 15000);
362-
363334
test("Проверка URL подсказок поиска", async () => {
364335
const url = Constants.URLS.SEARCH.HINT;
365336
let result;

0 commit comments

Comments
 (0)