2 poin oleh GN⁺ 2025-04-11 | 1 komentar | Bagikan ke WhatsApp
  • Karena sering melakukan perjalanan dinas dan bepergian, ditambah harus mengelola relasi di berbagai zona waktu, muncul kebutuhan akan sistem kalender mandiri yang mengurangi ketergantungan pada Big Tech dan memberi kontrol langsung atas data jadwal
  • Arsitektur baru menempatkan server CalDAV Baïkal sebagai pusat, mengumpulkan Airtrail, email IMAP, dan ICS sekolah bahasa ke CalDAV, lalu menerbitkannya kembali sebagai file .ics untuk dibagikan
  • Cara lama menulis jadwal dalam YAML lalu mengonversinya menjadi ICS lewat CI/CD cukup untuk prototipe, tetapi kesalahan manual dan beban pemeliharaan makin besar sehingga pendekatan file statis diganti
  • Skrip Python mengumpulkan dan mengklasifikasikan event setiap 15 menit, membuat ICS terpisah untuk keluarga dan pekerjaan, serta menandai sebagian event sebagai PRIVATE di kalender kerja
  • Google Calendar dan Google Script hanya dipakai untuk sinkronisasi kalender kerja; setelah integrasi Airtrail API, cukup memasukkan penerbangan sekali dan dalam 15 menit masuk ke kalender pribadi, dalam 1 jam masuk ke kalender kerja

Mengapa manajemen kalender menjadi rumit

  • Karena sering berpindah tempat, keluarga, teman, dan rekan kerja sulit mengetahui zona waktu saat ini atau apakah sedang naik pesawat, dan mencocokkan janji di berbagai zona waktu terus membutuhkan perhitungan waktu
  • Penerbangan, kereta, waktu blokir sebelum keberangkatan, dan waktu perjalanan ke bandara harus dimasukkan berulang di banyak tempat, sehingga beban pengelolaan jadwal meningkat
  • Ketidaknyamanan ekosistem kalender yang ada mencakup standar, aplikasi frontend, dan pengalaman pengguna secara keseluruhan
    • Meski penyedia email membuat entri kalender penerbangan, terkadang penerbangan lanjutan terlewat atau zona waktunya salah
    • Organizer pada entri yang dibuat bukan pengguna, sehingga berbagi atau mengubahnya bisa sulit
  • Syarat yang dibutuhkan bukan sekadar penyimpanan jadwal, tetapi juga mencakup berbagi dan kontrol
    • Event harus ditampilkan sebagai blocker di kalender kerja
    • Pasangan harus bisa berlangganan kalender
    • Input event harus dilakukan paling banyak satu kali
    • Harus bisa diedit dari beberapa perangkat
    • Data harus berada di bawah kontrol langsung
    • Berbagi kalender kerja dengan pasangan bukan opsi yang bisa digunakan
  • Kebutuhan tambahan mencakup impor lampiran email .ics, impor HTTP ICS dari kalender sekolah bahasa, integrasi pelacak penerbangan self-hosted Airtrail, pembedaan warna, flag privat untuk kalender kerja, refresh yang sering, dan penggunaan frontend apa pun

Titik ketika pendekatan YAML dan ICS mencapai batasnya

  • Cara berbagi yang ada sering kali memerlukan platform umum atau lingkungan akun yang sama agar semua fitur tersedia
    • Ekosistem Gmail atau Outlook.com
    • Berbagi akun dalam lingkungan yang sama seperti Exchange
  • Ada dua jalan pintas yang umum
    • Menyediakan data iCal lewat HTTP untuk menerbitkan kalender read-only
    • Mengirim file iCal .ics lewat email
  • Versi awal menggunakan cara mengunggah file .ics ke URL situs web yang publik tetapi sulit ditebak, lalu membuat beberapa URL sesuai tujuan
  • Data event ditulis dalam YAML dan diserialisasi ulang menjadi file ICS oleh skrip kecil di pipeline CI/CD
  • Ini cukup untuk prototipe, tetapi saat skalanya membesar, penulisan YAML manual makin sering menimbulkan kesalahan, dan pekerjaan yang semestinya selesai dengan usaha rendah menjadi membebani

Arsitektur yang beralih ke CalDAV dan Baïkal

  • Arsitektur baru meninggalkan file statis dan beralih ke sistem berbasis CalDAV yang di-host
  • CalDAV adalah ekstensi dari spesifikasi penulisan terdistribusi WebDAV, yang menyediakan fungsi yang dibutuhkan aplikasi kalender
  • Dengan server CalDAV, event bisa dilihat dan dikelola di berbagai perangkat seperti laptop dan ponsel menggunakan aplikasi frontend pilihan
  • Karena tidak banyak server CalDAV yang mudah dilanggani tanpa autentikasi, diperlukan skrip yang secara berkala melakukan polling server, mengekstrak event, dan menerbitkannya sebagai file iCal di situs web
  • Alur keseluruhannya adalah sebagai berikut
    • Melakukan polling event dari sumber data
    • Menerbitkan event ke CalDAV secara terprogram
    • Mengambil semua event dari CalDAV dan menuliskannya sebagai file .ics
    • Menyediakan file .ics lewat HTTP

Instalasi Baïkal dan koneksi klien

  • Alat yang dipilih adalah Baïkal, server CalDAV/CardDAV self-hosted yang ringan untuk mengelola kalender dan kontak
  • Menjalankan image ckulka/baikal:0.9.5 dengan Docker Compose, menetapkan port dan volume lokal, lalu memulainya dengan docker compose up -d
  • Baïkal juga bisa menggunakan MySQL, tetapi berjalan juga dengan SQLite, dan SQLite lebih sederhana untuk dikelola
  • Untuk publikasi web digunakan nginx reverse proxy
    • Menghubungkan ke port Baïkal lokal dengan proxy_pass
    • Melakukan redirect 301 dari /.well-known/caldav ke dav.php
    • Redirect ini diperlukan saat menambahkannya ke aplikasi Calendar di iPhone atau Mac
  • TLS dikonfigurasi dengan Let’s Encrypt dan certbot, dan certbot memperbarui file konfigurasi nginx secara otomatis
  • Setelah membuka domain lewat browser, dibuat akun admin, lalu pengguna dan kalender
  • Kalender dihubungkan ke aplikasi kalender bawaan macOS dan iOS; pada pengaturan macOS/iOS digunakan manual settings, bukan otomatis atau advanced

Klasifikasi event dan cakupan publik kalender kerja

  • Dalam spesifikasi iCalendar ada properti opsional CATEGORIES pada komponen EVENT, tetapi alat yang digunakan seperti macOS Calendar, iOS Calendar, dan Google Calendar tidak mengimplementasikan field ini
  • Klasifikasi teks bebas sulit dijaga konsistensinya, sehingga jenis event dimodelkan dengan enum Python
    • Contoh: TerminType, CultureType, SocialType, AwayType, TransportType
    • Mencakup nilai seperti MEETUP, CONFERENCE, CLASS, APPOINTMENT, MEETING, EXAM
  • Alasan enum dibagi ke beberapa grup adalah untuk menata jenis event secara konseptual
  • Skema klasifikasi juga memuat logika untuk menentukan cakupan publik kalender kerja
    • Nilai enum dua digit secara default diperlakukan sebagai private di kalender kerja
    • Event seperti kunjungan dokter diserialisasi sebagai privat di file kalender kerja terpisah
  • Klasifikasi ini digunakan untuk meningkatkan kemudahan pencarian event dan identifikasi visual, serta membuatnya mudah dilihat sekilas di frontend yang mendukung pembedaan warna

