Updates for real form
This commit is contained in:
parent
320b9c1b38
commit
f9ddc843be
2 changed files with 81 additions and 49 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
import { createLogger } from "@link-stack/logger";
|
import { createLogger } from "@link-stack/logger";
|
||||||
import { Zammad, getOrCreateUser } from "../../lib/zammad.js";
|
import { Zammad, getUser } from "../../lib/zammad.js";
|
||||||
|
|
||||||
const logger = createLogger('create-ticket-from-form');
|
const logger = createLogger('create-ticket-from-form');
|
||||||
|
|
||||||
|
|
@ -43,47 +43,29 @@ const createTicketFromFormTask = async (
|
||||||
? `${name.first || ''} ${name.last || ''}`.trim()
|
? `${name.first || ''} ${name.last || ''}`.trim()
|
||||||
: 'Unknown';
|
: 'Unknown';
|
||||||
|
|
||||||
// Build address string
|
// Get organization name from form data
|
||||||
let addressString = '';
|
const organizationName = type_of_organization || '';
|
||||||
if (address) {
|
|
||||||
const parts = [
|
// Build ticket title - matching ngo-isac-uploader pattern
|
||||||
address.address,
|
let title = fullName;
|
||||||
address.city,
|
if (organizationName) {
|
||||||
address.state,
|
title += ` - ${organizationName}`;
|
||||||
address.zip,
|
}
|
||||||
].filter(Boolean);
|
if (type_of_help_requested) {
|
||||||
addressString = parts.join(', ');
|
title += ` - ${type_of_help_requested}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build ticket title
|
// Build article body - only description and metadata
|
||||||
const title = `Help Request: ${type_of_help_requested || 'General'} - ${fullName}`;
|
// All other fields go into custom Zammad ticket fields
|
||||||
|
const body = description_of_issue
|
||||||
// Build ticket body with all form information
|
? `<p>${description_of_issue}</p>
|
||||||
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>
|
<hr>
|
||||||
<p><em>Form ID: ${FormID} | Submission ID: ${UniqueID} | Received: ${receivedAt}</em></p>`;
|
<p><em>Submitted via Formstack | Form ID: ${FormID} | Submission ID: ${UniqueID} | Received: ${receivedAt}</em></p>`
|
||||||
|
: `<p><em>No description provided</em></p>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<p><em>Submitted via Formstack | Form ID: ${FormID} | Submission ID: ${UniqueID} | Received: ${receivedAt}</em></p>`;
|
||||||
|
|
||||||
// Get Zammad configuration from environment
|
// Get Zammad configuration from environment
|
||||||
const zammadUrl = process.env.ZAMMAD_URL || 'http://zammad-nginx:8080';
|
const zammadUrl = process.env.ZAMMAD_URL || 'http://zammad-nginx:8080';
|
||||||
|
|
@ -97,29 +79,78 @@ const createTicketFromFormTask = async (
|
||||||
const zammad = Zammad({ token: zammadToken }, zammadUrl);
|
const zammad = Zammad({ token: zammadToken }, zammadUrl);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Get or create user based on phone number, Signal number, or email
|
// Get or create user based on contact info
|
||||||
|
// Priority: signal_number > phone_number > email_address
|
||||||
let customer;
|
let customer;
|
||||||
const contactInfo = signal_number || phone_number || email_address;
|
|
||||||
|
|
||||||
if (contactInfo) {
|
// Try to find existing user by phone or email
|
||||||
customer = await getOrCreateUser(zammad, contactInfo);
|
if (signal_number || phone_number) {
|
||||||
} else {
|
const phoneToSearch = signal_number || phone_number;
|
||||||
// Create user with just the name if no contact info
|
customer = await getUser(zammad, phoneToSearch);
|
||||||
|
if (customer) {
|
||||||
|
logger.info({ customerId: customer.id, method: 'phone' }, 'Found existing user by phone');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!customer && email_address) {
|
||||||
|
// Search by email if phone search didn't work
|
||||||
|
const emailResults = await zammad.user.search(`email:${email_address}`);
|
||||||
|
if (emailResults.length > 0) {
|
||||||
|
customer = emailResults[0];
|
||||||
|
logger.info({ customerId: customer.id, method: 'email' }, 'Found existing user by email');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!customer) {
|
||||||
|
// Create new user with all available contact information
|
||||||
|
logger.info('Creating new user from form submission');
|
||||||
customer = await zammad.user.create({
|
customer = await zammad.user.create({
|
||||||
firstname: name?.first,
|
firstname: name?.first || '',
|
||||||
lastname: name?.last,
|
lastname: name?.last || '',
|
||||||
|
email: email_address || `${UniqueID}@formstack.local`,
|
||||||
|
phone: signal_number || phone_number || '',
|
||||||
note: `User created from Formstack submission ${UniqueID}`,
|
note: `User created from Formstack submission ${UniqueID}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info({ customerId: customer.id, customerEmail: customer.email }, 'Customer identified/created');
|
logger.info({
|
||||||
|
customerId: customer.id,
|
||||||
|
customerEmail: customer.email,
|
||||||
|
customerPhone: customer.phone,
|
||||||
|
}, 'Customer identified/created');
|
||||||
|
|
||||||
// Create the ticket
|
// Build address parts
|
||||||
|
const streetAddress = address?.address || '';
|
||||||
|
const cityValue = address?.city || '';
|
||||||
|
const stateValue = address?.state || '';
|
||||||
|
const zipValue = address?.zip || '';
|
||||||
|
|
||||||
|
// Create the ticket with custom fields mapped to Zammad attributes
|
||||||
|
// Following the pattern from ngo-isac-uploader where all form data
|
||||||
|
// goes into structured fields rather than HTML body
|
||||||
const ticket = await zammad.ticket.create({
|
const ticket = await zammad.ticket.create({
|
||||||
title,
|
title,
|
||||||
group: "Users", // Default group - you may want to make this configurable
|
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,
|
customer_id: customer.id,
|
||||||
|
|
||||||
|
// Custom fields - these will be populated in Zammad's ticket attributes
|
||||||
|
// NOTE: 'organization', 'formstack_form_id', 'formstack_submission_id'
|
||||||
|
// fields could not be created due to naming conflicts, so metadata
|
||||||
|
// is included in the ticket body instead
|
||||||
|
signal_number: signal_number || undefined,
|
||||||
|
type_of_help_requested: type_of_help_requested || undefined,
|
||||||
|
type_of_organization: type_of_organization || undefined,
|
||||||
|
urgency_level: urgency_level || undefined,
|
||||||
|
city: cityValue || undefined,
|
||||||
|
us_state: stateValue || undefined,
|
||||||
|
zip_code: zipValue || undefined,
|
||||||
|
street_address: streetAddress || undefined,
|
||||||
|
preferred_contact_method: preferred_contact_method || undefined,
|
||||||
|
available_times: available_times_for_contact || undefined,
|
||||||
|
where_heard: how_did_you_hear_about_us || undefined,
|
||||||
|
preferred_language: preferred_language || undefined,
|
||||||
|
|
||||||
|
// Article with just the description
|
||||||
article: {
|
article: {
|
||||||
body,
|
body,
|
||||||
subject: title,
|
subject: title,
|
||||||
|
|
|
||||||
|
|
@ -33,4 +33,5 @@ services:
|
||||||
DATABASE_USER: ${DATABASE_USER}
|
DATABASE_USER: ${DATABASE_USER}
|
||||||
DATABASE_PASSWORD: ${DATABASE_PASSWORD}
|
DATABASE_PASSWORD: ${DATABASE_PASSWORD}
|
||||||
DATABASE_URL: ${DATABASE_URL}
|
DATABASE_URL: ${DATABASE_URL}
|
||||||
|
FORMSTACK_SHARED_SECRET: ${FORMSTACK_SHARED_SECRET}
|
||||||
LOG_LEVEL: debug
|
LOG_LEVEL: debug
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue