How can I setup Fitbit Subscribers/Webhooks via Pipedream?

Pipedream has a Fitbit integration, and I’ve successfully setup an automation which syncs my Fitbit sleep data to TogglTrack, triggered daily on a schedule.

However, Fitbit also offers setting up Subscribers (Using Subscriptions), which can trigger webhooks whenever a new event happens: “Fitbit has developed a subscription service allowing 3rd-party applications to be notified when a Fitbit user has updated their data”

Example use case: Fitbit device notices I’ve woken up → Fitbit device syncs to fitbit dot com → Pipedream webhook is notified → Pipedream automation syncs my Fitbit sleep time entry to TogglTrack.


However, as I understand it, Fitbit Subscribers must be configured for a “Fitbit app” setup at dev dot fitbit dot com. Presumably Pipedream’s own Fitbit OAuth token is based on their own official app setup at that URL, but I’m not aware of any way to access existing Subscribers on that app or to add new ones. Conversely, I can setup my own app at dev dot fitbit dot com, but then Pipedream’s Fitbit OAuth token doesn’t help, and thus I’d need to setup my own Fitbit OAuth authentication in Pipedream, which I don’t know how to do.

Any suggestions for how to proceed from here?

Hi @tobias.daenzer_pipedream,

Based on the information provided, it seems you’re looking to utilize Fitbit’s subscription service to trigger a Pipedream webhook when new Fitbit data is available. To achieve this, you would indeed need to set up a Fitbit app on dev.fitbit.com and configure the subscription service to send notifications to a Pipedream endpoint.

Here’s a step-by-step guide on how you might proceed:

  1. Create a Fitbit App: Go to dev.fitbit.com, sign up or log in, and create an app. This will give you the OAuth credentials you need to authenticate API requests.

  2. Set up OAuth in Pipedream: You’ll need to handle OAuth authentication in Pipedream for your Fitbit app. This involves setting up an OAuth app on Pipedream and using the auth object in your Pipedream code.

  3. Configure a Pipedream Workflow with a Webhook Trigger: In Pipedream, create a new workflow with an HTTP/Webhook trigger. This will give you a unique URL that you can use to receive notifications from Fitbit.

  4. Set up Fitbit Subscribers: Using the Fitbit API, configure subscribers to send notifications to your Pipedream webhook URL when new data is available.

  5. Sync Data to TogglTrack: Within the Pipedream workflow, after the webhook trigger, add steps to process the incoming Fitbit data and sync it to TogglTrack.

Since you’re looking to set up your own OAuth flow, you might need to write custom code to handle the OAuth tokens and refreshing them as needed. Pipedream’s platform supports custom OAuth and API key authentication, but the specific steps to set this up would depend on the capabilities of the Pipedream platform at the time of your implementation.

If you need further assistance with setting up OAuth for your Fitbit app in Pipedream or configuring the workflow, please visit Pipedream’s support page for more help.
I’m a bot powered by Pipedream and GPT-4. I’m still learning, so please double check my answers and code! Learn how to build your own.

That bot reply doesn’t help. In particular, the answer re: Pipedream supporting custom OAuth authentication is wrong, right? Unless it means “Pipedream supports doing arbitrary things because you can write arbitrary code”. There’s an open Github issue for this point, after all.

Bump.

Also interested here. I’m at the step where I need to verify the subscriber in Fitbit.

I have set up the subscriber in Fitbit using the endpoint, however I have a verification code and have no idea where to put that in pipedream to have the subscription verified.

I need that so the targeted events start to flow in and I configure the rest of my workflow.

I did manage to do this part on my own - it’s not where I initially got stuck -, so I can help you with this step.

A word of caution, since I finally did get subscribers to work: I noticed one limitation of using Fitbit subscribers with Pipedream: At least for the “activities” scope, Fitbit sends a whole bunch of notifications throughout the day (seemingly 2-5x per awake hour), and every such notification triggers the Pipedream webhook and therefore costs at least 1 credit. Whereas it seems that the “sleep” subscriber seems to trigger only a few (2-ish?) times per night.

