Skip to content

About

CLI for automating and managing Domo instances. Bulk operations on DataFlows, DataSets, Streams, PDP policies, content sharing, and more. Also includes skills and OpenAPI definitions that can help an AI model use Domo more extensively.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

domo-scripts

CLI toolkit for automating and managing Domo business intelligence instances. Bulk operations on DataFlows, DataSets, Streams, PDP policies, content sharing, and more — all through a single entry point.

Install

This package is not published to the npm registry. Install it directly from GitHub.

As a dependency in another project

npm install github:brycewc/domo-scripts            # latest main
npm install github:brycewc/domo-scripts#v1.0.0     # pinned to a release tag

or in your package.json:

"dependencies": {
  "domo-scripts": "github:brycewc/domo-scripts#v1.0.0"
}

There is no build step, so a plain npm install (or yarn add) is all that's needed.

Then create a .env in your project's root (the directory you run commands from) with your Domo credentials:

DOMO_INSTANCE=your-instance
DOMO_ACCESS_TOKEN=your-access-token

The instance name is the subdomain from your Domo URL (https://<instance>.domo.com). Config (.env / .env.<name>), logs/, and id-mappings/ all resolve against your project's working directory, not the installed package. You can also supply DOMO_INSTANCE / DOMO_ACCESS_TOKEN as real environment variables (e.g. in CI) with no .env file at all.

Use the CLI — the package installs a domo-scripts bin:

npx domo-scripts --help
npx domo-scripts bulk-share-content --file content.csv --user 12345 --content-type card

Use it as a library — require('domo-scripts') returns the shared modules:

const { api, readCSV, resolveIds, createLogger, config } = require('domo-scripts');

For local development on this repo

git clone https://github.com/brycewc/domo-scripts.git
cd domo-scripts
yarn install
cp .env.example .env

Edit .env with your Domo credentials (same variables as above), then run commands with node cli.js <command>.

Multiple Environments

To target more than one Domo instance, create a per-environment file alongside .env:

.env.prod        # DOMO_INSTANCE=acme-prod, DOMO_ACCESS_TOKEN=...
.env.sandbox     # DOMO_INSTANCE=acme-sandbox, DOMO_ACCESS_TOKEN=...

Select one at runtime with --env <name>:

node cli.js --env prod bulk-rename-datasets --file ds.csv
node cli.js --env sandbox bulk-rename-datasets --file ds.csv --dry-run

.env.* files are git-ignored. A bare .env is still loaded as a fallback for any shared defaults.

Transferring Between Instances

Migration commands (e.g. transfer-stream) operate on two instances at once. Pass both env names:

node cli.js transfer-stream --source-env prod --target-env sandbox --stream-id 12345
node cli.js transfer-stream --source-env prod --target-env sandbox --file streams.csv --dry-run

Each transfer records old→new IDs in id-mappings/<source>_to_<target>.json (also git-ignored), so multiple instance pairs can coexist (prod_to_sandbox.json, prod_to_dev.json, etc.). Some kinds — accounts, users, providers — must be pre-populated by hand before transferring assets that reference them; commands abort with a clear error if a required mapping is missing.

Usage

node cli.js [--env <name>] <command> [options]
node cli.js --help                    # List all commands
node cli.js <command> --help          # Command-specific options

Quick Examples

# Update stream schedules to once daily between 6 AM and 8 PM
node cli.js bulk-update-stream-schedules --file "streams.csv" --start-hour 6 --end-hour 20

# Add trigger conditions to dataflows from a CSV
node cli.js bulk-add-dataflow-trigger-condition --file "dataflows.csv" --column "DataFlow ID"

# Or pass a single ID for debug logging
node cli.js bulk-add-dataflow-trigger-condition --id 123

# Upload data to a dataset in batches
node cli.js upload-dataset --file "data.csv" --dataset-id "abc-123" --batch-size 50000

# Share content with a user
node cli.js bulk-share-content --file "content.csv" --user "12345" --content-type "card"

# Preview destructive changes with dry run
node cli.js bulk-delete-content --file "datasets.csv" --object-types "dataset" --id-column "DataSet ID" --dry-run

# Filter CSV input before processing
node cli.js bulk-update-stream-schedules --file "streams.csv" --filter-column "status" --filter-value "ACTIVE"

Commands

Command Description
build-activity-log-type-map Build a map of activity-log object types to their available event types (actions), written to a dated JSON file
bulk-add-dataflow-tags Add tags to dataflows from a CSV or by owner
bulk-add-dataflow-trigger-condition Add DATAFLOW_LAST_RUN trigger conditions to dataflow triggers
bulk-add-dataset-tags Add tags to datasets from a CSV or by owner
bulk-apply-pdp-policies Copy PDP policies from a source dataset to target datasets, or (without --source-dataset-id) add users/groups to each target's All Rows policy
bulk-convert-stream-provider Convert streams from one connector type to another
bulk-delete-content Delete mixed content (dataflows, cards, datasets, groups, beast modes, variables, pages, alerts, scheduled reports, app-studio apps, worksheets, custom apps, Code Engine packages, Jupyter workspaces, AI projects, AI models, workflows, projects, project tasks, goals, metrics, filesets, AppDB collections, accounts, workspaces) from a CSV, routing each row to the right endpoint by type — consumes the bulk-list-user-content CSV directly; --delete-output-datasets also deletes each dataflow's output datasets
bulk-delete-dataflow-triggers Remove all triggers from dataflows listed in a CSV
bulk-delete-users Delete users listed in a CSV. Does not check or transfer ownership — prompts for confirmation.
bulk-export-dataset-versions Export historical versions of a dataset
bulk-list-user-content List everything a set of users own (datasets, cards, pages, etc.) into a single Excel or CSV file — one row per (user, object), including a clickable link to each object (--format, default xlsx)
bulk-rename-dataflows Find/replace in dataflow names across the instance
bulk-rename-datasets Find/replace in dataset names across the instance, or rename explicit IDs to new names from a CSV (--file)
bulk-revoke-access-tokens Revoke developer access tokens by ID, CSV, owner, expiration, or deleted owner
bulk-unshare-content Unshare content in bulk
bulk-share-content Share content (cards, datasets, pages, dataflows) with users/groups
bulk-transfer-ownership Transfer ownership of a user's content (datasets, cards, pages, etc.) to a new owner — a user or a group — either all discovered from the user, from a CSV (per-row owner id + USER/GROUP type supported), or an ad-hoc list of IDs via --id/--ids. --verify re-reads every transferred object afterwards to confirm the owner actually moved; beast-mode link pruning (which can delete a formula) is opt-in via --prune-invalid-functions
bulk-update-column-pdp-policy Update users/groups on a column-based PDP policy
bulk-update-stream-schedules Change stream schedules to daily (randomized times), manual, or restore arbitrary schedules from a CSV (--mode from-file)
bulk-update-stream-update-method Change stream update mode from Replace to Append
bulk-update-users Bulk update user attributes from a CSV via PATCH (one row per user)
check-credentials Validate the configured API credentials against the selected instance
clear-logs Delete log files under logs/, keeping dry-run plans and retryable run logs unless --include-plans (supports --dry-run and --command filter)
delete-dashboard-tree Delete a dashboard and every subdashboard beneath it, deepest first (cards on the pages are left in place); --dry-run previews the tree and --from-dry-run deletes exactly that list
delete-unused-beast-modes Find and bulk-delete beast modes with no active links (not used in any card or view), optionally filtered by owner, dataset, or creation date; variables excluded unless --include-variables, archived beast modes unless --include-archived
export-dashboard-content Walk a dashboard and every subdashboard, exporting each page as a PowerPoint deck, each card as a PDF render, a PNG render and its definition as JSON (chart cards get the Analyzer definition: chart config, the query each component runs, slicers, beast modes, drill path, dataset columns; notebook cards get their markup and rendered HTML), the original file behind every doc/image card, every file embedded in a notebook card, and every dataset the cards read from as Excel. Output mirrors the page hierarchy; datasets are deduplicated at the root, and a cards.xlsx index there maps every card to the dataset behind it and to its exported files (--index-format csv, --no-card-index). A re-run redoes everything by default: --skip-existing reuses what is already on disk so a killed run can be resumed, --clear wipes each page folder first. A dataset Domo has vaulted cannot be queried, so a failed dataset export is retried once after requesting a defrost and waiting for it to thaw (--defrost-timeout <minutes>, default 30, 0 to skip)
extract-card-ids Extract card IDs from a page export JSON
replace-function-references Replace every reference to one beast mode / variable with another across the instance — rewrites the formula and links of each function that nests it, then saves in batches
run-workflow-from-csv Convert a CSV to workflow input format and run a Domo workflow
swap-input-in-dataflows Replace a dataset input across all consuming dataflows
transfer-beast-modes-to-content-owners Transfer a user's beast modes to whoever owns the card or dataset each one lives on. Because a beast mode cannot be group-owned, a group-owned resource falls through a cascade: the producing dataflow's owner when the dataset is a dataflow output, else the departing user's manager if they are in the group, else the group member owning the most beast modes (ties go to the older account). --dry-run plus --output writes the full routing plan to a CSV for review; --verify re-reads every beast mode afterwards
transfer-stream Copy a stream (and its input dataset) from one instance to another
upload-dataset Upload CSV data to a dataset in configurable batches

Common Options

Most bulk commands that process a list of IDs support these options:

Option Description
--file, -f Path to a CSV file containing IDs
--column, -c CSV column name to extract IDs from
--<entity>-id Single ID (enables detailed debug logging)
--<entity>-ids Comma-separated IDs
--filter-column Filter CSV rows: column name to match
--filter-value Filter CSV rows: required value
--dry-run Preview changes without applying them
--from-dry-run [file] Run exactly what a dry run planned, without rediscovering it (default: the latest dry run log)
--retry-errors [file] Retry the failed and unreached items of an earlier run (default: the latest run log)
--max-age <hours> Allow --from-dry-run / --retry-errors to use a log older than 24 hours

Reusing a Dry Run or Retrying a Run

Dry runs of large jobs can take a long time, and most of that time is discovery (searching, fetching, deciding what to change). Instead of repeating it, run the plan the dry run already wrote:

node cli.js delete-unused-beast-modes --created-before 2026-06-01 --dry-run   # slow: scans every beast mode
node cli.js delete-unused-beast-modes --from-dry-run                          # deletes exactly that list

If a real run has failures, or is interrupted (Ctrl-C, crash, lost connection), retry just what did not finish:

node cli.js delete-unused-beast-modes --retry-errors

How it works:

  • A dry run's log (logs/<command>/dry_run_<timestamp>.json) is the plan. --from-dry-run takes its dry-run rows and runs them through the command's normal execute step.
  • A real run checkpoints its log every 30 seconds and on exit, recording planned items it never reached under unreached. --retry-errors takes the error rows plus those unreached items. Items that failed before any change was attempted (a failed lookup during discovery) are listed but not retried. Retrying a retry works the same way.
  • The options recorded in the log are reused. Flags that change what the run selects or how it acts (filters, input files, IDs, --dry-run) are rejected alongside these flags. Execution-only flags such as --batch-size, --concurrency and --yes are still allowed.
  • The log must come from the same command and the same instance as the current --env, and be less than 24 hours old unless --max-age is passed. You are warned when a later run already used the same log, and asked to confirm before anything changes.
  • Commands that save whole objects (dataflows, streams, beast mode templates) re-fetch each object, check it still matches what the dry run saw, and skip it if it changed, so a plan never overwrites newer edits.
  • Commands that fetch and change each item in one step support only --retry-errors, since replaying their dry run would save nothing. Run node cli.js <command> --help to see which flags a command supports.
  • clear-logs keeps plans and retryable run logs unless --include-plans is passed.

Project Structure

domo-scripts/
├── cli.js              # Entry point, dispatches to commands
├── lib/
│   ├── index.js        # Re-exports all shared modules
│   ├── config.js       # Environment config and auth
│   ├── api.js          # Authenticated Domo API client (get/put/post/del)
│   ├── csv.js          # CSV parsing with optional filtering
│   ├── input.js        # Resolve IDs from CSV/flags
│   ├── log.js          # Debug and run log utilities
│   └── plan.js         # Loads dry-run plans and run logs for --from-dry-run / --retry-errors
├── commands/           # One file per command (29 total)
├── logs/               # Generated run/debug logs (git-ignored)
├── .env                # Your credentials (git-ignored)
├── .env.<name>         # Per-environment credentials, selected with --env (git-ignored)
├── .env.example        # Template for .env
└── id-mappings/        # Per-env-pair old→new ID mappings, written by transfer commands (git-ignored)

Adding a New Command

  1. Create commands/your-command.js
  2. Import shared libs: const { api, resolveIds, createLogger } = require('../lib');
  3. Add --help handling before any API calls
  4. Register it in the commands map in cli.js

Logging

Commands that support logging write JSON files to logs/<commandName>/:

  • Run logs (run_<timestamp>.json): summary of all items processed in a bulk run. Written as the run goes, so an interrupted run still leaves a log that --retry-errors can finish.
  • Debug logs (debug_<itemId>_<timestamp>.json): detailed per-item logs when using --<entity>-id
  • Dry-run variants are prefixed with dry_. Dry runs always write a run log (even for a single ID), because it is the plan --from-dry-run reads.

About

CLI for automating and managing Domo instances. Bulk operations on DataFlows, DataSets, Streams, PDP policies, content sharing, and more. Also includes skills and OpenAPI definitions that can help an AI model use Domo more extensively.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages