Актуальный код

Последняя версия кода

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}
 * Актуально для версии 414
 */

const WB = Wildberries;

const context = {
  service: PropertiesService,
  logRequest: false,
  debug: false,
};

WB.context = Object.assign(WB.context, {
  ...context,
  storage: WB.setStorage({ service: context.service }),
});

const { WBC, WBM, WBA, WBS, WBADV, WBFQ, WBPD, WBT, WBSP, WBCP, WBF } = WB.apiClasses(WB.context) || {};

function onOpen() {
  WB.checkApiKey();
  WB.CONFIG.menu.full();
}

function wildberriesSetMultipleAccess() {
  WB.wildberriesSetMultipleAccess();
}

function wildberriesJwtTokenInfo() {
  WB.wildberriesJwtTokenInfo();
}

// ####################################################################################################################################
// API ФИНАНСЫ
// ####################################################################################################################################

function financeBalance() {
  // Получить баланс продавца
  WB.financeBalance(WBF, {
    debug: true,
  });
}

// ####################################################################################################################################
// API СТАТИСТИКА
// ####################################################################################################################################

// Начальная дата для выгрузки
const dateFrom2004 = Utilities.formatDate(
  new Date(2004, 0, 1, 0, 0, 0),
  "Europe/Moscow",
  "yyyy-MM-dd"
);
// Начальная дата для выгрузки
const dateFrom2024 = Utilities.formatDate(
  new Date(2024, 0, 1, 0, 0, 0),
  "Europe/Moscow",
  "yyyy-MM-dd"
);

function statIncomes() {
  // Поставки
  const { dateFrom } = WB.settingsMain({ func: arguments.callee.name });
  WB.statIncomes(WBS, {
    dateFrom: dateFrom || dateFrom2024,
  });
}

function statStocks() {
  // Склад
  const { dateFrom, settings: accumulate } = WB.settingsMain({
    func: arguments.callee.name,
  });
  WB.statStocks(WBS, {
    dateFrom: dateFrom || dateFrom2004,
    accumulate, // on ChekBox для накопления
    filterKeysAboveZero: [
      // "quantity",
      // "inWayToClient",
      // "inWayFromClient",
      "quantityFull",
    ], // фильтр по количеству > 0
  });
}

function statOrders() {
  // Заказы
  const { dateFrom, settings: accumulate } = WB.settingsMain({
    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);"!!! Удалённый товар")))}`,
    ], // массив формул
  });
}

function statSales() {
  // Продажи
  const { dateFrom, settings: accumulate } = WB.settingsMain({
    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);"!!! Удалённый товар")))}`,
    ], // массив формул
  });
}

function statReportDetailByPeriod() {
  // Отчет о продажах по реализации новый
  const {
    dateFrom,
    dateTo,
    settings: accumulate,
  } = WB.settingsMain({ func: arguments.callee.name });

  WB.statReportDetailByPeriod(WBS, {
    dateFrom,
    dateTo,
    accumulate, // on ChekBox для накопления
    limit: 25000, // строк в запросе, раскомментировать, если не хватает памяти 50мб
    delay: 30000, // задержка межу запросами
    // returnSignConversion: false, // обратные знаки для возвратов
    // logisticSignConversion: false, // обратные знаки для логистики стронто
  });
}

// ####################################################################################################################################
// API МАРКЕТПЛЕЙС
// ####################################################################################################################################

function stocksFbs() {
  // Склад fbs
  WB.stocksFbs({
    marketplaceApi: WBM,
    contentApi: WBC,
    pricesDiscountsApi: WBPD,
    stocksPrices: true,
  });
}

function ordersFbsNew() {
  // Новые заказы fbs
  WB.ordersFbsNew(WBM, {
    oneBar: true, // первый баркод, если в массиве несколько
  });
}

function ordersFbs() {
  // Заказы fbs
  const { dateFrom, dateTo } = WB.settingsMain({
    func: arguments.callee.name,
  });
  WB.ordersFbs(WBM, {
    dateFrom: dateFrom || WB.subtractDays(93),
    dateTo: dateTo || WB.addDays(1),
    oneBar: true, // первый баркод, если в массиве несколько
    cut: true, // без адреса доставки
  });
}

function ordersFbsSetStickerId() {
  // Установить ID стикера в Заказы fbs
  WB.ordersFbsSetStickerId(WBM);
}

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.settingsMain({
    func: arguments.callee.name,
    custom: true,
  });

  WB.ratingsFedbacks({
    pricesDiscountsApi: WBPD, // использовать nmIds из апи Цены и скидки
    // contentApi: WBC, // использовать nmIds из апи Контент
    accumulate, // on ChekBox для накопления
  });
}

