PHPackages                             funnelchat20/wapi-gateway - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. funnelchat20/wapi-gateway

ActiveLibrary

funnelchat20/wapi-gateway
=========================

WAPI Gateway: librería Composer para integrar ZApi, UAZAPI, Funapi y Meta con webhooks automáticos

v0.3.0(3d ago)0277—3.8%[2 PRs](https://github.com/Funnelchat20/wapi-gateway/pulls)proprietaryPHPPHP ^8.2

Since Nov 21Pushed 3d agoCompare

[ Source](https://github.com/Funnelchat20/wapi-gateway)[ Packagist](https://packagist.org/packages/funnelchat20/wapi-gateway)[ RSS](/packages/funnelchat20-wapi-gateway/feed)WikiDiscussions production Synced today

READMEChangelog (10)Dependencies (4)Versions (26)Used By (0)

WAPI Gateway (SDK)
==================

[](#wapi-gateway-sdk)

[![Latest Version on Packagist](https://camo.githubusercontent.com/dc9fab43bc4176a9a347c17519fe71159aa157d2b59c71a1d60f30748f392626/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f66756e6e656c6368617432302f776170692d676174657761792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/funnelchat20/wapi-gateway)[![Total Downloads](https://camo.githubusercontent.com/3a408d4687ec1eb96f078c89a889e03713e95faf09739794791af26086a9038e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f66756e6e656c6368617432302f776170692d676174657761792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/funnelchat20/wapi-gateway)

SDK puro para integrar proveedores de WhatsApp soportados por Funnelchat: **Z-API**, **UAZAPI**, **Funapi** (Whatsmeow Bridge) y **Meta** (WhatsApp Cloud), sin rutas ni middlewares. La app host consume métodos programáticos mediante un Facade y decide si expone endpoints propios.

> **⚠️ Estado:** Esta librería está en desarrollo activo (v0.x.x). La API puede cambiar entre versiones menores. Se recomienda fijar versiones específicas en composer.json hasta v1.0.0.

Requisitos
----------

[](#requisitos)

- PHP ^8.2
- Laravel ^11.0 | ^12.0

Instalación
-----------

[](#instalación)

```
composer require funnelchat20/wapi-gateway
```

### Publicar configuración

[](#publicar-configuración)

```
php artisan vendor:publish --tag=wapi-config
```

Configuración
-------------

[](#configuración)

### Variables de entorno por proveedor

[](#variables-de-entorno-por-proveedor)

#### Global (Todos los proveedores)

[](#global-todos-los-proveedores)

```
# URL base para webhooks (requerida para recibir notificaciones)
WEBHOOK_BASE_URL=https://tu-app.com
```

#### Z-API

[](#z-api)

```
ZAPI_TOKEN=tu_token_aqui
ZAPI_CLIENT_TOKEN=tu_client_token
ZAPI_TIMEOUT=29
ZAPI_MAX_ATTEMPTS=2
ZAPI_RETRY_DELAY=500
```

#### UAZAPI

[](#uazapi)

```
UAZAPI_BASE_URL=https://funnelchat.uazapi.com
UAZAPI_ADMIN_TOKEN=tu_admin_token
UAZAPI_TIMEOUT=120

# Opcional: deshabilitar configuración automática de webhooks
UAZAPI_AUTO_CONFIGURE_WEBHOOKS=true
```

#### Funapi (Whatsmeow Bridge)

[](#funapi-whatsmeow-bridge)

```
FUNAPI_BASE_URL=https://api.funapi.example.com
FUNAPI_TOKEN=tu_token
FUNAPI_CLIENT_TOKEN=tu_client_token
FUNAPI_TIMEOUT=29
FUNAPI_MAX_ATTEMPTS=2
FUNAPI_RETRY_DELAY=500
```

#### Meta (WhatsApp Cloud)

[](#meta-whatsapp-cloud)

```
META_APP_ID=tu_app_id
AWS_BUCKET_URL=https://tu-bucket.s3.amazonaws.com
```

Uso básico
----------

[](#uso-básico)

```
use Funnelchat\WapiGateway\Facades\WapiGateway;
use Funnelchat\WapiGateway\Enums\ProviderEnum;

// Enviar mensaje de texto
$response = WapiGateway::messages(ProviderEnum::ZApi)
    ->sendText($uid, $token, $phone, 'Hola mundo', [
        'delayMessage' => 0,
        'delayTyping' => 0,
        'retry' => true,  // Habilita reintentos automáticos
    ]);

if (isset($response['error'])) {
    // Manejar error
}

// Crear instancia
$data = WapiGateway::instances(ProviderEnum::ZApi)->create($userId, $deviceId);
// $data = ['uid' => '...', 'token' => '...'] o ['error' => '...']

// Obtener estado
$status = WapiGateway::instances(ProviderEnum::ZApi)->status($uid, $token);
// Incluye 'accountStatus' y 'qrCode' automáticamente
```

Compatibilidad de Proveedores
-----------------------------

[](#compatibilidad-de-proveedores)

### 📨 Mensajería

[](#-mensajería)

MétodoZ-APIUAZAPIFunapiMeta`sendText()`✅✅✅✅`sendFile()`✅✅✅✅`sendLocation()`✅✅✅✅`sendButtons()`✅✅⚠️✅`sendButtonLink()`✅✅⚠️✅`sendOptionList()`✅✅⚠️✅`sendPoll()`✅✅⚠️✅`sendLink()`✅✅⚠️✅`sendEvent()`✅✅⚠️✅`sendTemplate()`✅✅⚠️✅`pinMessage()`✅✅⚠️❌### 🔧 Instancias

[](#-instancias)

MétodoZ-APIUAZAPIFunapiMeta`create()`✅✅✅✅`status()`✅✅✅✅`qrCode()`✅✅✅✅`logout()`✅✅✅✅`reboot()`✅✅✅✅`me()`✅✅✅✅`checkPhone()`✅✅❌✅`subscribe()`✅✅✅✅`unsubscribe()`✅✅✅✅### 👥 Grupos

[](#-grupos)

MétodoZ-APIUAZAPIFunapiMeta`groups()`✅✅✅❌`group()`✅✅✅❌`createGroup()`✅✅✅❌`updateGroupName()`✅✅✅❌`updateGroupDescription()`✅✅✅❌`updateGroupSettings()`✅✅✅❌`updateGroupPhoto()`✅✅✅❌`addParticipants()`✅✅✅❌`addAdmins()`✅✅✅❌`removeParticipants()`✅✅✅❌`removeAdmins()`✅✅✅❌`leaveGroup()`✅✅✅❌`adGroups()`✅✅✅❌`groupInvitationMetadata()`✅✅✅❌`groupInvitationLink()`✅✅✅❌`lightGroupMetadata()`✅✅✅❌`groupMetadata()`✅✅✅❌### 📇 Contactos

[](#-contactos)

MétodoZ-APIUAZAPIFunapiMeta`contact()`✅✅✅❌`contacts()`✅✅✅❌`sendContact()`✅✅✅✅`addContacts()`✅✅✅❌### 🏘️ Comunidades

[](#️-comunidades)

MétodoZ-APIUAZAPIFunapiMeta`community()`✅✅⚠️❌`communities()`✅✅⚠️❌`communitiesMetadata()`✅✅⚠️❌### 📢 Newsletters / Canales

[](#-newsletters--canales)

MétodoZ-APIUAZAPIFunapiMeta`createNewsletter()`✅✅⚠️❌`updateNewsletterName()`✅✅⚠️❌`updateNewsletterDescription()`✅✅⚠️❌`updateNewsletterPicture()`✅✅⚠️❌`newsletters()`✅✅⚠️❌`newsletterMetadata()`✅✅⚠️❌### 📋 Cola de Mensajes

[](#-cola-de-mensajes)

MétodoZ-APIUAZAPIFunapiMeta`showQueue()`✅✅✅❌`queueCount()`✅✅✅❌`deleteQueueMessage()`✅✅✅❌`clearQueue()`✅✅✅❌### 📝 Templates (Solo Meta)

[](#-templates-solo-meta)

MétodoMeta`listTemplates()`✅`getTemplate()`✅`createTemplate()`✅`updateTemplate()`✅`deleteTemplate()`✅`uploadHeaderHandle()`✅**Leyenda:**

- ✅ Completamente funcional
- ⚠️ En desarrollo (retorna error descriptivo)
- ❌ No soportado por el proveedor

Funcionalidades Avanzadas
-------------------------

[](#funcionalidades-avanzadas)

### Administración de Templates (Meta/WhatsApp Cloud)

[](#administración-de-templates-metawhatsapp-cloud)

```
use Funnelchat\WapiGateway\Facades\WapiGateway;
use Funnelchat\WapiGateway\Enums\ProviderEnum;

// Listar templates
$templates = WapiGateway::templates(ProviderEnum::WhatsAppCloud)
    ->listTemplates($wabaId, $token, [
        'limit' => 20,
        'after' => 'cursor123'  // Para paginación
    ]);

// Crear template
$template = WapiGateway::templates(ProviderEnum::WhatsAppCloud)
    ->createTemplate($wabaId, $token, [
        'name' => 'welcome_message',
        'language_code' => 'es',
        'category' => 'MARKETING',
        'header' => 'Bienvenido',
        'body' => 'Hola {{1}}, gracias por contactarnos',
        'footer' => 'Equipo de soporte',
        'buttons' => [
            ['type' => 'URL', 'text' => 'Visitar sitio', 'url' => 'https://example.com']
        ]
    ]);

// Eliminar template
$result = WapiGateway::templates(ProviderEnum::WhatsAppCloud)
    ->deleteTemplate($wabaId, $token, 'welcome_message', $templateUid);
```

### Eliminación Concurrente de Mensajes

[](#eliminación-concurrente-de-mensajes)

```
$deleteRequests = [
    ['messageId' => 'msg1', 'phone' => '123456789', 'owner' => true],
    ['messageId' => 'msg2', 'phone' => '987654321', 'owner' => true],
    // ... más mensajes
];

$results = WapiGateway::groups(ProviderEnum::ZApi)
    ->deleteMessagesConcurrently($uid, $token, $deleteRequests);

// Performance: ~2s para 100 mensajes vs ~30s+ secuencial
foreach ($results as $messageId => $result) {
    if (isset($result['error'])) {
        echo "Error eliminando {$messageId}: {$result['error']}";
    }
}
```

### Procesamiento Asíncrono de Videos

[](#procesamiento-asíncrono-de-videos)

```
// Automático para .mp4, .mov, .gif
$response = WapiGateway::messages(ProviderEnum::ZApi)
    ->sendFile($uid, $token, $phone, 'https://example.com/video.mp4', [
        'caption' => 'Mi video',
        'retry' => true,
        // 'async' => false  // Desactivar si es necesario
    ]);
```

### Retry Automático

[](#retry-automático)

```
$response = WapiGateway::messages(ProviderEnum::ZApi)
    ->sendText($uid, $token, $phone, 'Mensaje importante', [
        'retry' => true  // Reintenta automáticamente en errores de conexión
    ]);

// El SDK:
// - Solo reintenta en ConnectionException
// - NO reintenta en timeouts (evita duplicados)
// - Configurable vía ZAPI_MAX_ATTEMPTS y ZAPI_RETRY_DELAY
```

Configuración Automática de Webhooks
------------------------------------

[](#configuración-automática-de-webhooks)

El SDK configura webhooks automáticamente al crear instancias para recibir notificaciones en tiempo real de mensajes, conexión/desconexión, y otros eventos.

### ⚙️ Configuración

[](#️-configuración)

**Variable requerida:**

```
WEBHOOK_BASE_URL=https://tu-app.com
```

Si no defines `WEBHOOK_BASE_URL`, el SDK usará `APP_URL` como fallback. Si ninguna está configurada, no se configurarán webhooks automáticamente.

### 📡 Webhooks por Proveedor

[](#-webhooks-por-proveedor)

#### Z-API

[](#z-api-1)

Configurados en el payload de creación de instancia:

- `/webhooks/zapi/received` - Mensajes recibidos
- `/webhooks/zapi/received-and-delivery` - Mensajes y confirmaciones de entrega
- `/webhooks/zapi/disconnected` - Instancia desconectada
- `/webhooks/zapi/connected` - Instancia conectada
- `/webhooks/zapi/message-status` - Estados de mensajes enviados
- `/webhooks/zapi/block` - Bloqueos/desbloqueos

#### UAZAPI

[](#uazapi-1)

Configurados vía POST `/webhook` después de crear la instancia:

- `/webhooks/uazapi/messages` - Mensajes recibidos
- `/webhooks/uazapi/messages_update` - Actualizaciones de mensajes
- `/webhooks/uazapi/connection` - Cambios de conexión
- `/webhooks/uazapi/messages` - Eventos de grupos (comparte ruta con messages)

**Opciones:**

```
# Deshabilitar webhooks automáticos para UAZAPI
UAZAPI_AUTO_CONFIGURE_WEBHOOKS=false
```

#### Funapi

[](#funapi)

Configurados en el payload de creación de instancia:

- `/webhooks/funapi/received` - Mensajes recibidos
- `/webhooks/funapi/received-and-delivery` - Mensajes y confirmaciones de entrega
- `/webhooks/funapi/disconnected` - Instancia desconectada
- `/webhooks/funapi/connected` - Instancia conectada
- `/webhooks/funapi/message-status` - Estados de mensajes enviados
- `/webhooks/funapi/block` - Bloqueos/desbloqueos

### 💡 Ejemplo de Uso

[](#-ejemplo-de-uso)

```
// 1. Configurar .env
// WEBHOOK_BASE_URL=https://mi-app.com

// 2. Crear instancia (webhooks se configuran automáticamente)
$instance = WapiGateway::instances(ProviderEnum::Uazapi)->create($userId, $deviceId);
// Los webhooks ya están configurados en UAZAPI

// 3. La app host debe tener rutas para recibir webhooks
Route::post('/webhooks/uazapi/messages', [WebhookController::class, 'uazapiMessages']);
Route::post('/webhooks/uazapi/connection', [WebhookController::class, 'uazapiConnection']);
// etc...
```

### 🔍 Logging

[](#-logging)

El SDK registra automáticamente el éxito/error de la configuración de webhooks:

```
// Logs en UAZAPI
Log::info('UAZAPI webhook configured successfully', [...]);
Log::warning('UAZAPI webhook configuration failed', [...]);
Log::warning('UAZAPI webhook configuration skipped: WEBHOOK_BASE_URL not configured', [...]);
```

Device Logging (Request/Response a DB)
--------------------------------------

[](#device-logging-requestresponse-a-db)

El SDK puede loggear cada request HTTP a los proveedores en la tabla `device_logs`, incluyendo el payload enviado y la respuesta recibida. El logging está **deshabilitado por defecto** — solo se activa explícitamente en el proyecto que lo necesite.

### Configuración

[](#configuración-1)

```
# Habilitar logging a DB (deshabilitado por defecto)
WAPI_GATEWAY_LOGGING_ENABLED=true

# Conexión de base de datos a usar (por defecto: mysql)
WAPI_GATEWAY_DATABASE_CONNECTION=mysql
```

> **Importante:** No habilites `WAPI_GATEWAY_LOGGING_ENABLED=true` sin antes publicar y correr la migración. Con `queue: sync` (común en desarrollo), el job fallará directamente si la tabla no existe.

### Migración

[](#migración)

La migración **no se ejecuta automáticamente** al instalar el paquete. Solo debe publicarse en el proyecto que será dueño de la tabla `device_logs` (actualmente `user-api`):

```
# Solo en user-api:
php artisan vendor:publish --tag=wapi-migrations
php artisan migrate
```

Los demás proyectos que usen el paquete (`new-groups`, `sync-group-api`, etc.) no necesitan publicar la migración — solo configurar `WAPI_GATEWAY_DATABASE_CONNECTION` apuntando a la misma base de datos donde `user-api` creó la tabla.

### Estructura de la tabla `device_logs`

[](#estructura-de-la-tabla-device_logs)

CampoTipoDescripción`instance_uid`stringUID de la instancia de WhatsApp`provider`stringProveedor usado (`zapi`, `uazapi`, `funapi`, `meta`)`method`stringMétodo ejecutado (`sendText`, `status`, `createGroup`, etc.)`url`textURL completa del request HTTP`request_payload`jsonBody enviado al proveedor (ej: `{"phone": "549...", "message": "Hola"}`)`response_body`jsonRespuesta del proveedor`status_code`smallintCódigo HTTP de respuesta`duration_ms`intTiempo de respuesta en milisegundos`is_error`booleanSi el request resultó en error`sent_at`timestampFecha y hora real del request HTTP (distinto de `created_at` que es cuando se persistió el registro)### Queue

[](#queue)

Los logs se despachan vía el job `StoreDeviceLogJob` en la cola `device-logs`. Asegurate de tener un worker procesando esa cola:

```
php artisan queue:work --queue=device-logs
```

El dispatch del job está protegido con try-catch — si la infraestructura de cola falla (Redis caído, etc.), el error se loggea pero no interrumpe la operación de WhatsApp que lo originó.

### Protección contra payloads grandes

[](#protección-contra-payloads-grandes)

Los payloads de request y response se truncan automáticamente si superan 200KB (para evitar exceder el límite de 256KB de SQS). Cuando esto ocurre, el campo almacena `{"_truncated": true, "original_size": 350000}`.

### Notas

[](#notas)

- Los métodos GET (`status`, `qrCode`, `me`, `contact`, etc.) registran `request_payload` como `[]` ya que no envían body.
- Los métodos POST (`sendText`, `sendFile`, `createGroup`, `addContacts`, etc.) registran el payload completo enviado al proveedor.
- El logging es asíncrono y no impacta el tiempo de respuesta de las operaciones.
- El job usa 3 reintentos con backoff progresivo (5s, 15s, 30s) y timeout de 10s.

Sistema de Resources
--------------------

[](#sistema-de-resources)

El SDK transforma las respuestas de cada proveedor para mantener compatibilidad con WAPI original:

```
// Ejemplo: status() con fetch automático de QR
$status = WapiGateway::instances(ProviderEnum::ZApi)->status($uid, $token);
// Retorna: ['accountStatus' => 'authenticated', 'qrCode' => null]
// o: ['accountStatus' => 'got qr code', 'qrCode' => 'data:image/png;base64,...']

// checkPhone() normalizado
$result = WapiGateway::instances(ProviderEnum::ZApi)->checkPhone($uid, $token, $phone);
// Retorna: ['result' => true] (no 'exists', sino 'result')

// me() con campos adicionales
$me = WapiGateway::instances(ProviderEnum::ZApi)->me($uid, $token);
// Retorna: ['phone' => '...', 'name' => '...', 'avatar' => '...', 'locale' => 'es', 'isBusiness' => true]
```

Limitaciones de Funapi
----------------------

[](#limitaciones-de-funapi)

Funapi (Whatsmeow Bridge) tiene las siguientes **limitaciones conocidas**:

### ❌ No Soportado

[](#-no-soportado)

- `checkPhone()` - No existe endpoint equivalente

### ⚠️ En Desarrollo

[](#️-en-desarrollo)

Los siguientes métodos retornan error descriptivo indicando que están en desarrollo:

- `sendButtons()`
- `sendButtonLink()`
- `sendOptionList()`
- `sendPoll()`
- `sendLink()`
- `sendEvent()`
- `sendTemplate()`

### ✅ Totalmente Funcional

[](#-totalmente-funcional)

- Mensajería básica: texto, archivos, ubicación, contactos
- Gestión de instancias completa
- Operaciones de grupos completas
- Cola de mensajes completa

Manejo de Errores
-----------------

[](#manejo-de-errores)

Todos los métodos retornan arrays con:

- Éxito: `['messageId' => '...', 'status' => 'queued', ...]`
- Error: `['error' => 'mensaje descriptivo']`

```
$response = WapiGateway::messages(ProviderEnum::ZApi)->sendText(...);

if (isset($response['error'])) {
    // Error normalizado del proveedor
    Log::error('Error enviando mensaje', ['error' => $response['error']]);
    return response()->json(['error' => $response['error']], 409);
}

// Éxito
return response()->json($response);
```

Integración en Controladores
----------------------------

[](#integración-en-controladores)

```
use Funnelchat\WapiGateway\Facades\WapiGateway;
use Funnelchat\WapiGateway\Enums\ProviderEnum;

class WhatsAppController extends Controller
{
    public function send(Request $request)
    {
        $provider = match($request->provider) {
            'zapi' => ProviderEnum::ZApi,
            'uazapi' => ProviderEnum::Uazapi,
            'funapi' => ProviderEnum::Funapi,
            'meta' => ProviderEnum::WhatsAppCloud,
        };

        $response = WapiGateway::messages($provider)
            ->sendText(
                $request->uid,
                $request->header('token'),
                $request->phone,
                $request->message,
                ['retry' => true]
            );

        return isset($response['error'])
            ? response()->json(['error' => $response['error']], 409)
            : response()->json($response);
    }
}
```

Changelog
---------

[](#changelog)

### v0.3.0 - 2025-XX-XX (En desarrollo)

[](#v030---2025-xx-xx-en-desarrollo)

**Added:**

- ✨ Soporte completo para Newsletters/Canales: `createNewsletter()`, `updateNewsletterName()`, `updateNewsletterDescription()`, `updateNewsletterPicture()`, `newsletters()`, `newsletterMetadata()`
- ✨ Soporte para Comunidades: `community()`, `communities()`, `communitiesMetadata()`
- ✨ Sección de Contactos: `contact()`, `contacts()`, `sendContact()`, `addContacts()`
- ✨ Métodos de grupos: `adGroups()`, `groupInvitationMetadata()`, `groupInvitationLink()`, `lightGroupMetadata()`, `groupMetadata()`
- ✨ Método `pinMessage()` en MessagesContract
- ✨ Device Logging: `StoreDeviceLogJob` registra request payload y response en tabla `device_logs` vía cola asíncrona
- ✨ Campo `sent_at` en `device_logs` para capturar fecha/hora real del request HTTP
- ✨ Migración publicable vía `--tag=wapi-migrations` (solo para el proyecto dueño de la tabla)
- ✨ Trait `LogsDeviceRequests` — elimina ~160 líneas duplicadas entre los 4 clientes

**Fixed:**

- 🐛 `request_payload` en `device_logs` ahora contiene el body HTTP real enviado al proveedor en todos los métodos POST (antes se guardaba `[]`)
- 🐛 `StoreDeviceLogJob::dispatch()` envuelto en try-catch para no interrumpir operaciones de WhatsApp si la cola falla
- 🐛 Payloads &gt;200KB se truncan automáticamente para no exceder límite de SQS (256KB)
- 🐛 `ZApiClient::create()` ahora pasa `instance_uid` correctamente (antes pasaba string vacío)
- 🐛 Variable de entorno `WAPI_GATEWAY_DATABASE_CONNECTION` consistente entre config y README
- 🐛 `$backoff` corregido de `[5, 15]` a `[5, 15, 30]` para matchear `$tries = 3`
- 🐛 Métodos `sendFile`, `sendLocation`, y newsletter updates en FunapiClient/ZApiClient ahora logean el payload del request

**Changed:**

- 🔧 Default de `logging_enabled` cambiado de `true` a `false` (opt-in explícito)
- 🔧 Migración no se auto-carga — solo se publica en el proyecto que la necesite (`user-api`)
- 🔧 Casts de `DeviceLog` ampliados: `status_code => integer`, `duration_ms => integer`

### v0.2.0 - 2025-01-XX

[](#v020---2025-01-xx)

**Added:**

- ✨ Configuración automática de webhooks al crear instancias
- ✨ Variable de entorno `WEBHOOK_BASE_URL` para configuración centralizada
- ✨ Método privado `configureWebhooks()` en UazapiClient con logging completo
- ✨ Soporte para deshabilitar webhooks con `UAZAPI_AUTO_CONFIGURE_WEBHOOKS=false`

**Changed:**

- 🔧 ZApiClient, UazapiClient y FunapiClient ahora usan `WEBHOOK_BASE_URL` en lugar de `APP_URL`
- 🔧 Webhooks solo se configuran si `WEBHOOK_BASE_URL` está definida

### v0.1.0 - 2025-01-07

[](#v010---2025-01-07)

**Added:**

- ✨ Sistema completo de Resources para transformación de respuestas
- ✨ Soporte para Funapi (Whatsmeow Bridge) - 36/44 métodos funcionales
- ✨ Fetch automático de QR code en método `status()` cuando la instancia está desconectada
- ✨ Normalización de respuestas entre proveedores (accountStatus, result, locale, etc.)
- ✨ 20 Resources implementados (10 Z-API + 10 UAZAPI)
- ✨ Administración completa de templates para Meta/WhatsApp Cloud
- ✨ Método `deleteMessagesConcurrently()` para eliminación paralela de mensajes
- ✨ Retry automático configurable en métodos de envío
- ✨ Procesamiento asíncrono automático para videos
- ✨ Timeouts configurables por proveedor

**Fixed:**

- 🐛 Corregidos endpoints de Funapi (`/send-image` y `/send-document` sin sufijos)
- 🐛 Métodos no soportados de Funapi ahora retornan errores descriptivos

**Changed:**

- 🔧 Timeout por defecto reducido de 120s a 29s (configurable)
- 🔧 Retry inteligente: no reintenta en timeouts, solo en ConnectionException

**Performance:**

- ⚡ Eliminación de 100 mensajes: ~2s con HTTP Pool vs ~30s+ secuencial
- ⚡ Reducción de timeouts en envíos de videos gracias a procesamiento async

Roadmap
-------

[](#roadmap)

- Completar endpoints faltantes de Funapi (botones, listas, encuestas)
- Tests automatizados para todos los proveedores
- Documentación de DTOs y respuestas por operación
- Soporte para webhooks (configuración automática implementada)
- v1.0.0 - Release estable cuando todos los proveedores estén 100% completos

Contribución
------------

[](#contribución)

Esta es una librería privada de Funnelchat. Para reportar bugs o solicitar features, contacta a:

Licencia
--------

[](#licencia)

Privado (Funnelchat). Todos los derechos reservados.

###  Health Score

45

—

FairBetter than 93% of packages

Maintenance99

Actively maintained with recent releases

Popularity17

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 58.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

21

Last Release

3d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/59efc095e20f9321c3e3fafb3aebc9c3cc948b2faa42afc97d4e8d2499af2ef5?d=identicon)[marcelo.marin](/maintainers/marcelo.marin)

---

Top Contributors

[![marcemarin](https://avatars.githubusercontent.com/u/7118089?v=4)](https://github.com/marcemarin "marcemarin (27 commits)")[![martinherrera](https://avatars.githubusercontent.com/u/11825893?v=4)](https://github.com/martinherrera "martinherrera (15 commits)")[![haacho](https://avatars.githubusercontent.com/u/14254155?v=4)](https://github.com/haacho "haacho (4 commits)")

---

Tags

backendlibrary

### Embed Badge

![Health badge](/badges/funnelchat20-wapi-gateway/health.svg)

```
[![Health](https://phpackages.com/badges/funnelchat20-wapi-gateway/health.svg)](https://phpackages.com/packages/funnelchat20-wapi-gateway)
```

###  Alternatives

[leantime/leantime

Open source project management system for non-project managers. Simple like Trello, powerful like Jira. Built with neurodiversity in mind.

9.4k2.8k](/packages/leantime-leantime)[inovector/mixpost-pro-team-app

Standalone application with the Laravel Package of Mixpost Pro Team pre-installed and configured

1028.2k](/packages/inovector-mixpost-pro-team-app)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
