fix(syncro): omit contact_id by default; Syncro assigns primary automatically
Only set contact_id when ticket is opened by/regarding a named contact. Removed address_id, appointment_owner, and do_not_invite fields from the default gather step — these are edge cases, not routine inputs. Updated preview template to reflect default primary contact behavior. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -306,29 +306,23 @@ Collect in one pass (do not ask field by field):
|
||||
| 5 | **Do Not Email** | Suppress customer notification on ticket create? (yes for internal/reminder tickets) |
|
||||
| 6 | **Due Date** | ISO date |
|
||||
| 7 | **Assigned Tech** | Who owns the ticket. Defaults to API key owner if not specified (mike → 1735, howard → 1750). MUST always be included in the POST payload — never omit. |
|
||||
| 8 | **Contact** | Look up from `GET /customers/{id}` → `.contacts[]`; show list, ask user to pick |
|
||||
| 9 | **Address/Site** | `address_id` — also comes from customer contacts with address data |
|
||||
| 10 | **Appointment Type** | From table above; omit section if no appointment needed |
|
||||
| 11 | **Location** | Free text; usually blank unless onsite at non-primary address |
|
||||
| 12 | **Start Time** | ISO8601 datetime; omit if no scheduled appointment |
|
||||
| 13 | **End Time** | Default: start + 90 minutes |
|
||||
| 14 | **Appointment Owner** | Usually same as assigned tech; noted for calendar attribution (not a separate API field — inherits from ticket `user_id`) |
|
||||
| 15 | **Do Not Invite** | If not onsite, suppress calendar invite — note: not directly controllable via API; inform user if they need this set manually |
|
||||
| 16 | **Asset** | Search `GET /customer_assets?customer_id=N&query=<name>` if a specific device is involved |
|
||||
| 8 | **Contact** | Omit unless the ticket is opened by or specifically regarding a named contact. When omitted, Syncro assigns the customer's primary contact automatically. Only look up and set `contact_id` when the user names a specific person. |
|
||||
| 9 | **Appointment Type** | From table above; omit section if no appointment needed |
|
||||
| 10 | **Location** | Free text; usually blank unless onsite at non-primary address |
|
||||
| 11 | **Start Time** | ISO8601 datetime; omit if no scheduled appointment |
|
||||
| 12 | **End Time** | Default: start + 90 minutes |
|
||||
| 13 | **Asset** | Search `GET /customer_assets?customer_id=N&query=<name>` if a specific device is involved |
|
||||
|
||||
#### Step 2 — Look up customer data
|
||||
|
||||
Before showing the preview, fetch what you need:
|
||||
**Contact lookup (only when a specific contact is named):**
|
||||
|
||||
```bash
|
||||
# Get contacts and addresses
|
||||
curl -s "${BASE}/customers/${CUST_ID}?api_key=${API_KEY}" | jq '{contacts: [.customer.contacts[] | {id, name, address1, email}]}'
|
||||
|
||||
# Search assets
|
||||
curl -s "${BASE}/customer_assets?customer_id=${CUST_ID}&query=<name>&api_key=${API_KEY}" | jq '[.assets[] | {id, name, asset_type}]'
|
||||
curl -s "${BASE}/customers/${CUST_ID}?api_key=${API_KEY}" | \
|
||||
jq '[.customer.contacts[] | {id, name, email}]'
|
||||
```
|
||||
|
||||
#### Step 3 — Show preview and confirm
|
||||
Match by name, confirm with user, then include `contact_id` in the ticket POST. Never include `contact_id: null` — omit the field entirely when using the default.
|
||||
|
||||
#### Step 2 — Show preview and confirm
|
||||
|
||||
Display the full ticket before posting. Include all populated fields. Wait for explicit confirmation.
|
||||
|
||||
@@ -342,11 +336,10 @@ Priority: <priority>
|
||||
Description: <description>
|
||||
Due Date: <due_date>
|
||||
Assigned To: <tech name>
|
||||
Contact: <contact name>
|
||||
Address: <address>
|
||||
Contact: <primary — Syncro default> (or named contact if specified)
|
||||
Do Not Email: <yes/no>
|
||||
|
||||
APPOINTMENT
|
||||
APPOINTMENT (omit section if no appointment)
|
||||
-----------
|
||||
Type: <type name>
|
||||
Start: <start_at>
|
||||
@@ -358,7 +351,7 @@ ASSET: <asset name or none>
|
||||
Confirm? (yes/no)
|
||||
```
|
||||
|
||||
#### Step 4 — Execute (after confirmation)
|
||||
#### Step 3 — Execute (after confirmation)
|
||||
|
||||
**Call 1 — Create ticket:**
|
||||
|
||||
@@ -373,12 +366,7 @@ RESP=$(curl -s -X POST "${BASE}/tickets?api_key=${API_KEY}" \
|
||||
"status": "New",
|
||||
"priority": "2 Normal",
|
||||
"user_id": N,
|
||||
"due_date": "YYYY-MM-DD",
|
||||
"contact_id": N,
|
||||
"address_id": N,
|
||||
"start_at": "ISO8601",
|
||||
"end_at": "ISO8601",
|
||||
"asset_ids": [N]
|
||||
"due_date": "YYYY-MM-DD"
|
||||
}
|
||||
JSON
|
||||
)
|
||||
@@ -386,7 +374,7 @@ TICKET_ID=$(echo "$RESP" | jq -r '.ticket.id')
|
||||
CUST_ID=$(echo "$RESP" | jq -r '.ticket.customer_id')
|
||||
```
|
||||
|
||||
Omit null/blank fields from the payload before piping. The `'JSON'` quoting on the heredoc opener is required — it suppresses bash variable and backtick expansion inside, which matters when descriptions contain `$` (passwords, prices, regex, etc.).
|
||||
Omit `contact_id` unless a specific contact was named — Syncro assigns the primary automatically. Omit `asset_ids` unless an asset was identified. Omit `do_not_email` unless suppression was requested. Never include fields with null values. The `'JSON'` quoting on the heredoc suppresses `$` expansion inside the payload.
|
||||
|
||||
**Call 2 — Post initial description as "Initial Issue" comment:**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user