ICS → Discourse Importer

I’ve built a small utility that continuously syncs events from an iCalendar (ICS) feed into a Discourse category via the REST API.

This isn’t a full Discourse plugin — it runs alongside your Discourse install — so it belongs here in #extras. If you want to display calendar events from an external source (e.g. Google Calendar, University timetable feeds, etc.) inside Discourse topics, this will be useful.

Repository

How it works

  • Reads events from a given ICS feed
  • Matches them against existing topics (by UID or fallback to time/location)
  • Creates or updates topics in your chosen category
  • Can run continuously as a systemd service (safe against duplicate execution via flock)

Requirements

  • Ubuntu 24.04 LTS (tested)
  • Python 3 (already in Ubuntu 24.04 LTS)
  • A Discourse API key
  • A category ID to target for event topics

Example output

Here’s what it looks like when syncing a University timetable ICS feed into Discourse:

Quick start

Clone the repo and install requirements:

git clone https://github.com/Ethsim12/Discourse-ICS-importer-by-REST-API.git /opt/ics-sync
cd /opt/ics-sync
pip install -r requirements.txt

Run a sync once manually:

python3 ics_to_discourse.py \
  --ics "https://example.com/feed.ics" \
  --category-id 4 \
  --site-tz "Europe/London" \
  --static-tags "events,ics"

Set up as a systemd service/timer for continuous sync (example configs in the repo).

2 Likes

the tags were annoying me, so i made sure the search.json look for indexed content of the event - first post of each topic/event

1 Like

Thank you again for the share, this calendar is evolving more and more, getting new features thanks to people like you. I wonder how it will be like in 3-5 years :slight_smile:

1 Like

Brilliant! Thanks for testing it out. Anyone else who wants to try syncing an ICS feed into Discourse, I’d love feedback on whether your feeds behave the same.

2 Likes

A couple of comments.

If I had any time, I’d probably try converting this to a proper plugin. I think it shouldn’t be too hard to create some settings and convert the Python into Ruby and put it in a job.

Another idea, which could be useful for people who are hosted and want to use this, would be to convert the task into a github action and get it to run the task daily. I did this for some scripts a hosted client needed to run daily a while back and it’s working pretty well. It’s at once harder (it requires learning github workflows and how to deal with secrets instead of a good old cron job) and easier (you don’t have to learn how to muck with installing stuff on a machine via a command line interface).

1 Like

I haven’t tested it lately, but wrapped up the event bbcode parsing in my latest commit to

yes, though it would be nice if the ics_feeds setting were to be broken down, so the admin isn’t inputting a single JSON into UI

1 Like