function feedbacksList() {
  // Список отзывов (отвеченные)
  const {
    dateFrom,
    dateTo,
    settings: stat,
  } = WB.settingsMain({ func: arguments.callee.name, str: false });
  WB.feedbacksList(WBFQ, {
    dateFrom,
    dateTo,
    stat, // on ChekBox получить дополнительные поля для анализа
  });
}

function feedbacksUnanswered() {
  // Список отзывов (неотвеченные)
  const { dateFrom, dateTo } = WB.settingsMain({
    func: arguments.callee.name,
    str: false,
  });
  WB.feedbacksUnanswered(WBFQ, {
    dateFrom,
    dateTo,
  });
}

function feedbacksArcived() {
  // Список архивных отзывов
  WB.feedbacksArcived(WBFQ);
}

function questionsList() {
  // Список вопросов (отвеченные)
  const {
    dateFrom,
    dateTo,
    settings: additionalInfo,
  } = WB.settingsMain({ func: arguments.callee.name, str: false });
  WB.questionsList(WBFQ, {
    dateFrom,
    dateTo,
    additionalInfo, // on ChekBox получить дополнительные поля для анализа
  });
}

function questionsUnanswered() {
  // Список вопросов (неотвеченные)
  const { dateFrom, dateTo } = WB.settingsMain({
    func: arguments.callee.name,
    str: false,
  });
  WB.questionsUnanswered(WBFQ, {
    dateFrom,
    dateTo,
  });
}

// ####################################################################################################################################
// API ПРОДВИЖЕНИЕ (РЕКЛАМА)
// ####################################################################################################################################

function advBalance() {
  // Баланс РК
  WB.advBalance(WBADV);
}

function advList() {
  // Список РК
  const { dateFrom } = WB.settingsMain({ func: arguments.callee.name });
  WB.advList(WBADV, {
    dateFrom,
  });
}

function advListWithNmIds() {
  // Список РК c артикулами WB
  const { dateFrom } = WB.settingsMain({ func: arguments.callee.name });
  WB.advListWithNmIds(WBADV, {
    dateFrom,
  });
}

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.settingsMain({
    func: arguments.callee.name,
  });

  const { runInfo, advListJson } =
    WB.advStatFull(WBADV, {
      dateFrom,
      // newPayload: false,
      advertIdsExclude, // массив ID РК с ошибками
      request: {
        splitDatesBy,
      },
      // response: {
      //     booster: false, // статистика по ср. позиции товара на стр. поисковой выдачи и каталога (для автоматических кампаний)
      // },
      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);"!!! Удалённый товар")))}`,
      ], // массив формул
    }) || {};

  if (runInfo) {
    return WB.advStatFullRun(WBADV, {
      runInfo, // тело запроса
      advListJson, // данные по РК
    });
  }
}

function advStatFullRun() {
  WB.advStatFullRun(WBADV, {
    // booster: true, // статистика по ср. позиции товара на стр. поисковой выдачи и каталога (для автоматических кампаний)
  });
}

function advStatFullErrorsCheck() {
  // Проверка ошибок advStat
  const buOne = false;
  const errors = [
    {
      "id": 24597279,
      "interval": {
        "begin": "2025-05-15",
        "end": "2025-05-28"
      }
    },
  ];

  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.settingsMain({
    func: arguments.callee.name,
  });
  WB.advStatKeyWords(WBADV, { dateFrom, dateTo });
}

function advStatSerchWords() {
  // Статистика поисковой РК по ключевым фразам
  WB.advStatSerchWords(WBADV, {});
}

function advBudget() {
  // Бюджет РК
  const { dateFrom } = WB.settingsMain({
    func: arguments.callee.name,
    str: false,
  });

  const { runInfo } = WB.advBudget(WBADV, {
    dateFrom,
    dateTo: WB.addDays(1, false, true),
  });

  if (runInfo) {
    return WB.advBudgetRun(WBADV, {
      runInfo, // тело запроса
    });
  }
}

function advBudgetRun() {
  WB.advBudgetRun(WBADV);
}

function advBudgetTopUp() {
  // Обновление баланса активных компаний
  const { settings } = WB.settingsMain({
    func: arguments.callee.name,
    custom: true,
  });

  const [minBalance, topUpBalance] = /\//.test(settings) ? settings[0][2].split("/") : [];

  WB.advBudgetTopUp(WBADV, {
    statusFilter: 9,
    minBalance, // минимальный баланс
    topUpBalance, // пополнить баланс на
  });
}

function advUpdHistory() {
  // История затрат по РК
  const { dateFrom: startDate } = WB.settingsMain({
    func: arguments.callee.name,
  });

  WB.advUpdHistory(WBADV, {
    startDate, // начальная дата
  });
}

// ####################################################################################################################################
// API АНАЛИТИКА
// ####################################################################################################################################

function analyticsNmDetail() {
  // Получение статистики КТ за выбранный период, по nmID/предметам/брендам/тегам
  const {
    dateFrom,
    dateTo,
    settings: accumulate,
  } = WB.settingsMain({ 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);"!!! Удалённый товар")))}`,
    ],
  });
}

