kpi-bot
Build a daily KPI bot that sends a formatted Slack message with data from Databricks. The user will describe what data they want — your job is to write the SQL, format it for Slack, create or update an n8n workflow, and send a test message.
Step 1: Understand the Request
Ask the user (if not already clear from $ARGUMENTS):
- What data do you want? (e.g., "daily bookings by category", "live coach count", "weekly signups")
- Which Slack channel? (get the channel ID — they can find it by right-clicking the channel → View channel details → copy the ID at the bottom)
- What time should it send? (default: 8pm MT)
Remind them: the bot must be invited to the channel first — /invite @LeLoop in the target channel.
Step 2: Write the SQL
Query leland_analytics.ai tables by default. Key tables and columns:
bookings (approved orders only):
approved_at_pt(timestamp) — use for date filteringamount_booked(USD) — cash revenue (use this, NOTgeneral_manager_bookings, to match team dashboards)category_slug(text) — coaching category (mba, medical, law, etc.). Already a column — no join neededorder_type(text) — hourlyOrder, packageOrder, classOrder, bootcampOrder, subscriptionOrder, contentOrderorder_status— filter:IN ('APPROVED_BY_COACH', 'COACHING_COMPLETED')- Credit columns:
credit_bootcamp_used,credit_gift_card_used,credit_marketing_giveaway_used,credit_partnership_used,credit_referral_used,credit_refund_used,credit_trial_used,credit_unknown_used - GMV =
amount_booked+ all credit columns
coachmetricsviews: Coach performance. coach_status = 'LIVE' for live coaches.
weekly_active_users / monthly_active_users: WAU/MAU metrics. Columns: week_start/month_start, wau/mau.
events: Leland events with RSVP/attendee counts.
CRITICAL SQL RULES:
- Use
category_slug, nevercategory - Use
amount_booked, neverrevenue - Use
approved_at_ptfor dates - The bookings table already filters to approved orders — no need for
order_statusfilter unless you want COACHING_COMPLETED too - Only use tables/columns listed above or in
leland_analytics.ai
Test the SQL via Databricks before proceeding:
# Use the Databricks connection pattern from CLAUDE.md
result = run_sql(your_sql)
Step 3: Format for Slack
Write JavaScript that formats query results into a readable Slack message using mrkdwn. Patterns that work well:
- Header:
:chart_with_upwards_trend: *Bot Name*with emoji - Summary stats:
*Total:* 1,234on separate lines - Tables: Use code blocks with aligned columns:
```Category | Booked | Target | Pace
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
MBA | $45.2K | $60.0K | 112%```
- Pacing %: Normalize for day of month:
pacingPct = (rawPct / expectedPct) * 100whereexpectedPct = (dayOfMonth / daysInMonth) * 100 - Slack gotcha: The header text MUST be on the same line as the opening triple-backtick, or Slack swallows it
Step 4: Create/Update n8n Workflow
Use the n8n API to create a workflow with these nodes:
- Schedule Trigger — cron at the requested time, timezone
America/Denver - Execute Workflow — calls Databricks sub-workflow
v8CeBNa4Bp90sbXw1YVx0with{ "query": "YOUR SQL" } - Code node — JavaScript formatter from Step 3
- HTTP Request — POST to
https://slack.com/api/chat.postMessagewith LeLoop bot token
n8n API details:
- Host:
https://lelandteam.app.n8n.cloud - API key: check memory file
email-pipeline.mdfor current key - LeLoop bot token: check memory file
email-pipeline.md - Create:
POST /api/v1/workflowswith{ name, nodes, connections, settings } - Activate:
POST /api/v1/workflows/{id}/activate(separate call —activeis read-only on PUT) settings: { executionOrder: "v1" }
n8n API gotchas:
- Cannot assign credentials via API — Execute Workflow and HTTP Request nodes don't need credentials
- The Databricks sub-workflow handles all auth internally
- Always use
POST /activateendpoint, never setactive: truein PUT body
Step 5: Send Test Message
Run the SQL query via Databricks, format it with the JS logic (replicated in Python), and post directly to the Slack channel to verify everything looks right. Use the LeLoop bot token from memory.
Self-Serve Alternative
There's also a KPI Bot Factory form (n8n workflow bkYcMw31Hhrqfve2) that lets anyone fill out a form to create a bot without Claude Code. But it requires the Anthropic credential to be assigned in the n8n UI. For Claude Code users, this skill is the more reliable path.
The request:
$ARGUMENTS
More from kristenschumann/claude-skills
learn
Post-session retrospective: audits efficiency, proposes skill/memory/CLAUDE.md updates, and generates coaching feedback
54time-audit
Weekly personal time audit using macOS Screen Time and Chrome history, outputs an HTML visualization
2executive-critique
Executive critique with two modes: operational (Nick's lens — execution, timelines, dependencies) and strategic (John's lens — ROI, ambition, customer psychology)
2scope
Declares EXPAND/HOLD/REDUCE mode before planning sessions, monitors for scope drift, and maintains a parked ideas list
1