/** * Create Ticket Step — create an Autotask ticket from context. * Config: { template: { title, description, companyID, ticketType, priority, queueID, ... } } * All template values are pre-resolved by the engine. */ import { registerStepExecutor } from '../pipeline-engine'; import { AutotaskClient } from '../autotask-client'; import { PipelineStep, PipelineContext, StepExecutorResult } from '../../types/pipeline'; let _client: AutotaskClient | null = null; function getClient(): AutotaskClient { if (!_client) { _client = new AutotaskClient({ apiUrl: process.env.AUTOTASK_API_URL || '', username: process.env.AUTOTASK_USERNAME || '', password: process.env.AUTOTASK_SECRET || '', apiIntegrationCode: process.env.AUTOTASK_API_INTEGRATION_CODE || '', }); } return _client; } async function executeCreateTicket( step: PipelineStep, _context: PipelineContext, _executionId: number ): Promise { const template = step.config.template; if (!template || !template.title) { return { success: false, error: 'Missing ticket template or title' }; } // Build ticket payload — convert numeric strings to numbers const ticketPayload: Record = {}; for (const [key, value] of Object.entries(template)) { if (['companyID', 'ticketType', 'priority', 'queueID', 'ticketCategory', 'issueType', 'subIssueType', 'status'].includes(key)) { const num = Number(value); if (!isNaN(num) && num > 0) { ticketPayload[key] = num; } } else { ticketPayload[key] = value; } } // Default status to New (1) if not set if (!ticketPayload.status) { ticketPayload.status = 1; } console.log(`[PIPELINE:create_ticket] Creating ticket: "${ticketPayload.title}"`); const client = getClient(); const ticket = await client.createTicket(ticketPayload); return { success: true, output: { ticket_id: ticket.id, ticket_number: (ticket as any).ticketNumber, created_ticket: ticket, }, }; } registerStepExecutor('create_ticket', executeCreateTicket);