function analyticsExcise() {
  // Отчёт по товарам с обязательной маркировкой (ОМ)
  const { dateFrom, dateTo } = WB.settingsMain({
    func: arguments.callee.name,
    str: false,
  });
  WB.analyticsExcise(WBA, {
    dateFrom,
    dateTo,
  });
}

function analyticsAcceptance() {
  // Платная приёмка
  const {
    dateFrom,
    dateTo,
    settings: accumulate,
  } = WB.settingsMain({ func: arguments.callee.name, str: false });
  WB.analyticsAcceptance(WBA, {
    dateFrom,
    dateTo,
    requestsPerMinute: 1.5,
    accumulate, // on ChekBox для накопления
  });
}

function analyticsPaidStorage() {
  // Отчёт о платном хранении (за 8 дней)
  const {
    dateFrom,
    dateTo,
    settings: accumulate,
  } = WB.settingsMain({ func: arguments.callee.name });
  WB.analyticsPaidStorage(WBA, {
    dateFrom,
    dateTo,
    requestsPerMinute: 1.5,
    accumulate, // on ChekBox для накопления
  });
}

function analyticsAntifraudDetails() {
  // Отчёт самовыкупы
  const { dateFrom: date } = WB.settingsMain({
    func: arguments.callee.name,
    str: false,
  });
  WB.analyticsAntifraudDetails(WBA, {
    date,
  });
}

function analyticsIncorrectAttachments() {
  // Подмена товара
  const { dateFrom, dateTo } = WB.settingsMain({
    func: arguments.callee.name,
    str: false,
  });
  WB.analyticsIncorrectAttachments(WBA, {
    dateFrom,
    dateTo,
    requestsPerMinute: 20,
  });
}

function analyticsGoodsLabeling() {
  // Маркировка товара
  const { dateFrom, dateTo } = WB.settingsMain({
    func: arguments.callee.name,
    str: false,
  });
  WB.analyticsGoodsLabeling(WBA, {
    dateFrom,
    dateTo,
    requestsPerMinute: 10,
  });
}

function analyticsCharacteristicsChange() {
  // Смена характеристик
  const { dateFrom, dateTo } = WB.settingsMain({
    func: arguments.callee.name,
    str: false,
  });
  WB.analyticsCharacteristicsChange(WBA, {
    dateFrom,
    dateTo,
    requestsPerMinute: 10,
  });
}

function analyticsRegionSale() {
  // Продажи по регионам
  const { dateFrom, dateTo } = WB.settingsMain({
    func: arguments.callee.name,
    str: false,
  });
  WB.analyticsRegionSale(WBA, {
    dateFrom,
    dateTo,
    requestsPerMinute: 6,
  });
}

function analyticsGoodsReturn() {
  // Отчет по возвратам
  const { dateFrom, dateTo } = WB.settingsMain({
    func: arguments.callee.name,
    str: false,
  });
  WB.analyticsGoodsReturn(WBA, {
    dateFrom,
    dateTo,
  });
}

function analyticsRemains() {
  // Отчёт по остаткам на складах
  WB.analyticsRemains(WBA, {
    // groupByNm: true,
    // query: "nmId"
  });
}

function analyticsTurnoverDynamics() {
  // Динамика оборачиваемости — ежедневная динамика
  const { dateFrom, dateTo } = WB.settingsMain({
    func: arguments.callee.name,
    str: false,
  });
  WB.analyticsTurnoverDynamics(WBA, {
    dateFrom,
    dateTo,
  });
}

function analyticsStocsHystoryProducts() {
  // История по остаткам, данные по товарам
  const { dateFrom: start, dateTo: end } = WB.settingsMain({
    func: arguments.callee.name,
  });
  WB.analyticsStocsHystoryProducts(WBA, {
    start,
    end,
  });
}

function analyticsStocsHystoryOffices() {
  // История по остаткам, данные по по складам
  const { dateFrom: start, dateTo: end } = WB.settingsMain({
    func: arguments.callee.name,
  });
  WB.analyticsStocsHystoryOffices(WBA, {
    start,
    end,
  });
}

// ####################################################################################################################################
// ДЖЕМ API АНАЛИТИКА
// ####################################################################################################################################

function jamNmDetailHistory() {
  // Воронка продаж (Джем)
  const { dateFrom: startDate, dateTo: endDate } = WB.settingsMain({
    func: arguments.callee.name,
  });

  WB.jamNmDetailHistory(WBA, {
    startDate,
    endDate,
    // 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);"!!! Удалённый товар")))}`,
    ],
  });
}

function jamSerchReportMainPage() {
  // ПЗ Основная страница
  const options = WB.settingsSerchReport({ func: arguments.callee.name });
  console.log({ options });
  WB.jamSerchReportMainPage(WBA, options);
}

function jamSerchReportTableGroups() {
  // ПЗ Пагинация по группам
  const options = WB.settingsSerchReport({ func: arguments.callee.name });
  WB.jamSerchReportTableGroups(WBA, options);
}

function jamSerchReportTableDetails() {
  // ПЗ Пагинация по товарам в группе
  const options = WB.settingsSerchReport({ func: arguments.callee.name });
  WB.jamSerchReportTableDetails(WBA, options);
}

function jamSerchReportProductSerchTexts() {
  // ПЗ Поисковые запросы по товару
  const options = WB.settingsSerchReport({ func: arguments.callee.name });
  WB.jamSerchReportProductSerchTexts(WBA, options);
}

function jamSerchReportProductOrders() {
  // ПЗ Заказы и позиции по поисковым запросам товара
  const options = WB.settingsSerchReport({ func: arguments.callee.name });
  WB.jamSerchReportProductOrders(WBA, options);
}

// ####################################################################################################################################
// API ЦЕНЫ
// ####################################################################################################################################

function prices() {
  // Цены товаров
  WB.prices(WBPD);
}

function pricesQuarantine() {
  // Цены товаров в карантине
  WB.pricesQuarantine(WBPD);
}

function spp() {
  // Цены с СПП
  const { settings: accumulate } = WB.settingsMain({
    func: arguments.callee.name,
    custom: true,
  });
  WB.spp(WBPD, {
    accumulate, // on ChekBox для накопления
    // dateFormat: "dd.MM.yyyy H:mm", // формат даты обновления
    // inStock: false, // только товары в наличии, true
  });
}

// ####################################################################################################################################
// API КАЛЕНДАРЬ АКЦИЙ
// ####################################################################################################################################

function calendarPromoList() {
  // Список акций
  const { settings: allPromo } = WB.settingsMain({
    func: arguments.callee.name,
    custom: true,
  });
  WB.calendarPromoList(WBCP, {
    allPromo,
  });
}

function calendarPromoDetails() {
  // Детальная информация по акциям
  const { settings: promotionIDs } = WB.settingsMain({
    func: arguments.callee.name,
    custom: true,
  });
  WB.calendarPromoDetails(WBCP, {
    promotionIDs,
  });
}

function calendarPromoNomenclatures() {
  // Список товаров для участия в акции
  const { settings: promotionIDs } = WB.settingsMain({
    func: arguments.callee.name,
    custom: true,
  });
  WB.calendarPromoNomenclatures(WBCP, {
    promotionIDs,
    regularOnly: false,
  });
}

// ####################################################################################################################################
// API КОНТЕНТ
// ####################################################################################################################################

function nomenclature() {
  // Товары
  WB.nomenclature(WBC);
}

function cardsErrors() {
  // НМ с ошибками
  WB.cardsErrors(WBC, {});
}

// ####################################################################################################################################
// API С САЙТА
// ####################################################################################################################################

function stocksByWh() {
  // Остатки по складам
  WB.stocksByWarehouses({
    pricesDiscountsApi: WBPD, // использовать nmIds из апи Цены и скидки
    whNew: true,
  });
}

function stocksByWhAcc() {
  // Остатки по дням
  WB.stocksByWarehouses({
    pricesDiscountsApi: WBPD, // использовать nmIds из апи Цены и скидки
    accumulate: true,
  });
}

function stocksByWhCompetitors() {
  // Остатки по складам конкуренты
  WB.stocksByWarehouses({
    competitors: true, // конкуренты (ввести nmId на отдельный лист)
  });
}

// ####################################################################################################################################
// 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