📅 Suporte para sincronização de feed iCal no plugin de calendário Discourse (Importar de URLs .ics)

Eu reconstruí com sucesso minha instância do Discourse🥲


O plugin oficial discourse-calendar do Discourse já suporta exportação de .ics, o que é extremamente útil para compartilhar eventos do Discourse externamente. No entanto, muitas comunidades — particularmente nas áreas de educação, governo ou empresarial — dependem de feeds iCal externos para publicar informações de eventos (por exemplo, de Moodle, Office365, Google Calendar ou plataformas CMS institucionais).

Atualmente, não há uma maneira integrada de importar ou sincronizar de fontes .ics. Isso limita o uso do Discourse como um verdadeiro centro de calendário para comunidades que já publicam cronogramas importantes em outros lugares.


:sparkles: Proposta de Funcionalidade

Adicionar sincronização de feed iCal (importação de URLs .ics) ao plugin Discourse Calendar.

:white_check_mark: Funcionalidades Principais

  • Configurar uma URL de feed .ics para uma categoria ou tópico habilitado para calendário.
  • Importar eventos automaticamente para o calendário, correspondendo ao feed .ics.
  • Especificar um intervalo de sincronização (por exemplo, horário, diário) ou permitir um botão manual de “Sincronizar agora”.
  • Usar o campo UID do evento para evitar duplicatas e atualizar eventos modificados de forma limpa.

:wrench: Configurações Opcionais

  • Marcar ou rotular eventos importados para mostrar sua origem externa.
  • Escolher entre:
    • Sincronização unidirecional (externo → Discourse apenas),
    • ou sincronização bidirecional (editar eventos sincronizados dentro do Discourse envia alterações de volta — escopo futuro).
  • Suportar múltiplos feeds .ics por calendário, mesclados em uma única visualização.
  • Indicação visual de que um evento está sincronizado externamente (por exemplo, “Sincronizado de: outlook.university.edu”).

:teacher: Casos de Uso

Setor Exemplo de Caso de Uso
Educação Preencher automaticamente fóruns de alunos com datas de semestre, horários de cursos, exames, etc.
Governo Sincronizar eventos oficiais de CMS ou intranet para um calendário comunitário público
Empresas Espelhar calendários de reuniões internas (do Outlook ou Google Calendar)
Fóruns de Eventos Integrar listas de palestrantes ou cronogramas de sessões de provedores externos

:locked_with_key: Segurança e Privacidade

  • Os feeds de calendário podem suportar acesso público ou tokenizado (por exemplo, URL contendo um token secreto).
  • Suporte para OAuth2 / Autenticação Básica pode ser uma melhoria futura.

:paperclip: Relacionado


:counterclockwise_arrows_button: Compatibilidade

Este recurso não exigiria discourse-events (agora obsoleto) e funcionaria nativamente com a sintaxe existente do Discourse Calendar ([calendar] e [event]). Os usuários ainda poderiam criar eventos nativos do Discourse manualmente — a sincronização iCal apenas aumentaria esses calendários.


Adoraria saber se esta funcionalidade já está no roteiro — ou se outros na comunidade a achariam valiosa.

Obrigado!

5 curtidas

@Ethsim2 Essa seria uma funcionalidade enorme, e eu tenho investigado a viabilidade dela agora que o Discourse está mudando para o FullCalendar.

@sam vinculou diretamente ao fullcalendar.io recentemente, e descobriu que o FullCalendar agora tem suporte de primeira classe para feeds .ics através de seu sistema oficial de plugins — então o trabalho pesado já foi feito pela biblioteca.


:rocket: Proposta: Habilitar Sincronização de Feed .ics Usando Suporte Nativo do FullCalendar

Com a próxima integração do FullCalendar v6 ao Discourse, a base está pronta para suportar essa funcionalidade nativamente.

O plugin @fullcalendar/icalendar do FullCalendar (com ical.js por baixo dos panos) permite carregar feeds .ics públicos assim:

new Calendar(calendarEl, {
  plugins: [dayGridPlugin, iCalendarPlugin],
  events: {
    url: 'https://example.com/my-calendar.ics',
    format: 'ics'
  }
});

É só isso para renderizar um feed iCal remoto na interface do calendário — sem parsing personalizado, apenas conectar e usar.


:hammer_and_wrench: Passos de Implementação Sugeridos para o Discourse

  1. Adicionar @fullcalendar/icalendar e ical.js ao plugin (assim que o FullCalendar v6 estiver totalmente implementado).
  2. Adicionar uma configuração de administrador/plugin (ou opção por categoria) para inserir uma ou mais URLs .ics.
  3. No lado do cliente, renderizar o feed na visualização do calendário.
  4. (Opcional) Implementar sincronização do lado do servidor que:
    • Busca periodicamente o feed
    • Analisa eventos novos/atualizados
    • Cria ou atualiza tópicos do Discourse associados

