Рубрики
Без рубрики

Web Push-уведомление Полный стек Приложение с узлом JS RESTFLAY API

Web Push Notification Web Service используется для вещания коротких сообщений для ваших подписанных пользователей, не надо третьим сторонним сервисами для уведомления Web Push. Это полностью независимая управляемая веб-служба Web Push.

Автор оригинала: Saurabh Kashyap.

Позвольте мне сказать вам, почему Web Push-уведомление необходим для любого веб-приложения.

Это помогает в трансляции коротких сообщений с подписчиком веб-приложения и, а также, а также поможет поддержать взаимодействие пользователя с вашим приложением, чтобы уведомить каждые подписчики, это действительно трудно любую организацию отправить уведомление по электронной почте для короткого обмена сообщениями или трансляцией Сообщения, такие как предложения и обновления коротких сообщений, а также повышает стоимость серверных операций, чтобы решение было Web Push-уведомление .it Помогите вашу максимальную доступность пост.

Позвольте мне сказать вам, как это работает.

Web-push-how-working.png

Сервисский работник является главным ключевым ингредиатом и рыцарями этой функции, которая устанавливает в клиент Broswer и запускает интенсивность в качестве приложения после включения в браузере в качестве сервисного работника, который регулярно отправляет запрос к серверу поставщика, и попросить любое новое событие, а также отвечать на любое новое событие, а не отвечать на клиент, если на сервере происходит какое-либо новое событие, которое он всплывает сообщение, как

POPUP-Notify.png.

Нажмите на кнопку «Разрешить работник службы» Начните устанавливать в браузере клиента и отправить запрос на обещание для подписчика с Публичный ключ Vapib и проверьте на сервере, чтобы пользователь уже подписаться уведомление или нет, если он уже подписывается, он отправил обратный запрос с ложным утверждением, в противном случае сервер отправил истинный запрос. И сделал это это. Теперь давайте приходим к разделу кодирования и как реализовать эту функцию в вашем приложении без использования сторонних платных услуг и использовании до тех пор, пока вы.

Шаг 1

Нужна предварительная преследование, которые перечислены ниже, если у вас нет в вашей системе. Перыефы:

  1. IDE Визуальный студийный код
  2. Oddjs
  3. Портить
  4. Монгодб
  5. Почтальон

Теперь давайте начнем с следующего шага

Шаг 2

Откройте свою IDE Визуальный студийный код И чем запустить команду в интегрированном терминале с вашей IDE

git init

Чем добавьте все поля или пропустить, как хотите, и, чем снова запустить команду, чтобы включить все зависимость с

npm install express web-push body-parser mongoose q --save

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

git-init-commands.png
touch server.js

И снова нужно создать три папки в том же каталоге проекта по командам, как показано ниже

Add-new-file-app.png
mkdir config
cd config 
touch keys.js
touch keys_prod.js
touch keys_dev.js
create-config-dir.png
mkdir model
cd model
touch subscribers_model.js
create-model-dir.png
mkdir router
cd router
touch push.js
touch subscriber.js
touch index.js
Create-Router-Dir.png

Теперь все основные папки и файлы создаются и в этом проекте мы переходим к следующим запчагам кодирования на следующем шаге.

Шаг 3

Структура файла этого проекта ниже

|
|
|________________________./config
|                         |
|                         |____keys_prod.js
|                         |____keys_dev.js
|                         |____keys.js
|
|________________________./public
|                         |
|                         |____index.html
|                         |____sw.js
|                         |____app.js
|
|________________________./model
|                         |
|                         |____subscribers_model.js
|
|________________________./router
|                         |
|                         |____push.js
|                         |____subscribe.js
|
|___________________________server.js

Теперь начните с создания модели базы данных для базы данных MongoDB. Так что теперь я использую Мангуст ODM ORM Библиотека для Монгодб который уже установлен в проекте

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const SubscriberSchema = new Schema({
   endpoint: String,
   keys: Schema.Types.Mixed,
   createDate: {
       type: Date,
       default: Date.now
   }
});

