Skip to content

Webex Scaffolder Backend Module for Backstage

npm package CI npm downloads Node.js coverage: 100% license

A Backstage backend module that adds the webex:webhooks:sendMessage Scaffolder action. The action sends text or Markdown messages to one or more Webex incoming webhooks.

Features

  • Supports Webex text and markdown message formats.
  • Sends one message to multiple incoming webhooks.
  • Continues processing when an individual webhook fails.
  • Reports delivery failures through the failedMessages action output.
  • Integrates with the Backstage new backend system as a Scaffolder module.

Requirements

  • Backstage release line 1.52 or a compatible set of @backstage packages.
  • Node.js 22.22.2, 24.15.0, or a newer supported even-numbered release.
  • Corepack with the repository-pinned Yarn 4.8.1 package manager.
  • At least one Webex incoming-webhook URL.

Treat webhook URLs as secrets. Do not commit real URLs to templates or source control.

Installation

Install the module in the Backstage backend package:

yarn --cwd packages/backend add @coderrob/backstage-plugin-scaffolder-backend-module-webex

Registration

Add the module to packages/backend/src/index.ts alongside the Scaffolder backend plugin:

backend.add(import('@backstage/plugin-scaffolder-backend'));
backend.add(import('@coderrob/backstage-plugin-scaffolder-backend-module-webex'));

The package's default export is the webex Scaffolder backend module.

Configuration

Configure default destinations and the request timeout in app-config.yaml:

webex:
  webhooks:
    urls:
      - ${WEBEX_INCOMING_WEBHOOK_URL}
    timeout:
      seconds: 15
Configuration key Type Required Default Description
webex.webhooks.urls string[] No None Default incoming-webhook destinations.
webex.webhooks.timeout HumanDuration No { seconds: 10 } Timeout for each HTTP request.

The timeout uses Backstage's human-duration object. It accepts one or more of years, months, weeks, days, hours, minutes, seconds, and milliseconds:

webex:
  webhooks:
    timeout:
      minutes: 1
      seconds: 30

webex.webhooks.urls is marked as secret in the package's Backstage configuration schema. Use environment-variable substitution or another secret configuration source; do not store real webhook URLs in source control.

Every configured URL must use the format issued by the Webex Incoming Webhooks integration:

https://webexapis.com/v1/webhooks/incoming/<webhook-token>

The module rejects configured URLs with another scheme, host, path, query string, or fragment. Validation errors do not include the secret URL.

Destination precedence

The action selects destinations in this order:

  1. A non-empty webhooks array supplied by the Software Template step.
  2. The default webex.webhooks.urls array from Backstage configuration.

When no configured defaults exist, webhooks is required in the action input. When defaults exist, webhooks is optional and overrides the entire configured array when supplied.

Usage

Use configured destinations

When webex.webhooks.urls is configured, a template only needs to supply the message format and content:

- id: send-webex-message
  name: Send Webex message
  action: webex:webhooks:sendMessage
  input:
    format: markdown
    message: Deployment `${{ parameters.version }}` completed.

Override destinations for one step

Supply webhooks to replace the configured defaults for one action invocation:

- id: send-webex-message
  name: Send Webex message
  action: webex:webhooks:sendMessage
  input:
    format: text
    message: Build completed.
    webhooks:
      - ${{ secrets.WEBEX_INCOMING_WEBHOOK_URL }}

Pass webhook URLs through Backstage secrets rather than ordinary template parameters, because the URL contains a credential.

Input

Name Type Required Description
format text | markdown Yes Selects the Webex JSON payload field.
message string Yes Non-empty plain-text or Markdown message.
webhooks non-empty array of URLs Conditional Replaces configured destinations when supplied.

webhooks is required only when webex.webhooks.urls is not configured. Each input URL must match the Webex Incoming Webhooks URL format shown above.

Output

Name Type Description
failedMessages array of strings Delivery failures; empty when every webhook returns HTTP 200.

Delivery behavior

Webhook requests are processed sequentially using the configured timeout. An HTTP 200 response is considered successful. Other HTTP responses and request errors are added to failedMessages; a failure does not prevent the remaining destinations from being attempted.

Development

Project structure

  • src/contracts.ts defines the package's shared public API contracts.
  • src/actions/ contains the Scaffolder action implementation.
  • src/config/ translates Backstage configuration into action options.
  • src/utils/ contains generic internal runtime guards.
  • src/webex/ validates Webex Incoming Webhook URLs and delivers messages.
  • src/__tests__/ contains cross-cutting package contract tests.
  • scripts/package/ contains npm prepack and publication validation tooling.
  • scripts/local-setup.sh creates a disposable Backstage app for integration testing.

Tests for a production module are colocated with that module. yarn test runs the suite once and exits; use yarn test:watch for an interactive local watch session. yarn test:leaks runs Jest serially with memory-leak and open-handle detection.

Install dependencies and run the quality checks:

yarn install
yarn audit
yarn lint
yarn tsc:full
yarn test:coverage
yarn test:leaks
yarn build
yarn publint

Local Backstage integration

Run the setup script from a Unix-like shell with Git, a supported Node.js version, Corepack, and npx available:

bash scripts/local-setup.sh

Set BACKSTAGE_APP_DIR to override the default sibling application directory. The target must not already exist.

The script builds and packages the current checkout, creates ../my-backstage-app, installs the package in its backend, registers the backend module, adds an example Webex scaffolder template, and starts the Backstage development app. The process remains attached to the terminal; press Ctrl+C to stop it. Keeping the app beside the plugin repository prevents its workspace from affecting plugin linting and publication. The packaged plugin is kept under ../my-backstage-app/.local-packages, so subsequent installs do not depend on a temporary file or an unpublished Git commit.

Disable automatic startup for setup-only or automated checks with:

BACKSTAGE_START=false bash scripts/local-setup.sh

The script refuses to overwrite an existing ../my-backstage-app. Move or remove an earlier disposable application before rerunning it.

The audit fails on high or critical dependency advisories. The test suite enforces at least 95% coverage for statements, branches, functions, and lines. Publint validates the Backstage-transformed npm artifact and its explicit publication allowlist.

Contributing

Issues and pull requests are welcome. Please include tests for behavioral changes and ensure all development checks pass before opening a pull request.

License

Licensed under the Apache License 2.0.

Support the project

Buy Me a Coffee

About

A Backstage.io backend scaffolding plugin that provides actions for sending messages via Webex Incoming Webhooks in scaffolder templates, enabling automated notifications and integrations within your Backstage workflows.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages