Bi-Directional Slack Integration
Outbound alerts were straightforward. Inbound was harder than I expected.
The problem: the bot receives its own messages. Send a message, the bot reads it, processes it, sends another message, reads that one too. Without filtering, it loops. That's not a theoretical edge case — it's the first thing that happens when you enable bidirectional messaging.
Slack Outbound (UzF8PFUZnw3548lT — 7 nodes) is the shared send service. Every other workflow that needs to alert calls this one:
Webhook (called by other workflows)
└─ Format Message
└─ Post to Slack
└─ Build Response
└─ Success: Log
Error Trigger → Error: Log
Slack Inbound (aRpUo1mf0RcV0fOI — 23 nodes) is the control plane. Dual triggers — Slack event subscription and Chat — both feed the same pipeline:
Slack Trigger ─┐
├─ Filter Bot Messages
Chat Trigger ─┘ ├─ [bot] → Bot Message (Ignore) ← loop prevention
└─ [human] → Parse Command
└─ Log to Database ──[error]─→ Handle DB Error
└─ Merge Parsed Data
└─ Route by Action
└─ Switch
├─ kill → Execute Kill → Kill Confirm
├─ resume → Execute Resume → Resume Confirm
├─ status → Query Status → Format Status → Status Response
├─ help → Help Response
└─ other → General Ack
Error Trigger → Error: Log
Every command branch has its own DB error path back to a shared error handler — so a failed status query doesn't silently disappear, it logs and responds. The Filter Bot Messages node is what prevents the loop: if the sender is the bot itself, it exits immediately via NoOp.
The practical result: I can give the AI instructions without opening Claude. Pause all operations, resume, check status — from Slack, mid-day, without switching context into a full session.
Why it matters: Human-AI coordination through asynchronous messaging channels. Message classification, loop detection, and command parsing are the same problems you solve building any multi-system communication layer. The difference here is one of the participants forgets everything overnight.