Docs
Integrations - JavaScript SDK

Integrations - JavaScript SDK

Connect to external services with OAuth integrations

OAuth Integrations

Initiate OAuth Connection

import { LumnisClient } from 'lumnisai'
 
const client = new LumnisClient({ apiKey: process.env.LUMNISAI_API_KEY! })
 
// Initiate connection to GitHub
const result = await client.initiateConnection({
  userId: "user@example.com",
  appName: "GITHUB"
})
 
console.log(`Visit this URL to connect: ${result.redirectUrl}`)

Check Connection Status

// Get connection status
const status = await client.getConnectionStatus(
  "user@example.com",
  "GITHUB"
)
 
console.log(`Status: ${status.status}`)
console.log(`Connected at: ${status.connectedAt}`)
 
if (status.status === 'active') {
  console.log("Connection is active and ready to use")
}
else if (status.status === 'pending') {
  console.log("Waiting for user to complete OAuth flow")
}
else if (status.status === 'failed') {
  console.log(`Connection failed: ${status.errorMessage}`)
}

List User Connections

// Get all connections for a user
const connections = await client.listConnections("user@example.com")
 
console.log(`Total connections: ${connections.connections.length}`)
 
for (const conn of connections.connections) {
  console.log(`\n${conn.appName}`)
  console.log(`  Status: ${conn.status}`)
  console.log(`  Connected: ${conn.connectedAt}`)
}
 
// Filter by specific apps
const githubSlack = await client.listConnections(
  "user@example.com",
  { appFilter: "GITHUB,SLACK" }
)

Get Available Tools

// Get tools available based on user's connections
const tools = await client.getIntegrationTools("user@example.com", {
  appFilter: ["GITHUB", "SLACK"]
})
 
console.log(`Available tools: ${tools.toolCount}`)
 
for (const tool of tools.tools) {
  console.log(`\n${tool.name}`)
  console.log(`  Description: ${tool.description}`)
  console.log(`  App: ${tool.appName}`)
}

App Management

List Available Apps

// List enabled apps for tenant
const apps = await client.listApps({ includeAvailable: true })
 
console.log(`Enabled apps: ${apps.enabledApps.join(', ')}`)
console.log(`Total available: ${apps.totalAvailable}`)

Check if App is Enabled

// Check specific app
const result = await client.isAppEnabled("GITHUB")
 
if (result.enabled) {
  console.log("GitHub integration is enabled for this tenant")
}
else {
  console.log("GitHub integration is not enabled")
}

Enable/Disable Apps

// Enable an app for the tenant
await client.setAppEnabled("LINEAR", true)
console.log("Linear integration enabled")
 
// Disable an app
await client.setAppEnabled("LINEAR", false)
console.log("Linear integration disabled")

Complete Integration Workflow

import { LumnisClient } from 'lumnisai'
 
const client = new LumnisClient({ apiKey: process.env.LUMNISAI_API_KEY! })
const userEmail = "user@example.com"
 
// Step 1: Ensure user exists
try {
  await client.getUser(userEmail)
  console.log(`✅ User ${userEmail} exists`)
}
catch (error: any) {
  if (error.message.includes('not found')) {
    const newUser = await client.createUser({
      email: userEmail,
      firstName: "New",
      lastName: "User"
    })
    console.log(`✅ User created (ID: ${newUser.id})`)
  }
}
 
// Step 2: Enable apps for tenant
const appsToConnect = ["github", "gmail", "googledocs", "googlesheets"]
 
console.log('\nEnabling apps for tenant...')
for (const app of appsToConnect) {
  const appEnabled = await client.isAppEnabled(app)
  
  if (!appEnabled.enabled) {
    await client.setAppEnabled(app, true)
    console.log(`  ✓ Enabled ${app}`)
  }
  else {
    console.log(`  • ${app} already enabled`)
  }
}
 
// Step 3: Initiate connections for user
console.log(`\nInitiating connections for ${userEmail}...`)
for (const app of appsToConnect) {
  const status = await client.getConnectionStatus(userEmail, app)
  
  if (status.status !== 'active') {
    try {
      const connection = await client.initiateConnection({
        userId: userEmail,
        appName: app
      })
      
      if (connection.redirectUrl) {
        console.log(`  🔗 ${app}: ${connection.redirectUrl}`)
      }
    }
    catch (error: any) {
      console.log(`  ⚠️  ${app}: ${error.message}`)
    }
  }
  else {
    console.log(`  ✓ ${app} already connected`)
  }
}
 
// Step 4: Check final connection status
console.log('\nFinal connection status:')
const connections = await client.listConnections(userEmail)
 
for (const conn of connections.connections) {
  const statusIcon = conn.status === 'active' ? '✓' : '⨯'
  console.log(`  ${statusIcon} ${conn.appName}: ${conn.status}`)
}
 
console.log('\n✨ Integration setup complete!')

Using Integrations with AI Responses

With Connected Tools

import { LumnisClient, displayProgress, type AgentConfig } from 'lumnisai'
 
const client = new LumnisClient({ apiKey: process.env.LUMNISAI_API_KEY! })
const userEmail = "user@example.com"
 
// Ensure user has connected apps
const tools = await client.getIntegrationTools(userEmail)
console.log(`User has ${tools.toolCount} integration tools available`)
 
// Create AI response with access to integration tools
for await (const update of await client.invoke(
  `
  Search for recent pull requests in my GitHub repositories,
  then send a summary email via Gmail to team@example.com
  `,
  {
    stream: true,
    userId: userEmail,
    agentConfig: {
      coordinatorModelName: "openai:gpt-4.1",
      useCognitiveTools: true
    }
  }
)) {
  displayProgress(update)
  
  if (update.state === 'completed') {
    console.log(`\n${update.outputText}`)
  }
}

Real-World Example: Email and Calendar

import { LumnisClient, displayProgress } from 'lumnisai'
 
const client = new LumnisClient({ apiKey: process.env.LUMNISAI_API_KEY! })
const userEmail = "user@example.com"
 
// Ensure Gmail and Google Calendar are connected
const requiredApps = ["GMAIL", "GOOGLECALENDAR"]
 
for (const app of requiredApps) {
  const status = await client.getConnectionStatus(userEmail, app)
  if (status.status !== 'active') {
    console.log(`Please connect ${app}`)
    const result = await client.initiateConnection({
      userId: userEmail,
      appName: app
    })
    console.log(`Visit: ${result.redirectUrl}`)
  }
}
 
// Use in AI task
for await (const update of await client.invoke(
  `
  Check my calendar for meetings today, then send me an email
  summary of all scheduled meetings with their times and participants.
  Send to: ${userEmail}
  `,
  {
    stream: true,
    userId: userEmail
  }
)) {
  displayProgress(update)
  
  if (update.state === 'completed') {
    console.log(`\n${update.outputText}`)
  }
}

Best Practices

Check Connections Before Tasks

async function ensureConnections(
  client: LumnisClient,
  userId: string,
  requiredApps: string[]
): Promise<boolean> {
  const missing: string[] = []
  
  for (const app of requiredApps) {
    const status = await client.getConnectionStatus(userId, app)
    if (status.status !== 'active') {
      missing.push(app)
    }
  }
  
  if (missing.length > 0) {
    console.log(`Missing connections: ${missing.join(', ')}`)
    for (const app of missing) {
      const result = await client.initiateConnection({
        userId,
        appName: app
      })
      console.log(`Connect ${app}: ${result.redirectUrl}`)
    }
    return false
  }
  
  return true
}
 
// Usage
const client = new LumnisClient({ apiKey: process.env.LUMNISAI_API_KEY! })
 
if (await ensureConnections(client, "user@example.com", ["GITHUB", "SLACK"])) {
  // Proceed with task
  const response = await client.invoke(
    "Create a GitHub issue and notify team on Slack",
    { userId: "user@example.com" }
  )
}

Handle Connection Errors

import { LumnisClient, LumnisAPIError } from 'lumnisai'
 
const client = new LumnisClient({ apiKey: process.env.LUMNISAI_API_KEY! })
 
try {
  const status = await client.getConnectionStatus(
    "user@example.com",
    "GITHUB"
  )
  
  if (status.status === 'failed') {
    console.log(`Connection failed: ${status.errorMessage}`)
    // Re-initiate connection
    const result = await client.initiateConnection({
      userId: "user@example.com",
      appName: "GITHUB"
    })
    console.log(`Please reconnect: ${result.redirectUrl}`)
  }
}
catch (error) {
  if (error instanceof LumnisAPIError) {
    console.error(`API error: ${error.message}`)
  }
}

Refresh Stale Connections

async function checkConnectionFreshness(
  client: LumnisClient,
  userId: string,
  appName: string,
  maxAgeDays: number = 30
): Promise<boolean> {
  const status = await client.getConnectionStatus(userId, appName)
  
  if (status.status !== 'active') {
    return false
  }
  
  if (status.connectedAt) {
    const connectedDate = new Date(status.connectedAt)
    const age = Date.now() - connectedDate.getTime()
    const ageDays = age / (1000 * 60 * 60 * 24)
    
    if (ageDays > maxAgeDays) {
      console.log(`${appName} connection is ${Math.floor(ageDays)} days old`)
      return false
    }
  }
  
  return true
}
 
// Usage
if (!await checkConnectionFreshness(client, "user@example.com", "GITHUB", 30)) {
  // Reconnect
  const result = await client.initiateConnection({
    userId: "user@example.com",
    appName: "GITHUB"
  })
  console.log(`Please reconnect: ${result.redirectUrl}`)
}