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.
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 | Description | Integrations |
|---|---|---|
| message | Text message received | All messaging |
| message:image | Image message received | WhatsApp, Telegram, Discord |
| message:file | File attachment received | Slack, Discord, Telegram |
| reaction | Message reaction added/removed | Slack, Discord |
| mention | Bot was mentioned | Slack, Discord, Twitter |
| command | Slash command invoked | Slack, Discord |
| webhook | Raw webhook payload received | All |
| email:received | New email received | Gmail |
| calendar:event | Calendar event created/updated | Google Calendar |
| issue:created | New issue opened | GitHub |
| payment:received | Payment successful | Stripe |
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
}
}Use middleware to intercept and transform events before they reach handlers:
// 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()
})Monitor the internal state of your assistant:
// 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`)
})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
}
}
})