diff --git a/public/js/views/emailCompose.js b/public/js/views/emailCompose.js
index b3fcf08..5f39df0 100644
--- a/public/js/views/emailCompose.js
+++ b/public/js/views/emailCompose.js
@@ -324,9 +324,10 @@ const EmailCompose = (() => {
document.body.appendChild(overlay);
// Init tag inputs
- const initialTo = options.customerEmail ? [options.customerEmail] : [];
+ const initialTo = options.initialTo || (options.customerEmail ? [options.customerEmail] : []);
+ const initialCc = options.initialCc || [];
const toTagsCtrl = makeTagInput('ec-to-container', initialTo);
- const ccTagsCtrl = makeTagInput('ec-cc-container', []);
+ const ccTagsCtrl = makeTagInput('ec-cc-container', initialCc);
// Subject
const subjectEl = document.getElementById('ec-subject');
diff --git a/public/js/views/ticketDetail.js b/public/js/views/ticketDetail.js
index a999ef1..6dcc623 100644
--- a/public/js/views/ticketDetail.js
+++ b/public/js/views/ticketDetail.js
@@ -756,18 +756,46 @@ const TicketDetailView = {
`;
- // Extract sender email if possible for CC/To
- let customerEmail = ticket.customer_email || '';
- const matchEmail = (article.a_from || '').match(/<([^>]+)>/) || (article.a_from || '').match(/([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/);
- if (matchEmail) {
- customerEmail = matchEmail[1];
+ // Helper to extract email addresses from headers
+ const parseEmails = (str) => {
+ if (!str) return [];
+ return (str.match(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g) || [])
+ .map(email => email.toLowerCase().trim());
+ };
+
+ const fromEmails = parseEmails(article.a_from);
+ const toEmails = parseEmails(article.a_to);
+ const ccEmails = parseEmails(article.a_cc);
+
+ // Exclude list (helpdesk and active agent)
+ const config = App.lookups.config || {};
+ const helpdeskEmail = (config.helpdeskEmail || 'helpdesk@pharmaidea.com').toLowerCase();
+ const agentEmail = (config.agentEmail || '').toLowerCase();
+ const excludeEmails = [helpdeskEmail, agentEmail].filter(Boolean);
+
+ const initialToSet = new Set();
+ fromEmails.forEach(e => {
+ if (!excludeEmails.includes(e) && !e.includes('helpdesk')) {
+ initialToSet.add(e);
+ }
+ });
+ if (initialToSet.size === 0 && ticket.customer_email) {
+ initialToSet.add(ticket.customer_email.toLowerCase());
}
+ const initialCcSet = new Set();
+ [...toEmails, ...ccEmails].forEach(e => {
+ if (!excludeEmails.includes(e) && !e.includes('helpdesk') && !initialToSet.has(e)) {
+ initialCcSet.add(e);
+ }
+ });
+
EmailCompose.open({
ticketId: ticket.id,
ticketTn: ticket.tn,
ticketTitle: ticket.title,
- customerEmail: customerEmail,
+ initialTo: Array.from(initialToSet),
+ initialCc: Array.from(initialCcSet),
initialBodyHtml: initialBodyHtml,
});
} else {
diff --git a/routes/lookups.js b/routes/lookups.js
index 4c62af7..7f3e07c 100644
--- a/routes/lookups.js
+++ b/routes/lookups.js
@@ -132,12 +132,26 @@ router.get('/users', async (req, res) => {
});
// GET /api/config — Application config
-router.get('/config', (req, res) => {
+router.get('/config', async (req, res) => {
+ const agentId = parseInt(req.headers['x-agent-id'], 10) || 1;
+ let agentEmail = '';
+ try {
+ const prefRes = await pool.query(
+ `SELECT preferences_value FROM user_preferences WHERE user_id = $1 AND preferences_key = 'UserEmail'`,
+ [agentId]
+ );
+ if (prefRes.rows.length > 0) {
+ agentEmail = prefRes.rows[0].preferences_value || '';
+ }
+ } catch (_) {}
+
res.json({
defaultAgentLogin: process.env.OTRS_API_USER || '',
dailyTargetTime: parseInt(process.env.DAILY_TARGET_TIME, 10) || 480,
phraseThreshold: parseInt(process.env.PHRASE_THRESHOLD, 10) || 70,
- autoTimeMinHour: process.env.AUTO_TIME_MIN_HOUR || '18:00'
+ autoTimeMinHour: process.env.AUTO_TIME_MIN_HOUR || '18:00',
+ helpdeskEmail: process.env.OTRS_MAIL_BCC || '',
+ agentEmail: agentEmail
});
});