# Bildirim Kancaları

https://dev.wisecp.com/tr/bildirim-kancalari

Müşteriye giden her mesajın on iki kancası: gönderim kapısı, alıcı listesi, değişkenler ve teslim.

## Genel Bakış

Bir bildirim **iki kapıdan** geçer. Birincisi gönderimin kendisini durdurur: hiç kimseye gitmez. İkincisi **tek bir teslimi** durdurur: diğer alıcılar mesajı yine alır.

Arada alıcı listesi ve değişkenler vardır. Değişken filtresi **alıcı başına** çalışır, yani aynı bildirim herkese farklı içerikle gidebilir.

## Referans

### Gönderimin tamamını durdurma

gatenotification.dispatch

`Notification::dispatch()` dönüş sözleşmesi farklı

Bildirim hazırlanmadan önce çalışır. Durdurmak, mesajın **hiç kimseye** gitmemesi demektir.

Parametreler 3

$groupstringBildirim grubu: fatura, hizmet, sipariş, alan adı, destek.

$namestringBildirim anahtarı: `invoice-created`, `welcome` ve benzerleri. Bu, gerçekten gönderilen şablondur; çağıranın istediği ad olmayabilir. E-posta aktarımıyla açılan talepte `ticket-replied-by-admin` buraya `ticket-replied-by-admin-pipe` olarak gelir. Alıcı, değişken ve dispatched kancaları da aynı adı görür. Talep şablonunu adıyla süzen dinleyici iki adı da tanımalıdır. Müşterinin zil kaydı istenen adla yazılır.

$contextarrayHam bağlam: ilgili kayıt kimlikleri, ek parametreler, elle eklenen alıcılar, zorlanan kanallar.

Dönüş 1

mixed**Boş olmayan herhangi bir dönüş** gönderimi durdurur — `true` bile yeter. Diğer kapıların aksine burada **metin şartı yoktur**; yanlışlıkla bir değer döndürmek bildirimi sessizce keser.

Dinleyici PHP

```php
Hook::add('gate:notification.dispatch', 10, function ($group, $name, $context) {
    // DIKKAT: bos olmayan HER donus gonderimi durdurur, true bile.
    if ($name === 'invoice-reminder' && Acme::quietHours()) return true;

    return null;
});
```

### Alıcı listesini değiştirme

filternotification.recipients

`Notification` kanal başına satır

Alıcılar belirlendikten sonra, mesajlar hazırlanmadan önce çalışır.

Parametreler 3

$recipientsarrayrefAlıcı kayıtları: kanal, hesap, adres, ad, kopya adresi, dil. Aynı kişi **birden çok satırda** olabilir: e-posta ve kısa mesaj ayrı satırlardır.

$groupstringBildirim grubu: fatura, hizmet, sipariş, alan adı, destek.

$namestringBildirim anahtarı: `invoice-created`, `welcome` ve benzerleri.

Dönüş 1

voidDeğer **referansla** değişir; dönüş kullanılmaz.

Dinleyici PHP

```php
Hook::add('filter:notification.recipients', 10,
    function (&$recipients, $group, $name) {
        // Ayni kisi e-posta ve SMS icin AYRI satirdadir: kanala gore suzun.
        if ($name === 'invoice-created')
            $recipients = array_filter($recipients,
                fn ($r) => ($r['channel'] ?? '') !== 'sms');
    });
```

### Şablon değişkenlerini değiştirme

filternotification.render_variables

`Notification` alıcı başına çalışır

Mesaj metni üretilmeden önce, **her alıcı için ayrı ayrı** çalışır.

Parametreler 4

$variablesarrayrefBu alıcıya özel değişken seti. Şablondaki yer tutucular buradan doldurulur.

$groupstringBildirim grubu: fatura, hizmet, sipariş, alan adı, destek.

$namestringBildirim anahtarı: `invoice-created`, `welcome` ve benzerleri.

$recipientarrayAktif alıcı: kanal, dil, hesap, adres. Dil alanı önemlidir: metni onun diline göre üretin.

Dönüş 1

voidDeğer **referansla** değişir; dönüş kullanılmaz.

Dinleyici PHP

```php
Hook::add('filter:notification.render_variables', 10,
    function (&$variables, $group, $name, $recipient) {
        // ALICI BASINA calisir: metni onun diline gore uretin.
        $variables['acme_note'] = Acme::note($recipient['lang'] ?? 'en');
    });
```

### Tek bir teslimi durdurma

gatenotification.deliver

`Notification` mesaj hazır

Hazırlanmış mesaj gönderilmeden hemen önce çalışır. Durdurmak **yalnız bu teslimi** keser.

Parametreler 1

$itemarrayTeslim edilecek öğe: kanal, hesap, adres, ad, kopya, konu, gövde, ekler, gerekçe. Metin ve ekler **hazırdır**: son kontrolü burada yaparsınız.

