signalbird 2.6.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +200 -69
- package/dist/angular.js +23 -8
- package/dist/angular.js.map +1 -1
- package/dist/angular.mjs +23 -8
- package/dist/angular.mjs.map +1 -1
- package/dist/app.d.mts +41 -6
- package/dist/app.d.ts +41 -6
- package/dist/app.js +23 -8
- package/dist/app.js.map +1 -1
- package/dist/app.mjs +23 -8
- package/dist/app.mjs.map +1 -1
- package/dist/browser.d.mts +17 -0
- package/dist/browser.d.ts +17 -0
- package/dist/browser.js +92 -3
- package/dist/browser.js.map +1 -1
- package/dist/browser.mjs +92 -3
- package/dist/browser.mjs.map +1 -1
- package/dist/index.d.mts +114 -19
- package/dist/index.d.ts +114 -19
- package/dist/index.js +98 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +99 -10
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.js +23 -8
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +23 -8
- package/dist/react-native.mjs.map +1 -1
- package/dist/react.js +23 -8
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +23 -8
- package/dist/react.mjs.map +1 -1
- package/dist/signalbird.js +3 -3
- package/dist/vue.js +23 -8
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +23 -8
- package/dist/vue.mjs.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# Signalbird SDK
|
|
2
2
|
|
|
3
|
-
**Tek paket,
|
|
3
|
+
**Tek paket, beş yüzey, on iki giriş noktası.** Panelde tıklayarak yapabildiğiniz her şey
|
|
4
4
|
kodla da yapılabilir.
|
|
5
5
|
|
|
6
6
|
| Yüzey | Ne yapar | Anahtar | Nerede |
|
|
7
7
|
|---|---|---|---|
|
|
8
|
-
| **Telsiz** (Radio) |
|
|
9
|
-
| **Gönderim** (Messaging) | e-posta, SMS, push gönderir; kişi, liste, kampanya yönetir; mesaj durumu okur; webhook imzası doğrular | `
|
|
10
|
-
| **Yönetim** (Management) |
|
|
8
|
+
| **Telsiz** (Radio) | uygulamanızdan bir **kanala** log/olay yazar | `sb_secret_live_…` / `sb_public_live_…` | sunucu / tarayıcı |
|
|
9
|
+
| **Gönderim** (Messaging) | e-posta, SMS, push gönderir; kişi, liste, kampanya yönetir; mesaj durumu okur; webhook imzası doğrular | `sb_secret_live_…` | yalnız sunucu |
|
|
10
|
+
| **Yönetim** (Management) | kanal (modül anahtarı) açar, olay akışını okur, **sohbet gelen kutusunu** işler, push cihazlarını listeler | `sb_secret_live_…` | yalnız sunucu |
|
|
11
11
|
| **Uygulama** (App) | müşterinizin **son kullanıcısına** canlı sohbet + push cihaz kaydı | `sb_public_live_…` | web, iOS, Android |
|
|
12
12
|
| **Partner** | Signalbird'ü kendi ürününde satan **sözleşmeli platform** müşterisini sağlar ve yetkilendirir | `sb_secret_live_…` | yalnız sunucu |
|
|
13
13
|
|
|
@@ -32,8 +32,8 @@ Bir seçenek daha var ve kod yazmaz: hazır sohbet widget'ı
|
|
|
32
32
|
| Kotlin (Android) | ✓ | - | - | ✓ | `io.signalbird:signalbird-sdk` |
|
|
33
33
|
|
|
34
34
|
Metot adları diller arasında **birebir** aynıdır; her dil kendi yazım
|
|
35
|
-
geleneğini korur (`
|
|
36
|
-
`
|
|
35
|
+
geleneğini korur (`createModuleKey` / `create_module_key` /
|
|
36
|
+
`CreateModuleKey` / `CreateModuleKeyAsync`). `node scripts/check-parity.mjs` bunu her derlemede
|
|
37
37
|
denetler.
|
|
38
38
|
|
|
39
39
|
Uygulama yüzeyi mobil ve tarayıcı içindir: gizli anahtar oraya gömülmez.
|
|
@@ -41,7 +41,7 @@ Gönderim ve Yönetim yüzeyleri yalnız sunucudadır.
|
|
|
41
41
|
|
|
42
42
|
## Telsiz
|
|
43
43
|
|
|
44
|
-
Telsiz'in tek işi vardır:
|
|
44
|
+
Telsiz'in tek işi vardır: uygulamanızdan bir **kanala** mesaj yazmak.
|
|
45
45
|
|
|
46
46
|
Bildirimin kime gideceği, hangi kanaldan (push/e-posta), sessiz saatlerde ne
|
|
47
47
|
olacağı ve aynı mesajın kaç kez uyarı üreteceği **sunucuda, kanal ayarlarında**
|
|
@@ -49,11 +49,14 @@ durur. Kod tarafında bunlar yoktur ve olmamalıdır: bildirim kuralını
|
|
|
49
49
|
değiştirmek için uygulamanızı yeniden yayınlamanız gerekmesin.
|
|
50
50
|
|
|
51
51
|
```
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
olay
|
|
52
|
+
domain anahtarı → sb_secret_live_… / sb_public_live_… (kimlik: alan adınızın anahtarı)
|
|
53
|
+
modül anahtarı → odemeHatasi, deploy, browser… (kanal adı; bildirim kuralı burada)
|
|
54
|
+
olay → tek bir kayıt
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
+
Kanal adı (modül anahtarı) **gizli değildir** ve kodun içinde durur: domain
|
|
58
|
+
anahtarı olmadan hiçbir işe yaramaz. Gövdede `key` alanıyla gider.
|
|
59
|
+
|
|
57
60
|
## Tek anahtar
|
|
58
61
|
|
|
59
62
|
`.env` dosyanıza **bir satır** yazarsınız:
|
|
@@ -62,13 +65,13 @@ olay → tek bir kayıt
|
|
|
62
65
|
SIGNALBIRD_DOMAIN_KEY=sb_secret_live_…
|
|
63
66
|
```
|
|
64
67
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
Bu, alan adınızın **gizli domain anahtarıdır** (Panel → Alan adları →
|
|
69
|
+
Anahtarlar) ve sunucu yüzeylerinin hepsini kapsar: Telsiz log yazımı, e-posta,
|
|
70
|
+
SMS, push, kişi ve kampanya, Yönetim. Kapsam (scope) listesi yoktur (v2.0);
|
|
71
|
+
ayrım anahtarın **türündedir** - gizli (`sb_secret_live_…`, sunucu) ya da açık
|
|
72
|
+
(`sb_public_live_…`, istemci). Hangi kanala yazdığınızı **modül anahtarı**
|
|
73
|
+
(kanal adı) belirler. **Adres yazmanız gerekmez** - üretim kökü paketin
|
|
74
|
+
içindedir.
|
|
72
75
|
|
|
73
76
|
Bir de **açık** anahtarlar vardır; onlar `.env`'e değil, sayfanın içine gömülür
|
|
74
77
|
ve gizli olmadıkları için ayrı durmak zorundadırlar:
|
|
@@ -76,7 +79,7 @@ ve gizli olmadıkları için ayrı durmak zorundadırlar:
|
|
|
76
79
|
| Anahtar | Nerede | Ne yapar |
|
|
77
80
|
|---|---|---|
|
|
78
81
|
| `sb_public_live_…` | `<script data-key data-channel>` | sohbet widget'ı, push cihaz kaydı |
|
|
79
|
-
| `sb_public_live_…` | tarayıcı log istemcisi | yalnız izinli alan
|
|
82
|
+
| `sb_public_live_…` | tarayıcı log istemcisi | yalnız izinli kökenlerden (alan adları) |
|
|
80
83
|
|
|
81
84
|
Gizli anahtar tarayıcıya **gömülemez**: sunucu, `Origin` başlığı taşıyan bir
|
|
82
85
|
istekte gizli anahtarı reddeder (`SECRET_KEY_IN_BROWSER`). Bu bir kolaylık
|
|
@@ -94,7 +97,7 @@ değil, kasıtlı bir duvardır - anahtar bir kez istemciye indiğinde herkesind
|
|
|
94
97
|
| Go | `go get github.com/Pariette-Inc/signalbird.sdk` |
|
|
95
98
|
| .NET, ASP.NET Core | `dotnet add package Signalbird.Sdk` |
|
|
96
99
|
| Swift (iOS, macOS) | SPM: `https://github.com/Pariette-Inc/signalbird.sdk` |
|
|
97
|
-
| Kotlin (Android) | `implementation("io.signalbird:signalbird-sdk:2.
|
|
100
|
+
| Kotlin (Android) | `implementation("io.signalbird:signalbird-sdk:2.9.0")` |
|
|
98
101
|
| Canlı sohbet widget'ı (herhangi bir site) | `<script async src="https://signalbird.io/sdk/v1/signalbird.js" data-key="sb_public_live_…" data-channel="destek"></script>` |
|
|
99
102
|
|
|
100
103
|
> Hepsi **bu repodan** çıkar ve **aynı sürümü** taşır - ayrı SDK reposu ya da
|
|
@@ -125,7 +128,10 @@ const sb = new SignalbirdClient({
|
|
|
125
128
|
throwOnError: false, // üretimde kapalı kalmalı
|
|
126
129
|
})
|
|
127
130
|
|
|
128
|
-
await sb.log({
|
|
131
|
+
await sb.log({ key: 'deploy', message: 'v2.4.0 yayında', level: 'info' })
|
|
132
|
+
|
|
133
|
+
// Kanalı bir kez bağlayıp yazmak:
|
|
134
|
+
await sb.radio('deploy').info('v2.4.0 yayında')
|
|
129
135
|
```
|
|
130
136
|
|
|
131
137
|
**Yakalanmamış hatalar:**
|
|
@@ -138,8 +144,8 @@ signalbird().captureUncaught('critical')
|
|
|
138
144
|
|
|
139
145
|
```ts
|
|
140
146
|
const result = await signalbird().batch([
|
|
141
|
-
{
|
|
142
|
-
{
|
|
147
|
+
{ key: 'isler', message: 'iş 1 bitti', level: 'info' },
|
|
148
|
+
{ key: 'isler', message: 'iş 2 bitti', level: 'info' },
|
|
143
149
|
])
|
|
144
150
|
```
|
|
145
151
|
|
|
@@ -178,10 +184,22 @@ const sb = initSignalbird({
|
|
|
178
184
|
|
|
179
185
|
sb.captureErrors('browser') // window.onerror + unhandledrejection
|
|
180
186
|
sb.error('browser', 'sepet güncellenemedi', { cartId })
|
|
187
|
+
|
|
188
|
+
// Kanalı bir kez bağlamak (2.9.0): debug · info · warn · error
|
|
189
|
+
const sepet = sb.radio('sepet')
|
|
190
|
+
sepet.warn('stok azaldı', { sku })
|
|
181
191
|
```
|
|
182
192
|
|
|
193
|
+
Tarayıcı istemcisinin metotları: `log(key, message, level?, context?)`,
|
|
194
|
+
`info`, `warn`, `error`, `radio(key)`, `captureErrors(key?)`, `flush()`,
|
|
195
|
+
`destroy()`. Ayrı bir `critical()` / `debug()` kısayolu **yoktur**: istemci
|
|
196
|
+
kodu herkesin elindedir ve oradan kritik alarm çaldırmak kötüye kullanıma
|
|
197
|
+
açıktır (gerekirse `log(key, msg, 'critical')`; kanalın bildirimi panelde
|
|
198
|
+
susturulabilir).
|
|
199
|
+
|
|
183
200
|
Kayıtlar tek tek değil, **toplu** gider (varsayılan 3 saniyede bir) ve sekme
|
|
184
|
-
kapanırken `sendBeacon` ile boşaltılır
|
|
201
|
+
kapanırken `sendBeacon` ile boşaltılır (`text/plain` gövde - tarayıcı
|
|
202
|
+
cross-origin beacon'da JSON içerik türüne izin vermez).
|
|
185
203
|
|
|
186
204
|
**React** - `app/providers.tsx` ya da `main.tsx`:
|
|
187
205
|
|
|
@@ -209,9 +227,12 @@ export class SignalbirdErrorHandler implements ErrorHandler {
|
|
|
209
227
|
}
|
|
210
228
|
```
|
|
211
229
|
|
|
212
|
-
Panelde
|
|
213
|
-
unutmayın;
|
|
214
|
-
|
|
230
|
+
Panelde açık anahtarın **izinli kökenlerini** (alan adlarını) tanımlamayı
|
|
231
|
+
unutmayın; liste boşken tarayıcı anahtarı hiçbir şey yazamaz
|
|
232
|
+
(`ORIGIN_NOT_ALLOWED`). Kanal bazında bir kısıt **yoktur**: açık anahtar,
|
|
233
|
+
izinli kökenden her kanala yazabilir. Bu yüzden tarayıcıdan yazılan kanalları
|
|
234
|
+
(`browser` gibi) sunucunun kritik kanallarından ayrı tutun ve bildirim
|
|
235
|
+
kurallarını ona göre verin - istemci kodu herkesin elindedir.
|
|
215
236
|
|
|
216
237
|
## PHP / Laravel
|
|
217
238
|
|
|
@@ -238,13 +259,15 @@ SIGNALBIRD_SOURCE=api-01
|
|
|
238
259
|
'signalbird' => [
|
|
239
260
|
'driver' => 'monolog',
|
|
240
261
|
'handler' => \Signalbird\Sdk\SignalbirdLogHandler::class,
|
|
241
|
-
'with' => ['
|
|
262
|
+
'with' => ['key' => 'laravel'], // kanal adı (modül anahtarı)
|
|
242
263
|
'level' => 'error',
|
|
243
264
|
],
|
|
244
265
|
```
|
|
245
266
|
|
|
246
267
|
Sonra `LOG_STACK=single,signalbird`. Mevcut `Log::error()` satırlarınız olduğu
|
|
247
|
-
gibi çalışır; tek satır kod yazmadan Telsiz'e düşerler.
|
|
268
|
+
gibi çalışır; tek satır kod yazmadan Telsiz'e düşerler. `context` içindeki
|
|
269
|
+
istisna (`['exception' => $e]`) sınıf, mesaj, dosya, satır ve ilk 20 yığın
|
|
270
|
+
çerçevesiyle gider (2.9.0).
|
|
248
271
|
|
|
249
272
|
Laravel dışı PHP:
|
|
250
273
|
|
|
@@ -255,6 +278,36 @@ Signalbird::configure('sb_secret_live_…');
|
|
|
255
278
|
Signalbird::error('api', 'veritabanı bağlantısı koptu');
|
|
256
279
|
```
|
|
257
280
|
|
|
281
|
+
## AWS / webhook ile Telsiz'e yazmak
|
|
282
|
+
|
|
283
|
+
SDK kurmanın mümkün olmadığı ya da gereksiz olduğu kaynaklar (AWS alarmları,
|
|
284
|
+
CI, üçüncü parti servisler) Telsiz kanalına **gelen bağlantı adresiyle**
|
|
285
|
+
yazar. Her kanalın kendi adresi vardır; panelde **Telsiz → Kanallar → AWS /
|
|
286
|
+
Webhook** altında oluşturulur:
|
|
287
|
+
|
|
288
|
+
```
|
|
289
|
+
POST https://live.signalbird.io/api/v1/radio/hook/sbh_…
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
- Kimlik URL'deki kanal jetonudur (`sbh_…`), domain anahtarı değil: jetonun
|
|
293
|
+
yetkisi yalnız o kanala log yazmaktır. Jetonu bir sır gibi saklayın;
|
|
294
|
+
sızarsa panelden yenileyin.
|
|
295
|
+
- **AWS SNS:** konuya HTTPS aboneliği olarak bu adresi ekleyin. Abonelik
|
|
296
|
+
onayı (`SubscriptionConfirmation`) kendiliğinden yapılır ve her SNS
|
|
297
|
+
mesajının imzası doğrulanır.
|
|
298
|
+
- **CloudWatch alarmları:** `ALARM` → `critical`, `OK` → `info` seviyesinde
|
|
299
|
+
yazılır.
|
|
300
|
+
- **Herhangi bir sistem** JSON gönderebilir:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
curl -X POST https://live.signalbird.io/api/v1/radio/hook/sbh_… \
|
|
304
|
+
-H 'Content-Type: application/json' \
|
|
305
|
+
-d '{"message": "yedekleme başarısız", "level": "error"}'
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
`level` verilmezse kanalın varsayılan seviyesi geçerlidir; isteğe bağlı
|
|
309
|
+
`context` (nesne) ve `source` alanları da kabul edilir. SDK gerekmez.
|
|
310
|
+
|
|
258
311
|
## Davranış kuralları
|
|
259
312
|
|
|
260
313
|
- **Sessiz hata varsayılandır.** Telsiz erişilemezse çağrı `ok: false` döner ve
|
|
@@ -268,16 +321,26 @@ Signalbird::error('api', 'veritabanı bağlantısı koptu');
|
|
|
268
321
|
- **Kritik seviye sessiz saatleri deler.** Gece üçte ölen servis sabahı bekleyemez.
|
|
269
322
|
- **Tekrar bastırma kaydı değil bildirimi susturur.** Aynı mesaj kanalın
|
|
270
323
|
`dedupe` süresi içinde tekrar gelirse ikinci bildirim gitmez ama kayıt tutulur.
|
|
324
|
+
- **Mesaj 4000 karaktere kırpılır (2.9.0).** API daha uzununu 422 ile reddeder
|
|
325
|
+
ve toplu gönderimde tek uzun satır bütün paketi düşürürdü; SDK göndermeden
|
|
326
|
+
önce kırpar. `context` güvenle serileştirilir: döngüsel başvuru
|
|
327
|
+
`"[Circular]"`, `Error` `{name, message, stack}`, `BigInt` metin olur (PHP'de
|
|
328
|
+
`Throwable` → `class, message, code, file, line, trace`).
|
|
271
329
|
- **SDK sürümünü bildirir (2.6.0).** Her istek `X-Signalbird-Sdk:
|
|
272
330
|
<platform>/<sürüm>` taşır. Yeni sürüm çıktığında SDK süreç başına **bir kez**
|
|
273
331
|
uyarı yazar; eski sürümdeki anahtarların sahiplerine panel bildirimi gider.
|
|
274
332
|
Uyarı hata değildir, istek sonucu değişmez (CONTRACT §14).
|
|
333
|
+
- **Ziyaretçi kimliği doğrulanır (2.7.0).** Sohbet/push ziyaretçisinin
|
|
334
|
+
`external_id`'si ancak sunucunuzda üretilen `identity_hash` ile birlikte
|
|
335
|
+
gelirse güvenilir sayılır: kişi kaydına bağlama, cihaza push ve kanal
|
|
336
|
+
ajanının araçlarına giden güvenilir kimlik buna bağlıdır. Widget ayrıca
|
|
337
|
+
gerektiğinde Cloudflare Turnstile ister (CONTRACT §15).
|
|
275
338
|
|
|
276
339
|
## Gönderim (Messaging)
|
|
277
340
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
341
|
+
Telsiz ile **aynı** gizli domain anahtarıyla (`sb_secret_live_…`) çalışır.
|
|
342
|
+
Açık anahtar burada geçmez - istemci kurulurken `WRONG_KEY_TYPE` ile reddeder.
|
|
343
|
+
Yalnız sunucuda kullanılır.
|
|
281
344
|
|
|
282
345
|
Node:
|
|
283
346
|
|
|
@@ -294,6 +357,16 @@ const r = await sb.sendEmail({
|
|
|
294
357
|
})
|
|
295
358
|
if (!r.ok) console.error(r.code, r.message) // ok:false → code + message
|
|
296
359
|
|
|
360
|
+
// Panelde tanımlı şablonla ve gönderici kanalıyla (PHP: Signalbird::sendMail('noReply')):
|
|
361
|
+
await sb.sendEmail({
|
|
362
|
+
to: 'ali@example.com',
|
|
363
|
+
class: 'transactional',
|
|
364
|
+
template: 'Sipariş Onayı', // ad ya da template_id; varken subject/body gerekmez
|
|
365
|
+
vars: { ad: 'Ali', no: 'S-1234' },
|
|
366
|
+
module_key: 'noReply', // From adresini kanal seçer
|
|
367
|
+
reply_to: 'destek@ornek.com',
|
|
368
|
+
})
|
|
369
|
+
|
|
297
370
|
await sb.sendSms({ to: '+905551112233', class: 'transactional', body: 'Kodunuz: 4821' })
|
|
298
371
|
await sb.sendPush({ to: 'external:user-1042', class: 'transactional', subject: 'Yeni mesaj', body: '…' })
|
|
299
372
|
|
|
@@ -327,7 +400,8 @@ if (! $r['ok']) { Log::warning($r['code'], $r); }
|
|
|
327
400
|
|
|
328
401
|
`.env`: `SIGNALBIRD_DOMAIN_KEY=sb_secret_live_…` (isteğe bağlı `SIGNALBIRD_MESSAGING_URL`,
|
|
329
402
|
`SIGNALBIRD_MESSAGING_TIMEOUT`). Laravel dışı PHP:
|
|
330
|
-
`Signalbird::configureMessaging('
|
|
403
|
+
`Signalbird::configureMessaging('sb_secret_live_…')` ya da
|
|
404
|
+
`new MessagingClient('sb_secret_live_…')`.
|
|
331
405
|
|
|
332
406
|
Metot kümesi iki dilde aynıdır: `sendEmail` `sendSms` `previewSms` `sendPush` ·
|
|
333
407
|
`listContacts` `createContact` `updateContact` `deleteContact` `bulkContacts` ·
|
|
@@ -366,27 +440,30 @@ değil.
|
|
|
366
440
|
takımın kayıtlarına dokunur. Kullanıcı, faturalama ve abonelik işlemleri SDK'da
|
|
367
441
|
yoktur.
|
|
368
442
|
|
|
369
|
-
|
|
443
|
+
Aynı gizli domain anahtarıyla (`sb_secret_live_…`) çalışır; ayrı anahtar ya
|
|
444
|
+
da kapsam (scope) gerekmez. Domain anahtarının kendisi panelden üretilir ve
|
|
445
|
+
döndürülür - SDK anahtar üretmez.
|
|
370
446
|
|
|
371
447
|
```ts
|
|
372
448
|
import { management } from 'signalbird'
|
|
373
449
|
|
|
374
|
-
// Yeni ortam kurulumu:
|
|
375
|
-
const { data } = await management().
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
await vault.write('SIGNALBIRD_DOMAIN_KEY', data!.secret)
|
|
379
|
-
|
|
380
|
-
await management().createRadioChannel(data!.project.id, {
|
|
381
|
-
key: 'odeme',
|
|
382
|
-
name: 'Ödeme',
|
|
450
|
+
// Yeni ortam kurulumu: Telsiz kanalını (modül anahtarını) bildirim kuralıyla aç
|
|
451
|
+
const { data } = await management().createModuleKey('logger', {
|
|
452
|
+
key: 'odeme', // kodda kullanacağınız ad: signalbird().radio('odeme')
|
|
453
|
+
title: 'Ödeme',
|
|
383
454
|
level: 'critical',
|
|
384
|
-
|
|
455
|
+
notify: ['push'],
|
|
385
456
|
quiet_from: 0,
|
|
386
|
-
quiet_to: 7,
|
|
457
|
+
quiet_to: 7, // kritik seviye sessiz saatleri yine de deler
|
|
387
458
|
})
|
|
459
|
+
console.log(data?.module_key.id)
|
|
388
460
|
```
|
|
389
461
|
|
|
462
|
+
`module` ∈ `logger` (Telsiz) · `email` · `sms` · `push` · `chat`. Diğer
|
|
463
|
+
metotlar: `listModuleKeys`, `getModuleKey`, `updateModuleKey` (ad
|
|
464
|
+
değiştirilebilir; eski ad 30 gün kabul edilir), `deleteModuleKey`,
|
|
465
|
+
`listModuleKeyDevices`, `radioSummary`, `radioEvents`.
|
|
466
|
+
|
|
390
467
|
Sohbet gelen kutusunu kendi botunuzla işleyin:
|
|
391
468
|
|
|
392
469
|
```ts
|
|
@@ -409,25 +486,26 @@ const { data } = await management().embedToken({ module: 'chat' })
|
|
|
409
486
|
// data.url → 120 saniyelik, TEK KULLANIMLIK adres; doğrudan <iframe>'e verin
|
|
410
487
|
```
|
|
411
488
|
|
|
412
|
-
|
|
413
|
-
|
|
489
|
+
Anahtarın panelde **gömme jetonu üretebilir** (`can_issue_embed`) onayı
|
|
490
|
+
taşıması gerekir; yoksa 403 `EMBED_NOT_ALLOWED`. Jeton 60 dakikalık bir panel
|
|
491
|
+
oturumuna çevrildiği için bu onay bilerek ayrıdır.
|
|
414
492
|
|
|
415
493
|
Aynısı PHP, Python, Go ve .NET'te birebir aynı metot adlarıyla:
|
|
416
494
|
|
|
417
495
|
```php
|
|
418
|
-
Signalbird::management()->
|
|
496
|
+
Signalbird::management()->createModuleKey('logger', ['key' => 'odeme', 'title' => 'Ödeme']);
|
|
419
497
|
```
|
|
420
498
|
|
|
421
499
|
```python
|
|
422
|
-
signalbird.SignalbirdManagement(
|
|
500
|
+
signalbird.SignalbirdManagement(domain_key=key).create_module_key("logger", {"key": "odeme", "title": "Ödeme"})
|
|
423
501
|
```
|
|
424
502
|
|
|
425
503
|
```go
|
|
426
|
-
admin.
|
|
504
|
+
admin.CreateModuleKey(ctx, "logger", map[string]any{"key": "odeme", "title": "Ödeme"})
|
|
427
505
|
```
|
|
428
506
|
|
|
429
507
|
```csharp
|
|
430
|
-
await management.
|
|
508
|
+
await management.CreateModuleKeyAsync("logger", new Dictionary<string, object?> { ["key"] = "odeme", ["title"] = "Ödeme" });
|
|
431
509
|
```
|
|
432
510
|
|
|
433
511
|
Tam liste (40 metot): `docs/CONTRACT.md § 10`.
|
|
@@ -489,8 +567,8 @@ zaten saklanmıyor.
|
|
|
489
567
|
## Gönderim - müşterinin kendi sisteminden
|
|
490
568
|
|
|
491
569
|
Bir platformun (SubmitCMS, veribenim…) müşterisiyseniz kendi sunucunuzdan da
|
|
492
|
-
gönderim yapabilirsiniz. Gereken tek şey **kendi
|
|
493
|
-
(`
|
|
570
|
+
gönderim yapabilirsiniz. Gereken tek şey **kendi gizli domain anahtarınızdır**
|
|
571
|
+
(`sb_secret_live_…`); panelde Alan adları → Anahtarlar altında durur.
|
|
494
572
|
|
|
495
573
|
```ts
|
|
496
574
|
import { SignalbirdMessaging } from 'signalbird'
|
|
@@ -642,11 +720,43 @@ Signalbird.chat.open() // close() · toggle() · isOpen()
|
|
|
642
720
|
Signalbird.chat.on('unread', (n) => badge.textContent = n)
|
|
643
721
|
Signalbird.push.register({ token, platform: 'web', provider: 'fcm' })
|
|
644
722
|
Signalbird.destroy()
|
|
723
|
+
Signalbird.reset() // kullanıcı ÇIKIŞ yapınca (2.8.0, CONTRACT §15.3)
|
|
645
724
|
```
|
|
646
725
|
|
|
726
|
+
**Çıkışta `Signalbird.reset()` zorunlu (2.8.0).** Ziyaretçi sırrını, sohbet
|
|
727
|
+
geçmişini ve kimliği tarayıcıdan siler; aynı tarayıcıyı kullanan sonraki kişi
|
|
728
|
+
öncekinin sohbetini görmez, destek ajanı onu önceki kullanıcı sanmaz.
|
|
729
|
+
Sunucu da kimliği her oturumda yeniden imza ister.
|
|
730
|
+
|
|
647
731
|
`data-key`/`data-channel` yerine `Signalbird.init({ publicKey, chatKey, baseUrl?, locale? })` da
|
|
648
|
-
çağrılabilir.
|
|
649
|
-
|
|
732
|
+
çağrılabilir.
|
|
733
|
+
|
|
734
|
+
**Kimlik doğrulaması (2.7.0).** Oturum açmış kullanıcıyı tanıtırken
|
|
735
|
+
`external_id`'nin hash'ini SUNUCUNUZDA üretip birlikte verin; yoksa Signalbird
|
|
736
|
+
bu kimliği doğrulanmamış sayar (kişi kaydına bağlamaz, cihaza push hedeflemez,
|
|
737
|
+
ajan araçları kimliği yalnız `visitor.unverified` altında görür):
|
|
738
|
+
|
|
739
|
+
```php
|
|
740
|
+
// Blade - gizli anahtar sunucuda kalır
|
|
741
|
+
<script async src="https://signalbird.io/sdk/v1/signalbird.js"
|
|
742
|
+
data-key="sb_public_live_…" data-channel="destek"
|
|
743
|
+
data-external-id="{{ $user->id }}"
|
|
744
|
+
data-identity-hash="{{ Signalbird::identityHash((string) $user->id) }}"></script>
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
```js
|
|
748
|
+
Signalbird.identify({ external_id: 'user-1042', identityHash: '<sunucudan>', email: 'ali@example.com' })
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
`identity_hash = hex(HMAC-SHA256(hex(SHA-256(sb_secret_live_…)), external_id))`;
|
|
752
|
+
Node `client.identityHash(id)`, Python `client.identity_hash(id)`, Go
|
|
753
|
+
`client.IdentityHash(id)`, .NET `client.IdentityHash(id)`.
|
|
754
|
+
|
|
755
|
+
**Captcha.** Kanalda açıksa widget yeni ziyaretçide ve doğrulanmamış
|
|
756
|
+
ziyaretçinin ilk konuşmasında görünmez bir Cloudflare Turnstile jetonu alır;
|
|
757
|
+
betik yalnız panel ilk açıldığında yüklenir, etkileşim yalnız Cloudflare
|
|
758
|
+
isterse görünür. Kurulumda yapmanız gereken bir şey yoktur. Widget ev sahibi sayfaya asla hata fırlatmaz; Shadow DOM içinde
|
|
759
|
+
çalışır, sayfanızın CSS'iyle çakışmaz; < 40 KB gzip. Ayrıntı:
|
|
650
760
|
`docs/CONTRACT.md § 9` ve https://signalbird.io/sdk/widget.
|
|
651
761
|
|
|
652
762
|
## Gömme (embed) - Signalbird ekranını kendi panelinizde çalıştırın
|
|
@@ -689,21 +799,42 @@ Sunucu tarafı tek çağrıdır (`Signalbird::partner()->createEmbedToken(...)`,
|
|
|
689
799
|
|
|
690
800
|
## Hata kodları
|
|
691
801
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
|
696
|
-
|
|
697
|
-
| `
|
|
698
|
-
| `
|
|
699
|
-
| `
|
|
700
|
-
| `
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
`
|
|
705
|
-
|
|
802
|
+
Telsiz (`/v1/radio/log`, `/v1/radio/log/batch`) ve bütün anahtarlı uçların
|
|
803
|
+
ortak kapısı:
|
|
804
|
+
|
|
805
|
+
| Kod | HTTP | Anlamı |
|
|
806
|
+
|---|---|---|
|
|
807
|
+
| `DOMAIN_KEY_MISSING` | 401 | `X-Signalbird-Key` başlığı yok |
|
|
808
|
+
| `DOMAIN_KEY_INVALID` | 401 | Anahtar tanınmadı ya da kullanım dışı (iptal edilmiş) |
|
|
809
|
+
| `SECRET_KEY_IN_BROWSER` | 401 | Gizli anahtar `Origin` taşıyan (tarayıcı) bir istekte kullanıldı |
|
|
810
|
+
| `SECRET_KEY_IN_QUERY` | 401 | Gizli anahtar sorgu dizesinde (`?k=`) gönderildi |
|
|
811
|
+
| `SECRET_KEY_REQUIRED` | 403 | Uç gizli anahtar ister; açık anahtar verildi |
|
|
812
|
+
| `ORIGIN_REQUIRED` | 403 | Açık (web) anahtar `Origin`'siz, yani sunucudan kullanıldı |
|
|
813
|
+
| `ORIGIN_NOT_ALLOWED` | 403 | İstek kökeni açık anahtarın izinli kökenleri arasında değil |
|
|
814
|
+
| `APP_KEY_IN_BROWSER` | 403 | Mobil uygulama anahtarı web sayfasından kullanıldı |
|
|
815
|
+
| `DOMAIN_INACTIVE` / `TEAM_INACTIVE` | 403 | Alan adı ya da takım pasif |
|
|
816
|
+
| `MODULE_DISABLED` | 403 | Paketinizde Telsiz (`logger`) modülü yok |
|
|
817
|
+
| `MODULE_KEY_INVALID` | 422 | Kanal adı (`key`) geçersiz - normalize edilince boş kalıyor |
|
|
818
|
+
| `MODULE_KEY_DISABLED` | **202** | Kanal panelde kapalı - kayıt yazılmaz, kota da harcanmaz; yanıt `ok: false` taşır, tekrar denemeyin |
|
|
819
|
+
| `LIMIT_REACHED` | 429 | Aylık kayıt limitiniz doldu |
|
|
820
|
+
| `OVERAGE_CEILING_REACHED` | 429 | Aşım tavanına ulaşıldı |
|
|
821
|
+
| `NETWORK_ERROR` | - | SDK sunucuya ulaşamadı (istemci tarafı) |
|
|
822
|
+
|
|
823
|
+
Toplu uçta (`/log/batch`) kapı hatası tüm isteği reddeder; `MODULE_*` ve
|
|
824
|
+
kota kodları ise satır satır `results[i].code` içinde döner. Gövde
|
|
825
|
+
doğrulaması (ör. 4000 karakteri aşan `message`) satır satır DEĞİLDİR - tek
|
|
826
|
+
geçersiz satır bütün paketi 422 ile düşürür; SDK bu yüzden mesajı göndermeden
|
|
827
|
+
kırpar (2.9.0).
|
|
828
|
+
|
|
829
|
+
Gönderim ve Yönetim istemcilerine özgü: `WRONG_KEY_TYPE` (kurulumda, SDK),
|
|
830
|
+
`NO_CONSENT`, `SUPPRESSED`, `NO_SENDING_DOMAIN`, `SENDER_NOT_CONFIGURED`
|
|
831
|
+
(gönderici kanalına adres bağlanmamış), `MODULE_KEY_NOT_FOUND`,
|
|
832
|
+
`LIST_NOT_FOUND`, `EMBED_NOT_ALLOWED`, `MODULE_DISABLED`. SDK eşlemeleri
|
|
833
|
+
(sunucu kod döndürmediğinde): 401 → `API_KEY_INVALID`, 422 →
|
|
834
|
+
`VALIDATION_ERROR`, diğerleri `HTTP_<durum>`; ağ tarafı `NETWORK_ERROR`,
|
|
835
|
+
`TIMEOUT`.
|
|
706
836
|
|
|
707
837
|
Uygulama yüzeyi ve widget: `VISITOR_INVALID` (yerel kimlik silinir, yeni
|
|
708
838
|
oturum açılır), `CHAT_UNAVAILABLE` (kota - "sohbet kullanılamıyor" bandı),
|
|
709
|
-
`NOT_INITIALIZED
|
|
839
|
+
`NOT_INITIALIZED`, `CAPTCHA_REQUIRED` / `CAPTCHA_INVALID` (403 - widget yeni
|
|
840
|
+
jetonla bir kez yeniden dener), `CONVERSATION_RATE_LIMITED` (429 - nazik bant).
|
package/dist/angular.js
CHANGED
|
@@ -5,7 +5,7 @@ var rxjs = require('rxjs');
|
|
|
5
5
|
// src/angular/index.ts
|
|
6
6
|
|
|
7
7
|
// src/shared/version.ts
|
|
8
|
-
var SDK_VERSION = "2.
|
|
8
|
+
var SDK_VERSION = "2.9.0" ;
|
|
9
9
|
var SDK_HEADER = "X-Signalbird-Sdk";
|
|
10
10
|
function sdkHeaderValue(platform) {
|
|
11
11
|
return `${platform}/${SDK_VERSION}`;
|
|
@@ -64,7 +64,7 @@ var SignalbirdApp = class {
|
|
|
64
64
|
}
|
|
65
65
|
if (!config.publicKey.startsWith("sb_public_live_")) {
|
|
66
66
|
throw new Error(
|
|
67
|
-
"Signalbird: uygulama istemcisi a\xE7\u0131k domain anahtar\u0131 ister (sb_public_live_\u2026).
|
|
67
|
+
"Signalbird: uygulama istemcisi a\xE7\u0131k domain anahtar\u0131 ister (sb_public_live_\u2026). Gizli anahtar\u0131 (sb_secret_live_\u2026) istemci koduna KOYMAYIN."
|
|
68
68
|
);
|
|
69
69
|
}
|
|
70
70
|
this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
@@ -73,9 +73,19 @@ var SignalbirdApp = class {
|
|
|
73
73
|
this.doFetch = config.fetchImpl ?? ((...args) => fetch(...args));
|
|
74
74
|
}
|
|
75
75
|
// ── Kimlik ────────────────────────────────────────────────────────────
|
|
76
|
-
/**
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Uygulama ayarları: sohbet açık mı, renk, çalışma saati, ön-form.
|
|
78
|
+
*
|
|
79
|
+
* Oturum açmış kullanıcı biliniyorsa `external_id` + `identity_hash`
|
|
80
|
+
* verilir (CONTRACT §15.3): sunucu kimliği açılışta da doğrular. Kimliksiz
|
|
81
|
+
* açılış ziyaretçiye dokunmaz; çıkışta `signOut()` çağrılır.
|
|
82
|
+
*/
|
|
83
|
+
bootstrap(identity) {
|
|
84
|
+
const id = identity ? withIdentityHash(identity) : void 0;
|
|
85
|
+
return this.request("POST", "/v1/sdk/bootstrap", {
|
|
86
|
+
locale: this.config.locale,
|
|
87
|
+
...id?.external_id && id.identity_hash ? { external_id: id.external_id, identity_hash: id.identity_hash } : {}
|
|
88
|
+
});
|
|
79
89
|
}
|
|
80
90
|
/**
|
|
81
91
|
* Canlı bağlantı kanalı için imza.
|
|
@@ -94,7 +104,7 @@ var SignalbirdApp = class {
|
|
|
94
104
|
* derse yerel kimlik silinir ve bir sonraki çağrı yeni oturum açar.
|
|
95
105
|
*/
|
|
96
106
|
async startSession(input = {}) {
|
|
97
|
-
const result = await this.request("POST", "/v1/sdk/chat/session", input);
|
|
107
|
+
const result = await this.request("POST", "/v1/sdk/chat/session", withIdentityHash(input));
|
|
98
108
|
const visitor = result.data?.visitor;
|
|
99
109
|
if (result.ok && visitor?.id && visitor.secret) {
|
|
100
110
|
await this.storeVisitor({
|
|
@@ -109,7 +119,7 @@ var SignalbirdApp = class {
|
|
|
109
119
|
}
|
|
110
120
|
/** Oturum açmış kullanıcıyı ziyaretçiye bağlar (kişi kaydı upsert edilir). */
|
|
111
121
|
identify(input) {
|
|
112
|
-
return this.request("POST", "/v1/sdk/identify", input);
|
|
122
|
+
return this.request("POST", "/v1/sdk/identify", withIdentityHash(input));
|
|
113
123
|
}
|
|
114
124
|
/** Saklanan ziyaretçi kimliği - yoksa `null`. */
|
|
115
125
|
async currentVisitor() {
|
|
@@ -208,7 +218,7 @@ var SignalbirdApp = class {
|
|
|
208
218
|
* göstereceği ürün kararıdır, kütüphane kararı değil.
|
|
209
219
|
*/
|
|
210
220
|
registerDevice(input) {
|
|
211
|
-
return this.request("POST", "/v1/sdk/devices", input);
|
|
221
|
+
return this.request("POST", "/v1/sdk/devices", withIdentityHash(input));
|
|
212
222
|
}
|
|
213
223
|
/** Çıkışta çağrılır: kayıt silinmez, kapatılır (geçmiş korunur). */
|
|
214
224
|
unregisterDevice(token) {
|
|
@@ -319,6 +329,11 @@ var SignalbirdApp = class {
|
|
|
319
329
|
}
|
|
320
330
|
}
|
|
321
331
|
};
|
|
332
|
+
function withIdentityHash(input) {
|
|
333
|
+
if (!input || input.identityHash === void 0) return input;
|
|
334
|
+
const { identityHash, ...rest } = input;
|
|
335
|
+
return { ...rest, identity_hash: rest.identity_hash ?? identityHash };
|
|
336
|
+
}
|
|
322
337
|
function enc(value) {
|
|
323
338
|
return encodeURIComponent(value);
|
|
324
339
|
}
|