diff --git a/README.md b/README.md index 3bcea7e..61d05ee 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Built on a **pluggable architecture**, OpenWA lets you swap database engines (SQ | Feature | Status | Description | | ----------------- | ------ | -------------------------------- | -| Text Messages | ✅ | Send/receive text messages | +| Text Messages | ✅ | Send/receive text messages with link preview | | Media Messages | ✅ | Images, videos, documents, audio | | Message Reactions | ✅ | React to messages with emoji | | Bulk Messaging | ✅ | Send to multiple recipients | @@ -284,6 +284,14 @@ Comprehensive documentation is available in the `docs/` folder: --- +## 📝 Changelog + +### v0.1.7 +- **Link Preview**: Text messages containing URLs now automatically generate WhatsApp link preview cards (`linkPreview: true`) +- **HTTP Compatibility**: Dashboard now works when accessed via HTTP (non-secure context) — `crypto.randomUUID` fallback added for environments without HTTPS + +--- + ## 🤝 Contributing We welcome contributions! Here's how to get started: diff --git a/dashboard/src/components/Toast.tsx b/dashboard/src/components/Toast.tsx index d41df26..9a90865 100644 --- a/dashboard/src/components/Toast.tsx +++ b/dashboard/src/components/Toast.tsx @@ -45,7 +45,9 @@ export function ToastProvider({ children }: ToastProviderProps) { const addToast = useCallback( (toast: Omit) => { - const id = crypto.randomUUID(); + const id = typeof crypto.randomUUID === 'function' + ? crypto.randomUUID() + : `${Date.now()}-${Math.random().toString(36).slice(2)}`; const newToast = { ...toast, id }; setToasts(prev => [...prev, newToast]); diff --git a/docker-compose.yml b/docker-compose.yml index 229ea4f..34e95ad 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,8 +9,8 @@ services: profiles: ['with-proxy', 'full'] restart: unless-stopped ports: - - '127.0.0.1:${DASHBOARD_PORT:-2886}:80' - - '127.0.0.1:8080:8080' # Traefik dashboard + - '${DASHBOARD_PORT:-2886}:80' + - '127.0.0.1:8080:8080' # Traefik dashboard (localhost only) volumes: - ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro - ./traefik/dynamic.yml:/etc/traefik/dynamic.yml:ro @@ -26,14 +26,16 @@ services: container_name: openwa-api restart: unless-stopped ports: - - '127.0.0.1:${API_PORT:-2785}:2785' + - '${API_PORT:-2785}:2785' expose: - '2785' environment: # Core - NODE_ENV=${NODE_ENV:-production} - PORT=2785 - - LOG_LEVEL=${LOG_LEVEL:-info} + - LOG_LEVEL=${LOG_LEVEL:-warn} + # Node.js memory limit + - NODE_OPTIONS=--max-old-space-size=512 # Database - DATABASE_TYPE=${DATABASE_TYPE:-sqlite} - DATABASE_NAME=${DATABASE_NAME:-/app/data/openwa.sqlite} @@ -46,7 +48,7 @@ services: - ENGINE_TYPE=${ENGINE_TYPE:-whatsapp-web.js} - SESSION_DATA_PATH=/app/data/sessions - PUPPETEER_HEADLESS=${PUPPETEER_HEADLESS:-true} - - PUPPETEER_ARGS=${PUPPETEER_ARGS:---no-sandbox,--disable-setuid-sandbox,--disable-dev-shm-usage,--disable-gpu} + - PUPPETEER_ARGS=${PUPPETEER_ARGS:---no-sandbox,--disable-setuid-sandbox,--disable-dev-shm-usage,--disable-gpu,--single-process,--no-zygote,--disable-extensions,--disable-background-networking,--disable-default-apps,--disable-sync,--disable-translate,--disable-features=TranslateUI,--mute-audio,--disable-software-rasterizer} # Storage - STORAGE_TYPE=${STORAGE_TYPE:-local} - STORAGE_LOCAL_PATH=/app/data/media @@ -70,6 +72,8 @@ services: - PLUGINS_DIR=/app/data/plugins # Security - API_MASTER_KEY=${API_MASTER_KEY:-} + mem_limit: 1536m + memswap_limit: 2048m volumes: - openwa-data:/app/data - /var/run/docker.sock:/var/run/docker.sock:ro diff --git a/src/engine/adapters/whatsapp-web-js.adapter.ts b/src/engine/adapters/whatsapp-web-js.adapter.ts index 727a3db..d1ea1d7 100644 --- a/src/engine/adapters/whatsapp-web-js.adapter.ts +++ b/src/engine/adapters/whatsapp-web-js.adapter.ts @@ -271,7 +271,7 @@ export class WhatsAppWebJsAdapter extends EventEmitter implements IWhatsAppEngin async sendTextMessage(chatId: string, text: string): Promise { this.ensureReady(); - const msg = await this.client!.sendMessage(chatId, text); + const msg = await this.client!.sendMessage(chatId, text, { linkPreview: true }); return { id: msg.id._serialized, timestamp: msg.timestamp,