Soporte para sincronización de feed iCal en el plugin de calendario de Discourse (importar desde URLs .ics)

He reconstruido con éxito mi instancia de Discourse :smiling_face_with_tear:


El plugin oficial discourse-calendar de Discourse ya admite la exportación de .ics, lo cual es extremadamente útil para compartir eventos de Discourse externamente. Sin embargo, muchas comunidades —especialmente en educación, gobierno o empresas— dependen de fuentes de iCal externas para publicar información de eventos (por ejemplo, de Moodle, Office365, Google Calendar o plataformas CMS institucionales).

Actualmente, no hay una forma integrada de importar o sincronizar desde fuentes .ics. Esto limita el uso de Discourse como un verdadero centro de calendario para las comunidades que ya publican horarios importantes en otros lugares.


:sparkles: Propuesta de Funcionalidad

Añadir sincronización de fuentes iCal (importación desde URLs .ics) al plugin Discourse Calendar.

:white_check_mark: Funcionalidades Principales

  • Configurar una URL de fuente .ics para una categoría o tema habilitado para calendario.
  • Importar eventos automáticamente al calendario, coincidiendo con la fuente .ics.
  • Especificar un intervalo de sincronización (por ejemplo, cada hora, diario) o permitir un botón manual de “Sincronizar ahora”.
  • Utilizar el campo UID del evento para evitar duplicados y actualizar eventos modificados de forma limpia.

:wrench: Configuraciones Opcionales

  • Etiquetar o marcar los eventos importados para mostrar su origen externo.
  • Elegir entre:
    • Sincronización unidireccional (externo → Discourse solamente),
    • o sincronización bidireccional (editar eventos sincronizados dentro de Discourse y que los cambios se reflejen de vuelta — alcance futuro).
  • Soporte para múltiples fuentes .ics por calendario, fusionadas en una sola vista.
  • Indicación visual de que un evento está sincronizado externamente (por ejemplo, “Sincronizado desde: outlook.university.edu”).

:teacher: Casos de Uso

Sector Caso de Uso de Ejemplo
Educación Rellenar automáticamente foros de estudiantes con fechas de trimestre, horarios de cursos, exámenes, etc.
Gobierno Sincronizar eventos oficiales desde el CMS o intranet a un calendario comunitario público
Empresas Reflejar calendarios de reuniones internas (desde Outlook o Google Calendar)
Foros de eventos Integrar listas de ponentes o horarios de sesiones de proveedores externos

:locked_with_key: Seguridad y Privacidad

  • Las fuentes de calendario podrían admitir acceso público o tokenizado (por ejemplo, URL que contiene un token secreto).
  • El soporte para OAuth2 / Basic Auth podría ser una mejora futura.

:paperclip: Relacionado

  • discourse-calendar
  • La exportación .ics ya está soportada — ¡un gran precedente!
  • Necesidad similar discutida en hilos antiguos, por ejemplo, aquí

:counterclockwise_arrows_button: Compatibilidad

Esta funcionalidad no requeriría discourse-events (ahora obsoleto), y funcionaría de forma nativa con la sintaxis existente de Discourse Calendar ([calendar] y [event]). Los usuarios aún podrían crear eventos nativos de Discourse manualmente — la sincronización iCal simplemente aumentaría estos calendarios.


Me encantaría saber si esta funcionalidad ya está en el roadmap — o si otros en la comunidad la encontrarían valiosa.

¡Gracias!

5 Me gusta

@Ethsim2 Esta sería una gran característica, y he estado investigando su viabilidad ahora que Discourse está cambiando a FullCalendar.

@sam enlazó directamente a fullcalendar.io recientemente, y resulta que FullCalendar ahora tiene soporte de primera clase para feeds .ics a través de su sistema de plugins oficial — así que el trabajo pesado ya está hecho por la librería.


:rocket: Propuesta: Habilitar Sincronización de Feeds .ics Usando Soporte Nativo de FullCalendar

Con la próxima integración de FullCalendar v6 en Discourse, se sientan las bases para soportar esta característica de forma nativa.

El plugin de FullCalendar @fullcalendar/icalendar (con ical.js internamente) te permite cargar feeds .ics públicos de la siguiente manera:

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

Eso es todo lo que se necesita para renderizar un feed iCal remoto en la interfaz de usuario del calendario — sin análisis personalizado, solo conectar y usar.


:hammer_and_wrench: Pasos de Implementación Sugeridos para Discourse

  1. Añadir @fullcalendar/icalendar y ical.js al plugin (una vez que FullCalendar v6 esté completamente implementado).
  2. Añadir una configuración de administrador/plugin (o una opción por categoría) para introducir una o más URLs de .ics.
  3. En el lado del cliente, renderizar el feed en la vista del calendario.
  4. (Opcional) Implementar sincronización del lado del servidor que:
    • Obtenga periódicamente el feed
    • Analice eventos nuevos/actualizados
    • Cree o actualice temas de Discourse asociados

