To send automated website reports by email, schedule an audit, store structured findings, compare them with the previous completed run, render a useful summary, and queue delivery through an email provider. Track incomplete checks separately from failures and distinguish provider acceptance from recipient delivery.
This is a common engineering pattern: a process starts as a checklist, grows into a spreadsheet, and eventually becomes useful enough to automate.
A reliable website-audit workflow can be treated as a small data product.
URL -> Collect signals -> Validate -> Score -> Explain -> Generate report -> Deliver
The important part is not the score itself. It is designing each stage so the result remains understandable and actionable.
Start with signals, not a single score
A useful audit should collect independent signals before combining them.
Typical categories include:
- technical SEO;
- page metadata;
- crawlability;
- performance indicators;
- mobile readiness;
- content structure;
- structured data;
- analytics readiness;
- conversion paths;
- basic accessibility checks.
Keeping raw observations separate from recommendations makes the system easier to debug.
For example, “missing meta description” is an observation. “Add a concise description that communicates the page’s value” is a recommendation.
Those are different pieces of information and should remain separate in the data model.
Make every check deterministic where possible
Many audit checks do not require AI.
A page either has a canonical URL or it does not. A heading hierarchy can be inspected. A robots directive can be parsed. A sitemap can be fetched and validated.
Deterministic checks are useful because they are:
- cheap;
- reproducible;
- testable;
- easy to explain;
- less likely to change unexpectedly.
AI can still help with tasks such as summarizing findings or generating clearer recommendations, but it should not replace checks that can be performed reliably with normal code.
This principle also applies to search tools. See How an Evidence-First Search Tool Can Work Without AI for a similar design decision.
Separate scoring from recommendations
A common implementation mistake is to mix collection, scoring, and report text in one function.
That makes every future change risky.
A better structure is:
- collect normalized findings;
- assign severity or weight;
- calculate section-level scores;
- calculate an overall summary;
- map findings to explanations;
- render the final report.
This allows the scoring model to evolve without rewriting the collection layer.
It also allows multiple outputs from the same audit data: an HTML page, an email summary, a PDF, or an internal dashboard.
Design for partial failure
External websites are unpredictable.
A page may time out. A resource may block automated requests. A DNS lookup may fail temporarily. A third-party performance API may be unavailable.
The whole audit should not fail because one signal could not be collected.
Instead, each check should return a state such as:
- passed;
- failed;
- warning;
- unavailable;
- not applicable.
This makes incomplete reports explicit instead of silently treating missing data as a bad score.
Generate reports from structured data
The reporting layer becomes much simpler when the audit output is structured.
For example:
{
"section": "technical_seo",
"check": "canonical_url",
"status": "warning",
"evidence": "No canonical link element found",
"recommendation": "Add a canonical URL to the page head."
}
The frontend or report generator can then decide how this appears visually.
This is easier to maintain than hard-coding presentation logic inside the audit functions.
Add delivery only after the audit is stable
Choose between an existing reporting tool and a custom workflow
If you only need standard analytics summaries or a routine technical audit, an existing scheduled-report feature may be sufficient. A custom pipeline is more useful when reports must combine website checks with your own rules, business context, or delivery systems. This article explains that implementation approach; it is not a hosted report-generator service.
For analytics-only reporting, see Google Analytics scheduled reports. Analytics reports and technical website audits answer different questions: visits and engagement do not establish whether canonical URLs or crawl directives are correct.
Define the schedule and comparison baseline
Store the website, reporting interval, configured time zone, permitted recipients, and audit-rule version. Use a stable run key such as website-id:reporting-period:rules-version so a scheduler retry does not create another logical report.
Compare each run with the previous completed run using the same scope and rules. A crawl of ten pages should not be presented as a deterioration from a previous crawl of one hundred pages without explaining the coverage difference. Show unavailable checks explicitly.
The idempotent Python jobs guide includes a runnable transaction example and recovery tests.
Send a short summary with a useful report link
An email can lead with new critical issues, resolved issues, and the next action. Include the audited URL, reporting period, coverage, and a link to an accessible HTML report. A PDF attachment can be optional; large attachments and image-only reports make the result harder to use on mobile.
Escape website-derived text when rendering HTML and limit excerpts. If a report includes private observations, use authenticated access or expiring links rather than treating an unguessable URL as permanent access control.
Queue delivery and record its state
Store a pending delivery alongside the completed report. A dispatcher can retry recoverable provider errors with bounded backoff and a stable delivery key. If the provider supports idempotency, follow its documented key lifetime; otherwise a timeout after acceptance can still produce duplicate email.
| State | What it establishes |
|---|---|
| Report completed | Findings and report artifact were stored |
| Delivery queued | There is a durable intention to send |
| Provider accepted | The provider accepted the request |
| Delivered | A provider event reports recipient-server acceptance |
| Bounced or failed | Delivery needs investigation or correction |
Even a delivered event does not prove inbox placement or that the recipient read the report. Keep the HTML result available when email is delayed. The SMTP-blocked email guide explains transport alternatives.
Once the core workflow works, it can be connected to:
- an email service;
- a CRM;
- a lead form;
- a webhook;
- a database;
- an admin interface.
This turns a technical script into a business workflow.
The same pattern is useful for document-processing tools, data-quality checks, compliance checklists, and recurring operational reports.
Protect the backend from accidental abuse
Any public audit endpoint should have operational limits.
Useful controls include:
- input validation;
- URL allow/deny rules;
- timeouts;
- request limits;
- maximum crawl depth;
- background-job limits;
- logging;
- protected admin endpoints.
For user-supplied URLs, protect against server-side request forgery: block private, loopback, link-local, and metadata-service destinations, validate every redirect, and enforce outbound network controls. A hostname check before the first request alone is insufficient when DNS or redirects can change the destination. Only audit sites you are authorized to access and respect crawl limits.
A free public tool can otherwise become an expensive open proxy for arbitrary work.
Measure whether the workflow creates value
Once deployed, the important questions change.
It is useful to track:
- audit starts;
- successful completions;
- report views;
- email submissions;
- contact clicks;
- errors by stage;
- repeat usage.
A technically correct tool that nobody completes is not successful.
This is where analytics should be part of the implementation rather than an afterthought.
The general pattern
The architecture is not specific to website audits.
Any repeatable expert workflow can often be transformed using the same structure:
Input -> Evidence -> Rules -> Evaluation -> Explanation -> Delivery
The biggest improvement usually comes from making the process explicit before automating it.
For a related example of building lightweight web workflows, see Static Forms with Google Sheets and Apps Script.
Have a similar workflow that is still being handled manually? A project request can be sent here.