const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, AlignmentType, HeadingLevel, BorderStyle, WidthType, ShadingType, LevelFormat } = require('docx'); const fs = require('fs'); const B = { style: BorderStyle.SINGLE, size: 1, color: "DDDDDD" }; const borders = { top: B, bottom: B, left: B, right: B }; const BLUE = "1A3A6B"; const RED = "C0392B"; const GOLD = "E67E22"; const GREEN = "1E8449"; const LGRAY = "F4F6F8"; const WHITE = "FFFFFF"; const LBLUE = "EAF2FF"; const LRED = "FEF9F0"; function cell(text, w, fill = WHITE, bold = false, color = "222222", size = 20, italic = false) { return new TableCell({ borders, width: { size: w, type: WidthType.DXA }, shading: { fill, type: ShadingType.CLEAR }, margins: { top: 90, bottom: 90, left: 140, right: 140 }, children: [new Paragraph({ children: [new TextRun({ text, bold, color, size, italics: italic, font: "Arial" })] })] }); } function hCell(text, w) { return cell(text, w, BLUE, true, WHITE, 22); } function row(...cells) { return new TableRow({ children: cells }); } function h1(text) { return new Paragraph({ spacing: { before: 300, after: 140 }, children: [new TextRun({ text, bold: true, size: 34, color: BLUE, font: "Arial" })] }); } function h2(text) { return new Paragraph({ spacing: { before: 240, after: 100 }, children: [new TextRun({ text, bold: true, size: 26, color: RED, font: "Arial" })] }); } function h3(text) { return new Paragraph({ spacing: { before: 180, after: 80 }, children: [new TextRun({ text, bold: true, size: 23, color: GOLD, font: "Arial" })] }); } function p(text, opts = {}) { return new Paragraph({ spacing: { after: 100 }, children: [new TextRun({ text, size: 20, font: "Arial", ...opts })] }); } function note(text) { return new Paragraph({ spacing: { after: 120 }, shading: { fill: "FEF3CD", type: ShadingType.CLEAR }, border: { left: { style: BorderStyle.SINGLE, size: 12, color: GOLD, space: 6 } }, indent: { left: 200 }, children: [new TextRun({ text: "⚡ " + text, size: 20, font: "Arial", italics: true, color: "7D5A00" })] }); } function tip(text) { return new Paragraph({ spacing: { after: 120 }, border: { left: { style: BorderStyle.SINGLE, size: 12, color: GREEN, space: 6 } }, indent: { left: 200 }, children: [new TextRun({ text: "✅ " + text, size: 20, font: "Arial", color: "1A5C2A" })] }); } function warn(text) { return new Paragraph({ spacing: { after: 120 }, border: { left: { style: BorderStyle.SINGLE, size: 12, color: RED, space: 6 } }, indent: { left: 200 }, children: [new TextRun({ text: "⛔ " + text, size: 20, font: "Arial", color: "8B1A1A" })] }); } function bul(text, bold_prefix = null) { const children = bold_prefix ? [new TextRun({ text: bold_prefix + " ", bold: true, size: 20, font: "Arial" }), new TextRun({ text, size: 20, font: "Arial" })] : [new TextRun({ text, size: 20, font: "Arial" })]; return new Paragraph({ numbering: { reference: "bullets", level: 0 }, spacing: { after: 80 }, children }); } function divider() { return new Paragraph({ spacing: { before: 200, after: 200 }, border: { bottom: { style: BorderStyle.SINGLE, size: 6, color: "DDDDDD", space: 1 } }, children: [new TextRun("")] }); } function gap(n = 120) { return new Paragraph({ spacing: { after: n }, children: [new TextRun("")] }); } // ─── ТАБЛИЦЫ ──────────────────────────────────────────────── function adBlock(title, rows) { return [ h3(title), new Table({ width: { size: 9200, type: WidthType.DXA }, columnWidths: [2600, 5000, 1600], rows: [ row(hCell("Элемент", 2600), hCell("Текст", 5000), hCell("Симв.", 1600)), ...rows.map((r, i) => row( cell(r[0], 2600, i % 2 === 0 ? LBLUE : WHITE, true, BLUE, 20), cell(r[1], 5000, i % 2 === 0 ? LBLUE : WHITE), cell(r[2], 1600, i % 2 === 0 ? LRED : "FFFDF5", false, r[2].includes("✓") ? GREEN : RED, 19) )) ] }), gap(160) ]; } function kwBlock(groupTitle, rows) { return [ h3(groupTitle), new Table({ width: { size: 9200, type: WidthType.DXA }, columnWidths: [5400, 1900, 1900], rows: [ row(hCell("Ключевое слово", 5400), hCell("Тип", 1900), hCell("Частота", 1900)), ...rows.map((r, i) => row( cell(r[0], 5400, i % 2 === 0 ? LBLUE : WHITE, false, "222222", 20), cell(r[1], 1900, i % 2 === 0 ? LBLUE : WHITE, false, BLUE, 19), cell(r[2], 1900, i % 2 === 0 ? LRED : "FFFDF5", r[2] === "Высокая", r[2] === "Высокая" ? GREEN : r[2] === "Средняя" ? GOLD : "888888", 19) )) ] }), gap(160) ]; } // ─── ДОКУМЕНТ ─────────────────────────────────────────────── const doc = new Document({ numbering: { config: [{ reference: "bullets", levels: [{ level: 0, format: LevelFormat.BULLET, text: "•", alignment: AlignmentType.LEFT, style: { paragraph: { indent: { left: 560, hanging: 280 } } } }] }] }, styles: { default: { document: { run: { font: "Arial", size: 20 } } } }, sections: [{ properties: { page: { size: { width: 11906, height: 16838 }, margin: { top: 1080, right: 1080, bottom: 1080, left: 1080 } } }, children: [ // ═══════════════════════════════════════ // ОБЛОЖКА // ═══════════════════════════════════════ new Paragraph({ alignment: AlignmentType.CENTER, spacing: { before: 1200, after: 360 }, children: [new TextRun({ text: "ЯНДЕКС ДИРЕКТ", bold: true, size: 60, color: RED, font: "Arial" })] }), new Paragraph({ alignment: AlignmentType.CENTER, spacing: { after: 200 }, children: [new TextRun({ text: "Стратегия и структура рекламной кампании", bold: true, size: 32, color: BLUE, font: "Arial" })] }), new Paragraph({ alignment: AlignmentType.CENTER, spacing: { after: 160 }, children: [new TextRun({ text: "Вывоз мусора — Санкт-Петербург + Ленинградская область", size: 26, color: "555555", font: "Arial" })] }), gap(60), new Table({ width: { size: 6000, type: WidthType.DXA }, columnWidths: [3000, 3000], rows: [ row( cell("Бюджет в день:", 3000, LBLUE, true, BLUE, 22), cell("1 000 — 3 000 ₽", 3000, LBLUE, true, RED, 22) ), row( cell("География:", 3000, WHITE, true, BLUE, 22), cell("СПб + вся Ленинградская область", 3000, WHITE, false, "333333", 22) ), row( cell("Тип кампании:", 3000, LBLUE, true, BLUE, 22), cell("Поиск + отдельно РСЯ", 3000, LBLUE, false, "333333", 22) ), row( cell("Стратегия ставок:", 3000, WHITE, true, BLUE, 22), cell("Ручные ставки → Оптимизация кликов", 3000, WHITE, false, "333333", 22) ), ] }), gap(300), divider(), // ═══════════════════════════════════════ // РАЗДЕЛ 1: ЛОГИКА И СТРАТЕГИЯ // ═══════════════════════════════════════ h1("1. СТРАТЕГИЯ КАМПАНИИ"), p("При бюджете 1 000–3 000 ₽/день главный принцип — концентрация. Нельзя распылять бюджет на все ключи сразу. Нужно начать с горячих коммерческих запросов и постепенно расширяться по мере накопления данных."), gap(100), h2("1.1 Фазы запуска"), new Table({ width: { size: 9200, type: WidthType.DXA }, columnWidths: [1600, 2400, 3200, 2000], rows: [ row(hCell("Фаза", 1600), hCell("Период", 2400), hCell("Что делаем", 3200), hCell("Бюджет", 2000)), row( cell("Фаза 1", 1600, LBLUE, true, BLUE), cell("Дни 1–14", 2400, LBLUE), cell("Только горячие ключи: срочность + цена. Ручные ставки. Смотрим что конвертит.", 3200, LBLUE), cell("1 000 ₽/день", 2000, LBLUE, true, RED) ), row( cell("Фаза 2", 1600, WHITE, true, BLUE), cell("Дни 15–30", 2400, WHITE), cell("Добавляем ключи по типу мусора и районам. Отключаем неэффективные. Оптимизируем объявления.", 3200, WHITE), cell("1 500–2 000 ₽/день", 2000, WHITE, true, RED) ), row( cell("Фаза 3", 1600, LBLUE, true, BLUE), cell("Месяц 2+", 2400, LBLUE), cell("Переключаем на «Оптимизацию кликов». Запускаем РСЯ отдельно. Расширяем гео по ЛО.", 3200, LBLUE), cell("2 000–3 000 ₽/день", 2000, LBLUE, true, RED) ), ] }), gap(160), note("При бюджете 1 000 ₽/день и клике ~40–60 ₽ вы получаете 16–25 кликов в сутки. Это реально при CTR 8–12% даст 1–3 заявки в день — нормальный старт."), h2("1.2 Структура аккаунта"), p("Создайте 2 отдельные кампании — не смешивайте поиск и РСЯ:"), gap(80), new Table({ width: { size: 9200, type: WidthType.DXA }, columnWidths: [2400, 3600, 3200], rows: [ row(hCell("Кампания", 2400), hCell("Содержание", 3600), hCell("Примечание", 3200)), row( cell("Кампания 1: ПОИСК", 2400, LBLUE, true, BLUE), cell("5 групп объявлений по типу запроса (см. раздел 2)", 3600, LBLUE), cell("Запускать ПЕРВОЙ — горячий трафик", 3200, LBLUE, false, GREEN) ), row( cell("Кампания 2: РСЯ", 2400, WHITE, true, BLUE), cell("Более широкие ключи, визуальные баннеры", 3600, WHITE), cell("Запустить на ФАЗЕ 3, когда отладите поиск", 3200, WHITE, false, GOLD) ), ] }), gap(200), divider(), // ═══════════════════════════════════════ // РАЗДЕЛ 2: СТРУКТУРА ГРУПП // ═══════════════════════════════════════ h1("2. СТРУКТУРА ГРУПП ОБЪЯВЛЕНИЙ"), p("5 групп, каждая — под свой тип коммерческого запроса. Своё объявление с точным вхождением ключа в заголовок."), gap(100), new Table({ width: { size: 9200, type: WidthType.DXA }, columnWidths: [400, 2600, 3000, 1800, 1400], rows: [ row(hCell("№", 400), hCell("Группа", 2600), hCell("Тип запроса", 3000), hCell("Приоритет", 1800), hCell("Фаза", 1400)), ...[ ["1", "Цена / стоимость", "вывоз мусора спб цена, стоимость", "🔥 Горячие", "Фаза 1"], ["2", "Срочно / сегодня", "срочный вывоз, вывоз сегодня, за 2 часа", "🔥 Горячие", "Фаза 1"], ["3", "Строительный мусор", "вывоз строительного мусора спб", "🔥 Горячие", "Фаза 1"], ["4", "По районам СПб", "вывоз мусора Приморский район и т.д.", "🟡 Тёплые", "Фаза 2"], ["5", "Города ЛО", "вывоз мусора Всеволожск, Гатчина и т.д.", "🟡 Тёплые", "Фаза 2"], ].map((r, i) => row( cell(r[0], 400, i % 2 === 0 ? LBLUE : WHITE, true, BLUE), cell(r[1], 2600, i % 2 === 0 ? LBLUE : WHITE, true), cell(r[2], 3000, i % 2 === 0 ? LBLUE : WHITE), cell(r[3], 1800, i % 2 === 0 ? LRED : "FFFDF5", true, r[3].startsWith("🔥") ? RED : GOLD), cell(r[4], 1400, i % 2 === 0 ? LBLUE : WHITE, false, BLUE) )) ] }), gap(200), divider(), // ═══════════════════════════════════════ // РАЗДЕЛ 3: ОБЪЯВЛЕНИЯ // ═══════════════════════════════════════ h1("3. ТЕКСТЫ ОБЪЯВЛЕНИЙ"), p("Формат: Заголовок 1 (56 симв.) + Заголовок 2 (30 симв.) + Текст объявления (81 симв.). Для каждой группы — минимум 2 варианта: система сама выберет лучший по CTR."), gap(80), note("Правило: ключевое слово должно быть в Заголовке 1. Яндекс выделяет его жирным — CTR растёт на 20–35%."), gap(120), // ГРУППА 1 h2("ГРУППА 1 — «Цена / стоимость»"), ...adBlock("Объявление 1.1 — Акцент на цену + гарантия", [ ["Заголовок 1", "Вывоз мусора от 2500 ₽ — СПб", "30 / 56 ✓"], ["Заголовок 2", "За 2 часа. Без предоплаты", "25 / 30 ✓"], ["Текст", "Своя техника. Лицензия. Платите только после вывоза. Работаем 24/7 по СПб и ЛО.", "79 / 81 ✓"], ["URL", "ваш-сайт.рф/vyvoz-musora", "—"], ]), ...adBlock("Объявление 1.2 — Прямой прайс", [ ["Заголовок 1", "Вывоз мусора СПб — цены 2025", "31 / 56 ✓"], ["Заголовок 2", "От 2500 руб. Без скрытых доплат", "30 / 30 ✓"], ["Текст", "Газель от 2500 ₽, Камаз от 5500 ₽. Грузчики. Фото отчёт. Звоните — приедем сегодня!", "81 / 81 ✓"], ["URL", "ваш-сайт.рф/vyvoz-musora", "—"], ]), // ГРУППА 2 h2("ГРУППА 2 — «Срочно / сегодня»"), ...adBlock("Объявление 2.1 — Скорость", [ ["Заголовок 1", "Срочный вывоз мусора — 2 часа", "29 / 56 ✓"], ["Заголовок 2", "Приедем сегодня. СПб и ЛО", "26 / 30 ✓"], ["Текст", "Заявки 24/7. Машина выезжает сразу. Оплата после вывоза. Без очередей и предоплаты.", "81 / 81 ✓"], ["URL", "ваш-сайт.рф/srochno", "—"], ]), ...adBlock("Объявление 2.2 — Сегодня/сейчас", [ ["Заголовок 1", "Вывоз мусора сегодня в СПб", "27 / 56 ✓"], ["Заголовок 2", "Звоните — выедем через час!", "30 / 30 ✓"], ["Текст", "Работаем без выходных и праздников. 18 машин в парке. Цена по телефону без сюрпризов.", "80 / 81 ✓"], ["URL", "ваш-сайт.рф/srochno", "—"], ]), // ГРУППА 3 h2("ГРУППА 3 — «Строительный мусор»"), ...adBlock("Объявление 3.1 — Общее", [ ["Заголовок 1", "Вывоз строительного мусора СПб", "31 / 56 ✓"], ["Заголовок 2", "От 2500 ₽. Сегодня. Лицензия", "29 / 30 ✓"], ["Текст", "Бой плитки, штукатурка, кирпич, стяжка. Камаз, еврофура. Документы об утилизации.", "79 / 81 ✓"], ["URL", "ваш-сайт.рф/stroitelnyj", "—"], ]), ...adBlock("Объявление 3.2 — Для юрлиц", [ ["Заголовок 1", "Строительный мусор — вывоз СПб", "31 / 56 ✓"], ["Заголовок 2", "Договор, акт, лицензия. 24/7", "29 / 30 ✓"], ["Текст", "Работаем с юрлицами и ИП. Договор, акт, лицензия. Фото отчёт на полигоне. Без наличных.", "81 / 81 ✓"], ["URL", "ваш-сайт.рф/stroitelnyj", "—"], ]), // ГРУППА 4 h2("ГРУППА 4 — «По районам СПб» (шаблон — создать под каждый)"), p("Создайте отдельное объявление под каждый район. Просто замените название района в заголовке — это даёт +20–35% к CTR за счёт точного вхождения."), gap(80), ...adBlock("Шаблон по районам (пример: Приморский)", [ ["Заголовок 1", "Вывоз мусора [РАЙОН] район СПб", "~50 / 56 ✓"], ["Заголовок 2", "Приедем за 2 часа. От 2500 ₽", "30 / 30 ✓"], ["Текст", "Работаем в [РАЙОН] р-не СПб. Строительный, бытовой, мебель. Грузчики. Без предоплаты.", "81 / 81 ✓"], ["URL", "ваш-сайт.рф/rayon", "—"], ]), p("Районы для создания объявлений: Приморский, Выборгский, Калининский, Московский, Красносельский, Невский, Фрунзенский, Петроградский, Кировский, Василеостровский.", { italics: true, color: "666666" }), gap(120), // ГРУППА 5 h2("ГРУППА 5 — «Города ЛО» (шаблон)"), ...adBlock("Шаблон по городам ЛО (пример: Всеволожск)", [ ["Заголовок 1", "Вывоз мусора [ГОРОД]", "~30 / 56 ✓"], ["Заголовок 2", "Приедем сегодня. Без предоплаты", "30 / 30 ✓"], ["Текст", "Вывозим мусор в [ГОРОД] и районе. Строительный, бытовой, мебель. Оплата после вывоза.", "81 / 81 ✓"], ["URL", "ваш-сайт.рф/lo", "—"], ]), p("Города ЛО: Всеволожск, Гатчина, Тосно, Кингисепп, Выборг, Мурино, Кудрово, Девяткино, Сертолово, Шушары.", { italics: true, color: "666666" }), gap(200), divider(), // ═══════════════════════════════════════ // РАЗДЕЛ 4: РАСШИРЕНИЯ // ═══════════════════════════════════════ h1("4. РАСШИРЕНИЯ ОБЪЯВЛЕНИЙ"), p("Расширения увеличивают площадь объявления и CTR на 15–40%. Заполните все — система выберет лучшую комбинацию."), gap(120), h2("4.1 Быстрые ссылки"), new Table({ width: { size: 9200, type: WidthType.DXA }, columnWidths: [2400, 4200, 2600], rows: [ row(hCell("Текст ссылки", 2400), hCell("Описание (видно на десктопе)", 4200), hCell("URL страницы", 2600)), ...[ ["Рассчитать стоимость", "Онлайн-калькулятор — цена за 30 секунд", "#calculator"], ["Прайс-лист 2025", "Газель от 2500 ₽, Камаз от 5500 ₽", "#prices"], ["Строительный мусор", "Кирпич, плитка, штукатурка, стяжка", "#stroi"], ["Зоны выезда", "Все районы СПб + ЛО до 150 км", "#zones"], ].map((r, i) => row( cell(r[0], 2400, i % 2 === 0 ? LBLUE : WHITE, true), cell(r[1], 4200, i % 2 === 0 ? LBLUE : WHITE), cell(r[2], 2600, i % 2 === 0 ? LRED : "FFFDF5", false, "0070C0") )) ] }), gap(160), h2("4.2 Уточнения (до 8 штук по 25 символов)"), new Table({ width: { size: 9200, type: WidthType.DXA }, columnWidths: [4600, 4600], rows: [ row(hCell("Текст уточнения", 4600), hCell("Символов", 4600)), ...[ ["Без предоплаты", "14 / 25 ✓"], ["Платите только после вывоза", "27 — сократить до «Оплата после вывоза» ✓"], ["Работаем 24/7", "13 / 25 ✓"], ["Официальная лицензия", "21 / 25 ✓"], ["18 машин — свой парк", "20 / 25 ✓"], ["Фото отчёт об утилизации", "24 / 25 ✓"], ["Приедем за 2 часа", "17 / 25 ✓"], ["Документы для юрлиц", "20 / 25 ✓"], ].map((r, i) => row( cell(r[0], 4600, i % 2 === 0 ? LBLUE : WHITE), cell(r[1], 4600, i % 2 === 0 ? LRED : "FFFDF5", false, r[1].includes("сократить") ? RED : GREEN) )) ] }), gap(160), h2("4.3 Телефон и визитка"), bul("Добавьте расширение «Контактная информация» — показывает номер прямо в объявлении"), bul("На мобильных появляется кнопка «Позвонить» — это самый ценный клик в нише вывоза мусора"), bul("Заполните адрес компании в визитке — повышает доверие и улучшает ранжирование"), gap(160), h2("4.4 Цена в объявлении"), bul("Добавьте расширение «Цены»: Газель — от 2 500 ₽, Камаз — от 5 500 ₽, Грузчики — от 800 ₽/час"), bul("Люди видят цену до клика — отсекаются нецелевые, CTR растёт у целевых"), gap(200), divider(), // ═══════════════════════════════════════ // РАЗДЕЛ 5: КЛЮЧЕВЫЕ СЛОВА // ═══════════════════════════════════════ h1("5. КЛЮЧЕВЫЕ СЛОВА"), p("Тип соответствия: фразовое (кавычки) для всех ключей. Это даёт точность без потери охвата. Широкое соответствие при бюджете 1–3к/день сожжёт деньги на мусорный трафик."), gap(80), warn("Не используйте широкое соответствие при таком бюджете — деньги уйдут на нецелевые показы"), tip("На старте (Фаза 1) подключите только Группы 1, 2, 3. Группы 4–5 добавьте на Фазе 2."), gap(120), ...kwBlock("ГРУППА 1 — Цена / стоимость (Фаза 1 — ЗАПУСКАТЬ ПЕРВЫМИ)", [ ["вывоз мусора спб цена", "Фразовое", "Высокая"], ["вывоз мусора санкт петербург стоимость", "Фразовое", "Высокая"], ["сколько стоит вывоз мусора спб", "Фразовое", "Высокая"], ["вывоз мусора цены спб 2025", "Фразовое", "Высокая"], ["вывоз строительного мусора спб цена", "Фразовое", "Высокая"], ["вывоз мусора газель цена спб", "Фразовое", "Средняя"], ["вывоз мусора камаз цена спб", "Фразовое", "Средняя"], ["заказать вывоз мусора спб недорого", "Фразовое", "Средняя"], ["вывоз мусора ленинградская область цена", "Фразовое", "Средняя"], ]), ...kwBlock("ГРУППА 2 — Срочно / сегодня (Фаза 1 — ЗАПУСКАТЬ ПЕРВЫМИ)", [ ["срочный вывоз мусора спб", "Фразовое", "Высокая"], ["вывоз мусора сегодня спб", "Фразовое", "Высокая"], ["вывоз мусора срочно санкт петербург", "Фразовое", "Высокая"], ["вызвать машину для вывоза мусора спб", "Фразовое", "Высокая"], ["вывоз мусора в течение дня спб", "Фразовое", "Средняя"], ["вывоз мусора без предоплаты спб", "Фразовое", "Средняя"], ["вывоз мусора ночью спб", "Фразовое", "Низкая"], ["срочный вывоз строительного мусора спб", "Фразовое", "Средняя"], ]), ...kwBlock("ГРУППА 3 — Строительный мусор (Фаза 1 — ЗАПУСКАТЬ ПЕРВЫМИ)", [ ["вывоз строительного мусора спб", "Фразовое", "Высокая"], ["вывоз строительного мусора петербург", "Фразовое", "Высокая"], ["вывоз строительного мусора после ремонта спб", "Фразовое", "Высокая"], ["вывоз мусора после ремонта квартиры спб", "Фразовое", "Высокая"], ["вывоз бетонного мусора спб", "Фразовое", "Средняя"], ["вывоз боя плитки спб", "Фразовое", "Средняя"], ["вывоз штукатурки спб", "Фразовое", "Средняя"], ["вывоз кирпичного боя спб", "Фразовое", "Средняя"], ["вывоз грунта спб", "Фразовое", "Средняя"], ["вывоз старой мебели спб", "Фразовое", "Средняя"], ["вывоз хлама из квартиры спб", "Фразовое", "Средняя"], ["вывоз строительного мусора ленинградская область", "Фразовое", "Средняя"], ]), ...kwBlock("ГРУППА 4 — По районам СПб (Фаза 2)", [ ["вывоз мусора приморский район спб", "Фразовое", "Высокая"], ["вывоз мусора выборгский район спб", "Фразовое", "Высокая"], ["вывоз мусора калининский район спб", "Фразовое", "Высокая"], ["вывоз мусора московский район спб", "Фразовое", "Высокая"], ["вывоз мусора красносельский район спб", "Фразовое", "Высокая"], ["вывоз мусора невский район спб", "Фразовое", "Средняя"], ["вывоз мусора фрунзенский район спб", "Фразовое", "Средняя"], ["вывоз мусора кировский район спб", "Фразовое", "Средняя"], ["вывоз мусора петроградский спб", "Фразовое", "Средняя"], ["вывоз мусора василеостровский спб", "Фразовое", "Средняя"], ["вывоз мусора колпино спб", "Фразовое", "Средняя"], ]), ...kwBlock("ГРУППА 5 — Города ЛО (Фаза 2)", [ ["вывоз мусора всеволожск", "Фразовое", "Высокая"], ["вывоз мусора гатчина", "Фразовое", "Высокая"], ["вывоз мусора мурино", "Фразовое", "Высокая"], ["вывоз мусора кудрово", "Фразовое", "Высокая"], ["вывоз мусора девяткино", "Фразовое", "Средняя"], ["вывоз мусора тосно", "Фразовое", "Средняя"], ["вывоз мусора кингисепп", "Фразовое", "Средняя"], ["вывоз мусора выборг", "Фразовое", "Средняя"], ["вывоз мусора сертолово", "Фразовое", "Средняя"], ["вывоз мусора шушары", "Фразовое", "Средняя"], ["вывоз мусора парголово", "Фразовое", "Низкая"], ["вывоз мусора ленинградская область", "Фразовое", "Средняя"], ]), gap(200), divider(), // ═══════════════════════════════════════ // РАЗДЕЛ 6: МИНУС-СЛОВА // ═══════════════════════════════════════ h1("6. МИНУС-СЛОВА"), p("Добавлять на уровне КАМПАНИИ. Экономят до 30% бюджета, отсекая нецелевые клики. При бюджете 1–3к/день это критично."), gap(80), tip("После 2 недель зайдите в «Поисковые запросы» и добавьте минус-слова из реальных нецелевых кликов — это самые ценные минуса."), gap(120), h2("Блок 1 — Информационные запросы"), p("-своими руками -самостоятельно -как сделать -что такое -правила -нормы -законодательство -СНИЛС -штраф -скачать -реферат -дипломная -курсовая -доклад -рассчитать самому -калькулятор скачать"), gap(120), h2("Блок 2 — Нерелевантные типы отходов"), p("-медицинский -радиоактивный -опасный -токсичный -химический -ядерный -биологический -взрывоопасный -класс а -класс б -класс в"), gap(120), h2("Блок 3 — Другие города (не ваша зона)"), p("-Москва -Московская -Новосибирск -Екатеринбург -Краснодар -Казань -Самара -Уфа -Челябинск -Омск"), gap(120), h2("Блок 4 — Вакансии и работа"), p("-вакансия -работа -зарплата -водитель -устроиться -требуется -ищу работу -оформление -трудоустройство"), gap(120), h2("Блок 5 — Покупка и продажа"), p("-купить контейнер -продам -б/у -аренда -прокат -стоимость контейнера купить"), gap(120), h2("Блок 6 — Прочие нецелевые"), p("-форум -отзывы (если не ваш сайт) -фото -видео -дёшево (если вы не самые дешёвые) -бесплатно -за спасибо -своими силами"), gap(200), divider(), // ═══════════════════════════════════════ // РАЗДЕЛ 7: НАСТРОЙКИ // ═══════════════════════════════════════ h1("7. НАСТРОЙКИ КАМПАНИИ"), gap(80), h2("7.1 Стратегия ставок при бюджете 1–3к/день"), new Table({ width: { size: 9200, type: WidthType.DXA }, columnWidths: [1600, 3200, 4400], rows: [ row(hCell("Период", 1600), hCell("Стратегия", 3200), hCell("Что делать", 4400)), row( cell("Дни 1–14", 1600, LBLUE, true, BLUE), cell("Ручные ставки", 3200, LBLUE, true), cell("Начните с 25–40 ₽ за клик. Мониторьте каждые 2 дня. Поднимайте ставку на ключах с CTR > 5%.", 4400, LBLUE) ), row( cell("Дни 15–30", 1600, WHITE, true, BLUE), cell("Ручные ставки (оптимизация)", 3200, WHITE, true), cell("Отключите ключи: расход > 200 ₽ без конверсий. Оставьте топ-10 конвертирующих.", 4400, WHITE) ), row( cell("Месяц 2+", 1600, LBLUE, true, BLUE), cell("Оптимизация кликов (авто)", 3200, LBLUE, true), cell("Переключить на «Макс. кликов в неделю» при накопленной статистике 100+ кликов.", 4400, LBLUE) ), ] }), gap(160), warn("Не включайте сразу «Оптимизацию конверсий» — нужно минимум 10–20 конверсий в неделю. При 1–3к/день это придёт к концу 2-го месяца."), gap(160), h2("7.2 Геотаргетинг"), bul("Регион показа: Санкт-Петербург + Ленинградская область"), bul("Расширенный геотаргетинг: ВЫКЛЮЧИТЬ — иначе покажетесь людям из Москвы, ищущим вывоз в СПб"), bul("Корректировка ставок +15%: Приморский, Выборгский, Калининский р-ны (высокая плотность и спрос)"), bul("Корректировка ставок −20%: отдалённые районы ЛО (Выборг, Кингисепп) на Фазе 1"), gap(120), h2("7.3 Временной таргетинг"), new Table({ width: { size: 9200, type: WidthType.DXA }, columnWidths: [3000, 2600, 3600], rows: [ row(hCell("Время", 3000), hCell("Ставка", 2600), hCell("Обоснование", 3600)), ...[ ["Пн–Пт 07:00–21:00", "100%", "Основное рабочее время — максимум"], ["Сб–Вс 07:00–21:00", "+10%", "Пик ремонтов и генеральных уборок"], ["Ежедневно 21:00–23:00", "70%", "Люди планируют на завтра — стоит быть"], ["Ежедневно 23:00–07:00", "40%", "Срочные ночные запросы — не отключать"], ].map((r, i) => row( cell(r[0], 3000, i % 2 === 0 ? LBLUE : WHITE, true), cell(r[1], 2600, i % 2 === 0 ? LRED : "FFFDF5", true, r[1] === "100%" ? GREEN : r[1] === "+10%" ? GOLD : "555555"), cell(r[2], 3600, i % 2 === 0 ? LBLUE : WHITE) )) ] }), gap(160), h2("7.4 Корректировки ставок"), bul("+20% мобильные устройства", "→"), p(" Большинство ищут с телефона чтобы сразу позвонить. Это самый ценный трафик.", { color: "666666" }), bul("+40% ретаргетинг (посетители сайта)", "→"), p(" Люди которые уже были — конвертируют в 3–5 раз лучше.", { color: "666666" }), bul("−50% аудитория «дети 0–12 лет»", "→"), p(" Нецелевая аудитория — экономим бюджет.", { color: "666666" }), bul("−30% возраст 18–24", "→"), p(" Низкая конверсия в нише вывоза мусора.", { color: "666666" }), gap(160), h2("7.5 Обязательные технические настройки"), bul("Счётчик Яндекс Метрики — подключить к кампании (без этого оптимизация не работает)"), bul("Цели в Метрике: «Клик по номеру», «Отправка формы», «Сессия > 60 сек» — настроить ДО запуска"), bul("Колтрекинг — рекомендуется (CoMagic / Calltouch) — видно какой ключ приносит звонки"), bul("UTM-метки — на всех URL объявлений: ?utm_source=yandex&utm_medium=cpc&utm_campaign=poisk"), bul("Показ по доп. релевантным фразам — ВЫКЛЮЧИТЬ на Фазе 1"), bul("Автотаргетинг — ВЫКЛЮЧИТЬ (добавит нецелевой трафик)"), bul("Остановка при недоступности сайта — ВКЛЮЧИТЬ"), gap(200), divider(), // ═══════════════════════════════════════ // РАЗДЕЛ 8: ЧЕКЛИСТ И МЕТРИКИ // ═══════════════════════════════════════ h1("8. ЧЕКЛИСТ ЗАПУСКА И KPI"), h2("8.1 Чеклист — проверить перед стартом"), new Table({ width: { size: 9200, type: WidthType.DXA }, columnWidths: [600, 8600], rows: [ row(hCell("", 600), hCell("Задача", 8600)), ...[ ["☐", "Яндекс Метрика подключена к сайту и к кампании Директ"], ["☐", "Настроены цели: «Клик по телефону», «Отправка формы», «Кнопка заявки»"], ["☐", "Номер телефона в объявлении (расширение «Контактная информация»)"], ["☐", "Заполнена визитка (адрес, часы работы)"], ["☐", "Все минус-слова добавлены на уровне кампании"], ["☐", "Лендинг открывается на мобильном < 3 секунд"], ["☐", "Телефон на лендинге кликабелен (тег tel:)"], ["☐", "UTM-метки на всех URL объявлений"], ["☐", "Дневной бюджет с ограничением выставлен"], ["☐", "Расширенный геотаргетинг ВЫКЛЮЧЕН"], ["☐", "Автотаргетинг и доп. фразы ВЫКЛЮЧЕНЫ"], ["☐", "2 варианта объявления в каждой группе (A/B тест)"], ].map((r, i) => row( cell(r[0], 600, i % 2 === 0 ? "F0FFF0" : WHITE, false, GREEN, 22), cell(r[1], 8600, i % 2 === 0 ? "F0FFF0" : WHITE) )) ] }), gap(160), h2("8.2 Целевые KPI при бюджете 1–3к/день"), new Table({ width: { size: 9200, type: WidthType.DXA }, columnWidths: [3200, 2400, 3600], rows: [ row(hCell("Метрика", 3200), hCell("Целевое значение", 2400), hCell("Если хуже — что делать", 3600)), ...[ ["CTR (кликабельность)", "> 8–12%", "Переписать заголовок, добавить цену или цифры"], ["Цена клика (CPC)", "30–70 ₽", "Снизить ставки или сузить ключи"], ["Конверсия сайта в заявку", "> 5–8%", "Улучшить лендинг, добавить форму выше"], ["Стоимость заявки (CPL)", "< 500–800 ₽", "Отключить неконвертирующие ключи"], ["Отказы", "< 30%", "Проверить релевантность объявления и страницы"], ].map((r, i) => row( cell(r[0], 3200, i % 2 === 0 ? LBLUE : WHITE, true), cell(r[1], 2400, i % 2 === 0 ? LRED : "FFFDF5", true, GREEN), cell(r[2], 3600, i % 2 === 0 ? LBLUE : WHITE, false, "555555", 19) )) ] }), gap(240), divider(), new Paragraph({ alignment: AlignmentType.CENTER, spacing: { before: 120, after: 80 }, children: [new TextRun({ text: "Яндекс Директ · Вывоз мусора СПб и ЛО · Бюджет 1 000–3 000 ₽/день", size: 18, color: "AAAAAA", italics: true, font: "Arial" })] }), ] }] }); Packer.toBuffer(doc).then(buf => { fs.writeFileSync('/home/claude/yd-strategy.docx', buf); console.log('Done'); });
Made on
Tilda