:counterclockwise_arrows_button: Frecuencia de Sincronización

Es importante notar que el manejo predeterminado de .ics de FullCalendar solo obtiene el feed en la carga inicial del calendario en el navegador. Eso significa:

  • No hay actualización diaria o automática.
  • Los usuarios verán una copia desactualizada a menos que recarguen o activen manualmente una actualización.
  • No hay persistencia — si un usuario navega a otra página, los datos del feed se pierden.

Para que esto sea verdaderamente útil, Discourse idealmente debería:

  • Ejecutar un trabajo de Sidekiq diario (o programado) que obtenga el feed del lado del servidor.
  • Almacenar en caché los eventos analizados para una visualización consistente entre usuarios.
  • Opcionalmente, vincular eventos a temas o crear nuevos para una integración completa.

Esto permitiría un comportamiento de sincronización adecuado y reviviría una característica clave manejada previamente por el plugin de Angus — pero utilizando una base limpia y mantenible.


:white_check_mark: Beneficios

  • Integra sin problemas feeds .ics de Google Calendar, Outlook, iCal, etc.
  • Convierte a Discourse en un consumidor de calendarios, no solo un exportador.
  • Genial para foros comunitarios, grupos de estudiantes, eventos cívicos, etc.
  • Construido completamente sobre características soportadas de FullCalendar — se necesita un mínimo de JavaScript personalizado.

Me encantaría ver esto implementado ahora que el plugin de calendario está recibiendo atención nuevamente. Estaré encantado de ayudar a probarlo o contribuir a una prueba de concepto.

Lo siento @Halden42, pero estoy un poco confundido con tu publicación.

Entiendo que Discourse está “arreglando los cimientos” del sistema de calendario con la actualización de FullCalendar, pero me preocupa cuánto tiempo me llevaría completar manualmente un calendario ocupado. Uso la GUI de Discourse todos los días para todo, y tener que duplicar contenido fuera de la interfaz es inaceptable.

Noté que mencionaste una característica que realmente echo de menos del plugin de Angus, que creo que captura el punto principal de sincronizar eventos en Discourse:

Esta parte sería esencial para mi caso de uso.

Pero me preocupa porque no entraste en detalles sobre cómo se podría implementar. ¿Podrías explicar cómo se vería eso en la práctica? ¿Crearía Discourse un tema por evento? ¿Admitiría actualizaciones o eliminaciones si el calendario de origen cambia?

Esa es la parte en la que más necesitaría confiar, y todavía no estoy seguro de lo cerca que estamos de ella.

Gracias de nuevo por tu detallada respuesta.

2 Me gusta

Gracias @Ethsim2, esa es una excelente continuación, y creo que tu preocupación es exactamente la correcta: no se trata solo de mostrar eventos de un feed .ics, sino de incrustarlos en Discourse de una manera útil y rastreable.

Cuando dije “vincular eventos a temas o crear nuevos”, imaginé una configuración similar a como solía funcionar el plugin de Angus, donde cada evento en el feed correspondería a un tema en Discourse, y las actualizaciones del feed se reflejarían en el tema con el tiempo.


En este momento, FullCalendar por sí solo no persiste los eventos, solo los renderiza desde el feed al cargar la página. Por lo tanto, si un evento desaparece del feed (es decir, se ha cancelado o eliminado externamente), simplemente se desvanece silenciosamente de la interfaz de usuario del calendario.

Pero eso no es suficiente para la mayoría de los flujos de trabajo basados en foros, especialmente donde las publicaciones de eventos se utilizan para discusiones, confirmaciones de asistencia o anuncios.


Esto es lo que propondría para eso:

En lugar de eliminar el tema cuando un evento desaparece del feed, Discourse podría:

  • Mantener el tema en su lugar
  • Añadir una línea en la parte superior como:
    ⚠️ Este evento ha sido cancelado o eliminado del calendario de origen.
  • Opcionalmente bloquear o deslistar el tema, según la preferencia del administrador.

Esto preservaría el contexto, permitiría respuestas y haría visible la cancelación, sin eliminar nada. Técnicamente, esto es bastante factible: simplemente marcaríamos que el UID ya no existe en el archivo .ics y actualizaríamos el estado del tema correspondiente.


Así que sí, aunque FullCalendar en sí mismo no gestiona ese estado, Discourse podría manejarlo en la capa de sincronización. El trabajo que recupera el feed (por ejemplo, a través de Sidekiq) haría un seguimiento de qué eventos existían antes y ya no lo hacen, y marcaría el tema correspondiente en consecuencia.

Si suficientes personas están interesadas en esto, creo que podríamos desarrollar una especificación adecuada. No sería difícil de prototipar.

1 me gusta

Gracias por la reflexiva respuesta @Halden42 — esto aclara mucho.

Lo que describiste aquí…

…es exactamente el caso de uso principal que he estado intentando recuperar desde que dejé el plugin de Angus. Para mí, la parte más crítica no es solo renderizar visualmente los eventos, sino sincronizar un calendario externo en vivo en el foro, donde cada evento tiene un tema, y los cambios en ese evento (por ejemplo, cancelación, reprogramación) se reflejan en ese tema con el tiempo.

Estaría contento con un modelo de sincronización unidireccional para empezar — solo lectura de .ics a Discourse — e incluso una detección básica de actualizaciones cubriría el 90% de mis casos de uso. Un estado de “cancelado” que se muestre en el tema del evento si se elimina del feed sería ideal también, en lugar de eliminar el tema por completo.

Si hay un lugar preferido para proponer una especificación para esto — quizás una vez que la actualización de FullCalendar se estabilice — estaría muy interesado en contribuir o probar.

Gracias de nuevo.

1 me gusta

Mantenemos varios calendarios de Office 365 —cada uno con su propio feed .ics— para diferentes tipos de reuniones: Comité Ejecutivo, Sesiones de Participación Pública, Grupos de Trabajo Internos, etc. Estos feeds ya están bien estructurados y son mantenidos regularmente por los secretarios y equipos de administración.

Lo que necesitamos urgentemente es una forma de:

  • Suscribirse a diferentes feeds .ics por categoría (por ejemplo, un feed por tipo de reunión)
  • Crear automáticamente un nuevo tema en la categoría de Discourse correspondiente
  • Validar que el tema termine en la categoría correcta, de forma similar a como el plugin de Angus nos permitía filtrar por etiquetas u otros metadatos
  • Reflejar los cambios (hora, título) en el tema si el evento del calendario se actualiza
  • Opcionalmente marcar o cerrar el tema si el evento se cancela o se elimina del feed

Para ayuntamientos como el nuestro, las categorías se utilizan para gestionar la visibilidad granular: algunas reuniones son privadas (por ejemplo, ejecutivas o de planificación), otras son públicas. Un tema mal archivado podría dar lugar a la exposición de datos sensibles, por lo que la validación a nivel de categoría es imprescindible.

Nos encantaría ver algo como esto soportado oficialmente en la próxima revisión de FullCalendar. Reduciría significativamente el trabajo manual y haría que Discourse fuera mucho más viable como una única fuente de verdad para la coordinación y transparencia de las reuniones.

Soy un estudiante de farmacia en los EE. UU., y nuestra universidad proporciona todos nuestros horarios de rotación, exámenes y prácticas a través de un portal de calendario. Las URL de los feeds no terminan en .ics, pero cuando las abro en Chrome, descargan inmediatamente un archivo .ics válido. Así que definitivamente son feeds iCal estándar, solo que con una estructura de URL diferente.

Hasta hace poco, usaba el plugin de Angus, y manejaba estos feeds perfectamente. Cada evento generaba un tema, y podía dirigir diferentes feeds a diferentes categorías (por ejemplo, “Terapéutica”, “Rotaciones”, “Exámenes”), lo que ayudaba a nuestro grupo de estudio a mantenerse organizado.

Pero desde que el reciente error this.router rompió el plugin, he tenido que deshabilitarlo —como Ethsim2— y ahora no hay una forma fácil de mantener nuestro calendario sincronizado.

Si el plugin oficial pudiera soportar:

  • Feeds .ics entrantes (incluso si la URL no termina en .ics)
  • Creación de temas con segmentación por categoría
  • Configuración específica del feed (por ejemplo, un feed → una categoría)
  • Detección de actualizaciones y manejo opcional de cancelación de eventos

…eso haría de Discourse una herramienta poderosa para la colaboración académica. Estaba funcionando perfectamente para nosotros antes de que el plugin se rompiera, así que me encantaría ver esta funcionalidad implementada de forma nativa.

Estaré encantado de compartir una URL de calendario de muestra de forma privada si eso ayuda con las pruebas.

esto también se aplica a Office 365, entiendo que muchas universidades en los EE. UU. utilizan ese ecosistema

sí, uso ese ecosistema :+1:

2 Me gusta

no listado porque originalmente era un usuario y sus cuentas secundarias. pero las cuentas se fusionaron y ahora el tema es confuso ya que el usuario parece estar publicando de un lado a otro consigo mismo.