Skip to content

Instantly share code, notes, and snippets.

@s-mage
Created February 8, 2025 18:08
Show Gist options
  • Save s-mage/7d4813304e2abfe575505b670ea56780 to your computer and use it in GitHub Desktop.
Save s-mage/7d4813304e2abfe575505b670ea56780 to your computer and use it in GitHub Desktop.
import EventKit
import AppKit
func requestAccess(eventStore: EKEventStore) async -> Bool {
do {
return try await eventStore.requestFullAccessToEvents()
} catch {
print("Failed to request calendar access: \(error)")
return false
}
}
func checkUpcomingEvents(eventStore: EKEventStore) {
let now = Date()
let futureDate = now.addingTimeInterval(300.0)
let predicate = eventStore.predicateForEvents(withStart: now, end: futureDate, calendars: nil)
let events = eventStore.events(matching: predicate)
print("events: \(events)")
// TODO: skip event if already scheduled before
// TODO: schedule removing on end date
for event in events {
let url = extractMeetingUrl(from: event.notes ?? "") ?? extractMeetingUrl(from: event.location ?? "")
// TODO: && not declined
if url != nil, event.status != .canceled {
scheduleEventOpening(startDate: event.startDate, url: url!)
}
}
}
func scheduleEventOpening(startDate: Date, url: URL) {
let timeInterval = startDate.timeIntervalSinceNow
if timeInterval > 0 { // Only schedule if the event is in the future
print("Scheduling url opening for: \(url) in: \(timeInterval)")
let timer = Timer(fire: startDate, interval: 0, repeats: false) { _ in
openURL(url)
}
RunLoop.main.add(timer, forMode: .common)
} else {
print("Event \(url) has already started. Ignoring.")
}
}
func extractMeetingUrl(from text: String) -> URL? {
print("Extracting URL from: \(text)")
let url = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
.matches(in: text, range: NSRange(text.startIndex..., in: text))
.first?.url
print("Found URL: \(String(describing: url))")
return url
}
func openURL(_ url: URL) {
print("Opening URL: \(url)")
NSWorkspace.shared.open(url)
}
@main
struct CalendarApp {
static func main() {
let eventStore = EKEventStore()
// requestAccess(eventStore: eventStore)
let timer = Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { _ in
checkUpcomingEvents(eventStore: eventStore)
}
RunLoop.main.add(timer, forMode: .common)
RunLoop.main.run()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment