Перейти к основному содержимому
Altcraft Docs LogoAltcraft Docs Logo
Пользователям iconПользователям
Разработчикам iconРазработчикам
Администраторам iconАдминистраторам
Русский
  • Русский
  • English
Войти
    Документация пользователя
    С чего начать
    FAQ
    Термины
      Обновления платформыarrow
    • v2026.1.76
      v2025.4.75
      v2025.4.74
      v2025.3.73
      v2025.2.72
      v2025.1.71
      v2024.4.70
      v2024.3.69
      v2024.2.68.2
      v2024.1.68
      Хранение и сбор данныхarrow
    • Ресурсы подписок
      Работа с базами данных
      Профиль подписчика
      Импорт профилей клиентов и обновление данных
      Импорт данных по расписанию
      Автоматизация сбора данных о профиле
      Массовое обновление профилей клиентов
      Double opt-in подписка
      Стоп-списки
      Связи между профилями
      Экспорт истории профилей
      Экспорт профилей
      Автоматическое создание статического сегмента при импорте
      Как открыть CSV-файл
      Матчинг
      Типы полей в базе данных
      Глобальные контрольные группы
      Менеджер подписок
      Каналы коммуникацииarrow
      • Email-каналarrow
      • Рекомендации по взаимодействию с ISP
        Настройка собственного from-домена
        Настройка и использование постмастеров
        Быстрый старт
        Push-каналarrow
        • Mobile Pusharrow
        • Настройка и подключение
            Интеграция приложения с Altcraftarrow
          • Провайдеры: структура push сообщения
            Обработка и добавление подписки
            Регистрация событий
          Web Pusharrow
        • Предварительные настройки
            Настройка для различных браузеровarrow
          • Apple Safari
            Mozilla Services
            Firebase Cloud Messaging
          Подключение Web Push на сайт
          Передача данных в платформу
          Методы Web Push SDK
            Миграция и перенос подписокarrow
          • Перенос push-подписок из стороннего сервиса
            Как перенести push-подписки, настроенные для Safari
            Миграция с OneSignal
      SMS-канал
        Создание рассылки с нуляarrow
      • Email
        SMS
        Web Push
        Mobile Push
        WhatsApp
        Viber™
        Руководство: SMS-рассылка через VK Notify
        MAX Bot
        MAX Group
        Notify
        Telegram Bot
        Telegram Group
      Схема работы каналов коммуникации
      Руководство: SMS-рассылка через УТШ
      Руководство: push-рассылка через сервис от "Согласие"
      Сегментацияarrow
    • Статические сегменты
      Динамические сегменты
      Обновляемые сегменты
        Условия сегментацииarrow
      • Сегментация по данным профиля
        Сегментация по взаимодействиям с сущностями
        Сегментация по активности в каналах коммуникации
        Сегментация по внешним данным
        Сегментация по внешним SQL-таблицам
        Сегментация по структуре профиля
      Лучшее время отправки (BST)
      Логические операторы "И" и "ИЛИ"
      Рекомендации по работе с сегментами
      Шаблоны сообщенийarrow
      • Работа с шаблонами сообщенийarrow
      • Работа в редакторе
        Email-шаблон
        SMS-шаблон
        Push-шаблон
        MAX-шаблон
        Telegram-шаблон
        WhatsApp-шаблон
        Viber™-шаблон
        Notify-шаблон
        Визуальный редактор для email-шаблонаarrow
      • Интерфейс редактора
        Добавление элементов
        Элементы и их настройки
        Пользовательские блоки
        Стили элемента
        Структура элементов
      Блочный редактор для email-шаблона
      Фрагменты шаблонов
      Изображения в сообщениях
      Персонализация контента в сообщениях
      Формирование таблиц на основе элементов массива
        Переменные и функции Altcraftarrow
      • Использование логических выражений в сообщениях
        Использование циклов в сообщениях
        Использование переменных маркета в сообщениях
        Использование функционала JSONPath
        Динамический контент сообщенийarrow
      • Использование API-контента в сообщениях
        Использование HTML-контента в сообщениях
        Использование JSON-контента в сообщениях
        Использование контента из SQL базы данных в сообщениях
      Импорт и экспорт шаблона сообщения
      Экспорт шаблона из Pixcraft
      Импорт шаблона из стороннего сервиса
      Рассылкиarrow
    • Календарь рассылок
      Броадкаст рассылка
      Регулярная рассылка
      Триггерная рассылка
      Мультивариантный тест (A/B/n)
      Тестирование расылок
      Расписание рассылок
      Размещения
      Кампанииarrow
    • Работа с Кампаниями
      Локальные контрольные группы (ЛКГ)
      Расширение аудитории в кампании
      Разметка аудитории в кампаниях
      Сценарии автоматизацииarrow
    • Работа со Сценариями автоматизации
      Узлы сценария
      Классические сценарии автоматизации маркетинга
      Приветственный сценарий: пошаговая настройка
      Автоматическое оповещение менеджера через сценарий
      Сценарий брошенной корзины
      Маркетarrow
    • Настройки маркета
        Продуктыarrow
      • Создание продукта вручную
        Импорт продукта из файла
        Импорт по расписанию
        Сегменты продуктов и SKU
        Подготовка YML-файла
      Заказы
      Переменные маркета в шаблонах
      Руководство: как отправить письмо подтверждения заказа
      Лояльностьarrow
    • Создание и настройка программы лояльности
      Интеграция лояльности с внешними системами
      Быстрый старт
      Базовые кейсы использования программы лояльности
      Сегменты заказов
      Промокоды
      Веб-слойarrow
      • Формыarrow
      • Создание формы
        Конструктор формы
        Оформление формы
        Действия при активации формы
        Аналитика данных
        Связывание данных канала и формы
        Условная постраничная логика в формах и опросах
        NPS-тестирование
        Пикселиarrow
      • Целевые действия клиентов и скоринг
        Попапыarrow
      • Создание и публикация попапа
        Настройка попапа в редакторе кода
        Управление попапами вручную через скрипт
        Аналитика попапов
        Руководство: попап для подписки на push
        Базовые кейсы размещения попапа через Менеджер тегов
        Кейс: Создание попапа с виджетом "Колесо фортуны"
        Менеджер теговarrow
      • Настройка и установка Менеджера тегов
        Типы триггеров
        Типы переменных
        Связывание пикселя и Менеджера тегов
      Отчеты и аналитикаarrow
    • Отчет по каналам
      Отчёт по трафику
        Сводный отчётarrow
      • Все показатели сводного отчета
      Когортный отчёт
      Время жизни
      Воронка конверсии
      Цели
      Прирост аудитории
      Карта кликов (Email)
      Отчет по программам лояльности
      Отчёт о возвратах
      Отчёт о недоставках
      Отчет по глобальным контрольным группам
      Интеграцииarrow
    • Синхронизация статических сегментов
      MAX
      Яндекс.Аудитории™
      Аудитории Google Ads
      Facebook Ads Manager™
      Область видимости интеграции
      WhatsApp
      Viber™
      Tilda™
      Yandex AppMetrica™
      Lpgenerator™
      VK Реклама™
      Передаваемые при синхронизации данные
        Интеграция сторонних сервисов с Altcraft через Albatoarrow
      • Подключение Altcraft к Albato
        Запуск приветственного сценария через Albato
        Передача данных о событии
        Отправка триггерной рассылки
        Регистрация событий
        Импорт данных из Google Sheets через Albato
        Передача данных из Altcraft
      Notify
        Захват событийarrow
      • Захват событий Altcraft
        Типы событий для захвата
        Структуры сообщений захвата событий
        Отправить JSON-запрос батчем
        Отправить сообщение в очередь RabbitMQ
        Отправить сообщение в exchange RabbitMQ
        Отправить сообщение в Kafka broker
        Предварительное тестирование события
      Настройкиarrow
    • Настройки аккаунта
      Настройки атрибутов
      Поисковые теги: создание и применение
      Пользовательские ссылки
      Виртуальные сендеры
      Политики отправки
        Пользователи и разграничение доступаarrow
      • Двухфакторная аутентификация (2FA)
        Подключенияarrow
      • Подключение к Facebook Ads
        Подключение к Google Ads
        Подключение к Яндекс.Аудиториям™
        Подключение к 360dialog
        Подключение к Edna
        Подключение к Devino Telecom
        Подключение к SMS Traffic
        Подключение к VK Рекламе™
        Подключение к MTS OmniChannel
        Подключение через OAuth2
        Подключение через Basic Authentication
        Подключение через Token Authentication
        Подключение через Custom Authentication
        Подключение к MAX
        Подключение к Notify
        Подключение к Rapporto
      Журнал аудита
      API-запросы: с чего начатьarrow
    • Импорт и обновление профиля
      Запуск триггерной рассылки
      Отправка профиля клиента в сценарий
    Архив документации
    Библиотека email-маркетолога
  • Веб-слой
  • Попапы
  • Кейс: Создание попапа с виджетом "Колесо фортуны"

