Пуш‑уведомления (push‑notifications) – это короткие сообщения, которые появляются у посетителей сайта даже тогда, когда они находятся не на странице, а в другом окне браузера. Правильно реализованная пуш‑уведомление повышает вовлечённость, удерживает аудиторию и стимулирует продажи.
Содержание - Что такое пуш‑уведомление?
- Технические требования
- Выбор сервиса рассылки
- Пошаговая реализация
- Лучшие практики и ограничения
- Юридические аспекты
- Контакты для обращений
Что такое пуш‑уведомление?
Пуш‑уведомление – это небольшое сообщение, отправляемое через браузер (Web Push) или мобильное приложение. Оно состоит из заголовка, текста, иконки и, при желании, изображения и кнопки действия.
Технические требования - HTTPS – браузеры разрешают отправлять push‑сообщения только с защищённого соединения.
- Service Worker – скрипт, работающий в фоне и принимающий push‑сообщения.
- Push API – интерфейс браузера для подписки и получения сообщений.
- VAPID‑ключи – пара публичного/приватного ключа, необходимая для аутентификации отправителя.
Выбор сервиса рассылки
Существует несколько готовых платформ, которые упрощают процесс:
- Webpushr
- OneSignal
- PushCrew
- Самостоятельная реализация через Firebase Cloud Messaging (FCM) или Amazon SNS.
Пошаговая реализация Шаг 1. Генерация VAPID‑ключей npm install web-push -g
web-push generate-vapid-keys
npm install web-push -g
web-push generate-vapid-keys
Сохраните publicKey и privateKey – они понадобятся в коде сервера и клиенте.
Шаг 2. Добавление Service Worker // /service-worker.js
self.addEventListener('push', function(event) {
const data = event.data ? event.data.json : {};
const = data. || 'Новое сообщение';
const options = {
body: data.body,
icon: data.icon,
image: data.image,
data: { url: data.url }
};
event.waitUntil(self.registration.showNotification(, options));
});
self.addEventListener('notificationclick', function(event) {
event.notification.close;
const url = event.notification.data.url;
event.waitUntil(clients.openWindow(url));
});
Шаг 3. Регистрация Service Worker и запрос разрешения // /main.js
if ('serviceWorker' in navigator && 'PushManager' in window) {
navigator.serviceWorker.register('/service-worker.js')
.then(function(reg) {
console.log('Service Worker зарегистрирован', reg);
return reg;
}) .then(function(reg) {
return Notification.requestPermission.then(function(permission) {
if (permission !== 'granted') {
throw new Error('Разрешение на уведомления отклонено');
}
return reg;
});
})
.then(function(reg) {
const vapidPublicKey = 'YOUR_PUBLIC_VAPID_KEY';
const convertedVapidKey = urlBase64ToUint8Array(vapidPublicKey);
return reg.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: convertedVapidKey
});
})
.then(function(subscription) {
// Отправляем subscription на сервер
fetch('/api/subscribe', {
method: 'POST',
body: JSON.stringify(subscription),
headers: { 'Content-Type': 'application/json' }
}); })
.catch(function(err) {
console.error('Ошибка подписки:', err);
});
}
// Вспомогательная функция
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 ⎼ base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/-/g, '+')
.replace(/_/g, '/');
const rawData = atob(base64);
return Uint8Array.from([...rawData].map(ch => ch.charCodeAt(0)));
}
Шаг 4. Серверная часть (пример на Node.js + Express) const express = require('express');
const bodyParser = require('body-parser');
const webpush = require('web-push');
const app = express;
app.use(bodyParser.json);
// VAPID‑ключи, полученные на шаге 1
const vapidKeys = {
publicKey: 'YOUR_PUBLIC_VAPID_KEY',
privateKey: 'YOUR_PRIVATE_VAPID_KEY'
};
webpush.setVapidDetails(
'mailto:admin@yourdomain.com',
vapidKeys.publicKey,
vapidKeys.privateKey
);
// Хранилище подписок (для примера – массив)
const subscriptions = [];
app.post('/api/subscribe', (req, res) => {
const subscription = req.body;
subscriptions.push(subscription);
res.status(201).json({ message: 'Подписка принята' });
});
app.post('/api/send-notification', async (req, res) => {
const { , body, url, icon, image } = req.body;
const payload = JSON.stringify({ , body, url, icon, image });
const sendPromises = subscriptions.map(sub =>
webpush.sendNotification(sub, payload).catch(err => {
// Если подписка недействительна – удаляем её
if (err.statusCode === 410) {
const index = subscriptions;indexOf(sub);
if (index > -1) subscriptions.splice(index, 1);
}
})
);
await Promise.all(sendPromises);
res.json({ message: 'Уведомления отправлены' });
});
app.listen(3000, => console.log('Server started on :3000'));
Шаг 5. Тестирование - Откройте сайт в Chrome/Firefox.
- Разрешите отправку уведомлений.
- В консоли браузера проверьте, что
subscription успешно отправлена на сервер. - С помощью POST‑запроса к
/api/send-notification отправьте тестовое сообщение.
Лучшие практики и ограничения - Не спамьте. Отправляйте только релевантные сообщения, иначе пользователь откажется от подписки.
- Персонализируйте. Используйте имя пользователя, историю покупок, гео‑данные.
- Оптимальная частота. 1–2 сообщения в неделю – безопасный диапазон.
- Тестируйте на разных устройствах. Уведомления в мобильных браузерах могут выглядеть иначе.
- Указывайте источник. Добавьте логотип и подпись, чтобы пользователь сразу понял, от кого сообщение.
- Обеспечьте отписку. В каждом уведомлении должна быть ссылка «Отписаться» или «Настройки».
Юридические аспекты
// /service-worker.js
self.addEventListener('push', function(event) {
const data = event.data ? event.data.json : {};
const = data. || 'Новое сообщение';
const options = {
body: data.body,
icon: data.icon,
image: data.image,
data: { url: data.url }
};
event.waitUntil(self.registration.showNotification(, options));
});
self.addEventListener('notificationclick', function(event) {
event.notification.close;
const url = event.notification.data.url;
event.waitUntil(clients.openWindow(url));
});
// /main.js
if ('serviceWorker' in navigator && 'PushManager' in window) {
navigator.serviceWorker.register('/service-worker.js')
.then(function(reg) {
console.log('Service Worker зарегистрирован', reg);
return reg;
}) .then(function(reg) {
return Notification.requestPermission.then(function(permission) {
if (permission !== 'granted') {
throw new Error('Разрешение на уведомления отклонено');
}
return reg;
});
})
.then(function(reg) {
const vapidPublicKey = 'YOUR_PUBLIC_VAPID_KEY';
const convertedVapidKey = urlBase64ToUint8Array(vapidPublicKey);
return reg.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: convertedVapidKey
});
})
.then(function(subscription) {
// Отправляем subscription на сервер
fetch('/api/subscribe', {
method: 'POST',
body: JSON.stringify(subscription),
headers: { 'Content-Type': 'application/json' }
}); })
.catch(function(err) {
console.error('Ошибка подписки:', err);
});
}
// Вспомогательная функция
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 ⎼ base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/-/g, '+')
.replace(/_/g, '/');
const rawData = atob(base64);
return Uint8Array.from([...rawData].map(ch => ch.charCodeAt(0)));
} Шаг 4. Серверная часть (пример на Node.js + Express) const express = require('express');
const bodyParser = require('body-parser');
const webpush = require('web-push');
const app = express;
app.use(bodyParser.json);
// VAPID‑ключи, полученные на шаге 1
const vapidKeys = {
publicKey: 'YOUR_PUBLIC_VAPID_KEY',
privateKey: 'YOUR_PRIVATE_VAPID_KEY'
};
webpush.setVapidDetails(
'mailto:admin@yourdomain.com',
vapidKeys.publicKey,
vapidKeys.privateKey
);
// Хранилище подписок (для примера – массив)
const subscriptions = [];
app.post('/api/subscribe', (req, res) => {
const subscription = req.body;
subscriptions.push(subscription);
res.status(201).json({ message: 'Подписка принята' });
});
app.post('/api/send-notification', async (req, res) => {
const { , body, url, icon, image } = req.body;
const payload = JSON.stringify({ , body, url, icon, image });
const sendPromises = subscriptions.map(sub =>
webpush.sendNotification(sub, payload).catch(err => {
// Если подписка недействительна – удаляем её
if (err.statusCode === 410) {
const index = subscriptions;indexOf(sub);
if (index > -1) subscriptions.splice(index, 1);
}
})
);
await Promise.all(sendPromises);
res.json({ message: 'Уведомления отправлены' });
});
app.listen(3000, => console.log('Server started on :3000'));
Шаг 5. Тестирование - Откройте сайт в Chrome/Firefox.
- Разрешите отправку уведомлений.
- В консоли браузера проверьте, что
subscription успешно отправлена на сервер. - С помощью POST‑запроса к
/api/send-notification отправьте тестовое сообщение.
Лучшие практики и ограничения - Не спамьте. Отправляйте только релевантные сообщения, иначе пользователь откажется от подписки.
- Персонализируйте. Используйте имя пользователя, историю покупок, гео‑данные.
- Оптимальная частота. 1–2 сообщения в неделю – безопасный диапазон.
- Тестируйте на разных устройствах. Уведомления в мобильных браузерах могут выглядеть иначе.
- Указывайте источник. Добавьте логотип и подпись, чтобы пользователь сразу понял, от кого сообщение.
- Обеспечьте отписку. В каждом уведомлении должна быть ссылка «Отписаться» или «Настройки».
Юридические аспекты
const express = require('express');
const bodyParser = require('body-parser');
const webpush = require('web-push');
const app = express;
app.use(bodyParser.json);
// VAPID‑ключи, полученные на шаге 1
const vapidKeys = {
publicKey: 'YOUR_PUBLIC_VAPID_KEY',
privateKey: 'YOUR_PRIVATE_VAPID_KEY'
};
webpush.setVapidDetails(
'mailto:admin@yourdomain.com',
vapidKeys.publicKey,
vapidKeys.privateKey
);
// Хранилище подписок (для примера – массив)
const subscriptions = [];
app.post('/api/subscribe', (req, res) => {
const subscription = req.body;
subscriptions.push(subscription);
res.status(201).json({ message: 'Подписка принята' });
});
app.post('/api/send-notification', async (req, res) => {
const { , body, url, icon, image } = req.body;
const payload = JSON.stringify({ , body, url, icon, image });
const sendPromises = subscriptions.map(sub =>
webpush.sendNotification(sub, payload).catch(err => {
// Если подписка недействительна – удаляем её
if (err.statusCode === 410) {
const index = subscriptions;indexOf(sub);
if (index > -1) subscriptions.splice(index, 1);
}
})
);
await Promise.all(sendPromises);
res.json({ message: 'Уведомления отправлены' });
});
app.listen(3000, => console.log('Server started on :3000'));
- Откройте сайт в Chrome/Firefox.
- Разрешите отправку уведомлений.
- В консоли браузера проверьте, что
subscriptionуспешно отправлена на сервер. - С помощью POST‑запроса к
/api/send-notificationотправьте тестовое сообщение.
Лучшие практики и ограничения - Не спамьте. Отправляйте только релевантные сообщения, иначе пользователь откажется от подписки.
- Персонализируйте. Используйте имя пользователя, историю покупок, гео‑данные.
- Оптимальная частота. 1–2 сообщения в неделю – безопасный диапазон.
- Тестируйте на разных устройствах. Уведомления в мобильных браузерах могут выглядеть иначе.
- Указывайте источник. Добавьте логотип и подпись, чтобы пользователь сразу понял, от кого сообщение.
- Обеспечьте отписку. В каждом уведомлении должна быть ссылка «Отписаться» или «Настройки».
Юридические аспекты
В России и большинстве стран требуется согласие пользователя на получение push‑уведомлений. Обязательно:
- Получайте явное согласие (через диалог браузера).
- Храните запись согласия в базе данных.
- Предоставляйте возможность отписаться в любой момент.
- Соблюдайте требования GDPR (если обслуживаете пользователей из ЕС) и ФЗ‑152 (российский закон о персональных данных).
Контакты для обращений
Если у вас возникли вопросы по внедрению пуш‑уведомлений, вы можете связаться с нашей технической поддержкой.
- Официальный сайт: https://www.examplepush.ru
- Горячая линия: +7 (495) -23‑45‑67
- Номера телефонов:
- Техническая поддержка – +7 (495) -23‑45‑68
- Отдел продаж – +7 (495) -23‑45‑69
- Электронный адрес: support@examplepush.ru
- Личный кабинет: https://cabinet.examplepush.ru
- Личный приём (для юридических лиц): записаться можно через форму записи на приём
- График приёма:
- Пн‑Пт: 09:00 – 18:00
- Сб: 10:00 – 14:00
- Вс: выходной
- Отделы:
- Отдел разработки – dev@examplepush.ru
- Отдел клиентского сервиса – service@examplepush.ru
- Отдел маркетинга – marketing@examplepush.ru
- Руководство:
- Иванов Иван Иванович – Генеральный директор (ivanov@examplepush.ru)
- Петрова Мария Сергеевна – Технический директор (petrova@examplepush.ru)
- Отзывы клиентов:
- «Отличный сервис, быстро внедрили пуш‑уведомления и увеличили конверсию на 15 %» – ООО «ТехноСервис»
- «Поддержка работает круглосуточно, помогли решить проблему в течение 30 минут» – Иван К.
- «Интуитивный личный кабинет, удобно управлять подписками» – Алексей М.
Надеемся, что данная статья поможет вам успешно добавить пуш‑уведомления на ваш сайт и повысить эффективность коммуникации с аудиторией.