Skip to content

Connected Apps — Strava & Chess.com Integration

Connected Apps lets you link Strava or Chess.com to Objectuve so activity you already log elsewhere checks off the matching habit automatically — no re-entering the same run or chess game twice. It's a free feature, no paywall.

Availability

Connected Apps is rolling out gradually behind the connected_apps_enabled feature flag — it is not yet visible to all users. As of this writing the flag is disabled by default (0% general rollout); Settings → Connected Apps and both provider connect flows are hidden until a user's account is included in the rollout. See docs/operations/rollouts/v4.14-activity-nexus-connected-apps.md for the staged ramp plan — public availability is additionally gated on a Privacy Policy/ToS update covering third-party activity ingest, tracked separately.

Overview

If you're already tracking runs on Strava or playing daily games on Chess.com, Connected Apps closes the loop: your activity there checks in your habit here. Import is one-way (Objectuve never posts anything back to Strava or Chess.com), and every auto-completed check-in is clearly labeled so you always know it came from an import, not a manual tap.

Two providers ship today:

ProviderHow activity arrivesAuth
StravaReal-time, via a Strava webhook the moment you save an activity thereOAuth 2.0 (in-app browser)
Chess.comOnce a day, via a poll of your public game archiveNone — Chess.com's public API needs no login

Connecting a provider

Once the feature is available on your account, go to Settings → Connected Apps.

Strava

  1. Tap Connect Strava. This opens an in-app browser (not a full app switch) to Strava's own login/consent screen.
  2. Log in and approve access. Objectuve requests exactly one permission scope — activity:read_all — so it can read your activities. It cannot post, edit, or delete anything in your Strava account.
  3. The browser closes automatically and hands control back to Objectuve.
  4. If any of your existing habits look like a match for your Strava activity types, you'll see a mapping review before anything is linked (see Mapping review below).

Chess.com

  1. Tap Connect Chess.com and enter your Chess.com username. No login or password — Chess.com's game archive is public.
  2. Objectuve checks that games exist for that username, then connects.
  3. Same mapping review as Strava, scoped to Chess.com games.

What data we access

Strava — Objectuve only reads: activity type (run, ride, swim, walk, hike, workout, etc.), duration, distance, and the timestamp of each activity. Objectuve does not request, fetch, or store GPS location data, maps, or routes from Strava — only the summary fields listed above.

Chess.com — game results and timestamps from your public game archive. No account credentials are involved since Chess.com's API is public and unauthenticated.

Strava access and refresh tokens are stored encrypted (Rails ActiveRecord::Encryption) and are never written to logs.

Mapping review

The first time a provider connects, Objectuve proposes matches between the provider's activity types and your existing habits (for example, "Strava runs" → your "Morning Run" habit), each with a confidence level. You choose accept, edit, or dismiss per proposed match — nothing links automatically without you seeing it first.

After that first review, two things can happen when new activity comes in:

  • High-confidence match — the check-in happens automatically, and you get a toast: "Linked to Strava. <habit> checks itself off now." This is a completed-action notice, not a request — the check-in already happened.
  • Possible match, lower confidence — nothing is checked in. You get a toast: "New match from Strava. <habit> could check itself off — want to link it?" with a Review link to Manage Mappings. It stays a proposal until you accept it.

Either way, you always see a toast when a new mapping is detected — Objectuve never silently links a new habit to a provider behind the scenes.

Managing mappings

From Settings → Connected Apps → Manage Mappings, per provider, you can:

  • See every active mapping (provider activity type → habit).
  • Remove a mapping — auto check-in stops for that habit; anything already logged stays.
  • Re-run auto-mapping to scan for new matches (e.g. after you add a new habit).

Activity feed attribution

Any habit check-in that came from a connected provider shows a small "via Strava" or "via Chess.com" pill in your activity feed, tinted with the provider's own brand color, so imported check-ins are always visually distinct from ones you logged yourself.

Pausing, reconnecting, and disconnecting

  • Pause — stops new activity from syncing without removing the connection. Your existing mappings and tokens are kept; resume any time.
  • Disconnect — removes the connection entirely. Past check-ins stay — disconnecting only stops future syncing, it doesn't touch your habit history or streaks.
  • Error — if a connection's token can't be refreshed or a sync repeatedly fails, it shows an error status in Settings rather than failing silently. Reconnect through the same OAuth flow to clear it.

Known limitations (v1)

  • Import is one-way only — Objectuve never writes back to Strava or Chess.com.
  • Only habit check-ins are automated; a goal's numeric progress (e.g. "% toward a monthly distance target") stays manual.
  • Historical activity from before you connected isn't imported — sync starts from the moment you connect.
  • Toggling "auto-check" off for one existing mapping isn't available yet in Manage Mappings — it currently shows "Can't update this yet — check back soon." Removing the mapping is the current workaround.

Looking for your history from before you connected? That's Data Import, not Connected Apps — the two solve different problems. Connected Apps is ongoing, forward-only sync (see the limitation above: it structurally can't backfill anything from before you connected). Data Import is a one-time CSV migration of your existing goals and habit history, done once, not an ongoing connection.

Technical details

Connected Apps is a reusable integration framework, not a one-off — the same models and adapter pattern will carry future providers (Apple Health, Google Health, Garmin) without a rewrite. See Import Provider Evaluation for the v4.64 assessment of Apple Health, Habitica, Strides, and Google Fit against this framework and the one-way CSV importer.

  • Data model & adapter pattern: Connected Apps Integration FrameworkIntegrationProvider, IntegrationConnection (encrypted tokens, acts_as_paranoid), HabitIntegrationMapping, IntegrationActivity.
  • Feature flag: connected_apps_enabled (ionic_frontend/src/lib/featureFlags.ts, rails_api/app/services/feature_flag_service.rb) gates the Settings entry point, both connect routes, the connectedApps/connectStrava/connectChessCom GraphQL surface, and the global NewHabitToast mount in App.vue (v-if="connectedAppsEnabled") — see rollout playbook for ramp stages.
  • Strava adapter: rails_api/lib/integration_provider/strava.rb — OAuth scope activity:read_all; webhook receiver at rails_api/app/controllers/webhooks/strava_controller.rb verifies Strava's HMAC-SHA256 signature (X-Strava-Signature) before enqueuing Strava::IngestionJob.
  • Chess.com adapter: rails_api/lib/integration_provider/chess.rb — public REST, no auth; polled hourly by Integrations::SyncChessActivityJob (rails_api/config/cronotab.rb), which fetches each user's prior day of games once their local clock hits 2am (User#timezone_or_default falls back to UTC if the user's stored timezone is blank or unrecognized).
  • Confidence scoring: Integrations::MapIncomingActivity (rails_api/app/interactions/integrations/map_incoming_activity.rb) — AUTO_CHECK_THRESHOLD = 0.85, PROPOSAL_THRESHOLD = 0.50.
  • Auto check-in: Integrations::AutoCheckIn wraps the existing GoalTracking::CheckInHabit, idempotent on (goal, completed date, provider); a deleted habit fails gracefully (no error) rather than raising.
  • Toast surfacing: ionic_frontend/src/components/connected-apps/NewHabitToast.vue, triggered by the integrations.activity_checked_in / integrations.activity_proposed domain events (Integrations::ProcessIncomingActivity, Integrations::Subscribers).
  • Settings UI: ionic_frontend/src/views/ConnectedAppsView.vue (/settings/connected-apps) and ManageMappingsView.vue (/settings/connected-apps/:provider/mappings).
  • Feed attribution: GoalEvent#source enum (manual / integration); pill rendered by ionic_frontend/src/components/connected-apps/AttributionPill.vue using the --brand-strava and --brand-chesscom HSL design tokens, each with a WCAG-AA-adjusted -accessible variant for text (design_system/css/tokens.css).

Last updated: 2026-09-15 — added the Data Import cross-link (sync vs. one-time migration) (v4.64 Phase 7, OBJ-3827) · Version: v4.14 (Phases 1–6, merged to master 8e719f925) · Related: Activity Nexus PRD, Rollout playbook

Loading…