fix(15): CR-01 fix webhook-triggered phishing detection reading from unpopulated payload.entity
This commit is contained in:
parent
e94482bd0b
commit
ecc34b4bad
1 changed files with 37 additions and 28 deletions
|
|
@ -443,39 +443,48 @@ export class WebhookService {
|
|||
|
||||
/**
|
||||
* Trigger phishing detection for a new ticket.
|
||||
* Runs asynchronously — does not block webhook response. Mirrors
|
||||
* triggerWorkflowEngine's "prefer inline payload.entity, else payload.entityId" shape.
|
||||
* Runs asynchronously — does not block webhook response.
|
||||
*
|
||||
* NOTE: `payload.entity` is never populated by the real Autotask webhook
|
||||
* flow (see lib/types/webhook.ts's normalizeWebhookPayload) — Autotask's
|
||||
* actual payload only carries Action/Guid/EntityType/Id/Fields/EventTime,
|
||||
* with no embedded entity body. Instead, read the ticket row back from
|
||||
* Postgres — by the time this fires, handleCreateOrUpdate() (called
|
||||
* earlier in the same processWebhook flow, see line ~95) has already
|
||||
* upserted the ticket, so the row is guaranteed to exist with current
|
||||
* title/description.
|
||||
*/
|
||||
private async triggerPhishingDetection(payload: AutotaskWebhookPayload): Promise<void> {
|
||||
let ticket: DetectableTicket;
|
||||
const row = await postgresClient.query<{
|
||||
id: string;
|
||||
ticket_number: string | null;
|
||||
title: string | null;
|
||||
description: string | null;
|
||||
company_id: number | null;
|
||||
contact_id: number | null;
|
||||
created_by_contact_id: number | null;
|
||||
}>(
|
||||
`SELECT id, ticket_number, title, description, company_id, contact_id, created_by_contact_id
|
||||
FROM tickets WHERE id = $1`,
|
||||
[payload.entityId]
|
||||
);
|
||||
|
||||
if (payload.entity) {
|
||||
// NOTE: Autotask's requester field is `createdByContactID` (mapped to
|
||||
// created_by_contact_id at lib/utils/entity-mapper.ts:211). There is no
|
||||
// similarly-named alternative field — since payload.entity is typed
|
||||
// Record<string, any>, a wrong field name would compile cleanly but
|
||||
// silently produce undefined at runtime.
|
||||
ticket = {
|
||||
id: payload.entityId,
|
||||
ticket_number: payload.entity.ticketNumber || null,
|
||||
title: payload.entity.title || null,
|
||||
description: payload.entity.description || null,
|
||||
company_id: payload.entity.companyID || null,
|
||||
contact_id: payload.entity.contactID || null,
|
||||
created_by_contact_id: payload.entity.createdByContactID || null,
|
||||
};
|
||||
} else {
|
||||
ticket = {
|
||||
id: payload.entityId,
|
||||
ticket_number: null,
|
||||
title: null,
|
||||
description: null,
|
||||
company_id: null,
|
||||
contact_id: null,
|
||||
created_by_contact_id: null,
|
||||
};
|
||||
const r = row.rows[0];
|
||||
if (!r) {
|
||||
console.warn(`[WEBHOOK] Skipping phishing detection — ticket ${payload.entityId} not found in Postgres yet`);
|
||||
return;
|
||||
}
|
||||
|
||||
const ticket: DetectableTicket = {
|
||||
id: Number(r.id),
|
||||
ticket_number: r.ticket_number,
|
||||
title: r.title,
|
||||
description: r.description,
|
||||
company_id: r.company_id,
|
||||
contact_id: r.contact_id,
|
||||
created_by_contact_id: r.created_by_contact_id,
|
||||
};
|
||||
|
||||
console.log(`[WEBHOOK] Triggering phishing detection for ticket ${payload.entityId}`);
|
||||
await detectPhishingTicket(ticket);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue