MCPcopy Index your code
hub / github.com/JimScope/vendel

github.com/JimScope/vendel @v0.5.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.5.1 ↗ · + Follow
1,134 symbols 3,320 edges 324 files 283 documented · 25%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Vendel

Vendel

Plataforma SMS Gateway

Website · Dashboard · Read in English

Vendel - An open source SMS gateway for your own devices | Product Hunt

Vendel es una plataforma full-stack para gestión y envío de SMS a través de dispositivos conectados. Permite enviar mensajes SMS usando dispositivos registrados (teléfonos Android o módems) como gateways, con gestión de cuotas, webhooks y soporte para múltiples usuarios.

Vendel Homepage

Stack Tecnológico

Backend

  • Framework: PocketBase (Go)
  • Base de datos: SQLite (embebido)
  • Autenticación: JWT (built-in), OAuth2 (Google, GitHub)
  • Push Notifications: Firebase Cloud Messaging (FCM)
  • Email: Soporte SMTP integrado, Mailcatcher para dev local
  • Admin: Dashboard de PocketBase en /_/

Frontend

  • Framework: React 19 con TypeScript
  • Build: Vite
  • Estado: TanStack Query + TanStack Router
  • Estilos: Tailwind CSS + shadcn/ui
  • Formularios: React Hook Form + Zod
  • Cliente API: PocketBase JS SDK
  • Tests E2E: Playwright

Infraestructura

  • Hosting Backend: Render
  • Hosting Frontend: Cloudflare Pages
  • Contenedores: Docker & Docker Compose
  • CI/CD: GitHub Actions
  • Releases: Tag v* → Imagen Docker en GHCR + binarios Go vía GoReleaser

Funcionalidades Principales

SMS

  • Envío de SMS individuales y masivos
  • Distribución round-robin entre dispositivos
  • Cola de mensajes cuando no hay dispositivos online
  • Tracking de estado (pending, queued, processing, sent, delivered, failed)
  • Historial y reportes de SMS
  • Soporte para SMS entrantes

Dispositivos

  • Registro de dispositivos con API keys únicas
  • Gestión de tokens FCM para push notifications
  • Monitoreo de estado de dispositivos

Cuotas y Planes

  • Múltiples planes de suscripción
  • Tracking de cuota mensual de SMS
  • Límites de dispositivos por plan
  • Reset automático mensual de cuota (cron)

Webhooks

  • Suscripciones de webhooks configurables por tipo de evento
  • Eventos soportados: sms_received, sms_sent, sms_delivered, sms_failed
  • Payloads firmados con HMAC-SHA256 y JSON con claves ordenadas

Pagos

  • Abstracción de proveedores de pago (QvaPay)
  • Gestión de ciclo de vida de suscripciones
  • Flujos de pago por factura y autorización

Integraciones

  • API keys múltiples por usuario
  • Códigos QR para onboarding de dispositivos
  • API pública para sistemas externos

Proveedores SMS externos

Vendel puede entregar SMS a través de gateways externos además de teléfonos Android físicos y módems USB. Actualmente AWS End User Messaging (AEUM) es el primer proveedor externo soportado.

Cuando AEUM_ENABLED=true, Vendel crea un dispositivo virtual global "AWS End User Messaging" que: - Aparece en la lista de dispositivos de cada usuario (solo lectura). - Actúa como fallback cuando el usuario no tiene dispositivos físicos online. - Puede dirigirse explícitamente vía device_id en POST /api/sms/send.

El pool de AWS al que apuntes puede incluir short codes, sender IDs, números 10DLC y RCS Agents. Vendel llama a SendTextMessage una vez por destinatario; AWS elige el canal y la origination identity desde el pool.

Los eventos de delivery vuelven vía SNS HTTPS subscription a /api/webhooks/aws-aeum-events; Vendel actualiza sms_messages.status y dispara los webhooks estándar sms_delivered / sms_failed.

Configuración: ver docs/aws-end-user-messaging-setup.md.

Limitaciones del MVP: - RCS solo texto — sin rich cards, carousels, media ni suggested replies. - La selección de canal vive en AWS (el pool decide); Vendel solo expone channel=auto. - El costo no se trackea en Vendel; configura un límite mensual de gasto en la consola de AWS.

Estructura del Proyecto

vendel/
├── backend/                    # Go + PocketBase API
│   ├── main.go                 # Setup de PocketBase, hooks, cron, rutas
│   ├── go.mod / go.sum
│   ├── handlers/               # Rutas API custom (sms, planes, webhooks)
│   ├── services/               # Lógica de negocio (SMS, FCM, cuota, suscripciones)
│   │   └── payment/            # Proveedor de pago (QvaPay)
│   ├── middleware/              # Auth por API key, modo mantenimiento
│   └── migrations/             # Definiciones de colecciones + datos semilla
├── frontend/                   # App React
│   ├── src/
│   │   ├── routes/             # Páginas (TanStack Router)
│   │   ├── components/         # Componentes React
│   │   ├── hooks/              # Hooks custom (PocketBase SDK)
│   │   └── lib/pocketbase.ts   # Cliente PocketBase
│   └── tests/                  # Tests Playwright
├── modem-agent/                # Agente Go para módems USB (AT commands)
├── Dockerfile                  # Multi-stage (node + go + alpine)
├── docker-compose.yml
├── litestream.yml              # Config de replicación Litestream (opt-in)
├── entrypoint.sh               # Startup condicional (con/sin Litestream)
└── .env                        # Variables de entorno

Inicio Rápido

Requisitos Previos

  • Docker y Docker Compose
  • Go 1.23+ (para dev local del backend)
  • Node.js 24+ (para dev local del frontend)

Desarrollo con Docker Compose (Recomendado)

# Iniciar la app
docker compose up -d

# Ver logs
docker compose logs -f app

Servicios disponibles: | Servicio | URL | |----------|-----| | App (API + Frontend) | http://localhost:8090 | | PocketBase Admin | http://localhost:8090/_/ | | Mailcatcher | http://localhost:1080 |

Desarrollo Manual

Backend

cd backend

# Ejecutar servidor de desarrollo
go run . serve --http=0.0.0.0:8090

# Compilar binario
go build -o vendel .
./vendel serve --http=0.0.0.0:8090

Frontend

cd frontend

# Instalar dependencias
npm install

# Servidor de desarrollo
npm run dev

# Build
npm run build

# Tests E2E
npx playwright test

Modem Agent

El modem agent permite usar módems USB LTE/4G/5G con tarjeta SIM física como gateways de SMS — sin necesidad de un teléfono Android.

cd modem-agent

# Configurar módems (formato: api_key:command_port[:notify_port], separados por coma)
export VENDEL_URL=http://localhost:8090
export MODEMS="tu_api_key_del_dispositivo:/dev/ttyUSB0:/dev/ttyUSB1"

# Ejecutar
go run .

Configuración

Variables de Entorno

Crea un archivo .env en la raíz del proyecto:

# Core
ENVIRONMENT=local
FIRST_SUPERUSER=admin@vendel.cc
FIRST_SUPERUSER_PASSWORD=changethis

# Firebase (push notifications)
FIREBASE_SERVICE_ACCOUNT_JSON=<json-de-firebase>

# OAuth (opcional)
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=

# Pago (QvaPay)
QVAPAY_APP_ID=
QVAPAY_APP_SECRET=

# Seguridad
WEBHOOK_ENCRYPTION_KEY=         # Clave AES para secretos de webhooks

# SMTP (por defecto localhost:1025 para mailcatcher en dev)
SMTP_HOST=
SMTP_PORT=
SMTP_USERNAME=
SMTP_PASSWORD=

# Backup (Litestream - opcional)
LITESTREAM_REPLICA_URL=         # ej. s3://my-bucket/vendel/data
LITESTREAM_ACCESS_KEY_ID=
LITESTREAM_SECRET_ACCESS_KEY=

# URLs
APP_URL=http://localhost:8090
FRONTEND_URL=http://localhost:5173    # Usar el valor de APP_URL en producción

Testing

Frontend

# Tests E2E
npx playwright test

# Modo UI
npx playwright test --ui

Despliegue

  • Backend: Desplegado en Render (despliegue manual)
  • Frontend: Desplegado en Cloudflare Pages (despliegue manual)
  • Releases: Crear un tag (git tag v0.1.0 && git push --tags) para publicar imagen Docker en GHCR y compilar binarios Go vía GoReleaser
  • Modem Agent: Crear un tag (git tag modem-agent/v0.1.0 && git push --tags) para compilar binarios del modem agent

Repositorios Relacionados

Repositorio Descripción
vendel-homepage Landing page y sistema de diseño
vendel-android App Android (gateway de dispositivo)
vendel-mcp Servidor MCP para asistentes de IA
vendel-sdk-js SDK JavaScript/TypeScript (vendel-sdk en npm)
vendel-sdk-python SDK Python (vendel-sdk en PyPI)
vendel-sdk-go SDK Go (Go modules)

Licencia

MIT License

Extension points exported contracts — how you extend this code

AEUMClient (Interface)
AEUMClient is the minimal interface we depend on from the AWS SDK so we can mock it in tests without spinning up the rea [1 …
backend/services/smsprovider/aeum_provider.go
ImportMetaEnv (Interface)
(no doc)
frontend/src/vite-env.d.ts
Provider (Interface)
Provider is the interface all payment providers must implement.
backend/services/payment/provider.go
ImportMeta (Interface)
(no doc)
frontend/src/vite-env.d.ts
ConfigResolver (FuncType)
ConfigResolver reads config values (used for system_config DB fallback).
backend/services/payment/provider.go
FileRoutesByFullPath (Interface)
(no doc)
frontend/src/routeTree.gen.ts
Provider (Interface)
(no doc)
backend/services/smsprovider/provider.go
FileRoutesByTo (Interface)
(no doc)
frontend/src/routeTree.gen.ts

Core symbols most depended-on inside this repo

cn
called by 148
frontend/src/lib/utils.ts
ptrStr
called by 83
backend/migrations/1740000000_initial.go
Error
called by 55
backend/services/quota.go
useCustomToast
called by 44
frontend/src/hooks/useCustomToast.ts
showErrorToast
called by 44
frontend/src/hooks/useCustomToast.ts
showSuccessToast
called by 40
frontend/src/hooks/useCustomToast.ts
randomPassword
called by 23
frontend/tests/utils/random.ts
useAppConfig
called by 21
frontend/src/hooks/useAppConfig.ts

Shape

Function 886
Interface 126
Method 79
Struct 40
TypeAlias 2
FuncType 1

Languages

TypeScript58%
Go42%

Modules by API surface

backend/handlers/aws_aeum_events_test.go26 symbols
frontend/src/components/ui/sidebar.tsx25 symbols
backend/services/webhook.go24 symbols
backend/services/payment/provider.go19 symbols
modem-agent/profiles.go17 symbols
frontend/src/types/collections.ts17 symbols
backend/services/quota.go16 symbols
frontend/src/components/ui/dropdown-menu.tsx15 symbols
backend/handlers/sms.go14 symbols
backend/services/circuitbreaker.go13 symbols
modem-agent/main.go12 symbols
frontend/src/components/Plans/TopUpDialog.tsx12 symbols

For agents

$ claude mcp add vendel \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact