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:
100
server/api/webhooks/[id]/test.post.ts
Normal file
100
server/api/webhooks/[id]/test.post.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* POST /api/webhooks/:id/test
|
||||
* Test a webhook with a sample payload
|
||||
*/
|
||||
import { query } from '../../../utils/database'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const username = getHeader(event, 'x-authentik-username')
|
||||
if (!username) {
|
||||
throw createError({ statusCode: 401, message: 'Unauthorized' })
|
||||
}
|
||||
|
||||
const id = getRouterParam(event, 'id')
|
||||
|
||||
// Get webhook
|
||||
const result = await query<{ url: string; secret: string | null; headers: any }>(
|
||||
'SELECT url, secret, headers FROM webhooks WHERE id = $1',
|
||||
[id]
|
||||
)
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
throw createError({ statusCode: 404, message: 'Webhook not found' })
|
||||
}
|
||||
|
||||
const webhook = result.rows[0]
|
||||
|
||||
// Create test payload
|
||||
const testPayload = {
|
||||
event: 'test',
|
||||
timestamp: new Date().toISOString(),
|
||||
data: {
|
||||
message: 'This is a test webhook delivery',
|
||||
webhookId: id,
|
||||
sentBy: username
|
||||
}
|
||||
}
|
||||
|
||||
const body = JSON.stringify(testPayload)
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Webhook-Event': 'test',
|
||||
'X-Webhook-Timestamp': Date.now().toString(),
|
||||
...(webhook.headers || {})
|
||||
}
|
||||
|
||||
// Add signature if secret exists
|
||||
if (webhook.secret) {
|
||||
const crypto = await import('crypto')
|
||||
const signature = crypto
|
||||
.createHmac('sha256', webhook.secret)
|
||||
.update(body)
|
||||
.digest('hex')
|
||||
headers['X-Webhook-Signature'] = `sha256=${signature}`
|
||||
}
|
||||
|
||||
try {
|
||||
const controller = new AbortController()
|
||||
const timeout = setTimeout(() => controller.abort(), 10000)
|
||||
|
||||
const response = await fetch(webhook.url, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body,
|
||||
signal: controller.signal
|
||||
})
|
||||
|
||||
clearTimeout(timeout)
|
||||
|
||||
const responseText = await response.text()
|
||||
|
||||
// Log the test
|
||||
await query(
|
||||
`INSERT INTO webhook_logs (webhook_id, event_type, payload, response_status, response_body, attempt, delivered_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)`,
|
||||
[id, 'test', testPayload, response.status, responseText.slice(0, 1000), 1, new Date()]
|
||||
)
|
||||
|
||||
return {
|
||||
success: response.ok,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
response: responseText.slice(0, 500)
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = (error as Error).message
|
||||
|
||||
// Log the failure
|
||||
await query(
|
||||
`INSERT INTO webhook_logs (webhook_id, event_type, payload, response_status, error_message, attempt)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)`,
|
||||
[id, 'test', testPayload, 0, errorMessage, 1]
|
||||
)
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: errorMessage
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user