7.1 KiB
MongoDB Bridge ↔ Zammad Schema Mapping
Reference for linking the gmail-bridge (MongoDB) with Zammad's PostgreSQL schema. Source: schema zammad.txt.
Primary link: Ticket ↔ Zammad ticket
| 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 withdiscord_idso 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):
- Set
discordusernameon claim – When a staff member claims the ticket in Discord, PATCH the Zammad ticket withdiscordusername: claimedByso Zammad shows who is handling it on Discord. Clear it on unclaim. - Sync priority to Zammad – When priority changes in Discord via
/priority, PATCH the Zammad ticket with the matching priority (e.g. Zammad uses1low,2normal,3high 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:
- Extracts sender email (
sEmail). - Looks up MongoDB User (website user) by
email(case-insensitive). If that user has adiscordID, it is stored for the next step. - Creates the Zammad ticket (Zammad creates or finds the customer user by email).
- If the ticket response has
customer_idand we have adiscordIDfrom step 2, the bridge PATCHes the Zammad user withdiscord_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”):
- The bridge looks up MongoDB User (website user) by the creator’s Discord ID (
interaction.user.idormessage.author.id). - 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_idon them via PATCH.
- Searches Zammad for a user with that email (
- 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
- New email → new ticket
Bridge creates MongoDBTicketand calls ZammadPOST /api/v1/tickets; stores returnedidinTicket.zammadTicketId. - Staff reply in Discord
Bridge sends reply to Gmail and calls ZammadPOST /api/v1/ticket_articleswithticket_id: ticket.zammadTicketId. - Force-close in Discord
Bridge sets MongoDBstatus: 'closed'and calls ZammadPATCH /api/v1/tickets/:idwithstate: '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_GROUPandZAMMAD_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 Zammad’s 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
zammadCustomerIdto 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
discordusernameto the replier’s display name (if Zammad API supports updating that field).