.NET SDK
Pushizo (NuGet) — .NET 8, HttpClient ve System.Text.Json; üretilen modeller ve kaynaklar, yeniden deneme, idempotency, IAsyncEnumerable sayfalama, webhook imza doğrulaması.
Kaynak: sdk/dotnet. Modeller (Pushizo.Models), parametre sınıfları (Pushizo.Params) ve kaynaklar (Pushizo.Resources) api/openapi.yaml'dan üretilir (src/Pushizo/Generated/); kimlik doğrulama, yeniden deneme, idempotency, sayfalama ve webhook imza doğrulaması el yazımıdır. Ek bağımlılık yoktur.
Kurulum
dotnet add package PushizoKullanım
using Pushizo;
using Pushizo.Models;
using Pushizo.Params;
using var hs = new PushizoClient(new PushizoOptions
{
ApiKey = Environment.GetEnvironmentVariable("HS_API_KEY")!,
AppId = "app_…",
// BaseUrl = "http://localhost:4000",
});
// Bildirim gönder: Idempotency-Key verilmezse otomatik UUID
var res = await hs.Notifications.CreateAsync(new CreateNotificationDto
{
Target = new CreateNotificationDtoTarget { IncludeAliases = new() { ["external_id"] = new() { "user-42" } } },
Contents = new() { ["en"] = "Your order shipped", ["tr"] = "Siparişiniz kargoya verildi" },
}, new RequestOptions { IdempotencyKey = "order-1001" });
Console.WriteLine($"{res.Id} {res.Status}");
// Kullanıcı oluştur/güncelle
await hs.Users.UpsertAsync(new UpsertUserDto { ExternalId = "user-42", Tags = new() { ["plan"] = "pro" } });
// Cursor sayfalama: IAsyncEnumerable, sayfalar tembel yüklenir
await foreach (var segment in hs.Segments.ListAllAsync(new SegmentsListParams { Limit = 100 }))
{
Console.WriteLine(segment.Name);
}
// Başka bir app için tek çağrı
await hs.Apps.GetAsync(RequestOptions.ForApp("app_diger"));
// SDK identity verification
var identityHash = PushizoClient.IdentityHash(Environment.GetEnvironmentVariable("HS_SDK_SECRET")!, "user-42");ASP.NET Core'da IHttpClientFactory ile: new PushizoOptions { ApiKey = …, HttpClient = factory.CreateClient("pushizo") }. Tüm model özellikleri nullable'dır; null alanlar gönderilmez. Kaynaklar hs.Notifications, hs.Users, hs.Aliases, hs.Subscriptions, hs.Events, hs.Channels, hs.Segments, hs.Templates, hs.Campaigns, hs.Journeys, hs.InAppMessages, hs.Inbox, hs.Categories, hs.Preferences, hs.Suppressions, hs.Webhooks, hs.Analytics, hs.Exports, hs.Imports, hs.ApiKeys, hs.Apps, hs.Organization; her metot …Async son ekiyle RequestOptions ve CancellationToken alır. A/B kazananı: hs.Campaigns.SelectWinnerAsync, hs.InAppMessages.SelectWinnerAsync (InAppMessages.WinnerAsync eski addır, [Obsolete]). SDK'da metodu olmayan uçlar ya da JSON dışı yanıtlar için hs.RequestAsync("GET", "/v1/apps/{appId}/analytics/messages", new Dictionary<string, object?> { ["format"] = "csv" }) gövdeyi metin döner.
Ayarlar
PushizoOptions | Varsayılan | Açıklama |
|---|---|---|
ApiKey | — | hs_live_… API anahtarı (Bearer) |
AppId | — | Çağrıda RequestOptions.AppId verilmezse kullanılan app |
BaseUrl | https://api.pushizo.com | API adresi |
Timeout | 30 sn | Deneme başına zaman aşımı |
MaxRetries | 3 | En fazla yeniden deneme (politika) |
AutoIdempotencyKey | true | Idempotency-Key destekleyen çağrılarda otomatik UUID |
HttpClient | yeni örnek | Özel HttpClient |
Hatalar
Kalıcı hatalar PushizoException alt sınıflarıdır: Status, Code, RequestId, Details.
try
{
await hs.Notifications.GetAsync("msg_yok");
}
catch (NotFoundException) { /* 404 */ }
catch (InvalidRequestException e) when (e.Code == ErrorCodes.NoRecipients) { /* 422 */ }
catch (PushizoException e) { Console.WriteLine($"{e.Status} {e.Code} {e.Message}"); }
// Diğer alt sınıflar: AuthenticationException, PermissionDeniedException, ConflictException, RateLimitException, ServerException, NetworkExceptionYeniden deneme politikası
Yeniden denemeler üstel geri çekilmeyle (0,3 / 1 / 3 sn; Retry-After başlığı varsa ona uyulur) en fazla MaxRetries kez yapılır. Sunucuda tekrarlanması güvenli olmayan isteklerin çift işlenmemesi için kural HTTP metoduna göre değişir:
| Durum | GET, HEAD, OPTIONS, PUT, DELETE | POST, PATCH |
|---|---|---|
429 | Yeniden denenir | Yeniden denenir (istek işlenmeden reddedilmiştir) |
5xx, zaman aşımı, gönderim sonrası bağlantı kopması | Yeniden denenir | Yalnızca Idempotency-Key varsa |
İstek hiç gönderilemedi (HttpRequestError.NameResolutionError/ConnectionError, SocketError.ConnectionRefused/HostNotFound/HostUnreachable) | Yeniden denenir | Yeniden denenir |
Diğer 4xx | Denenmez | Denenmez |
5xx ya da gönderim sonrası ağ hatasında sunucu isteği işlemiş olabilir; anahtarsız bir POST/PATCH tekrarı çift bildirim veya kayıt üretebilir. Notifications.CreateAsync ve Users.UpsertAsync anahtar verilmezse otomatik UUID üretir (otomatik anahtar kapatılmadıysa), bu yüzden bu iki çağrı güvenle yeniden denenir. Başka bir POST/PATCH çağrısının da yeniden denenmesini istiyorsanız anahtarı kendiniz verin: await hs.Events.SendAsync(body, new RequestOptions { IdempotencyKey = $"evt-{id}" }). Yeniden denemelerde aynı anahtar gönderilir; API aynı anahtarla 24 saat içinde gelen tekrarı ilk yanıtla karşılar.
Webhook imza doğrulaması
app.MapPost("/hooks/pushizo", async (HttpRequest request) =>
{
using var ms = new MemoryStream();
await request.Body.CopyToAsync(ms); // ham gövde
try
{
var events = Webhooks.ConstructEvents(ms.ToArray(),
request.Headers[Webhooks.SignatureHeader],
new[] { Environment.GetEnvironmentVariable("HS_WEBHOOK_SECRET")! }); // rotasyonda eski + yeni secret
foreach (var ev in events) { /* ev.Id ile tekrarları ayıklayın; ev.Type, ev.Data */ }
return Results.NoContent();
}
catch (WebhookSignatureException e)
{
return Results.BadRequest(e.Reason);
}
});Yalnızca doğrulama için Webhooks.VerifySignature(...) WebhookVerifyResult(Ok, Timestamp, Reason) döner. Olay türleri: Webhook'lar.
Geliştirme
dotnet test # sdk/dotnet içinde (xUnit)
node sdk/scripts/generate-server-sdks.mjs --lang dotnet # depo kökünde; Generated/ yenilenirJava SDK
io.pushizo:pushizo-java — Java 17+, java.net.http ve Jackson; üretilen modeller, parametre sınıfları ve kaynaklar; yeniden deneme, idempotency, sayfalama, webhook imza doğrulaması.
Ruby SDK
pushizo (RubyGems) — Ruby 3.0+, Net::HTTP; üretilen modeller ve kaynak metotları, yeniden deneme, idempotency, Enumerator sayfalama, webhook imza doğrulaması.