filipedeschamps / tabnews.com.br

Conteúdos para quem trabalha com Programação e Tecnologia.
https://tabnews.com.br
GNU General Public License v3.0
5.03k stars 369 forks source link

Criar o sistema de notificação via API e interface web (em complemento ao email) #738

Open 33gustavo33 opened 1 year ago

33gustavo33 commented 1 year ago

Hoje temos o email para notificações, mas não seria interessante ter um endpoint na api pra isso também? Algo como GET api/v1/notifications E isso retornaria as notificações que o usuário tem.

Porque?

A maior utilidade ao meu ver seria criar um menu de notificações no frontend, parecido com o do youtube:

https://user-images.githubusercontent.com/50342600/189706254-ff576c25-42ee-472f-995f-fa1edbcd38a0.mp4

Também poderia ser usado pra push notifications, etc..

Rafatcb commented 6 months ago

Nunca implementei um sistema de notificações, então dei uma pesquisada e tentei elaborar quais são as nossas necessidades para conseguir progredir com o issue, principalmente porque isso é uma dependência para outras melhorias. Eu precisaria fazer esse estudo de qualquer forma para eu mesmo, então resolvi compartilhar aqui, até porque alguém pode saber mais do assunto e contribuir.

Separei as características entre o que é necessário e o que é desejável, assim fica fácil decidir o que deixar de lado durante a implementação dependendo do custo e complexidade.

Das referências que li sobre o assunto, vale compartilhar o artigo Designing a notification system - Tan Nguyen e também essa thread do Reddit que contém possíveis soluções para alguns problemas que menciono no próximo tópico. Podem até ler antes de continuar o meu comentário, se preferirem.

Necessário

Desejável

Já falei sobre alguns desses pontos no tópico anterior, mas vou listar novamente para ficar fácil de encontrar.

Solução própria ou de terceiros?

Custos

Temos uma ideia dos custos na época do lançamento do TabNews, mas sem nada específico para estimarmos com base em armazenamento ou demora das consultas:

Serviço Valor
Vercel ~$ 80,00 / mês~
Cloudflare $ 20,00 / mês
PostgreSQL (homologação) $ 15,00 / mês
PostgreSQL (produção) $150,00 / mês
Mailgun $35,00 / mês
Upstash $48,00 / mês
Gmail $6,00 / mês
Total $ 274,00 / mês

Nas minhas pesquisas, encontrei várias soluções de terceiros sugeridas para esse tipo de problema, então precisei ler como elas resolvem isso e qual o custo envolvido.

  1. AWS SNS. Pelo o que li, não parece que atende nosso cenário, mas posso estar enganado.
  2. Ably.
  3. Novu.
  4. Knock.
  5. MagicBell.
Ably Novu Knock MagicBell
Custo/mês Grátis Grátis Grátis Grátis
Limite/mês 6 milhões de mensagens 10 mil eventos 10 mil notificações 100 usuários ativos/mês
Próximo custo/mês US$ 2,50/milhão US$ 25 US$ 250 US$ 99
Próximo limite/mês - 20 mil eventos 50 mil notificações 2.000 usuários ativos
Persistência até 72 horas 30 dias / 90 dias Ilimitado ?

Dos quatro serviços mencionados acima, três (Novu, Knock e MagicBell) fornecem soluções de UI e se vendem como otimizadores de tempo para implantar o sistema de notificação. O esquema de precificação do MagicBell me faria excluí-lo da lista (por usuário ativo/mês), e o preço do "próximo custo" do Knock é muito alto. Sobra o Novu, mas vou mencionar novamente o Ably mais para frente.

Implementação própria

Além da estrutura do banco de dados, similar ao que foi mencionado nos links de referência (Medium e Reddit), no backend teríamos a responsabilidade de:

  1. Salvar a notificação.
  2. Enviar a notificação para o cliente, assim que criada.
  3. Endpoint para obter as notificações.

No frontend, precisaríamos implementar a interface. O GitHub possui uma página de notificações, mas não uma "caixa simples" de notificações (como o Stack Overflow, Reddit e Facebook). Para fazermos isso, provavelmente precisaríamos usar o Popover, que está em draft. Na documentação não fica claro se ele é o melhor componente para esse cenário.

Fiquei em dúvida se poderíamos usar server-sent events para notificar o cliente em tempo real. Nunca usei SSE e os exemplos que vi não me deram a certeza, principalmente considerando o ambiente serverless. Aqui a Vercel não menciona o SSE como alternativa ao WebSocket, mas indica o Ably.

Viabilidade

Criar algumas tabelas no banco de dados e ter o controle próprio me parece muito bom: não teremos uma dependência extra e nem um custo financeiro por essa nova dependência.

Para saber se conseguiríamos lidar com isso criando as tabelas (como mencionado nos links de referência e adaptando para nossas necessidades) com bom desempenho, podemos fazer alguns testes na casa de milhões de notificações localmente. Seria interessante fazer o teste também em ambiente de homologação e entender os custos.

Pegando um mês inteiro pela página /status, e sem o efeito dos feriados de fim de ano, escolhi de 15/11 até 15/12. Nesse período, tivemos:

Se considerarmos uma notificação por comentário (como acontece com e-mails hoje) e uma por voto recebido, teríamos 7.469 notificações. Isso ainda deixaria uma certa margem para os 10 mil eventos gratuitos do Novu, onde a próxima faixa é 20 mil eventos por US$ 25.

Temos 3 opções:

  1. 100% solução de terceiro.
  2. 100% solução interna.
  3. Solução mista. Exemplo: Ably para o envio de eventos e o resto próprio; ou o Novu para cuidar de tudo, migrando para uma solução própria quando necessário.

Imagino que, para a opção que envolve migração, precisaríamos armazenar as notificações desde o início no banco de dados para conseguirmos exibir para os usuários as notificações antigas (que é desejável, mas não obrigatório, e talvez nem precise armazenar todas notificações, só alguns tipos). Mesmo assim, nós poderíamos aproveitar o componente de UI do Novu e a parte de notificar o cliente. E numa "versão beta" poderia descartar a parte de nós salvarmos as notificações, tendo o Novu.

O que vocês acham?

Qual opção parece fazer mais sentido para vocês? Já precisaram implementar um sistema parecido e tem alguma informação para acrescentar aqui?

aprendendofelipe commented 2 months ago
  • Armazenamento de notificações por pelo menos 30 dias: O ideal seria não ter restrição de tempo, mas não sei da complexidade em manter um bom desempenho assim. A rede Stack Exchange, por exemplo, armazena todas as notificações que vão para o Inbox, e a rede tem vários sites, usuários e tipos de notificação. ...
  • Armazenamento de todas notificações "para sempre".

Não vejo razão para armazenar as notificações por tempo indeterminado. Acho que as visualizadas podem ser excluídas após um certo tempo e/ou quantidade.

  • Poder desfazer a notificação, caso a ação seja desfeita.

Também acho que devem ser excluídas se o que elas estiverem notificando deixar de fazer sentido.