Webhooks: Completar integracion backend-frontend
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m1s
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m1s
- Inicializar webhookDispatcher en plugin de servidor - Conectar pagina de webhooks con API - Agregar selector de instancias en formulario - Corregir bug en toast de handleSaved
This commit is contained in:
@@ -93,9 +93,15 @@ interface Webhook {
|
||||
instanceId?: string
|
||||
}
|
||||
|
||||
interface Instance {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
|
||||
interface Props {
|
||||
open: boolean
|
||||
webhook?: Webhook | null
|
||||
instances?: Instance[]
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
@@ -129,8 +135,11 @@ const availableEvents = [
|
||||
{ value: 'instance.qr', label: 'QR disponible' }
|
||||
]
|
||||
|
||||
// TODO: Cargar instancias reales
|
||||
const instanceOptions = ref<any[]>([])
|
||||
// Instance options for selector
|
||||
const instanceOptions = computed(() => [
|
||||
{ label: 'Todas las instancias', value: null },
|
||||
...(props.instances || []).map(i => ({ label: i.name, value: i.id }))
|
||||
])
|
||||
|
||||
const isValid = computed(() => {
|
||||
return form.value.name.trim() && form.value.url.trim() && form.value.events.length > 0
|
||||
|
||||
@@ -8,27 +8,34 @@
|
||||
</div>
|
||||
<UButton
|
||||
icon="i-lucide-plus"
|
||||
@click="showCreateModal = true"
|
||||
@click="openCreateModal"
|
||||
>
|
||||
Nuevo Webhook
|
||||
</UButton>
|
||||
</div>
|
||||
|
||||
<!-- Webhooks List -->
|
||||
<div v-if="webhooks.length === 0" class="instance-card p-12 text-center">
|
||||
<!-- Loading -->
|
||||
<div v-if="loading" class="instance-card p-12 text-center">
|
||||
<UIcon name="i-lucide-loader-2" class="w-8 h-8 text-[var(--wa-text-muted)] mx-auto mb-4 animate-spin" />
|
||||
<p class="text-[var(--wa-text-muted)]">Cargando webhooks...</p>
|
||||
</div>
|
||||
|
||||
<!-- Empty state -->
|
||||
<div v-else-if="webhooks.length === 0" class="instance-card p-12 text-center">
|
||||
<UIcon name="i-lucide-webhook" class="w-16 h-16 text-[var(--wa-text-muted)] mx-auto mb-4" />
|
||||
<h3 class="text-xl font-semibold text-[var(--wa-text)] mb-2">No hay webhooks configurados</h3>
|
||||
<p class="text-[var(--wa-text-muted)] mb-6">Los webhooks te permiten recibir notificaciones en tiempo real cuando ocurren eventos en WhatsApp</p>
|
||||
<UButton
|
||||
icon="i-lucide-plus"
|
||||
@click="showCreateModal = true"
|
||||
@click="openCreateModal"
|
||||
>
|
||||
Crear Webhook
|
||||
</UButton>
|
||||
</div>
|
||||
|
||||
<!-- Webhooks list -->
|
||||
<div v-else class="space-y-4">
|
||||
<WebhookCard
|
||||
<WebhooksWebhookCard
|
||||
v-for="webhook in webhooks"
|
||||
:key="webhook.id"
|
||||
:webhook="webhook"
|
||||
@@ -39,10 +46,11 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Create Webhook Modal -->
|
||||
<WebhookFormModal
|
||||
v-model:open="showCreateModal"
|
||||
<!-- Create/Edit Webhook Modal -->
|
||||
<WebhooksWebhookFormModal
|
||||
v-model:open="showModal"
|
||||
:webhook="editingWebhook"
|
||||
:instances="instances"
|
||||
@saved="handleSaved"
|
||||
/>
|
||||
</div>
|
||||
@@ -55,32 +63,139 @@ definePageMeta({
|
||||
icon: 'i-lucide-webhook'
|
||||
})
|
||||
|
||||
const showCreateModal = ref(false)
|
||||
const editingWebhook = ref<any>(null)
|
||||
const toast = useToast()
|
||||
|
||||
// TODO: Conectar con API real
|
||||
const showModal = ref(false)
|
||||
const editingWebhook = ref<any>(null)
|
||||
const loading = ref(true)
|
||||
const webhooks = ref<any[]>([])
|
||||
const instances = ref<any[]>([])
|
||||
|
||||
// Fetch webhooks
|
||||
const fetchWebhooks = async () => {
|
||||
try {
|
||||
webhooks.value = await $fetch('/api/webhooks')
|
||||
} catch (error) {
|
||||
console.error('Error fetching webhooks:', error)
|
||||
toast.add({
|
||||
title: 'Error',
|
||||
description: 'No se pudieron cargar los webhooks',
|
||||
color: 'red'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch instances for the form
|
||||
const fetchInstances = async () => {
|
||||
try {
|
||||
instances.value = await $fetch('/api/instances')
|
||||
} catch (error) {
|
||||
console.error('Error fetching instances:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Initial load
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
await Promise.all([fetchWebhooks(), fetchInstances()])
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
const openCreateModal = () => {
|
||||
editingWebhook.value = null
|
||||
showModal.value = true
|
||||
}
|
||||
|
||||
const handleEdit = (webhook: any) => {
|
||||
editingWebhook.value = webhook
|
||||
showCreateModal.value = true
|
||||
showModal.value = true
|
||||
}
|
||||
|
||||
const handleDelete = async (webhookId: string) => {
|
||||
console.log('Deleting webhook', webhookId)
|
||||
if (!confirm('¿Estás seguro de eliminar este webhook?')) return
|
||||
|
||||
try {
|
||||
await $fetch(`/api/webhooks/${webhookId}`, { method: 'DELETE' })
|
||||
webhooks.value = webhooks.value.filter(w => w.id !== webhookId)
|
||||
toast.add({
|
||||
title: 'Webhook eliminado',
|
||||
color: 'green'
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error deleting webhook:', error)
|
||||
toast.add({
|
||||
title: 'Error',
|
||||
description: 'No se pudo eliminar el webhook',
|
||||
color: 'red'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handleTest = async (webhookId: string) => {
|
||||
console.log('Testing webhook', webhookId)
|
||||
try {
|
||||
const result = await $fetch<{ success: boolean; status?: number; error?: string }>(
|
||||
`/api/webhooks/${webhookId}/test`,
|
||||
{ method: 'POST' }
|
||||
)
|
||||
|
||||
if (result.success) {
|
||||
toast.add({
|
||||
title: 'Test exitoso',
|
||||
description: `El webhook respondio con status ${result.status}`,
|
||||
color: 'green'
|
||||
})
|
||||
} else {
|
||||
toast.add({
|
||||
title: 'Test fallido',
|
||||
description: result.error || 'El webhook no respondio correctamente',
|
||||
color: 'red'
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error testing webhook:', error)
|
||||
toast.add({
|
||||
title: 'Error',
|
||||
description: 'No se pudo probar el webhook',
|
||||
color: 'red'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handleToggle = async (webhookId: string, active: boolean) => {
|
||||
console.log('Toggle webhook', webhookId, active)
|
||||
try {
|
||||
await $fetch(`/api/webhooks/${webhookId}`, {
|
||||
method: 'PUT',
|
||||
body: { isActive: active }
|
||||
})
|
||||
|
||||
// Update local state
|
||||
const webhook = webhooks.value.find(w => w.id === webhookId)
|
||||
if (webhook) {
|
||||
webhook.isActive = active
|
||||
}
|
||||
|
||||
const handleSaved = (webhook: any) => {
|
||||
showCreateModal.value = false
|
||||
toast.add({
|
||||
title: active ? 'Webhook activado' : 'Webhook desactivado',
|
||||
color: 'green'
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error toggling webhook:', error)
|
||||
toast.add({
|
||||
title: 'Error',
|
||||
description: 'No se pudo cambiar el estado del webhook',
|
||||
color: 'red'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handleSaved = async () => {
|
||||
const isEdit = !!editingWebhook.value
|
||||
showModal.value = false
|
||||
editingWebhook.value = null
|
||||
// TODO: Refresh list
|
||||
await fetchWebhooks()
|
||||
toast.add({
|
||||
title: isEdit ? 'Webhook actualizado' : 'Webhook creado',
|
||||
color: 'green'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/**
|
||||
* Nitro plugin to initialize Baileys manager on server start
|
||||
* Nitro plugin to initialize Baileys manager and Webhook dispatcher on server start
|
||||
*/
|
||||
import { baileysManager } from '../services/baileys/manager'
|
||||
import { webhookDispatcher } from '../services/webhooks/dispatcher'
|
||||
|
||||
export default defineNitroPlugin(async () => {
|
||||
console.log('[Plugin] Initializing Baileys Manager...')
|
||||
@@ -12,7 +13,11 @@ export default defineNitroPlugin(async () => {
|
||||
try {
|
||||
await baileysManager.initialize()
|
||||
console.log('[Plugin] Baileys Manager initialized successfully')
|
||||
|
||||
// Initialize webhook dispatcher after baileys manager
|
||||
await webhookDispatcher.initialize()
|
||||
console.log('[Plugin] Webhook Dispatcher initialized successfully')
|
||||
} catch (error) {
|
||||
console.error('[Plugin] Failed to initialize Baileys Manager:', error)
|
||||
console.error('[Plugin] Failed to initialize:', error)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user