Criando notificações via API

Oi, uma pergunta rápida: é possível enviar notificações aos usuários via API? (ou de outra forma).
Na documentação, encontrei como obter as notificações do usuário e como marcá-las como lidas, mas não como enviar (POST) novas. Se não for possível, imagino que sempre haja a opção de usar mensagens privadas.
Agradeço qualquer informação sobre isso. Obrigado.

Acho que seria necessário um plugin. Que tipo de notificação você deseja? Pode descrever seu caso de uso?

Normalmente, substituir as notificações por e-mail de um serviço externo pelas notificações do Discourse. O serviço seria oferecido gratuitamente aos membros (*). Isso permitiria centralizar tudo no Discourse e criar um incentivo para que os usuários acessem (regularmente) o fórum. Essa era a ideia que eu tinha em mente. Não tenho certeza se faz sentido ou não, ou se há falhas no raciocínio. Estou aberto a todas as sugestões e críticas.

[ (*): Membros = participantes do fórum. Pelo menos pessoas registradas no fórum. Ainda resta ver se haverá um nível mínimo de participação ou confiança exigido, ou se o registro é suficiente. ]

O plugin receberia as informações e acionaria as notificações no Discourse? As notificações podem ser feitas (mais facilmente) por meio de um plugin?

Posso imaginar um plugin que adicionasse uma rota e permitisse enviar uma carga com o ID do usuário (ou endereço de e-mail), uma URL e um título, o que criaria uma notificação. Não acho que seja possível fazer isso sem um plugin, mas não examinei o código com tanta atenção.

Comecei ontem a considerar adicionar notificações a um plugin que estou desenvolvendo, então não estou muito familiarizado com o funcionamento.

Estou planejando um plugin semelhante, centrando as notificações do meu site (não por e-mail) no Discourse, para as quais você pode se inscrever via MessageBus e ter uma configuração central de notificações push.

O que estou planejando é apenas ter um endpoint personalizado para criar notificações personalizadas; ao ver esses trechos, acho que é viável.

Para criar uma notificação personalizada:

Para personalizar como o item da notificação é exibido na lista de notificações:
https://github.com/discourse/discourse-code-review/blob/master/assets/javascripts/discourse/widgets/code-review-commit-approved-notification-item.js.es6

Se houvesse uma API principal para criar a notificação, acho que esse widget de item de notificação poderia ser feito em um componente de tema, o que seria ainda mais simples.

Não sei o quão mais complicado pode ser fazer isso, mas não faria sentido adicionar a criação de notificações diretamente à API? Talvez a equipe esteja disposta a fazer isso ou aberta a um PR (se alguém puder e estiver disposto a fazer isso)?

Ainda não está documentado, mas existe um endpoint da API de criação de notificação:

 POST /notifications(.:format) notifications#create {:format=>/(json|html|\*\/\*)/}

Você pode ser capaz de usar o tipo de notificação custom em vez de precisar criar o seu próprio.

Isso é ótimo! Obrigado.

Então, se entendi corretamente, com o endpoint, se houver necessidade de sobrescrever DefaultNotificationItem, ainda será necessário um plugin apenas para registrar o tipo de notificação adicional a ser usado em um widget personalizado?

Notification.types[:following] = 800

(da discourse-follow/plugin.rb at main · discourse/discourse-follow · GitHub)

Ao usar o tipo custom, ele será renderizado usando https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/app/widgets/custom-notification-item.js, então, para sobrescrever a url de destino, ainda será necessário um widget personalizado?

Vi um plugin sobrescrevendo “custom-notification-item” em um cenário semelhante. É seguro sobrescrever apenas a url quando houver algo específico em data e recorrer a this._super.url caso contrário?

Obrigado, @renato!

Aqui está o que consegui.

Notification.create!(
  notification_type: Notification.types[:custom],
  user_id: 1,
  topic_id: nil,
  post_number: nil,
  high_priority: true,
  data: {
    message: 'pfaffmanager.title',
    display_username: 'pfaffman',
    topic_title: 'my title'
  }.to_json
)

Vejo a notificação, mas, previsivelmente, (EDIT:) NADA acontece se eu clicar. Além disso (o que não era óbvio para mim até eu fazer isso), o message é uma I18n, não uma string arbitrária… O que eu gostaria é poder colocar a URL do modelo que a chamou.

Suponho que quis dizer que “nada” acontece?
Se você pudesse clicar e ser redirecionado para uma URL que você se juntou através da API, isso seria realmente incrível.

O DefaultNotificationItem cria um url automaticamente se você preencher data.badge_id, topic_id ou data.group_id.

Testei essa abordagem e funciona. Basta preencher data.url e usá-lo em um componente de tema:

  api.reopenWidget("custom-notification-item", {
      url(data) {
          return data.url || this._super(data);
      }
  })

Não consigo fazer isso funcionar…

POST https://XXX/notifications
Api-Key:XXX
Api-Username:system
Content-Type:application/json
Accept:application/json

{
    "notification_type":9,
    "user_id": 123,
    "post_number": 1,
    "topic_id": 956,
    "data": {
        "topic_title": "Test",
        "original_post_id": 2222,
        "original_post_type": 1,
        "original_username": "User.Name",
        "revision_number": 1,
        "display_username": "Text"
            }

}

Recebo como resposta:


{
  "errors": [
    "Data can't be blank"
  ],
  "error_type": "record_invalid"
}

Erro de formatação, mal-entendido? Ou estou perdendo algo em data?

Não consigo realmente fazer engenharia reversa disso pela web - Ou esta API é chamada em algum lugar?

Você precisa codificar o valor data.

por exemplo:

"data": "{\"topic_title\":\"Test\",\"original_post_id\":2222,\"original_post_type\":1,\"original_username\":\"User.Name\",\"revision_number\":1,\"display_username\":\"Text\"}"