Project detail · technical deep-dive
A Node.js microservice for automated Slack reporting with BigQuery, job queues, and HTML-table-to-PNG rendering—templates in Supabase, scheduled delivery, and Block Kit payloads with embedded visualizations.
Role
Backend & automation
Timeline
2024
Tech
Fastify, BullMQ, Puppeteer, BigQuery, Slack API, GCS
9 page views
Product showcase

Slack delivery: rendered tables posted as images—heatmaps and KPI columns match the viz config (alignment, currency, percent, conditional colors).
Production patterns
Status
Reporting & queues
Focus
Cloud Run + Puppeteer
Deploy
HTML → image pipeline
BigQuery results become styled HTML tables; Puppeteer renders PNGs, uploads to GCS, and Block Kit messages swap in visualization URLs.
Scheduling & workers
Cron + timezone aware jobs via BullMQ and Redis, with separate workers for general tasks and Slack execution—including recovery on startup.
Templates & safety
Supabase-backed templates and credentials; Zod-validated Fastify routes, Bearer auth, and Prometheus metrics for operability.
Live product, repository, or both—pick what matters for this case.
This project is a TypeScript microservice that automates Slack delivery from templates stored in Supabase. The typical flow: load templates and credentials, run BigQuery SQL (scoped by company), build HTML tables with conditional formatting, render PNGs with Puppeteer, upload images to Google Cloud Storage, and replace placeholders (such as {{visualization_url}}) in Slack Block Kit payloads before posting. Scheduling uses cron + timezone, asynchronous processing with BullMQ and Redis, a Fastify API with Zod validation, and observability via Prometheus (/metrics) and health checks.
cd slack-bot-microservice
npm install
cp .env.example .env
# Fill in Redis, Supabase, GCP, GCS, Slack tokens, etc.
npm run devMain routes (most require Bearer authentication):
GET /health — service statusGET /metrics — Prometheus metricsPOST /jobs — create, update, or disable a scheduled job (cron + timezone)POST /execute-slack-message — enqueue an immediate run (full pipeline)POST /send-message-simple — send a message by messageId (handy for testing)POST /test-sql — run BigQuery SQL without posting to SlackGET /debug-template/:messageId — inspect a template for debuggingcurl -X POST "http://localhost:8080/jobs" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <SUPABASE_SERVICE_ROLE_KEY>" \
-d '{
"scheduleId": "YOUR-SCHEDULE-UUID",
"cron": "0 9 * * 1-5",
"timezone": "America/New_York",
"status": "enabled",
"payload": {}
}'position.viz_config_json controls alignment, number/currency/percent formats, and conditional color scales on cells.Dockerfile.puppeteer); min-instances so workers are not scaled to zero.