Merge 3540c35cc2f0dd2b98ccf6bea1ff3050b674fd84 into 598f1826d8b2bc969aace2c6459824737667218c

This commit is contained in:
Eulices 2026-03-21 03:15:10 +00:00 committed by GitHub
commit 25321b9300
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 57 additions and 4 deletions

View File

@ -6,7 +6,12 @@ final class CalendarService: CalendarServicing {
func events(params: OpenClawCalendarEventsParams) async throws -> OpenClawCalendarEventsPayload {
let store = EKEventStore()
let status = EKEventStore.authorizationStatus(for: .event)
let authorized = EventKitAuthorization.allowsRead(status: status)
let authorized: Bool
if status == .notDetermined {
authorized = await Self.requestEventAccess(store: store)
} else {
authorized = EventKitAuthorization.allowsRead(status: status)
}
guard authorized else {
throw NSError(domain: "Calendar", code: 1, userInfo: [
NSLocalizedDescriptionKey: "CALENDAR_PERMISSION_REQUIRED: grant Calendar permission",
@ -39,7 +44,12 @@ final class CalendarService: CalendarServicing {
func add(params: OpenClawCalendarAddParams) async throws -> OpenClawCalendarAddPayload {
let store = EKEventStore()
let status = EKEventStore.authorizationStatus(for: .event)
let authorized = EventKitAuthorization.allowsWrite(status: status)
let authorized: Bool
if status == .notDetermined {
authorized = await Self.requestWriteOnlyEventAccess(store: store)
} else {
authorized = EventKitAuthorization.allowsWrite(status: status)
}
guard authorized else {
throw NSError(domain: "Calendar", code: 2, userInfo: [
NSLocalizedDescriptionKey: "CALENDAR_PERMISSION_REQUIRED: grant Calendar permission",
@ -95,6 +105,38 @@ final class CalendarService: CalendarServicing {
return OpenClawCalendarAddPayload(event: payload)
}
private static func requestEventAccess(store: EKEventStore) async -> Bool {
if #available(iOS 17.0, *) {
return await withCheckedContinuation { continuation in
store.requestFullAccessToEvents { granted, _ in
continuation.resume(returning: granted)
}
}
}
return await withCheckedContinuation { continuation in
store.requestAccess(to: .event) { granted, _ in
continuation.resume(returning: granted)
}
}
}
private static func requestWriteOnlyEventAccess(store: EKEventStore) async -> Bool {
if #available(iOS 17.0, *) {
return await withCheckedContinuation { continuation in
store.requestWriteOnlyAccessToEvents { granted, _ in
continuation.resume(returning: granted)
}
}
}
return await withCheckedContinuation { continuation in
store.requestAccess(to: .event) { granted, _ in
continuation.resume(returning: granted)
}
}
}
private static func resolveCalendar(
store: EKEventStore,
calendarId: String?,

View File

@ -103,8 +103,7 @@ final class ContactsService: ContactsServicing {
case .authorized, .limited:
return true
case .notDetermined:
// Dont prompt during node.invoke; the caller should instruct the user to grant permission.
// Prompts block the invoke and lead to timeouts in headless flows.
// Avoid prompting during node.invoke; headless/unattended flows should fail fast.
return false
case .restricted, .denied:
return false

View File

@ -50,6 +50,14 @@
</array>
<key>NSCameraUsageDescription</key>
<string>OpenClaw can capture photos or short video clips when requested via the gateway.</string>
<key>NSCalendarsUsageDescription</key>
<string>OpenClaw uses your calendars to show events and scheduling context when you enable calendar access.</string>
<key>NSCalendarsFullAccessUsageDescription</key>
<string>OpenClaw uses your calendars to show events and scheduling context when you enable calendar access.</string>
<key>NSCalendarsWriteOnlyAccessUsageDescription</key>
<string>OpenClaw uses your calendars to add events when you enable calendar access.</string>
<key>NSContactsUsageDescription</key>
<string>OpenClaw uses your contacts so you can search and reference people while using the assistant.</string>
<key>NSLocalNetworkUsageDescription</key>
<string>OpenClaw discovers and connects to your OpenClaw gateway on the local network.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>

View File

@ -134,6 +134,10 @@ targets:
NSBonjourServices:
- _openclaw-gw._tcp
NSCameraUsageDescription: OpenClaw can capture photos or short video clips when requested via the gateway.
NSCalendarsUsageDescription: OpenClaw uses your calendars to show events and scheduling context when you enable calendar access.
NSCalendarsFullAccessUsageDescription: OpenClaw uses your calendars to show events and scheduling context when you enable calendar access.
NSCalendarsWriteOnlyAccessUsageDescription: OpenClaw uses your calendars to add events when you enable calendar access.
NSContactsUsageDescription: OpenClaw uses your contacts so you can search and reference people while using the assistant.
NSLocationWhenInUseUsageDescription: OpenClaw uses your location when you allow location sharing.
NSLocationAlwaysAndWhenInUseUsageDescription: OpenClaw can share your location in the background when you enable Always.
NSMicrophoneUsageDescription: OpenClaw needs microphone access for voice wake.