Кейс: Создание попапа с виджетом "Колесо фортуны"

Специальный виджет "Колесо фортуны" позволяет создать интерактивный попап, который вовлекает посетителей сайта в игру с призами. Пользователь заполняет простую форму и вращает колесо, чтобы получить случайный подарок: скидку, промокод или другой бонус. Данное руководство описывает процесс создания такого попапа в конструкторе Altcraft:


Перед настройкой колеса рекомендуется создать поле в базе профилей, в которое будет сохраняться информация о выигранном призе. О том, как создавать дополнительные поля, вы можете узнать в этой статье.

Создание попапа и выбор шаблона​

Начните с создания нового попапа в разделе Веб-слой — Попапы, нажав кнопку Создать. Выберите тип попапа. Для колеса фортуны идеально подходит Модальное окно — оно появляется в центре экрана:


Выберите шаблон. Воспользуйтесь любым из готовых шаблонов как основой. Для упрощения кастомизации рекомендуется использовать шаблоны с минималистичным дизайном (например, с космонавтом):


Задайте имя и описание. Укажите системное имя и при необходимости — описание:


Интеграция кода виджета​

Виджет "Колесо фортуны" реализован на HTML, CSS и JavaScript. Для его добавления необходимо заменить код стандартного шаблона на предоставленный готовый код.

  • CSS
  • HTML
  • JavaScript

