Files
broccolini-bot/docs/MONGODB_ZAMMAD_LINK.md
root 519788c633 Initial commit
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 08:22:19 -06:00

7.1 KiB
Raw Blame History

MongoDB Bridge ↔ Zammad Schema Mapping

Reference for linking the gmail-bridge (MongoDB) with Zammad's PostgreSQL schema. Source: schema zammad.txt.

MongoDB (Ticket) Zammad (tickets) Notes
zammadTicketId id (serial) Primary link; set when we create a Zammad ticket via API.
gmailThreadId Bridge-only; Gmail thread ID.
discordThreadId Bridge-only; Discord channel ID.
senderEmail customer_id → users.email Zammad creates/finds user by email when we POST ticket.
subject title Ticket title.
status (open/closed) state_id → ticket_states We PATCH state to closed on force-close.

Zammad tables we touch via API

  • tickets Create (POST), update state (PATCH). Key columns: id, group_id, priority_id, state_id, title, customer_id, owner_id, number, discordusername, gameid.
  • ticket_articles Create (POST) when staff reply in Discord. Key columns: ticket_id, type_id (e.g. note), sender_id, body, content_type, internal, subject, from.
  • users Zammad creates/finds customer by email on ticket create. If the sender email matches a MongoDB User (website user) with discordID, the bridge PATCHes the Zammad user with discord_id so the customer in Zammad has the Discord ID. Requires adding a custom attribute discord_id on the User object in Zammad (Admin → Object Manager → User).

Zammad custom fields on tickets (from schema)

  • discordusername (limit 120) Can store Discord display name for the ticket.
  • gameid (limit 255) We already send this when creating a ticket (game key from bridge).

Important MongoDB fields → Zammad custom attributes

These MongoDB Ticket fields matter for Zammad; the schema only has two custom columns on tickets, so we map into those or would need new attributes in Zammad.

MongoDB (Ticket) Zammad today Action
gameKey (from email/game) gameid Already sent on ticket create.
claimedBy (Discord display name) discordusername Not set today. Should PATCH ticket when someone claims (e.g. set discordusername to claimedBy on claim, clear on unclaim).
priority (low/normal/medium/high) priority_id (core) Not synced. We could PATCH ticket when /priority is used so Zammad shows same priority.
gmailThreadId No column in Zammad. If you add a custom attribute (e.g. gmail_thread_id) in Zammad, we can send it on create/update.
discordThreadId No column in Zammad. Same: add e.g. discord_channel_id in Zammad if you want it there.
escalated No column in Zammad. Add a custom attribute (e.g. escalated boolean) in Zammad if you want it visible in Zammad.

Recommended now (no Zammad schema change):

  1. Set discordusername on claim When a staff member claims the ticket in Discord, PATCH the Zammad ticket with discordusername: claimedBy so Zammad shows who is handling it on Discord. Clear it on unclaim.
  2. Sync priority to Zammad When priority changes in Discord via /priority, PATCH the Zammad ticket with the matching priority (e.g. Zammad uses 1 low, 2 normal, 3 high or similar; check your Zammad priority_id values).

Optional (requires adding custom attributes in Zammad):

  • gmail_thread_id Useful for agents to open or reference the Gmail thread.
  • discord_channel_id Useful for deep links to the Discord thread.
  • escalated If you want Zammad to show that the ticket was escalated from Discord.

Email ticket → Zammad user with discord_id

When an email ticket comes in, the bridge:

  1. Extracts sender email (sEmail).
  2. Looks up MongoDB User (website user) by email (case-insensitive). If that user has a discordID, it is stored for the next step.
  3. Creates the Zammad ticket (Zammad creates or finds the customer user by email).
  4. If the ticket response has customer_id and we have a discordID from step 2, the bridge PATCHes the Zammad user with discord_id: discordID.

Requirement: In Zammad, add a custom attribute discord_id (text) on the User object: Admin → Object Manager → User → add attribute discord_id. Without it, the PATCH will fail (the bridge logs the error and continues).

Discord ticket → ensure Zammad user exists

When a Discord ticket is created (modal “Create Support Ticket” or “Create ticket from message”):

  1. The bridge looks up MongoDB User (website user) by the creators Discord ID (interaction.user.id or message.author.id).
  2. If a User is found with an email, the bridge calls ensureZammadUserForDiscordUser:
    • Searches Zammad for a user with that email (GET /api/v1/users/search?query=...).
    • If none exists, creates a Zammad user (Customer) with email, firstname, lastname, and discord_id.
    • If a user exists, optionally sets discord_id on them via PATCH.
  3. No Zammad ticket is created for Discord-only tickets; only the Zammad user is ensured so they exist when you later create tickets or link them.

Requirement: Same as above: add discord_id on the User object in Zammad Object Manager if you want Discord ID stored. User create will still work without it; only the discord_id field will be skipped.

Flow summary

  1. New email → new ticket
    Bridge creates MongoDB Ticket and calls Zammad POST /api/v1/tickets; stores returned id in Ticket.zammadTicketId.
  2. Staff reply in Discord
    Bridge sends reply to Gmail and calls Zammad POST /api/v1/ticket_articles with ticket_id: ticket.zammadTicketId.
  3. Force-close in Discord
    Bridge sets MongoDB status: 'closed' and calls Zammad PATCH /api/v1/tickets/:id with state: 'closed'.

Creating Zammad objects to match the bridge

To ensure Zammad has the groups (and reference data) the bridge expects, run from gmail-bridge:

npm run create-zammad-objects

This script (see scripts/create-zammad-objects.js) uses the same .env as the bridge and:

  • Creates the groups Email Users and Discord Users if they do not exist (from ZAMMAD_EMAIL_GROUP and ZAMMAD_DISCORD_GROUP).
  • Lists ticket priorities and ticket states so you can verify IDs (e.g. for future priority sync).

Custom attributes (e.g. gmail_thread_id, discord_channel_id, escalated) must be added in Zammads admin UI (Object Manager) if you want them; the API for creating object attributes is admin-only.

Optional improvements

  • Store Zammad customer id If we ever need to reference the same customer across tickets, add zammadCustomerId to MongoDB Ticket and set it from the Zammad ticket create response.
  • Set discordusername on ticket When adding an article from Discord, we could PATCH the ticket to set discordusername to the repliers display name (if Zammad API supports updating that field).