CDS pluginCDS plugintypeInstalls into a CAP project and extends the runtime. CAP loads it through cds.requires or the plugin hook.See every one →What this type is →independently maintainedindependently maintainedoriginPublished by one person or a small company outside SAP. Says nothing about quality; the readings say that.See every one →

@expertum/cap-email-plugin

Sends mail on entity lifecycle events from an annotation — @email.enabled on an entity, an HTML template with {{placeholder}} substitution, and a plugin-owned log entity recording what went out and what failed.

The dispatcher is swappable through cds.requires.kinds, and the Microsoft Graph provider authenticates through the BTP Destination Service rather than holding credentials itself. Triggers are INSERT and UPDATE, so it covers "tell someone this record changed" without a handler.

Facts

Latestv0.1.1ReleasedLast pushLicenceApache-2.0

Where it sits

Lives in
Provides
NotificationsCAPNotificationscapabilityTelling a person something happened when they are not looking at the screen — a notification in the launchpad, an email, a message somewhere they already are.
Flavors
Requires
@sap/cds≥ 9@sap/cdsartifactThe peer range, as published.
Optional
@sap-cloud-sdk/http-client@sap-cloud-sdk/http-clientartifactDeclared an optional peer dependency at ^4, beside @sap-cloud-sdk/resilience, so it is present only where the project installs it.SAP Destination serviceSAP Destination serviceartifactCarries the OAuth2 client credentials the graph provider authenticates Microsoft Graph with, configured as a destination in the BTP subaccount.

Who is behind it

ExpertumExpertumOrganisationMaintains this
In the atlas: maintains 1
@expertum-net
Stijn MertensStijn MertensPersonMaintains this
In the atlas: maintains 1, contributes to 1
@stijnme
maintainersMatthis VansteenhuysePersonContributes to this
In the atlas: contributes to 1
@MVansteenhuyse
1 contributor

Before choosing this

Conditions

LicenceSAP Developer License Agreement 3.2 CAP§ 1, 2, 3A cds-plugin is used with SAP CAP materials, or an artifact is explicitly identified as a CAP plugin or application.
  • § 1 License. Productive customer applications are limited to SAP BTP or another SAP-licensed platform, and mass extraction to a non-SAP product is restricted except where solely required for SAP interoperability.
  • § 2 Intellectual Property. The agreement retains SAP's rights in the covered materials and limits making APIs, tools or software available to third parties, while preserving ownership of customer applications subject to SAP's underlying rights.
  • § 3 Artificial Intelligence Training. The agreement prohibits use of the covered materials and customer applications for training artificial-intelligence models or systems.
SAP Developer License Agreement 3.2 CAP →
PracticalFunctional boundary

Node below 22, or @sap/cds below 9: the package declares the first in engines and the second as a peer dependency. Any mail path other than Microsoft Graph, until a provider is written for it: graph is the only kind that sends, and basic, the kind configured by default, is the base class such a provider extends.

What it declares

Every artifact

Type
CDS plugin
Origin
Independently maintained
Runtime
Node.js

As a CDS plugin

Declared for
>=9
Distributed through
npm

Connections3

@expertum/cap-email-plugin connections@expertum/cap-email-pluginPROVIDES→ provides1provides stated Sends mail to a person when an annotated entity is inserted or updated, with the recipient taken from a field on the record, a fixed address or the logged-in user, and every attempt recorded in a log entity the plugin owns. @expertum/cap-email-plugin — README: https://raw.githubusercontent.com/expertum-net/cap-email-plugin/main/README.md @expertum/cap-email-plugin — README: https://raw.githubusercontent.com/expertum-net/cap-email-plugin/main/README.md @expertum/cap-email-plugin — README: https://raw.githubusercontent.com/expertum-net/cap-email-plugin/main/README.mdNotificationsNEEDS→ optionally needs2optionally needs declared If: The project installs it; peerDependenciesMeta marks it optional. Declared an optional peer dependency at ^4, beside @sap-cloud-sdk/resilience, so it is present only where the project installs it. @expertum/cap-email-plugin — package.json on main: https://raw.githubusercontent.com/expertum-net/cap-email-plugin/main/package.json@sap-cloud-sdk/http-clientifoptionally needs stated If: The graph kind is configured for Microsoft Graph. Carries the OAuth2 client credentials the graph provider authenticates Microsoft Graph with, configured as a destination in the BTP subaccount. @expertum/cap-email-plugin — README: https://raw.githubusercontent.com/expertum-net/cap-email-plugin/main/README.md @expertum/cap-email-plugin — README: https://raw.githubusercontent.com/expertum-net/cap-email-plugin/main/README.mdSAP Destination serviceif

Install

npm add @expertum/cap-email-plugin

Derived from the package name. No recipe recorded; the README has the configuration.

Where it sits in your app

