Skip to content

Events & Handlers

Event System#

Cognest uses an event-driven architecture. Integrations emit events, and you register handlers to process them. Events propagate through the Think Engine by default, but you can intercept them with custom handlers.

Listening for Events#

events.ts
import { Cognest } from '@cognest/sdk'

const cognest = new Cognest()

// Listen on a specific integration
const whatsapp = cognest.integration('whatsapp')

whatsapp.on('message', async (msg) => {
  console.log(`From: ${msg.from}, Text: ${msg.text}`)
  const reply = await cognest.think(msg.text, { context: msg })
  await whatsapp.send(msg.from, reply)
})

// Listen on ALL integrations
cognest.on('message', async (msg) => {
  console.log(`[${msg.integration}] ${msg.from}: ${msg.text}`)
})

Event Types#

EventDescriptionIntegrations
messageText message receivedAll messaging
message:imageImage message receivedWhatsApp, Telegram, Discord
message:fileFile attachment receivedSlack, Discord, Telegram
reactionMessage reaction added/removedSlack, Discord
mentionBot was mentionedSlack, Discord, Twitter
commandSlash command invokedSlack, Discord
webhookRaw webhook payload receivedAll
email:receivedNew email receivedGmail
calendar:eventCalendar event created/updatedGoogle Calendar
issue:createdNew issue openedGitHub
payment:receivedPayment successfulStripe

Event Object#

types.ts
interface CognestEvent {
  id: string                    // Unique event ID
  type: string                  // Event type (e.g., 'message')
  integration: string           // Source integration name
  timestamp: Date               // When the event occurred
  from: string                  // Sender identifier
  to: string                    // Recipient identifier
  data: Record<string, any>     // Integration-specific payload
  metadata: {
    raw: any                    // Raw payload from the platform
    thread_id?: string          // Conversation thread ID
    reply_to?: string           // ID of message being replied to
  }
}

Middleware Pattern#

Use middleware to intercept and transform events before they reach handlers:

middleware.ts
// Log all incoming events
cognest.use(async (event, next) => {
  console.log(`[${event.integration}] ${event.type}: ${event.from}`)
  const start = Date.now()
  await next()
  console.log(`Processed in ${Date.now() - start}ms`)
})

// Filter events
cognest.use(async (event, next) => {
  // Skip bot messages to prevent loops
  if (event.data.is_bot) return
  await next()
})

// Transform events
cognest.use(async (event, next) => {
  // Translate incoming messages
  if (event.data.language !== 'en') {
    event.data.text = await translate(event.data.text, 'en')
  }
  await next()
})

Lifecycle Events#

Monitor the internal state of your assistant:

lifecycle.ts
// Client lifecycle
cognest.on('ready', () => console.log('All integrations connected'))
cognest.on('error', (err) => console.error('Client error:', err))
cognest.on('shutdown', () => console.log('Shutting down...'))

// Integration lifecycle
cognest.on('integration:connected', (name) => {
  console.log(`${name} connected`)
})
cognest.on('integration:disconnected', (name, reason) => {
  console.log(`${name} disconnected: ${reason}`)
})

// Think Engine lifecycle
cognest.on('think:start', (context) => {
  console.log(`Processing with ${context.availableSkills.length} skills`)
})
cognest.on('think:complete', (result) => {
  console.log(`Response generated in ${result.duration}ms`)
})

Error Handling in Handlers#

error-handling.ts
whatsapp.on('message', async (msg) => {
  try {
    const reply = await cognest.think(msg.text)
    await whatsapp.send(msg.from, reply)
  } catch (error) {
    if (error instanceof CognestError) {
      console.error(`Cognest error [${error.code}]: ${error.message}`)
      await whatsapp.send(msg.from, 'Sorry, I encountered an error. Please try again.')
    } else {
      throw error // Re-throw unexpected errors
    }
  }
})