chore: bump version to 1.7.22 and update CHANGELOG, tests and docs
Docs Check / Markdown lint (push) Successful in 1m14s
Build and Push Docker Image / build (push) Successful in 1m52s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m55s
CI / Security audit (push) Successful in 2m25s
Docs Check / Mermaid diagram parse check (push) Successful in 3m6s
CI / Swagger Validation & Coverage (push) Successful in 3m22s
CI / Tests & coverage (push) Successful in 3m45s

This commit is contained in:
2026-05-27 17:42:41 +01:00
parent d2ac7731ca
commit 95bd703b26
16 changed files with 664 additions and 65 deletions
+62 -5
View File
@@ -180,7 +180,7 @@ function validateWebhookSecret(req) {
* @param {string} serviceType - 'sonarr', 'radarr', or 'ombi'
* @param {string} eventType - the eventType from the webhook payload
*/
async function processWebhookEvent(serviceType, eventType) {
async function processWebhookEvent(serviceType, eventType, payload = null) {
const affectsQueue = QUEUE_EVENTS.has(eventType);
const affectsHistory = HISTORY_EVENTS.has(eventType);
const affectsOmbi = OMBI_EVENTS.has(eventType);
@@ -259,9 +259,66 @@ async function processWebhookEvent(serviceType, eventType) {
const ombiInstances = getOmbiInstances();
if (affectsOmbi) {
// Add a 2000ms delay to resolve the race condition where Ombi fires the webhook before committing to DB
await new Promise(r => setTimeout(r, 2000));
const ombiRequests = await arrRetrieverRegistry.getOmbiRequests(true);
const delayMs = parseInt(process.env.OMBI_WEBHOOK_REFRESH_DELAY_MS, 10);
const initialDelay = !isNaN(delayMs) ? delayMs : 2000;
logToFile(`[Webhook] Waiting initial delay of ${initialDelay}ms for Ombi webhook synchronization...`);
await new Promise(r => setTimeout(r, initialDelay));
const requestId = payload ? (payload.requestId || payload.RequestId || payload.id || payload.Id) : null;
const mediaType = payload ? (payload.type || payload.Type || '').toLowerCase() : null;
let ombiRequests = { movie: [], tv: [] };
let foundAndValid = false;
const maxRetries = 3;
const retryDelayMs = 1500;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
if (attempt > 1) {
logToFile(`[Webhook] Ombi request not found or missing user (attempt ${attempt-1}/${maxRetries}), retrying in ${retryDelayMs}ms...`);
await new Promise(r => setTimeout(r, retryDelayMs));
}
ombiRequests = await arrRetrieverRegistry.getOmbiRequests(true);
if (!requestId) {
// If no requestId was provided in payload, we can't search specifically, so just accept the fetch
foundAndValid = true;
break;
}
// Search in movie or tv lists
const targetList = (mediaType === 'tv' || mediaType === 'series') ? (ombiRequests.tv || []) : (ombiRequests.movie || []);
// Also check both if mediaType not specified
const searchList = mediaType ? targetList : [...(ombiRequests.movie || []), ...(ombiRequests.tv || [])];
const targetReq = searchList.find(r => r && (r.id === requestId || r.Id === requestId));
if (targetReq) {
const user = extractRequestedUser(targetReq);
if (user) {
logToFile(`[Webhook] Verified request ${requestId} has valid user "${user}" on attempt ${attempt}`);
foundAndValid = true;
break;
} else {
logToFile(`[Webhook] Found request ${requestId} on attempt ${attempt}, but user extraction was empty.`);
}
} else {
logToFile(`[Webhook] Request ${requestId} not found in retrieved list on attempt ${attempt}.`);
}
}
if (!foundAndValid && requestId) {
logToFile(`[Webhook] WARNING: Could not verify request ${requestId} with valid user info after ${maxRetries} retries.`);
// Try to log the raw target request if we found one
ombiRequests = await arrRetrieverRegistry.getOmbiRequests(true);
const searchList = [...(ombiRequests.movie || []), ...(ombiRequests.tv || [])];
const targetReq = searchList.find(r => r && (r.id === requestId || r.Id === requestId));
if (targetReq) {
logToFile(`[Webhook] Raw request object where extraction failed: ${JSON.stringify(targetReq)}`);
} else {
logToFile(`[Webhook] Request ${requestId} was completely absent from Ombi requests list.`);
}
}
cache.set('poll:ombi-requests', ombiRequests, CACHE_TTL);
logToFile(`[Webhook] Refreshed poll:ombi-requests (${ombiRequests.movie?.length || 0} movies, ${ombiRequests.tv?.length || 0} TV shows)`);
}
@@ -777,7 +834,7 @@ router.post('/ombi', webhookLimiter, (req, res) => {
}
// Background cache refresh + SSE broadcast (fire-and-forget)
processWebhookEvent('ombi', eventType).catch(err => {
processWebhookEvent('ombi', eventType, req.body).catch(err => {
logToFile(`[Webhook] Ombi background refresh error: ${err.message}`);
});