AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Render Transactional Emails

skill-kennguyen887-agent-foundation-render-transactional-emails · by kennguyen887

Use when sending a templated transactional email (or generating a templated PDF/document) — rendering from a named template + data through one shared render service, with per-locale template files, CSS inlining, returning subject/html/text, then dispatching via the notification facade (not inline). Covers reusing the same render for HTML→PDF. NestJS/TS reference, framework-flexible.

No reviews yet
0 installs
17 views
0.0% view→install

Install

$ agentstack add skill-kennguyen887-agent-foundation-render-transactional-emails

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-kennguyen887-agent-foundation-render-transactional-emails)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
24d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Render Transactional Emails? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Render transactional emails (and documents)

Producing transactional content — order receipts, OTPs, invites, notices, PDFs — from templates rather than hand-built strings. Examples NestJS/TS (an email-templates/EJS + CSS-inliner stack), neutral domain. principle → ▸ Example▸ Other stacks. Sending lives behind the notification facade in integrate-external-services §1; this skill is how the content is produced.

Core principle

Never concatenate email HTML in a handler. Render from a versioned template + a typed data context through one shared service — localized and CSS-inlined — and return a { subject, html, text } the transport sends. Templates hold markup; code holds logic.

1. One render service over a template engine

Wrap the template lib (EJS / Handlebars / …) + a CSS inliner (so styles survive email clients) in a single render(templateName, context); resolve the file by name + locale convention; configure the template root via DI, not hard-coded paths.

@Injectable() export class TemplateService {
  private email = new Email({
    views: { root, options: { extension: 'ejs' } },
    getPath: (file, template, ctx) => path.join(dir, template, `${file}.${ctx.language ?? 'en'}`), // /.
    juiceResources: { /* inline CSS */ },
  });
  render(name: string, ctx: { language?: string; data: unknown }) {
    return this.email.renderAll(name, ctx.data);   // → { subject, html, text }
  }
}

2. Templates are data-driven + localized

  • Pass a typed context { language, data }; one folder per template with per-locale files

(welcome/subject.en.ejs, welcome/html.en.ejs, …). Adding a language = adding files, no code change.

  • Keep logic out of templates — format dates/money/decimals in code (a date/decimal lib, see

write-service-code §5) and pass display-ready values in; the template only interpolates.

3. Render → dispatch via the facade (separate concerns)

The use-case renders, then hands off to the notification send() facade — don't call the email provider inline. Render (content) and transport (channel/vendor) are different responsibilities.

const { subject, html } = await this.templates.render('membership-invite', { language, data: { name, link } });
await this.notifier.sendEmail({ to, subject, html });   // facade picks the provider — integrate-external-services §1

Mask PII before any logging (write-service-code §7); don't log full rendered bodies (they hold names/OTPs).

4. PDFs reuse the same render

A document (invoice, policy, form) is the same template render → then convert the HTML to PDF (headless browser / a render lambda) and store it (e.g. object storage), returning a URL/ref. Same template discipline; the HTML→PDF conversion is the only extra step.

const { html } = await this.templates.render('policy-doc', { language, data });
const pdf = await this.htmlToPdf.convert(html);     // headless/lambda
await this.storage.put(`${id}.pdf`, pdf);           // store + reference

Other stacks: any engine (Jinja2 / Thymeleaf / Razor / Liquid) + an email lib + an inliner; HTML→PDF via wkhtmltopdf / Puppeteer / a service. Principle: template + data → localized content, CSS-inlined, produced once and reused for email or PDF, separate from sending.

Verification

  • Email content comes from a named template + typed context via one service — no string-built HTML in handlers.
  • Templates are per-locale files under a per-template folder; formatting is done in code, not the template.
  • The use-case renders then dispatches via the facade — the provider isn't called inline; bodies/PII aren't logged.
  • PDFs reuse the same render then convert + store.

Related

  • integrate-external-services §1 — the notification send() facade (email/SMS/push) that transports the rendered content.
  • write-service-code §5 (format money/dates in code), §7 (mask PII, don't log bodies).
  • structure-a-shared-backend-lib — the render service is a good shared-lib primitive · handle-files-frontend (the FE side of file/PDF download).

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.