bird

package module
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 6, 2026 License: MIT Imports: 22 Imported by: 0

README

Bird Go SDK

The official Go SDK for the Bird email platform.

go get github.com/messagebird/bird-sdk-go

Requires Go 1.24+.

This SDK is generated from Bird's public OpenAPI bundle inside Bird's internal monorepo, which is the single source of truth; this repository tracks tagged releases. Generation runs in the monorepo, so make generate won't work from a clone here — see CONTRIBUTING.md.

Overview

bird.NewClient(option.WithAPIKey(...)) returns a client whose region is inferred from the API key's prefix (bk_{region}_…); pass option.WithBaseURL or option.WithRegion to override. From there:

  • client.EmailSend, Get, List (auto-paginating; ListPage for manual cursors).
  • client.WebhooksUnwrap (verify a signed event into a typed value).
  • Typed errors. A failure is a *bird.APIError (or a richer *bird.RateLimitError / *bird.ValidationError) you branch on with errors.As. Transient failures (timeouts, 429, 5xx) are retried automatically with a reused idempotency key.
  • Options configure the client and override per call (option.WithEmailDefaults, WithTimeout, WithIdempotencyKey, …).
  • client.Get/Post/Put/Patch/Delete reach endpoints outside the curated surface.

Examples

Runnable, per-method examples live in example_test.go and render under each method on pkg.go.dev: sending (simple and rich), error handling, get, pagination, channel defaults, the webhook receiver, and the escape hatch.

Design

The wire types and a low-level client are generated from the OpenAPI spec into internal/oapi; this package is the hand-written idiomatic layer on top.

Documentation

Overview

Package bird is the Go SDK for the Bird email platform (ADR-0044).

The wire types and a low-level client are generated from the OpenAPI spec into internal/oapi and never hand-edited. This package is the hand-written, idiomatic layer on top: a curated resource surface, a typed error hierarchy, context cancellation, functional options, safe retries with reused idempotency keys, range-over-func pagination, and webhook verification. The request lifecycle lives in internal/requestconfig and the error model in internal/apierror; both are re-exported here.

client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil { ... }
msg, err := client.Email.Send(ctx, bird.EmailSendParams{
	From: "hello@acme.com", To: []string{"customer@example.com"},
	Subject: "Welcome", HTML: "<h1>Hi</h1>",
})
Example

Example constructs a client and sends an email. The region is taken from the API key's prefix; pass option.WithBaseURL or option.WithRegion to override.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	msg, err := client.Email.Send(context.Background(), bird.EmailSendParams{
		From:    "onboarding@messagebird.dev",
		To:      []string{"delivered@messagebird.dev"},
		Subject: "Hello from Bird",
		HTML:    "<p>My first Bird email.</p>",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(msg.Id)
}

Index

Examples

Constants

View Source
const (
	ErrorTypeBadRequest         = apierror.ErrorTypeBadRequest
	ErrorTypeAuth               = apierror.ErrorTypeAuth
	ErrorTypeBilling            = apierror.ErrorTypeBilling
	ErrorTypePermission         = apierror.ErrorTypePermission
	ErrorTypeNotFound           = apierror.ErrorTypeNotFound
	ErrorTypeConflict           = apierror.ErrorTypeConflict
	ErrorTypePrecondition       = apierror.ErrorTypePrecondition
	ErrorTypePayloadTooLarge    = apierror.ErrorTypePayloadTooLarge
	ErrorTypeMisdirected        = apierror.ErrorTypeMisdirected
	ErrorTypeValidation         = apierror.ErrorTypeValidation
	ErrorTypeRateLimit          = apierror.ErrorTypeRateLimit
	ErrorTypeInternal           = apierror.ErrorTypeInternal
	ErrorTypeNotImplemented     = apierror.ErrorTypeNotImplemented
	ErrorTypeServiceUnavailable = apierror.ErrorTypeServiceUnavailable
)

ErrorType values — the coarse categories clients branch on (ADR-0016).

Variables

This section is empty.

Functions

func Bool

