5.3 KiB
5.3 KiB
MongoDB Setup for Gmail-Discord-Zammad Bridge
Overview
The bridge uses MongoDB only for persistent storage (tickets, transcripts, counters, tags, close requests). SQLite has been removed; a backup of the old SQLite-based code and schema lives in backup-sqlite/. To migrate existing SQLite data to MongoDB, run npm run migrate-from-sqlite (see that script’s prerequisites).
Files Created
db-connection.js- MongoDB connection module with reconnection logicmodels.js- Updated with three new schemas:Ticket- Stores ticket informationTicketCounter- Tracks ticket numbers per senderTranscript- Stores transcript message references
mongodb-example.js- Example usage patterns
Configuration
1. Environment Variable
Add to your .env file:
MONGODB_URI=mongodb://localhost:27018/indifferent_broccoli
Note: Uses port 27018 to match your existing Indifferent Broccoli setup (as defined in docker-compose.yml).
2. Install Dependencies
npm install
This will install mongoose@^6.12.0.
Usage in Your Code
Basic Connection
const { connectMongoDB, closeMongoDB, mongoose } = require('./db-connection');
// In your Discord client.once('ready', ...) event:
await connectMongoDB(process.env.MONGODB_URI);
console.log('Connected to MongoDB');
// Get models:
const Ticket = mongoose.model('Ticket');
const TicketCounter = mongoose.model('TicketCounter');
const Transcript = mongoose.model('Transcript');
Replacing SQLite Operations
Old (SQLite):
const ticket = await dbGet("SELECT * FROM tickets WHERE gmail_thread_id = ?", [threadId]);
New (MongoDB):
const Ticket = mongoose.model('Ticket');
const ticket = await Ticket.findOne({ gmail_thread_id: threadId });
Old (SQLite):
await dbRun("INSERT INTO tickets (gmail_thread_id, discord_thread_id, ...) VALUES (?, ?, ...)",
[threadId, channelId, ...]);
New (MongoDB):
const Ticket = mongoose.model('Ticket');
await Ticket.create({
gmail_thread_id: threadId,
discord_thread_id: channelId,
...
});
Old (SQLite):
await dbRun("UPDATE tickets SET status = ? WHERE gmail_thread_id = ?", ['closed', threadId]);
New (MongoDB):
const Ticket = mongoose.model('Ticket');
await Ticket.updateOne(
{ gmail_thread_id: threadId },
{ $set: { status: 'closed' } }
);
Schema Reference
Ticket Schema
{
gmail_thread_id: String (required, unique, indexed),
discord_thread_id: String,
zammad_ticket_id: Number,
sender_email: String (required),
subject: String,
created_at: Date (default: now),
status: String (enum: ['open', 'closed'], default: 'open'),
claimed_by: String (Discord user ID),
escalated: Boolean (default: false),
ticket_number: Number,
rename_count: Number (default: 0),
rename_window_start: Date
}
TicketCounter Schema
{
sender_local: String (required, unique),
counter: Number (default: 1)
}
Transcript Schema
{
gmail_thread_id: String (required),
transcript_message_id: String,
created_at: Date (default: now)
}
Testing the Connection
Run the example file to verify everything works:
node mongodb-example.js
Expected output:
Connecting to MongoDB...
✓ Connected to MongoDB
✓ Models loaded: Ticket, TicketCounter, Transcript
--- Example: Create Ticket ---
Created ticket: example_thread_123
...
✓ Example completed successfully
Graceful Shutdown
Add this to your main file for clean shutdown:
process.on('SIGTERM', async () => {
console.log('SIGTERM received, closing connections...');
await closeMongoDB();
await client.destroy(); // Discord client
process.exit(0);
});
process.on('SIGINT', async () => {
console.log('SIGINT received, closing connections...');
await closeMongoDB();
await client.destroy();
process.exit(0);
});
Migration Notes
- No automatic data migration from SQLite - starting fresh with MongoDB
- The existing
tickets.sqliteanddiscord_only.sqlitefiles remain untouched - You can manually export data from SQLite and import into MongoDB if needed
Connection Features
- Auto-reconnection: If MongoDB connection drops, Mongoose will automatically attempt to reconnect
- Connection events: Logs when connected, disconnected, and reconnected
- Error handling: Graceful error messages with stack traces
- Timeouts: Configured with reasonable defaults (5s server selection, 45s socket timeout)
Next Steps
- Review the schemas in
models.js(lines 793-819) - Test the connection with
node mongodb-example.js - Start replacing SQLite operations in
zammad-discord.jswith MongoDB operations - Monitor MongoDB connection in production logs
Troubleshooting
Connection refused
- Check MongoDB is running:
docker psorsystemctl status mongodb - Verify port 27018 is correct in
.env - Check MongoDB logs for errors
Authentication failed
- If MongoDB requires auth, update URI:
mongodb://username:password@localhost:27018/indifferent_broccoli
Schema validation errors
- Check required fields are provided when creating documents
- Ensure
statusis either 'open' or 'closed' (enum validation)