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

# Kanallar ve olaylar

> Tüm gerçek zamanlı kanalları, olay adlarını ve olay içeriklerini listeler.

Bu sayfa, Flextell'in gerçek zamanlı bağlantısında yayınlanan kanalların, olay adlarının ve olay içeriklerinin tam listesidir. Bağlantı kurma ve kanal yetkilendirme adımları için önce [Gerçek zamanlı genel bakış](/api/gercek-zamanli/genel-bakis) sayfasını okuyun. Çalışan bir istemci için [Örnek istemci](/api/gercek-zamanli/ornek-istemci) sayfasına bakın.

<Note>
  Gerçek zamanlı bağlantı yalnızca "bir şey değişti" bilgisini taşır. Olaylar yeniden gönderilmez; kaçırdığınız değişiklikleri REST API'den okuyarak tamamlayın.
</Note>

## Kanal kataloğu

Her kanal için abonelik, `POST /api/broadcasting/auth` ile imzalanır. Yetkisi olmayan kullanıcı bu uç noktadan `403 FORBIDDEN` alır (`Bu işlem için yetkiniz yok.`). Kimlik doğrulaması eksikse yanıt `401 UNAUTHENTICATED` olur.

| Abonelik adı | Tür | Kim katılabilir | Ne taşır |
| - | - | - | - |
| `private-chat-log.{tenantId}` | private | Klinik üyesi olan, `View:Conversation` iznine sahip ve tüm sohbetleri görebilen kullanıcı (`ViewAllConversations:Conversation` izni olan ya da platform yöneticisi). Diğer herkes 403 alır. | Sohbet olayları, mesaj içeriğiyle birlikte |
| `private-chat-log-activity.{tenantId}` | private | `View:Conversation` iznine sahip her klinik üyesi | Yalnızca kimlikler. Okuma için REST'e dönersiniz. |
| `private-ai-suggestion.{conversationId}` | private | Klinik üyesi, `View:Conversation` izni olan ve sohbeti görebilen kullanıcı | AI önerisi olayları |
| `private-App.Models.User.{userId}` | private | Yalnızca kimliği `userId` olan kullanıcı | Kullanıcı bildirimleri |
| `presence-conversation.{conversationId}` | presence | Web sitesi widget'ının ziyaretçisi veya sohbeti görebilen, `View:Conversation` izni olan klinik personeli | Widget mesajları ve yazıyor göstergesi |

<Info>
  `private-chat-log` kanalı mesaj metnini taşıdığı için kısıtlıdır. Tüm sohbetleri görme izniniz yoksa `private-chat-log-activity` kanalına abone olun ve gelen kimliklerle `/conversations` uç noktalarını çağırın. Hangi sohbetleri görebileceğiniz [İzinler ve görünürlük](/api/izinler-ve-gorunurluk) sayfasında anlatılır.
</Info>

`private-App.Models.User.{userId}` kanalı klinik bazlı değildir. Kullanıcı birden fazla kliniğe üye olabilir; bu yüzden her olay `tenant_id` taşır. Etkin kliniğinizin dışındaki olayları yok sayın.

## Olay adlandırma

Özel adı olmayan olaylar, ad alanı dahil tam adlarıyla yayınlanır. Tek ters eğik çizgiyle yazılır, örneğin `Modules\Chat\Events\ChatLogCreated`.

| İstemci | Nasıl dinlenir |
| - | - |
| pusher-js | `channel.bind('Modules\\Chat\\Events\\ChatLogCreated', handler)`. Kaynak kodda ters eğik çizgiler iki kez yazılır. |
| Laravel Echo | Başına nokta ekleyin: `.listen('.Modules\\Chat\\Events\\ChatLogCreated', handler)`. Nokta olmazsa Echo adın başına `App.Events` ekler ve olay eşleşmez. |

Özel adlı olaylar şunlardır: `notification.created`, `notifications.updated`, `MessageSent`, `PresenceUpdated`.

## Sohbet olayları

Sohbet olayları iki kanala dağılır. Aşağıdaki tabloda **İçerik** `private-chat-log` kanalını, **Aktivite** `private-chat-log-activity` kanalını gösterir.

