Backend2026

AI Marketing Automation System

Built a FastAPI-based backend that automates end-to-end marketing campaign generation, scheduling, and dispatch using AI-generated text and image assets, with a resilient provider abstraction, SQLAlchemy persistence, and background processing. The system implements a domain-driven campaign workflow, runtime provider switching, deterministic fallback behavior, and containerized deployment for a single-process asynchronous scheduler.

Primary technologies

  • Python
  • FastAPI
  • Uvicorn
  • Pydantic
  • SQLAlchemy
  • SQLite
  • OpenAI
  • Google Gemini
  • Anthropic Claude
  • httpx
  • Docker
  • docker-compose
  • Gunicorn
  • uv
AI marketing automation system campaign dashboard and generated marketing assets

What this project is

The project is a backend service for creating marketing campaigns, generating campaign copy and visuals from a prompt, scheduling delivery, and dispatching a simulated SMS at the target time.

Engineering problem

Marketing teams need a repeatable way to turn a campaign brief into text, image, and delivery logic without manual coordination across separate AI and messaging workflows.

Success criteria

Deliver an automated campaign lifecycle from prompt intake to scheduled execution while keeping the system resilient when AI providers are unavailable and easy to configure through environment variables.

The application centers a Campaign model and a scheduling workflow that validate inputs, persist campaign records, invoke the selected AI provider, generate local image assets, and dispatch due campaigns through a bounded asynchronous polling loop.

What I designed, built, and shipped

The areas I owned end to end as Backend Engineer.

  1. Designed and implemented a REST API for campaign creation and retrieval with Pydantic validation, status tracking, and SQLite persistence using SQLAlchemy models and session management.

  2. Implemented a background scheduler that polls due campaigns every 10 seconds, generates copy and promotional images, records results to the campaign record, and simulates SMS dispatch without blocking on external AI failures.

  3. Built a pluggable AI provider system for text and image generation with runtime configuration via environment variables, supporting OpenAI, Google Gemini, and Anthropic Claude with deterministic mock fallback when credentials or APIs are unavailable.

  4. Structured the project around service-oriented modules for text generation, image generation, SMS simulation, and scheduling to keep business logic readable, extensible, and isolated from the FastAPI app layer.

  5. Containerized the application with Docker and docker-compose, mounted persistent storage for the SQLite database and generated images, and exposed health checks and Swagger documentation for local and production deployment workflows.

How the system is structured

  1. Layer 01

    API and domain boundary

    The FastAPI app exposes a small campaign API at /campaigns, validates inbound payloads with Pydantic schemas, and uses SQLAlchemy sessions to persist and fetch Campaign records while keeping request handlers thin and focused on transport concerns.

  2. Layer 02

    Service-oriented campaign execution

    The scheduler coordinates text generation, image generation, and SMS simulation through dedicated service classes, creating a clear separation between orchestration logic and vendor-specific provider implementations.

  3. Layer 03

    Provider abstraction with fail-safe behavior

    Text and image providers are selected at runtime from configuration and wrapped in factory functions; when a provider is missing, misconfigured, or errors, the system falls back to deterministic mock implementations rather than failing campaign dispatch.

  4. Layer 04

    Local asset hosting and container persistence

    Generated images are written to a local directory and served through a FastAPI static mount, while Docker volume configuration ensures the SQLite database and generated images persist across container restarts.

Key technical decisions

Environment-driven provider selection

The application treats AI vendor choice as configuration rather than code-level branching, which keeps the system extensible and allows switching among OpenAI, Gemini, Claude, or mock mode without code changes.

Single-process scheduler design

The project explicitly enforces one running scheduler instance in production because the same due campaign should not be dispatched multiple times; the README documents this constraint and the Docker setup is built around a single worker process.

Local image persistence instead of hosted URLs

Generated image bytes are saved to disk and exposed through a static route so the backend can return a stable URL even when the underlying AI SDK returns raw binary output rather than a remote hosted image URL.

Graceful degradation for provider outages

Fail-safe logic in the text and image generator services ensures a campaign still completes with fallback content and a placeholder image if an AI API is unavailable, which is important for maintaining automation continuity.

Technology stack

Application Layer

  • Python
  • FastAPI
  • Uvicorn
  • Pydantic

Data Layer

  • SQLAlchemy
  • SQLite
  • ORM session management

AI & Integrations

  • OpenAI
  • Google Gemini
  • Anthropic Claude
  • httpx

Infrastructure & Delivery

  • Docker
  • docker-compose
  • Gunicorn
  • uv

What the system does

Campaign lifecycle management

The API supports creating campaigns with name, prompt, phone number, and scheduled time, persists them in a Campaign model with status transitions, and exposes endpoints to list all campaigns or fetch a single campaign record.

AI-powered marketing copy generation

The text generator service delegates to the configured provider and formats a short SMS-appropriate marketing message using a shared system prompt, with response validation and fallback output when generation fails.

AI-powered promotional image generation

The image generation pipeline creates a visual asset from the campaign prompt, stores it locally, and returns a URL for a static endpoint so the final message includes a generated image reference.

Scheduled campaign dispatch

A background asyncio loop checks for pending campaigns whose schedule_time is due, generates content, updates the campaign status to sent, and triggers the SMS simulation for the target number.

Health and deployment observability

The app exposes a /health endpoint and structured logging for campaign creation, scheduler runs, provider calls, and dispatch operations, making it easier to monitor the service in Docker and containerized environments.

Challenges & solutions

Challenge 01

AI provider outages and missing credentials

Problem

External API failures, empty responses, or absent keys could block campaign execution and break the full dispatch flow.

Solution

The factory and service layers validate configuration, catch provider initialization or runtime errors, and route to deterministic mock providers so scheduling remains operational without manual intervention.

Challenge 02

Preventing duplicate dispatches

Problem

In a polling background scheduler, duplicate execution across workers or repeated process instances can trigger the same campaign multiple times.

Solution

The project documents the requirement for only one scheduler process and configures the production Docker setup to run a single worker, reducing the risk of multiple dispatches.

Challenge 03

Handling AI-generated image outputs across vendors

Problem

Different providers return different formats and delivery mechanisms for image generation, including raw bytes and temporary URLs.

Solution

A shared local storage helper converts raw image bytes to files and returns a servable URL, while the image provider interface normalizes this behavior across providers.

Challenge 04

Keeping the project runnable without API keys

Problem

A clean development setup should not require external account credentials or service quotas for basic execution.

Solution

Default configuration selects the mock provider and the code explicitly falls back to deterministic outputs when no provider is configured or when a real provider fails.

What was delivered

  1. Built a modular backend workflow for campaign automation that separates API, persistence, provider logic, and background execution.

  2. Achieved resilient AI execution by defaulting to deterministic mock providers when credentials or external APIs are unavailable.

  3. Created a deployment-ready service with Docker configuration, persistent storage for the database and generated images, and a clear production single-worker constraint.

  4. Produced a maintainable architecture where provider implementations are isolated behind factories and shared interfaces, allowing new AI vendors to be added without rewriting core orchestration.

What I took away

  1. AI-first backends need explicit failure handling and fallback behavior to remain operational when third-party services are unavailable or misconfigured.

  2. Background processing is most reliable when orchestration and execution boundaries are clear, especially when there is a risk of duplicate dispatches in distributed or multi-worker environments.

  3. Local asset persistence is a practical solution when AI-generated media is returned as raw bytes rather than hosted URLs, reducing dependency on external storage during early-stage deployment.

Next step

Building something that needs this kind of backend?

I take on backend, API, and DevOps work — from data modelling and REST design through containerization and production deployment.

A project case study by Md Fahad MirBackend & DevOps Engineer, Dhaka, Bangladesh.