feat: WhatsApp Nucleo con Nuxt 4 + Baileys v7
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 6m46s
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 6m46s
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
This commit is contained in:
92
server/api/messages/send.post.ts
Normal file
92
server/api/messages/send.post.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* 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}`
|
||||
})
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user