Dönüş 1

stringBoş olmayan bir string **bu teslimi** durdurur; diğer alıcılar mesajı yine alır.

Dinleyici PHP

```php
Hook::add('gate:notification.deliver', 10, function ($item) {
    // YALNIZ bu teslimi durdurur: digerleri gitmeye devam eder.
    if (Acme::bounced($item['recipient'] ?? '')) return 'adres gecersiz';

    return null;
});
```

### Gönderimi izleme

actionnotification.dispatched

`Notification` tek dizi parametre

Bildirim gönderildikten sonra çalışır.

Parametreler 1

$payloadarrayTek dizi: grup, ad, hesap, değişkenler, toplu gönderim kimliği. Toplu kimlik aynı gönderimin **bütün mesajlarını** bir araya bağlar.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:notification.dispatched', 10, function ($payload) {
    // batch_id ayni gonderimin tum mesajlarini birbirine baglar.
    Acme::trackBatch($payload['batch_id'] ?? '', $payload['name'] ?? '');
});
```

### Şablon alanlarını genişletme

filternotification.template_merge_fields

`AdminNotifications` operatöre gösterilen liste

Şablon düzenleme ekranında kullanılabilir alanlar listelenirken çalışır.

Parametreler 1

$fieldsarrayrefOperatöre gösterilen alan listesi. Buraya alan eklemek onu **listede gösterir**; değeri üretmek için değişken filtresini de yazmanız gerekir.

Dönüş 1

voidDeğer **referansla** değişir; dönüş kullanılmaz.

Dinleyici PHP

```php
Hook::add('filter:notification.template_merge_fields', 10, function (&$fields) {
    // Listeye eklemek DEGERI uretmez: render_variables filtresini de yazin.
    $fields['acme_note'] = 'Acme notu';
});
```

### Fatura eki adını değiştirme

filternotification.invoice_pdf_name

`Notification` dosya adı

Fatura belgesi bildirime eklenirken çalışır.

Parametreler 1

$namestringrefEk dosyanın adı. Müşterinin bilgisayarında görünecek addır; dosya sistemi için **güvenli karakterler** kullanın.

Dönüş 1

voidDeğer **referansla** değişir; dönüş kullanılmaz.

Dinleyici PHP

```php
Hook::add('filter:notification.invoice_pdf_name', 10, function (&$name) {
    $name = Acme::safeFileName($name);
});
```

### Şablon etiketini değiştirme

filternotification.template_label

`AdminNotifications` panelde görünür

Bildirim şablonunun panelde görünen adı belirlenirken çalışır.

Parametreler 1

$labelstringrefŞablonun görünen adı. Yalnız operatör görür; müşteriye giden metni etkilemez.

Dönüş 1

voidDeğer **referansla** değişir; dönüş kullanılmaz.

Dinleyici PHP

```php
Hook::add('filter:notification.template_label', 10, function (&$label) {
    $label = Acme::prefixLabel($label);
});
```

### Fatura kalemlerini değiştirme

filternotification.invoice_items

`Notification::build_items` döndürerek değiştirir

Fatura bildiriminin kalem listesi şablona gitmeden önce çalışır. Kalem ekleyebilir, çıkarabilir, sıralayabilir veya her kaleme kendi alanınızı koyabilirsiniz.

Parametreler 3

$resultarrayŞablona hazırlanmış kalemler. Değiştirdiğiniz liste budur.

$invoicearrayFaturanın kendisi.

$itemsarrayHam kalemler, veritabanından geldiği hâliyle. Hazırlanmış listede kaybolan bir alanı buradan geri alabilirsiniz.

Dönüş 1

array|nullBir dizi döndürürseniz listenin **tamamının yerine geçer**. Tuzak: birkaç dinleyici varsa en son dönen kazanır, öncekinin eklediği kaybolur. Eklemek istiyorsanız gelen listeyi alıp üzerine koyun, sıfırdan liste kurmayın.

Dinleyici PHP

```php
Hook::add('filter:notification.invoice_items', 10, function ($result, $invoice, $items) {
    // Gelen listeyi koruyun: sifirdan kurarsaniz oncekinin eklediklerini silersiniz.
    foreach ($result as $i => $line)
        $result[$i]['acme_note'] = Acme::noteFor($line['id'] ?? 0);

    return $result;
});
```

### Sipariş kalemlerini değiştirme

filternotification.order_items

`Notification::build_order_items` döndürerek değiştirir

Sipariş bildiriminin kalem listesi için aynı iş. Adet birden çoksa kalemler çoktan ayrılmış, ek ürünler çoktan yüklenmiş hâlde gelir.

Parametreler 2

$itemsarrayŞablona hazırlanmış kalemler.

$orderarraySiparişin kendisi, ham kalem verisi içinde.

Dönüş 1

array|nullDizi döndürürseniz listenin tamamının yerine geçer; başka bir şey döndürürseniz yoksayılır.

Dinleyici PHP

```php
Hook::add('filter:notification.order_items', 10, function ($items, $order) {
    // Ic kullanim kalemlerini musteriye gosterme.
    return array_values(array_filter($items, fn ($x) => ($x['name'] ?? '') !== 'internal'));
});
```

### Gönderim kaydını maskeleme

filternotification.log_entry

`LogManager` bağla geçer kişisel veri

Bir e-posta ya da SMS kaydı veritabanına yazılmadan hemen önce çalışır. Kişisel veriyi maskelemenin, hatta kaydı hiç tutmamanın yeri burasıdır.

Parametreler 1

$entryarraybağlaYazılacak kayıt. Ortak alanlar: `channel` (mail ya da sms), `user_id`, `reason`, `content`, `data`, `private`. E-postada ayrıca `subject` bulunur.

Dönüş 1

voidDönüş yoksayılır; değişikliği dizinin üzerine yazarak yaparsınız. `$entry['abort'] = true` koyarsanız kayıt **hiç yazılmaz** ve sayaç sıfır döner. Gönderim yine de yapılır, yalnız izi tutulmaz.

Dinleyici PHP

```php
Hook::add('filter:notification.log_entry', 10, function (&$entry) {
    // Parola sifirlama gonderiminin govdesini hic saklama.
    if (($entry['reason'] ?? '') === 'password-reset') {
        $entry['content'] = '[maskelendi]';
        return;
    }

    // Pazarlama SMS'i icin kayit hic acilmasin.
    if (($entry['channel'] ?? '') === 'sms' && ($entry['reason'] ?? '') === 'campaign')
        $entry['abort'] = true;
});
```

### Önizlemeye örnek değer verme

filternotification.preview_variables

`AdminNotifications` bağla geçer

Panelde bir şablon önizlenirken çalışır. Önizleme gerçek gönderim yapmaz ve yalnız çekirdekle gelen şablonları tanır: **sizin kurduğunuz şablonun alanları boş görünür**. Örnek değerleri burada verirsiniz.

Parametreler 2

$variablesarraybağlaŞablona verilecek değerler, ad karşılık değer. Kendi alanlarınızı ekleyin, var olanları ezmeyin.

$ctxarraybağlaHangi şablonun önizlendiği: `group`, `template`, `lang`. Kendi şablonunuz değilse dokunmadan çıkın.

Dönüş 1

voidDönüş yoksayılır; değerleri diziye yazarak eklersiniz.

Dinleyici PHP

```php
Hook::add('filter:notification.preview_variables', 10, function (&$variables, &$ctx) {
    // Yalniz kendi sablonunuzla ilgilenin.
    if (($ctx['template'] ?? '') !== 'acme-welcome') return;

    $variables = array_merge($variables, [
        'acme_plan'  => 'Baslangic',
        'acme_quota' => '10 GB',
    ]);
});
```

## Tuzaklar

> **Gönderim kapısı her dönüşü engelleme sayar**
> 
> Diğer kapılar **boş olmayan bir metin** ister; gönderim kapısı **boş olmayan her değeri** engelleme sayar. Kapanışın sonunda yanlışlıkla bir değer döndürmek — hatta `true` — bildirimin **hiç gitmemesine** yol açar ve hiçbir yerde iz kalmaz.

> **Aynı kişi listede birden çok kez bulunur**
> 
> Alıcı listesi **kanal başına** satır taşır: bir müşteri hem e-posta hem kısa mesaj alıyorsa iki satırdadır. Hesap kimliğine göre tekilleştiren bir dinleyici, farkında olmadan **bir kanalı komple kapatır**.

> **Değişken filtresi alıcı sayısı kadar çalışır**
> 
> On alıcıya giden bir bildirimde bu filtre **on kez** çalışır. İçine sorgu ya da uzak çağrı koymak, tek bir bildirimi on isteğe çıkarır. Ortak veriyi **bir kez** hazırlayın, filtrede yalnız alıcıya özel olanı üretin.

> **Alanı listelemek değerini üretmez**
> 
> Şablon alanları filtresi yalnız **operatöre gösterilen listeyi** genişletir. Alanı listeye ekleyip değişken filtresini yazmazsanız operatör alanı şablona koyar ve müşteriye **boş** gider. İkisi birlikte yazılır.

## İlgili Makaleler

- Bilgi Bankası ve Bildirim Kancaları
- [Müşteri Hesabı Kancaları](https://dev.wisecp.com/tr/musteri-hesabi-kancalari)
- [Fatura Yaşam Döngüsü Kancaları](https://dev.wisecp.com/tr/fatura-yasam-dongusu-kancalari)