| Olay | Kanal | Ne zaman |
| - | - | - |
| `Modules\Chat\Events\ChatLogCreated` | Yalnızca içerik | Her yeni mesaj: müşteriden gelen, personelin veya botun gönderdiği, sistem mesajı |
| `Modules\Chat\Events\ChatLogUpdated` | Yalnızca içerik | Medya hazır olduğunda, mesaj düzenlenince, iletim durumu veya tepki değişince, ses çevirisi bitince veya başarısız olunca |
| `Modules\Chat\Events\WhatsappHistorySyncProgressed` | Yalnızca içerik | WhatsApp geçmiş aktarımının her ilerleme adımı |
| `Modules\Chat\Events\ChatLogChanged` | Yalnızca aktivite | Sohbeti olan her yeni mesajda ve her mesaj güncellemesinde |
| `Modules\Chat\Events\ChatLogDeleted` | İkisi | Mesaj silinince |
| `Modules\Chat\Events\ConversationCreated` | İkisi | Personel `POST /conversations` ile yeni sohbet başlatınca |
| `Modules\Chat\Events\ConversationDeleted` | İkisi | Sohbet silinince |
| `Modules\Chat\Events\ConversationRead` | İkisi | Sohbet okundu işaretlenince (`/read`, `/open`, `/read-all`) |
| `Modules\Chat\Events\ConversationArchiveStatusChanged` | İkisi | Arşivleme, arşivden çıkarma veya arşivdeki sohbete müşteri mesajı gelmesi |
| `Modules\Chat\Events\ConversationTagsChanged` | İkisi | Sohbet etiketleri değişince |
| `Modules\Chat\Events\ConversationAgentStatusChanged` | İkisi | AI asistan sohbette kapatılınca veya açılınca |
| `Modules\Chat\Events\ConversationPresenceUpdated` | İkisi | Müşteri veya bot yazarken ya da ses kaydederken |
| `Modules\Chat\Events\CustomerBlacklisted` | İkisi | Engelleme kaydı oluşturulunca |
| `Modules\Chat\Events\CustomerUnblacklisted` | İkisi | Engel kaldırılınca |
| `Modules\Customer\Events\CustomerUpdated` | İkisi | Hasta oluşturulunca, adı veya fotoğrafı değişince, birleştirilince veya KVKK imhası uygulanınca |

İki kanala giden olayların içeriği aynıdır. Yalnızca aktivite kanalına abone olan bir istemci `ChatLogCreated` ve `ChatLogUpdated` olaylarını almaz; bunların yerine `ChatLogChanged` alır. WhatsApp geçmiş aktarımı ilerlemesi de yalnızca içerik kanalındadır.

### İçerik taşıyan olaylar

| Olay | İçerik (payload) |
| - | - |
| `ChatLogCreated` | `{ chatLog: <mesaj> }` |
| `ChatLogUpdated` | `{ conversation_id, chatLog: <mesaj> }` |
| `ChatLogDeleted` | `{ chatLogId, conversationId, deletedByUserName }`. Bu olayın alanları camelCase yazılır. Müşteri WhatsApp'ta sildiyse `deletedByUserName` değeri `null` olur. |
| `WhatsappHistorySyncProgressed` | `id`, `channel_id`, `trigger`, `status`, `since`, `pass`, `progress_percent`, `provider_total`, `processed`, `imported`, `skipped`, `settings`, `started_at`, `finished_at`, `created_at` |

`status` değerleri `pending`, `running`, `completed`, `failed`, `cancelled` olarak gelir. `skipped` nesnesi `unknown_contact`, `deleted_contact`, `lid_unresolved`, `group` ve `failed` sayaçlarını taşır.

<Tip>
  Medya içeren bir mesaj için `ChatLogCreated` olayı dosya eklenmeden önce gelir. Dosya hazır olunca aynı mesaj için `file` ve `file_temporary_url` dolu bir `ChatLogUpdated` olayı iletilir.
</Tip>

Mesaj gönderimi kabul edildikten (`202`) sonra sohbetin kanalı kapatılırsa mesaj saklanır, `metadata.delivery_status` değeri `failed` olur ve mesaj için yeni bir `ChatLogUpdated` olayı iletilir. Kanal baştan pasifse gönderim uç noktası mesajı kabul etmez ve `422 CHANNEL_INACTIVE` döner; bu durumda olay oluşmaz.

Mesaj nesnesinin (`chatLog`) başlıca alanları:

| Alan | Tür | Açıklama |
| - | - | - |
| `id` | tamsayı | Mesaj kimliği |
| `conversation_id` | tamsayı | Sohbet kimliği |
| `channel_id` | tamsayı, `null` olabilir | Kanal kimliği |
| `user_id`, `user_name` | tamsayı, metin | Mesajı gönderen personel |
| `is_customer` | boolean | `true` ise müşteriden gelen mesaj |
| `message_type` | metin | `text`, `audio`, `video`, `document`, `image`, `sticker`, `location`, `contact`, `system`. Bilinmeyen değeri genel mesaj olarak gösterin. |
| `media_type` | metin, `null` olabilir | `audio`, `video`, `gif`, `document`, `image`, `sticker` |
| `message` | metin, `null` olabilir | Silinmiş mesajda `null` |
| `message_format` | metin | `plain` veya `markdown` |
| `quoted_text` | metin, `null` olabilir | Alıntılanan metin |
| `transcript`, `transcript_status` | metin, `null` olabilir | Ses mesajı çevirisi |
| `is_deleted`, `is_edited` | boolean | Silinme ve düzenlenme durumu |
| `edited_by_user_name`, `deleted_by_user_name` | metin, `null` olabilir | `ChatLogCreated` içinde her zaman `null` |
| `read_at` | tarih-saat, `null` olabilir | Okunma zamanı |
| `delivery_status` | değişken | WhatsApp iletim durumu (`sent`, `delivered`, `read`). Gönderilemeyen mesajda `failed` olur. |
| `metadata` | nesne, `null` olabilir | Konum: `latitude`, `longitude`, `location_name`, `location_address`. Kişi: `contacts` listesi. GIF video: `is_gif`. |
| `created_at` | tarih-saat | Oluşturulma zamanı |
| `file`, `file_temporary_url` | nesne, metin | Ek dosya ve imzalı geçici bağlantısı |
| `media_group_id`, `media_group_index` | metin, tamsayı | Albüm gruplaması |
| `reactions` | liste | Tepkiler. `ChatLogCreated` içinde boş liste gelir. |

### Yalnızca kimlik taşıyan olaylar

Bu olaylar "yeniden oku" sinyalidir. Ayrıntıyı REST API'den alın.

| Olay | İçerik (payload) |
| - | - |
| `ChatLogChanged` | `{ conversation_id, chat_log_id }`. `chat_log_id` değeri `null` olabilir. |
| `ConversationCreated`, `ConversationDeleted`, `ConversationRead` | `{ conversation_id }` |
| `ConversationTagsChanged` | `{ conversation_id }`. Etiket listesi gelmez. |
| `ConversationArchiveStatusChanged` | `{ conversation_id, archived }` |
| `ConversationAgentStatusChanged` | `{ conversation_id, agent_disabled }`. `agent_expires_at` ve `agent_disabled_by_user_name` gelmez; bunlar için `GET /conversations/{id}/agent` çağırın. |
| `CustomerUpdated` | `{ customer_id }` |
| `CustomerBlacklisted`, `CustomerUnblacklisted` | `{ channel_id, customer_id }` |

`ConversationCreated` olayı yalnızca personelin `POST /conversations` ile başlattığı yeni sohbetlerde gelir. Müşterinin yazdığı yeni bir sohbeti, bilinmeyen bir `conversation_id` taşıyan ilk `ChatLogCreated` veya `ChatLogChanged` olayından öğrenirsiniz.

### Yazıyor göstergesi

`ConversationPresenceUpdated` olayının içeriği `{ conversation_id, presence, source }` biçimindedir. `source` değeri `customer` veya `bot` olur.

| `presence` alanı | Açıklama |
| - | - |
| `conversation_id`, `tenant_id`, `channel_id`, `customer_id` | İlgili kayıtların kimlikleri |
| `state` | Müşteri için WhatsApp durumu küçük harfle (`composing`, `recording`, `paused` gibi; `available` iletilmez). Bot için `typing` veya `paused` |
| `label` | `yazıyor...`, `ses kaydediyor...` veya `null` |
| `is_active`, `is_typing`, `is_recording` | Gösterge durumu |
| `updated_at` | ISO 8601 zaman |
| `expires_at` | Müşteride 10 saniye, botta 45 saniye sonrası. Botun `paused` durumunda yoktur. |

Göstergeyi `expires_at` zamanında kendiniz kapatın. Bot yazmayı bitirince veya hata alınca da `paused` durumu gönderilir.

### Web sitesi widget'ı olayları

`presence-conversation.{conversationId}` kanalı yalnızca web sitesi widget'ı sohbetlerinde kullanılır. Ayrıntılar için [Web sitesi widget'ı](/api/webhooklar/web-sitesi-widgeti) sayfasına bakın.

| Olay | İçerik (payload) | Ne zaman |
| - | - | - |
| `MessageSent` | `{ message }` | Widget sohbetinde sistem mesajı olmayan her yeni veya değişen mesaj. Giden medya dosya hazır olunca gönderilir. |
| `PresenceUpdated` | `{ conversation_id, is_typing, expires_at }` | Yalnızca AI yanıt modu `Auto` olan Website kanallarında, bot yazmaya başlayınca ve bitirince |

