Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
33gustavo33 opened this issue Sep 12, 2022 · 2 comments
Labels
back Envolve modificações no backend front Envolve modificações no frontend novo recurso Nova funcionalidade/recurso

Comments

@33gustavo33
Copy link
Contributor

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:

youtube.dropdown.mp4

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

@Rafatcb
Copy link
Collaborator

Rafatcb commented Jan 11, 2024

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

  • Relacionar quem enviou, quem recebeu e o motivo: Enxergo algumas notificações possíveis diferentes:
    • "O usuário A comentou na sua publicação B" - Tem quem enviou e o motivo.
    • "Sua publicação B recebeu 1 TabCoin" - Tem o motivo.
    • "Sua publicação B foi removida pela moderação" - Tem o motivo, que envolve um elemento "removido".
  • Enviar a mesma notificação para mais de um usuário: Futuramente teremos a possibilidade de seguir uma publicação, então mais de um usuário poderá receber a mesma notificação. Já devemos estruturar de forma a permitir isso.
  • Tolerância a atrasos: Podemos notificar em tempo real, mas não vejo problemas se a notificação atrasar alguns segundos. A princípio, me parece que até 1 minuto de atraso é tolerável. Isso ficará ruim se a pessoa ver a ação antes da notificação.
  • Marcar notificação como lida/não-lida: Comportamento similar ao de um e-mail na caixa de mensagens.
  • 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.
  • Quando ocorreu: Como armazenaremos um histórico, é importante saber quando foi que o evento gerador da notificação ocorreu.
  • Não duplicar: A mesma notificação deve ser enviada uma única vez, podendo ser consumida novamente pelo histórico.

Desejável

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

  • Notificação em tempo real.
  • Armazenamento de todas notificações "para sempre".
  • Poder desfazer a notificação, caso a ação seja desfeita.
  • Agrupamento de notificações quando possível. Ao invés do usuário receber várias notificações iguais, pode receber uma única notificação como "A, B e C comentaram na sua publicação X".

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 ?
  • ?: Não encontrei informações sobre.

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:

  • 808 cadastros.
  • 774 publicações.
  • 2.182 comentários.
  • 5.287 votos.

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
Copy link
Collaborator

  • 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
back Envolve modificações no backend front Envolve modificações no frontend novo recurso Nova funcionalidade/recurso
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants