List icon
OutputValues icon
If icon
SlackIncomingWebhook icon
Log icon
Schedule icon

Dropbox Stale File Retention Sentinel

List Dropbox files past a retention threshold, alert Slack with the stale paths, and log the result for platform teams.

Categories
Business

A shared Dropbox folder accumulates exports, old reports, and one-off uploads nobody ever circles back to clean up. Dropbox has no scheduled, folder-wide retention sweep of its own, only a per-file view if someone opens it. This blueprint reads what is actually under a path, flags what has outlived its retention window by its own clientModified date, and reports the real file paths, not a guess.

This blueprint was created by Mohit Jeswani.

How it works

  1. list_files (io.kestra.plugin.dropbox.files.List) lists every entry under dropbox_path, recursively when recursive_scan is true. Read-only; nothing in Dropbox is changed. allowFailure: true covers an API or auth error without failing the flow outright.
  2. evaluate (io.kestra.plugin.core.output.OutputValues) filters to entries where type is file and clientModified is older than retention_days, with a jq filter, since the Dropbox List API itself has no age-based filter.
  3. route (io.kestra.plugin.core.flow.If):
    • compliant: logs that nothing is stale.
    • alert: posts the count and file paths to Slack.
  4. summary logs the count and severity, closing the governance cycle.
  5. errors alerts Slack if the flow itself fails, for example an expired access token.

What you get

  • A real count and path list of what is actually past retention, not an estimate from folder size alone.
  • Folders correctly excluded from the stale count, since clientModified is null for a folder and this check only ever evaluates type == "file".
  • A read-only check with zero risk of deleting a real file.

Who it's for

  • Platform and IT teams who own a shared Dropbox folder and have no process catching old exports or reports nobody cleaned up.
  • Teams evaluating the Dropbox plugin who want a worked example of files.List used for a governance check, distinct from this repo's existing Dropbox blueprints, which handle intake, backup, and report distribution rather than retention auditing.

Why orchestrate this with Kestra

Dropbox shows a file's modified date one file at a time; it does not compare that date across a whole folder against a retention policy you declare, or notify anyone. Kestra keeps retention_days as a flow input, turns the scan into a Slack page naming the actual stale file paths, and keeps a full execution history of every run.

Prerequisites

  • A Dropbox account or team folder with an access token scoped to read dropbox_path.
  • At least one file in the target path old enough to confirm the filter logic against.
  • A Slack incoming webhook URL.

This flow calls the Dropbox API directly over HTTPS; there is no official local Dropbox emulator, so list_files cannot be exercised against a local Docker container.

Secrets

  • DROPBOX_ACCESS_TOKEN: the Dropbox access token used by list_files. In Kestra OSS, provide it as the base64-encoded environment variable SECRET_DROPBOX_ACCESS_TOKEN.
  • SLACK_WEBHOOK_URL: used by alert and the errors block. In Kestra OSS, provide it as the base64-encoded environment variable SECRET_SLACK_WEBHOOK_URL.

Inputs

Input Default Purpose
dropbox_path `` (root) Dropbox path to scan
recursive_scan true Whether to traverse sub-folders
retention_days 180 Age past which a file is reported stale
max_stale_count 1 Matched-file count that triggers the Slack alert

Outputs

  • {{ outputs.list_files.rows }}: every scanned entry (name, id, path, type, size, clientModified).
  • {{ outputs.evaluate.values.stale_count }} / .stale_paths: how many files are stale and their display paths, semicolon-joined.
  • {{ outputs.evaluate.values.severity }}: OK, STALE_FILES_FOUND, or CRITICAL.

Pitfalls

  • clientModified is the last time the file's content changed, set by the client that uploaded or edited it, not when Dropbox itself last touched the file internally; a file re-synced but not actually edited does not reset the staleness clock.
  • limit on files.List defaults to 2000 entries per call with no pagination handled here; a path with more entries than that is only partially scanned in one run.
  • recursive_scan: false only lists the top level of dropbox_path; a stale file several folders deep is invisible to this check unless recursion is enabled.

Quick start

  1. Add the DROPBOX_ACCESS_TOKEN and SLACK_WEBHOOK_URL secrets.
  2. Set dropbox_path to a real folder.
  3. Run the flow manually and confirm summary logs a count.
  4. Raise retention_days above every scanned file's age, then lower it below a known old file's age, to confirm both compliant and alert fire correctly.
  5. Enable the weekly trigger once retention_days matches your actual retention policy.

How to extend

  • Loop over several dropbox_path values with io.kestra.plugin.core.flow.Loop to cover more than one shared folder in a single scheduled run.
  • Chain io.kestra.plugin.dropbox.files.Move on each stale file to a "pending deletion" sub-folder instead of deleting outright, gated behind an explicit confirm_move input.
  • Sum size across stale entries in the evaluate step to report reclaimable bytes alongside the file count.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.