## AI önerisi olayları

AI önerisi olayları yalnızca `private-ai-suggestion.{conversationId}` kanalına gider. Sohbet kanallarına gönderilmez.

| Olay | Ne zaman |
| - | - |
| `Modules\Ai\Events\AiSuggestionCreated` | Yeni bekleyen bir öneri oluşturulunca |
| `Modules\Ai\Events\AiSuggestionUpdated` | Öneri yenisiyle değiştirilince (`status: superseded`), gönderilince (`sent_as_is`, `sent_edited`), reddedilince, puanlanınca (`rating`: `up`, `down` veya `null`) veya bekleyen randevu ya da tedaviler düzenlenince |

Öneri değiştirildiğinde, eski öneri için `AiSuggestionUpdated` (`superseded`), ardından yenisi için `AiSuggestionCreated` gelir.

Normal içerik `{ suggestion_id, tenant_id, requires_hydration: false, ...öneri alanları }` biçimindedir. İçerik 9000 bayttan büyükse kısaltılmış bir içerik gelir.

```json theme={null}
{
  "suggestion_id": 123,
  "id": 123,
  "conversation_id": 456,
  "tenant_id": 1,
  "requires_hydration": true,
  "status": "pending",
  "rating": null
}
```

`requires_hydration` değeri `true` ise `GET /api/v1/conversations/{id}/ai-suggestion` ile öneriyi okuyun.

Öneri alanları:

| Alan | Açıklama |
| - | - |
| `id`, `conversation_id` | Öneri ve sohbet kimliği |
| `original_text`, `final_text` | AI'ın yazdığı metin ve gönderilen son metin |
| `status`, `rating` | Öneri durumu ve puanı |
| `pending_actions` | Bekleyen işlemler (liste) |
| `attachments`, `actions` | Ek ve işlem önizlemeleri |
| `block_reason` | Önerinin engellenme nedeni |
| `editable_insert` | Ekleme düzenlenebilir mi (boolean) |
| `found_treatments`, `editable_found_treatments` | Bulunan tedaviler (`id`, `name`) ve düzenlenebilirlik |
| `trigger_chat_log_ids` | Öneriyi tetikleyen mesaj kimlikleri |
| `has_new_messages` | Öneriden sonra yeni mesaj gelip gelmediği (boolean) |
| `generated_at` | Üretim saati (`H:i`, klinik saat dilimi) |
| `sent_at`, `created_at`, `updated_at` | ISO 8601 zamanlar |

<Warning>
  İçerik, olayın yayınlandığı andaki bir görüntüdür ve eskimiş olabilir. Karar vermeden önce güncel öneriyi `GET /conversations/{id}/ai-suggestion` ile okuyun.
</Warning>

AI asistanın sohbette açılıp kapanması bir öneri olayı değildir. Bu değişiklik `ConversationAgentStatusChanged` olayıyla gelir. Bot yazarken `ConversationPresenceUpdated` (`source: bot`) gelir.

## Kullanıcı bildirimleri

Bildirim olayları yalnızca `private-App.Models.User.{userId}` kanalına gider.

| Olay | İçerik (payload) | Ne zaman |
| - | - | - |
| `notification.created` | `{ tenant_id, notification }` | Kullanıcı için yeni bir sistem bildirimi veya yeni müşteri mesajı bildirimi oluşunca |
| `notifications.updated` | `{ tenant_id, unread_count, chat, system }` | Kullanıcı bir bildirimi okundu işaretleyince, kapatınca, tümünü okundu işaretleyince veya temizleyince. Kullanıcının diğer açık istemcilerini yenilemek içindir. |

`notification` nesnesi:

| Alan | Tür | Açıklama |
| - | - | - |
| `id` | metin | Bildirim kimliği |
| `source` | metin | `chat` veya `system` |
| `type` | metin, `null` olabilir | Bildirim türü, örneğin `chat_new_message` |
| `category` | metin, `null` olabilir | Kategori |
| `level` | metin, `null` olabilir | Önem düzeyi |
| `title`, `body` | metin, `null` olabilir | Başlık ve metin |
| `resource`, `resource_id` | metin, tamsayı | Bildirimin ilgili olduğu kayıt |
| `parent_resource`, `parent_resource_id` | metin, tamsayı | Üst kayıt. Görevlerde `lead` veya `customer` olur. |
| `download_url` | metin, `null` olabilir | Dışa aktarma bildirimlerinde indirme bağlantısı |
| `avatar_url` | metin, `null` olabilir | Avatar |
| `tenant_id` | tamsayı | Klinik kimliği |
| `read_at`, `created_at` | tarih-saat, `null` olabilir | Klinik saat dilimiyle yazılır |