Skrip sinkronisasi Python dan penerbitan ICS

  • Untuk otomatisasi, skrip Python dihubungkan ke cron job
  • Skrip mengumpulkan berbagai input ke Baïkal, lalu mengekspornya kembali sebagai ICS yang bisa dibagikan
    • Mengambil event dari email melalui IMAP
    • Mengekstrak event penerbangan dari Airtrail API
    • Mengambil file ICS yang di-host sekolah bahasa
    • Melakukan push event yang terkumpul ke Baïkal
    • Mengambil semua event dari Baïkal dan menyerialisasikannya kembali menjadi satu atau lebih file ICS yang bisa dibagikan
  • Integrasi IMAP otomatis mengambil undangan kalender yang diterima lewat email dan menambahkannya ke kalender, sehingga menyediakan fungsi yang mirip dengan Google Calendar
  • Skrip entry point cron membuat Calendar untuk keluarga dan kerja secara terpisah, mengambil event dari Baïkal, lalu memprosesnya dengan percabangan
    • Menambahkan event ke ICS keluarga
    • Menambahkan ke ICS kerja hanya jika alamat email kerja tidak ada dalam hasil serialisasi event
    • Menetapkan classification sebagai PUBLIC atau PRIVATE berdasarkan hasil is_work_public
  • Skrip integrasi Baïkal menggunakan request PROPFIND dan autentikasi HTTP Digest untuk mengambil event jarak jauh
  • Jika ada pola CATEGORIES: dalam deskripsi event, kategori diekstrak dari field deskripsi dan dimasukkan ke event.categories, lalu string tersebut dihapus dari deskripsi
  • File ICS untuk berbagi disediakan oleh nginx melalui URL yang sulit ditebak, dan URL dibuat dari string hash acak yang diberi salt
  • Cron job ini berjalan setiap 15 menit

Sinkronisasi Google Calendar untuk pekerjaan

  • Selain melihat event di kalender pribadi, jadwal perjalanan dan penerbangan harus terlihat sebagai waktu yang diblokir di kalender kerja agar rekan kerja mengetahui statusnya
  • Untuk menyalin ke kalender kerja digunakan Google Script Engine
  • Skrip dasarnya adalah versi modifikasi dari GAS-ICS-Sync
  • Versi modifikasi membaca properti CATEGORIES kalender dan menerapkan color coding di kalender kerja
  • Google Script berjalan dengan interval 30 menit
  • Penggunaan Google Calendar memang bertentangan dengan tujuan mengurangi ketergantungan pada Big Tech, tetapi dibedakan sebagai pilihan lingkungan kerja, bukan ketergantungan untuk penggunaan pribadi

Hasil operasional dan biaya

  • Sistem ini telah digunakan selama sekitar 6 bulan dengan perbaikan dan tambahan kecil
  • Perubahan terbaru adalah integrasi Airtrail API
    • Saat memesan penerbangan, data dimasukkan ke pelacak penerbangan
    • Dalam 15 menit, penerbangan ditambahkan ke kalender pribadi
    • Dalam 1 jam, penerbangan otomatis disalin ke kalender kerja
  • Untuk kebutuhan mobilitas yang kompleks, waktu pengelolaan jadwal berkurang besar dan berujung pada peningkatan kualitas hidup
  • Total biaya bisa diminimalkan, dan sistem ini juga mudah dijalankan di NAS rumahan
  • Saat ini, untuk menjalankan situs web dan integrasi, data ditempatkan di Swiss dan berlangganan waktu server sekitar 100 dolar AS per bulan
  • Biaya ini adalah konfigurasi yang agak berlebihan, dan akan dioptimalkan seiring waktu
  • Fakta bahwa semuanya bisa dikonfigurasi cepat di host Docker pada instance VM membuat biaya tambahan itu layak ditanggung, dan kemudahan manajemen jadwal menghemat waktu yang setara dengan 100 dolar AS per bulan

