Integration first pass

This commit is contained in:
Darren Clarke 2025-10-15 16:08:53 +02:00
parent 11563a794e
commit 320b9c1b38
3 changed files with 215 additions and 1 deletions

View file

@ -0,0 +1,150 @@
import { createLogger } from "@link-stack/logger";
import { Zammad, getOrCreateUser } from "../../lib/zammad.js";
const logger = createLogger('create-ticket-from-form');
export interface CreateTicketFromFormOptions {
formData: any;
receivedAt: string;
}
const createTicketFromFormTask = async (
options: CreateTicketFromFormOptions,
): Promise<void> => {
const { formData, receivedAt } = options;
logger.info({
formData,
receivedAt,
formDataKeys: Object.keys(formData),
}, 'Processing Formstack form submission');
// Extract data from Formstack payload
const {
FormID,
UniqueID,
name,
signal_number,
type_of_help_requested,
type_of_organization,
urgency_level,
email_address,
phone_number,
address,
description_of_issue,
preferred_contact_method,
available_times_for_contact,
how_did_you_hear_about_us,
preferred_language,
} = formData;
// Build full name
const fullName = name
? `${name.first || ''} ${name.last || ''}`.trim()
: 'Unknown';
// Build address string
let addressString = '';
if (address) {
const parts = [
address.address,
address.city,
address.state,
address.zip,
].filter(Boolean);
addressString = parts.join(', ');
}
// Build ticket title
const title = `Help Request: ${type_of_help_requested || 'General'} - ${fullName}`;
// Build ticket body with all form information
const body = `<h3>Contact Information</h3>
<ul>
<li><strong>Name:</strong> ${fullName}</li>
${email_address ? `<li><strong>Email:</strong> ${email_address}</li>` : ''}
${phone_number ? `<li><strong>Phone:</strong> ${phone_number}</li>` : ''}
${signal_number ? `<li><strong>Signal Number:</strong> ${signal_number}</li>` : ''}
${addressString ? `<li><strong>Address:</strong> ${addressString}</li>` : ''}
</ul>
<h3>Request Details</h3>
<ul>
${type_of_help_requested ? `<li><strong>Type of Help:</strong> ${type_of_help_requested}</li>` : ''}
${type_of_organization ? `<li><strong>Organization Type:</strong> ${type_of_organization}</li>` : ''}
${urgency_level ? `<li><strong>Urgency Level:</strong> ${urgency_level}</li>` : ''}
${preferred_contact_method ? `<li><strong>Preferred Contact Method:</strong> ${preferred_contact_method}</li>` : ''}
${available_times_for_contact ? `<li><strong>Available Times:</strong> ${available_times_for_contact}</li>` : ''}
${preferred_language ? `<li><strong>Preferred Language:</strong> ${preferred_language}</li>` : ''}
</ul>
${description_of_issue ? `<h3>Description of Issue</h3><p>${description_of_issue}</p>` : ''}
${how_did_you_hear_about_us ? `<p><strong>How they heard about us:</strong> ${how_did_you_hear_about_us}</p>` : ''}
<hr>
<p><em>Form ID: ${FormID} | Submission ID: ${UniqueID} | Received: ${receivedAt}</em></p>`;
// Get Zammad configuration from environment
const zammadUrl = process.env.ZAMMAD_URL || 'http://zammad-nginx:8080';
const zammadToken = process.env.ZAMMAD_API_TOKEN;
if (!zammadToken) {
logger.error('ZAMMAD_API_TOKEN environment variable is not configured');
throw new Error('ZAMMAD_API_TOKEN is required');
}
const zammad = Zammad({ token: zammadToken }, zammadUrl);
try {
// Get or create user based on phone number, Signal number, or email
let customer;
const contactInfo = signal_number || phone_number || email_address;
if (contactInfo) {
customer = await getOrCreateUser(zammad, contactInfo);
} else {
// Create user with just the name if no contact info
customer = await zammad.user.create({
firstname: name?.first,
lastname: name?.last,
note: `User created from Formstack submission ${UniqueID}`,
});
}
logger.info({ customerId: customer.id, customerEmail: customer.email }, 'Customer identified/created');
// Create the ticket
const ticket = await zammad.ticket.create({
title,
group: "Users", // Default group - you may want to make this configurable
note: `This ticket was created automatically from Formstack form ${FormID}.`,
customer_id: customer.id,
article: {
body,
subject: title,
content_type: "text/html",
type: "note",
},
});
logger.info({
ticketId: ticket.id,
customerId: customer.id,
formId: FormID,
submissionId: UniqueID,
}, 'Zammad ticket created successfully');
} catch (error: any) {
logger.error({
error: error.message,
stack: error.stack,
output: error.output,
formId: FormID,
submissionId: UniqueID,
}, 'Failed to create Zammad ticket');
throw error;
}
};
export default createTicketFromFormTask;