# Müşteri Tarafı Talep Kancaları

https://dev.wisecp.com/tr/musteri-talep-kancalari

Müşterinin yaptıklarının sekiz kancası: açma, yanıtlama, kapatma ve puanlama.

## Genel Bakış

Müşterinin destek tarafında yapabildiği her şey burada: talep açmak, yanıt yazmak, kapatmak, yeniden açmak ve puanlamak.

Bu dalın kendine özgü zorluğu **kim yaptı** sorusudur. Alt kullanıcı başkasının hesabında işlem yapabilir, misafir hiçbir hesaba bağlı olmayabilir; kancalar bu yüzden hem hesabı hem giriş kimliğini ayrı taşır.

Aynı kancalar **WChat** canlı sohbet eklentisinden gelen mesajlarda da çalışır. Sohbetin ilk mesajı talep açar, sonraki mesajlar o talebe yanıt olarak eklenir. Sohbetin kapatılması ve puanlanması kapatma ve puanlama kancalarını çalıştırır. Sohbet talebinin dizisinde `WChat = 1` ve `WChat_domain` (sohbetin gömüldüğü site) bulunur. `filter:ticket.client_message` bağlamında `source = 'wchat'` gelir. Sohbet mesajlarına anında tepki veren bir entegrasyonun giriş noktası budur.

## Referans

### Müşterinin talep açmasını izleme

actionticket.opened_by_client

`ClientTickets` misafirde sıfır

Müşteri ya da posta yoluyla bir talep açıldığında çalışır.

Parametreler 4

$ticketAfterarrayOluşan taze talep kaydı.

$messagestringİlk mesaj, normalize edilmiş gövdesiyle.

$clientIdintTalebin sahibi. Posta yoluyla gelen **tanınmayan gönderici** için **sıfırdır**: hesap araması yapmadan kullanmayın.

$replyIdintİlk yanıt satırının kimliği.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:ticket.opened_by_client', 10,
    function ($ticketAfter, $message, $clientId, $replyId) {
        // Taninmayan gondericide SIFIR gelir.
        if (!$clientId) { Acme::queueIdentify($ticketAfter); return; }

        Acme::classify((int) ($ticketAfter['id'] ?? 0), $message);
    });
```

### Müşteri yanıtını durdurma

gateticket.reply_by_client

`ClientTickets` şekil kaynağa göre değişir

Müşteri bir talebe yanıt yazmadan önce çalışır. Panelden, posta yoluyla ve misafir bağlantısıyla gelen yanıtların hepsi buradan geçer.

Parametreler 5

$ticketarrayYanıtlanan talep. 🔴 **Şekli kaynağa göre değişir**: panelden gelenle posta yoluyla gelen aynı alanları taşımaz. Bir alana erişmeden önce varlığını sınayın.

$messagestringGönderilecek metin, düz metin hâliyle.

$ownerIdintTalebin sahibi hesap. **Misafirde sıfırdır.**

$loginIdintİşlemi yapan giriş kimliği. Alt kullanıcı başka hesabın talebini yanıtladıysa sahipten **farklıdır**; misafirde sıfırdır.

$isGuestboolMisafir bağlantısıyla mı geldiği.

Dönüş 1

string|null**Boş olmayan bir metin işlemi engeller** ve hata olarak gösterilir. Boş dönüş devam ettirir.

Dinleyici PHP

```php
Hook::add('gate:ticket.reply_by_client', 10,
    function ($ticket, $message, $ownerId, $loginId, $isGuest) {
        // Misafirde iki kimlik de SIFIR gelir.
        if ($isGuest && Acme::guestRepliesClosed()) return 'Misafir yanitlari kapali.';

        return null;
    });
```

### Müşteri yanıtını izleme

actionticket.reply_added_by_client

`ClientTickets` misafirde sıfır

Müşteri bir talebe yanıt yazdıktan sonra çalışır.

Parametreler 4

$ticketAfterarrayYanıt sonrası taze talep kaydı.

$messagestringEklenen mesaj.

$clientIdintYanıtı yazan; anonim posta yanıtında sıfır olabilir.

$replyIdintEklenen yanıtın kimliği.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:ticket.reply_added_by_client', 10,
    function ($ticketAfter, $message, $clientId, $replyId) {
        Acme::restartSlaClock((int) ($ticketAfter['id'] ?? 0));
    });
```

### Müşterinin talebi kapatmasını izleme

actionticket.closed_by_client

`ClientTickets` iki ayrı kimlik

Müşteri kendi talebini kapattığında çalışır.

Parametreler 3

$ticketarrayKapatma **öncesi** anlık görüntü.

$ownerIdintTalebin ait olduğu hesap.