:counterclockwise_arrows_button: Frequência de Sincronização

É importante notar que o tratamento padrão de .ics do FullCalendar apenas busca o feed na carga inicial do calendário no navegador. Isso significa:

  • Não há atualização diária ou automática.
  • Os usuários verão uma cópia desatualizada, a menos que recarreguem ou acionem manualmente uma atualização.
  • Não há persistência — se um usuário navegar para longe, os dados do feed desaparecem.

Para tornar isso verdadeiramente útil, o Discourse idealmente deveria:

  • Executar um job do Sidekiq diário (ou agendado) que busca o feed do lado do servidor.
  • Armazenar em cache os eventos analisados para renderização consistente entre os usuários.
  • Opcionalmente, vincular eventos a tópicos ou criar novos para integração completa.

Isso permitiria um comportamento de sincronização adequado e reviveria uma funcionalidade chave anteriormente tratada pelo plugin do Angus — mas usando uma base limpa e de fácil manutenção.


:white_check_mark: Benefícios

  • Integra perfeitamente feeds .ics do Google Calendar, Outlook, iCal, etc.
  • Torna o Discourse um consumidor de calendário, não apenas um exportador.
  • Ótimo para fóruns comunitários, grupos de estudantes, eventos cívicos, etc.
  • Construído inteiramente com recursos suportados do FullCalendar — JavaScript personalizado mínimo necessário.

Adoraria ver isso implementado agora que o plugin de calendário está recebendo atenção novamente. Fico feliz em ajudar a testar ou contribuir para um proof-of-concept.

Desculpe @Halden42, mas estou um pouco confuso com sua postagem.

Entendo que o Discourse está “consertando as bases” do sistema de calendário com a atualização do FullCalendar, mas estou preocupado com o tempo que levaria para preencher manualmente um calendário agitado. Eu uso a interface gráfica do Discourse todos os dias para tudo, e ter que duplicar conteúdo fora da interface é inaceitável.

Notei que você mencionou um recurso que sinto muita falta do plugin do Angus, que acredito capturar o ponto principal de sincronizar eventos no Discourse:

Esta parte seria essencial para o meu caso de uso.

Mas estou preocupado porque você não entrou em detalhes sobre como isso poderia ser implementado. Você poderia explicar como isso se pareceria na prática? O Discourse criaria um tópico por evento? Ele suportaria atualizações ou exclusões se o calendário de origem mudar?

Essa é a parte em que eu mais precisaria confiar, e ainda não tenho certeza de quão perto estamos disso.

Obrigado novamente por sua resposta detalhada.

2 curtidas

Obrigado @Ethsim2 — essa é uma ótima continuação, e acho que sua preocupação é exatamente a certa: não se trata apenas de exibir eventos de um feed .ics, mas sim de incorporá-los ao Discourse de forma útil e rastreável.

Quando eu disse “vincular eventos a tópicos ou criar novos”, eu estava imaginando uma configuração semelhante à forma como o plugin do Angus costumava funcionar — onde cada evento no feed corresponderia a um tópico no Discourse, e as atualizações no feed seriam refletidas no tópico ao longo do tempo.


No momento, o FullCalendar por si só não persiste eventos — ele apenas os renderiza a partir do feed no carregamento da página. Portanto, se um evento desaparecer do feed (ou seja, for cancelado ou excluído externamente), ele simplesmente desaparecerá silenciosamente da interface do calendário.

Mas isso não é suficiente para a maioria dos fluxos de trabalho baseados em fóruns, especialmente onde as postagens de eventos são usadas para discussões, confirmações de presença ou anúncios.


Eis o que eu proporia para isso:

Em vez de remover o tópico quando um evento desaparece do feed, o Discourse poderia:

  • Manter o tópico no lugar
  • Adicionar uma linha no topo como:
    ⚠️ Este evento foi cancelado ou removido do calendário de origem.
  • Opcionalmente, bloquear ou deslistar o tópico, dependendo da preferência do administrador

Isso preservaria o contexto, permitiria respostas e tornaria o cancelamento visível — sem excluir nada. Tecnicamente, isso é bastante viável: apenas sinalizaríamos que o UID não existe mais no arquivo .ics e atualizaríamos o status do tópico correspondente.


Então, sim — embora o FullCalendar em si não gerencie esse status, o Discourse poderia lidar com isso na camada de sincronização. O trabalho que busca o feed (por exemplo, via Sidekiq) acompanharia quais eventos existiam e não existem mais, e marcaria o tópico correspondente de acordo.