mongoose.model('subscribers', SubscriberSchema, 'subscribers');

Так что теперь давайте приедем в файл конфигурации

cd config

и чем откройте файл keys.js, который уже создан в этой папке

if (process.env.NODE_ENV === 'production') {
    module.exports = require('./keys_prod');
} else {
    module.exports = require('./keys_dev');
}

И обновите файл Keys.js с помощью этого кода, фактически этот код предоставляет адрес аутентификации базы данных Smart Switch между производственным и разработкой. Перед обновлением Keys_Prod.js и файл keys_dev.js генерируют кнопки VAPID для браузера клиентского устройства и между запуском сервера. Используя эту команду

./node_modules/.bin/web-push generate-vapid-keys

Вы увидите, что две клавиши сгенерированы, один является частным, а другой – открытый ключ, который отображается ниже. Скопируйте как клавиши и вставьте в Keys_dev.js или на конфигурации сервера Encireoment Envireoment.

create-vapib-key.png
module.exports = {
//i used mlab database for fast and realiable pace development enviroment
   mongoURI: 'mongodb://web-push:webpush123@ds213053.mlab.com:13053/web-push',
   privateKey: 'ayTIBl3f0gcI-koFq-ZXPxSR4qicC0GcMNHA1dpHaj0' || process.env.VAPID_PRIVATE_KEY,
   publicKey: 'BK3Q7j8fcGFws03RiU5XakzDJ7KGEiRhdIX2H5U8eNmhhkdHT_j0_SD09KL96aFZOH_bsjr3uRuQPTd77SRP3DI' || process.env.VAPID_PUBLIC_KEY
}

process.env.vapid_public_key или Process.env.vapid_private_key Понять в качестве конфигурации среды выполнения среды производства сервера.

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

Итак, теперь все важные настройки структуры приложений сделают сейчас начать кодирование в server.js который существует на вершине папки проекта

const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');

require('./model/subscribers_model');

// Load Routes
const index = require('./router');

// subscriber route load push
const push = require('./router/push');

// subscriber route load
const subscribe = require('./router/subscribe');
// Load Keys
const keys = require('./config/keys');
//Handlebars Helpers

mongoose.Promise = global.Promise;

// Mongoose Connect
mongoose.connect(keys.mongoURI, {
        useMongoClient: true
    })
    .then(() => console.log('MongoDB Connected'))
    .catch(err => console.log(err));

//Create Express middleware
const app = express();
app.set('trust proxy', true);
// parse application/json
app.use(bodyParser.json());
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({
    extended: true
}));

// Set static folder
app.use(express.static(path.join(__dirname, 'public')));
// app.set('views', __dirname + '/public/js');

// Set global vars
app.use((req, res, next) => {
    res.locals.user = req.user || null;
    next();
});



// Use Routes

app.use('/', index);
app.use('/subscribe', subscribe);
app.use('/push', push);


