go get github.com/Pariette-Inc/signalbird.sdk/v2signalbird - Go
Üç yüzey taşır: Telsiz (log), Gönderim (e-posta/SMS/push) ve Yönetim (proje, sohbet gelen kutusu, uygulama).
Kurulum
go get github.com/Pariette-Inc/signalbird.sdk/v2import "github.com/Pariette-Inc/signalbird.sdk/v2/src/go/signalbird"Go 1.21+ gerekir. Bağımlılığı yoktur - yalnız standart kütüphane.
Anahtarlar
| Yüzey | Tip | Anahtar |
|---|---|---|
| Telsiz | signalbird.Client |
sb_secret_live_… |
| Gönderim | signalbird.Messaging |
sb_… |
| Yönetim | signalbird.Management |
sb_… + kapsam |
Telsiz - log ve olay
radio, err := signalbird.NewClientFromEnv() // SIGNALBIRD_DOMAIN_KEY / _URL / _SOURCE
if err != nil {
log.Fatal(err)
}
radio.Critical(ctx, "critical", "ödeme servisi yanıt vermiyor", map[string]any{
"service": "iyzico",
"attempt": 3,
})
radio.Info(ctx, "info", "ahmet@x.com yeni hesap oluşturdu", nil)Kendi yapılandırmanız:
radio, err := signalbird.NewClient(signalbird.Config{
DomainKey: os.Getenv("SIGNALBIRD_DOMAIN_KEY"),
Source: "api-01",
Timeout: 5 * time.Second, // varsayılan
ThrowOnError: false, // varsayılan: sessiz hata
})Beş seviye: LevelDebug, LevelInfo, LevelWarn, LevelError,
LevelCritical. Seviye vermezseniz kanalın kendi varsayılanı geçerlidir.
Toplu gönderim
result, err := radio.Batch(ctx, []signalbird.Event{
{Channel: "deploy", Message: "v2.4.0 yayında", Level: signalbird.LevelInfo},
{Channel: "critical", Message: "kuyruk doldu"},
})En fazla 100 kayıt; kısmi başarı normaldir ve başarısız satırlar yeniden denenmez.
HTTP middleware deseni
func SignalbirdRecovery(radio *signalbird.Client) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if recovered := recover(); recovered != nil {
// Log göndermek isteği bekletmesin: bağlam kopyalanır
radio.Critical(context.WithoutCancel(r.Context()), "critical",
fmt.Sprint(recovered), map[string]any{
"path": r.URL.Path,
"method": r.Method,
})
http.Error(w, "internal error", http.StatusInternalServerError)
}
}()
next.ServeHTTP(w, r)
})
}
}Gönderim - e-posta, SMS, push
send, err := signalbird.NewMessaging(signalbird.KeyConfig{
DomainKey: os.Getenv("SIGNALBIRD_DOMAIN_KEY"),
})
result, err := send.SendEmail(ctx, map[string]any{
"to": "ahmet@example.com",
"class": "transactional", // ZORUNLU, varsayılanı yok
"subject": "Siparişiniz yola çıktı",
"body": "<p>Kargo takip no: 1234</p>",
})
if err != nil || !result.OK {
log.Printf("signalbird: %s - %s", result.Code, result.Message)
}send.SendSms(ctx, map[string]any{"to": "+905551112233", "class": "transactional", "body": "Kodunuz: 123456"})
send.PreviewSms(ctx, "Merhaba, siparişiniz hazır.") // parça hesabı, kota harcamaz
send.SendPush(ctx, map[string]any{"to": "contact:42", "class": "transactional", "subject": "Sipariş", "body": "Yola çıktı"})Kişiler
send.ListContacts(ctx, signalbird.Query{"q": "ahmet", "page": 1})
send.CreateContact(ctx, map[string]any{"email": "ahmet@example.com"})
send.UpdateContact(ctx, contactID, map[string]any{"phone": "+905551112233"})
send.DeleteContact(ctx, contactID)
// 1000'lik parçalar, SIRAYLA
send.BulkContacts(ctx, map[string]any{
"contacts": rows, // []any ya da []map[string]any
"list_id": 42,
})Kampanyalar
send.CreateCampaign(ctx, map[string]any{
"name": "Ağustos bülteni",
"channel": "email",
"list_id": 42,
"subject": "Bu ay neler oldu?",
"body": "<h1>Merhaba</h1>",
})
// Sayfaları gezer; fn false dönerse durur
send.IterateCampaignMessages(ctx, batchID, nil, func(row map[string]any) bool {
reconcile(row["external_ref"], row["status"])
return true
})Webhook doğrulama
func handleWebhook(w http.ResponseWriter, r *http.Request) {
raw, _ := io.ReadAll(r.Body)
// HAM gövde üzerinde: json.Unmarshal + Marshal imzayı bozar
if !signalbird.VerifyWebhook(raw, r.Header.Get("X-Signalbird-Signature"), secret) {
http.Error(w, "invalid signature", http.StatusUnauthorized)
return
}
var event struct {
ID string `json:"id"`
Type string `json:"type"`
}
json.Unmarshal(raw, &event)
// Yeniden gönderimlere karşı `id` ile tekilleştirin
if seen(event.ID) {
w.WriteHeader(http.StatusOK)
return
}
}Yönetim - kendi projenizi kurun
admin, err := signalbird.NewManagement(signalbird.KeyConfig{
DomainKey: os.Getenv("SIGNALBIRD_DOMAIN_KEY"),
})
created, _ := admin.CreateModuleKey(ctx, "logger", map[string]any{"title": "Ödeme hataları"})
var payload struct {
Project struct{ ID int } `json:"project"`
Secret string `json:"secret"` // YALNIZ burada döner
}
created.Into(&payload)
admin.CreateRadioChannel(ctx, payload.Project.ID, map[string]any{
"key": "odeme",
"name": "Ödeme",
"level": "critical",
"notify_push": true,
})
// Sohbet gelen kutusu
inbox, _ := admin.ListConversations(ctx, signalbird.Query{"status": "open"})
admin.Reply(ctx, conversationID, map[string]any{"body": "Merhaba! Birazdan dönüyoruz."})
admin.SetConversationStatus(ctx, conversationID, "resolved")Anahtarınızın radio:*, chat:*, apps:* kapsamlarını taşıması gerekir.
Ayrıntı: Yönetim dokümanı.
Sonuç biçimi
type Result struct {
OK bool
Status int
Data json.RawMessage
Code string
Message string
}Gövdeyi çözmek için Into:
var project struct {
Project struct {
ID int `json:"id"`
Name string `json:"name"`
} `json:"project"`
}
result.Into(&project)ThrowOnError: true iken metotlar ikinci dönüş değerinde *signalbird.Error
verir (Code, Status, Message, Body).
Ziyaretçi kimliği doğrulaması - identityHash
Sohbet widget'ı ve uygulama SDK'sı oturum açmış kullanıcıyı external_id ile
tanıtır. Açık anahtar sayfada durduğu için Signalbird bu kimliği ancak
yanında sizin sunucunuzda üretilmiş geçerli bir hash varsa güvenilir sayar
(2.7.0). Hash olmadan ziyaretçi kişi kaydına bağlanmaz, cihazı o kullanıcıya
push hedefi olarak bağlanmaz ve kanal ajanının araçları kimliği yalnız
visitor.unverified altında görür.
client, _ := signalbird.NewClientFromEnv()
hash := client.IdentityHash(user.ID)Gizli anahtarı zaten tutan Telsiz istemcisinin üzerindedir; ayrı kurulum gerekmez. Algoritma (her dilde aynı çıktı):
identity_hash = hex( HMAC-SHA256( hex(SHA-256(sb_secret_live_…)), external_id ) )Anahtar gizli anahtarın SHA-256 özetidir (sunucu anahtarı düz saklamaz). Kullanım: Widget - Kimlik doğrulaması, Uygulama SDK'sı.
Sürüm bildirimi
SDK her istekte sürümünü bildirir: X-Signalbird-Sdk: go/<sürüm>. Yeni bir
sürüm yayınlandığında API yanıtında Signalbird-Sdk-Status: outdated (ya da
artık desteklenmiyorsa unsupported) döner ve SDK süreç başına bir kez
uyarı yazar (log.Printf). Uyarı hata değildir: isteğin sonucu değişmez.
Panelde Domainler → [domain] → Anahtarlar her anahtarın hangi SDK sürümüyle kullanıldığını gösterir; eski sürümdeki anahtarlar için panelin tepesinde bir uyarı şeridi ve bildirim çıkar. Güncellemek için:
go get github.com/Pariette-Inc/signalbird.sdk/v2@latestHata kodları
| Kod | Anlamı |
|---|---|
ErrNoKey / ErrWrongKeyType |
Kurulum anında (NewClient hatası) |
INVALID_KEY |
Anahtar yok, yanlış ya da proje pasif |
API_KEY_SCOPE |
Anahtarda gereken kapsam yok |
MODULE_DISABLED |
Paketinizde bu modül yok |
LIMIT_REACHED |
Aylık limitiniz doldu |
VALIDATION_ERROR |
422 |
NETWORK_ERROR / TIMEOUT |
Ağ (status 0) |
Davranış kuralları
- Sessiz hata varsayılandır:
err == nilamaresult.OK == falseolabilir. İkisini de kontrol edin. - Retry yoktur. Yeniden deneme kararı çağıranındır.
contexther metotta ilk parametredir; isteğin iptali size bağlıdır.- Sorgu dizesinde
nilalanlar atlanır, dilimlerkey[]=biçiminde gider, booletrue/falsemetnine çevrilir.