TristamTech

Disclaimer: This repository documents the architecture and problem-solving approach behind systems independently designed and built by the author. It contains no proprietary source code, API keys, credentials, employer branding, or real user/organizational data. Screenshots are illustrative proof-of-concept only. Systems built using employer infrastructure (Jamf Pro) are documented here as a record of skill and handover-ready design, not a claim of personal ownership over the deployed instance.

๐ŸŽซ Native IT Support Ticket Form (SwiftDialog + Dual API)

A zero-training, native macOS ticket form that replaces โ€œemail IT and hopeโ€ โ€” submitting simultaneously to a helpdesk platform and a live ops Slack channel, with built-in anti-spam cooldown.

๐Ÿ“ Fields ๐Ÿ”€ Destinations โณ Resubmit Cooldown
4 2 (Helpdesk API + Slack) 15 min

IT Contact Form

๐Ÿ“– Executive Summary

Users click one menu item, fill a native form (category, name, contact, issue description), and the submission lands simultaneously in a helpdesk queue (for tracking/SLA) and a live Slack channel (for ops visibility) โ€” with no possibility of a user accidentally double-submitting the same ticket.

๐Ÿ—๏ธ Architecture

User clicks "Contact IT"
        โ”‚
        โ–ผ
Cooldown check (/var/tmp/xxx_ticket_cooldown.txt)
        โ”‚  exists? โ†’ block, "please wait 15 minutes"
        โ–ผ  not exists
SwiftDialog form (radio category + 3 text fields + rich text editor)
        โ”‚
        โ–ผ
Sanitize input (strip quotes, trim whitespace, sed off UI artifacts)
        โ”‚
        โ”œโ”€โ”€โ–ถ Helpdesk REST API (ticket created, routed to correct group)
        โ””โ”€โ”€โ–ถ Slack Block Kit payload (formatted card, ops visibility)
        โ”‚
        โ–ผ
Drop cooldown token + detached 15-min auto-expiry timer
        โ”‚
        โ–ผ
Native confirmation dialog

Dead ends that shaped the final design:

Problem What broke Fix
Dependency on swiftDialog being pre-installed Fresh Macs have no binary Script self-bootstraps: pulls the latest release asset URL from the GitHub API rather than hardcoding a versioned filename
swiftDialog radio buttons Silently appends a hidden index to the label (Software 1 not Software), breaking both downstream APIs Caught only via exec > /tmp/log 2>&1 diagnostic logging; sanitized with sed/awk before either payload builds
Repeat/accidental submissions Same ticket lands in the queue twice Cooldown token + detached 15-min self-deleting timer (same pattern as the SwiftBar trapdoor)

๐Ÿ“ค Payload A โ€” Helpdesk API (sanitized)

cat <<EOF > /tmp/helpdesk_payload.json
{
  "description": "$ticketBody",
  "subject": "Self Service Request: $issueCat",
  "email": "$userContact",
  "priority": 2,
  "status": 2,
  "type": "$issueCat",
  "group_id": [GROUP_ID_PLACEHOLDER]
}
EOF
curl -s -u "${apiKey}:X" -H "Content-Type: application/json" \
  -d @/tmp/helpdesk_payload.json -X POST "https://[org].example.com/api/v2/tickets"

๐Ÿ“ค Payload B โ€” Slack Block Kit (sanitized)

cat <<EOF > /tmp/slack_payload.json
{
  "blocks": [
    { "type": "header", "text": { "type": "plain_text", "text": "Incoming IT Support Request" } },
    { "type": "section", "fields": [
        { "type": "mrkdwn", "text": "*User:*\n$userName" },
        { "type": "mrkdwn", "text": "*Contact:*\n$userContact" } ] },
    { "type": "section", "text": { "type": "mrkdwn", "text": "*Issue:*\n> $userIssue" } }
  ]
}
EOF
curl -s -X POST -H 'Content-type: application/json' \
  -d @/tmp/slack_payload.json "[SLACK_WEBHOOK_URL_PLACEHOLDER]"

Slack Notification

๐Ÿ› ๏ธ Tech Stack

SwiftDialog ยท bash ยท Helpdesk REST API ยท Slack Block Kit / Incoming Webhooks ยท Jamf Pro

๐Ÿ“‚ Repository Structure

it-contact-form/
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ screenshots/
โ”‚   โ”œโ”€โ”€ IT_Contact_Form.png
โ”‚   โ””โ”€โ”€ Slack_Notification.png
โ””โ”€โ”€ scripts/
    โ””โ”€โ”€ it_contact_form.sh