Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 134 additions & 0 deletions src/high-value-pages/handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* Copyright 2024 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/

import { Audit } from '@adobe/spacecat-shared-data-access';
import { AuditBuilder } from '../common/audit-builder.js';
import { wwwUrlResolver } from '../common/index.js';

const { AUDIT_STEP_DESTINATIONS } = Audit;
const AUDIT_TYPE = Audit.AUDIT_TYPES.HIGH_VALUE_PAGES || 'high-value-pages';

/**
* Step 1: Run the audit and import top pages data
* Retrieves existing high value pages from the URL store (to be implemented)
* @param {Object} context - The execution context containing site, log, and finalUrl
* @returns {Object} Audit result with existing high value pages
*/
export async function runAuditAndImportTopPagesStep(context) {
const { site, log, finalUrl } = context;

log.debug(`[${AUDIT_TYPE}] [Site: ${site.getId()}] starting audit`);

/**
* TODO: Implement getting existing high value pages from URL store when URL store API is ready
* Format of the HighValuePage should be: {
"url": "https://www.example.com/services/engineering/iot",
"reasoning": "This is a service detail page for IoT engineering, relevant to the...",
"rank": "3:96" // 3 is the rank of the page, 96 is the score of the page
}
*/
const existingHighValuePages = [];

return {
auditResult: {
existingHighValuePages,
},
fullAuditRef: finalUrl,
type: 'top-pages',
siteId: site.getId(),
};
}

/**
* Step 2: Send message to Mystique for high value page generation
* Filters out existing high value pages from top pages and sends to Mystique queue
* @param {Object} context - The execution context containing dataAccess, sqs, audit, etc.
* @returns {Object} Status object indicating completion
*/
export async function sendToMystiqueForGeneration(context) {
const {
log, site, finalUrl, sqs, env, dataAccess, audit,
} = context;
const { SiteTopPage } = dataAccess;

const { existingHighValuePages } = audit.getAuditResult();
let topPagesWithoutExistingHighValuePages = [];
try {
// Fetch all top pages for the site
const topPages = await SiteTopPage.allBySiteId(site.getId());
// Filter out existing high value pages and map to required format
const existingHvpUrls = new Set(existingHighValuePages.map((hvp) => hvp.url));
topPagesWithoutExistingHighValuePages = topPages
.filter((topPage) => !existingHvpUrls.has(topPage.getUrl()))
.map((topPage) => ({
url: topPage.getUrl(),
traffic: topPage.getTraffic(),
topKeyword: topPage.getTopKeyword(),
}));
} catch (error) {
log.error(
`[${AUDIT_TYPE}] [Site: ${site.getId()}] Error occurred: ${error.message}`,
);
throw new Error(`Error occurred: ${error.message}`);
}

try {
// Prepare message for Mystique queue
const message = {
type: 'guidance:high-value-pages',
siteId: site.getId(),
auditId: audit.getId(),
deliveryType: site.getDeliveryType(),
time: new Date().toISOString(),
data: {
finalUrl,
highValuePages: existingHighValuePages,
topPages: topPagesWithoutExistingHighValuePages,
},
};

await sqs.sendMessage(env.QUEUE_SPACECAT_TO_MYSTIQUE, message);
log.info(`[${AUDIT_TYPE}] Message sent to Mystique`, {
...message,
data: {
...message.data,
highValuePages: `total existing high value pages: ${existingHighValuePages.length}`,
topPages: `total top pages: ${topPagesWithoutExistingHighValuePages.length}, without existing high value pages`,
},
});

return {
status: 'complete',
};
} catch (error) {
log.error(
`[${AUDIT_TYPE}] [Site: ${site.getId()}] Failed to send message to Mystique: ${
error.message
}`,
);
throw error;
}
}

/**
* Export the audit handler with all steps configured
* Uses AuditBuilder to chain the steps together
*/
export default new AuditBuilder()
.withUrlResolver(wwwUrlResolver)
.addStep(
'runAuditAndImportTopPages',
runAuditAndImportTopPagesStep,
AUDIT_STEP_DESTINATIONS.IMPORT_WORKER,
)
.addStep('send-message-to-mystique', sendToMystiqueForGeneration)
.build();
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ import permissions from './permissions/handler.js';
import permissionsRedundant from './permissions/handler.redundant.js';
import faqs from './faqs/handler.js';
import faqsGuidance from './faqs/guidance-handler.js';
import highValuePages from './high-value-pages/handler.js';
import pageCitability from './page-citability/handler.js';

const HANDLERS = {
Expand Down Expand Up @@ -171,6 +172,7 @@ const HANDLERS = {
'security-permissions-redundant': permissionsRedundant,
faqs,
'guidance:faqs': faqsGuidance,
'high-value-pages': highValuePages,
'page-citability': pageCitability,
dummy: (message) => ok(message),
};
Expand Down
Loading