<Accordion title="Bildirim türü, kategori ve kaynak değerleri">
  `type` değerleri: `appointment_created`, `appointment_assignment`, `appointment_status_changed`, `appointment_rescheduled`, `appointment_bulk_reschedule`, `appointment_reschedule_no_alternative`, `chat_new_message`, `ticket_created`, `ticket_assigned`, `ticket_status_changed`, `lead_unassigned`, `lead_task_assigned`, `lead_task_due`, `lead_bulk_operation`, `inventory_low_stock`, `storage_file_uploaded`, `storage_overage`, `sales_export`, `customer_balance_export`, `announcement_updated`, `panel_ticket_created`, `panel_ticket_status_updated`, `ai_report_ready`, `ai_report_failed`.

  `category` değerleri: `appointment`, `message`, `ticket`, `lead`, `inventory`, `sales`, `finance`, `announcement`, `panel_ticket`, `report`.

  `resource` değerleri: `task`, `appointment`, `ticket`, `panel_ticket`, `lead`, `ai_report`, `proforma_invoice`, `announcement`, `product`, `file`, `conversation`.
</Accordion>

Yeni müşteri mesajı bildirimi (`type`: `chat_new_message`, `resource`: `conversation`), sohbet bildirimi alacak şekilde ayarlanmış rollerdeki ve o sohbeti görebilen kullanıcılara gider. Bir Satış Temsilcisi, kendisine atanmamış kişilerin mesaj bildirimini almaz.

Bildirim listesi, okundu işaretleme ve temizleme uç noktaları için [Bildirimler](/api/kaynaklar/bildirimler) sayfasına bakın.

## Sıralama ve boyut sınırları

Gerçek zamanlı bağlantı REST API'nin yerini almaz. İstemcinizi aşağıdaki davranışlara göre tasarlayın.

| Konu | Davranış |
| - | - |
| Sıralama | Farklı olay türleri arasında sıra garantisi yoktur. Bazı olaylar gecikmeli iletilir; örneğin `ConversationRead` olayı, daha sonra oluşan bir `ChatLogCreated` olayından sonra gelebilir. |
| Teslim | En fazla bir kez iletilir. Bağlantı koptuğunda veya uygulama arka plandayken kaçan olaylar tekrar gönderilmez. |
| Kendi değişiklikleriniz | Değişikliği yapan istemci de olayı alır. Olayları kimliğe göre tekilleştirin. |
| Boyut | Pusher olay verisi için 10 KB sınırı vardır. Yalnızca AI önerisi olayları bunu 9000 baytlık bir bütçeyle denetler ve aşılırsa `requires_hydration: true` içeriği gönderir. |
| Kısmi içerik | Çoğu olay yalnızca kimlik taşır. Etiket listesi, geri sayım ve hasta ayrıntıları gelmez. |
| Zaman damgaları | Herhangi bir ISO 8601 saat dilimi farkını kabul edin. `notification.created` zamanları klinik saat dilimiyle yazılır. |

<Steps>
  <Step title="Abone olun">
    İlgili kanala abone olun. Başarılı abonelik `pusher:subscription_succeeded` olayıyla bildirilir.
  </Step>

  <Step title="Durumu REST'ten okuyun">
    Her başarılı abonelikten sonra, yeniden bağlanma sonrası dahil, ilgili listeyi ve açık sohbetin mesajlarını REST ile yeniden okuyun.
  </Step>

  <Step title="Olayları uygulayın">
    Gelen olayları kimliğe göre tekilleştirerek uygulayın. Kimlik taşıyan olaylarda yalnızca etkilenen kaydı yeniden okuyun.
  </Step>
</Steps>

## İlgili sayfalar

<CardGroup cols={2}>
  <Card title="Gerçek zamanlı genel bakış" icon="radio" href="/api/gercek-zamanli/genel-bakis">
    Bağlantı kurma ve kanal yetkilendirme.
  </Card>

  <Card title="Örnek istemci" icon="code" href="/api/gercek-zamanli/ornek-istemci">
    Abonelik ve olay dinleme örneği.
  </Card>

  <Card title="Sohbetler" icon="messages-square" href="/api/kaynaklar/sohbetler">
    Olaylardan sonra çağıracağınız sohbet uç noktaları.
  </Card>

  <Card title="AI asistan" icon="bot" href="/api/kaynaklar/ai-asistan">
    AI önerisi ve asistan kontrolü uç noktaları.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.