Перейдите на вкладку CSS. Не удаляйте существующие стили. Прокрутите редактор в самый конец и добавьте предоставленный CSS-код для стилизации колеса и его контейнера.

.formWrapper {
display: flex;
align-items: center;
justify-content: space-around;
flex-wrap: wrap;
}

.ac-button:disabled {
opacity: 0.6;
cursor: not-allowed;
background-color: #cccccc;
color: #666666;
transform: none;
box-shadow: none;
}

.ac-button:disabled:hover {
background-color: #cccccc;
color: #666666;
transform: none;
box-shadow: none;
}

В разделе "Настройки" откройте вкладку HTML. Полностью удалите текущее содержимое редактора и вставьте предоставленный HTML-код для колеса.

<div class="ac-popup-overlay">
<div class="ac-modal">
<div class="ac-modal_content">
<div style="display: none;" data-popupId="{{popup('copywriting' 'popupId' 'text')}}"></div>
<div id="firstPage">
<h4 class="ac-title">
{{popup('copywriting' 'title' 'text')}}
</h4>
<div class="ac-description">
{{popup('copywriting' 'text' 'text')}}
</div>
<div class="formWrapper">
<div class="canvas-container">
<canvas id="canvas" width="420" height="420"></canvas>
</div>
<form id="ac-form" class="ac-form" action>
<div class="ac-field">
<label class="ac-label" for="email">
{{popup('copywriting' 'emailLabel' 'text')}}
</label>
<input
id="email"
type="email"
class="ac-input"
name="{{popup('form' 'email' 'fieldData')}}"
placeholder="{{popup('copywriting' 'emailPlaceholder' 'text')}}"
/>
</div>
<div class="ac-field">
<label class="ac-label" for="name">
{{popup('copywriting' 'nameLabel' 'text')}}
</label>
<input
id="name"
class="ac-input"
name="{{popup('form' 'name' 'fieldData')}}"
placeholder="{{popup('copywriting' 'namePlaceholder' 'text')}}"
/>
</div>
<div class="ac-field">
<label>
<input type="checkbox" name="{{popup('form' 'privacyPolicy' 'fieldData')}}" id="privacyPolicy" required>
<span>С <a href="{{popup('copywriting' 'policy' 'link')}}" target="_blank">политикой конфиденциальности</a> ознакомлен</span>
</label>
</div>
<div class="ac-validation-msg" for="email"></div>
<input type="text" style="display: none;" class="ac-input" id="prizeField" name="{{popup('form' 'prize' 'fieldData')}}">
<button class="ac-button" type="button" id="winBtn" disabled>
{{popup('copywriting' 'winBtn' 'text')}}
</button>

