# Müşteri Hizmet ve Mesaj Kancaları

https://dev.wisecp.com/tr/musteri-hizmet-ve-mesaj-kancalari

Hizmet detayı ve toplu mesajın on üç kancası: modül paneli, eklentiler, paket değişimi, kullanım grafiği ve mesaj gönderimi.

## Genel Bakış

Müşterinin hizmet detayında gördüğü veri ve toplu mesaj gönderimi burada.

Hizmet filtrelerinin ortak deseni **görünürlük işaretidir**: bir bölümü gizlemek ile içini boşaltmak farklı sonuçlar verir. Mesaj tarafında ise her şey **parça** üzerinden hesaplanır; alıcı sayısı ücreti vermez.

## Referans

### Modül panelini değiştirme

filterclient.service_management_content

`ClientServices` ham işaretleme

Sunucu modülünün ürettiği panel müşteriye gösterilmeden önce çalışır. Uzak panelin çıktısına dokunmanın tek yeri burasıdır.

Parametreler 2

$contentstringbağlaModülün ürettiği **ham işaretleme**. ? Bu çıktı uzak sunucudan gelen değerleri taşıyabilir ve **kaçışsız** gösterilir. İçine dışarıdan bir değer eklerseniz kendiniz temizleyin.

$ctxarrayBağlam: hizmet kaydı ve istenen panel sayfası.

Dönüş 1

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

Dinleyici PHP

```php
Hook::add('filter:client.service_management_content', 10, function (&$content, $ctx) {
    // Cikti KACISSIZ gosterilir.
    if (($ctx['page'] ?? '') !== 'dashboard') return;

    $content .= '<div class="alert alert-info">Acme</div>';
});
```

### Eklenti listelerini değiştirme

filterclient.service_detail.addons

`ClientServices` iki liste

Hizmet detayındaki eklenti listeleri hazırlandıktan sonra çalışır. **İki ayrı liste** gelir: sahip olunanlar ve satın alınabilecekler.

Parametreler 3

$addonsOwnedarraybağlaHizmetin sahip olduğu eklentiler; etkin ve bekleyenler birlikte.

$addonsAvailablearraybağlaSatın alınabilecek eklenti teklifleri. Bir eklentiyi tekliflerden çıkarmak satın almayı da engeller: müşteri onu göremez.

$ctxarrayBağlam: hizmet kaydı ve hesap kimliği.

Dönüş 1

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

Dinleyici PHP

```php
Hook::add('filter:client.service_detail.addons', 10,
    function (&$addonsOwned, &$addonsAvailable, $ctx) {
        // Tekliflerden cikarmak satin almayi da engeller.
        $addonsAvailable = array_values(array_filter($addonsAvailable,
            fn ($a) => Acme::offerAllowed($a, $ctx['service'] ?? [])));
    });
```

### Paket değişimi kataloğunu değiştirme

filterclient.service_detail.upgrade_plans

`ClientServices` görünürlük işareti

Paket yükseltme ve düşürme seçenekleri hazırlandıktan sonra çalışır.

Parametreler 2

$updownarraybağlaPlan kataloğu ve durum işaretleri: görünürlük, plan listesi ve fiyatlar. Görünürlük işaretini kapatmak bölümü tümüyle gizler; plan listesini boşaltmak ise bölümü boş gösterir. İkisi farklı sonuçtur.

$ctxarrayBağlam: hizmet kaydı.

Dönüş 1

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

Dinleyici PHP

```php
Hook::add('filter:client.service_detail.upgrade_plans', 10, function (&$updown, $ctx) {
    // Gizlemek ile bosaltmak farkli sonuclardir.
    if (Acme::locked($ctx['service'] ?? [])) $updown['visible'] = false;
});
```

### Lisans devri bölümünü değiştirme

filterclient.service_detail.license_transfer

`ClientServices` ücret notu dâhil

Yazılım lisansının devir bölümü hazırlandıktan sonra çalışır.

Parametreler 2

$ltarraybağlaDevir verisi: görünürlüğü, kipi, bekleyen bir devir olup olmadığı, ücreti kimin ödediği ve ücret notu.

$ctxarrayBağlam: hizmet kaydı ve tipi.

Dönüş 1

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

Dinleyici PHP

```php
Hook::add('filter:client.service_detail.license_transfer', 10, function (&$lt, $ctx) {
    // Devredilemeyen lisansta bolumu hic gostermeyin.
    if (Acme::nonTransferable($ctx['service'] ?? [])) $lt['visible'] = false;
});
```

### Hizmet zaman çizelgesini değiştirme

filterclient.service_detail.activity

`ClientServices` zaman çizelgesi

Hizmetin geçmiş satırları ekrana gitmeden önce çalışır. Kendi olaylarınızı çekirdek geçmişin arasına koymanın yeri.

Parametreler 2

$activityarraybağlaZaman çizelgesi satırları.

$ctxarrayBağlam: hizmetin kimliği.

Dönüş 1

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

Dinleyici PHP

```php
Hook::add('filter:client.service_detail.activity', 10, function (&$activity, $ctx) {
    foreach (Acme::events((int) ($ctx['service_id'] ?? 0)) as $e) $activity[] = $e;
});
```

### Kullanım grafiğini değiştirme

filterclient.service_metric_chart

`ClientServices` boşluk için null

Metrik kullanım grafiğinin verisi hazırlandıktan sonra çalışır.

Parametreler 2

$chartarraybağlaGrafik verisi: gün etiketleri ve gün başına değerler. ? Veri olmayan günde değer **boş** gelir, sıfır değil: bunları sıfıra çevirmek grafiğe gerçekte olmayan bir düşüş koyar.

$ctxarrayBağlam: hizmet, metrik anahtarı ve grafiklenen ay.

Dönüş 1

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

Dinleyici PHP

```php
Hook::add('filter:client.service_metric_chart', 10, function (&$chart, $ctx) {
    // Veri olmayan gun BOS gelir: sifira cevirmeyin.
    $chart['acme_limit'] = Acme::planLimit($ctx['metric'] ?? '');
});
```

### Mesaj gönderimini durdurma

gateclient.sms_send

`ClientSms` gönderimden önce

Müşteri toplu mesaj göndermeden önce çalışır. Ücret hesaplanmış ama **henüz tahsil edilmemiştir**.

Parametreler 4

$uidintGönderen hesap.

$originstringGönderici kimliği.

$quotearrayGönderim özeti: alıcı sayısı, toplam tutar ve ülkeler.

$sendCtxarrayEk bağlam: liste, grup ve para birimi.

Dönüş 1

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

Dinleyici PHP

```php
Hook::add('gate:client.sms_send', 10, function ($uid, $origin, $quote, $sendCtx) {
    // Ucret hesaplandi ama HENUZ tahsil edilmedi.
    if ((int) ($quote['recipients'] ?? 0) > Acme::dailyCap($uid))
        return 'Gunluk gonderim sinirini asiyorsunuz.';

    return null;
});
```

### Mesaj gönderimini izleme

actionclient.sms_sent

`ClientSms` faturalanan gerçek

Toplu mesaj gönderildikten sonra çalışır.

Parametreler 4

$uidintGönderen hesap.

$originstringGönderici kimliği.

$quotearrayGönderimin özeti. Bu **faturalanan gerçektir**: alıcı sayısı, parça sayısı, uzunluk ve kodlama. Mesaj uzunsa parça sayısı alıcı sayısından fazladır; ücret parça üzerinden hesaplanır.

$sentCtxarrayBağlam: para birimi, gönderici kaydı, modül ve toplu gönderim numarası.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:client.sms_sent', 10, function ($uid, $origin, $quote, $sentCtx) {
    // Ucret PARCA uzerinden hesaplanir, alici sayisi uzerinden degil.
    Acme::recordUsage($uid, (int) ($quote['total_parts'] ?? 0));
});
```

### Gönderici kimliği eklemeyi durdurma

gateclient.sms_sender_add

`ClientSms` biçim doğrulanmış

Müşteri yeni bir gönderici kimliği eklemeden önce çalışır.

Parametreler 2

$uidintİsteği yapan hesap.

$namestringTalep edilen gönderici adı. Biçimi çoktan doğrulanmıştır: en fazla on bir harf ya da rakam, boşluksuz. Sizin denetiminiz **içeriğe** bakmalıdır, biçime değil.

Dönüş 1

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

Dinleyici PHP

```php
Hook::add('gate:client.sms_sender_add', 10, function ($uid, $name) {
    // Bicim zaten dogrulandi: icerige bakin.
    if (Acme::reservedBrand($name)) return 'Bu ad kullanilamaz.';

    return null;
});
```

### Gönderici kimliğinin eklenmesini izleme

actionclient.sms_sender_created

`ClientSms` eklendi, onaylanmadı

Yeni bir gönderici kimliği eklendikten sonra çalışır. **Eklenmiş olması kullanılabilir olduğu anlamına gelmez**: bazı ülkelerde ayrıca başvuru gerekir.

Parametreler 2

$uidintEkleyen hesap.

$originarrayOluşan kaydın özeti: kimliği ve adı.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:client.sms_sender_created', 10, function ($uid, $origin) {
    // Eklenmis olmasi kullanilabilir oldugu anlamina gelmez.
    Acme::noteSender($uid, $origin['name'] ?? '');
});
```

### Gönderici başvurusunu izleme

actionclient.sms_sender_requested

`ClientSms` ülke listesi

Gönderici kimliği için ön kayıt başvurusu yapıldıktan sonra çalışır.

Parametreler 3

$uidintBaşvuran hesap.

$originarrayGönderici kimliğinin özeti.

$codesarrayBaşvurulan ülkelerin kodları. İlk başvuruda birden çok ülke olabilir; yeniden başvuruda genellikle tek ülkedir. Her zaman **liste** gelir.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:client.sms_sender_requested', 10, function ($uid, $origin, $codes) {
    // Her zaman liste gelir.
    foreach ($codes as $iso) Acme::trackApplication($uid, $origin['name'] ?? '', $iso);
});
```

### Kişi içe aktarımını izleme

actionclient.sms_contacts_imported

`ClientSms` atlananlar ayrı

Müşteri kişi listesini içe aktardıktan sonra çalışır.

Parametreler 4

$uidintİçe aktarımı yapan hesap.

$importedintGerçekten yazılan kişi sayısı; **her zaman birden büyüktür**.

$skippedintGeçersiz ad ya da numara yüzünden atlanan satır sayısı. Otomatik atlanan başlık satırı bu sayıya **dâhil değildir**: kullanıcıya rapor verirken ikisini karıştırmayın.

$group_idintHedef grup; **sıfır** ise kişiler grupsuz kaydedilmiştir.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:client.sms_contacts_imported', 10,
    function ($uid, $imported, $skipped, $group_id) {
        // Baslik satiri atlananlara dahil degil.
        if ($skipped > 0) Acme::warnImportQuality($uid, $imported, $skipped);
    });
```

### Ülke fiyat tablosunu değiştirme

filterclient.sms_rate

`ClientSms` parça başına

Müşteriye gösterilen ülke fiyatları hazırlandıktan sonra çalışır.

Parametreler 2

$outarraybağlaÜlke karşılık fiyat tablosu; her ülke için ücret ve ön kayıt gerekip gerekmediği. ? Ücret **parça başınadır**, mesaj başına değil: uzun bir mesaj birden çok parçaya bölünür ve o kadar ücretlendirilir.

$ctxarrayBağlam: fiyatların çözüldüğü para birimi.

Dönüş 1

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

Dinleyici PHP

```php
Hook::add('filter:client.sms_rate', 10, function (&$out, $ctx) {
    // Ucret PARCA basinadir.
    foreach ($out as $iso => $row)
        $out[$iso]['rate'] = Acme::applyMargin((float) ($row['rate'] ?? 0));
});
```

## Tuzaklar

> **Grafikte boş gün sıfır değildir**
> 
> Kullanım grafiğinde veri toplanmamış bir gün **boş** gelir. Bunu sıfıra çevirmek grafiğe gerçekte yaşanmamış bir düşüş koyar ve müşteriye yanlış bir kullanım tablosu gösterir. Boşluğu boş bırakın.

> **Mesaj ücreti parça başınadır**
> 
> Uzun bir mesaj birden çok parçaya bölünür ve **her parça ayrı ücretlendirilir**. Alıcı sayısını maliyet sanan bir hesap, uzun mesajlarda gerçek tutarın çok altında kalır. Gönderim özetindeki parça sayısını kullanın.

## İlgili Makaleler

- [Hizmet Kancaları](https://dev.wisecp.com/tr/hizmet-yasam-dongusu-kancalari)
- [Müşteri Panel Verisi Kancaları](https://dev.wisecp.com/tr/musteri-panel-verisi-kancalari)
- [Müşteri Sitesi Kancaları](https://dev.wisecp.com/tr/musteri-sitesi-kancalari)