func Bool(v bool) *bool

Bool returns a pointer to v.

func Int

func Int(v int) *int

Int returns a pointer to v.

func Ptr

func Ptr[T any](v T) *T

Ptr returns a pointer to v, for setting optional pointer fields inline. Bool, String, and Int are typed shorthands for the common cases:

bird.EmailSendParams{TrackOpens: bird.Bool(false)}

func String

func String(v string) *string

String returns a pointer to v.

Types

type APIError

type APIError = apierror.APIError

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type Category

type Category = oapi.EmailMessageCategory

Category classifies a send's suppression policy.

const (
	CategoryTransactional Category = "transactional"
	CategoryMarketing     Category = "marketing"
)

type Client

type Client struct {
	Email    *EmailService
	Webhooks *WebhookService
	// contains filtered or unexported fields
}

Client is the entry point to the SDK. Construct it with NewClient and reach the API through its resource fields.

func NewClient

func NewClient(opts ...option.RequestOption) (*Client, error)

NewClient builds a Client. An API key is required (option.WithAPIKey); the base URL is derived from the key's region prefix unless option.WithBaseURL or option.WithRegion is given.

func (*Client) Delete

func (c *Client) Delete(ctx context.Context, path string, out any, opts ...option.RequestOption) error

func (*Client) Do

func (c *Client) Do(ctx context.Context, method, path string, body, out any, opts ...option.RequestOption) error

Do is the low-level call the verb methods build on: it marshals body as JSON (when non-nil), runs the request lifecycle, and decodes a 2xx body into out (when non-nil).

func (*Client) Get

func (c *Client) Get(ctx context.Context, path string, out any, opts ...option.RequestOption) error

Get, Post, Put, Patch, and Delete are the escape hatch for endpoints outside the curated surface. They run through the same auth, retry, idempotency, and base-URL handling as the typed methods. body (if non-nil) is sent as JSON; a 2xx response is decoded into out (if non-nil).

var out SuppressionList
err := client.Get(ctx, "/v1/email/suppressions", &out)
Example

The verb methods reach endpoints outside the curated surface, decoding the response into a value you provide.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	var out struct {
		Data []struct {
			Recipient string `json:"recipient"`
		} `json:"data"`
	}
	if err := client.Get(context.Background(), "/v1/email/suppressions", &out); err != nil {
		log.Fatal(err)
	}
	fmt.Println(len(out.Data))
}

func (*Client) Patch

func (c *Client) Patch(ctx context.Context, path string, body, out any, opts ...option.RequestOption) error

func (*Client) Post

func (c *Client) Post(ctx context.Context, path string, body, out any, opts ...option.RequestOption) error

func (*Client) Put

func (c *Client) Put(ctx context.Context, path string, body, out any, opts ...option.RequestOption) error

type ConnectionError

type ConnectionError = apierror.ConnectionError

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type DomainFailedEvent

type DomainFailedEvent = oapi.EventDomainFailed

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type DomainVerifiedEvent

type DomainVerifiedEvent = oapi.EventDomainVerified

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailAcceptedEvent

type EmailAcceptedEvent = oapi.EventEmailAccepted

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailAttachment

type EmailAttachment = oapi.EmailAttachment

EmailAttachment is a file attachment on a send.

type EmailBatch added in v0.2.0

type EmailBatch = oapi.EmailMessageBatchResponse

EmailBatch is the result of a batch send: one item per submitted message, in submission order.

type EmailBatchItem added in v0.2.0

type EmailBatchItem = oapi.EmailMessageBatchItem

EmailBatchItem is a single message's entry in a batch send result.

type EmailBouncedEvent

type EmailBouncedEvent = oapi.EventEmailBounced

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailClickedEvent

type EmailClickedEvent = oapi.EventEmailClicked

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailComplainedEvent

type EmailComplainedEvent = oapi.EventEmailComplained

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailDefaults

type EmailDefaults = requestconfig.EmailDefaults

EmailDefaults are values applied to an email send when the per-send params leave the field unset. Configure with option.WithEmailDefaults.

