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

95 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Discord messageCreate handler forwards staff replies to Gmail and Zammad.
*/
const { mongoose } = require('../db-connection');
const { CONFIG } = require('../config');
const { ZAMMAD } = require('../config');
const { extractRawEmail } = require('../utils');
const { getGmailClient, sendGmailReply } = require('../services/gmail');
const { addZammadArticle } = require('../services/zammad');
const { updateTicketActivity } = require('../services/tickets');
const Ticket = mongoose.model('Ticket');
/**
* Handle a Discord message in a ticket channel → relay to Gmail (email tickets only) + Zammad.
*/
async function handleDiscordReply(m) {
if (m.author.bot || m.interaction) return;
const ticket = await Ticket.findOne({ discordThreadId: m.channel.id }).lean();
if (!ticket) return;
const discordUser = m.member?.displayName || m.author.username;
// Discord-originated tickets: no Gmail thread; only add reply to Zammad.
if (ticket.gmailThreadId.startsWith('discord-')) {
if (ticket.zammadTicketId && ZAMMAD.URL && ZAMMAD.TOKEN) {
try {
await addZammadArticle(ticket.zammadTicketId, m.content, { from: discordUser });
} catch (zErr) {
console.error('Zammad article (Discord ticket reply) failed:', zErr.response?.data || zErr.message);
}
}
return;
}
// Email tickets: send reply via Gmail and add to Zammad.
try {
const gmail = getGmailClient();
const thread = await gmail.users.threads.get({
userId: 'me',
id: ticket.gmailThreadId
});
const last = [...thread.data.messages].reverse().find(msg => {
const from =
msg.payload.headers.find(h => h.name === 'From')?.value || '';
return !from.toLowerCase().includes(CONFIG.MY_EMAIL);
});
if (!last) return;
let recipient =
last.payload.headers.find(h => h.name === 'From')?.value || '';
const replyTo =
last.payload.headers.find(h => h.name === 'Reply-To')?.value;
if (replyTo) recipient = replyTo;
const subject =
last.payload.headers.find(h => h.name === 'Subject')?.value ||
'Support';
const msgId =
last.payload.headers.find(h => h.name === 'Message-ID')?.value;
const recipientEmail = extractRawEmail(recipient).toLowerCase();
if (!recipientEmail || recipientEmail === CONFIG.MY_EMAIL) {
console.warn('Bad recipient for reply:', recipientEmail);
return;
}
await sendGmailReply(
ticket.gmailThreadId,
m.content,
recipientEmail,
subject,
discordUser,
msgId
);
await updateTicketActivity(ticket.gmailThreadId);
if (ticket.zammadTicketId && ZAMMAD.URL && ZAMMAD.TOKEN) {
try {
await addZammadArticle(ticket.zammadTicketId, m.content, { from: discordUser });
} catch (zErr) {
console.error('Zammad article (Discord reply) failed:', zErr.response?.data || zErr.message);
}
}
} catch (e) {
console.error('REPLY ERROR:', e);
}
}
module.exports = { handleDiscordReply };