Se houver interesse suficiente das pessoas, acho que poderíamos desenvolver uma especificação adequada. Não seria difícil prototipar.

1 curtida

Obrigado pela resposta atenciosa @Halden42 — isso esclarece muito.

O que você descreveu aqui…

…é exatamente o caso de uso principal que tenho tentado recuperar desde que saí do plugin do Angus. Para mim, a parte mais crítica não é apenas renderizar eventos visualmente, mas sincronizar um calendário externo ao vivo no fórum, onde cada evento tem um tópico, e as alterações nesse evento (por exemplo, cancelamento, reagendamento) são refletidas nesse tópico ao longo do tempo.

Eu ficaria feliz com um modelo de sincronização unidirecional para começar — somente leitura de .ics para Discourse — e até mesmo uma detecção básica de atualizações cobriria 90% dos meus casos de uso. Um status de “cancelado” exibido no tópico do evento se ele for removido do feed seria ideal também, em vez de excluir o tópico completamente.

Se houver um local preferencial para propor uma especificação para isso — talvez depois que a atualização do FullCalendar se estabilizar — eu estaria muito interessado em contribuir ou testar.

Obrigado novamente.

1 curtida

Mantemos vários calendários do Office 365 — cada um com seu próprio feed .ics — para diferentes tipos de reuniões: Comitê Executivo, Sessões de Engajamento Público, Grupos de Trabalho Internos e assim por diante. Esses feeds já são bem estruturados e mantidos regularmente por funcionários e equipes administrativas.

O que precisamos urgentemente é uma maneira de:

  • Assinar diferentes feeds .ics por categoria (por exemplo, um feed por tipo de reunião)
  • Criar automaticamente um novo tópico na categoria Discourse correspondente
  • Validar que o tópico acabe na categoria correta, semelhante a como o plugin de Angus nos permitiu filtrar por tags ou outros metadados
  • Refletir alterações (hora, título) no tópico se o evento do calendário for atualizado
  • Opcionalmente sinalizar ou fechar o tópico se o evento for cancelado ou removido do feed

Para conselhos como o nosso, as categorias são usadas para gerenciar a visibilidade granular — algumas reuniões são privadas (por exemplo, executivas ou de planejamento), outras são públicas. Um tópico arquivado incorretamente pode resultar na exposição de dados sensíveis, portanto, a validação em nível de categoria é um item essencial.

Gostaríamos de ver algo assim suportado oficialmente na próxima reformulação do FullCalendar. Isso reduziria significativamente o trabalho manual e tornaria o Discourse muito mais viável como uma única fonte de verdade para coordenação e transparência de reuniões.

Sou estudante de farmácia nos EUA, e nossa universidade fornece todas as nossas programações de rotação, exames e práticas através de um portal de calendário. As URLs dos feeds não terminam em .ics, mas quando eu as abro no Chrome, elas imediatamente baixam um arquivo .ics válido. Portanto, são definitivamente feeds iCal padrão — apenas com uma estrutura de URL diferente.

Até recentemente, eu usava o plugin do Angus, e ele lidava com esses feeds perfeitamente. Cada evento gerava um tópico, e eu podia rotear diferentes feeds para diferentes categorias (por exemplo, “Terapêutica”, “Rotações”, “Exames”), o que ajudava nosso grupo de estudos a se manter organizado.

Mas, desde que o erro recente this.router quebrou o plugin, tive que desativá-lo — como o Ethsim2 — e agora não há uma maneira fácil de manter nosso calendário sincronizado.

Se o plugin oficial pudesse suportar:

  • Feeds .ics de entrada (mesmo que a URL não termine em .ics)
  • Criação de tópicos com direcionamento de categoria
  • Configuração específica do feed (por exemplo, um feed → uma categoria)
  • Detecção de atualizações e tratamento opcional de cancelamento de eventos

…isso tornaria o Discourse uma ferramenta poderosa para colaboração acadêmica. Estava funcionando perfeitamente para nós antes do plugin quebrar — então adoraria ver essa funcionalidade implementada nativamente.

Ficarei feliz em compartilhar um URL de calendário de exemplo privadamente, se isso ajudar nos testes.

isso também se aplica ao Office 365, entendo que muitas universidades nos EUA usam esse ecossistema

sim, eu uso esse ecossistema :+1:

2 curtidas

não listado porque originalmente era um usuário e seus fantoches. mas as contas foram mescladas e agora o tópico está confuso, pois o usuário parece estar postando de um lado para o outro consigo mesmo.