Skip to content

Commit 456842a

Browse files
committed
feat: replace Mystique brand presence triggers with DRS (LLMO-1819)
- Remove dead triggerMystiqueCategorization code (DRS config writer already populates categories via LLMO-1819) - Replace triggerGeoBrandPresence/triggerGeoBrandPresenceRefresh calls with DrsClient.triggerBrandDetection() for config-change flows - Remove isAdobe guard (DRS handles all sites uniformly) - Keep old Mystique trigger functions for backward compat (Slack manual) Depends on: adobe/spacecat-shared feat/drs-client-package being published Made-with: Cursor
1 parent b5dad0a commit 456842a

File tree

1 file changed

+18
-94
lines changed

1 file changed

+18
-94
lines changed

src/llmo-customer-analysis/handler.js

Lines changed: 18 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
*/
1212

1313
import {
14-
getLastNumberOfWeeks, isNonEmptyObject, llmoConfig,
14+
getLastNumberOfWeeks, llmoConfig,
1515
} from '@adobe/spacecat-shared-utils';
1616
import RUMAPIClient from '@adobe/spacecat-shared-rum-api-client';
1717
import { Config } from '@adobe/spacecat-shared-data-access/src/models/site/config.js';
18-
import { ImsClient } from '@adobe/spacecat-shared-ims-client';
18+
// eslint-disable-next-line import/no-unresolved -- available after spacecat-shared#1398 is published
19+
import DrsClient from '@adobe/spacecat-shared-drs-client';
1920
import { AuditBuilder } from '../common/audit-builder.js';
2021
import { wwwUrlResolver } from '../common/index.js';
2122
import { isAuditEnabledForSite } from '../common/audit-utils.js';
@@ -228,81 +229,23 @@ export async function triggerGeoBrandPresenceRefresh(context, site, configVersio
228229
log.info(`Successfully triggered ${auditType} audit`);
229230
}
230231

231-
async function triggerAllSteps(context, site, log, triggeredSteps, auditContext = {}) {
232-
log.info('Triggering all relevant audits (no config version provided or first-time setup)');
233-
234-
await triggerGeoBrandPresence(context, site, auditContext);
235-
triggeredSteps.push(auditContext?.brandPresenceCadence === 'daily' ? 'geo-brand-presence-daily' : 'geo-brand-presence');
236-
}
237-
238-
async function triggerMystiqueCategorization(context, siteId, domain) {
239-
const {
240-
env, log, s3Client,
241-
} = context;
242-
243-
const s3Bucket = env.S3_IMPORTER_BUCKET_NAME;
244-
const mystiqueApiBaseUrl = env.MYSTIQUE_API_BASE_URL;
245-
const categorizationEndpoint = `${mystiqueApiBaseUrl}/v1/categorization/site`;
246-
247-
const {
248-
config,
249-
exists,
250-
} = await llmoConfig.readConfig(siteId, s3Client, { s3Bucket });
251-
252-
if (exists && isNonEmptyObject(config.categories)) {
253-
log.info('Config categories already exist; skipping Mystique categorization');
232+
async function triggerBrandPresenceViaDrs(context, site, log, triggeredSteps) {
233+
const drsClient = DrsClient.createFrom(context);
234+
if (!drsClient.isConfigured()) {
235+
log.warn('DRS client not configured, skipping brand presence trigger via DRS');
254236
return;
255237
}
256238

257-
log.info(`Triggering Mystique categorization for siteId: ${siteId}, domain: ${domain}`);
258-
const imsContext = {
259-
log,
260-
env: {
261-
IMS_HOST: env.IMS_HOST,
262-
IMS_CLIENT_ID: env.IMS_CLIENT_ID,
263-
IMS_CLIENT_CODE: env.IMS_CLIENT_CODE,
264-
IMS_CLIENT_SECRET: env.IMS_CLIENT_SECRET,
265-
},
266-
};
267-
const imsClient = ImsClient.createFrom(imsContext);
268-
const { access_token: accessToken } = await imsClient.getServiceAccessToken();
269-
239+
const siteId = site.getSiteId();
270240
try {
271-
const response = await fetch(categorizationEndpoint, {
272-
method: 'POST',
273-
headers: {
274-
'Content-Type': 'application/json',
275-
authorization: accessToken,
276-
},
277-
body: JSON.stringify({
278-
url: domain,
279-
}),
280-
timeout: 60000,
281-
});
282-
283-
const data = await response.json();
284-
const { categories } = data.categories;
285-
config.categories = categories;
286-
await llmoConfig.writeConfig(siteId, config, s3Client, { s3Bucket });
241+
await drsClient.triggerBrandDetection(siteId);
242+
triggeredSteps.push('drs-brand-detection');
243+
log.info(`Triggered DRS brand detection for site ${siteId}`);
287244
} catch (error) {
288-
log.error(`Failed to trigger Mystique categorization: ${error.message}`);
245+
log.error(`Failed to trigger DRS brand detection for site ${siteId}: ${error.message}`);
289246
}
290247
}
291248

292-
async function getBaseUrlBySiteId(siteId, context) {
293-
const { dataAccess, log } = context;
294-
const { Site } = dataAccess;
295-
296-
try {
297-
const site = await Site.findById(siteId);
298-
/* c8 ignore next */
299-
return site?.getBaseURL() || '';
300-
} catch /* c8 ignore start */ {
301-
log.info(`Unable to fetch base URL for siteId: ${siteId}`);
302-
return '';
303-
} /* c8 ignore stop */
304-
}
305-
306249
export async function runLlmoCustomerAnalysis(finalUrl, context, site, auditContext = {}) {
307250
const {
308251
env, log, s3Client,
@@ -376,7 +319,6 @@ export async function runLlmoCustomerAnalysis(finalUrl, context, site, auditCont
376319
const isFirstTimeOnboarding = !previousConfigVersion;
377320

378321
if (isFirstTimeOnboarding) {
379-
await triggerMystiqueCategorization(context, siteId, domain);
380322
await sendOnboardingNotification(context, site, 'first_onboarding');
381323
}
382324

@@ -391,10 +333,10 @@ export async function runLlmoCustomerAnalysis(finalUrl, context, site, auditCont
391333
log.info('Domain has no OpTel data available; skipping referral traffic import');
392334
}
393335

394-
// If no config version provided, trigger all steps
336+
// If no config version provided, trigger brand presence via DRS
395337
if (!configVersion) {
396-
log.info('No config version provided; triggering all relevant audits');
397-
await triggerAllSteps(context, site, log, triggeredSteps, auditContext);
338+
log.info('No config version provided; triggering brand presence via DRS');
339+
await triggerBrandPresenceViaDrs(context, site, log, triggeredSteps);
398340

399341
return {
400342
auditResult: {
@@ -470,31 +412,13 @@ export async function runLlmoCustomerAnalysis(finalUrl, context, site, auditCont
470412
triggeredSteps.push('cdn-logs-report');
471413
}
472414

473-
const brandPresenceCadence = auditContext?.brandPresenceCadence || 'weekly';
474415
const hasBrandPresenceChanges = changes.topics || changes.categories || changes.entities;
475416
const needsBrandPresenceRefresh = previousConfigVersion
476417
&& (changes.brands || changes.competitors);
477418

478-
const baseUrl = await getBaseUrlBySiteId(siteId, context);
479-
const isAdobe = baseUrl.startsWith('https://adobe.com');
480-
481-
if (hasBrandPresenceChanges && !isAdobe) {
482-
const isAICategorizationOnly = changes.metadata?.isAICategorizationOnly || false;
483-
484-
if (isAICategorizationOnly) {
485-
log.info('LLMO config changes detected from AI categorization flow; triggering geo-brand-presence refresh');
486-
await triggerGeoBrandPresenceRefresh(context, site, configVersion);
487-
triggeredSteps.push('geo-brand-presence-refresh');
488-
} else {
489-
log.info('LLMO config changes detected in topics, categories, or entities; triggering geo-brand-presence audit');
490-
await triggerGeoBrandPresence(context, site, auditContext);
491-
triggeredSteps.push(brandPresenceCadence === 'daily' ? 'geo-brand-presence-daily' : 'geo-brand-presence');
492-
}
493-
}
494-
if (needsBrandPresenceRefresh && !isAdobe) {
495-
log.info('LLMO config changes detected in brand or competitor aliases; triggering geo-brand-presence-refresh');
496-
await triggerGeoBrandPresenceRefresh(context, site, configVersion);
497-
triggeredSteps.push('geo-brand-presence-refresh');
419+
if (hasBrandPresenceChanges || needsBrandPresenceRefresh) {
420+
log.info('LLMO config changes detected affecting brand presence; triggering DRS brand detection');
421+
await triggerBrandPresenceViaDrs(context, site, log, triggeredSteps);
498422
}
499423

500424
if (triggeredSteps.length > 0) {

0 commit comments

Comments
 (0)