📅 Поддержка синхронизации iCal-ленты в плагине Discourse Calendar (импорт по URL .ics)

Я успешно восстановил свой экземпляр Discourse :smiling_face_with_tear:


Официальный плагин discourse-calendar уже поддерживает экспорт в формате .ics, что крайне полезно для внешнего обмена событиями Discourse. Однако многие сообщества — особенно в сфере образования, государственных органов или крупных предприятий — полагаются на внешние iCal-каналы для публикации информации о событиях (например, из Moodle, Office365, Google Calendar или корпоративных CMS).

На данный момент не существует встроенного способа импорта или синхронизации из источников .ics. Это ограничивает использование Discourse в качестве полноценного календарного центра для сообществ, которые уже публикуют важные расписания в других местах.


:sparkles: Предложение по новой функции

Добавить синхронизацию iCal-каналов (импорт по URL .ics) в плагин календаря Discourse.

:white_check_mark: Основные функции

  • Настройка URL .ics-канала для категории или темы с поддержкой календаря.
  • Автоматический импорт событий в календарь в соответствии с .ics-каналом.
  • Возможность указать интервал синхронизации (например, ежечасно, ежедневно) или добавить кнопку ручной синхронизации «Синхронизировать сейчас».
  • Использование поля UID события для предотвращения дубликатов и корректного обновления изменённых событий.

:wrench: Дополнительные настройки

  • Добавление тегов или меток к импортированным событиям для отображения внешнего источника.
  • Выбор между:
    • Однонаправленной синхронизацией (только из внешнего источника в Discourse),
    • или двунаправленной синхронизацией (изменение синхронизированных событий внутри Discourse приводит к обновлению внешнего источника — перспектива на будущее).
  • Поддержка нескольких .ics-каналов в одном календаре с объединением в единое представление.
  • Визуальное отображение того, что событие синхронизировано из внешнего источника (например, «Синхронизировано из: outlook.university.edu»).

:teacher: Сценарии использования

Сектор Пример использования
Образование Автоматическое заполнение студенческих форумов датами семестра, расписанием занятий, экзаменами и т.д.
Государственные органы Синхронизация официальных событий из CMS или интранета с публичным календарём сообщества
Компании Отображение внутренних календарей встреч (из Outlook или Google Calendar)
Форумы мероприятий Интеграция списков спикеров или расписаний сессий от внешних провайдеров

:locked_with_key: Безопасность и конфиденциальность

  • Каналы календаря могут поддерживать публичный или токенизированный доступ (например, URL с секретным токеном).
  • Поддержка OAuth2 / базовой аутентификации может быть реализована как будущая доработка.

:paperclip: Ссылки


:counterclockwise_arrows_button: Совместимость

Эта функция не потребует discourse-events (теперь устаревший) и будет работать нативно с существующим синтаксисом календаря Discourse ([calendar] и [event]). Пользователи по-прежнему смогут вручную создавать нативные события Discourse — синхронизация iCal просто дополнит эти календари.


Буду рад узнать, находится ли эта функция уже в плане разработки, или же другие участники сообщества также считают её полезной.

Спасибо!

5 лайков

@Ethsim2 Это была бы отличная функция, и я сейчас изучаю её реализуемость в свете перехода Discourse на FullCalendar.

@sam недавно дал прямую ссылку на fullcalendar.io, и оказалось, что FullCalendar теперь имеет полноценную поддержку .ics-лент благодаря своей официальной системе плагинов — значит, основная работа уже выполнена самой библиотекой.


:rocket: Предложение: Включение синхронизации .ics-лент с использованием нативной поддержки FullCalendar

С предстоящей интеграцией FullCalendar v6 в Discourse, основа для реализации этой функции на уровне ядра уже заложена.

Плагин FullCalendar @fullcalendar/icalendar (с использованием ical.js «под капотом») позволяет загружать публичные .ics-ленты следующим образом:

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

Больше ничего не требуется, чтобы отобразить удалённый iCal-фид в интерфейсе календаря — никакого кастомного парсинга, просто подключи и работай.


:hammer_and_wrench: Предлагаемые шаги реализации для Discourse

  1. Добавить @fullcalendar/icalendar и ical.js в плагин (после полной интеграции FullCalendar v6).
  2. Добавить настройку администратора/плагина (или опцию для каждой категории) для ввода одного или нескольких .ics-URL.
  3. На стороне клиента отобразить ленту в представлении календаря.
  4. (Опционально) Реализовать серверную синхронизацию, которая:
    • Периодически запрашивает ленту
    • Парсит новые или обновлённые события
    • Создаёт или обновляет соответствующие темы Discourse

:counterclockwise_arrows_button: Частота синхронизации

Важно отметить, что стандартная обработка .ics в FullCalendar загружает ленту только при первоначальной загрузке календаря в браузере. Это означает:

  • Нет ежедневного или автоматического обновления.
  • Пользователи увидят устаревшую копию, если не перезагрузят страницу или не вызовут обновление вручную.
  • Нет сохранения данных — если пользователь перейдёт на другую страницу, данные ленты исчезнут.

Чтобы сделать это по-настоящему полезным, Discourse в идеале должен:

  • Запускать ежедневную (или по расписанию) задачу Sidekiq для загрузки ленты на стороне сервера.
  • Кэшировать распаршенные события для стабильного отображения у всех пользователей.
  • Опционально связывать события с темами или создавать новые для полной интеграции.

Это обеспечит корректное поведение синхронизации и вернёт ключевую функцию, ранее реализованную в плагине Ангуса, но на чистой и поддерживаемой основе.


:white_check_mark: Преимущества

  • Бесшовная интеграция .ics-лент из Google Calendar, Outlook, iCal и других.
  • Превращает Discourse в потребителя календарей, а не только в экспортёр.
  • Отлично подходит для форумов сообществ, студенческих групп, городских мероприятий и т.д.
  • Построено исключительно на поддерживаемых функциях FullCalendar — требуется минимальный кастомный JS.

Буду рад увидеть реализацию этой функции, особенно сейчас, когда плагин календаря снова в центре внимания. Готов помочь с тестированием или внести вклад в создание прототипа.

Извините, @Halden42, но я немного запутался в вашем сообщении.

Я понимаю, что Discourse «укрепляет фундамент» календарной системы с помощью обновления до FullCalendar, но меня беспокоит, сколько времени займёт ручное заполнение загруженного календаря. Я ежедневно использую графический интерфейс Discourse для всего, и необходимость дублировать контент вне интерфейса для меня неприемлема.

Я заметил, что вы упомянули функцию, которой мне очень не хватает в плагине Ангуса, и которая, на мой взгляд, отражает основную идею синхронизации событий с Discourse:

Эта часть критически важна для моего сценария использования.

Однако меня беспокоит, что вы не привели никаких деталей о том, как это может быть реализовано. Не могли бы вы объяснить, как это будет выглядеть на практике? Будет ли Discourse создавать одну тему на каждое событие? Будет ли поддерживаться обновление или удаление тем, если исходный календарь изменится?

Именно на эту часть мне больше всего нужно будет полагаться, и пока я не уверен, насколько мы близки к её реализации.

Ещё раз спасибо за ваш подробный ответ.

2 лайка

Спасибо @Ethsim2 — это отличный вопрос, и я считаю, что ваша озабоченность абсолютно обоснована: дело не только в отображении событий из .ics-ленты, а в интеграции их в Discourse полезным и отслеживаемым образом.

Когда я говорил о «связывании событий с темами или создании новых», я представлял себе настройку, похожую на то, как раньше работал плагин Ангуса: каждое событие в ленте соответствовало теме на Discourse, а обновления в ленте со временем отражались в теме.


Сейчас FullCalendar сам по себе не сохраняет события — он просто отображает их из ленты при загрузке страницы. Поэтому, если событие исчезает из ленты (то есть оно было отменено или удалено внешним источником), оно просто бесшумно пропадает из интерфейса календаря.

Но этого недостаточно для большинства рабочих процессов, основанных на форумах, особенно когда посты о событиях используются для обсуждений, подтверждения участия (RSVP) или объявлений.


Вот что я предлагаю для этого:

Вместо того чтобы удалять тему, когда событие исчезает из ленты, Discourse мог бы:

  • Оставить тему на месте
  • Добавить строку вверху, например:
    ⚠️ Это событие было отменено или удалено из исходного календаря.
  • При желании заблокировать тему или скрыть её из списка в зависимости от предпочтений администратора

Это позволит сохранить контекст, даст возможность отвечать и сделает отмену видимой — без удаления чего-либо. Технически это вполне реализуемо: нам нужно будет лишь пометить, что UID больше не существует в .ics-файле, и обновить статус соответствующей темы.


Так что да — хотя сам FullCalendar не управляет этим статусом, Discourse мог бы обрабатывать это на уровне синхронизации. Задача, которая загружает ленту (например, через Sidekiq), будет отслеживать, какие события существовали ранее, а каких больше нет, и соответствующим образом помечать тему.

Если этот подход заинтересует достаточно большое количество людей, я думаю, мы сможем разработать полноценную спецификацию. Создать прототип будет несложно.

1 лайк

Спасибо за вдумчивый ответ, @Halden42 — это проясняет многое.

То, что вы описали здесь…

…это именно тот основной сценарий использования, который я пытаюсь восстановить после отказа от плагина Ангуса. Для меня самое важное — не просто визуальное отображение событий, а синхронизация внешнего календаря с форумом в реальном времени, где каждое событие имеет свою тему, а изменения этого события (например, отмена или перенос) отражаются в этой теме со временем.

Меня устроила бы односторонняя синхронизация для начала — только чтение из .ics в Discourse — и даже простое обнаружение обновлений покрыло бы 90% моих сценариев использования. Идеально также было бы иметь статус «отменено» в теме события, если оно удалено из ленты, вместо того чтобы удалять тему полностью.

Если есть предпочтительное место для предложения спецификации этого — возможно, после стабилизации обновления FullCalendar — я был бы очень заинтересован внести свой вклад или провести тестирование.

Спасибо ещё раз.

1 лайк

Мы поддерживаем несколько календарей Office 365, каждый со своим .ics-фидом, для различных типов встреч: исполнительный комитет, сессии общественного взаимодействия, внутренние рабочие группы и так далее. Эти фиды уже хорошо структурированы и регулярно обновляются секретарями и административными командами.

Что нам срочно необходимо:

  • Подписка на разные .ics-фиды по категориям (например, один фид на тип встречи)
  • Автоматическое создание новой темы в соответствующей категории Discourse
  • Проверка того, что тема оказывается в правильной категории, аналогично тому, как плагин Angus позволял нам фильтровать по тегам или другим метаданным
  • Отражение изменений (время, заголовок) в теме при обновлении события календаря
  • Опциональная пометка или закрытие темы, если событие отменено или удалено из фидa

Для советов, подобных нашему, категории используются для управления детализированной видимостью — некоторые встречи закрыты (например, исполнительные или планирующие), другие открыты для публики. Неправильное размещение темы может привести к утечке конфиденциальных данных, поэтому проверка на уровне категории является обязательной.

Мы были бы рады, если бы такая функциональность была официально поддержана в предстоящем крупном обновлении FullCalendar. Это значительно сократит ручной труд и сделает Discourse гораздо более жизнеспособным в качестве единого источника правды для координации встреч и обеспечения прозрачности.

Я студент-фармацевт в США, и наш университет предоставляет все расписания ротаций, экзамены и практические занятия через календарный портал. URL-адреса каналов не заканчиваются на .ics, но при их открытии в Chrome сразу скачивается валидный файл .ics. Это значит, что это стандартные iCal-каналы — просто с другой структурой URL.

До недавнего времени я использовал плагин Ангуса, и он отлично обрабатывал эти каналы. Каждое событие создавало тему, и я мог направлять разные каналы в разные категории (например, «Терапия», «Ротации», «Экзамены»), что помогало нашей учебной группе оставаться организованной.

Но после того как недавняя ошибка this.router сломала плагин, мне пришлось его отключить — как это сделал Ethsim2 — и теперь нет простого способа синхронизировать наш календарь.

Если бы официальный плагин поддерживал:

  • Входящие каналы .ics (даже если URL не заканчивается на .ics)
  • Создание тем с привязкой к категории
  • Конфигурацию для каждого канала отдельно (например, один канал → одна категория)
  • Обнаружение обновлений и опциональную обработку отмены событий

…это сделало бы Discourse мощным инструментом для академического сотрудничества. Раньше всё работало у нас идеально, пока плагин не сломался — поэтому я бы очень хотел увидеть эту функциональность в ядре.

Готов поделиться примером URL календаря в частном порядке, если это поможет в тестировании.

Это также относится к Office 365, насколько я понимаю, многие университеты в США используют эту экосистему.

да, я использую эту экосистему :+1:

2 лайка

скрыто, так как изначально это был один пользователь и его скомпрометированные аккаунты. Однако аккаунты были объединены, и теперь тема запутана, поскольку пользователь, похоже, пишет сообщения сам себе.