SRS: UC_9.16 — Flow 38: Support Interception & Freshdesk Ticket Creation
| Field | Value |
|---|---|
| UC_ID | UC_9.16 |
| Version | v1.1 |
| Last Updated | 2026-11-05 |
| BA PiC | linh.nguyen34 |
| Category | BACKGROUND MECHANISMS & CRON JOBS |
| Module | Flow 38 |
| Function | Support Interception |
| Document References | Zapier Integration V7.pdf (§Flow 38 Support Interception & Zendesk Creation) · RFQ_ Stack Trading Prop Tech V7.pdf (§2.3 Automated Support Interception & Routing) · CR-20260720-004 (Freshdesk replaces Zendesk) · CR-20260818-002 (monitor #live-broadcast-chat) · QnA_STAGE2_COMMUNITY_LIVE_BROADCAST.md (DCS-BIZ-21, PIT-BIZ-03) · list_email.md (FD-01) |
1. UC Index
| UC_ID | Function | Description |
|---|---|---|
| UC_9.16 | Flow 38 — Support Interception | Node.js Discord Bot monitors #the-pit, #verify and #live-broadcast-chat. Messages containing operational trigger words go through a Gemini (light) sentiment gate. If Complaint: bot deletes the message, posts a public placeholder tagging the user, and fires a webhook to Zapier; Zapier looks up the user's registered email by discord_id and creates a High-priority Freshdesk ticket; Freshdesk sends the confirmation email. |
UC_9.16 — Flow 38: Support Interception & Freshdesk Ticket Creation
| Field | Value |
|---|---|
| Use Case | Support Interception |
| Description | Moves operational complaints (slippage, lag, frozen platform, …) out of public Discord channels into a private Freshdesk ticket, preventing public sentiment contagion while still serving the trader. |
| Actor | Trader (Discord member) · System (Discord Bot, Gemini, Middleware Hub, Zapier, Freshdesk) |
| Zapier Flow | Flow 38 |
| Trigger Source | Webhook from Middleware Hub / Discord Bot — "Negative Operational Sentiment Detected" |
| 3rd Party | Discord · Google Gemini (light model — same as "The Desk Manager") · Freshdesk |
| Related UCs | UC_4.5.2 The Pit · UC_4.9.1 / UC_4.14.1 Discord Chat Stream (#live-broadcast-chat) |
2. Trigger
- Bot listener: any new message in a monitored channel containing a trigger word.
- Zapier trigger: webhook from Middleware Hub (Discord Bot) after the sentiment gate returns
Complaint. Payload:discord_id,message_text,timestamp.
(Source: RFQ_ Stack Trading Prop Tech V7.pdf §2.3; Zapier Integration V7.pdf §Flow 38)
Monitored channels
| Channel | Source |
|---|---|
#the-pit | RFQ V7 §2.3 |
#verify | RFQ V7 §2.3 |
#live-broadcast-chat | CR-20260818-002 (CR wins over V7) |
3. Pre-conditions
| ID | Pre-condition |
|---|---|
| P1 | Bot has Read Message History and Manage Messages in all monitored channels. |
| P2 | Trigger-word list configured (see BR_9.16.2). |
| P3 | Zapier Flow 38 webhook URL configured in the bot / Middleware. |
| P4 | Freshdesk API credentials configured in Zapier. |
4. Post-conditions (Complaint path)
| # | Post-condition |
|---|---|
| 1 | Original message deleted from the public channel. |
| 2 | Public placeholder reply posted tagging the user (see Q1 for #live-broadcast-chat). |
| 3 | Freshdesk ticket created: Requester = registered email, Description = message_text, Priority = High. |
| 4 | Confirmation email sent by Freshdesk to the trader. |
| 5 | Execution logged to BPS_Audit_Log. |
5. Basic Flow
Step 1 — Keyword pre-filter (Bot)
Bot scans each new message in monitored channels. No trigger word → ignore (Alt-1).
Step 2 — LLM sentiment gate (Bot → Gemini light model)
Message is sent to Gemini to classify intent as Complaint or Positive/Neutral (prevents false positives such as "Stack Trading has no slippage!"). Not Complaint → ignore (Alt-2).
(Source: RFQ_ Stack Trading Prop Tech V7.pdf §2.3 — LLM Sentiment Gate)
Reference prompt (BA draft — not client-supplied):
You are an operations sentiment classifier for Stack Trading. Classify the user's intent:
1. "Complaint": reports an actual operational issue, technical glitch, execution failure, or frustration with system performance.
2. "Positive/Neutral": compliments the system, discusses normal market conditions, or uses the keyword in a non-complaint context.
Output ONLY JSON: {"intent": "Complaint" | "Positive/Neutral", "confidence_score": float}Step 3 — Delete message (Bot) — instantly.
Step 4 — Public placeholder (Bot)
"@[User], to protect your account details and resolve this immediately, we have opened a secure Freshdesk support ticket for you. Please check your registered email."
(Source: RFQ_ Stack Trading Prop Tech V7.pdf §2.3 — "Zendesk" replaced by "Freshdesk" per CR-20260720-004)
Step 5 — Webhook to Zapier
{ "discord_id": "123456789012345678", "discord_username": "trader_jane", "channel_name": "the-pit", "message_text": "MT5 frozen again, lost my entry", "timestamp": "2026-10-27T09:15:00Z" }Step 6 — Lookup (Zapier)
Query PostgreSQL Users by discord_id → registered email. Not found → Exc-1.
Step 6.5 — One ticket per UTC day (Zapier / Middleware)
Check the last Freshdesk ticket creation date (UTC) for this discord_id. If a ticket was already created today (before 00:00 UTC), do not create a second ticket — either append the message as a note to that day's ticket, or skip (Dev picks the simpler option). The Discord message is still deleted (Step 3). See BR_9.16.7.
Step 7 — Create Freshdesk ticket (Zapier → Freshdesk POST /api/v2/tickets)
| Freshdesk field | Value | Source |
|---|---|---|
email (Requester) | Registered email | V7 Flow 38 |
subject | Stack Trading Support Ticket Created - Discord Escalation | V7 Flow 38 (email subject) — see Q3 |
description | message_text + channel_name, discord_username, discord_id, message timestamp | V7 Flow 38; [BG-019] |
priority | 3 (High) | V7 Flow 38 |
status | 2 (Open) | BA assumption |
tags | ["discord-escalation", channel_name] | [BG-019] — client sheet 2026-11-04 |
custom_fields.cf_discord_user_id | discord_id | BA assumption |
Step 8 — Confirmation email (Freshdesk)
Subject: Stack Trading Support Ticket Created - Discord Escalation
Hello,
We intercepted your recent message in the Stack Trading Discord regarding an operational issue. To protect your privacy and ensure our team can assist you securely, we have converted your message into a high-priority support ticket. Your original message: "[Insert message_text payload]"
Our team is reviewing this now and will reply to this email directly. Please reply to this email with any additional context or screenshots.
Regards,
(Source: Zapier Integration V7.pdf §Flow 38 — Notify; sent via Freshdesk per CR-20260720-004)
6. Alternative Flows
Alt-1 — No trigger word: no action.
Alt-2 — Gemini returns Positive/Neutral: message stays; no ticket.
Alt-3 — Message in #live-broadcast-chat: same pipeline. Release 1/2: deleting the message in Discord is sufficient. Removing it from the dashboard Live Chat Feed (DISCORD_CHAT_STREAM) is a Day 2 item, via either (1) pre-filter — hold a trigger-word message for the Gemini check before pushing it to DISCORD_CHAT_STREAM, and never push it if flagged; or (2) delete event — include message_id in the stream payload and emit a delete event when the bot deletes the message. Placeholder behaviour pending Q1.
(Source: CR-20260818-002; QnA_BACKGROUND_MECHANISMS_CRON.md [BG-020] — client sheet 2026-11-04)
7. Exceptional Flows
Exc-1 — discord_id not linked to any user
- Do not create a Freshdesk ticket (a placeholder email would bounce and Ops could not reply).
- The bot still deletes the message and replies publicly, instructing the user to link their account or email
support@stacktrading.com(copy not yet provided). - Post to Slack
#ops-generalwithdiscord_username,channel_name,message_text.
(Source: QnA_BACKGROUND_MECHANISMS_CRON.md [BG-021] — client sheet 2026-11-04)
Exc-2 — Gemini unavailable / timeout
- Retry the Gemini call once. Still unavailable / timeout → fail-open: leave the message as-is, no ticket, log a warning. Never fail-closed (an outage would mass-delete normal chat and flood Freshdesk).
(Source: QnA_BACKGROUND_MECHANISMS_CRON.md [BG-022] — client sheet 2026-11-04)
Exc-3 — Bot cannot delete (missing permission / message already deleted): continue Steps 5–8 (ticket still created); log warning.
Exc-4 — Freshdesk API failure: Zapier retry; on final failure alert Ops (#ops-general). The public placeholder is already posted — ticket must be created manually.
8. Business Rules
BR_9.16.1: Monitored Channels
#the-pit, #verify, #live-broadcast-chat.
(Source: RFQ_ Stack Trading Prop Tech V7.pdf §2.3 · CR-20260818-002)
BR_9.16.2: Trigger Words
V7 examples: slippage, lag, frozen. Full list is not confirmed (PIT-BIZ-03 open). Proposed config (BA draft): ["slippage", "lag", "frozen", "scam", "missing payout", "Rithmic down", "MT5 down", "TradingView down", "connection dropped"]. Must be config-driven (Ops-editable), case-insensitive.
(Source: RFQ_ Stack Trading Prop Tech V7.pdf §2.3 · QnA PIT-BIZ-03 — open)
BR_9.16.3: LLM Gate Is Mandatory
Keyword match alone never deletes a message; only intent = "Complaint" triggers interception. Uses the same light Gemini model as "The Desk Manager".
(Source: RFQ_ Stack Trading Prop Tech V7.pdf §2.3)
BR_9.16.4: Ticketing Platform Is Freshdesk
All references to Zendesk in V7 Flow 38 are replaced by Freshdesk.
(Source: CR-20260720-004)
BR_9.16.5: Ticket Mapping
Requester = registered email (lookup by discord_id); Description = original message_text; Priority = High.
(Source: Zapier Integration V7.pdf §Flow 38)
BR_9.16.6: Order of Actions
Delete → placeholder → webhook. Deletion must be immediate ("instantly") and not wait for the ticket.
(Source: RFQ_ Stack Trading Prop Tech V7.pdf §2.3 — Execution)
BR_9.16.7: One Ticket per discord_id per UTC Day
Repeated complaints from the same discord_id within one UTC calendar day produce at most one Freshdesk ticket (extra messages appended as notes or skipped). A complaint after 00:00 UTC creates a new ticket. Every complaint message is still deleted in Discord.
(Source: QnA_BACKGROUND_MECHANISMS_CRON.md [BG-023] — client sheet 2026-11-04)
9. Acceptance Criteria
| AC_ID | Flow | Given | Then | Type |
|---|---|---|---|---|
| AC-9.16-01 | Happy path | Linked user posts "MT5 frozen again" in #the-pit; Gemini → Complaint | Message deleted; placeholder tags user; Freshdesk ticket (Requester = registered email, Priority High, description = original text); confirmation email received | E2E |
| AC-9.16-02 | False positive | "Stack Trading has no slippage!" | Gemini → Positive/Neutral; message stays; no ticket | Integration |
| AC-9.16-03 | No keyword | "Good morning traders" | Not sent to Gemini | Integration |
| AC-9.16-04 | #verify | Complaint in #verify | Same as AC-9.16-01 | Integration |
| AC-9.16-05 | #live-broadcast-chat | Complaint during live broadcast | Message deleted in Discord; ticket created. Removal from dashboard Live Chat Feed = Day 2 (not tested in Release 1/2) | E2E |
| AC-9.16-06 | Unmonitored channel | Complaint in #general | No action | Integration |
| AC-9.16-07 | Unlinked user | discord_id not in Users | Message deleted; no Freshdesk ticket; public reply (link account / email support@stacktrading.com); Slack #ops-general alert | Integration |
| AC-9.16-08 | Freshdesk branding | AC-9.16-01 | Placeholder and email say "Freshdesk", never "Zendesk" | Content |
| AC-9.16-09 | Same-day repeat | Linked user posts a second complaint the same UTC day | Message deleted; no second ticket (note appended or skipped) | Integration |
| AC-9.16-10 | Next UTC day | Same user complains again after 00:00 UTC | New ticket created | Integration |
| AC-9.16-11 | Gemini outage | Gemini call fails, retry fails | Message stays; no ticket; warning logged | Integration |
10. Open Questions
| ID | Priority | Question | Assumption |
|---|---|---|---|
| Q1 | H | In #live-broadcast-chat, should the bot still post the public placeholder during a live stream? (DCS-BIZ-21a — open) | Yes, same as other channels. |
| Q2 | M | Should the ticket be tagged with the source channel (e.g. live-broadcast) for priority during live hours? (DCS-BIZ-21c) | ✅ Answered 2026-11-04 — tags ["discord-escalation", channel_name] + context in description ([BG-019]). |
| Q3 | M | V7 Flow 38 defines a custom confirmation email; list_email.md FD-01 is Freshdesk's generic "New Ticket Created" auto-reply. Which one is sent (or both)? | Flow 38 custom template replaces FD-01 for tag discord-escalation ([BG-019]). |
| Q4 | H | Unlinked discord_id handling (placeholder email + Ops alert) — confirm or drop ticket? | ✅ Answered 2026-11-04 — no ticket; public reply + Slack #ops-general ([BG-021]). |
| Q5 | M | Race: message reaches the dashboard via WebSocket before bot deletes it — need a retract event? (CR-20260818-002 Q4) | ✅ Answered 2026-11-04 — Release 1/2: Discord delete only; dashboard removal = Day 2 ([BG-020]). |
| Q6 | M | Gemini unavailable: fail-open or fail-closed? | ✅ Answered 2026-11-04 — retry once, then fail-open; never fail-closed ([BG-022]). |
| Q7 | L | Final trigger-word list per channel (PIT-BIZ-03, DCS-BIZ-21b). | BR_9.16.2 draft list, same for all channels. |
| Q8 | L | Should the same user's repeated complaints within a short window create one ticket or many? | ✅ Answered 2026-11-04 — one ticket per discord_id per UTC day (BR_9.16.7, [BG-023]). |
11. Changelog
| Date | Version | Change | Previous | After | Source |
|---|---|---|---|---|---|
| 2026-11-05 | v1.1 | Header; §5 Step 5 payload, Step 6.5 (new), Step 7 description/tags; §6 Alt-3; §7 Exc-1, Exc-2; §8 BR_9.16.7 (new); §9 AC-9.16-05/07, AC-9.16-09–11 (new); §10 Q2, Q4, Q5, Q6, Q8 | Tags Discord_Escalation (BA assumption); unlinked → placeholder ticket; one ticket per message; dashboard removal required; Gemini fail-open assumed | Tags discord-escalation + channel; description with channel/username/id/timestamp; unlinked → no ticket, public reply + Slack; 1 ticket / discord_id / UTC day; dashboard removal = Day 2; Gemini retry once then fail-open | Client sheet 2026-11-04 [BG-019]–[BG-023] |
| 2026-10-27 | v1.0 | Initial document creation | — | Full spec: 3 monitored channels, keyword + Gemini gate, delete/placeholder/webhook, Freshdesk ticket + email, BR_9.16.1–6, AC-9.16-01–08 | RFQ V7 §2.3; Zapier V7 §Flow 38; CR-20260720-004; CR-20260818-002 |