> ## Documentation Index
> Fetch the complete documentation index at: https://docs.plazbot.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Ejemplos

> Ejemplos practicos de workers por tipo

A continuacion se presentan ejemplos reales de workers para cada tipo principal. Estos mismos ejemplos estan disponibles en el tab "Ejemplos" del modulo Developers en el dashboard.

***

## Tool: Consultar inventario

El agente IA consulta productos disponibles en stock desde un ERP o base de datos externa.

```typescript theme={null}
import { defineTool } from 'plz/workers'

export default defineTool({
  name: 'consultar-inventario',
  reference: 'Busca productos disponibles en stock por nombre o SKU',
  agents: ['id_agent_1'],
  parameters: [
    { name: 'query', type: 'string', description: 'Nombre o SKU del producto', example: 'Que producto estas buscando?' }
  ],

  async run(payload, plz) {
    const apiUrl = plz.env.INVENTORY_API_URL
    const apiKey = plz.env.INVENTORY_API_KEY

    const res = await fetch(`${apiUrl}/products/search?q=${payload.query}`, {
      headers: { 'Authorization': `Bearer ${apiKey}` }
    })

    const products = await res.json()

    return products.map(p => ({
      nombre: p.name,
      precio: `$${p.price}`,
      stock: p.stock > 0 ? `${p.stock} disponibles` : 'Agotado',
      sku: p.sku
    }))
  }
})
```

**Como funciona:**

* El agente detecta que el usuario pregunta por un producto.
* Recopila el parametro `query` del usuario.
* Ejecuta el tool, que consulta la API de inventario.
* El agente responde con la informacion de los productos encontrados.

**Secrets necesarios:** `INVENTORY_API_URL`, `INVENTORY_API_KEY`

***

## Worker: Notificar a Slack

Notifica a Slack cuando un contacto solicita atencion humana. Demuestra el uso de `plz.log` para registrar cada paso.

```typescript theme={null}
import { defineWorker } from 'plz/workers'

export default defineWorker({
  name: 'notificar-slack',
  reference: 'Notifica a Slack cuando un contacto solicita atencion humana',

  async run(payload, plz) {
    const { contactId, contact } = payload

    plz.log.info('Worker iniciado', { contactId })

    // Validar configuracion
    const webhookUrl = plz.env.SLACK_WEBHOOK_URL
    if (!webhookUrl) {
      plz.log.error('SLACK_WEBHOOK_URL no configurado en secrets')
      return { success: false, error: 'Webhook no configurado' }
    }

    // Obtener datos del contacto si no vienen en el payload
    let contactName = contact?.name || 'Sin nombre'
    let contactPhone = contact?.phoneNumber || ''

    if (!contact && contactId) {
      plz.log.info('Consultando datos del contacto...')
      const contactData = await plz.contacts.get(contactId)
      contactName = contactData.name || 'Sin nombre'
      contactPhone = contactData.phoneNumber || ''
    }

    plz.log.info('Contacto identificado', { contactName, contactPhone })

    // Enviar notificacion a Slack
    const message = `*Nuevo lead solicita atencion humana*\n- Nombre: ${contactName}\n- Telefono: ${contactPhone}\n- Ultimo mensaje: ${contact?.lastMessage || 'N/A'}`

    const response = await fetch(webhookUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ text: message })
    })

    if (!response.ok) {
      plz.log.error('Error enviando a Slack', await response.text())
      return { success: false }
    }

    plz.log.info('Notificacion enviada a Slack exitosamente')

    return { success: true, contactName }
  }
})
```

**Como funciona:**

* Se invoca desde una accion del agente (`action.worker`) cuando el usuario pide hablar con un humano.
* Usa `plz.log.info` y `plz.log.error` para registrar cada paso (visibles en el tab Logs).
* Obtiene datos del contacto y envia un mensaje a Slack con la informacion.

**Secrets necesarios:** `SLACK_WEBHOOK_URL`

***

## Webhook: Pagos de Stripe

Recibe notificaciones de pagos exitosos de Stripe y actualiza el contacto automaticamente.

```typescript theme={null}
import { defineWebhook } from 'plz/workers'

export default defineWebhook({
  name: 'webhook-stripe-payments',
  reference: 'Recibe eventos de pago de Stripe y actualiza contactos',
  method: 'POST',

  async run(payload, plz) {
    const event = payload

    if (event.type !== 'checkout.session.completed') {
      return { ignored: true, reason: `Evento ${event.type} ignorado` }
    }

    const session = event.data.object
    const email = session.customer_details.email

    // Buscar contacto por email y actualizar
    const matches = await plz.contacts.search({ email })

    if (matches.length > 0) {
      const contactId = matches[0].id

      // Actualizar variables custom del contacto
      await plz.contacts.setVariable(contactId, 'ctc_ultimo_pago', `$${session.amount_total / 100}`)
      await plz.contacts.setVariable(contactId, 'ctc_fecha_pago', new Date().toISOString())
      await plz.contacts.setVariable(contactId, 'ctc_stripe_customer', session.customer)

      // Agregar tag
      await plz.contacts.addTag(contactId, 'cliente-pagado')
    }

    return {
      success: true,
      email,
      amount: session.amount_total / 100,
      currency: session.currency
    }
  }
})
```

**Como funciona:**

* Stripe envia un POST a la URL del webhook cada vez que ocurre un evento.
* El worker filtra solo eventos `checkout.session.completed`.
* Busca el contacto por email y actualiza sus variables custom con los datos del pago.
* Agrega el tag `cliente-pagado` para segmentacion.

**Configuracion en Stripe:**

1. Despliega el webhook con `plazbot workers deploy webhook-stripe.ts`.
2. Copia la URL generada (visible con `plazbot workers list`).
3. Configura esa URL en Stripe Dashboard > Webhooks > Add endpoint.

***

## Schedule: Reporte nocturno

Envia un resumen diario de conversaciones pendientes al equipo por Slack, de lunes a viernes a las 10pm.

```typescript theme={null}
import { defineSchedule } from 'plz/workers'

export default defineSchedule({
  name: 'reporte-nocturno',
  reference: 'Envia resumen diario de chats pendientes por Slack',
  cron: '0 22 * * 1-5',
  timezone: 'America/Mexico_City',

  async run(plz) {
    // Obtener contactos y filtrar los no resueltos
    const allContacts = await plz.contacts.list({ limit: 200 })
    const pendingChats = allContacts.filter(c => !c.isSolved)

    const summary = {
      total: pendingChats.length,
      byAgent: {}
    }

    for (const chat of pendingChats) {
      const agent = chat.assignedAgentName || 'Sin asignar'
      summary.byAgent[agent] = (summary.byAgent[agent] || 0) + 1
    }

    const agentLines = Object.entries(summary.byAgent)
      .map(([agent, count]) => `  - ${agent}: ${count} chats`)
      .join('\n')

    await fetch(plz.env.SLACK_WEBHOOK, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        text: `*Reporte nocturno*\n\nChats pendientes: *${summary.total}*\n\nPor agente:\n${agentLines}`
      })
    })

    return { sent: true, pending: summary.total }
  }
})
```

**Como funciona:**

* Se ejecuta automaticamente de lunes a viernes a las 22:00 (hora Mexico).
* Lista todos los contactos y filtra los no resueltos.
* Agrupa los chats pendientes por agente asignado.
* Envia un resumen formateado a Slack.

**Secrets necesarios:** `SLACK_WEBHOOK`

**Cron explicado:** `0 22 * * 1-5` = minuto 0, hora 22, cualquier dia del mes, cualquier mes, lunes(1) a viernes(5).