<div class="ac-form_submit" style="display: none;">
<button type="submit" class="ac-button" id="submitBtn">
{{popup('cta' 'text' 'text')}}
</button>
</div>
</form>
</div>
</div>
<div id="secondPage" style="display: none;">
<h4 class="ac-title">
{{popup('copywriting' 'title-congrats' 'text')}}
</h4>
<div class="ac-description">
{{popup('copywriting' 'text-before-prize' 'text')}}
<span id="prizeName"></span>
<div>
{{popup('copywriting' 'text-after-prize' 'text')}}
</div>
</div>
</div>
</div>
{{popup('closeButton' 'closeButton' 'closeBtn')}}
</div>
</div>

Переключитесь на вкладку JavaScript. Полностью удалите текущее содержимое и вставьте предоставленный JS-код, который отвечает за логику вращения колеса, определение выигрыша и работу с формой.

// Список выигрышей. Длина может варьироваться
// id - Идентификатор, отправляемый на сервер
// text - Подпись у сектора колеса
const options = [
{id: 1, text: '$100'},
{id: 2, text: '$10'},
{id: 3, text: '$25'},
{id: 4, text: '$250'},
{id: 5, text: '$30'},
{id: 6, text: '$1000'},
{id: 7, text: '$1'},
{id: 8, text: '$200'},
{id: 9, text: '$45'},
{id: 10, text: '$500'},
{id: 11, text: '$5'},
{id: 12, text: '$20'}
]

// Цвета секторов колеса. Если цветов меньше, чем секторов, то цвета повторяются циклично
const colors = ['white', '#3583FF']

// Начальный угол поворота колеса
let currentAngle = 0;

// Длительность вращения колеса задаётся случайно
// Минимальное время вращения (сек)
const minSpinTime = 4;

// Максимальное время вращения (сек)
const maxSpinTime = 7;

// Задержка между остановкой колеса и сообщением о выигрыше (сек)
const pageSwitchDelay = 2;

// Цвет подписей секторов на колесе
const textColor = "black";


let isPreview = true;
let myPopup = null;

const allPopups = document.querySelectorAll('[data-ac-popup-container]');

allPopups.forEach(item =>{
const idContainer = item.shadowRoot.querySelector('[data-popupId={{popup('copywriting' 'popupId' 'text')}}]');
if(idContainer){
myPopup = item.shadowRoot;
isPreview = false;
}
})

if (!myPopup) {
myPopup = document;
}

const winBtn = myPopup.getElementById('winBtn');

function initInputs(){
let emailInput = myPopup.getElementById('email');
let nameInput = myPopup.getElementById('name');
let policyInput = myPopup.getElementById('privacyPolicy');

function updateButtonState() {
const isEmailEmpty = !emailInput.value.trim();
const isNameEmpty = !nameInput.value.trim();
const isPolicyChecked = policyInput.checked;

console.log(myPopup.getElementById('winBtn'))
myPopup.getElementById('winBtn').disabled = isEmailEmpty || isNameEmpty || !isPolicyChecked
}

emailInput.addEventListener('input', updateButtonState);
nameInput.addEventListener('input', updateButtonState);
policyInput.addEventListener('input', updateButtonState);
myPopup.getElementById("winBtn").addEventListener("click", spin);

updateButtonState();
}
if(isPreview) {
setTimeout(()=>{initInputs()}, 1000);
} else {
initInputs();
}