Download
Your CAP applicationYour SAP BTP subaccountdocumentedmay needif The project installs it;peerDependenciesMeta marks itoptionaldocumentedmay needif The graph kind isconfigured for Microsoft Graph@expertum/cap-email-plugin, module@expertum/cap-email-…@sap-cloud-sdk/http-client, module@sap-cloud-sdk/http-…SAP Destination service, service instanceSAP Destinationservice
SAPnot SAP's, or the project's ownunder a condition

README

quoted from expertum-net/cap-email-plugin under Apache-2.0, read
expertum-net/cap-email-plugin/README.mdOn GitHub

@expertum/cap-email-plugin

A SAP CAP plugin that provides annotation-driven email automation for CAP entities. Emails are triggered on entity lifecycle events (INSERT, UPDATE) and dispatched via configurable email clients.

Features

  • Annotation-based configuration — no custom handler code required
  • Automatic trigger handling — emails sent on entity INSERT/UPDATE
  • Template support — HTML templates with {{placeholder}} substitution
  • BTP integration — leverages Destination Service for OAuth2 authentication
  • Extensible architecture — swappable email clients via cds.requires.kinds
  • Email logging — plugin-owned log entity tracks send status and errors

Prerequisites

  • SAP CAP (@sap/cds >= 9)
  • Node.js >= 22 (required for ESM + @cap-js/cds-test compatibility)
  • BTP Destination Service (for Microsoft Graph provider)

Installation

npm install @expertum/cap-email-plugin

Quick Start

1. Annotate your entity
@email.enabled: true
entity Orders {
  key ID     : UUID;
  orderNumber : String;
  status      : String;
  contactEmail: String;
}

That's it for a minimal setup. The plugin defaults to:

  • Template: Orders.html (convention-based on entity name)
  • Trigger: INSERT
  • Recipient: req.user.email (from XSUAA context)
2. Create a template

Place an HTML template in your project:

email-templates/Orders.html
<h1>Order Confirmation</h1>
<p>Your order {{orderNumber}} has been received.</p>

Placeholders use {{fieldName}} syntax, where fieldName matches a field on the annotated entity. When an email is triggered, the plugin replaces each placeholder with the corresponding value from the entity record. Missing fields are replaced with an empty string.

3. Configure the email provider

In your application's package.json:

{
  "cds": {
    "requires": {
      "email": {
        "kind": "graph",
        "email": {
          "from": "noreply@example.com",
        },
      },
    },
  },
}

The graph kind uses Microsoft Graph API via a BTP destination. Configure the destination with OAuth2ClientCredentials in your BTP subaccount.

{
  "cds": {
    "requires": {
      "email": {
        "kind": "graph",
        "destination": "microsoft-graph",
        "email": {
          "from": "noreply@example.com",
        },
      },
      "microsoft-graph": {
        "kind": "rest",
        "credentials": {
          "destination": "your-ms-graph-btp-destination",
        },
      },
    },
  },
}

Annotation Reference

All @email properties have sensible defaults. Only specify what you need to override.

PropertyTypeDefaultDescription
enabledBooleanfalseActivates email for the entity
templateString{EntityName}Template file name (without extension)
triggerArray['INSERT']Lifecycle events: INSERT, UPDATE
conditionString(none)Optional CDS expression for conditional sending
recipientString(none)Static recipient email address (mutually exclusive with recipientField)
recipientFieldString(none)Entity field containing recipient email (mutually exclusive with recipient)
subjectString(none)Subject line (supports {{placeholder}} syntax)
rollbackBooleanfalseIf true, roll back the originating transaction on email failure
Full annotation example
@email: {
  enabled: true,
  template: 'order-confirmation',
  trigger: ['INSERT', 'UPDATE'],
  condition: 'status = ''APPROVED''',
  recipientField: 'contactEmail',
  subject: 'Order {{orderNumber}} confirmed',
  rollback: true
}
entity Orders { ... }
Static recipient example
@email: {
  enabled: true,
  recipient: 'support@company.com',
  subject: 'New support request'
}
entity SupportRequests { ... }

Email Providers

Providers are registered as CAP service kinds. The plugin ships with:

KindDescription
basicBase email service class
graphMicrosoft Graph API via cds.connect.to() and BTP Destination Service

Select your provider in package.json under cds.requires.email.kind.

How It Works

  1. Entity INSERT/UPDATE triggers an after handler
  2. Plugin evaluates @email annotations and optional conditions
  3. Template is loaded from your project and rendered with entity data
  4. Recipient resolved from @email.recipient, @email.recipientField, or req.user.email
  5. Email dispatched asynchronously via the configured provider
  6. Status logged; failures recorded in the plugin-owned log entity

Emails are sent after successful operations only. Failed transactions never trigger emails. By default, email failures do not roll back the originating transaction, but this is configurable via @email.rollback.

Plugin Architecture

cds-plugin.ts          → Entry point; registers handlers
lib/plugin.ts          → Core logic; attaches after handlers for @email entities
lib/basic.ts           → Base EmailService class (extends cds.Service)
lib/graph-mail.ts      → Microsoft Graph implementation
lib/template-engine.ts → Template loading and {{placeholder}} rendering

Development

npm install
npm test
Test App

A minimal CAP application lives at test/test-app/ for testing the plugin end-to-end. It depends on the plugin via "file:../../." so changes are picked up immediately without publishing.

test/test-app/
  package.json               ← plugin dependency + basic kind config
  db/schema.cds              ← Orders (minimal), Tickets (full), Products (control)
  srv/services.cds           ← TestService exposing all entities
  email-templates/           ← templates for annotated entities

To run the test app standalone:

cd test/test-app
npm install
npx cds serve
Tech Stack
  • TypeScript (ESM)
  • Node.js >= 22
  • oxlint + Prettier
  • @cap-js/cds-test + @types/jest (jest-style assertions)
  • Conventional Commits (feat:, fix:, chore:, etc.)

License

Copyright 2026 Expertum Group Apache-2.0

Apache-2.0, read

History

Latest

v0.1.1

  1. v0.1.0

On npm
1downloads per week, npm
Weekly downloads for @expertum/cap-email-plugin26 complete calendar weeks from 2026-04-27 to 2026-10-25; the latest total is 1.27 Apr – 3 May: 04 May – 10 May: 011 May – 17 May: 018 May – 24 May: 025 May – 31 May: 01 Jun – 7 Jun: 08 Jun – 14 Jun: 015 Jun – 21 Jun: 022 Jun – 28 Jun: 029 Jun – 5 Jul: 06 Jul – 12 Jul: 013 Jul – 19 Jul: 020 Jul – 26 Jul: 027 Jul – 2 Aug: 03 Aug – 9 Aug: 010 Aug – 16 Aug: 017 Aug – 23 Aug: 024 Aug – 30 Aug: 031 Aug – 6 Sept: 07 Sept – 13 Sept: 1714 Sept – 20 Sept: 18121 Sept – 27 Sept: 1828 Sept – 4 Oct: 105 Oct – 11 Oct: 712 Oct – 18 Oct: 419 Oct – 25 Oct: 1
Notifications
  1. aditheos/ApplicationLogsNotificationToFioriFiori launchpad notification for application log errorsfrom ABAP
  2. agiguere/SCPmsPushNotificationREST_APIABAP classes sending push notifications to Mobile Servicesfrom ABAP
  3. ABAP-PRCFramework for multi-step ABAP processes with monitoringfrom ABAP
  4. com.sap.cds:cds-feature-notificationsBusiness notifications from CAP Java via SAP Alert Notificationfrom CAP
  5. @cap-js/notificationsBusiness notifications from CAP to SAP Build WorkZonefrom CAP
  6. @cap-rp/notificationsRenamed copy of @cap-js/notifications under another scopefrom CAP
  7. DryDumbHead/easyHtmlEmailABAP helper class building HTML emails from templatesfrom ABAP
  8. @neoimpulse/cap-js-notificationsCopy of @cap-js/notifications published under another scopefrom CAP
  9. peterlangner/zrssRSS feed publisher for content from an SAP NetWeaver ABAP systemfrom ABAP

Details

Sources4
npm registrydiscovered here, keywords:cdschecked
npm registry, @expertum/cap-email-pluginversion, releases, installschecked
github.com/git+https://github.com/expertum-net/cap-email-plugin.gittree, pushes, contributors, CIchecked
README.mdquoted, and what the entry declareschecked

Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.

Compatibility and provenance
runtimesnode
declared for>=9
latestv0.1.1
first release
releases and cadence2
discovered vianpm registry · keywords:cds
first seen in the atlas
ecosystem and domaincap, integration-and-messaging
Flavors1
Node.js
“Node.js >= 22 (required for ESM + `@cap-js/cds-test` compatibility)” — @expertum/cap-email-plugin — READMEchecked
Contributors1

From the repository’s contributor list, .

History in the atlas6
  1. The repository answers again: the GitHub API returns it created 2026-03-06 and pushed 2026-09-18, and raw.githubusercontent serves its README, its package.json and lib/. Nothing says whether it was private or gone between 2026-09-08 and now.
  2. Follows the repository being readable again. The declared Apache-2.0 licence and the TypeScript the package is built from are both in it.
  3. The two version floors, and the provider boundary
  4. object form, both conditional
  5. 404 from the GitHub API. Found by the first full run of scripts/check-links.mjs — the citation had a checked date and nobody had re-read it.
  6. First seen.
For your agent
Ref
artifact:expertum-cap-email-plugin
JSON
/artifacts/expertum-cap-email-plugin.json
MCP
Connecting an agent