Anyway, here’s how to verify the subscriber with the given verification code:

  1. The subscriber endpoint URL configured at https://dev.fitbit.com/apps/ must be a Pipedream webhook URL configured as a Pipedream Webhook trigger URL of the form https://your_unique_webhook_string.m.pipedream.net
  2. In the “Configure” step of your Pipedream Webhook component, set “HTTP Response” to “Return a custom response from your workflow”.
  3. As the next step in the Pipedream workflow, add a “Return HTTP response” component.
  4. As per Fitbit’s docs, the Pipedream automation must respond to the verification GET request with either HTTP 204 or 404, depending on whether the verification code is correct or not. And later on, once the subscriber is configured and Fitbit sends notification POST requests, Fitbit expects a HTTP 204 response.
  5. Because of these requirements from the docs, I used the following custom code in that “Return HTTP response” component:
// To return a custom HTTP response, use $.respond() [requires HTTP trigger]
export default defineComponent({
  async run({ steps, $ }) {
    if (steps.trigger.event.method == 'POST') {
      await $.respond({status: 204, headers: {}})
      return steps.trigger.event.body
    } else if (steps.trigger.event.method == 'GET') {
      let correct_code = "YOUR_VERIFICATION_CODE_FOR_THIS_SUBSCRIBER_GOES_HERE"
      let current_code = steps.trigger.event.query.verify
      if (current_code == correct_code) {
        await $.respond({status: 204, headers: {}})
      } else {
        await $.respond({status: 404, headers: {}})
      }
    }
  },
})
  1. Once you’ve inserted your own verification code into that custom code, deploy this automation in Pipedream.
  2. Now you can trigger the verification step at https://dev.fitbit.com/apps/. It might take a few tries & refreshes until this succeeds, because Fitbit expects a response within 5 seconds, which Pipedream doesn’t consistently do, at least on its free tier. If the verification still doesn’t succeed after a few tries, you can check Pipedream’s event history for this workflow to debug the problem.
  3. Once the subscriber is verified and configured etc. according to the Fitbit docs, Fitbit will send notifications to the configured Pipedream webhook URL. You can then setup the rest of your workflow by adding a new code step in Pipedream, based on the returned values in steps.trigger.event.body.

And here’s where I got stuck myself, and how I eventually managed to resolve it:

As per the Fitbit docs, the final step of implementing the subscription API is to create a subscription. That is, one must send a POST request of the following form: /1/user/[user-id]/[collection-path]/apiSubscriptions/[subscription-id].json.

For example, to subscribe to my own sleep data, I’d use this URL: https://api.fitbit.com//1/user/-/sleep/apiSubscriptions/arbitrary_string.json.

These are the required headers:

    headers = {
        'accept': 'application/json',
        'content-length': "0",
        "X-Fitbit-Subscriber-Id": "your_subscriber_id_configured_at_dev.fitbit.com/apps",
        "Authorization": authorization
    }

But what is the correct authorization? Here’s where I got stuck for a long time. I initially used Pipedream’s Fitbit authorization, i.e. the following:

  token = f'{pd.inputs["fitbit"]["$auth"]["oauth_access_token"]}'
  authorization = f'Bearer {token}'
  headers = {"Authorization": authorization}

When using this authorization to create a subscription, I got a cryptic error response from Fitbit, indicating that my given subscriber ID didn’t exist, even though it clearly did. I didn’t understand this for a long while, but eventually realized that Pipedream’s authorization above presumably belongs to their own Fitbit app configured at dev.fitbit.com/apps, which I can’t access, and thus I can’t create subscribers for that app.

So instead, one has to manually authorize one’s own Fitbit app via Fitbit’s interactive OAuth 2.0 Tutorial. (This tutorial looks rather long but essentially just consists of pasting a bunch of values and clicking a few buttons, until one finally receives an OAuth2 Access Token, which is valid for 8 hours.)

Once that’s done, one can straightforwardly create a subscriber by using a one-of Pipedream workflow which makes the following HTTP request (here as Python code):

import requests
def handler(pd: "pipedream"):
    token = "your_temporary_OAuth2_access_token_goes_here"
    authorization = f'Bearer {token}'

    headers = {
        'accept': 'application/json',
        'content-length': "0",
        "X-Fitbit-Subscriber-Id": "your_subscriber_id_configured_at_dev.fitbit.com/apps"
        "Authorization": authorization
    }

    // Example Requests URL to subscribe to one's own "sleep" data.
    r = requests.post('https://api.fitbit.com/1/user/-/sleep/apiSubscriptions/pipedream-sleep.json', headers=headers)

    print(r.status_code, r.reason)
    return r.json()