esolutions / ws
Cliente HTTP universal para la API de WhatsApp (wsperu.dev). Compatible con PHP 7.2+ y Laravel 5.7 a 13 (y standalone).
Requires
- php: ^7.2 || ^8.0
- ext-json: *
- guzzlehttp/guzzle: ^6.0 || ^7.0 || ^8.0
Requires (Dev)
- laravel/framework: ^5.7 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0 || ^13.0
Suggests
- laravel/framework: Para autodescubrimiento del ServiceProvider y usar config('esolutions.ws.*'). No es obligatorio: la clase Client funciona standalone.
README
Cliente HTTP universal para la API de WhatsApp de wsperu.dev (docs: https://docs.wsperu.dev). Envía texto, archivos, PDF (comprobantes) y administra sesiones/líneas y grupos.
- Universal: PHP 7.2+ y Laravel 5.7 → 13, o standalone (sin Laravel).
- Usa Guzzle directamente (no el HTTP client de Illuminate, que exige Laravel 7+).
- URL fija dentro del paquete (
Client::BASE_URL = https://api.wsperu.dev): no es configurable ni inyectable — el paquete solo funciona contra la infraestructura de wsperu.dev. - Lo único configurable es el token (por inyección o
config('esolutions.ws.token')). - Todos los métodos devuelven
array(respuesta de la API) o['success' => false, 'message' => ...].
Auth: header x-api-key.
Instalación
composer require esolutions/ws
En Laravel el ServiceProvider se autodescubre. Token por env:
WS_API_TOKEN=tu_api_key
(Opcional) publicar el archivo de config:
php artisan vendor:publish --tag=esolutions-config
Uso
1) Laravel (config/env)
use Esolutions\Ws\Service; Service::sendPdf($base64Pdf, '51999999999', 'Su comprobante', 'F001-1.pdf'); Service::sendTextTo('51999999999', 'Hola 👋');
2) Token guardado en BD (inyección en runtime)
Ideal para apps donde el token se configura por pantalla y se guarda en base de datos (la URL no se pasa: está fija en el paquete):
use Esolutions\Ws\Client; $ws = new Client($config->ws_api_token); $ws->sendPdf($base64Pdf, '51999999999', 'Su comprobante', 'F001-1.pdf');
O fijándolo como default para usar la facade estática:
use Esolutions\Ws\Service; use Esolutions\Ws\Client; Service::using(new Client($config->ws_api_token)); Service::sendTextTo('51999999999', 'Hola');
3) Standalone (sin Laravel)
require 'vendor/autoload.php'; $ws = new \Esolutions\Ws\Client('tu_api_key'); $ws->sendText('51999999999', 'Hola sin framework');
Endpoints
| Método del cliente | HTTP | Endpoint |
|---|---|---|
sendText($to, $text, $sessionId = null) |
POST | /messages/send/text |
sendFile($to, $file, $caption = null, $sessionId = null) |
POST | /messages/send/file (multipart) |
sendBulk($messages, $sessionId = null) |
POST | /messages/send/bulk |
sendPdf($base64Pdf, $number, $message = '', $filename = 'document.pdf') |
POST | /message/send/pdf |
messageStatus($messageId) |
GET | /messages/{id}/status |
messageHistory($query = []) |
GET | /messages/history |
sessions() |
GET | /sessions |
createSession($name, $pairingPhone = null) |
POST | /sessions |
sessionQr($sessionId) |
GET | /sessions/{id}/qr |
sessionStatus($sessionId) |
GET | /sessions/{id}/status |
checkNumber($sessionId, $number) |
POST | /sessions/{id}/check-number |
reconnect($sessionId) |
POST | /sessions/{id}/reconnect |
disconnect($sessionId) |
POST | /sessions/{id}/disconnect |
logout($sessionId) |
POST | /sessions/{id}/logout |
deleteSession($sessionId) |
DELETE | /sessions/{id} |
groups($sessionId) |
GET | /sessions/{id}/groups |
Notas:
sendPdfno requieresessionId: usa automáticamente la primera línea conectada (pensado para sistemas de facturación).- Para enviar a un grupo, pasá el JID del grupo (
...@g.us) como$toensendText/sendFile. $fileensendFilepuede ser una ruta local o un recurso (fopen).
Compatibilidad (facade Service)
Service arrastra nombres de la versión anterior del paquete. Se mantienen —y
se van a seguir manteniendo— para no romper a nadie, pero no son los nombres
buenos: los del Client sí.
⚠️ La trampa: sendText no recibe lo mismo en los dos sitios
Service::sendText($sessionId, $to, $text); // ← sesión primero Client::sendText($to, $text, $sessionId); // ← teléfono primero
Mismo nombre, primer argumento distinto. Si te equivocas, el teléfono viaja como sesión: no hay error ni excepción, el mensaje simplemente no llega.
Para enviar texto desde la facade usa Service::sendTextTo(), que sí tiene el
mismo orden que el Client. (Se llama así porque sendText ya estaba ocupado
por la firma histórica.)
Equivalencias
Service (histórico) |
Usa mejor |
|---|---|
Service::sendText($sessionId, $to, $text) |
Service::sendTextTo($to, $text, $sessionId) |
Service::getSessions() |
Client::sessions() |
Service::getSessionStatus($id) |
Client::sessionStatus($id) |
Service::getMessageStatus($id) |
Client::messageStatus($id) |
Service::sendPdf() no tiene este problema: misma firma que el Client.
En código nuevo, usa Client directamente. Es la única clase donde los
nombres se mantienen al día.
Matriz de versiones
| Versión | |
|---|---|
| PHP | ^7.2 || ^8.0 |
| Laravel (opcional) | 5.7 → 13 |
| Guzzle | ^6.0 || ^7.0 |
El versionado del paquete lo deriva Packagist del tag de git; el
composer.jsonintencionalmente no lleva campoversion.