Documentation menu

"Example: welcome email via Plunk"

Send a welcome email to every newly-created OMMAX user.

Fires on user.human.added, sends a Plunk transactional email pointing the new user at Atrium.

Prereqs

  1. Plunk API key stored as a secret in /admin/secrets:
    • Name: PLUNK_API_KEY
    • Value: your Plunk private API key (sk_...)
    • Allowed scripts: welcome-new-hire (or leave empty for all)
  2. Allowlist api.useplunk.com on the runtime via ATRIUM_ACTIONS_FETCH_ALLOWLIST (already set)

Script

In /admin/actions:

  • Name: welcome-new-hire
  • Trigger type: EVENT
  • Trigger name: user.human.added
  • Secret refs: PLUNK_API_KEY
// Welcome email — fires once per new user.

const u = ctx.payload.event_payload ?? {};
const email = u.email;
const firstName = u.firstName ?? u.userName ?? 'there';

if (!email) {
  ctx.log.warn('no email in event_payload; skipping', { payload: ctx.payload });
  return null;
}

const res = await ctx.fetch('https://api.useplunk.com/v1/send', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${ctx.secrets.PLUNK_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    to: email,
    subject: 'Welcome to OMMAX',
    body: `
      <h2>Hi ${firstName}, welcome to OMMAX</h2>
      <p>Your accounts are live. Get started at
        <a href="https://atrium.ommax-intelligence.de">Atrium</a> —
        the directory of every OMMAX tool you have access to.</p>
      <p>Questions? Hit us in #it-helpdesk on Slack.</p>
    `,
  }),
});

if (!res.ok) {
  ctx.log.error('plunk failed', { status: res.status, body: await res.text() });
  return { ok: false, status: res.status };
}

ctx.log.info('welcome email sent', { email });
return { ok: true };

Test before promoting

Use the "Test against sample payload" button (TODO when shipped) with this fixture:

{
  "aggregateID": "111222333",
  "event_type": "user.human.added",
  "event_payload": {
    "email": "you+test@ommax.de",
    "firstName": "Test",
    "userName": "you+test@ommax.de"
  }
}

Make sure the Plunk send actually lands in your inbox before promoting to ACTIVE.

What can go wrong

  • PLUNK_API_KEY not set or wrong → script returns ok:false with status 401. Fix in /admin/secrets.
  • Email already exists in Plunk's blocklist → 200 from Plunk but no delivery. Plunk dashboard tells you.
  • Atrium runtime down → event lost (Zitadel doesn't retry). User onboarding still completes; they just don't get the email. Ops trade-off: acceptable for low-stakes notifications.

For higher-stakes notifications, consider mirroring this into a Slack channel as a backup signal.