jiraCloud/routes/webhooks.js
jmcqueen efc64a227c Add Webex inbound OAuth flow and room-to-Jira job request pipeline.
Introduces integration-based webhook registration, message parsing, dry-run
monitoring, JSM ticket creation, and OAuth token refresh for DC Ops spaces.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-28 08:27:52 -04:00

74 lines
2.8 KiB
JavaScript

import { validateJiraWebhook, validateSupportWebhook } from '../lib/validate.js';
const WEBHOOK_LOG_PROVIDERS = {
'jira-request': 'jira',
request: 'request',
};
export function createWebhookRoutes({ config, jiraProcessor, webexService, log }) {
const { logger, logWarn, safeProcess, logFile, runWithCorrelationId, createCorrelationId } = log;
function healthCheck(req, res) {
res.status(200).json({ status: 'alive' });
}
function handleJiraWebhook(routeName, req, res) {
res.status(201).send();
const validation = validateJiraWebhook(req.body);
const correlationMeta = { routeName, issueKey: validation.issueKey || req.body?.issue?.key };
if (!validation.valid) {
runWithCorrelationId(createCorrelationId(correlationMeta), () => {
logWarn(routeName, `Invalid webhook payload: ${validation.error}`);
});
return;
}
safeProcess(routeName, () => {
logger(
routeName,
`Accepted webhook event=${req.body.webhookEvent || 'unknown'} issue=${validation.issueKey} project=${req.body.issue?.fields?.project?.key || '?'}`
);
logFile(WEBHOOK_LOG_PROVIDERS[routeName] || routeName, req.body);
jiraProcessor.processJiraTicket(req.body);
}, correlationMeta);
}
function registerRoutes(app) {
app.get('/healthCheck', healthCheck);
app.get('/heathCheck', healthCheck);
app.post('/jira-request', (req, res) => handleJiraWebhook('jira-request', req, res));
app.post('/request', (req, res) => handleJiraWebhook('request', req, res));
app.post('/support', (req, res) => {
res.status(201).send();
const validation = validateSupportWebhook(req.body);
const correlationMeta = { routeName: 'support', issueKey: validation.issueKey || req.body?.issue?.key };
if (!validation.valid) {
runWithCorrelationId(createCorrelationId(correlationMeta), () => {
logWarn('support', `Invalid webhook payload: ${validation.error}`);
});
return;
}
safeProcess('support', () => {
logFile('support', req.body);
logger('support', `Received support webhook for ${validation.issueKey}`);
webexService.processHighSeverity(req.body, config.rooms.support);
}, correlationMeta);
});
}
function registerErrorHandler(app) {
app.use((err, req, res, next) => {
log.logError('express', `${req.method} ${req.path}`, err);
if (!res.headersSent) {
res.status(500).json({ error: 'Internal server error' });
}
});
}
return { registerRoutes, registerErrorHandler };
}