@redacto.io/dpdpa-report-sdk-js
v0.2.0
Published
Vanilla JavaScript embeddable lead form that generates DPDPA compliance reports via n8n
Downloads
63
Readme
@redacto.io/dpdpa-report-sdk-js
Embeddable, brand-configurable lead form that generates a DPDPA compliance report. Collects company name, domain, and work email, submits to Redacto's n8n workflow, polls for job completion, and renders a success card with a Download PDF link.
Zero runtime dependencies. Shadow-DOM isolated (no CSS bleed). Ships as IIFE (<script> tag), ESM, and CJS.
Install
Script tag (WordPress, static HTML, PHP)
<div id="dpdpa-report-form" style="max-width:520px;margin:0 auto"></div>
<script src="https://cdn.redacto.io/dpdpa-report/0.1/dpdpa-report.global.js" defer></script>
<script>
window.addEventListener("DOMContentLoaded", function () {
window.RedactoDpdpaReport.init({
target: "#dpdpa-report-form",
});
});
</script>npm
npm install @redacto.io/dpdpa-report-sdk-js
# or
pnpm add @redacto.io/dpdpa-report-sdk-jsimport RedactoDpdpaReport from "@redacto.io/dpdpa-report-sdk-js";
RedactoDpdpaReport.init({
target: "#dpdpa-report-form",
});How it works
┌──────────────┐ POST /webhook/dpdpa/generate ┌────────────┐
│ Form │ ──────────────────────────────────▶│ n8n │
│ (browser) │ { company_name, company_domain } │ workflow │
│ │◀────────────────────────────────── │ │
│ │ { job_id } │ │
│ │ │ │
│ │ GET /webhook/dpdpa/status?… │ │
│ │ ──────────────────────────────────▶│ │
│ │◀────────────────────────────────── │ │
│ │ { status, report_url? } │ │
└──────────────┘ └────────────┘- User fills form → client validates (domain regex + freemail-email rejection).
- SDK POSTs
{ company_name, company_domain }to/webhook/dpdpa/generate. Email is captured inlocalStoragebut is not sent to n8n — the host page can read it back viagetCapturedLead()for CRM/marketing use. - On
job_id, SDK polls/webhook/dpdpa/status?job_id=…every 3s. Pauses when tab is hidden; resumes on focus. - When
status === "complete", renders success card with a Download PDF link (target="_blank").
API
RedactoDpdpaReport.init(options)
Mounts the form. Destroys any existing instance first.
| Option | Type | Default | Notes |
| ----------------- | ------------------------------------------------------ | -------------------------------- | ------------------------------------------------------------- |
| target | string \| HTMLElement | — | Required. CSS selector or element to mount into. |
| baseUrl | string | https://salazar.redacto.tech | n8n host. |
| branding | BrandingConfig | Redacto defaults | See below. |
| pollIntervalMs | number | 3000 | Delay between status polls. |
| pollTimeoutMs | number | 300000 (5 min) | Hard stop; fires onError with phase: "timeout". |
| onSubmit | (lead) => void | — | Fires when form passes validation, before the POST. |
| onJobAccepted | (job_id, lead) => void | — | Fires on 200 from /generate. |
| onStatusChange | (status) => void | — | "pending" \| "researching" \| "analysis_complete". |
| onComplete | (report_url, lead) => void | — | Fires when the PDF is ready. |
| onError | (error) => void | — | error.phase is "validation" \| "submit" \| "poll" \| "timeout". |
RedactoDpdpaReport.destroy()
Removes the mounted form, clears poll timers, detaches the visibilitychange listener.
RedactoDpdpaReport.getCapturedLead()
Returns the most recent lead from localStorage (key: redacto_dpdpa_lead), or null. Useful for pulling email into a CRM after submission:
const lead = RedactoDpdpaReport.getCapturedLead();
// { email, company_name, company_domain, job_id, timestamp }Branding
type BrandingConfig = {
logo?: string; // URL or data URI. Defaults to Redacto logo.
name?: string; // Appears in footer. Default "Redacto".
primaryColor?: string; // Default "#4262ff". Submit button, progress bar, CTA.
accentColor?: string; // Default "#a259ff".
textColor?: string; // Default "#050038".
borderColor?: string; // Default "#e5e5e5".
backgroundColor?: string; // Default "#f7f7f7".
borderRadius?: string; // Default "8px".
fontFamily?: string; // Default "inherit" (blends with host page).
};If the logo URL 404s at runtime, the form falls back to a text wordmark built from branding.name.
Example: client WordPress embed
<div id="dpdpa-report-form" style="max-width:520px;margin:0 auto"></div>
<script src="https://cdn.redacto.io/dpdpa-report/0.1/dpdpa-report.global.js" defer></script>
<script>
window.addEventListener("DOMContentLoaded", function () {
window.RedactoDpdpaReport.init({
target: "#dpdpa-report-form",
branding: {
name: "Acme Legal",
logo: "https://acme.example.com/logo.svg",
primaryColor: "#0b5cff",
},
onComplete: function (reportUrl, lead) {
// optional: push to analytics
window.dataLayer?.push({
event: "dpdpa_report_ready",
email: lead.email,
company: lead.company_name,
});
},
});
});
</script>Validation rules
- Company name: trimmed, 2–120 chars.
- Company domain:
http(s)://andwww.are stripped, then matched against a standard domain regex. - Work email: standard email regex + hard-reject on freemail providers (gmail, yahoo, hotmail, outlook, icloud, aol, proton, zoho, rediffmail, etc.).
Server-side 400s from n8n surface as inline errors (non-retryable, focuses the offending field). Network/timeout errors are retryable via a "Try again" button.
Polling behaviour
- Uses recursive
setTimeout, so requests never overlap. - Pauses when
document.hiddenis true, resumes on visibility change. - Aborts after 3 consecutive network errors with a retryable error banner.
- Aborts after
pollTimeoutMs;onErrorfires withphase: "timeout".
Storage
The lead is written to localStorage["redacto_dpdpa_lead"] twice:
- On validation pass (
job_id: null). - On 200 from
/generate(withjob_idpopulated).
No expiry. Read it via getCapturedLead().
n8n contract (reference)
| Path | Method | Body / Query | Response |
| --------------------------- | ------ | ----------------------------------------- | --------------------------------------------------------------------- |
| /webhook/dpdpa/generate | POST | { company_name, company_domain } | { job_id } |
| /webhook/dpdpa/status | GET | ?job_id=… | { status: "pending" \| "researching" \| "analysis_complete" \| "complete" \| "error", report_url?, message? } |
Development
# build (watch)
pnpm --filter @redacto.io/dpdpa-report-sdk-js dev
# demo app (Vite)
pnpm --filter dpdpa-form-demo devThe demo app syncs the IIFE from dist/ into its public/ folder via scripts/sync-sdk.mjs.
License
Apache-2.0
