TutorialMy work
Free iCal sync between booking channels
Merge Airbnb, Booking.com and direct calendars without a channel manager. Cron, a script, done.
If you only need block-out sync (not full two-way pricing and content), you do not need a channel manager.
The shape of the solution
- Each channel exports an
.icsfeed - A script downloads and merges them on a schedule
- Each channel imports the merged feed as an “external calendar”
Minimal merger
from icalendar import Calendar
from pathlib import Path
def load(path: str) -> Calendar:
return Calendar.from_ical(Path(path).read_bytes())
def merge(paths: list[str]) -> Calendar:
out = Calendar()
out.add("prodid", "-//ical-cleaner//EN")
out.add("version", "2.0")
seen = set()
for p in paths:
cal = load(p)
for component in cal.walk():
if component.name != "VEVENT":
continue
uid = str(component.get("uid"))
if uid in seen:
continue
seen.add(uid)
out.add_component(component)
return out
if __name__ == "__main__":
cal = merge(["airbnb.ics", "booking.ics", "direct.ics"])
Path("combined.ics").write_bytes(cal.to_ical())
Cron
*/30 * * * * cd /opt/ical && ./fetch-and-merge.sh >> /var/log/ical-sync.log 2>&1
Serve combined.ics over HTTPS (even a static file on Caddy is fine). Point each channel’s “block calendar” URL at it.
Watch-outs
- Some channels cache external calendars aggressively — allow an hour when testing
- UIDs must be stable or you’ll duplicate events
- This does not push prices or listing content — only availability blocks