let isInitialized = false;

function initializeWheel() {
if (isInitialized) return;

const canvas = myPopup.getElementById("canvas");
if (!canvas) return;

const ctx = canvas.getContext("2d");
if (ctx && !canvas.dataset.initialized) {
drawRouletteWheel();
canvas.dataset.initialized = "true";
isInitialized = true;
}
}

const observer = new MutationObserver((mutations) => {
for (let mutation of mutations) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === 1 && (node.id === 'canvas' || node.querySelector?.('#canvas'))) {
setTimeout(initializeWheel, 100);
}
});
}
}
});

if (document.body) {
observer.observe(document.body, { childList: true, subtree: true });
}

document.addEventListener('DOMContentLoaded', initializeWheel);

let segmentAngle = Math.PI / (options.length / 2);
let spinTimeout = null;

let spinAngleStart = 0;

let spinTime = 0;
let spinTimeTotal = 0;

let ctx;



function drawRouletteWheel() {
const canvas = myPopup.getElementById("canvas");

if (canvas.getContext) {
const centerX = 210;
const centerY = 210;
const outsideRadius = 200;
const textRadius = 130;
const insideRadius = 0;

ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, 400, 400);

ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.font = 'bold 12px Helvetica, Arial';

ctx.strokeStyle = "white";
ctx.lineWidth = 15;
ctx.beginPath();
ctx.arc(centerX, centerY, outsideRadius, 0, 2 * Math.PI);
ctx.stroke();

ctx.strokeStyle = "black";
ctx.lineWidth = 2;

for(let i = 0; i < options.length; i++) {
const angle = currentAngle + i * segmentAngle;
const segmentMiddleAngle = angle + segmentAngle / 2;
ctx.fillStyle = colors[i % colors.length];
ctx.beginPath();
ctx.arc(centerX, centerY, outsideRadius, angle, angle + segmentAngle, false);
ctx.arc(centerX, centerY, insideRadius, angle + segmentAngle, angle, true);
ctx.stroke();
ctx.fill();

ctx.save();
ctx.fillStyle = textColor;

const textX = centerX + Math.cos(segmentMiddleAngle) * textRadius;
const textY = centerY + Math.sin(segmentMiddleAngle) * textRadius;

ctx.translate(textX, textY);
ctx.rotate(segmentMiddleAngle);

const text = options[i].text;
ctx.fillText(text, -ctx.measureText(text).width / 2, 0);
ctx.restore();
}

ctx.fillStyle = "white";
ctx.strokeStyle = "#666666";
ctx.lineWidth = 2;

ctx.beginPath();
ctx.moveTo(centerX - 10, centerY - 15);
ctx.lineTo(centerX + 30, centerY);
ctx.lineTo(centerX - 10, centerY + 15);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
}

function rotateWheel() {
spinTime += 30;
if(spinTime >= spinTimeTotal) {
stopRotateWheel();
return;
}
const spinAngle = spinAngleStart - easeOut(spinTime, 0, spinAngleStart, spinTimeTotal);
currentAngle += (spinAngle * Math.PI / 180);
drawRouletteWheel();
spinTimeout = setTimeout(rotateWheel, 30);
}

function spin(e) {
e.preventDefault();
const form = myPopup.getElementById('ac-form');
const isValid = form.checkValidity();

if(!isValid){
myPopup.getElementById('submitBtn').click();
return;
}
winBtn.removeEventListener('click', spin);
spinAngleStart = Math.random() * 10 + 10;
spinTime = 0;
spinTimeTotal = Math.random() * (maxSpinTime - minSpinTime) + minSpinTime * 1000;
rotateWheel();
}

function handlePrize(prize){
myPopup.getElementById("prizeField").value = prize.id;
myPopup.getElementById('submitBtn').click();
myPopup.getElementById('prizeName').innerText = prize.text;
}

function showSecondPage() {
myPopup.getElementById('firstPage').style.display = 'none';
myPopup.getElementById('secondPage').style.display = 'block';
}

function stopRotateWheel() {
clearTimeout(spinTimeout);

const degrees = currentAngle * 180 / Math.PI;
const segmentDegrees = segmentAngle * 180 / Math.PI;
const index = Math.floor((360 - degrees % 360) / segmentDegrees);

handlePrize(options[index]);

const form = myPopup.getElementById('ac-form');
const isValid = form.checkValidity();

setTimeout(()=>{
showSecondPage();
}, pageSwitchDelay * 1000);

}

function easeOut(currentTime, startValue, changeInValue, duration) {
const normalizedTime = currentTime / duration;
const squaredTime = normalizedTime * normalizedTime;
const cubedTime = squaredTime * normalizedTime;

return startValue + changeInValue * (cubedTime + -3 * squaredTime + 3 * normalizedTime);
}

drawRouletteWheel();

myPopup.getElementById('ac-form').submit = () => {}

Настройка контента и дизайна в визуальном редакторе​

После интеграции кода перейдите в раздел Дизайн. Здесь вы можете наполнить попап текстом и настроить его внешний вид, используя привычный визуальный интерфейс, без правки кода.

  • Ширина окна
  • Текстовое наполнение
  • Внешний вид

Первым делом задайте ширину окна (Форма — width). Размеры холста с колесом фиксированы (420 px). Поэтому ширина всего попапа должна быть не менее 420 px. Если вы хотите разместить колесо и форму для ввода данных на одной горизонтальной линии, установите ширину не менее 810 px.

На вкладке Копирайтинг заполните ключевые текстовые параметры:

  • title — главный заголовок на первом экране (например, "Испытай удачу!").
  • text — поясняющий текст или описание акции.
  • emailLabel и emailPlaceholder — подпись и подсказка для поля ввода email.
  • nameLabel и namePlaceholder — подпись и подсказка для поля ввода имени.
  • policy — обязательная ссылка на страницу с политикой конфиденциальности. Без заполнения этого поля сохранить попап не получится.
  • winBtn — текст на кнопке, которая запускает вращение колеса (например, "Крутить колесо!").
  • popupId — обязательный параметр. Уникальный текстовый идентификатор попапа (например, bookverse_wheel). Необходим для корректной работы, если на странице используется несколько попапов.

Попап состоит из двух экранов. Параметры для экрана с сообщением о выигрыше:

  • title-congrats — заголовок поздравления.
  • text-before-prize — текст, который будет показан перед названием выигранного приза.
  • text-after-prize — дополнительный текст под сообщением о призе.

Используйте остальные вкладки раздела Дизайн для тонкой настройки внешнего вида:

  • Фон — измените цвет фона попапа и прозрачность затемнения страницы (overlay).
  • Рамка — настройте скругление углов всплывающего окна.
  • Форма — задайте стили для полей ввода: отступы, цвета границ, фона и текста.
  • Действия — настройте внешний вид кнопок (цвет, скругление, шрифт).
  • Типографика — выберите общий шрифт и стили для всех текстовых элементов.

Любые изменения в визуальном редакторе сразу отображаются в окне предпросмотра справа.

Кастомизация колеса фортуны​

Внешний вид и поведение самого колеса (призы, цвета секторов, скорость вращения) настраиваются путём правки переменных в JavaScript-коде.

Вернитесь в раздел Настройки — JavaScript. В начале файла найдите и отредактируйте следующие переменные.

  • Призы (options)
  • Цвета секторов (colors)
  • Скорость вращения
  • Задержка показа
  • Цвет текста (textColor)

Переменная options определяет список призов на колесе. Это массив объектов, где каждый объект содержит id и текст приза text.