Example

EmailDefaults set common send fields once; a per-send value always wins.

package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(
		option.WithAPIKey(os.Getenv("BIRD_API_KEY")),
		option.WithEmailDefaults(bird.EmailDefaults{
			From:     "hello@acme.com",
			Category: bird.CategoryTransactional,
		}),
	)
	if err != nil {
		log.Fatal(err)
	}
	// From is filled from the default.
	if _, err := client.Email.Send(context.Background(), bird.EmailSendParams{
		To: []string{"customer@example.com"}, Subject: "Hi", HTML: "<p>hi</p>",
	}); err != nil {
		log.Fatal(err)
	}
}

type EmailDeferredEvent

type EmailDeferredEvent = oapi.EventEmailDeferred

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailDeliveredEvent

type EmailDeliveredEvent = oapi.EventEmailDelivered

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailListParams

type EmailListParams struct {
	Limit         int
	Status        EmailStatus
	Category      Category
	Tag           string
	To            string
	From          string
	CreatedAfter  time.Time
	CreatedBefore time.Time
}

EmailListParams filters the message list. Zero-value fields are omitted.

type EmailListUnsubscribedEvent

type EmailListUnsubscribedEvent = oapi.EventEmailListUnsubscribed

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailMessage

type EmailMessage = oapi.EmailMessage

EmailMessage is a sent message with aggregate delivery status.

type EmailMessageList

type EmailMessageList = oapi.EmailMessageList

EmailMessageList is one page of messages plus its pagination cursors.

type EmailOpenedEvent

type EmailOpenedEvent = oapi.EventEmailOpened

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailOutOfBandBounceEvent

type EmailOutOfBandBounceEvent = oapi.EventEmailOutOfBandBounce

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailProcessedEvent

type EmailProcessedEvent = oapi.EventEmailProcessed

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailReceivedEvent

type EmailReceivedEvent = oapi.EventEmailReceived

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailRejectedEvent

type EmailRejectedEvent = oapi.EventEmailRejected

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailSendBatchParams added in v0.2.0

type EmailSendBatchParams struct {
	Messages []EmailSendParams
}

EmailSendBatchParams is a batch of email sends submitted in one request. Each Message is an individual send; the whole batch is validated before any item is queued. The result preserves submission order.

type EmailSendParams

type EmailSendParams struct {
	From        string            // sender; bare address or "Name <addr>" form; must be on a verified domain
	To          []string          // primary recipients; each may be bare or "Name <addr>" form
	Cc          []string          // optional; same syntax as To
	Bcc         []string          // optional; same syntax as To
	ReplyTo     []string          // optional Reply-To; same syntax as To
	Subject     string            // subject line
	HTML        string            // HTML body; at least one of HTML or Text is required
	Text        string            // plain-text body
	Tags        []EmailTag        // structured {name,value} labels for filtering and analytics
	Metadata    map[string]any    // arbitrary JSON, echoed on reads and in webhook payloads
	Headers     map[string]string // custom email headers
	Attachments []EmailAttachment // file attachments
	Category    Category          // transactional (default) or marketing
	IpPoolId    string            // IP pool ID (ipp_…); workspace default when empty
	// TrackOpens and TrackClicks are pointers because the server default is
	// true — a nil leaves the default, false explicitly disables tracking.
	TrackOpens  *bool
	TrackClicks *bool
}

EmailSendParams is an email send. Optional fields are omitted from the request when left at their zero value.

Address fields (From, To, Cc, Bcc, ReplyTo) accept either a bare email address or RFC 5322 mailbox syntax with a display name: "Support Team <support@example.com>".

type EmailService

type EmailService struct {
	// contains filtered or unexported fields
}

EmailService sends and reads email messages. Reach it via Client.Email.

func (*EmailService) Get

Get returns a single message by ID, with aggregate delivery status rolled up across recipients.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	msg, err := client.Email.Get(context.Background(), "em_abc123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(*msg.Status, *msg.DeliveredCount)
}

func (*EmailService) List

