LogoRobo.js

Recipes

Common patterns for reports, automation, monitoring, and multi-guild setups.

Practical examples for common use cases beyond basic sync operations.

Generate a monthly report

Use date range helpers to build activity reports:

import { getCardsFromLastMonth, getProvider, isProviderReady } from '@robojs/roadmap'

export default async function monthlyReport(interaction) {
  if (!isProviderReady()) {
    return 'Provider not configured.'
  }

  const provider = getProvider()
  const cards = await getCardsFromLastMonth(provider)

  const created = cards.filter(c => c.column === 'Backlog')
  const completed = cards.filter(c => c.column === 'Done')
  const inProgress = cards.filter(c => c.column === 'In Progress')

  return [
    `**Monthly Report**`,
    `Cards updated: ${cards.length}`,
    `New: ${created.length} | Active: ${inProgress.length} | Completed: ${completed.length}`
  ].join('\n')
}
import { getCardsFromLastMonth, getProvider, isProviderReady } from '@robojs/roadmap'

export default async function monthlyReport(interaction) {
  if (!isProviderReady()) {
    return 'Provider not configured.'
  }

  const provider = getProvider()
  const cards = await getCardsFromLastMonth(provider)

  const created = cards.filter(c => c.column === 'Backlog')
  const completed = cards.filter(c => c.column === 'Done')
  const inProgress = cards.filter(c => c.column === 'In Progress')

  return [
    `**Monthly Report**`,
    `Cards updated: ${cards.length}`,
    `New: ${created.length} | Active: ${inProgress.length} | Completed: ${completed.length}`
  ].join('\n')
}

Trigger sync from a webhook

Use the REST API to trigger syncs from CI/CD pipelines or external services:

# Trigger sync after a Jira webhook fires
curl -X POST http://localhost:3000/api/roadmap/sync/YOUR_GUILD_ID

Or trigger from a custom event handler:

import { syncRoadmap, getProvider } from '@robojs/roadmap'

export default async function onWebhook(guild) {
  const provider = getProvider()
  if (!provider) return

  const result = await syncRoadmap({ guild, provider })
  console.log(`Synced ${result.stats.total} cards`)
}
import { syncRoadmap, getProvider } from '@robojs/roadmap'

export default async function onWebhook(guild) {
  const provider = getProvider()
  if (!provider) return

  const result = await syncRoadmap({ guild, provider })
  console.log(`Synced ${result.stats.total} cards`)
}

Monitor provider health

Build a health check dashboard using the REST API:

# Check provider status
curl http://localhost:3000/api/roadmap/provider/status

# Get last sync time
curl http://localhost:3000/api/roadmap/sync/YOUR_GUILD_ID/status

Track activity over time

Use date range helpers for trend analysis:

import { getCardsFromLastDays, getProvider } from '@robojs/roadmap'

async function weeklyTrend() {
  const provider = getProvider()

  const thisWeek = await getCardsFromLastDays(provider, 7)
  const lastWeek = await getCardsFromLastDays(provider, 14)

  // Compare activity between periods
  const delta = thisWeek.length - lastWeek.length
  return `This week: ${thisWeek.length} cards (${delta >= 0 ? '+' : ''}${delta} vs last week)`
}
import { getCardsFromLastDays, getProvider } from '@robojs/roadmap'

async function weeklyTrend() {
  const provider = getProvider()

  const thisWeek = await getCardsFromLastDays(provider, 7)
  const lastWeek = await getCardsFromLastDays(provider, 14)

  // Compare activity between periods
  const delta = thisWeek.length - lastWeek.length
  return `This week: ${thisWeek.length} cards (${delta >= 0 ? '+' : ''}${delta} vs last week)`
}

Sync a single card

Sync one card after creation or update without running a full sync:

import { syncSingleCard, getProvider } from '@robojs/roadmap'

const provider = getProvider()
const card = await provider.getCard('PROJ-123')

if (card) {
  const result = await syncSingleCard(card, guild, provider)
  if (result) {
    console.log(`Thread: ${result.threadUrl}`)
  }
}
import { syncSingleCard, getProvider } from '@robojs/roadmap'

const provider = getProvider()
const card = await provider.getCard('PROJ-123')

if (card) {
  const result = await syncSingleCard(card, guild, provider)
  if (result) {
    console.log(`Thread: ${result.threadUrl}`)
  }
}

Cancelable sync with progress

Run a sync with progress tracking and cancellation support:

import { syncRoadmap, SyncCanceledError, getProvider } from '@robojs/roadmap'

const controller = new AbortController()
const provider = getProvider()

try {
  const result = await syncRoadmap({
    guild,
    provider,
    signal: controller.signal,
    onProgress: (update) => {
      console.log(`[${update.currentIndex + 1}/${update.totalCards}] ${update.currentCard.title}`)
      if (update.stats.errors > 5) {
        controller.abort()  // Cancel if too many errors
      }
    }
  })
  console.log('Sync complete:', result.stats)
} catch (error) {
  if (error instanceof SyncCanceledError) {
    console.log('Sync canceled')
  }
}
import { syncRoadmap, SyncCanceledError, getProvider } from '@robojs/roadmap'

const controller = new AbortController()
const provider = getProvider()

try {
  const result = await syncRoadmap({
    guild,
    provider,
    signal: controller.signal,
    onProgress: (update) => {
      console.log(`[${update.currentIndex + 1}/${update.totalCards}] ${update.currentCard.title}`)
      if (update.stats.errors > 5) {
        controller.abort()  // Cancel if too many errors
      }
    }
  })
  console.log('Sync complete:', result.stats)
} catch (error) {
  if (error instanceof SyncCanceledError) {
    console.log('Sync canceled')
  }
}

Multi-guild management

Each guild has independent settings. Manage multiple guilds programmatically:

import { getSettings, updateSettings } from '@robojs/roadmap'

const guildIds = ['guild-1', 'guild-2', 'guild-3']

for (const guildId of guildIds) {
  const settings = getSettings(guildId)
  console.log(`${guildId}: last sync ${new Date(settings.lastSyncTimestamp ?? 0)}`)

  // Apply consistent settings across guilds
  updateSettings(guildId, {
    threadTitleTemplate: '[{id}] {title}',
    isPublic: true
  })
}
import { getSettings, updateSettings } from '@robojs/roadmap'

const guildIds = ['guild-1', 'guild-2', 'guild-3']

for (const guildId of guildIds) {
  const settings = getSettings(guildId)
  console.log(`${guildId}: last sync ${new Date(settings.lastSyncTimestamp ?? 0)}`)

  // Apply consistent settings across guilds
  updateSettings(guildId, {
    threadTitleTemplate: '[{id}] {title}',
    isPublic: true
  })
}

Next steps

On this page