$loginIdintİşlemi **gerçekten yapan** kimlik. Alt kullanıcı başka hesabın talebini kapattıysa bu ikisi farklıdır: denetim kaydına yazılacak olan budur.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:ticket.closed_by_client', 10, function ($ticket, $ownerId, $loginId) {
    // Denetime yazilacak olan LOGIN kimligidir.
    Acme::audit('ticket-closed', $loginId, $ownerId);
});
```

### Müşterinin talebi yeniden açmasını izleme

actionticket.reopened_by_client

`ClientTickets` iki ayrı kimlik

Müşteri kapanmış bir talebi yeniden açtığında çalışır.

Parametreler 3

$ticketarrayYeniden açma **öncesi** anlık görüntü.

$ownerIdintTalebin ait olduğu hesap.

$loginIdintİşlemi yapan giriş kimliği.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:ticket.reopened_by_client', 10, function ($ticket, $ownerId, $loginId) {
    Acme::restartSlaClock((int) ($ticket['id'] ?? 0));
});
```

### Puanlamayı izleme

actionticket.rated

`ClientTickets` iki kapsam

Müşteri bir talebi ya da tek bir personel yanıtını puanladığında çalışır. **İki ayrı kapsam** aynı kancaya düşer.

Parametreler 5

$scopestringNeyin puanlandığı: `ticket` ya da `reply`. İlk satırda buna bakın: iki kapsamın parametreleri farklı doludur.

$ratingintVerilen puan, birden beşe. Aralık dışı bir değer kancaya **hiç ulaşmaz**.

$ticketIdintTalebin kimliği; **her iki kapsamda da doludur**.

$replyIdintPuanlanan yanıt. Talep kapsamında **sıfırdır**.

$ownerIdintTalebin ait olduğu hesap.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:ticket.rated', 10,
    function ($scope, $rating, $ticketId, $replyId, $ownerId) {
        // Once kapsama bakin: yanit kimligi talep kapsaminda SIFIR.
        if ($scope === 'reply') { Acme::scoreAgent($replyId, $rating); return; }

        Acme::scoreTicket($ticketId, $rating);
    });
```

### Misafir görüntülemesini izleme

actionticket.guest.viewed

`ClientTickets` erişim değeri taşır

Giriş yapmamış biri bağlantıyla bir talebi görüntülediğinde çalışır.

Parametreler 2

$ticketarrayÇözülen talep. 🔴 İçinde **gönderenin adı, e-postası ve erişim değeri** bulunur. Erişim değerini gören herkes o talebi açabilir: kaydınıza ya da günlüğünüze yazmayın.

$tokenstringAdresten gelen erişim değeri, doğrulanmış hâliyle.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:ticket.guest.viewed', 10, function ($ticket, $token) {
    // Erisim degerini HICBIR YERE yazmayin.
    Acme::countGuestView((int) ($ticket['id'] ?? 0));
});
```

### Müşteri mesajını değiştirme

filterticket.client_message

`ClientTickets` bağla geçer

Müşterinin yazdığı metin kaydedilmeden önce çalışır. Hem yeni talep hem yanıt buradan geçer.

Parametreler 2

$messagestringbağlaMesaj gövdesi, düz metin hâliyle.

$ctxarrayBağlam: kaynağı, talep kimliği, hesap ve misafir olup olmadığı. Yeni talepte talep kimliği **sıfırdır**: talep henüz yoktur.

Dönüş 1

voidDönüş yoksayılır; verinin üzerine yazarsınız.

Dinleyici PHP

```php
Hook::add('filter:ticket.client_message', 10, function (&$message, $ctx) {
    // Yeni talepte talep kimligi SIFIR.
    $message = Acme::stripSecrets($message);
});
```

## Tuzaklar

> **Kapatılan sohbet talebi kapanış sonrası hâliyle gelir**
> 
> Müşteri bir WChat sohbetini kapattığında `action:ticket.closed_by_client` kapanıştan sonraki talep kaydını alır; `status` zaten `solved` gelir. Web paneli ve Client API kapanıştan önceki anlık görüntüyü verir. Eski durumu bu argümandan okumayın, kendi kaydınızla karşılaştırın. Misafir sohbette iki kimlik argümanı da `0` gelir.

> **Hesap ile giriş kimliği aynı şey değildir**
> 
> Kapatma, yeniden açma ve yanıt kancaları iki kimlik taşır: talebin **ait olduğu hesap** ve işlemi **gerçekten yapan** giriş. Alt kullanıcı başkasının hesabında çalışıyorsa bunlar farklıdır. Denetim kaydına giriş kimliği yazılır; yetki kararı hesaba göre verilir.

> **Misafir görüntüleme kancası erişim değeri taşır**
> 
> Talep verisinin içinde gönderenin adı, e-postası ve **erişim değeri** bulunur. O değeri gören herkes talebi açabilir: kendi kaydınıza, günlüğünüze ya da bir dış servise yazmak, bağlantıyı üçüncü bir yere kopyalamaktır.

## İlgili Makaleler

- Destek Talebi Kancaları
- [Müşteri Hesabı Kancaları](https://dev.wisecp.com/tr/musteri-hesabi-kancalari)
- [Kancalar Nasıl Çalışır](https://dev.wisecp.com/tr/kancalar-nasil-calisir)
