Актуальный код
Последняя версия кода
Code.js
/**
* @OnlyCurrentDoc
* @author Mikhail Nosaev <m.nosaev@gmail.com>
* @see {@link https://t.me/nosaev_m Telegram} разработка Google таблиц и GAS скриптов
* @see {@link https://openapi.wb.ru Wildberries API}
* Актуально для версии 410
*/
var service = PropertiesService.getScriptProperties();
const WB = Wildberries;
const LR = LongRun; // LongRun ID: 1FGSkC1f4YZbX17sQMsHKPNJ8VOKRfMUkN8yqFfkF1B_YIFfEC431aS4l
LR.setSttings({
objThis: this,
service,
maxMinutesRun: 5,
delayMinutes: 0.5,
});
const debug = false;
const { WBC, WBM, WBA, WBS, WBADV, WBFQ, WBPD, WBT, WBSP, WBCP } =
WB.apiClasses({
service,
logRequest: debug,
check: false,
}) || {};
function onOpen() {
WB.checkApiKey(service);
WB.CONFIG.menu.full();
}
function setApiKeyMultipleAccess() {
WB.setApiKeyMultipleAccess(service);
}
function wildberriesJwtTokenInfo() {
WB.wildberriesJwtTokenInfo(service);
}
// ####################################################################################################################################
// API СТАТИСТИКА
// ####################################################################################################################################
// Начальная дата для выгрузки
const dateFrom2004 = Utilities.formatDate(
new Date(2004, 0, 1, 0, 0, 0),
Session.getScriptTimeZone(),
"yyyy-MM-dd"
);
const dateFrom2024 = Utilities.formatDate(
new Date(2024, 0, 1, 0, 0, 0),
Session.getScriptTimeZone(),
"yyyy-MM-dd"
);
function statIncomes() {
// Поставки
const { dateFrom } = WB.getSettingsMain({ func: arguments.callee.name });
WB.statIncomes(WBS, {
dateFrom: dateFrom || dateFrom2024,
debug, // режим отладки
});
}
function statStocks() {
// Склад
const { dateFrom, settings: accumulate } = WB.getSettingsMain({
func: arguments.callee.name,
});
WB.statStocks(WBS, {
dateFrom: dateFrom || dateFrom2004,
accumulate, // on ChekBox для накопления
filterKeysAboveZero: [
// "quantity",
// "inWayToClient",
// "inWayFromClient",
"quantityFull",
], // фильтр по количеству > 0
debug, // режим отладки
});
}
function statOrders() {
// Заказы
const { dateFrom, settings: accumulate } = WB.getSettingsMain({
func: arguments.callee.name,
});
WB.statOrders(WBS, {
dateFrom: dateFrom || WB.subtractDays(93),
minusDays: 31, // смещение дней от текущей даты
accumulate, // on ChekBox для накопления
formulas: [
`={"Название";ArrayFormula(IF(INDIRECT("G2:G")="";;IFNA(VLOOKUP(INDIRECT("G2:G");'📝 Товары'!D:I;6;0);"!!! Удалённый товар")))}`,
], // массив формул
debug, // режим отладки
});
}
function statSales() {
// Продажи
const { dateFrom, settings: accumulate } = WB.getSettingsMain({
func: arguments.callee.name,
});
WB.statSales(WBS, {
dateFrom: dateFrom || WB.subtractDays(93),
minusDays: 31, // смещение дней от текущей даты
accumulate, // on ChekBox для накопления
formulas: [
`={"Название";ArrayFormula(IF(INDIRECT("G2:G")="";;IFNA(VLOOKUP(INDIRECT("G2:G");'📝 Товары'!D:I;6;0);"!!! Удалённый товар")))}`,
], // массив формул
debug, // режим отладки
});
}
function statReportDetailByPeriod() {
// Отчет о продажах по реализации новый
const {
dateFrom,
dateTo,
settings: accumulate,
} = WB.getSettingsMain({ func: arguments.callee.name });
WB.statReportDetailByPeriod(WBS, {
dateFrom,
dateTo,
accumulate, // on ChekBox для накопления
limit: 25000, // строк в запросе, раскомментировать, если не хватает памяти 50мб
delay: 30000, // задержка межу запросами
// returnSignConversion: false, // обратные знаки для возвратов
// logisticSignConversion: false, // обратные знаки для логистики стронто
debug, // режим отладки
});
}
// ####################################################################################################################################
// API МАРКЕТПЛЕЙС
// ####################################################################################################################################
function stocksFbs() {
// Склад fbs
WB.stocksFbs({
marketplaceApi: WBM,
contentApi: WBC,
pricesDiscountsApi: WBPD,
stocksPrices: true,
debug, // режим отладки
});
}
function ordersFbsNew() {
// Новые заказы fbs
WB.ordersFbsNew(WBM, {
oneBar: true, // первый баркод, если в массиве несколько
});
}
function ordersFbs() {
// Заказы fbs
const { dateFrom, dateTo } = WB.getSettingsMain({
func: arguments.callee.name,
});
WB.ordersFbs(WBM, {
dateFrom: dateFrom || WB.subtractDays(93),
dateTo: dateTo || WB.addDays(1),
oneBar: true, // первый баркод, если в массиве несколько
cut: true, // без адреса доставки
debug, // режим отладки
});
}
function ordersFbsStickers() {
// Получить этикетки для сборочных заданий
WB.ordersFbsStickers(WBM, {
type: "png",
width: 58,
height: 40,
});
}
function ordersFbsCreateStickers() {
// Создать и сохранить этикетки для сборочных заданий на Google Drive
WB.ordersFbsCreateStickers(WBM, {});
}
// ####################################################################################################################################
// API ОТЗЫВЫ
// ####################################################################################################################################
function ratingsFedbacks() {
// Рейтинги (сайт)
const { settings: accumulate } = WB.getSettingsMain({
func: arguments.callee.name,
});
WB.ratingsFedbacks({
pricesDiscountsApi: WBPD, // использовать nmIds из апи Цены и скидки
// contentApi: WBC, // использовать nmIds из апи Контент
accumulate, // on ChekBox для накопления
debug, // режим отладки
});
}
function feedbacksList() {
// Отзывы все
const {
dateFrom,
dateTo,
settings: stat,
} = WB.getSettingsMain({ func: arguments.callee.name, str: false });
WB.feedbacksList(WBFQ, {
dateFrom,
dateTo,
stat, // on ChekBox получить дополнительные поля для анализа
});
}
function feedbacksUnanswered() {
// Отзывы неотвеченные
const { dateFrom, dateTo } = WB.getSettingsMain({
func: arguments.callee.name,
str: false,
});
WB.feedbacksUnanswered(WBFQ, {
dateFrom,
dateTo,
});
}
function questionsList() {
// Вопросы все
const {
dateFrom,
dateTo,
settings: additionalInfo,
} = WB.getSettingsMain({ func: arguments.callee.name, str: false });
console.log({
dateFrom,
dateTo,
additionalInfo
});
WB.questionsList(WBFQ, {
dateFrom,
dateTo,
additionalInfo, // on ChekBox получить дополнительные поля для анализа
});
}
function questionsUnanswered() {
// Вопросы неотвеченные
const { dateFrom, dateTo } = WB.getSettingsMain({
func: arguments.callee.name,
str: false,
});
WB.questionsUnanswered(WBFQ, {
dateFrom,
dateTo,
});
}
// ####################################################################################################################################
// API ПРОДВИЖЕНИЕ (РЕКЛАМА)
// ####################################################################################################################################
function advBalance() {
// Баланс РК
WB.advBalance(WBADV);
}
function advList() {
// Список РК
const { dateFrom } = WB.getSettingsMain({ func: arguments.callee.name });
WB.advList(WBADV, {
dateFrom,
service,
});
}
function advListWithNmIds() {
// Список РК c артикулами WB
const { dateFrom } = WB.getSettingsMain({ func: arguments.callee.name });
WB.advListWithNmIds(WBADV, {
dateFrom,
service,
debug,
});
}
function advStatFull() {
/**
* Статистика РК
*
* Данные вернутся для кампаний в статусе 7, 9 и 11
*
* Статусы кампании:
* -1 - кампания в процессе удаления
* 4 - готова к запуску
* 7 - кампания завершена
* 8 - отказался
* 9 - идут показы
* 11 - кампания на паузе
*
* Типы кампании:
* 4 - кампания в каталоге
* 5 - кампания в карточке товара
* 6 - кампания в поиске
* 7 - кампания в рекомендациях на главной странице
* 8 - автоматическая кампания
* 9 - аукцион
*/
// Массив ID РК с ошибками
const advertIdsExclude = [];
const { dateFrom, settings: splitDatesBy } = WB.getSettingsMain({ func: arguments.callee.name });
const { newRunInfo, advListJson } =
WB.advStatFull(WBADV, {
dateFrom,
advertIdsExclude, // массив ID РК с ошибками
request: {
splitDatesBy
},
// response: {
// booster: false, // статистика по ср. позиции товара на стр. поисковой выдачи и каталога (для автоматических кампаний)
// },
service,
formulas: [
`={"Артикул продавца";ArrayFormula(IF(INDIRECT("E2:E")="";;IFNA(VLOOKUP(INDIRECT("E2:E");SORT('📝 Товары'!C:K;1;TRUE);2;0);"!!! Удалённый товар")))}`,
`={"Предмет";ArrayFormula(IF(INDIRECT("E2:E")="";;IFNA(VLOOKUP(INDIRECT("E2:E");SORT('📝 Товары'!C:K;1;TRUE);8;0);"!!! Удалённый товар")))}`,
`={"Бренд";ArrayFormula(IF(INDIRECT("E2:E")="";;IFNA(VLOOKUP(INDIRECT("E2:E");SORT('📝 Товары'!C:K;1;TRUE);9;0);"!!! Удалённый товар")))}`,
], // массив формул
debug,
}) || {};
if (newRunInfo) {
return WB.advStatFullRun(WBADV, {
service,
newRunInfo, // тело запроса
advListJson, // данные по РК
logRequest: debug, // режим отладки
});
}
}
function advStatFullRun() {
WB.advStatFullRun(WBADV, {
service,
// booster: true, // статистика по ср. позиции товара на стр. поисковой выдачи и каталога (для автоматических кампаний)
logRequest: debug, // режим отладки
});
}
function advStatFullErrorsCheck() {
// Проверка ошибок advStat
const buOne = true;
const errors =
[
{ id: 9380912, interval: { begin: "2024-01-01", end: "2024-01-10" } },
{ id: 9380912, interval: { begin: "2024-01-11", end: "2024-01-21" } },
];
if (buOne)
for (const request of errors) {
const check = WBADV.statFull([request]);
WB.saveAsJSON("advStatFullErrorsCheck", check);
console.log(JSON.stringify(check, null, 2));
}
else {
const check = WBADV.statFull(errors);
WB.saveAsJSON("advStatFullErrorsCheck", check);
console.log(JSON.stringify(check, null, 2));
}
}
function advStatAutoWords() {
// Статистика автоматической РК по кластерам фраз
WB.advStatAutoWords(WBADV, {});
}
function advStatKeyWords() {
// Статистика по ключевым фразам для Автоматических РК и Аукциона
const { dateFrom, dateTo } = WB.getSettingsMain({
func: arguments.callee.name,
});
WB.advStatKeyWords(WBADV, { dateFrom, dateTo });
}
function advStatSerchWords() {
// Статистика поисковой РК по ключевым фразам
WB.advStatSerchWords(WBADV, {});
}
function advBudget() {
// Бюджет РК (<300)
const { dateFrom } = WB.getSettingsMain({
func: arguments.callee.name,
str: false,
});
WB.advBudget(WBADV, {
dateFrom,
dateTo: WB.addDays(1, false, true),
});
}
function advBudgetLongRun() {
// Бюджет РК (<=300)
const start = Date.now();
const { dateFrom } = WB.getSettingsMain({
func: arguments.callee.name,
str: false,
});
const advertsList = WB.advListProperties(
WBADV,
{
dateFrom,
dateTo: WB.addDays(1, false, true),
},
true
);
const chunks = WB.chunkArrayForRound(advertsList, 300);
LR.executeLongRun({
mainFuncName: "advBudgetRun",
loopCount: chunks.length,
params: {
apiKey: WBADV.apiKey,
chunks,
logRequest: debug, // режим отладки
start,
},
});
}
function advBudgetRun(index, params) {
// Запуск Бюджет РК (>300)
WB.advBudgetRun(index, params);
}
function advBudgetTopUp() {
// Обновление баланса активных компаний
const { settings } = WB.getSettingsMain({ func: arguments.callee.name });
const [minBalance, topUpBalance] = /\//.test(settings)
? settings.split("/")
: [settings];
WB.advBudgetTopUp(WBADV, {
statusFilter: 9,
minBalance, // минимальный баланс
topUpBalance, // пополнить баланс на
});
}
function advUpdHistory() {
// История затрат по РК
const { dateFrom } = WB.getSettingsMain({ func: arguments.callee.name });
WB.advUpdHistory(WBADV, {
startDate: dateFrom || WB.subtractDays(93, true), // начальная дата
});
}
// ####################################################################################################################################
// API АНАЛИТИКА
// ####################################################################################################################################
function analyticsNmDetail() {
// Получение статистики КТ за выбранный период, по nmID/предметам/брендам/тегам
const {
dateFrom,
dateTo,
settings: accumulate,
} = WB.getSettingsMain({ func: arguments.callee.name });
WB.analyticsNmDetail(WBA, {
dateFrom,
dateTo,
nmIDs: WB.nomenclatureUniqueNmIds({
// contentApi: WBC,
pricesDiscountsApi: WBPD
}),
accumulate,
formulas: [
`={"Название товара";ArrayFormula(IF(INDIRECT("A2:A")="";;IFNA(VLOOKUP(INDIRECT("A2:A");'📝 Товары'!C:K;7;0);"!!! Удалённый товар")))}`,
`={"Предмет";ArrayFormula(IF(INDIRECT("A2:A")="";;IFNA(VLOOKUP(INDIRECT("A2:A");'📝 Товары'!C:J;8;0);"!!! Удалённый товар")))}`,
`={"Бренд";ArrayFormula(IF(INDIRECT("A2:A")="";;IFNA(VLOOKUP(INDIRECT("A2:A");'📝 Товары'!C:K;9;0);"!!! Удалённый товар")))}`,
],
debug,
});
}
function analyticsExciseReport() {
// Отчёт по товарам с обязательной маркировкой (ОМ)
const { dateFrom, dateTo } = WB.getSettingsMain({
func: arguments.callee.name,
str: false,
});
WB.analyticsExciseReport(WBA, {
dateFrom,
dateTo,
});
}
function analyticsAcceptanceReport() {
// Платная приёмка
const { dateFrom, dateTo } = WB.getSettingsMain({
func: arguments.callee.name,
str: false,
});
WB.analyticsAcceptanceReport(WBA, {
dateFrom,
dateTo,
requestsPerMinute: 20,
});
}
function analyticsPaidStorageReport() {
// Отчёт о платном хранении (за 8 дней)
const {
dateFrom,
dateTo,
settings: accumulate,
} = WB.getSettingsMain({ func: arguments.callee.name });
WB.analyticsPaidStorageReport(WBA, {
dateFrom,
dateTo,
requestsPerMinute: 1.5,
accumulate, // on ChekBox для накопления
debug, // режим отладки
});
}
function analyticsAntifraudReport() {
// Отчёт самовыкупы
const { dateFrom: date } = WB.getSettingsMain({
func: arguments.callee.name,
str: false,
});
WB.analyticsAntifraudReport(WBA, {
date,
});
}
function analyticsIncorrectAttachments() {
// Подмена товара
const { dateFrom, dateTo } = WB.getSettingsMain({
func: arguments.callee.name,
str: false,
});
WB.analyticsIncorrectAttachments(WBA, {
dateFrom,
dateTo,
requestsPerMinute: 20,
});
}
function analyticsStorageCoefficient() {
// Отчёт Коэффициент логистики и хранения
const { dateFrom: date } = WB.getSettingsMain({
func: arguments.callee.name,
str: false,
});
WB.analyticsStorageCoefficient(WBA, {
date,
});
}
function analyticsGoodsLabeling() {
// Маркировка товара
const { dateFrom, dateTo } = WB.getSettingsMain({
func: arguments.callee.name,
str: false,
});
WB.analyticsGoodsLabeling(WBA, {
dateFrom,
dateTo,
requestsPerMinute: 10,
});
}
function analyticsCharacteristicsChange() {
// Смена характеристик
const { dateFrom, dateTo } = WB.getSettingsMain({
func: arguments.callee.name,
str: false,
});
WB.analyticsCharacteristicsChange(WBA, {
dateFrom,
dateTo,
requestsPerMinute: 10,
});
}
function analyticsRegionSale() {
// Продажи по регионам
const { dateFrom, dateTo } = WB.getSettingsMain({
func: arguments.callee.name,
str: false,
});
WB.analyticsRegionSale(WBA, {
dateFrom,
dateTo,
requestsPerMinute: 6,
});
}
function analyticsGoodsReturn() {
// Отчет по возвратам
const { dateFrom, dateTo } = WB.getSettingsMain({
func: arguments.callee.name,
str: false,
});
WB.analyticsGoodsReturn(WBA, {
dateFrom,
dateTo,
});
}
function analyticsRemainsReport() {
// Отчёт по остаткам на складах
WB.analyticsRemainsReport(WBA, {
// groupByNm: true,
// query: "nmId"
debug,
});
}
function analyticsTurnoverDynamics() {
// Динамика оборачиваемости — ежедневная динамика
const { dateFrom, dateTo } = WB.getSettingsMain({
func: arguments.callee.name,
str: false,
});
WB.analyticsTurnoverDynamics(WBA, {
dateFrom,
dateTo,
});
}
// ####################################################################################################################################
// ДЖЕМ API АНАЛИТИКА
// ####################################################################################################################################
function jamNmDetailHistory() {
// Воронка продаж (Джем)
const {
dateFrom: startDate,
dateTo: endDate,
settings: isJam,
} = WB.getSettingsMain({ func: arguments.callee.name });
WB.jamNmDetailHistory(WBA, {
startDate,
endDate,
isJam,
// nmIDs: WB.nomenclatureUniqueNmIds({
// // contentApi: WBC,
// pricesDiscountsApi: WBPD
// }), // если закоментировать получим по всем номенклатурам
formulas: [
`={"Артикул продавца";ArrayFormula(IF(INDIRECT("A2:A")="";;IFNA(VLOOKUP(INDIRECT("A2:A");SORT('📝 Товары'!C:K;1;TRUE);2;0);"!!! Удалённый товар")))}`,
`={"Название товара";ArrayFormula(IF(INDIRECT("A2:A")="";;IFNA(VLOOKUP(INDIRECT("A2:A");'📝 Товары'!C:K;7;0);"!!! Удалённый товар")))}`,
`={"Предмет";ArrayFormula(IF(INDIRECT("A2:A")="";;IFNA(VLOOKUP(INDIRECT("A2:A");'📝 Товары'!C:J;8;0);"!!! Удалённый товар")))}`,
`={"Бренд";ArrayFormula(IF(INDIRECT("A2:A")="";;IFNA(VLOOKUP(INDIRECT("A2:A");'📝 Товары'!C:K;9;0);"!!! Удалённый товар")))}`,
],
debug, // режим отладки
});
}
function jamSerchReportMainPage() {
// ПЗ Основная страница
const options = WB.getSettingsSerchReport({ func: arguments.callee.name });
WB.jamSerchReportMainPage(WBA, options);
}
function jamSerchReportTableGroups() {
// ПЗ Пагинация по группам
const options = WB.getSettingsSerchReport({ func: arguments.callee.name });
WB.jamSerchReportTableGroups(WBA, options);
}
function jamSerchReportTableDetails() {
// ПЗ Пагинация по товарам в группе
const options = WB.getSettingsSerchReport({ func: arguments.callee.name });
WB.jamSerchReportTableDetails(WBA, options);
}
function jamSerchReportProductSerchTexts() {
// ПЗ Поисковые запросы по товару
const options = WB.getSettingsSerchReport({ func: arguments.callee.name });
WB.jamSerchReportProductSerchTexts(WBA, options);
}
function jamSerchReportProductOrders() {
// ПЗ Заказы и позиции по поисковым запросам товара
const options = WB.getSettingsSerchReport({ func: arguments.callee.name });
WB.jamSerchReportProductOrders(WBA, options);
}
// ####################################################################################################################################
// API ЦЕНЫ
// ####################################################################################################################################
function prices() {
// Цены товаров
WB.prices(WBPD, {
debug, // режим отладки
});
}
function pricesQuarantine() {
// Цены товаров в карантине
WB.pricesQuarantine(WBPD, {
debug, // режим отладки
});
}
function spp() {
// Цены с СПП
const { settings: accumulate } = WB.getSettingsMain({
func: arguments.callee.name,
});
WB.spp(WBPD, {
accumulate, // on ChekBox для накопления
// dateFormat: "dd.MM.yyyy H:mm", // формат даты обновления
// inStock: false, // только товары в наличии, true
debug, // режим отладки
});
}
// ####################################################################################################################################
// API КАЛЕНДАРЬ АКЦИЙ
// ####################################################################################################################################
function calendarPromoList() {
// Список акций
const { settings: allPromo } = WB.getSettingsMain({
func: arguments.callee.name,
go: true,
});
WB.calendarPromoList(WBCP, {
allPromo,
debug, // режим отладки
});
}
function calendarPromoDetails() {
// Детальная информация по акциям
const { settings: promotionIDs } = WB.getSettingsMain({
func: arguments.callee.name,
go: true,
});
WB.calendarPromoDetails(WBCP, {
promotionIDs,
debug, // режим отладки
});
}
function calendarPromoNomenclatures() {
// Список товаров для участия в акции
const { settings: promotionIDs } = WB.getSettingsMain({
func: arguments.callee.name,
go: true,
});
WB.calendarPromoNomenclatures(WBCP, {
promotionIDs,
regularOnly: false,
debug, // режим отладки
});
}
// ####################################################################################################################################
// API КОНТЕНТ
// ####################################################################################################################################
function nomenclature() {
// Товары
WB.nomenclature(WBC, {
debug, // режим отладки
});
}
function cardsErrors() {
// НМ с ошибками
WB.cardsErrors(WBC, {});
}
// ####################################################################################################################################
// API С САЙТА
// ####################################################################################################################################
function stocksByWh() {
// Остатки по складам
WB.stocksByWarehouses({
pricesDiscountsApi: WBPD, // использовать nmIds из апи Цены и скидки
whNew: true,
debug, // режим отладки
});
}
function stocksByWhAcc() {
// Остатки по дням
WB.stocksByWarehouses({
pricesDiscountsApi: WBPD, // использовать nmIds из апи Цены и скидки
accumulate: true,
debug, // режим отладки
});
}
function stocksByWhCompetitors() {
// Остатки по складам конкуренты
WB.stocksByWarehouses({
competitors: true, // конкуренты (ввести nmId на отдельный лист)
debug, // режим отладки
});
}
// ####################################################################################################################################
// API ПОСТАВКИ
// ####################################################################################################################################
function suppliesWarehouses() {
// Список складов
WB.suppliesWarehouses(WBSP);
}
function suppliesAcceptanceCoefficients() {
// Коэффициенты приёмки на ближайшие 14 дней
WB.suppliesAcceptanceCoefficients(WBSP);
}
// ####################################################################################################################################
// API ТАРИФЫ
// ####################################################################################################################################
function tariffs() {
// Тарифы все
WB.tariffs(WBT);
}
function tariffsCommissions() {
// Комиссия по категориям товаро
WB.tariffsCommissions(WBT);
}
Last updated