Skip to content

About

Inventory every IFTTT Applet that depends on Fitbit, flag the Google account conversion it needs first, and rebuild it on the Fitbit Web API before the September 30 shutdown.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fitbit Applet Migration Kit

Built and maintained by Avalux, a full-stack AI and automation agency. This repository is scaffolding for a migration you still have to run. It gives you an inventory pass over your IFTTT Applets, the account-conversion gate that blocks every rebuild, and a mapping from each retired Fitbit trigger to a real Fitbit Web API equivalent. It does not give you a finished integration. Credentials, hardening, retry logic, and your actual business rules are yours to add. Part of Avalux Open Source.

Why this exists

IFTTT is retiring its Fitbit service on September 30, 2026. Every Applet with a Fitbit trigger, a Fitbit query, or a Fitbit action stops working on that date. Confirm the exact date and scope against IFTTT's own help center before you plan around it, because deprecation timelines slip and this kit assumes the hard version of the deadline.

The reason this matters more than a normal service deprecation is the failure mode. When a connected service goes away, Applets do not throw an error your client sees. They stop running. The activity feed simply goes quiet. A studio that has been auto-logging member workouts into a Google Sheet for three years will not get an alert saying the pipeline died. They will notice six weeks later when a coach asks why nobody has a streak count anymore, and by then the gap in the data is unrecoverable because Fitbit only retains intraday history for the window your OAuth scopes allow you to read.

The second problem is inventory. Almost nobody knows how many Applets they actually have. In a typical ten-person studio we find Applets spread across the owner's personal IFTTT account, a shared ops account nobody can log into, and the account of a coach who left in 2024. Some are Applets the studio built. Some are published Applets they enabled from the IFTTT gallery, which means the logic is not even theirs to read. Counting them is the first real task.

The third problem is sequencing, and it is the one most teams get wrong. You cannot simply swap the Fitbit service for the new Google Health service on IFTTT and move on. Fitbit accounts created before the Google migration are legacy fitbit.com accounts. Google's health services authenticate against a Google Account. If the login behind your studio's Fitbit connection is still a legacy account, the new service will not connect at all, and the conversion is one way. That conversion has to happen before you touch any Applet, and it has to be coordinated with whoever owns the account, which is frequently a client rather than you.

This kit puts those three problems in order: inventory, conversion gate, rebuild.

Who this is for

This is aimed at operators, not consumers.

  • Boutique fitness studios running class attendance, streak tracking, or challenge leaderboards off member Fitbit activity.
  • Wellness and health coaches whose client check-in workflows fire when a client logs a workout, a weight, or a sleep session.
  • Corporate wellness program administrators running step challenges across a few hundred employees, where the aggregation currently lands in Sheets or Airtable through IFTTT.
  • Small agencies and ops consultants who inherited a client's consumer-grade automation stack and now own the migration.

It is not for you if you have one personal Applet that posts your step count to a Discord channel. Delete it and rebuild it by hand in ten minutes. It is also not for you if you already run a health data platform with a warehouse behind it, because you have better tooling than a CSV worksheet.

You will need: Python 3.10 or newer, a registered app at dev.fitbit.com, an HTTPS endpoint you control for webhook delivery, and access to the IFTTT account that owns the Applets.

What's in the box

fitbit-applet-migration-kit/
├── src/
│   └── applet_inventory.py     # inventory pass, conversion gate, worksheet output
├── data/
│   └── applets.sample.json     # shape the inventory expects
├── .env.example                # credentials and endpoint config
├── LICENSE                     # MIT
└── README.md

applet_inventory.py is the shipped piece. It reads an Applet export, walks every trigger, query, and action step, flags the ones bound to the Fitbit service, resolves each to a rebuild path on the Fitbit Web API, runs a live token check to tell you whether the underlying account still authorizes, and writes a migration worksheet as CSV.

Deliberately not included, because these are the parts that have to be built against your stack rather than copy-pasted: the subscriber endpoint itself, your notification sink, the reconciliation sweep, and per-member token storage. The mapping tables and the handshake details below are what you need to write them, and the "What you still have to build" section is explicit about the work.

Quick start

git clone https://github.com/elikem2021/fitbit-applet-migration-kit.git
cd fitbit-applet-migration-kit

python3 -m venv .venv && source .venv/bin/activate
pip install requests

cp .env.example .env
# fill in FITBIT_CLIENT_ID, FITBIT_CLIENT_SECRET, FITBIT_ACCESS_TOKEN

export $(grep -v '^#' .env | xargs)
python src/applet_inventory.py \
  --applets data/applets.sample.json \
  --out migration-worksheet.csv

Output is one row per Fitbit-dependent step, with the owning Applet, the role the step plays, the rebuild path, and the conversion status of the account behind it. Sort by conversion status and you have your work queue.

Getting the Applet list without scraping

There is no public REST endpoint that hands you an arbitrary user's Applet inventory, and screen-scraping the IFTTT dashboard is a fragile play we will not ship. Two supported routes:

  1. The IFTTT MCP server. If you have access, my_applets returns the Applet list for the connected account and get_applet returns the step detail for each one. Dump those responses to JSON and point the inventory at the file. get_activity_feed is the companion call worth making, because it is how you get a real last-run timestamp instead of a guess.
  2. An IFTTT account data export. Request it from account settings, then normalize it into the shape below.

The inventory expects records like this, and will accept either service_slug or service on each step:

{
  "applets": [
    {
      "id": "aBc123",
      "name": "Log member workout to studio roster",
      "owner": "ops@example-studio.com",
      "status": "enabled",
      "last_run": "2026-09-14T06:12:00Z",
      "triggers": [{"service_slug": "fitbit", "name": "New activity logged"}],
      "actions":  [{"service_slug": "google_sheets", "name": "Add row to spreadsheet"}]
    }
  ]
}

Run the inventory once per IFTTT account. The forgotten accounts are where the surprises live.

The account conversion gate

Before anything else, sort every account into one of three states and record it on the worksheet:

State Meaning Action
legacy Still signs in with a fitbit.com email and password Convert to a Google Account first. Nothing downstream works until this is done.
converted Signs in with Google, Fitbit data intact Ready for the new service and for a fresh OAuth grant.
unknown Nobody at the studio remembers Treat as legacy until a human confirms by attempting a sign-in.

Use encodedId from the Fitbit profile as your join key across the migration, not the email address, because emails change during conversion and IDs generally do not. Verify that assumption on a throwaway account of your own before you trust it across a member roster. A usable mapping sheet looks like this:

member_ref   encodedId   login_type   conversion   subscription_id   last_notified
M-0114       2ABCDE      google       converted    sub-M-0114        2026-09-16T05:02Z
M-0119       3FGHIJ      fitbit.com   legacy       (blocked)         (none)

For a corporate wellness program this is the entire project. Two hundred employees each have to convert their own account. You cannot do it for them, so the deliverable is a tracked comms sequence with a deadline, and the worksheet is what you track against.

Rebuilding on the Fitbit Web API

The replacement for an IFTTT Fitbit trigger is a subscription plus a read, not a poll. Base URL is https://api.fitbit.com. Auth is OAuth 2.0 authorization code with PKCE against https://api.fitbit.com/oauth2/token. Request only the scopes you need: activity, heartrate, sleep, weight, profile. Per-user rate limit is 150 requests per hour, which is the number that kills naive polling designs.

The math: 240 members polled every 15 minutes is 4 requests per member per hour, comfortably inside the limit. Fan that out to five endpoints per poll and you are at 20 per hour per member, still inside, but now you are burning 4,800 requests an hour to learn almost nothing, since most members log nothing most hours. Subscriptions collapse that to one inbound notification per actual change.

Mapping from the retired IFTTT triggers:

IFTTT Fitbit trigger Subscription collection Read after notification
New activity logged activities GET /1/user/-/activities/list.json
Daily activity summary activities GET /1/user/-/activities/date/{date}.json
Daily step goal achieved activities summary steps compared against GET /1/user/-/activities/goals/daily.json
New sleep logged sleep GET /1.2/user/-/sleep/date/{date}.json
New weight logged body GET /1/user/-/body/log/weight/date/{date}.json
(no IFTTT equivalent) userRevokedAccess revoke locally, stop all downstream sends

Subscribe with POST /1/user/-/{collection}/apiSubscriptions/{subscription-id}.json. Pick a subscription-id that is your own stable member reference so notifications route without a lookup table.

The subscriber endpoint handshake has two halves people miss. First, verification: Fitbit sends GET /your-endpoint?verify=<code> and expects 204 when the code matches the one in your dev.fitbit.com app settings and 404 when it does not. Returning 200 for both fails the check. Second, every notification POST carries X-Fitbit-Signature, an HMAC-SHA1 of the raw request body keyed on your client secret with a trailing ampersand, base64 encoded:

import base64, hashlib, hmac

def valid_signature(raw_body: bytes, header: str, client_secret: str) -> bool:
    key = (client_secret + "&").encode()
    digest = hmac.new(key, raw_body, hashlib.sha1).digest()
    return hmac.compare_digest(base64.b64encode(digest).decode(), header)

Validate against the raw bytes, before any JSON parsing or framework middleware reformats the body. Verify the current header name and key construction against Fitbit's developer docs when you implement, since these details do change.

Notifications arrive in minutes, not seconds, and delivery is not guaranteed. Build a reconciliation sweep that re-reads the last 48 hours for any member whose data looks thinner than their history suggests it should, and alert when a member with a daily logging pattern goes quiet for longer than their normal gap. That quiet-detection job is the thing that would have caught the original IFTTT failure, so build it even if you never expect to need it.

What you still have to build

This repository stops well short of production. You still need token storage with encryption at rest and a refresh loop, idempotency on notification handling because Fitbit will redeliver, a dead letter queue for failed downstream sends, consent and retention handling for health data that your jurisdiction almost certainly regulates, and the actual destination integration that replaces whatever the old Applet's action step was doing. Treat what is here as the first two days of a two-week migration.

Why we built this

Avalux builds automation for small and mid-sized businesses, which means we spend a lot of time inside stacks that were assembled by a founder on a Sunday and then quietly became load-bearing. Consumer glue is genuinely good at getting a business to its first working workflow. It is bad at surviving a vendor deprecation, because the failure is silent and the inventory is unknowable.

We built this kit after watching the same pattern repeat: the deadline is public for months, nobody maps their exposure, and the scramble happens in the last two weeks with incomplete information. The inventory pass is boring and it is the part that actually reduces risk, so it is the part we open sourced.

If you would rather not run this migration yourself, or you want the hardened version with token storage, reconciliation, and monitoring already built, that is the kind of work we do. Reach us at avalux.io.

Avalux's other open source projects

Issues and pull requests are welcome, particularly corrections to the trigger mapping table from anyone who has run this migration in anger.

License

MIT. See LICENSE. Use it commercially, fork it, ship it to clients, no attribution required.

Keywords

fitbit ifttt shutdown, google health service migration, fitbit applet replacement, ifttt fitbit service retirement September 30 2026, fitbit web api subscriptions, fitbit legacy account to google account conversion, ifttt applet inventory, fitbit webhook subscriber endpoint, x-fitbit-signature validation, fitness studio automation migration, corporate wellness step challenge api, wellness coach client automation, fitbit oauth2 pkce scopes, fitbit api rate limit 150 requests per hour, replace ifttt applet with api integration

About

Inventory every IFTTT Applet that depends on Fitbit, flag the Google account conversion it needs first, and rebuild it on the Fitbit Web API before the September 30 shutdown.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages