WhatsApp messages
Evolution API integration for sending text via authenticated REST.
Overview
The whatsapp module sends text messages through the Evolution API (/message/sendText/{instance}). It is a thin wrapper: one REST endpoint and a service using fetch.
Key points
- • Config via EVOLUTION_API_URL / INSTANCE / KEY
- • POST /whatsapp/send with JWT
- • Phone number sent as provided
- • Network/API failures propagate as HTTP 502
- • WhatsappService exported
Structure
src/modules/whatsapp/
├── whatsapp.module.ts
├── whatsapp.controller.ts
├── whatsapp.service.ts
└── dtos/
└── send-whatsapp.dto.ts
src/config/whatsapp.config.ts
Evolution API configuration
whatsapp namespace in src/config/whatsapp.config.ts:
EVOLUTION_API_URL=http://localhost:8080 EVOLUTION_API_INSTANCE=default EVOLUTION_API_KEY=your-api-key
Instance
The instance must exist in Evolution API. The key is sent as the apiKey request header. Missing URL/instance yields HTTP 503.
WhatsappService
Main method:
- • sendMessage(to, message) — POST ${url}/message/sendText/${instance}
- • Body: { number: to, text: message }
- • Headers: Content-Type application/json, apiKey
Error behavior
Network or non-OK Evolution HTTP → BadGatewayException (502). Missing config → ServiceUnavailableException (503). The controller does not return 200 in those cases.
// WhatsappService.sendMessage(to, message)
// number is sent as-is
POST ${EVOLUTION_API_URL}/message/sendText/${EVOLUTION_API_INSTANCE}
Headers: { "Content-Type": "application/json", "apiKey": "..." }
Body: { "number": to, "text": message }
REST API
JWT required. No @Roles — any authenticated user.
DTO
- • to — digit-only string (@Matches /^\d+$/); sent as-is
- • message — non-empty string
Send message
to: digits only, in the format Evolution expects (include DDI yourself if needed, e.g. 5511999999999). message: text.
POST /api/v1/whatsapp/send
Content-Type: application/json
Authorization: Bearer <access_token>
{
"to": "5511999999999",
"message": "Hello, this is a test message"
}Success response
{
"message": "WhatsApp message sent successfully"
}Error responses
- • 401 — missing or invalid JWT
- • 502 — Evolution unreachable or returned an error
- • 503 — EVOLUTION_API_URL / INSTANCE not configured
Use in another module
Import WhatsappModule and inject WhatsappService.
@Module({
imports: [WhatsappModule],
providers: [MyService],
})
export class MyModule {}
@Injectable()
export class MyService {
constructor(private readonly whatsappService: WhatsappService) {}
async notify(phone: string, text: string) {
await this.whatsappService.sendMessage(phone, text);
}
}
Notes
Number format
The service does not add a DDI. Send to already in the format Evolution API expects (e.g. 5511999999999 for Brazil).
API errors
Network/HTTP failures from Evolution surface as 502. Success only after response.ok.