← Back to Projects
DevOps & Tooling

OpenProject ↔ Slack Bridge

Ticket changes into threaded Slack notifications, with a GitOps config dashboard

Rewrote and owned it end to end (AI-assisted) · Jun 2025 — Jan 2026
Go Gin Next.js TypeScript MySQL Slack API GitLab CI Docker

Overview

An internal tool that turns OpenProject ticket changes into threaded Slack notifications and personal DMs. I rewrote a Python prototype into a Go engine plus a Next.js dashboard, made it multi-tenant, and built its deployment. Delivered with Claude Code, Codex and Cursor.

Architecture

OpenProject webhooks → Go engine (snapshot diff → Slack Block Kit messages, threads and DMs; S3 for media; cron jobs per instance). Admin service (Go) ↔ GitLab API for versioned YAML config; push webhook → per-service rebuild or restart over SSH. Next.js dashboard with dropdowns filled from live OpenProject and Slack data. The engine ships as a scratch-based image built by GitLab CI.

Key Highlights

01

Field-level change detection against stored snapshots; threaded channel messages and role-based DMs

02

Private attachments re-hosted on S3 so they render in Slack; thread links written back to the ticket

03

One deployment serves 3 OpenProject instances (separate teams), with per-instance config and data isolation

04

Scheduled bug-statistics, ticket-health and daily-report jobs with batched messages

05

GitOps config dashboard: every edit is a Git commit through the GitLab API (~340 changes); a push webhook rebuilds or restarts only the affected service

Technical Decisions

Technical Decisions Chosen Alternative Reason
Config store YAML in Git, edited through a dashboard that commits via the GitLab API A database table Every change gets history, review and revert for free, and config-only edits can restart services without rebuilding images.