List walks every message matching params, fetching pages lazily. Range over it; the second value is non-nil only on the iteration where a fetch failed, after which the sequence ends.

for msg, err := range client.Email.List(ctx, bird.EmailListParams{Status: bird.EmailStatusBounced}) {
	if err != nil { return err }
	log.Println(msg.Id)
}
Example

List auto-paginates: it lazily fetches each page and yields every matching message across all of them.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	for msg, err := range client.Email.List(context.Background(), bird.EmailListParams{Status: bird.EmailStatusBounced}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(msg.Id)
	}
	page, err := client.Email.ListPage(context.Background(), bird.EmailListParams{}, "")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(len(page.Data)) // page.NextCursor carries the next starting_after
}

func (*EmailService) ListPage

func (s *EmailService) ListPage(ctx context.Context, params EmailListParams, startingAfter string, opts ...option.RequestOption) (*EmailMessageList, error)

ListPage fetches one page of messages. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the most recent.

func (*EmailService) Send

Send delivers an email and returns the created message. Sends are retried safely: a single idempotency key is reused across attempts, so a retry never double-delivers. Provide your own key with option.WithIdempotencyKey.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	msg, err := client.Email.Send(context.Background(), bird.EmailSendParams{
		From:    "onboarding@messagebird.dev",
		To:      []string{"delivered@messagebird.dev"},
		Subject: "Hello from Bird",
		HTML:    "<p>My first Bird email.</p>",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(msg.Id, *msg.Status)
}
Example (DisplayNames)

Send with display names: "Name <addr>" syntax in From and To.

package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	_, err = client.Email.Send(context.Background(), bird.EmailSendParams{
		From:    "Bird Support <support@acme.com>",
		To:      []string{"Jane Doe <jane@example.com>", "bob@example.com"},
		Subject: "Your order is confirmed",
		HTML:    "<p>Thanks for your order!</p>",
	})
	if err != nil {
		log.Fatal(err)
	}
}
Example (Errors)

Branch on the typed error hierarchy. The SDK already retries transient failures (timeouts, 429, 5xx), so a returned error is terminal — most callers just propagate it; branch only to act on a category.

package main

import (
	"context"
	"errors"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	_, err = client.Email.Send(context.Background(), bird.EmailSendParams{
		From: "onboarding@messagebird.dev", To: []string{"delivered@messagebird.dev"}, Subject: "Hello from Bird", HTML: "<p>My first Bird email.</p>",
	})
	if err != nil {
		var rle *bird.RateLimitError
		var ve *bird.ValidationError
		var ae *bird.APIError
		switch {
		case errors.As(err, &rle):
			fmt.Println("rate limited; retry after", rle.RetryAfter)
		case errors.As(err, &ve):
			for _, d := range ve.Details {
				fmt.Printf("%s: %s\n", d.Param, d.Message)
			}
		case errors.As(err, &ae):
			fmt.Printf("API error %s (status %d, request %s)\n", ae.Code, ae.StatusCode, ae.RequestID)
		default:
			log.Print(err) // transport: *bird.ConnectionError or *bird.TimeoutError
		}
	}
}
Example (Rich)

A richer send: cc/bcc, reply-to, tags, metadata, opt-out of click tracking, and an idempotency key (safe to retry — the server dedupes).

package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	_, err = client.Email.Send(context.Background(), bird.EmailSendParams{
		From:        "hello@acme.com",
		To:          []string{"a@example.com", "b@example.com"},
		Cc:          []string{"manager@example.com"},
		ReplyTo:     []string{"support@acme.com"},
		Subject:     "Your March invoice",
		HTML:        "<p>Attached.</p>",
		Tags:        []bird.EmailTag{{Name: "category", Value: "billing"}},
		Metadata:    map[string]any{"invoice_id": "inv_123"},
		TrackClicks: bird.Bool(false),
	}, option.WithIdempotencyKey("invoice-march/cust_1"))
	if err != nil {
		log.Fatal(err)
	}
}

func (*EmailService) SendBatch added in v0.2.0

