Webhooks on new flights

It would be nice to have a webhook that is automatically sent when new flights are available on specific accounts. Currently, we need to poll the flight log endpoint which creates more traffic on both fronts and leads to delays in flight log availability.

For instance, using the API we would create a webhook record in flight reader that would record:

  • account_id
  • webhook_url

Then the flight reader api would hit the webhook_url with the basic flight information so our system could then kick off a pull / decrypt process as necessary.

1 Like

I have a few questions for you:

  • Would the process look something like this?

    • Retrieve the account_id for a new DJI account
    • Call a new endpoint to subscribe that account by passing the account_id and URL to the webhook receiver
    • Send webhook notifications to the webhook receiver as new flight logs are discovered
  • What’s the maximum amount of time that would be reasonable to wait between new flight log checks? Once a day? Several times a day? While near real-time notifications would be fantastic, we also wouldn’t want to overwhelm any systems.

  • If the account_id becomes invalid at some point (like when the account owner changes their DJI password), would you expect to receive some type of message indicating there is a problem? And perhaps the webhook should auto unsubscribe itself at that point until the account issue has been resolved.

Anything else I missed?

This would be a great addition.

Maybe make the interval configurable with a value between a reasonable max and min range? We’d also need to (optionally) be able to identify our internal account id. So the subscribe endpoint payload could be something like:

{
  "dji_account_id": "123abc456abc789abc",
  "webhook_url": "https://example.com/webhook/",
  "interval": 30,
  "internal_id": "abc123"
}

Agree on the auto-unsubscribe if the id becomes invalid.

1 Like

@dor how about a way to subscribe to specific webhook events? That way new types of webhook events could be easily added in the future.

To receive a webhook request when a new flight log is available in the DJI Cloud for a specific DJI account, you’d subscribe to this webhook event:

{
  "event": "flight_log.created",
  "url": "https://www.YourWebsite.com/WebhookEndpoint",
  "interval": 30,
  "dji_account_id": "123abc456abc789abc",
  "metadata": {
    "internal_id": "abc123"
  }
}
  • interval would only apply to those webhook events that have a configurable interval (since they don’t notify in real-time).
  • metadata would be an optional set of key-value pairs that you’d like included in all webhook requests.

For receiving real-time notifications when a DJI account is failing to authenticate (like when the DJI account password is changed), you could optionally subscribe to this webhook event:

{
  "event": "account.dji.disconnected",
  "url": "https://www.YourWebsite.com/WebhookEndpoint"
}

For receiving real-time notifications when one of your webhook subscriptions is auto cancelled (like when flight logs permanently fail to retrieve for a specific DJI account), you could optionally subscribe to this webhook event:

{
  "event": "webhook.unsubscribed",
  "url": "https://www.YourWebsite.com/WebhookEndpoint"
}

Note: When possible, webhook subscriptions would be retried after failure instead of instantly cancelling on the first failure. But in a case of a failing DJI account authentication, that request would continue to fail (a case of a permanent failure) until the /v1/accounts/dji endpoint is called again to update the DJI account password.

Great suggestion on specifying the event to subscribe to - nice bit of future-proofing.

Not sure how useful the account.dji.disconnected would be for us as we encrypt the DJI account id at our end with a per-account salt so almost impossible to reverse lookup (hence the ask for metadata passthrough).

I could include the dji_account_id and metadata from the flight_log.created webhook subscription.

That would solve it! :+1:

Think you got all the big pieces - the frequency though is the real value here to us. We’re polling DJI hourly for new flights so if we can’t get that window down to 15-30 min maybe, there’s not as much value for us as we currently have the whole polling infrastructure already setup and working. If we can match the hour timeframe then the big advantage would be to simplify our implementation and remove all of our polling infrastructure all together.

In this workflow, if your system is responsible for reflecting the status of the passwords, I think webhooks on credentials becoming invalid would be required otherwise we’d be unaware when the system stops reporting.

Yes, I think 15 minute intervals is doable.

Agreed.

Here are example payloads for the above webhooks:

flight_log.created

{
  "id": "whe_48lp66db15d39q4waytq7cs2q11p",
  "event": "flight_log.created",
  "description": "Occurs when a new flight log is uploaded to the DJI Cloud.",
  "createdUtc": "2023-09-16T17:35:47.1773314Z",
  "djiAccountId": "c8415db575f219f3fb34a7047939b500",
  "djiFlightLogs": [
    {
      "aircraftName": "Mavic 3",
      "aircraftSerialNumber": "1231F45TB19ZV3AF122B",
      "downloadUrl": "https://api.flightreader.com/v1/files/flight-logs/1d8a3d88433bf0a59537c2bc748f68710/DJIFlightRecord_2023-03-29_[12-28-24].txt",
      "fileName": "DJIFlightRecord_2023-03-29_[12-28-24].txt",
      "maxHeight": 65,
      "md5Hash": "386425e054c9ad3db38c19cfc4cb0252",
      "timestamp": 1680107304788,
      "totalDistance": 1485.5077,
      "totalTime": 165400
    }
  ],
  "metadata": {
    "internalId": "12345"
  }
}

account.dji.disconnected

{
  "id": "whe_as7gd1hr2gyubcx5b10wxvf91bvs",
  "event": "account.dji.disconnected",
  "description": "Occurs when the DJI Cloud token expires for a connected DJI account. Use the /v1/accounts/dji endpoint to reconnect the DJI account.",
  "createdUtc": "2023-09-16T17:35:49.0376009Z",
  "djiAccountId": "c8415db575f219f3fb34a7047939b500",
  "metadata": {
    "internalId": "12345"
  },
  "reason": "DJI account password is invalid."
}

webhook.unsubscribed

{
  "id": "whe_npkmgqgtkssu24rd811uxctuz5ne",
  "event": "webhook.unsubscribed",
  "description": "Occurs when a webhook is automatically disabled due to a permanent failure.",
  "createdUtc": "2023-09-16T17:35:50.8449973Z",
  "reason": "The webhook endpoint returned a 500 HTTP status code on the final POST attempt.",
  "url": "https://webhook.site/c6ad6033-c81c-4f2e-8aac-7b17082164c7",
  "webhook": {
    "id": "wh_9f3e1e1eada8799eea40e8f0",
    "event": "flight_log.created",
    "description": "Occurs when a new flight log is uploaded to the DJI Cloud.",
    "createdUtc": "2023-09-14T06:17:07Z",
    "djiAccountId": "c8415db575f219f3fb34a7047939b500",
    "interval": 15,
    "metadata": {
      "internalId": "12345"
    }
  }
}

Some additional details:
  • The webhook event id (e.g. whe_48lp66db15d39q4waytq7cs2q11p) can be used to verify whether or not the webhook has already been processed on your end (in case it’s successfully delivered more than once).

  • An “Api-Signature” header will be included so you can optionally verify the webhook was sent from the Flight Reader API. I’ll include more details about this in the API documentation when these changes go to production.

1 Like

Looks awesome @msinger