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
93 lines
2.4 KiB
TypeScript
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}`
|
|
})
|
|
}
|
|
})
|