// catch 404 and forward to error handler
app.use(function (req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function (err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});


const port = process.env.PORT || 3000;

app.listen(port, () => {
    console.log(`Server started on port ${port}`);
});

И теперь приходите к папке Маршрутизатор Сначала начните с подписки .js, который уже создан командой. Откройте этот файл на новой вкладке, а затем вставьте этот код в свой Подписки.js файл

const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const Subscription = mongoose.model('subscribers');

//Post route of subscribe url is as http://host:3000/subscribe
router.post('/', (req, res) => {
    const subscriptionModel = new Subscription(req.body);
    subscriptionModel.save((err, subscription) => {
        if (err) {
            console.error(`Error occurred while saving subscription. Err: ${err}`);
            res.status(500).json({
                error: 'Technical error occurred'
            });
        } else {
            res.json({
                data: 'Subscription saved.'
            });
        }
    });
});

// fixed the error get request for this route with a meaningful callback
router.get('/', (req, res) => {
            res.json({
                data: 'Invalid Request Bad'
            });
});
module.exports = router;

Сохраните изменения и перейти к следующему файлу push.js и вставить этот код в уже созданный push.js Файл по командной строке

const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const Subscription = mongoose.model('subscribers');
const q = require('q');
const webPush = require('web-push');
const keys = require('./../config/keys');
//Post route of push url is as http://host:3000/push
router.post('/', (req, res) => {
    const payload = {
        title: req.body.title,
        message: req.body.message,
        url: req.body.url,
        ttl: req.body.ttl,
        icon: req.body.icon,
        image: req.body.image,
        badge: req.body.badge,
        tag: req.body.tag
    };

    Subscription.find({}, (err, subscriptions) => {
        if (err) {
            console.error(`Error occurred while getting subscriptions`);
            res.status(500).json({
                error: 'Technical error occurred'
            });
        } else {
            let parallelSubscriptionCalls = subscriptions.map((subscription) => {
                return new Promise((resolve, reject) => {
                    const pushSubscription = {
                        endpoint: subscription.endpoint,
                        keys: {
                            p256dh: subscription.keys.p256dh,
                            auth: subscription.keys.auth
                        }
                    };

                    const pushPayload = JSON.stringify(payload);
                    const pushOptions = {
                        vapidDetails: {
                            subject: "http://example.com",
                            privateKey: keys.privateKey,
                            publicKey: keys.publicKey
                        },
                        TTL: payload.ttl,
                        headers: {}
                    };
                    webPush.sendNotification(
                        pushSubscription,
                        pushPayload,
                        pushOptions
                    ).then((value) => {
                        resolve({
                            status: true,
                            endpoint: subscription.endpoint,
                            data: value
                        });
                    }).catch((err) => {
                        reject({
                            status: false,
                            endpoint: subscription.endpoint,
                            data: err
                        });
                    });
                });
            });
            q.allSettled(parallelSubscriptionCalls).then((pushResults) => {
                console.info(pushResults);
            });
            res.json({
                data: 'Push triggered'
            });
        }
    });
});

// fixed the error get request for this route with a meaningful callback
router.get('/', (req, res) => {
    res.json({
        data: 'Invalid Request Bad'
    });
});
module.exports = router;

Опять же убедитесь, что этот код изменяется в вашем push.js Файл с этим кодом теперь снова перейдите к index.js Файл и обновите код с этим следующим

const express = require('express');
const router = express.Router();

router.get('/', (req, res) => {
    res.locals.metaTags = {
        title: 'web-push-api',
        description: 'Web Push Notification Full Stack Application With Node Js Restful API',
        keywords: 'Web Push Notification Full Stack Application With Node Js Restful API',
        generator: '0.0.0.1',
        author: 'Saurabh Kashyap'
    };
    res.json({
        status: 'ok',
        message: 'Server is running'
    });
});

module.exports = router;

и сохранить изменения в файле Server.js с вышеуказанным кодом в server.js Команда файла и запуска Нажмите эту команду запуска

node server.js

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

Server-rocing-command.jpg

Нажмите еще раз закройте приложение после проверки приложения. Так что теперь выполняется серверный код на стороне приложения. Теперь давайте начнем с следующего шага

Шаг 4.

Создайте новую папку с публичным именем и создайте файл с этими командами, как показано ниже

mkdir public
cd public
touch index.html
touch sw.js
touch app.js
create-public-dir.png
create-package-dir-files.png

Теперь давайте подчеркиваем базовый HTML-код в index.html файл





   
   
   
   Web-Push Application with Restful Api


   

This is a web-push notification example

Сохраните этот код и перейдите к следующему файлу app.js Где сервисный работник браузера проверяет и зарегистрируйте рабочую услугу в браузере, а также отправлять запрос AJAX в API приложения http://Хост: 3000/Подписаться Для подписки на службу в браузере клиента.

let isSubscribed = false;
let swRegistration = null;
let applicationKey = "put_your_public_key_here";


// Url Encription
function urlB64ToUint8Array(base64String) {
    const padding = '='.repeat((4 - base64String.length % 4) % 4);
    const base64 = (base64String + padding)
        .replace(/\-/g, '+')
        .replace(/_/g, '/');

    const rawData = window.atob(base64);
    const outputArray = new Uint8Array(rawData.length);

    for (let i = 0; i < rawData.length; ++i) {
        outputArray[i] = rawData.charCodeAt(i);
    }
    return outputArray;
}

// Installing service worker
if ('serviceWorker' in navigator && 'PushManager' in window) {
    console.log('Service Worker and Push is supported');

    navigator.serviceWorker.register('sw.js')
        .then(function (swReg) {
            console.log('service worker registered');

            swRegistration = swReg;

            swRegistration.pushManager.getSubscription()
                .then(function (subscription) {
                    isSubscribed = !(subscription === null);

                    if (isSubscribed) {
                        console.log('User is subscribed');
                    } else {
                        swRegistration.pushManager.subscribe({
                                userVisibleOnly: true,
                                applicationServerKey: urlB64ToUint8Array(applicationKey)
                            })
                            .then(function (subscription) {
                                console.log(subscription);
                                console.log('User is subscribed');

                                saveSubscription(subscription);

                                isSubscribed = true;
                            })
                            .catch(function (err) {
                                console.log('Failed to subscribe user: ', err);
                            })
                    }
                })
        })
        .catch(function (error) {
            console.error('Service Worker Error', error);
        });
} else {
    console.warn('Push messaging is not supported');
}

// Send request to database for add new subscriber
function saveSubscription(subscription) {
    let xmlHttp = new XMLHttpRequest();
    //put here API address
    xmlHttp.open("POST", "/subscribe");
    xmlHttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    xmlHttp.onreadystatechange = function () {
        if (xmlHttp.readyState != 4) return;
        if (xmlHttp.status != 200 && xmlHttp.status != 304) {
            console.log('HTTP error ' + xmlHttp.status, null);
        } else {
            console.log("User subscribed to server");
        }
    };

    xmlHttp.send(JSON.stringify(subscription));
}

И теперь сохраните все файлы и начните кодирование для обслуживания, давайте начнем сейчас

let notificationUrl = '';
//notification registered feature for getting update automatically from server api
self.addEventListener('push', function (event) {
    console.log('Push received: ', event);
    let _data = event.data ? JSON.parse(event.data.text()) : {};
    notificationUrl = _data.url;
    event.waitUntil(
        self.registration.showNotification(_data.title, {
            body: _data.message,
            icon: _data.icon,
            tag: _data.tag
        })
    );
});

//notification url redirect event click
self.addEventListener('notificationclick', function (event) {
    event.notification.close();

    event.waitUntil(
        clients.matchAll({
            type: "window"
        })
        .then(function (clientList) {
            if (clients.openWindow) {
                return clients.openWindow(notificationUrl);
            }
        })
    );
});

NAD Сохранить все код. АГА..!! Выполнено. Так что теперь мы должны проверить, работает ли он или нет. Поэтому снова запустите команду в вашем терминале

node server.js

открыть URL: http://localhot: 3000 в вашем браузере сейчас

puh-popup.png.

После нажатия Allo, вы видите сообщение, как в консоли браузера

и сохранить весь код. АГА..!! Выполнено. Так что теперь мы должны проверить, работает ли он или нет. Поэтому снова запустите команду в вашем терминале

node server.js

открыть URL: http://localhot: 3000 в вашем браузере сейчас

puh-popup.png.

После нажатия позволяю увидеть сообщение в вашем браузере консоль

и открыть почтальон с для отправки Push-сообщения для подписчиков.

Console-actuct.png.png.
Post-message.png.png.png

Нажимать пример отправки

{
    "title": "StoryBook",
    "message": "welcome friends",
    "url": "https://new-storybook.herokuapp.com",
    "ttl": 36000,
    "icon": "https://cdn3.iconfinder.com/data/icons/happy-x-mas/501/santa15-128.png",
    "badge": "https://cdn3.iconfinder.com/data/icons/happy-x-mas/501/santa15-128.png",
    "data":"Hello New World",
    "tag": "Book Story"
}
Final-route.png.png.png.

Исходный код здесь Считаю, что вы успешно сделаны!