Add /syncro command — Syncro PSA ticket management
Create, update, close, comment on, search, and bill tickets via Syncro REST API. Includes customer search, invoice creation, line items, and ticket timer management. API key from SOPS vault. Verified: pulls real ticket data from computerguru.syncromsp.com. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
145
.claude/commands/syncro.md
Normal file
145
.claude/commands/syncro.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# /syncro — Syncro PSA ticket management
|
||||
|
||||
Create, update, close, comment on, and bill tickets in Syncro PSA.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/syncro Show open tickets summary
|
||||
/syncro ticket <number> View ticket details + comments
|
||||
/syncro create <customer> <subject> Create new ticket
|
||||
/syncro update <number> <status> Update ticket status
|
||||
/syncro close <number> Close/resolve a ticket
|
||||
/syncro comment <number> <text> Add a comment to a ticket
|
||||
/syncro bill <number> Create invoice from ticket time entries
|
||||
/syncro search <query> Search tickets by subject/customer
|
||||
/syncro customers <query> Search customers
|
||||
```
|
||||
|
||||
## API Configuration
|
||||
|
||||
**Base URL:** `https://computerguru.syncromsp.com/api/v1`
|
||||
**API Key:** SOPS vault `msp-tools/syncro.sops.yaml` → `credentials.credential`
|
||||
**Rate limit:** 180 requests/minute per IP
|
||||
**Docs:** https://api-docs.syncromsp.com/
|
||||
|
||||
## Implementation
|
||||
|
||||
When invoked, use the Syncro REST API via `curl`. All requests include `?api_key=<key>` as query parameter (NOT in header — Syncro uses query param auth).
|
||||
|
||||
### Get API key
|
||||
|
||||
```bash
|
||||
API_KEY=$(bash D:/vault/scripts/vault.sh get-field msp-tools/syncro.sops.yaml credentials.credential)
|
||||
BASE="https://computerguru.syncromsp.com/api/v1"
|
||||
```
|
||||
|
||||
If `vault.sh get-field` fails (yq not installed), fall back to:
|
||||
```bash
|
||||
API_KEY=$(sops -d D:/vault/msp-tools/syncro.sops.yaml | python -c "import sys,yaml; print(yaml.safe_load(sys.stdin)['credentials']['credential'])")
|
||||
```
|
||||
|
||||
### Endpoints reference
|
||||
|
||||
#### Tickets
|
||||
|
||||
| Operation | Method | Endpoint | Body |
|
||||
|---|---|---|---|
|
||||
| List tickets | GET | `/tickets?status=<status>&per_page=25` | — |
|
||||
| Get ticket | GET | `/tickets/<id>` | — |
|
||||
| Create ticket | POST | `/tickets` | `{"customer_id": N, "subject": "...", "problem_type": "...", "status": "New"}` |
|
||||
| Update ticket | PUT | `/tickets/<id>` | `{"status": "In Progress", "priority": "..."}` |
|
||||
| Delete ticket | DELETE | `/tickets/<id>` | — |
|
||||
|
||||
**Ticket statuses:** `New`, `In Progress`, `Waiting on Customer`, `Waiting on Vendor`, `Scheduled`, `Resolved`, `Invoiced`, `Closed`
|
||||
|
||||
**Ticket fields (create/update):**
|
||||
- `customer_id` (required for create)
|
||||
- `subject` (required for create)
|
||||
- `problem_type` (string, free-form)
|
||||
- `status` (string, one of the statuses above)
|
||||
- `priority` (string)
|
||||
- `due_date` (ISO date)
|
||||
- `user_id` (assign to tech)
|
||||
- `contact_id` (customer contact)
|
||||
- `ticket_type_id` (ticket category)
|
||||
|
||||
#### Comments
|
||||
|
||||
| Operation | Method | Endpoint | Body |
|
||||
|---|---|---|---|
|
||||
| Add comment | POST | `/tickets/<id>/comment` | `{"subject": "Update", "body": "...", "hidden": false, "do_not_email": false}` |
|
||||
|
||||
**Comment fields:**
|
||||
- `subject` — comment header (e.g., "Update", "Resolution", "Internal Note")
|
||||
- `body` — comment text (HTML supported)
|
||||
- `hidden` — if true, internal-only (customer can't see)
|
||||
- `do_not_email` — if true, don't email customer about this comment
|
||||
|
||||
#### Customers
|
||||
|
||||
| Operation | Method | Endpoint |
|
||||
|---|---|---|
|
||||
| List/search | GET | `/customers?query=<search>&per_page=25` |
|
||||
| Get customer | GET | `/customers/<id>` |
|
||||
| Create customer | POST | `/customers` |
|
||||
|
||||
#### Invoices
|
||||
|
||||
| Operation | Method | Endpoint | Body |
|
||||
|---|---|---|---|
|
||||
| List invoices | GET | `/invoices?per_page=25` |
|
||||
| Get invoice | GET | `/invoices/<id>` |
|
||||
| Create from ticket | POST | `/invoices` | `{"ticket_id": N, "customer_id": N}` |
|
||||
|
||||
#### Line Items
|
||||
|
||||
| Operation | Method | Endpoint | Body |
|
||||
|---|---|---|---|
|
||||
| Add line item | POST | `/line_items` | `{"invoice_id": N, "item": "...", "quantity": 1, "price": 125.00}` |
|
||||
|
||||
#### Ticket Timers
|
||||
|
||||
| Operation | Method | Endpoint |
|
||||
|---|---|---|
|
||||
| List | GET | `/ticket_timers?ticket_id=<id>` |
|
||||
| Create | POST | `/ticket_timers` |
|
||||
|
||||
### Display formatting
|
||||
|
||||
When showing ticket lists, format as:
|
||||
|
||||
```
|
||||
#32164 New Jerry Burger Own cloud thing again
|
||||
#32163 New LeeAnn Parkinson Remote - Jim cant access his email
|
||||
#32162 Invoiced Len's Auto Brokerage Server upgrade
|
||||
```
|
||||
|
||||
When showing ticket detail, include:
|
||||
- Ticket number, subject, status, priority
|
||||
- Customer name + contact
|
||||
- Created date, due date, last updated
|
||||
- Assigned tech
|
||||
- Comments (most recent first, truncated to last 5)
|
||||
- Time entries if any
|
||||
- Billing status
|
||||
|
||||
### Billing workflow
|
||||
|
||||
When `/syncro bill <number>` is called:
|
||||
1. Get ticket details + time entries
|
||||
2. Show summary: total billable time, line items that would be created
|
||||
3. Ask for confirmation: "Create invoice for $X? [yes/no]"
|
||||
4. On yes: POST `/invoices` with ticket_id, then add line items
|
||||
5. Update ticket status to "Invoiced"
|
||||
|
||||
### Error handling
|
||||
|
||||
- 401: API key invalid or expired
|
||||
- 404: ticket/customer/invoice not found
|
||||
- 422: validation error (show the error message from response body)
|
||||
- 429: rate limited (wait 60s and retry)
|
||||
|
||||
### Integration with session logs
|
||||
|
||||
When closing a ticket (`/syncro close`), offer to create a session log entry in `clients/<customer>/session-logs/` documenting what was resolved. Pull the ticket subject, comments, and resolution into a structured log.
|
||||
Reference in New Issue
Block a user