1 komentar

 
GN⁺ 2025-04-11
Komentar Hacker News
  • Mungkin akan ada yang tidak setuju, tapi menurut saya CalDAV itu kurang bagus
    Kalau memang benar-benar mudah dan bagus, mestinya ada jauh lebih banyak solusi CalDAV self-hosted dan usability-nya juga lebih baik; Radicale pun tidak terlalu mengesankan bagi saya
    Sebenarnya karena yang perlu saya sediakan praktis hanya satu file kalender, saya sempat mencoba mengimplementasikan server CalDAV sendiri, tetapi bahkan mengekspos satu file saja terasa terlalu tidak intuitif dan rumit, jadi saya menyerah
    Kalau perlu berbagi kalender dengan orang lain lewat aplikasi yang mendukung CalDAV, saya paham kebutuhannya, tetapi untuk hosting kalender yang dipakai sendiri rasanya hampir seperti buang-buang waktu
    Sebagai gantinya, awalnya saya mengunggah file iCal yang diperbarui secara dinamis ke bucket S3 dan menyinkronkannya dengan ICSx5 di Android. HTTPS saja sudah cukup, tanpa CalDAV
    Namun aplikasi kalender open source bebas untuk Android masih kurang, dan ICSx5 tidak berjalan baik di GrapheneOS, jadi sekarang saya memakai Proton Calendar yang mendukung tautan langsung file iCal dengan cara yang hampir sama
    Pendekatan menggunakan format iCalendar itu bagus, tetapi cakupan dukungan fitur iCalendar sangat berbeda-beda di tiap software kalender, sehingga pada akhirnya sebagian besar metadata saya masukkan ke field deskripsi alih-alih properti khusus
    Kegunaan saya adalah software yang mengambil data dari berbagai situs seperti Eventbrite, Meetup, penyelenggara pub quiz, dan kalender acara publik, lalu menyaring hanya acara sosial yang saya minati dan menggabungkannya menjadi satu kalender yang bisa dilihat di aplikasi kalender yang biasa saya pakai

    • Saya pernah mengerjakan klien CalDAV yang ada di semua produk Apple, dan saya setuju bahwa protokolnya kurang bagus
      Selain itu, kami sangat kerepotan menangani server CalDAV Exchange dan Google yang tidak mematuhi spesifikasi, dan pengguna menyalahkan kami sepenuhnya atas masalah itu
      Setelah sekarang bekerja di Google, saya tahu aplikasi gCal memakai protokol yang sama sekali berbeda
    • Masalah inti CalDAV dan fondasinya, WebDAV, mirip dengan penyakit kronis yang terlihat di sebagian besar standar yang disetujui W3
      Alih-alih menjadi format yang ringan, ia mencoba melakukan terlalu banyak hal sekaligus dan menjadi over-engineered; hasilnya protokol seperti gumpalan kusut berisi berbagai ide yang saling bercampur
      Karena itu, banyak layanan merasa cakupannya melampaui apa yang sebenarnya mereka inginkan, sehingga mereka tidak berusaha sepenuhnya mematuhi seluruh spesifikasi
      Spesifikasi format data W3 sepertinya selalu berakhir seperti ini, sedangkan pada spesifikasi protokol tingkat rendah hal itu relatif tidak terlalu terlihat
    • Buku berjudul Dreaming in Code membahas secara rinci bagaimana CalDAV dan WebDAV lahir melalui tim yang membuat program kalender Chandler
      Sudah sekitar 15 tahun sejak saya membacanya, tetapi seingat saya buku itu juga membahas sebagian bagaimana protokol semacam ini tersesat dalam komite selama proses desain
      Fakta bahwa proyek ini dimulai sekitar tahun 2001 saja sudah menunjukkan betapa lamanya masalah kalender menjadi sumber sakit kepala
      Saya merekomendasikannya kalau ingin tahu mengapa ini kurang bagus; buku itu juga menarik sebagai cerita tentang benturan startup dan open source, pembuatan produk, dan pengembangan software secara umum
      http://www.dreamingincode.com/ ; https://en.m.wikipedia.org/wiki/Dreaming_in_Code
    • Saya memakai CalDAV dan CardDAV Nextcloud bersama DAVx5, dan hampir berjalan sempurna
    • Penyedia CalDAV saya adalah ZOHO
      Untuk sinkronisasi Android, saya memakai DAVX5, aplikasi open source tanpa root yang menjalankan layanan sinkronisasi latar belakang, tetapi pengaturannya banyak masalah dan mungkin karena perbedaan implementasi CalDAV. Sinkronisasi dari DAVX5 ke kalender ZOHO juga memakan waktu lama
      Evolution di Ubuntu punya dukungan CalDAV yang cukup baik, tetapi setiap kali beralih antara tampilan email dan tampilan kalender, ia menyegarkan seluruh kalender. Penyegaran kalender ZOHO memakan waktu lama dan rate limit ZOHO juga ketat, sehingga praktis saya terkena soft block
      Thunderbird terbaru memiliki inkompatibilitas CalDAV karena mengharapkan kode sukses HTTP yang berbeda. ZOHO mengirim 200, tetapi Thunderbird mengharapkan kode lain. Sebagai catatan, kode CalDAV Thunderbird ditulis dalam JS
      Masalah ini hanya terjadi pada kalender kedua, dan mulai gagal begitu kalender kedua ditambahkan. Setidaknya di ZOHO, ini cukup menyakitkan
  • Server CalDAV lain yang layak direkomendasikan adalah Radicale
    Ditulis dengan Python dan dirancang cukup modular, sehingga bisa ditambahi plugin untuk autentikasi, otorisasi, dan sebagainya
    Data disimpan sebagai file teks biasa, lalu dilacak dan dicadangkan dengan git
    Seiring waktu saya menumpuk beberapa modifikasi menarik. Autentikasi ditangani oleh pam sistem host, dan untuk berbagi kalender saya menjalankan skrip berkala yang membuat symbolic link kalender ke semua pengguna yang diizinkan. Namun ada masalah ledakan kombinatorial
    Saya juga menambahkan daftar kontrol akses dengan plugin otorisasi yang memakai properti CalDAV kustom dan plugin web yang dimodifikasi
    Kalender publik diberi izin baca untuk pengguna public lewat ACL, dan dengan hack nginx saya mengizinkan akses menyeluruh untuk operasi baca
    Kalender publik ini bisa dilihat di kalender web: https://gitlab.nomagic.uk/popi/js_calendar_from_ics
    Sepertinya saya perlu menulis posting blog tentang konfigurasi ini

    • Saya sudah memakai Radicale selama beberapa tahun. Selain masalah sesekali di BusyCal, semuanya berjalan sangat mulus
  • Ini persis tulisan yang saya butuhkan
    Di server pribadi saya memakai kalender SoGO dari Mailcow, sedangkan untuk kalender kerja saya memakai Fastmail, dan keduanya tidak terlalu cocok satu sama lain
    Saya belum menemukan cara menyambungkan kalender Mailcow dengan benar ke tool lain, jadi saya menghabiskan waktu untuk menyinkronkannya secara semi-manual
    Sudah cukup lama saya ingin memisahkan kalender, tetapi satu-satunya alternatif yang saya tahu hanyalah Nextcloud, dan menurut saya itu agak berat
    Baïkal terlihat bagus dan saya ingin segera mencobanya. Dengan begitu saya juga bisa menjajaki penggantian Mailcow dengan layanan email self-hosted lain

  • Belakangan ini sedang sangat agresif keluar dari cloud. Ada ratusan GB data, tetapi meski pemindahannya dilakukan sesekali, belum sampai 2 minggu, dan semuanya berjalan jauh lebih baik dari perkiraan
    Satu-satunya layanan yang masih diserahkan ke pihak luar hanya email, karena tidak suka mengurus record MX dan IMAP/SMTP
    Untuk sisanya, Asus PN40 dengan CPU Celeron dual-core sangat membantu. Kelebihannya aksesibilitasnya bagus, serta ada slot M.2 NVME dan drive SATA sehingga konfigurasi backup yang aman bisa dibuat di satu tempat
    Saya setuju bahwa CalDAV agak meragukan, tetapi Nextcloud memenuhi sebagian besar kebutuhan. Meski dipasangi Redis, beberapa pekerjaan tetap bisa lambat, tetapi kalender, pengganti Dropbox/Google Drive, dokumen, foto, backup, sampai sinkronisasi otomatis ditangani dengan baik
    Jika ditambah berbagai solusi open source, semuanya beres, mulai dari streaming musik dan video, monitoring, notifikasi, VPN, reader, tool manajemen, hingga berbagai utilitas
    Mini PC ini tergolong berperforma rendah, tetapi karena ISP-nya bagus, ia mampu menangani semuanya dengan banyak ruang sisa, bahkan rasanya masih sanggup menampung 5–6 orang lagi seperti saya

    • Kalau ingin meningkatkan ketahanan data, sebaiknya cari tahu tentang strategi backup 3-2-1. RAID juga layak dilihat bersamaan
  • Rasanya seperti hal lama menjadi baru lagi
    Pada awal 2000-an, saya meng-host kalender dengan Mozilla Sunbird melalui modul IIS WebDAV di server Win2k pribadi
    Sepertinya CardDAV belum ada saat itu, meski bisa saja saya keliru
    Pada akhirnya saya memindahkan semua data itu ke Google Calendar, dan cukup menarik karena kalau ditelusuri jauh ke belakang, masih ada hal-hal seperti tugas kuliah

    • Sekitar 2004, Sunbird hampir seperti yang saya inginkan, tetapi tampak tidak stabil
      Ada beberapa janji yang tidak naik ke server sehingga hilang, dan saya memakainya sebagai CalDAV bersama server DAViCal
      Sunbird sudah dihentikan, dan belakangan ini saya belum mencari apakah ada pengganti yang layak untuk berjalan di Windows
  • Baikal terlihat menarik
    Dulu saya memakai DAViCal untuk berbagi kalender di antara beberapa perangkat Apple iOS. Saat berjalan, ia berjalan baik, tetapi seiring versi iOS berubah sepertinya menjadi tidak stabil, jadi akhirnya saya menyerah
    Kalau suatu saat saya meninjaunya lagi, saya akan melihat DAViCal dan Radicale, dan sekarang Baikal juga
    https://www.davical.org/
    https://radicale.org/v3.html

    • Saya lama memakai Radicale dan berjalan baik
      Baru-baru ini saya pindah ke Nextcloud, karena shared hosting menangani deployment-nya dan ada UI web terpadu, sehingga beban konfigurasi jauh lebih kecil
  • Saya sudah memakai Baikal selama beberapa tahun dan cukup solid. Namun saya memakainya sendirian dan tidak punya semua kebutuhan yang disebut di tulisan asli
    Di desktop saya menghubungkannya lewat kalender bawaan Thunderbird, dan di ponsel memakai DAVx5 serta Fossify Calendar dari F-Droid
    Fossify Calendar merupakan fork dari aplikasi Calendar milik Simple Mobile Tools, tetapi berbeda dari namanya, ini aplikasi kalender paling kaya fitur yang pernah saya lihat sejauh ini
    Saya suka karena kesederhanaannya adalah menampilkan semua opsi langsung, tanpa membuat kita menggali berbagai menu dan dialog

  • Di kantor saya memakai Outlook, di rumah memakai Google Calendar, dan sinkronisasi lewat HTTP benar-benar tidak stabil
    Sepertinya zona waktu terus dikacaukan; kadang diterbitkan sebagai UTC dan kadang tidak, sehingga waktu rapat selalu salah
    Saya tidak paham mengapa dua penyedia besar ini tidak bisa memperbaiki fungsi sedasar ini
    Kalau memakai sistem sendiri bisa menyelesaikannya, saya akan langsung melakukannya, tetapi saya khawatir masalah yang sama terjadi: rapat yang dibuat di Outlook diimpor dengan selisih 2 jam

    • Penanganan zona waktu di seluruh produk Google selama puluhan tahun kacau parah dari satu aplikasi ke aplikasi lain. Tapi sekarang para developer AI pasti akan segera membereskannya
    • Hampir tidak ada insentif finansial untuk memperbaiki masalah ini. Malah justru membantu efek lock-in
      Selain itu, banyak perusahaan secara nyata melarang sinkronisasi antara kalender pribadi dan kalender kerja karena masalah kebocoran data
  • Saya ingin melakukan hal seperti ini juga untuk foto. Saya sudah cukup lama ingin lepas dari Dropbox dan Google, dan prioritasnya ada dua
    Pertama, saya ingin membuat semacam fitur kenangan dari foto-foto saya dan mengirimkannya ke ponsel. Caranya dengan mengelompokkan berdasarkan kriteria seperti hari peringatan, aktivitas serupa, saya dan X (X adalah pasangan, keluarga, teman, dll.), atau perubahan seiring waktu
    Kedua, foto yang diambil dari perangkat harus bisa disimpan ke server saya
    Saya sudah menyiapkan 3 mesin TrueNAS dengan ruang 2TB di lokasi berbeda, dan ingin membangun fitur ini perlahan-lahan

  • Cara lain adalah memakai DecSync tanpa server
    Thunderbird atau Evolution tersinkronisasi dengan aplikasi Android, dan kalender, kontak, tugas, sampai RSS direplikasi ke peer lain. Bisa juga didapat dari F-Droid
    https://github.com/39aldo39/DecSync

    • Menarik, tetapi dukungan iOS tidak terlihat, dan sayangnya tampaknya juga tidak lagi dipelihara