const options = [
{ id: 1, text: '$100' },
{ id: 2, text: '$10' },
{ id: 3, text: '$25' },
{ id: 4, text: '$250' },
{ id: 5, text: '$30' },
{ id: 6, text: '$1000' },
{ id: 7, text: '$1' },
{ id: 8, text: '$200' },
{ id: 9, text: '$45' },
{ id: 10, text: '$500' },
{ id: 11, text: '$5' },
{ id: 12, text: '$20' }
];

Как изменить:

  • Текст приза: Замените значение text на нужное (например, '10% скидка' или 'Бесплатная доставка').
  • Количество призов: Добавьте новые объекты в массив или удалите существующие. Количество секторов на колесе изменится автоматически.

Переменная colors — это массив цветов для заливки секторов колеса. Цвета применяются по порядку, начиная с первого сектора.

const colors = ['black', 'orange'];

Как изменить: Замените цвета в массиве на нужные. Вы можете использовать:

  • Названия цветов на английском: 'red', 'blue', 'green'
  • HEX-коды: '#4f46e5', '#f59e0b', '#10b981'
  • RGB/RGBA значения: 'rgb(79, 70, 229)'

Длительность вращения колеса задаётся двумя переменными:

  • minSpinTime — минимальное время вращения (в секундах).
  • maxSpinTime — максимальное время вращения (в секундах).

Фактическое время каждого вращения будет случайным числом в этом диапазоне.

const minSpinTime = 4;
const maxSpinTime = 7;

Как изменить: Увеличьте значения, чтобы колесо вращалось дольше, или уменьшите значения для более быстрого результата.

Переменная pageSwitchDelay задаёт паузу (в секундах) между остановкой колеса и автоматическим переходом на экран с сообщением о выигрыше.

const pageSwitchDelay = 2;

Как изменить: Измените значение на необходимое количество секунд.

Переменная textColor определяет цвет надписей с названиями призов на секторах колеса.

const textColor = "white";

Как изменить: Замените значение на любой валидный CSS-цвет, чтобы текст хорошо читался на фоне сектора. Например, "#ffffff", "black", "#1f2937".

Сохранение данных о выигранном призе​

После того как пользователь вращает колесо и выигрывает приз, информация о выигрыше автоматически заполняется в скрытом поле формы prize. Чтобы сохранить эти данные в профиле пользователя в Altcraft, необходимо настроить действие импорта в разделе Действия.

В редакторе попапа откройте вкладку Действия:

Настройте импорт профилей:

  • Следуйте стандартной процедуре настройки импорта, описанной в статье о создании попапов.
  • В настройках импорта обязательно настройте сопоставление поля prize из формы с нужным полем в вашей базе данных Altcraft.

По умолчанию JavaScript-код записывает в поле prize текст выигранного приза (prize.text). Если вам нужно сохранять идентификатор приза (prize.id), отредактируйте функцию handlePrize() в JS-коде, заменив prize.text на prize.id.

После настройки импорта при каждой отправке формы данные о выигрыше (текст или ID приза) будут сохраняться в профиле пользователя вместе с его email и именем.

Публикация попапа​

После полной настройки сохраните попап и убедитесь, что его статус Активен.

В разделе Появление привяжите попап к контейнеру Менеджера тегов:

Задайте Имя тега и настройте триггер — условие, при котором попап будет показан (например, Таймер или Глубина прокрутки):

Подробнее о настройке триггеров читайте в отдельной статье.

После полной настройки сохраните попап и убедитесь, что его статус установлен в Активен. После публикации попап с колесом фортуны будет готов к работе и начнёт появляться у посетителей вашего сайта согласно заданным правилам.

Автоматическая отправка персонализированных призов через сценарии​

Для автоматической отправки промокодов, соответствующих выигранным призам, настройте сценарий с триггером на изменение поля Prize. Вам потребуется создать отдельные промокоды для каждого типа приза и настроить условные ветвления в сценарии.

Создание промокодов​

Перейдите в Лояльность — Создать для создания новой программы лояльности. В настройках программы создайте промокоды для каждого выигрыша. Например:

  • Скидка 10% — промокод BOOK10
  • Скидка 15% — промокод BOOK15
  • Бесплатная доставка — промокод FREESHIP
  • И т. д. для каждого приза

