Google Calendar Integration + automatic Shift Swap Request generation (#4220)

# What this PR does

## Which issue(s) this PR closes

Closes https://github.com/grafana/oncall-private/issues/2591

## Checklist

- [ ] Unit, integration, and e2e (if applicable) tests updated (N/A)
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] Added the relevant release notes label (see labels prefixed w/
`release:`). These labels dictate how your PR will
    show up in the autogenerated release notes.
This commit is contained in:
Joey Orlando 2024-04-15 08:56:28 -04:00 committed by GitHub
parent 87ca3a0fc3
commit 25f8963749
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 5 deletions

View file

@ -98,6 +98,24 @@ You can also check (and take) a swap request details in the web UI.
Once a swap is taken, the affected rotations and the final schedule will reflect the changes.
## Google Calendar Integration
Grafana OnCall allows you to connect your Google user to your OnCall user, giving us read-only access to your
Google Calendar's Out of Office events. We periodically check your Out of Office events to see if these overlap
with any of your on-call shifts. If so, we'll go ahead and automatically generate a shift swap request for you!
To link your Google user, simply head over to "View my profile" on the OnCall "Users" page. From there, follow the steps
under the Google Calendar tab. Once linked, you can further configure things, such as which OnCall schedules you would
like us to consider for automatic shift swap generation (by default we will consider all of the schedules that you
are involved in).
### Configuring for open source
1. Follow the instructions [here](https://developers.google.com/identity/protocols/oauth2) to setup your Google OAuth2
application.
2. Create a Client ID for your OAuth2 app and set the `SOCIAL_AUTH_GOOGLE_OAUTH2_KEY` and `SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET`
environment variables accordingly.
{{% docs/reference %}}
[mobile push notification]: "/docs/oncall/ -> /docs/oncall/<ONCALL_VERSION>/manage/mobile-app/push-notifications#shift-swap-notifications"
[mobile push notification]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/alerting-and-irm/oncall/manage/mobile-app/push-notifications#shift-swap-notifications"

View file

@ -65,7 +65,7 @@ class FeaturesAPIView(APIView):
if is_labels_feature_enabled(self.request.auth.organization):
enabled_features.append(Feature.LABELS)
if settings.FEATURE_GOOGLE_OAUTH2_ENABLED:
if settings.GOOGLE_OAUTH2_ENABLED:
enabled_features.append(Feature.GOOGLE_OAUTH2)
return enabled_features

View file

@ -71,7 +71,6 @@ GRAFANA_CLOUD_NOTIFICATIONS_ENABLED = getenv_boolean("GRAFANA_CLOUD_NOTIFICATION
FEATURE_LABELS_ENABLED_FOR_ALL = getenv_boolean("FEATURE_LABELS_ENABLED_FOR_ALL", default=False)
# Enable labels feature for organizations from the list. Use OnCall organization ID, for this flag
FEATURE_LABELS_ENABLED_PER_ORG = getenv_list("FEATURE_LABELS_ENABLED_PER_ORG", default=list())
FEATURE_GOOGLE_OAUTH2_ENABLED = getenv_boolean("FEATURE_GOOGLE_OAUTH2_ENABLED", default=False)
TWILIO_API_KEY_SID = os.environ.get("TWILIO_API_KEY_SID")
TWILIO_API_KEY_SECRET = os.environ.get("TWILIO_API_KEY_SECRET")
@ -650,15 +649,17 @@ AUTHENTICATION_BACKENDS = [
"apps.social_auth.backends.GoogleOAuth2",
]
if FEATURE_GOOGLE_OAUTH2_ENABLED:
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = os.environ.get("SOCIAL_AUTH_GOOGLE_OAUTH2_KEY")
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = os.environ.get("SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET")
GOOGLE_OAUTH2_ENABLED = SOCIAL_AUTH_GOOGLE_OAUTH2_KEY is not None and SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET is not None
if GOOGLE_OAUTH2_ENABLED:
CELERY_BEAT_SCHEDULE["sync_google_calendar_out_of_office_events_for_all_users"] = {
"task": "apps.google.tasks.sync_out_of_office_calendar_events_for_all_users",
"schedule": crontab(minute="*/30"), # every 30 minutes
"args": (),
}
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = os.environ.get("SOCIAL_AUTH_GOOGLE_OAUTH2_KEY")
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = os.environ.get("SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET")
# NOTE: for right now we probably only need the calendar.events.readonly scope
# however, if we want to write events back to the user's calendar
# we'll probably need to change this to the calendar.events scope