Um dos pontos problemáticos ao trabalhar com push na Web é que acionar uma mensagem push é extremamente "violino". Para acionar uma mensagem push, um aplicativo precisa fazer uma solicitação POST para um push após o envio por push da Web protocolo. Para usar push em todas você precisa usar VAPID (ou chaves do servidor de aplicativos), que basicamente requer a definição de um cabeçalho com um valor que comprove seu aplicativo pode enviar uma mensagem a um usuário. Para enviar dados com uma mensagem push, eles precisam estar criptografados e cabeçalhos específicos precisam ser adicionados para que o navegador possa descriptografar a mensagem corretamente.
O principal problema com o acionamento de push é que, se você encontra um problema, é difícil diagnosticar o problema. Isso está melhorando com o tempo e a compatibilidade com os navegadores, mas está longe de ser fácil. Para Por isso, recomendamos o uso de uma biblioteca para lidar com a criptografia, formatação o gatilho da mensagem push.
Se você realmente quiser saber o que as bibliotecas estão fazendo, vamos abordar na próxima seção. Por enquanto, vamos aprender a gerenciar assinaturas e usar uma biblioteca push da Web existente para fazer as solicitações de push.
Nesta seção, vamos usar o web-push Node biblioteca. Outros idiomas terão diferenças, mas não serão muito diferentes. Estamos analisando o Node, já que é JavaScript e deve ser a mais acessível para os leitores.
Vamos seguir estas etapas:
- Envie uma assinatura para nosso back-end e salve-a.
- Recuperar assinaturas salvas e acionar uma mensagem push.
Salvando inscrições
Salvar e consultar PushSubscription
s em um banco de dados varia de acordo com
sua escolha de linguagem do lado do servidor e banco de dados, mas pode ser útil ver
um exemplo de como isso pode ser feito.
Na página da Web de demonstração, o PushSubscription
é enviado ao nosso back-end fazendo uma solicitação POST simples:
function sendSubscriptionToBackEnd(subscription) {
return fetch('/api/save-subscription/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(subscription),
})
.then(function (response) {
if (!response.ok) {
throw new Error('Bad status code from server.');
}
return response.json();
})
.then(function (responseData) {
if (!(responseData.data && responseData.data.success)) {
throw new Error('Bad response from server.');
}
});
}
O servidor Express em nossa demonstração tem um listener de solicitação correspondente para os
Endpoint /api/save-subscription/
:
app.post('/api/save-subscription/', function (req, res) {
Nessa rota, validamos a inscrição apenas para garantir que a solicitação esteja correta e não esteja cheia de lixo:
const isValidSaveRequest = (req, res) => {
// Check the request body has at least an endpoint.
if (!req.body || !req.body.endpoint) {
// Not a valid subscription.
res.status(400);
res.setHeader('Content-Type', 'application/json');
res.send(
JSON.stringify({
error: {
id: 'no-endpoint',
message: 'Subscription must have an endpoint.',
},
}),
);
return false;
}
return true;
};
Se a assinatura for válida, precisamos salvá-la e retornar um Resposta JSON:
return saveSubscriptionToDatabase(req.body)
.then(function (subscriptionId) {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({data: {success: true}}));
})
.catch(function (err) {
res.status(500);
res.setHeader('Content-Type', 'application/json');
res.send(
JSON.stringify({
error: {
id: 'unable-to-save-subscription',
message:
'The subscription was received but we were unable to save it to our database.',
},
}),
);
});
Esta demonstração usa o nedb para armazenar as assinaturas, é um um banco de dados simples baseado em arquivos, mas você pode usar o banco de dados que quiser. Estamos usando isso apenas como não exige configuração. Para produção, é melhor usar algo mais confiável. (tendo a fique com o bom e velho MySQL.)
function saveSubscriptionToDatabase(subscription) {
return new Promise(function (resolve, reject) {
db.insert(subscription, function (err, newDoc) {
if (err) {
reject(err);
return;
}
resolve(newDoc._id);
});
});
}
Como enviar mensagens push
Quando se trata de enviar uma mensagem push, precisamos de algum evento para acionar o processo de
enviar uma mensagem aos usuários. Uma abordagem comum é criar uma página
de administração que permita
configura e aciona a mensagem push. Mas você pode criar um programa para ser executado localmente ou
outra abordagem que permita acessar a lista de PushSubscription
s e executar o código para
acionar a mensagem push.
Nossa demonstração tem um "gostei" de administrador que permite acionar um push. Como é apenas uma demonstração, página pública.
Apresentarei todas as etapas envolvidas no funcionamento da demonstração. Estes são os bebês para que todos possam acompanhar, incluindo iniciantes no Node.
Quando discutimos a inscrição de um usuário, abordamos a adição de um applicationServerKey
à
subscribe()
opções. Vamos precisar dessa chave privada no back-end.
Na demonstração, esses valores são adicionados ao nosso app Node dessa forma (código chato, eu sei, mas só quero que não há mágica):
const vapidKeys = {
publicKey:
'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
privateKey: 'UUxI4O8-FbRouAevSmBQ6o18hgE4nSG3qwvJTfKc-ls',
};
Em seguida, precisamos instalar o módulo web-push
para o servidor de nó:
npm install web-push --save
Em seguida, no script do Node, precisamos do módulo web-push
.
assim:
const webpush = require('web-push');
Agora podemos começar a usar o módulo web-push
. Primeiro, precisamos informar o módulo web-push
sobre
as chaves do servidor de aplicativos. Lembre-se de que elas também são conhecidas como chaves VAPID, porque esse é o nome
da especificação.
const vapidKeys = {
publicKey:
'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
privateKey: 'UUxI4O8-FbRouAevSmBQ6o18hgE4nSG3qwvJTfKc-ls',
};
webpush.setVapidDetails(
'mailto:web-push-book@gauntface.com',
vapidKeys.publicKey,
vapidKeys.privateKey,
);
Observe que também incluímos um arquivo "mailto:" fio. Essa string precisa ser um URL ou um protocolo mailto endereço de e-mail. Essa informação será enviada para o serviço de push da web como parte do a solicitação para acionar um push. Isso é feito para que, se um serviço de push na Web precisar para entrar em contato com o remetente, essa pessoa tem algumas informações para permitir isso.
Com isso, o módulo web-push
está pronto para uso. A próxima etapa é acionar uma mensagem push.
A demonstração usa o painel de administração fictício para acionar mensagens push.
Clicando em "Acionar mensagem push" vai fazer uma solicitação POST para /api/trigger-push-msg/
,
que é o sinal para que nosso back-end envie mensagens push, então criamos a rota
expresso para este endpoint:
app.post('/api/trigger-push-msg/', function (req, res) {
Quando essa solicitação é recebida, pegamos as assinaturas do banco de dados e para cada um deles, uma mensagem push é acionada.
return getSubscriptionsFromDatabase().then(function (subscriptions) {
let promiseChain = Promise.resolve();
for (let i = 0; i < subscriptions.length; i++) {
const subscription = subscriptions[i];
promiseChain = promiseChain.then(() => {
return triggerPushMsg(subscription, dataToSend);
});
}
return promiseChain;
});
A função triggerPushMsg()
pode então usar a biblioteca web-push para enviar uma mensagem ao
que forneceu uma assinatura.
const triggerPushMsg = function (subscription, dataToSend) {
return webpush.sendNotification(subscription, dataToSend).catch((err) => {
if (err.statusCode === 404 || err.statusCode === 410) {
console.log('Subscription has expired or is no longer valid: ', err);
return deleteSubscriptionFromDatabase(subscription._id);
} else {
throw err;
}
});
};
A chamada para webpush.sendNotification()
vai retornar uma promessa. Se o
for enviada, a promessa vai ser resolvida e há
não precisamos fazer nada. Se a promessa for rejeitada, você precisará examinar
porque informa se PushSubscription
ainda está
válidas ou não.
Para determinar o tipo de erro de um serviço de push, é melhor observar o código de status. Erro as mensagens variam entre os serviços de push, e algumas são mais úteis que outras.
Neste exemplo, ele verifica os códigos de status 404
e 410
, que são os códigos de status HTTP para
"Não encontrado" e "Desaparecido". Se recebermos um desses, significa que a assinatura expirou
ou não é mais válida. Nesses cenários, precisamos remover as assinaturas do nosso banco de dados.
No caso de algum outro erro, apenas throw err
, que fará a promessa retornada pelo
triggerPushMsg()
rejeitado.
Abordaremos alguns dos outros códigos de status na próxima seção quando examinarmos o envio do protocolo com mais detalhes.
Depois de percorrer as assinaturas, precisamos retornar uma resposta JSON.
.then(() => {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ data: { success: true } }));
})
.catch(function(err) {
res.status(500);
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({
error: {
id: 'unable-to-send-messages',
message: `We were unable to send messages to all subscriptions : ` +
`'${err.message}'`
}
}));
});
Abordamos as principais etapas de implementação:
- Criar uma API para enviar inscrições da nossa página da Web para o nosso back-end para poder salvá-los em um banco de dados.
- Crie uma API para acionar o envio de mensagens push (neste caso, uma API chamada a partir do painel de administração fictício).
- Recuperar todas as assinaturas do nosso back-end e enviar uma mensagem para cada assinatura com um dos métodos web-push bibliotecas.
Independentemente do back-end (Node, PHP, Python, etc.), as etapas para implementar push são sejam iguais.
Em seguida, o que exatamente essas bibliotecas de push da Web estão fazendo por nós?
A seguir
- Visão geral das notificações push na Web
- Como funciona o Push
- Como inscrever um usuário
- UX de permissão
- Como enviar mensagens com bibliotecas push da Web
- Protocolo push na Web
- Como processar eventos de push
- Como exibir uma notificação
- Comportamento das notificações
- Padrões de notificação comuns
- Perguntas frequentes sobre notificações push
- Problemas comuns e como informar bugs