Подробнее о промокодах можно узнать в этой статье.

Создание шаблона письма​

Создайте универсальный шаблон письма, который будет показывать разный текст в зависимости от выигранного приза. Используйте логические выражения для проверки значения поля Prize. Подробнее о работе с логическими выражениями и переменными в шаблонах можно узнать в этой статье.

В шаблоне проверяется, какое значение содержит поле с призом (например Prize) в профиле пользователя ({lead.Prize}), и в зависимости от этого показывается соответствующий текст. Для каждого типа приза в текст письма нужно вставить переменную промокода:


{if lead.Prize}

{if lead.Prize equal "1" or lead.Prize equal "$100"}
<p>Поздравляем, {lead._fname}!</p>
<p>Вы выиграли денежный приз в размере $100!</p>
<p>Ваш промокод: {loyalty.prize100.promocode}</p>
<p>Промокод действует на все товары в нашем магазине.</p>
{end}

{if lead.Prize equal "2" or lead.Prize equal "$10"}
<p>Поздравляем, {lead._fname}!</p>
<p>Вы выиграли денежный приз в размере $10!</p>
<p>Ваш промокод: {loyalty.prize10.promocode}</p>
<p>Промокод действует на все товары в нашем магазине.</p>
{end}

{if lead.Prize equal "3" or lead.Prize equal "скидка 10%"}
<p>Поздравляем, {lead._fname}!</p>
<p>Вы выиграли скидку 10% на следующую покупку!</p>
<p>Ваш промокод: {loyalty.discount10.promocode}</p>
<p>Скидка действует на все товары в нашем каталоге.</p>
{end}
{else}
<p>Поздравляем, {lead._fname}!</p>
<p>Вы выиграли приз в нашей акции!</p>
<p>Подробности уточняйте у менеджера.</p>
{end}

В результате у вас получится шаблон, где для каждого условия указан свой промокод:

Создание сценария​

Перейдите в раздел Сценарии — Создать. Выберите базу данных, в которой хранятся профили участников акции. В настройках входа установите опцию Отключить повторный вход в сценарий для профиля клиента. Это гарантирует, что сценарий будет запущен для каждого пользователя только один раз при каждом новом выигрыше.

После создания сценария добавьте триггер входа. Выберите тип триггера Изменение профиля, укажите поле Prize и установите оператор Изменено. Это означает, что сценарий будет запускаться каждый раз, когда в профиле пользователя появляется или изменяется значение поля с призом.

После настройки триггера добавьте в сценарий элемент Условие. В условии проверяйте значение поля Prize. Например, укажите Поле — Prize, Оператор — equal, и введите значение 1 (если в поле сохраняется ID приза) или текст первого приза, например $100.

Если условие выполняется (пользователь выиграл приз с ID 1 или "$100"), добавьте два узла:

  • Промокод — выберите созданную программу лояльности и конкретный промокод, соответствующий этому призу.
  • Отправить email — выберите созданный универсальный шаблон письма.

Если условие не выполняется, добавьте следующий элемент Условие для проверки второго приза. Настройте его аналогично: проверяйте, содержит ли поле Prize значение 2 или текст второго приза.

Повторите эту логику для каждого приза, создав цепочку условий и соответствующих действий по назначению промокодов и отправке писем:

В конце не забудьте сохранить и активировать сценарий.

Последнее обновление 12 мар. 2026 г.
Предыдущая страница
Базовые кейсы размещения попапа через Менеджер тегов
Следующая страница
Менеджер тегов
  • Создание попапа и выбор шаблона
    • Интеграция кода виджета
    • Настройка контента и дизайна в визуальном редакторе
    • Кастомизация колеса фортуны
    • Сохранение данных о выигранном призе
  • Публикация попапа
  • Автоматическая отправка персонализированных призов через сценарии
    • Создание промокодов
    • Создание шаблона письма
    • Создание сценария
© 2015 - 2026 Altcraft. Все права защищены.