> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API custom_data ile mesajları kişiselleştirin

> Create Message API kullanarak custom_data ile dinamik, mesaja özel veriler gönderin. Gerçek zamanlı kişiselleştirme için şablonlarda Liquid söz dizimi ile değerlere referans verin.

Arka uçunuzdan dinamik veri göndermek ve [Liquid söz dizimi](./using-liquid-syntax) kullanarak şablonlarda render etmek için [Create Message API](/reference/create-message) içindeki `custom_data` alanını kullanın.

`custom_data`:

* **Mesaja özeldir**
* **Saklanmaz**
* Yalnızca API isteği sırasında mevcuttur
* Bir `template_id` ile kullanılmalıdır

Şablonlarda değerlere şu şekilde referans verin:

```liquid Liquid theme={null}
{{ message.custom_data.key_name }}
```

<Warning>
  `custom_data` geçicidir. Veriler kullanıcı profillerine kaydedilmez ve gelecek mesajlarda yeniden kullanılamaz. Kalıcı veriye ihtiyacınız varsa [Mesaj kişiselleştirme](./message-personalization) bölümüne bakın.
</Warning>

***

## `custom_data` ne zaman kullanılır

Aşağıdaki durumlarda `custom_data` kullanın:

* Veriler mesaj başına değişiyorsa (sipariş toplamları, sepet ürünleri, bakiyeler)
* Dizilere ihtiyacınız varsa (ürün listeleri, satır öğeleri, öneriler)
* Veriler kalıcı olmamalıysa (tek kullanımlık kodlar, geçici URL'ler)
* Arka uçtan tetiklenen mesajlar gönderiyorsanız
* Tek bir API isteğinde toplu kişiselleştirme yapmak istiyorsanız

***

## `custom_data` kişiselleştirmesi nasıl çalışır

Mesajlara `custom_data` eklemek birkaç adım gerektirir:

<Steps>
  <Step title="Bir şablon oluşturun">
    Panelde veya [Create Template API](/reference/create-template) aracılığıyla bir Push, E-posta veya SMS [Şablonu](./templates) oluşturun.
  </Step>

  <Step title="Liquid yer tutucuları ekleyin">
    Gerekli ön eki kullanarak referanslar ekleyin:

    ```liquid Liquid theme={null}
    Hi {{ message.custom_data.first_name }},
    Order {{ message.custom_data.order_id }} is confirmed.
    ```
  </Step>

  <Step title="API isteğinizde custom_data gönderin">
    [Create Message API](/reference/create-message) çağrısını şunlarla yapın:

    * `template_id` - Şablonun ID'si
    * `custom_data` - Veri nesnesi
    * Hedef kitle belirleme (`include_player_ids`, `include_aliases` veya segmentler)

    OneSignal, gönderim sırasında verilerinizi kullanarak şablonu render eder.

    Liquid söz dizimi geçersizse veya anahtarlar mevcut değilse, bu alanlar boş dize olarak render edilir ancak mesaj yine de gönderilir.
  </Step>
</Steps>

***

## Veri kalıpları

`custom_data` ile kullanabileceğiniz yaygın veri kalıpları örnekleri.

### Düz JSON örneği

İsimler, ID'ler, URL'ler veya herhangi bir tek değerli veri gibi temel kişiselleştirme için basit anahtar-değer çiftleri kullanın.

**Kullanım senaryosu:** Her alanın tek bir değer içerdiği işlemsel mesajlar (faturalar, makbuzlar, onaylar).

**Şablon:**

```liquid Liquid theme={null}
Invoice {{ message.custom_data.invoice_id }} for {{ message.custom_data.product_name }} is ready.
```

**API isteği:**

```json JSON theme={null}
{
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "include_email_tokens": ["user@example.com"],
  "custom_data": {
    "invoice_id": "463246732",
    "product_name": "Widget"
  }
}
```

**Müşterinin gördüğü:**

```liquid Text theme={null}
Invoice 463246732 for Widget is ready.
```

***

### Dizi verisi örneği

Sepet ürünleri, sipariş satır öğeleri veya öneriler gibi birden fazla öğeyle çalışmak için nesne dizileri gönderin. Diziler hem doğrudan erişimi (indeksleme) hem de yinelemeyi (döngüler) mümkün kılar.

**Kullanım senaryosu:** Ürün listelerini, sıralamaları, sipariş özetlerini veya herhangi bir çok öğeli veriyi görüntüleme.

**İndeksleme şablonu (ilk öğeye erişim):**

```liquid Liquid theme={null}
Your {{message.custom_data.cart_items[0].item_name}} is waiting for you!
Image: {{message.custom_data.cart_items[0].img_url}}
```

<Warning>
  **Dizi indeksleme 0'dan başlar**, 1'den değil. İlk öğe `[0]`, ikincisi `[1]` vb. şeklindedir. Mevcut olmayan bir indekse erişim boş döndürür (hata fırlatılmaz).
</Warning>

**Döngü şablonu (tüm öğelere erişim):**

```liquid Liquid theme={null}
{% for item in message.custom_data.cart_items %}
- {{ item.item_name }} — {{ item.img_url }}
{% endfor %}
```

**API isteği:**

```json theme={null}
{
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "include_email_tokens": ["user@example.com"],
  "custom_data": {
    "cart_items": [
      {
        "item_name": "sweater",
        "img_url": "https://.../sweater.png"
      },
      {
        "item_name": "socks",
        "img_url": "https://.../socks.png"
      }
    ]
  }
}
```

**Müşterinin gördüğü:**

```liquid Text theme={null}
Your sweater is waiting for you!
Image: https://.../sweater.png

- sweater — https://.../sweater.png
- socks — https://.../socks.png
```

**Faydalı dizi özellikleri:**

* `{{message.custom_data.cart_items.size}}` — Dizideki öğe sayısı (bu örnekte `2` döndürür)
* `{{message.custom_data.cart_items.first.item_name}}` — İlk öğenin adı (`[0]` ile eşdeğer)
* `{{message.custom_data.cart_items.last.item_name}}` — Son öğenin adı

***

### Toplu kişiselleştirme örneği

Her alıcının `external_id` değerine göre kişiselleştirilmiş içerik gördüğü tek bir API isteğini birden fazla kullanıcıya gönderin.

**Nasıl çalışır:**

1. `custom_data` yapısını **anahtarların external\_id'ler**, **değerlerin kullanıcıya özel veriler** olduğu bir nesne olarak oluşturun
2. Şablonda, geçerli alıcının verilerini aramak için `subscription.external_id` kullanın
3. OneSignal, şablonu her alıcı için kendi özel verileriyle bir kez render eder

**Şablon:**

```liquid theme={null}
{% assign user = message.custom_data.users[subscription.external_id] %}
Hi {{ user.first_name }}, you have {{ user.points }} points. Your level is {{ user.level }}.
```

**Neler oluyor:**

* `subscription.external_id` geçerli alıcının external\_id değerini içerir (ör. "user123")
* `message.custom_data.users[subscription.external_id]` custom\_data nesnesinden o kullanıcının verilerini arar
* `user`, o kullanıcının verileri için bir kısayol değişkeni olur
* Her alıcı yalnızca kendi kişiselleştirilmiş içeriğini görür

**API isteği:**

```json theme={null}
{
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "include_aliases": {
    "external_id": ["user123", "user456"]
  },
  "custom_data": {
    "users": {
      "user123": { "first_name": "John", "points": "150", "level": "Gold" },
      "user456": { "first_name": "Sarah", "points": "200", "level": "Platinum" }
    }
  }
}
```

**Her kullanıcının gördüğü:**

<Check>
  * **John** (user123): "Hi John, you have 150 points. Your level is Gold."
  * **Sarah** (user456): "Hi Sarah, you have 200 points. Your level is Platinum."
</Check>

<Info>
  **Toplu kişiselleştirme gereksinimleri:**

  * Tüm alıcıların OneSignal'da bir `external_id` değeri ayarlanmış olmalıdır
  * `include_aliases` içindeki her `external_id`, `custom_data.users` içinde eşleşen bir anahtara sahip olmalıdır
  * Bir alıcının external\_id değeri `custom_data` içinde yoksa, mesajında boş alanlar olacaktır
</Info>

***

## Örnek: custom\_data ile terk edilmiş sepet

`custom_data` kullanarak hem e-posta hem de push için terk edilmiş sepet mesajları nasıl oluşturulur.

**Bu yaklaşım ne zaman kullanılır:**

* Sunucunuz sepet terkini algıladığında (ör. son aktiviteden 1 saat sonra)
* Gerçek zamanlı sepet verileri veritabanınızda olduğunda
* Resimler, isimler, fiyatlarla birden fazla ürün görüntülemek istediğinizde
* Her kullanıcının farklı ürünleri ve miktarları olabildiğinde
* Mesajı arka uçunuzdan yönetmek istediğinizde

### Örnek `custom_data` payload

Bu, bu örnek için [Create Message API](/reference/create-message) isteğidir.

```json JSON theme={null}
{
  "custom_data": {
    "cart_url": "https://yourdomain.com/cart",
    "cart": [
      {
        "product_name": "24 Pack of Acorns",
        "product_image": "https://i.imgur.com/ssPCfbC.png",
        "product_price": "$12.99",
        "product_quantity": "1"
      },
      {
        "product_name": "Fancy Sweater",
        "product_image": "https://i.imgur.com/8QWTfV4.png",
        "product_price": "$9.99",
        "product_quantity": "1"
      }
    ]
  },
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "include_aliases": {
    "external_id": ["YOUR_EXTERNAL_ID"]
  }
}
```

**Alan açıklamaları:**

| Alan               | Tür    | Amaç                                                                  |
| ------------------ | ------ | --------------------------------------------------------------------- |
| `cart_url`         | string | Müşterinin benzersiz sepet bağlantısı (butonlar/açılış URL'leri için) |
| `cart`             | array  | Ürün listesi—sayma, döngü ve detay görüntülemeyi destekler            |
| `product_image`    | string | Ürün görseli (dizideki her öğe için)                                  |
| `product_name`     | string | Ürün adı (her öğe için)                                               |
| `product_quantity` | string | Miktar (her öğe için)                                                 |
| `product_price`    | string | Biçimlendirilmiş fiyat (her öğe için)                                 |

<Note>
  Alanlara istediğiniz ismi verebilirsiniz—sadece şablonunuzdaki Liquid söz diziminin eşleştiğinden emin olun.
</Note>

<Warning>
  **2KB altında kalın:** Büyük sepetleriniz varsa, boyut sınırını aşmamak için ilk 3-5 öğeyle sınırlamayı veya yalnızca temel alanları göndermeyi düşünün.
</Warning>

### E-posta şablonu

Bu örnek, aşağıdakileri görüntüleyen bir e-posta şablonunun nasıl oluşturulacağını gösterir:

* Sepet öğe sayısı
* Bir for-döngüsü kullanarak her ürünü resim, ad, miktar ve fiyatla birlikte
* Müşterinin benzersiz sepet URL'sine bağlanan bir buton

<Frame caption="Terk edilmiş sepet e-posta şablonu örneği">
  <img src="https://mintcdn.com/onesignal/KSCNwSpBCNSQ8xdF/images/docs/fd61543-Screenshot_2023-08-28_at_10.52.05_AM.png?fit=max&auto=format&n=KSCNwSpBCNSQ8xdF&q=85&s=4128b15d8d53d69c6626e129eee538fa" width="693" height="1477" data-path="images/docs/fd61543-Screenshot_2023-08-28_at_10.52.05_AM.png" />
</Frame>

<Steps>
  <Step title="E-posta şablonunu oluşturun">
    **Messages > Templates > New Email Template** bölümüne gidin ve Sürükle ve Bırak Düzenleyiciyi açın.
  </Step>

  <Step title="Düzen yapısını ekleyin">
    Beş satır oluşturun:

    * Satır 1, 2 ve 4: **Paragraph** bloğu olan tek sütun
    * Satır 3: **HTML | Paragraph | Paragraph | Paragraph** olan dört sütun
    * Satır 5: **Button** bloğu olan tek sütun

    <Frame caption="Terk edilmiş sepet için başlangıç e-posta şablonu">
      <img src="https://mintcdn.com/onesignal/v-hm59YoewwF90UX/images/email/starter-template-abandoned-cart.png?fit=max&auto=format&n=v-hm59YoewwF90UX&q=85&s=551e9ec4618f64fdc0b6ab610a537c48" width="2968" height="2124" data-path="images/email/starter-template-abandoned-cart.png" />
    </Frame>
  </Step>

  <Step title="Öğe sayısını görüntüleyin">
    Satır 1'e şunu ekleyin:

    ```liquid Liquid theme={null}
    We're holding onto {{message.custom_data.cart.size}} items in your cart, but don't wait too long, other squirrels are getting ahead!
    ```

    Daha iyi dilbilgisi için "1 item" ve "2 items" şeklinde koşullu ifade kullanabilirsiniz, ancak terk edilmiş sepet e-postaları için çoğul genellikle kabul edilebilir.

    ```liquid Liquid theme={null}
    {% assign cart = message.custom_data.cart %}
    {% assign item_count = cart.size | plus: 0 %}
    {% if item_count == 1 %}
    We're holding onto {{item_count}} item in your cart, but don't wait too long, other squirrels are getting ahead!
    {% endif %}
    {% if item_count > 1 %}
    We're holding onto {{item_count}} items in your cart, but don't wait too long, other squirrels are getting ahead!
    {% endif %}
    ```
  </Step>

  <Step title="Döngüyü başlatın">
    Sepetteki her öğe için ürün görüntüleme satırını tekrarlamak üzere bir [for-döngüsü](./using-liquid-syntax#for-loops) kullanın.

    Satır 2'de (döngü başlangıcı) Metin bloğuna şunu ekleyin:

    ```liquid Text theme={null}
    {% for product in message.custom_data.cart %}
    ```

    **Bunun yaptığı:**

    * `cart` dizisindeki her nesne üzerinde yineleme yapan bir döngü başlatır
    * Geçerli öğeyi temsil eden `product` adında geçici bir değişken oluşturur
    * `{% for %}` ve `{% endfor %}` arasındaki her şey sepet öğesi başına bir kez tekrarlanır
    * `product` yerine herhangi bir isim verebilirsiniz (ör. `item`, `cartItem`)—sadece tutarlı olun

    <Warning>
      For-döngüsü yerleşimi: `{% for %}` söz diziminin kendi Metin bloğu satırında olduğundan emin olun. Diğer içeriklerle birlikte çok sütunlu bir satırın içine koymayın, bu bazı istemcilerde e-posta render'ını bozabilir.
    </Warning>
  </Step>

  <Step title="Ürün detaylarını görüntüleyin">
    Bu 4 sütunlu satır resim, ad, miktar ve fiyatı gösterir. Döngünün içinde olduğu için her sepet öğesi için tekrarlanır.

    Satır 3'te (ürün detayları) yapılandırın:

    **Sütun 1 - HTML bloğu** (ürün görseli):

    ```html HTML theme={null}
    <img src="{{product.product_image}}" alt="Product image" style="max-width:100%;" />
    ```

    **Sütun 2–4 - Metin blokları** (ürün adı, miktar, fiyat):

    * Sütun 2: `{{product.product_name}}`
    * Sütun 3: `{{product.product_quantity}}`
    * Sütun 4: `{{product.product_price}}`

    **Döngü nasıl çalışır:**

    * İlk yinelemede, `product` = sepet dizisindeki ilk nesne
    * `{{product.product_image}}` ilk öğenin resim URL'sini alır
    * İkinci yinelemede, `product` = ikinci nesne
    * Satır tüm sepet öğeleri için otomatik olarak tekrarlanır

    <Warning>
      **Alan adı eşleştirmesi:** `product_image` gibi anahtarlar, olay payload'ınızla tam olarak eşleşmelidir (büyük/küçük harfe duyarlı). Eşleşmeyenler boş dize olarak render edilir.
    </Warning>
  </Step>

  <Step title="Döngüyü sonlandırın">
    Tekrarlamanın nerede durduğunu belirlemek için döngüyü kapatın.

    Satır 4'te (döngü sonu) şunu ekleyin:

    ```liquid Liquid theme={null}
    {% endfor %}
    ```

    <Note>
      Her `{% for %}` ifadesinin eşleşen bir `{% endfor %}` ifadesi olmalıdır. Bu eksik olursa e-posta render'ı bozulur.
    </Note>
  </Step>

  <Step title="Sepet bağlantı butonu ekleyin">
    Satır 5'teki **Button** bloğunda Action URL değerini ayarlayın:

    ```liquid Text theme={null}
    {{message.custom_data.cart_url}}
    ```

    <Frame caption="Stillenmemiş terk edilmiş sepet için tamamlanmış temel e-posta şablonu">
      <img src="https://mintcdn.com/onesignal/v-hm59YoewwF90UX/images/email/finished-template-abandoned-cart-custom-data.png?fit=max&auto=format&n=v-hm59YoewwF90UX&q=85&s=d26b638eb17878bb51c28a5e08f77724" width="2968" height="1716" data-path="images/email/finished-template-abandoned-cart-custom-data.png" />
    </Frame>
  </Step>

  <Step title="Şablonu test edin">
    * [Örnek `custom_data` payload](#example-custom-data-payload) kullanarak API isteğinizi ayarlayın
    * Kendinize e-postayı gönderin.
    * Verilerin doğru görüntülendiğini doğrulayın.

    <Check>Başarılı! Artık şablona kendi stilinizi uygulayabilirsiniz. [Sürükle ve bırak ile e-posta tasarlama](./design-emails-with-drag-and-drop) bölümüne bakın.</Check>
  </Step>
</Steps>

### Push şablonu

Push bildirimleri karakter sınırlarına ve işletim sistemi kısıtlamalarına sahiptir, bu nedenle tüm öğeleri göstermek yerine ilk ürünü görüntüleyin ve doğru dilbilgisiyle toplam sayıyı belirtin.

İşte oluşturacağımız örnek push bildirimi:

<Frame caption="Terk edilmiş sepet push şablonu örneği">
  <img src="https://mintcdn.com/onesignal/4HyuQPBpu-4xjmQC/images/docs/d0db985-Screenshot_2023-08-28_at_9.30.23_AM.png?fit=max&auto=format&n=4HyuQPBpu-4xjmQC&q=85&s=6cf03ce9b622ba399656f2b14fb055f3" width="688" height="656" data-path="images/docs/d0db985-Screenshot_2023-08-28_at_9.30.23_AM.png" />
</Frame>

**Mesaj alanı:**

```liquid Liquid theme={null}
{% assign cart = message.custom_data.cart %}
{% assign item_count = cart.size | plus: 0 %}
{% if item_count == 1 %}
You left {{cart.first.product_name}} in your cart.
{% endif %}
{% if item_count == 2 %}
You left {{cart.first.product_name}} and {{item_count | minus: 1}} more item in your cart.
{% endif %}
{% if item_count > 2 %}
You left {{cart.first.product_name}} and {{item_count | minus: 1}} more items in your cart.
{% endif %}
```

<Info>
  Daha fazla bilgi için [Liquid söz dizimi kullanımı](./using-liquid-syntax#if-elsif-else) bölümüne bakın.
</Info>

**Görsel alanı:**

```liquid Liquid theme={null}
{{message.custom_data.cart.first.product_image | default: "https://i.imgur.com/ssPCfbC.png"}}
```

<Info>
  Daha fazla bilgi için [Bildirim görselleri ve zengin medya](./rich-media) bölümüne bakın.
</Info>

**Açılış URL alanı:**

```liquid Liquid theme={null}
{{cart_url | default: "https://yourdomain.com/cart"}}
```

<Check>
  Başarılı! Şablonu kaydedin ve test etmek için `template_id` değerini `custom_data` özelliğiyle birlikte [Create message](/reference/create-message) API isteğinizde kullanın.
</Check>

***

## Sorun giderme ve en iyi uygulamalar

* **Basit tutun**: Yalnızca şablonda gerçekten kullanacağınız verileri dahil edin
* **2KB altında kalın**: Özellikle dizilerde payload boyutunuzu izleyin
* **Tutarlı adlandırma kullanın**: Baştan sona `snake_case` veya `camelCase` kullanın
* **Göndermeden önce doğrulayın**: Null değerleri, boş dizileri ve gerekli alanları kontrol edin

**Şablon tasarımı:**

* İsteğe bağlı alanlar için **her zaman default filtreleri kullanın**:
  ```liquid Liquid theme={null}
  {{message.custom_data.user_name | default: "there"}}
  ```
* **Döngü yapmadan önce dizi boyutunu kontrol edin**:
  ```liquid Liquid theme={null}
  {% if message.custom_data.items.size > 0 %}
    {% for item in message.custom_data.items %}
      {{item.name}}
    {% endfor %}
  {% endif %}
  ```
* **Uç durumlarla test edin**: boş diziler, eksik alanlar, maksimum öğe sayıları

**Hata yönetimi:**

* Doğrulama hatalarını yakalamak için API yanıtlarını sunucu tarafında kaydedin
* Mesaj teslim oranlarını izleyin—ani düşüşler Liquid hatalarına işaret edebilir
* Kritik işlemsel mesajlar için yedek şablonları hazır bulundurun

**Performans:**

* Karmaşık Liquid mantığı kullanmak yerine **karmaşık verileri arka uçunuzda önceden biçimlendirin**
* **Şablonları önbelleğe alın** ve birçok API çağrısında yeniden kullanın
* Yüksek hacimli işlemsel mesajları pazarlama kampanyalarından ayırmayı düşünün

<Accordion title="Mesaj gönderiliyor ancak içerik boş">
  **Neden:** Liquid söz dizimi hataları veya eşleşmeyen alan adları

  **Çözümler:**

  * Alan adlarının `custom_data` ve şablon arasında tam olarak eşleştiğini doğrulayın (büyük/küçük harfe duyarlı)
  * Yazım hatalarını kontrol edin: `{{message.custom_data.name}}` olmalı, `{{message.custm_data.name}}` değil
  * Eksik alanları yakalamak için [default filtreleri](./using-liquid-syntax#default) kullanın
  * Üretime geçmeden önce şablonları gerçek `custom_data` yapısıyla test edin
</Accordion>

<Accordion title="API Hatası: İstek gövdesi çok büyük">
  **Neden:** `custom_data` 2KB sınırını aşıyor

  **Çözümler:**

  * Payload'ınızdan gereksiz alanları kaldırın
  * Mümkün olduğunda alan adlarını ve değerleri kısaltın
  * Dizileri ilk 3-5 öğeyle sınırlayın
  * Büyük statik içeriği (tam HTML gibi) bunun yerine şablonunuza taşıyın
</Accordion>

***

## İlgili sayfalar

<Columns cols={2}>
  <Card title="Mesaj kişiselleştirme" href="./message-personalization" icon="sparkles">
    Tags, kullanıcı nitelikleri ve segmentasyon dahil OneSignal'daki tüm kişiselleştirme seçeneklerine genel bakış.
  </Card>

  <Card title="Create Message API" href="/reference/create-message" icon="code">
    custom\_data, hedefleme seçenekleri ve mevcut tüm alanlarla mesaj göndermek için eksiksiz API referansı.
  </Card>

  <Card title="Liquid söz dizimi kullanımı" href="./using-liquid-syntax" icon="droplet">
    Filtreler, koşullar, döngüler ve dize işleme dahil tam Liquid söz dizimi referansı.
  </Card>

  <Card title="Templates" href="./templates" icon="file">
    Push, E-posta, SMS ve Uygulama İçi kanalları için yeniden kullanılabilir mesaj şablonları oluşturun ve yönetin.
  </Card>
</Columns>

<Info>
  Yardıma mı ihtiyacınız var?

  Destek ekibimizle sohbet edin veya `support@onesignal.com` adresine e-posta gönderin

  Lütfen şunları ekleyin:

  * Yaşadığınız sorunun ayrıntıları ve varsa yeniden üretme adımları
  * OneSignal Uygulama Kimliğiniz
  * Varsa Harici ID veya Abonelik ID
  * Varsa OneSignal Panosunda test ettiğiniz mesajın URL'si
  * İlgili [günlükler veya hata mesajları](/docs/en/capturing-a-debug-log)

  Size yardımcı olmaktan mutluluk duyarız!
</Info>

***