func (s *EmailService) SendBatch(ctx context.Context, params EmailSendBatchParams, opts ...option.RequestOption) (*EmailBatch, error)

SendBatch queues multiple emails in one request and returns one result item per submitted message, in submission order. The whole batch is validated before any item is queued. Like Send, the batch is retried safely: a single idempotency key is reused across attempts, so a retry never double-delivers. Provide your own key with option.WithIdempotencyKey.

Example

SendBatch queues several emails in one request and returns one result item per message, in submission order.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	batch, err := client.Email.SendBatch(context.Background(), bird.EmailSendBatchParams{
		Messages: []bird.EmailSendParams{
			{
				From:    "onboarding@messagebird.dev",
				To:      []string{"alice@example.com"},
				Subject: "Hello, Alice",
				HTML:    "<p>Welcome!</p>",
			},
			{
				From:    "onboarding@messagebird.dev",
				To:      []string{"bob@example.com"},
				Subject: "Hello, Bob",
				HTML:    "<p>Welcome!</p>",
			},
		},
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, item := range batch.Data {
		fmt.Println(item.Id)
	}
}

type EmailStatus

type EmailStatus = oapi.EmailMessageStatus

EmailStatus is a message's aggregate delivery status.

const (
	EmailStatusAccepted       EmailStatus = "accepted"
	EmailStatusProcessed      EmailStatus = "processed"
	EmailStatusDelivered      EmailStatus = "delivered"
	EmailStatusDeferred       EmailStatus = "deferred"
	EmailStatusBounced        EmailStatus = "bounced"
	EmailStatusComplained     EmailStatus = "complained"
	EmailStatusRejected       EmailStatus = "rejected"
	EmailStatusPartialFailure EmailStatus = "partial_failure"
)

type EmailSuppressionCreatedEvent

type EmailSuppressionCreatedEvent = oapi.EventEmailSuppressionCreated

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailTag

type EmailTag = oapi.EmailTag

EmailTag is a structured {Name, Value} label.

type EmailUnsubscribedEvent

type EmailUnsubscribedEvent = oapi.EventEmailUnsubscribed

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type ErrorDetail

type ErrorDetail = apierror.ErrorDetail

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type ErrorNextAction added in v0.2.2

type ErrorNextAction = apierror.ErrorNextAction

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type ErrorType

type ErrorType = apierror.ErrorType

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type Event

type Event struct {
	// contains filtered or unexported fields
}

Event is a verified webhook event. Switch on Type, or call AsAny and type-switch on the concrete payload (e.g. EmailDeliveredEvent).

func (Event) AsAny

func (e Event) AsAny() (any, error)

AsAny decodes the event into its concrete payload type. An unknown future event type returns an error rather than a panic, so an older SDK keeps working against a newer server.

func (Event) Type

func (e Event) Type() WebhookEventType

Type returns the event's discriminant, e.g. EventTypeEmailDelivered.

type RateLimitError

type RateLimitError = apierror.RateLimitError

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type Response

type Response = requestconfig.Response

Response is the transport metadata for one call, captured via option.WithResponseInto.

type TimeoutError

type TimeoutError = apierror.TimeoutError

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type ValidationError

type ValidationError = apierror.ValidationError

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type WebhookEventType

type WebhookEventType = oapi.WebhookEventType

WebhookEventType is a webhook event's discriminant. It is an open string: the known values are the EventType* constants in eventtypes.gen.go, and an event type added by a newer server flows through Unwrap as a plain string.

const (
	EventTypeDomainFailed            WebhookEventType = "domain.failed"
	EventTypeDomainVerified          WebhookEventType = "domain.verified"
	EventTypeEmailAccepted           WebhookEventType = "email.accepted"
	EventTypeEmailBounced            WebhookEventType = "email.bounced"
	EventTypeEmailCanceled           WebhookEventType = "email.canceled"
	EventTypeEmailClicked            WebhookEventType = "email.clicked"
	EventTypeEmailComplained         WebhookEventType = "email.complained"
	EventTypeEmailDeferred           WebhookEventType = "email.deferred"
	EventTypeEmailDelivered          WebhookEventType = "email.delivered"
	EventTypeEmailListUnsubscribed   WebhookEventType = "email.list_unsubscribed"
	EventTypeEmailOpened             WebhookEventType = "email.opened"
	EventTypeEmailOutOfBandBounce    WebhookEventType = "email.out_of_band_bounce"
	EventTypeEmailProcessed          WebhookEventType = "email.processed"
	EventTypeEmailReceived           WebhookEventType = "email.received"
	EventTypeEmailRejected           WebhookEventType = "email.rejected"
	EventTypeEmailScheduled          WebhookEventType = "email.scheduled"
	EventTypeEmailSuppressionCreated WebhookEventType = "email_suppression.created"
	EventTypeEmailUnsubscribed       WebhookEventType = "email.unsubscribed"
	EventTypeSmsAccepted             WebhookEventType = "sms.accepted"
	EventTypeSmsDelivered            WebhookEventType = "sms.delivered"
	EventTypeSmsExpired              WebhookEventType = "sms.expired"
	EventTypeSmsFailed               WebhookEventType = "sms.failed"
	EventTypeSmsRejected             WebhookEventType = "sms.rejected"
	EventTypeSmsSent                 WebhookEventType = "sms.sent"
	EventTypeSmsUndelivered          WebhookEventType = "sms.undelivered"
)

Webhook event types known at this SDK version. WebhookEventType is an open string on the wire: a value added by a newer server flows through Unwrap unchanged, so switch on these constants with a default branch.

type WebhookService

type WebhookService struct {
	// contains filtered or unexported fields
}

WebhookService verifies inbound webhook deliveries. Reach it via Client.Webhooks. Configure the signing secret with option.WithWebhookSecret on the client (or per call on Unwrap). It is pure crypto — no transport.

func (*WebhookService) Unwrap

func (s *WebhookService) Unwrap(payload []byte, headers http.Header, opts ...option.RequestOption) (Event, error)

Unwrap verifies the Standard Webhooks signature over the raw request body and returns the decoded event. Hand it the exact bytes received — parsing and re-serializing before verifying breaks the signature.

Example

Unwrap verifies the Standard Webhooks signature over the raw request body and returns a typed event to dispatch on.

package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(
		option.WithAPIKey(os.Getenv("BIRD_API_KEY")),
		option.WithWebhookSecret(os.Getenv("BIRD_WEBHOOK_SECRET")),
	)
	if err != nil {
		log.Fatal(err)
	}
	http.HandleFunc("/webhooks/bird", func(w http.ResponseWriter, r *http.Request) {
		body, _ := io.ReadAll(r.Body)
		event, err := client.Webhooks.Unwrap(body, r.Header)
		if err != nil {
			http.Error(w, "invalid signature", http.StatusBadRequest)
			return
		}
		w.WriteHeader(http.StatusNoContent) // ack fast, then process

		payload, _ := event.AsAny()
		switch p := payload.(type) {
		case bird.EmailDeliveredEvent:
			fmt.Println("delivered:", p.Data.EmailId, p.Data.Recipient)
		case bird.EmailBouncedEvent:
			fmt.Println("bounced:", p.Type)
		}
	})
}

type WebhookVerificationError

type WebhookVerificationError = apierror.WebhookVerificationError

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

Directories

Path Synopsis
examples
internal
apierror
Package apierror holds the SDK's error model: the wire-error mapping and the typed error hierarchy returned to callers.
Package apierror holds the SDK's error model: the wire-error mapping and the typed error hierarchy returned to callers.
oapi
Package oapi provides primitives to interact with the openapi HTTP API.
Package oapi provides primitives to interact with the openapi HTTP API.
requestconfig
Package requestconfig holds the resolved per-request configuration.
Package requestconfig holds the resolved per-request configuration.
Package option carries the functional options that configure a bird.Client at construction and override settings for a single call.
Package option carries the functional options that configure a bird.Client at construction and override settings for a single call.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL