docfast-support: add needs-reply command, prevent duplicate replies

This commit is contained in:
Hoid 2026-02-16 20:41:33 +00:00
parent 5cce30d31c
commit 5dc184a33b
3 changed files with 61 additions and 1 deletions

View file

@ -146,6 +146,44 @@ async function cmdReply(args) {
}
}
async function cmdNeedsReply(args) {
// Show only tickets where the last non-note thread is from a customer (needs agent reply)
const page = getFlag(args, '--page') || '1';
let endpoint = `/conversations?page=${page}&status=active`;
if (MAILBOX_ID) endpoint += `&mailboxId=${MAILBOX_ID}`;
const res = await apiRequest('GET', endpoint);
if (res.status !== 200) { console.error('Error:', res.status, JSON.stringify(res.data)); process.exit(1); }
const conversations = res.data._embedded?.conversations || [];
if (conversations.length === 0) { console.log('No tickets need a reply.'); return; }
const needsReply = [];
for (const c of conversations) {
const tRes = await apiRequest('GET', `/conversations/${c.id}/threads`);
if (tRes.status !== 200) continue;
const threads = (tRes.data._embedded?.threads || [])
.filter(t => t.type !== 'note') // ignore internal notes
.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
if (threads.length === 0) continue;
const lastThread = threads[0];
// type 'customer' = from customer, 'message' = from agent
if (lastThread.type === 'customer') {
needsReply.push(c);
}
}
if (needsReply.length === 0) { console.log('No tickets need a reply.'); return; }
console.log('ID\tSUBJECT\tCUSTOMER\tCREATED');
for (const c of needsReply) {
const customer = c.customer?.email || c.customer?.firstName || 'unknown';
const created = c.createdAt?.split('T')[0] || '-';
console.log(`${c.id}\t${c.subject}\t${customer}\t${created}`);
}
console.log(`\n${needsReply.length} ticket(s) need a reply.`);
}
async function cmdClose(args) {
const id = args[0];
if (!id) { console.error('Usage: docfast-support close <ticket-id>'); process.exit(1); }
@ -195,6 +233,7 @@ const [cmd, ...args] = process.argv.slice(2);
const commands = {
tickets: cmdTickets,
'needs-reply': cmdNeedsReply,
view: cmdView,
reply: cmdReply,
close: cmdClose,
@ -209,6 +248,7 @@ Usage: docfast-support <command> [args]
Commands:
tickets [--status active|pending|closed|spam] List tickets (default: active)
needs-reply Tickets waiting for agent reply
view <ticket-id> View ticket with all messages
reply --ticket <id> --message "..." Send reply to customer
[--draft] Save as internal note instead

View file

@ -0,0 +1,20 @@
# DocFast Support Log
## 2026-02-16 20:17 UTC
**Ticket #369** - Lost API key
- Customer: dominik@superbros.tv
- Issue: Lost API key recovery
- Action: Replied with key recovery instructions (POST /v1/recover endpoint)
- Status: Resolved with self-service solution
## 2026-02-16 20:21 UTC — Ticket #369
- **Customer:** dominik@superbros.tv
- **Subject:** Lost API key
- **Action:** Replied with self-service recovery instructions (website link + API endpoint)
- **Status:** Replied, awaiting customer confirmation
## 2026-02-16 20:24 UTC
- **Ticket #369** (dominik@superbros.tv): Lost API key → Replied with recovery flow instructions. Simple case.
## 2026-02-16 20:27 UTC
- **Ticket #369** (dominik@superbros.tv): Lost API key → Replied with recovery flow instructions. Straightforward.

View file

@ -1 +1 @@
FAIL
OK