Files
whatsappNucleo/server/api/messages/send.post.ts
josedario87 faedec47d7
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 6m46s
feat: WhatsApp Nucleo con Nuxt 4 + Baileys v7
Reemplazo completo de Evolution API por implementación directa con Baileys.

Características:
- Dashboard completo con Nuxt UI v4
- Soporte para múltiples instancias de WhatsApp
- Conexión via QR code o pairing code
- Persistencia de mensajes en PostgreSQL
- API REST para integraciones externas
- Webhooks con firma HMAC
- SSE para actualizaciones en tiempo real
- Autenticación con Authentik
2025-12-02 17:54:31 -06:00

93 lines
2.4 KiB
TypeScript

/**
* POST /api/messages/send
* Send a message (External API - uses API Key)
*/
import { query } from '../../utils/database'
import { baileysManager } from '../../services/baileys/manager'
interface SendMessageBody {
instanceId: string
to: string
message: string
}
export default defineEventHandler(async (event) => {
// Check API Key authentication
const authHeader = getHeader(event, 'authorization')
if (!authHeader?.startsWith('Bearer ')) {
throw createError({ statusCode: 401, message: 'API Key required' })
}
const apiKey = authHeader.slice(7)
const config = useRuntimeConfig()
// Check master API key
if (config.masterApiKey && apiKey === config.masterApiKey) {
// Master key - allowed
} else {
// Check database API keys
const crypto = await import('crypto')
const keyHash = crypto.createHash('sha256').update(apiKey).digest('hex')
const keyResult = await query(
`SELECT id, instance_id FROM api_keys
WHERE key_hash = $1 AND is_active = TRUE
AND (expires_at IS NULL OR expires_at > NOW())`,
[keyHash]
)
if (keyResult.rows.length === 0) {
throw createError({ statusCode: 401, message: 'Invalid API Key' })
}
// Update last used
await query(
'UPDATE api_keys SET last_used_at = NOW() WHERE id = $1',
[keyResult.rows[0].id]
)
}
// Parse body
const body = await readBody<SendMessageBody>(event)
if (!body.instanceId) {
throw createError({ statusCode: 400, message: 'instanceId is required' })
}
if (!body.to) {
throw createError({ statusCode: 400, message: 'to is required' })
}
if (!body.message?.trim()) {
throw createError({ statusCode: 400, message: 'message is required' })
}
// Format JID
let jid = body.to.replace(/[^0-9]/g, '')
if (!jid.includes('@')) {
jid = `${jid}@s.whatsapp.net`
}
// Check instance exists and is connected
const status = baileysManager.getStatus(body.instanceId)
if (!status || status.status !== 'connected') {
throw createError({ statusCode: 400, message: 'Instance not connected' })
}
try {
const result = await baileysManager.sendMessage(body.instanceId, jid, {
text: body.message
})
return {
success: true,
messageId: result.key.id,
to: jid
}
} catch (error) {
throw createError({
statusCode: 500,
message: `Failed to send message: ${(error as Error).message}`
})
}
})