huge changes
This commit is contained in:
@@ -8,7 +8,7 @@ const {
|
||||
ButtonStyle,
|
||||
EmbedBuilder
|
||||
} = require('discord.js');
|
||||
const { mongoose } = require('./db-connection');
|
||||
const { mongoose, withRetry } = require('./db-connection');
|
||||
const { CONFIG, GAME_NAME_TO_KEY } = require('./config');
|
||||
const {
|
||||
getCleanBody,
|
||||
@@ -16,23 +16,38 @@ const {
|
||||
stripEmailQuotes,
|
||||
stripMobileFooter,
|
||||
detectGame,
|
||||
getFormattedDate
|
||||
getFormattedDate,
|
||||
truncateEmbedField,
|
||||
enforceEmbedLimit
|
||||
} = require('./utils');
|
||||
const { getGmailClient } = require('./services/gmail');
|
||||
const { getNextTicketNumber, checkTicketLimits, getOrCreateTicketCategory, createEmailTicketAsThread, toDiscordSafeName, getSenderLocal } = require('./services/tickets');
|
||||
const { getEmailRouting } = require('./services/guildSettings');
|
||||
const { logError } = require('./services/debugLog');
|
||||
const { logError, logGmail } = require('./services/debugLog');
|
||||
const { increment } = require('./services/patternStore');
|
||||
|
||||
const Ticket = mongoose.model('Ticket');
|
||||
const Transcript = mongoose.model('Transcript');
|
||||
|
||||
let isPolling = false;
|
||||
let authErrorNotified = false;
|
||||
let pollCount = 0, totalProcessed = 0, totalSkipped = 0, totalErrors = 0;
|
||||
|
||||
/**
|
||||
* Poll Gmail for unread primary-inbox messages and route them to Discord.
|
||||
* @param {import('discord.js').Client} client
|
||||
*/
|
||||
async function poll(client) {
|
||||
console.log('Running poll()...');
|
||||
if (isPolling) return;
|
||||
isPolling = true;
|
||||
try {
|
||||
pollCount++;
|
||||
if (pollCount % 10 === 0) {
|
||||
logGmail('Poll summary', `polls: ${pollCount}, processed: ${totalProcessed}, skipped: ${totalSkipped}, errors: ${totalErrors}`, null, null).catch(() => {});
|
||||
pollCount = 0; totalProcessed = 0; totalSkipped = 0; totalErrors = 0;
|
||||
}
|
||||
console.log('Running poll()...');
|
||||
try {
|
||||
const gmail = getGmailClient();
|
||||
const list = await gmail.users.messages.list({
|
||||
userId: 'me',
|
||||
@@ -68,6 +83,7 @@ async function poll(client) {
|
||||
email.data.payload.headers.find(h => h.name === 'From')
|
||||
?.value || '';
|
||||
if (from.toLowerCase().includes(CONFIG.MY_EMAIL)) {
|
||||
totalSkipped++;
|
||||
await gmail.users.messages.batchModify({
|
||||
userId: 'me',
|
||||
requestBody: {
|
||||
@@ -146,6 +162,7 @@ async function poll(client) {
|
||||
// Check ticket limits before creating
|
||||
const limitCheck = await checkTicketLimits(sEmail);
|
||||
if (!limitCheck.ok) {
|
||||
totalSkipped++;
|
||||
console.log(`Ticket limit reached for ${sEmail}: ${limitCheck.reason}`);
|
||||
await gmail.users.messages.batchModify({
|
||||
userId: 'me',
|
||||
@@ -227,20 +244,29 @@ async function poll(client) {
|
||||
.setColor(CONFIG.EMBED_COLOR_INFO)
|
||||
.addFields({
|
||||
name: 'Ticket Info',
|
||||
value:
|
||||
value: truncateEmbedField(
|
||||
`**Name:** ${sName}\n` +
|
||||
`**Email:** ${sEmail}\n` +
|
||||
`**Date:** ${getFormattedDate()}\n` +
|
||||
`**Game:** ${detectedGame}\n` +
|
||||
`**Subject:** ${subject || 'No subject'}`
|
||||
`**Subject:** ${subject || 'No subject'}`)
|
||||
});
|
||||
|
||||
await ticketChan.send({
|
||||
enforceEmbedLimit([welcomeEmbed, ticketInfoEmbed]);
|
||||
const welcomeMsg = await ticketChan.send({
|
||||
content: `<@&${CONFIG.ROLE_ID_TO_PING}>`,
|
||||
embeds: [welcomeEmbed, ticketInfoEmbed],
|
||||
components: [buttons]
|
||||
});
|
||||
|
||||
const { createStaffThread } = require('./services/staffThread');
|
||||
await createStaffThread(ticketChan, client).catch(() => {});
|
||||
|
||||
if (CONFIG.PIN_INITIAL_MESSAGE_ENABLED && welcomeMsg) {
|
||||
const { pinMessage } = require('./services/pinMessage');
|
||||
await pinMessage(welcomeMsg, client).catch(() => {});
|
||||
}
|
||||
|
||||
// On reopen, link previous transcripts
|
||||
if (isReopened) {
|
||||
try {
|
||||
@@ -292,7 +318,7 @@ async function poll(client) {
|
||||
const now = new Date();
|
||||
const defaultPriority = CONFIG.PRIORITY_ENABLED ? CONFIG.DEFAULT_PRIORITY : 'normal';
|
||||
|
||||
await Ticket.findOneAndUpdate(
|
||||
await withRetry(() => Ticket.findOneAndUpdate(
|
||||
{ gmailThreadId: email.data.threadId },
|
||||
{
|
||||
$set: {
|
||||
@@ -308,7 +334,15 @@ async function poll(client) {
|
||||
}
|
||||
},
|
||||
{ upsert: true, new: true }
|
||||
);
|
||||
));
|
||||
totalProcessed++;
|
||||
logGmail(subject, sEmail, number, detectedGame).catch(() => {});
|
||||
increment('user_tickets', sEmail, 'today');
|
||||
increment('user_tickets', sEmail, 'week');
|
||||
if (detectedGame) {
|
||||
increment('game_tickets', detectedGame, 'today');
|
||||
increment('game_tickets', detectedGame, 'week');
|
||||
}
|
||||
}
|
||||
console.log('Archiving/reading Gmail message', msgRef.id);
|
||||
await gmail.users.messages.batchModify({
|
||||
@@ -319,10 +353,32 @@ async function poll(client) {
|
||||
}
|
||||
});
|
||||
}
|
||||
authErrorNotified = false;
|
||||
} catch (e) {
|
||||
const isAuthError =
|
||||
(e.message && (
|
||||
e.message.includes('invalid_grant') ||
|
||||
e.message.includes('unauthorized') ||
|
||||
e.message.includes('Invalid Credentials')
|
||||
)) ||
|
||||
e.status === 401 ||
|
||||
e.code === 401;
|
||||
|
||||
if (isAuthError) {
|
||||
logError('Gmail OAuth', { message: 'Gmail OAuth token invalid or expired. Re-authentication required.', stack: e.stack || e.message || String(e) }, null, client);
|
||||
if (CONFIG.ADMIN_ID && !authErrorNotified) {
|
||||
authErrorNotified = true;
|
||||
client.users.fetch(CONFIG.ADMIN_ID).then(u => u.send('Gmail OAuth token invalid or expired. Re-authentication required.')).catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
totalErrors++;
|
||||
console.error('POLL ERROR:', e);
|
||||
logError('Gmail poll', e, null, client);
|
||||
}
|
||||
} finally {
|
||||
isPolling = false;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { poll };
|
||||
|
||||
Reference in New Issue
Block a user