feat(discord): Ticket-Threads mit bidirektionaler Synchronisierung
Zweiter Teil des Discord-Ausbaus. Hat ein Kunde sein Konto verknüpft (siehe vorheriger Commit), bekommt sein Ticket automatisch einen privaten Thread im konfigurierten Ticket-Kanal: - Neuer Job discord.ticket_sync: legt den Thread beim ersten Bedarf an (Name "ticket-<Nummer>", Kunde wird als Mitglied hinzugefügt) und postet dort jede neue, nicht-interne Nachricht (sowohl Kunden- als auch Personal-Antworten). Wird von /tickets (Erstellung durch Kunden) und /tickets/:id/messages (Antworten, keine internen Notizen) ausgelöst. - Umgekehrte Richtung: Antwortet der Kunde direkt im Thread, übernimmt ein neuer messageCreate-Listener im Bot die Nachricht als Ticket-Antwort – nur wenn der Absender über discord_user_id eindeutig als Mitglied der Organisation des Tickets verifiziert ist. Personal-Nachrichten im Thread werden bewusst nicht übernommen (Web- Oberfläche bleibt die Quelle für Personal-Antworten, kein Echo). - Dafür nötig: privilegierte Message Content Intent (war in der Anleitung aus dem vorigen Schritt schon vermerkt). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
fcbd34b0c6
commit
1cd1a8b03a
3 changed files with 54 additions and 5 deletions
|
|
@ -73,6 +73,7 @@ export const ticketsModule: KcModule = {
|
|||
if (!staff) {
|
||||
await notify('ticket.created', { number, subject: b.subject.slice(0, 100) }, `ticket.created:${id}`, req.correlationId);
|
||||
await mailTo(a.user.email, 'ticket_created', { name: a.user.name, number, subject: b.subject, ticketLink: ticketLink(id) }, `mail:ticket.created:${id}`, req.correlationId);
|
||||
await enqueue('discord.ticket_sync', { ticketId: id, body: b.body, authorLabel: 'Kunde' }, { idempotencyKey: `discord:ticket.created:${id}`, correlationId: req.correlationId });
|
||||
}
|
||||
return { id, number, messageId };
|
||||
});
|
||||
|
|
@ -118,6 +119,7 @@ export const ticketsModule: KcModule = {
|
|||
});
|
||||
await audit({ actorType: 'user', actorId: a.user.id, orgId: t.org_id, action: 'ticket.message', resourceType: 'ticket', resourceId: id, correlationId: req.correlationId, ip: clientIp(req), after: { internalNote: b.internalNote } });
|
||||
if (!b.internalNote && !staff) await notify('ticket.message', { number: t.number }, `ticket.message:${id}:${Date.now()}`, req.correlationId);
|
||||
if (!b.internalNote) await enqueue('discord.ticket_sync', { ticketId: id, body: b.body, authorLabel: staff ? 'Support' : 'Kunde' }, { idempotencyKey: `discord:ticket.message:${messageId}`, correlationId: req.correlationId });
|
||||
let emailed = false;
|
||||
if (!b.internalNote && staff && b.notifyEmail) {
|
||||
const creator = await one('SELECT email, name FROM users WHERE id = ?', [t.created_by]);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue