NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky
Tickets for Laravel

Odpovede a interné poznámky

Konverzácia tiketu je vlákno comments-for-laravel na tikete. Tickets zapisuje každú správu cez comments a pridáva blok meta vo vlastnom mennom priestore — vaše vlastné kľúče meta zostanú vedľa neho a kľúč hostiteľa nikdy nemôže podvrhnúť menný priestor tickets:

comment.meta.tickets = { internal: bool, role: 'agent'|'requester'|'participant'|'system', channel: string }

Správy sú koreňové komentáre (bez vnorených odpovedí): comments skryje z verejného vlákna všetko pod neviditeľným komentárom, takže verejná odpoveď pod poznámkou by zmizla.

Odpovede a poznámky

// A public reply — with an optional transition applied in the same transaction
$comment = Tickets::for($ticket)->by($agent)->reply('A technician is on the way.', transition: 'wait');
Tickets::for($ticket)->by($customer)->reply('Here is a photo.', attachments: [$request->file('photo')], channel: 'web');

// An internal note — agents only, never shown to the requester
Tickets::for($ticket)->by($agent)->note('Roller worn out, order a spare.');

// Model conveniences, through the manager
$ticket->reply('Thanks!', $customer);
$ticket->note('Escalated to vendor.', $agent);

// Edit and delete (scoped to the ticket; each left in the timeline)
Tickets::for($ticket)->by($agent)->editComment($comment, 'A technician is on the way (ETA 2 pm).');
Tickets::for($ticket)->by($agent)->deleteComment($comment);

// Read
Tickets::for($ticket)->thread();                 // public: published replies, oldest first
Tickets::for($ticket)->thread(internal: true);   // every message: notes and held replies too

reply() berie body, transition, attachments, channel, reason a payload (pre prechod) a meta; note() berie body, attachments, channel a meta. Obe vracajú Comment z comments. Kanál musí byť jeden z tickets.channels (predvolene tickets.default_channel).

AspektVerejná odpoveďInterná poznámka
visible v commentstruefalse — verejné čítania v comments ju nikdy neukážu
meta.tickets.internalfalsetrue — obrana do hĺbky: komentár označený ako interný sa tak berie, aj keď ho hostiteľ zviditeľnil
ktožiadateľ, agent, účastník, systémagenti a systém
aktivitareplied (verejná)note_added (interná; id komentára, nikdy text)
udalosťTicketReplied (s rolou)TicketNoteAdded
notifikáciareplied / requester_repliednote_added (len agenti)

Úpravy a mazanie

editComment() a deleteComment() konajú ako aktér handlu a zapíšu záznam aktivity comment_edited / comment_deleted — id komentára a rolu autora správy, nikdy text — s rovnakou viditeľnosťou ako správa: verejný pri zverejnenej verejnej odpovedi, interný pri poznámke či zadržanej odpovedi. TicketCommentUpdated / TicketCommentDeleted sa spustia po potvrdení. Kto smie upravovať či mazať, rozhoduje policy API (updateComment / deleteComment); PHP API sa nepýta.

Roly autorov

Určia sa pri odoslaní správy:

AutorRola
žiadateľ tiketurequester
agent pre tento tiket (oprávnenie agenta zúžené cez AgentScope)agent
sledujúci (pri tickets.watchers.can_view)participant
nikto (asSystem())system
ktokoľvek inýodmietnuté — TicketAccessDeniedException

Agent, ktorého rozsah agentov z tohto tiketu vylúči, tu agentom nie je: odpovedá ako sledujúci, ktorým je (účastník — bez pečiatky prvej odpovede a jeho odpoveď obnoví čakajúci tiket), alebo sa odmietne. Poznámka od kohokoľvek iného ako agenta pre tento tiket vyhodí TicketAccessDeniedException. Uzavretý tiket neprijme žiadnu správu — odpovede, poznámky, úpravy aj mazanie vyhodia TicketClosedException (v API 409 ticket_closed); namiesto toho založte nadväzujúci tiket.

Čo odpoveď spustí

  • Explicitné transition: sa uplatní atomicky — zamietnutý prechod nenechá žiadnu odpoveď — a nahradí automatizáciu odpovede. Uplatní sa, len keď sa odpoveď zverejní; pri zadržanej odpovedi sa jeho názov ani nekontroluje.
  • Automatizácie odpovedí (len odpovede žiadateľa alebo účastníka): čakajúci tiket sa obnoví (RequesterReplied); vyriešený tiket sa znovu otvorí (RequesterReopened), keď je zapnuté tickets.comments.reply_reopens.
  • Prvá odpoveď: prvá zverejnená verejná odpoveď agenta raz zaznamená first_responded_at a spustí TicketFirstResponded. Poznámky, odpovede žiadateľa a zadržané odpovede ju nikdy nezaznamenajú.
  • Automatické sledovanie: agent, ktorý napíše, začne tiket sledovať (tickets.watchers.auto.agent_repliers).
  • last_activity_at sa posunie pri každej odpovedi, poznámke, prechode a priradení. Posúva ho aj poznámka, preto je v API resources a radení len pre agentov a posun sa nikdy nedotkne updated_at.

Moderácia hostiteľa

Nastavenie hostiteľaÚčinok na odpoveď na tiket
comments.require_approval zapnutéHneď schválená (tickets.comments.auto_approve, predvolene zapnuté).
comments.require_approval zapnuté a tickets.comments.auto_approve vypnutéZadržaná pre moderátora.
zhoda s blocklistom s akciou pending / hiddenZadržaná — nikdy sa automaticky neschváli (obišlo by to filter hostiteľa).
zhoda s blocklistom s akciou rejectcomments vyhodí CommentRejectedException a celá odpoveď sa vráti späť (API 422 comment_rejected).

Zadržaná odpoveď nezmení nič okrem vlákna. Zostane viditeľná len pre agentov, jej aktivita replied je interná (held: true plus prechod, o ktorý žiadala) a neuplatní prechod, nespustí automatizáciu, nezaznamená prvú odpoveď, nespustí TicketReplied a nikoho neupovedomí — žiadateľ tak nikdy neuvidí zmenu stavu spôsobenú správou, ktorú nikto nemôže prečítať. Neskoršie schválenie cez comments správu len zverejní; ak prechod stále chcete, uplatnite ho sami.

Ručná moderácia zastaví tok čakanie → obnovenie: pri zapnutom comments.require_approval a vypnutom tickets.comments.auto_approve sa zadrží každá odpoveď a jej neskoršie schválenie nič nedobehne — čakajúci tiket zostane čakať, vyriešený sa znovu neotvorí, nikto nedostane notifikáciu a aktivita replied zostane interná. Zmienky z odpovede comments pri schválení doručí. Ak moderujete ručne, počúvajte CommentApproved z comments pre komentáre tiketov a spustite, čo potrebujete (Tickets::for($ticket)->resume(), notifikáciu riešiteľovi).

comments.authorization

Pri zapnutom comments.authorization (predvolene vypnuté) kontroluje comments vlastné Gate oprávnenia voči prihlásenému používateľovi pri každom príspevku, schválení, zamknutí a odomknutí — nie voči autorovi komentára. Odpovede hostí, systémové poznámky, poznámky zo zlúčenia, automatické schvaľovanie aj zamknutie pri automatickom uzavretí z plánovača potom závisia od vašej CommentPolicy a tickets:doctor upozorní. Vlastná policy balíka tickets už rozhodla, kto smie na tiket písať, preto komentované tikety pustite ďalej:

use Illuminate\Database\Eloquent\Model;
use RoundlyConsulting\Comments\Models\Comment;
use RoundlyConsulting\Comments\Policies\CommentPolicy;
use RoundlyConsulting\Tickets\Models\Ticket;

final class AppCommentPolicy extends CommentPolicy
{
    public function create(?Model $user, ?Model $commentable = null): bool
    {
        return $commentable instanceof Ticket || parent::create($user, $commentable);
    }

    public function moderate(?Model $user, Comment $comment): bool
    {
        return $comment->commentable instanceof Ticket || parent::moderate($user, $comment);
    }

    public function lock(?Model $user, Model $lockable): bool
    {
        return $lockable instanceof Ticket || parent::lock($user, $lockable);
    }

    public function unlock(?Model $user, Model $lockable): bool
    {
        return $lockable instanceof Ticket || parent::unlock($user, $lockable);
    }

    // update() / delete() the same way, if you edit ticket messages through comments
}

Zmienky

Comments rozpozná @handle a spustí CommentMentioned — len keď hostiteľ nastaví comments.mention_resolver, len pri schválenom komentári a raz na osobu. Tickets z toho urobí TicketMentioned len pre niekoho, kto smie daný komentár čítať: zmienka v poznámke zasiahne agentov, ktorým rozsah agentov povoľuje na tikete pracovať, zmienka v odpovedi vyžaduje prístup na zobrazenie. Notifikácia mentioned odíde, len ak danú osobu už nezasiahne notifikácia samotnej správy; pri zapnutom tickets.watchers.auto.mentioned začne spomenutý čitateľ tiket sledovať. Vaše vlastné listenery CommentMentioned / CommentCreated vidia aj interné poznámky — filtrujte v nich podľa meta.tickets.internal.

Prílohy správ

Prílohy odpovedí a poznámok sú prílohy komentárov: súkromná skupina príloh balíka comments na comments.media.private_disk, cez media-library. API ich servíruje cez krátkodobé podpísané URL a hosť si môže stiahnuť len súbory tiketu a jeho verejného vlákna.

Dopyty na vlákno cez comments

use RoundlyConsulting\Comments\Facades\Comments;

Comments::for($ticket)->whereMeta('tickets.role', 'requester')->get();
Comments::for($ticket)->whereMeta('tickets.internal', true)->get();   // the notes

Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

Ďalšie spôsoby podpory vrátane kryptomien

Odoslaním daru súhlasíte s našimi podmienkami prijímania darov.

Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.