{"id":37345112,"url":"https://github.com/weprodev/wpd-message-gateway","last_synced_at":"2026-06-07T22:01:05.001Z","repository":{"id":332217966,"uuid":"1132338523","full_name":"weprodev/wpd-message-gateway","owner":"weprodev","description":"A unified Go gateway for sending messages through multiple providers (Email, SMS, Push, Chat). One API, any provider.","archived":false,"fork":false,"pushed_at":"2026-06-07T17:47:38.000Z","size":35956,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"develop","last_synced_at":"2026-06-07T18:18:56.050Z","etag":null,"topics":["chat","email","golang","golang-library","golang-package","library","mailgun","message-gateway","messaging","notifications","push-notifications","sms"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/weprodev.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-01-11T19:18:34.000Z","updated_at":"2026-06-07T17:47:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/weprodev/wpd-message-gateway","commit_stats":null,"previous_names":["weprodev/wpd-message-gateway"],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/weprodev/wpd-message-gateway","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weprodev%2Fwpd-message-gateway","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weprodev%2Fwpd-message-gateway/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weprodev%2Fwpd-message-gateway/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weprodev%2Fwpd-message-gateway/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/weprodev","download_url":"https://codeload.github.com/weprodev/wpd-message-gateway/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weprodev%2Fwpd-message-gateway/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34039495,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-07T02:00:07.652Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chat","email","golang","golang-library","golang-package","library","mailgun","message-gateway","messaging","notifications","push-notifications","sms"],"created_at":"2026-01-16T03:56:55.372Z","updated_at":"2026-06-07T22:01:04.991Z","avatar_url":"https://github.com/weprodev.png","language":"Go","funding_links":["https://github.com/sponsors/weprodev"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"frontend/public/logo-dark-mode.svg\"\u003e\n    \u003cimg src=\"frontend/public/logo-light-mode.svg\" alt=\"Message Gateway\" width=\"400\" /\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003c!-- Build \u0026 CI --\u003e\n  \u003ca href=\"https://github.com/weprodev/wpd-message-gateway/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/weprodev/wpd-message-gateway/actions/workflows/ci.yml/badge.svg\" alt=\"CI Status\"\u003e\u003c/a\u003e\n  \u003c!-- Quality \u0026 Go --\u003e\n  \u003ca href=\"https://goreportcard.com/report/github.com/weprodev/wpd-message-gateway\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/weprodev/wpd-message-gateway\" alt=\"Go Report Card\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/weprodev/wpd-message-gateway\"\u003e\u003cimg src=\"https://pkg.go.dev/badge/github.com/weprodev/wpd-message-gateway.svg\" alt=\"Go Reference\"\u003e\u003c/a\u003e\n  \u003c!-- License --\u003e\n  \u003ca href=\"https://github.com/weprodev/wpd-message-gateway/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eA unified messaging solution for Email, SMS, Push, and Chat.\u003c/strong\u003e\n\u003c/p\u003e\n\nThis project offers two distinct ways to integrate messaging into your architecture:\n1. **Embedded Go SDK:** A lightweight library for your Go applications. Send messages natively without running a separate server or database.\n2. **Standalone HTTP Gateway:** A fully-featured service deployable via Docker. Provides a unified REST API for any programming language, backed by PostgreSQL and a React UI.\n\nWrite your messaging code once — switch between different email, SMS, and chat providers without changing a single line of application code.\n\n---\n\n## Key Features\n\n- **Unified Interface:** Send Email, SMS, Push, and Chat messages through one consistent API.\n- **Provider Abstraction:** Change a configuration value to switch providers, not your code.\n- **DB-First Configuration:** Provider catalog, fields, credentials, and settings stored in PostgreSQL and resolved dynamically.\n- **Workspace Isolation:** Multi-tenant support for separate providers, API keys, and templates per workspace.\n- **Developer-Friendly:** Includes a local Memory provider to capture messages locally and assert real payloads without mocking.\n\n---\n\n## Two Ways to Use\n\n```mermaid\ngraph TD\n    classDef main fill:#f9f9f9,stroke:#333,stroke-width:2px;\n    classDef feature fill:#e1f5fe,stroke:#0288d1,stroke-width:1px;\n    classDef embedded fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;\n    classDef standalone fill:#fff3e0,stroke:#e65100,stroke-width:2px;\n\n    %% SDK Usage Path\n    subgraph SDK [\"Go Package (Embedded SDK)\"]\n        direction TB\n        A[\"💻 go get wpd-message-gateway\"] --\u003e B[\"📦 gateway.New(config)\"]\n        B -.-\u003e C[\"✓ No server needed\"]:::feature\n        B -.-\u003e D[\"✓ No database needed\"]:::feature\n        B -.-\u003e E[\"✓ Config in your code\"]:::feature\n    end\n    class SDK embedded;\n\n    %% Server Usage Path\n    subgraph Server [\"HTTP Server (Standalone Gateway)\"]\n        direction TB\n        F[\"🐳 make dev (Docker)\"] --\u003e G[\"🌐 POST /v1/email (HTTP)\"]\n        G -.-\u003e H[\"✓ Any language (Python, JS...)\"]:::feature\n        G -.-\u003e I[\"✓ React Portal UI included\"]:::feature\n        G -.-\u003e J[\"✓ PostgreSQL stores secrets\"]:::feature\n    end\n    class Server standalone;\n```\n\n---\n\n## System Architecture\n\nWPD Message Gateway is structured with clean architecture separation, allowing the same provider registry to run either in-process (SDK mode) or as a distributed service (Standalone HTTP mode).\n\n```mermaid\ngraph LR\n    classDef client fill:#e1f5fe,stroke:#0288d1,stroke-width:1px;\n    classDef main fill:#fff3e0,stroke:#e65100,stroke-width:2px;\n    classDef db fill:#e8f5e9,stroke:#2e7d32,stroke-width:1px;\n    classDef ext fill:#f5f5f5,stroke:#9e9e9e,stroke-width:1px;\n\n    subgraph ClientLayer [\"Client Interfaces\"]\n        UI[\"🖥️ React Portal UI\"]:::client\n        AppClient[\"💻 API Client (curl/Go/Node...)\"]:::client\n    end\n\n    subgraph ServerLayer [\"Go HTTP Gateway (Standalone)\"]\n        API[\"📡 REST API Routes\"]:::main\n        Svc[\"⚙️ Gateway \u0026 Portal Services\"]:::main\n        Reg[\"📦 Provider Registry (Self-Registration)\"]:::main\n    end\n\n    subgraph DBLayer [\"Database Layer\"]\n        DB[(🗄️ PostgreSQL)]:::db\n    end\n\n    subgraph ExternalServices [\"External APIs\"]\n        EmailProvider[\"📧 Email Providers\"]:::ext\n        SMSProvider[\"💬 SMS Providers\"]:::ext\n        ChatProvider[\"✈️ Chat Providers\"]:::ext\n    end\n\n    %% Routing\n    UI --\u003e|\"/api/v1/* (Portal JWT)\"| API\n    AppClient --\u003e|\"/v1/* (API Key)\"| API\n    API --\u003e Svc\n    Svc --\u003e|Load Config| DB\n    Svc --\u003e Reg\n    Reg --\u003e EmailProvider\n    Reg --\u003e SMSProvider\n    Reg --\u003e ChatProvider\n```\n\n### 1. Embedded Go SDK (`pkg/gateway`)\n* **Zero Dependencies**: Requires no database, cache, or background server. It runs completely inside your application process.\n* **Provider Registry**: Uses Go's self-registration factory mechanism (Open/Closed Principle) to register messaging adapters.\n* **In-Memory Simulator**: Includes a built-in memory provider to capture sent payloads in-process, allowing you to test messaging without making actual network calls.\n\n### 2. Standalone HTTP Server (`cmd/server`)\n* **Layered Clean Architecture**:\n  * **Presentation Layer**: Thin Echo HTTP handlers mapped under RBAC permissions.\n  * **Core Layer**: Domain services executing business logic and orchestrating providers.\n  * **Infrastructure Layer**: PostgreSQL repository implementations storing API keys, workspace configurations, integrations, templates, and request logs.\n* **DB-First Configuration**: Provider credentials (stored AES-encrypted) and settings reside in PostgreSQL as the single source of truth—no server-side configuration files needed for provider setup.\n* **Context-Aware Tracing**: Context-aware structured logger (`slog`) automatically maps request correlation IDs across all handlers, services, and repositories to trace requests end-to-end.\n\n### 3. Portal React UI (`frontend/`)\n* **Modern UI \u0026 Design System**: A responsive React 19 single-page application built with Vite and clean CSS tokens.\n* **Dynamic Integrations UI**: Instead of hardcoding vendor configurations, the UI dynamically fetches provider metadata from the database and renders tailored configuration forms for connecting new providers.\n* **Workspace Isolation**: Allows tenant-level scoping of connected integrations, logs, and send tests.\n\n---\n\n\n## Quick Start\n\n### Option A: Embedded Go SDK\n\nInstall the SDK:\n\n```bash\ngo get github.com/weprodev/wpd-message-gateway\n```\n\nSend an email in 10 lines:\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com/weprodev/wpd-message-gateway/pkg/contracts\"\n    \"github.com/weprodev/wpd-message-gateway/pkg/gateway\"\n)\n\nfunc main() {\n    gw, err := gateway.New(gateway.Config{\n        DefaultEmailProvider: \"mailgun\",\n        EmailProviders: map[string]gateway.EmailConfig{\n            \"mailgun\": {\n                CommonConfig: gateway.CommonConfig{APIKey: \"key-xxx\"},\n                Domain:       \"mg.example.com\",\n                FromEmail:    \"noreply@example.com\",\n            },\n        },\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    result, err := gw.SendEmail(context.Background(), \u0026contracts.Email{\n        To:      []string{\"user@example.com\"},\n        Subject: \"Welcome!\",\n        HTML:    \"\u003ch1\u003eHello!\u003c/h1\u003e\",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n    log.Printf(\"Sent! ID: %s\", result.ID)\n}\n```\n\nNo server. No database. Just `go get` and send.\n\n---\n\n### Option B: Standalone HTTP Gateway\n\nThe easiest way to get the standalone server running is with Docker Compose.\n\n**Prerequisites:** Docker and Docker Compose\n\n```bash\n# 1. Clone the repository\ngit clone https://github.com/weprodev/wpd-message-gateway.git\ncd wpd-message-gateway\n\n# 2. Start the gateway, PostgreSQL, and Portal UI\nmake dev\n```\n\nOnce running:\n\n1. Open **http://localhost:10104** — the Portal UI\n2. Create an account and sign in (or use the pre-seeded demo user: `demo@example.com` / `password`)\n3. Select the pre-seeded workspace or create a new workspace, create an API key, and configure integrations directly in the Portal UI. (Alternatively, you can bootstrap via the REST API; see [E2E Bootstrap Guide](docs/backend/e2e-testing.md#2-bootstrap-create-workspace-and-api-key) for details).\n4. Send a message from any language:\n\n```bash\ncurl -X POST http://localhost:10101/v1/email \\\n  -u \"wk_client_id:your_secret\" \\\n  -H \"X-Workspace-Key: myapp\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"to\":[\"user@example.com\"],\"subject\":\"Hello\",\"html\":\"\u003ch1\u003eWorld\u003c/h1\u003e\"}'\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eAlternative: Manual Setup (No Docker)\u003c/strong\u003e\u003c/summary\u003e\n\nIf you prefer to run components directly on your machine:\n**Prerequisites:** Go 1.22+, PostgreSQL, Node.js 20+\n\n```bash\ngit clone https://github.com/weprodev/wpd-message-gateway.git\ncd wpd-message-gateway\ncp configs/local.example.yml configs/local.yml   # edit DB credentials here\n\nmake install\nmake start\n```\n\u003c/details\u003e\n\n---\n\n## Why Message Gateway?\n\n| Problem | Solution |\n|---------|----------|\n| Each provider has a different API | **Unified interface** — Email, SMS, Push, Chat through one consistent API |\n| Switching providers means rewriting code | **Provider abstraction** — change a config value, not your code |\n| Credentials scattered in env vars | **DB-first config** — all secrets in PostgreSQL, managed via Portal UI |\n| Hard to test messaging in CI | **Memory provider** — captures messages locally, assert real payloads without mocking |\n| Multi-tenant apps need isolation | **Workspace isolation** — separate providers, API keys, templates per workspace |\n\n---\n\n## Portal UI\n\nAvailable at **http://localhost:10104** when the server runs.\n\n| Feature | Description |\n|---------|-------------|\n| **Sign in / Register** | Register and sign in with first/last name (JWT-based session authentication) |\n| **Workspaces** | Create, view, and select workspaces |\n| **Message Logs** | Audit trail of gateway send requests with detailed metadata |\n| **Email Inbox** | Read and test outbound messages captured in real-time by the secure memory simulator |\n| **Email Templates** | Create and manage reusable HTML layouts and template assets |\n| **Integrations** | Dynamically view, configure, and connect messaging providers |\n| **Settings** | Configure workspace PIN, owner email, data retention policy, and manage/rotate API keys |\n| **Send Test** | Run manual test sends for any supported channel directly from the dashboard |\n\nAll workspace management and developer tools are fully accessible directly via the Portal UI. The Portal REST API is also fully documented for automated workflows. See [Usage guide](docs/backend/usage.md) and [Portal inbox](docs/backend/portal-inbox.md).\n\n---\n\n## Configuration\n\nThe gateway enforces a strict separation between **server infrastructure** and **messaging credentials**:\n\n1. **Server Configuration (`configs/local.yml`):**\n   This file handles the operational infrastructure. Copy `configs/local.example.yml` to `configs/local.yml`.\n   - `DISPATCH_MODE`: Defines if messages are sent for real (`provider_only`), captured (`memory_only`), or both.\n   - Database credentials (`DB_HOST`, `DB_USER`, etc.) for PostgreSQL.\n   - `JWT_SECRET` for Portal UI session authentication.\n   *(Note: Never place provider credentials like API keys in this file.)*\n\n2. **Provider credentials (server mode):**\n   Stored AES-encrypted in PostgreSQL. Configure dynamically via the **Integrations** tab in the **Portal UI** (or programmatically via the Portal REST API). See [Usage guide](docs/backend/usage.md) and [E2E bootstrap](docs/backend/e2e-testing.md).\n\n## E2E Testing\n\nUse `memory_only` dispatch mode in CI/CD to capture messages without sending real emails or SMS. Then assert the payloads via the Portal Inbox API.\n\nNo mocking. Real HTTP calls. Full payload assertions.\n\n```yaml\n# docker-compose.test.yml — drop in with your CI\nservices:\n  message-gateway:\n    image: weprodev/wpd-message-gateway\n    environment:\n      DISPATCH_MODE: memory_only\n```\n\n📖 Full setup guide: [E2E Testing with Docker \u0026 GitHub Actions](docs/backend/e2e-testing.md)\n\n---\n\n## Development Environment \u0026 Workflow\n\nThere are two primary ways to set up the development environment:\n\n1. **Local Setup:** Using `make install` and `make start` with local dependencies (Go, Node, PostgreSQL).\n2. **Docker Setup:** Using `make dev` as the recommended one-command method to run everything via Docker Compose.\n\n| Command | Description |\n|---------|------------|\n| `make install` | Install Go + frontend dependencies |\n| `make start` | Start Gateway API + Portal UI |\n| `make dev` | Run via Docker Compose (includes PostgreSQL) |\n| `make test` | Run Go tests |\n| `make audit` | Full quality gate: fmt + lint + test (Go + frontend) + govulncheck + build |\n| `make build` | Compile Go binary + build frontend (no tests) |\n| `make ui` | Portal UI only (Vite dev server, port 10104) |\n| `make storybook` | Component library (Storybook, port 6006) |\n| `make upgrade` | Upgrade all dependencies |\n\nThis project uses a spec-driven, AI-assisted development workflow. See the [Development Flow](docs/development-flow.md) documentation for details on Spec Kit commands and Agent Mapping.\n\n---\n\n## Project Structure\n\n```\nwpd-message-gateway/\n├── cmd/server/          # HTTP server entry point\n├── configs/             # Server config (ports, JWT) — NOT provider credentials\n├── database/\n│   ├── migrations/      # SQL schema migrations\n│   └── seeds/           # Optional demo data\n├── internal/\n│   ├── app/             # Config, wire, validation, provider registration\n│   ├── core/            # Domain models, services, ports (interfaces)\n│   ├── infrastructure/  # Provider adapters + Postgres repos + logger\n│   ├── presentation/    # HTTP router, handlers, middleware\n│   └── registry/        # Provider factory registry (self-registration via init)\n├── pkg/                 # Public Go packages\n│   ├── contracts/       # Email, SMS, Push, Chat message types\n│   └── gateway/         # Embedded SDK — gateway.New()\n├── frontend/            # React Portal UI (Vite + TypeScript + Tailwind)\n├── tests/bruno/         # HTTP API test collection (Bruno)\n├── specs/               # Feature specifications (Spec Kit)\n└── docs/                # Documentation\n```\n\n---\n\n## Documentation\n\n| Document | Description |\n|----------|------------|\n| [Docs Hub](docs/README.md) | Index of all backend + frontend documentation |\n| [Usage Guide](docs/backend/usage.md) | SDK and HTTP API reference, authentication, multi-language examples |\n| [Architecture](docs/backend/architecture.md) | System design, two modes of operation, DB schema |\n| [Portal Inbox](docs/backend/portal-inbox.md) | Message inbox, dispatch modes, inbox API |\n| [E2E Testing](docs/backend/e2e-testing.md) | CI/CD integration, capturing and asserting messages |\n| [Contributing](docs/backend/contributing.md) | Adding new providers, code quality gates |\n| [Code Conventions](docs/backend/code-conventions.md) | Go coding standards |\n| [Frontend Docs](docs/frontend/README.md) | Portal UI — Vite, TypeScript, shadcn/ui, conventions |\n| [Frontend Engineer](docs/frontend/frontend-engineer.md) | Principal-style workflow, architecture, Storybook |\n| [Backend Engineer](docs/backend/backend-engineer.md) | Go layers, registry, security, quality gate |\n| [Workflow](docs/workflow.md) | CI/CD and release process |\n| [Development Flow](docs/development-flow.md) | Spec Kit workflow and AI-Assisted Development |\n| [Bruno Collections](tests/bruno/) | HTTP API tests |\n\n---\n\n## Contributing\n\n1. **Report bugs** — [Open an issue](https://github.com/weprodev/wpd-message-gateway/issues)\n2. **Suggest features** — Ideas and discussions welcome\n3. **Pull requests** — Code, docs, and tests\n4. **Add providers** — See [Contributing Guide](docs/backend/contributing.md)\n5. **Sponsor** — Support ongoing development\n\n\u003e Run **`/smell develop`** then **`make audit`** before opening a PR — see [docs/agents/verification.md](docs/agents/verification.md).\n\n---\n\n## Licensing \u0026 Sponsorship\n\nReleased under the **[MIT License](LICENSE)**.\n\n| Who | What we ask |\n|-----|------------|\n| Individuals, learning, side projects | Use freely. Sponsorship optional. |\n| Small teams | Use freely. Consider sponsoring if it's central to your stack. |\n| Mid-size companies \u0026 enterprises | **Please [sponsor](https://github.com/sponsors/weprodev)** |\n| Qualifying non-profits | Use freely. Sponsorship optional. |\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/sponsors/weprodev\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Sponsor-❤️-ea4aaa?style=for-the-badge\" alt=\"Sponsor on GitHub\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n\u003cp align=\"center\"\u003e\n  Built with ❤️ by \u003ca href=\"https://github.com/weprodev\"\u003eWeProDev\u003c/a\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweprodev%2Fwpd-message-gateway","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fweprodev%2Fwpd-message-gateway","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweprodev%2Fwpd-message-gateway/lists"}