trigv

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jul 7, 2026 License: MIT Imports: 14 Imported by: 0

README

trigv-go

Official Trigv SDK for Go. Send notification events from scripts, servers, and CI pipelines.

What Trigv is

Trigv delivers developer notifications to your team's devices. Your backend sends lightweight JSON events; Trigv queues push delivery. Notification title and body are not stored on Trigv servers — metadata only.

Installation

go get github.com/trigv/trigv-go@v1.0.0

Quick start

package main

import (
	"context"
	"log"

	"github.com/trigv/trigv-go"
)

func main() {
	client, err := trigv.NewClient(trigv.ClientConfig{
		APIKey: "trgv_your_api_key",
	})
	if err != nil {
		log.Fatal(err)
	}

	_, err = client.SendEvent(context.Background(), trigv.SendEventRequest{
		Channel:     "general",
		Title:       "Deploy finished",
		Description: "Build #42 succeeded in 38s",
	})
	if err != nil {
		log.Fatal(err)
	}
}

Authentication

Create a workspace API key at app.trigv.com. Keys look like trgv_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.

client, err := trigv.NewClient(trigv.ClientConfig{
	APIKey: "trgv_your_api_key",
})
// or set TRIGV_API_KEY in the environment and omit APIKey

Do not send the API key in the JSON body — the SDK uses the Authorization: Bearer header automatically.

Sending an event

result, err := client.SendEvent(ctx, trigv.SendEventRequest{
	Channel:     "general",
	Title:       "Cron job failed",
	Description: "Nightly backup did not complete",
	Level:       trigv.LevelError,
	EventType:   "cron.failed",
})

Event options

Field Required Description
Channel Yes Channel slug (e.g. general)
Title Yes Notification title
Description No Body text
ImageURL No HTTPS image URL (not stored server-side)
URL No Destination URL for the notification (max 2048 characters; not stored server-side)
Level No info, success, warning, error (default: info)
DeliveryUrgency No standard or time_sensitive (default: standard)
EventType No Free-form label (e.g. deploy.completed)
IdempotencyKey No Dedup key per workspace

Levels

  • info — general information (default)
  • success — completed successfully
  • warning — attention needed
  • error — failure or alert

Delivery urgency

  • standard — normal notifications (default)
  • time_sensitive — iOS Time Sensitive delivery (requires user permission)

Idempotency

When you set IdempotencyKey, retries with the same key return the existing event (Duplicate: true, HTTP 200) without billing again.

result, err := client.SendEvent(ctx, trigv.SendEventRequest{
	Channel:        "deploys",
	Title:          "Production deploy complete",
	IdempotencyKey: "deploy-prod-42",
})

Error handling

result, err := client.SendEvent(ctx, req)
if err != nil {
	var validationErr *trigv.ValidationError
	var notFoundErr *trigv.NotFoundError
	var rateErr *trigv.RateLimitError

	switch {
	case errors.As(err, &validationErr):
		log.Println(validationErr.Errors)
	case errors.As(err, &notFoundErr):
		log.Println("channel not found")
	case errors.As(err, &rateErr):
		if rateErr.Retryable {
			log.Println("retry later")
		} else {
			log.Println("monthly limit reached")
		}
	default:
		log.Println(err)
	}
}

Typed errors support errors.Is with sentinels such as trigv.ErrAuthentication and trigv.ErrNotFound.

Configuration

Option Default Description
APIKey TRIGV_API_KEY env Workspace API key
BaseURL https://api.trigv.com/api API base URL
Timeout 30 Request timeout (seconds)
MaxRetries 2 Retries for retryable errors (nil uses default; 0 disables)
Verify connection
connection, err := client.VerifyConnection(ctx)
if err != nil {
	log.Fatal(err)
}
log.Println(connection.Workspace.Name)

Examples

See the examples/ directory:

  • Basic event
  • Deploy completed (canonical example)
  • Warning event
  • Idempotency
  • Cron job failed
  • WooCommerce order notification
  • AI agent task completed

Run an example (requires TRIGV_API_KEY):

TRIGV_API_KEY=trgv_... go run ./examples/basic

Development

go test ./...
go vet ./...
gofmt -w .

Testing

go test ./...

Tests use httptest — no live API key required.

Contributing

Contributions welcome. Please open an issue before large changes.

Licence

MIT

Documentation

Index

Constants

View Source
const (
	// Version is the SDK release version.
	Version = "1.0.0"

	// DefaultBaseURL is the production API base URL.
	DefaultBaseURL = "https://api.trigv.com/api"

	// DefaultTimeout is the default HTTP client timeout.
	DefaultTimeout = 30

	// DefaultMaxRetries is the default number of retries for retryable errors.
	DefaultMaxRetries = 2
)

Variables

View Source
var (
	ErrValidation     = errors.New("trigv: validation error")
	ErrAuthentication = errors.New("trigv: authentication error")
	ErrAuthorization  = errors.New("trigv: authorization error")
	ErrNotFound       = errors.New("trigv: not found")
	ErrRateLimit      = errors.New("trigv: rate limit")
	ErrAPI            = errors.New("trigv: api error")
	ErrNetwork        = errors.New("trigv: network error")
	ErrTimeout        = errors.New("trigv: timeout")
)

Sentinel errors for errors.Is matching.

View Source
var DeliveryUrgencies = []string{"standard", "time_sensitive"}

DeliveryUrgency values accepted by the ingest API.

View Source
var FieldMaxLengths = map[string]int{
	"channel":         120,
	"title":           255,
	"description":     1000,
	"image_url":       2048,
	"url":             2048,
	"event_type":      120,
	"idempotency_key": 190,
}

FieldMaxLengths mirrors API contract limits.

View Source
var Levels = []string{"info", "success", "warning", "error"}

Notification levels accepted by the ingest API.

View Source
var ProhibitedFields = []string{"api_key", "icon"}

ProhibitedFields must not appear in ingest request bodies.

Functions

func IsMonthlyLimitMessage

func IsMonthlyLimitMessage(message string) bool

IsMonthlyLimitMessage reports whether a 429 message is the workspace monthly cap.

Types

type APIError

type APIError struct {
	Message    string
	StatusCode int
	Body       any
}

APIError is returned for other HTTP error responses.

func (*APIError) Error

func (e *APIError) Error() string

func (*APIError) Is

func (e *APIError) Is(target error) bool

type AuthenticationError

type AuthenticationError struct {
	Message    string
	StatusCode int
}

AuthenticationError is returned for HTTP 401 responses.

func (*AuthenticationError) Error

func (e *AuthenticationError) Error() string

func (*AuthenticationError) Is

func (e *AuthenticationError) Is(target error) bool

type AuthorizationError

type AuthorizationError struct {
	Message    string
	StatusCode int
}

AuthorizationError is returned for HTTP 403 responses.

func (*AuthorizationError) Error

func (e *AuthorizationError) Error() string

func (*AuthorizationError) Is

func (e *AuthorizationError) Is(target error) bool

type Client

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

Client is the Trigv ingest API client.

func NewClient

func NewClient(cfg ClientConfig) (*Client, error)

NewClient creates a Client from configuration. APIKey may be omitted when TRIGV_API_KEY is set in the environment.

func (*Client) SendEvent

func (c *Client) SendEvent(ctx context.Context, req SendEventRequest) (*SendEventResult, error)

SendEvent posts an event to POST /v1/events.

func (*Client) UserAgent

func (c *Client) UserAgent() string

UserAgent returns the SDK user-agent string.

func (*Client) VerifyConnection

func (c *Client) VerifyConnection(ctx context.Context) (*ConnectionResult, error)

VerifyConnection checks the API key via GET /v1/connection.

type ClientConfig

type ClientConfig struct {
	// APIKey is the workspace ingest API key (trgv_…).
	// When empty, TRIGV_API_KEY from the environment is used.
	APIKey string

	// BaseURL is the API base URL. Default: DefaultBaseURL.
	BaseURL string

	// Timeout is the HTTP client timeout in seconds. Default: DefaultTimeout.
	Timeout int

	// MaxRetries is the number of retries for retryable errors.
	// When nil, DefaultMaxRetries is used. Set to a pointer to 0 to disable retries.
	MaxRetries *int

	// HTTPClient is an optional custom HTTP client (primarily for testing).
	HTTPClient HTTPDoer
}

ClientConfig configures a Trigv API client.

type ConnectionAPIKey

type ConnectionAPIKey struct {
	PublicID string `json:"public_id"`
	Name     string `json:"name"`
	Prefix   string `json:"prefix"`
}

ConnectionAPIKey is API key metadata from GET /v1/connection.

type ConnectionResult

type ConnectionResult struct {
	Workspace ConnectionWorkspace `json:"workspace"`
	APIKey    ConnectionAPIKey    `json:"api_key"`
}

ConnectionResult is the parsed success response from GET /v1/connection.

type ConnectionWorkspace

type ConnectionWorkspace struct {
	PublicID string `json:"public_id"`
	Name     string `json:"name"`
}

ConnectionWorkspace is workspace metadata from GET /v1/connection.

type DeliveryUrgency

type DeliveryUrgency string

DeliveryUrgency controls iOS delivery urgency.

const (
	UrgencyStandard      DeliveryUrgency = "standard"
	UrgencyTimeSensitive DeliveryUrgency = "time_sensitive"
)

type Event

type Event struct {
	PublicID          string  `json:"public_id"`
	EventUUID         string  `json:"event_uuid"`
	Status            string  `json:"status"`
	Level             string  `json:"level"`
	EventType         *string `json:"event_type"`
	TargetDeviceCount int     `json:"target_device_count"`
	ReceivedAt        string  `json:"received_at"`
}

Event is the event metadata returned by the ingest API.

type HTTPDoer

type HTTPDoer interface {
	Do(req *http.Request) (*http.Response, error)
}

HTTPDoer performs HTTP requests. *http.Client implements this interface.

type NetworkError

type NetworkError struct {
	Message string
	Cause   error
}

NetworkError is returned for connection-level failures.

func (*NetworkError) Error

func (e *NetworkError) Error() string

func (*NetworkError) Is

func (e *NetworkError) Is(target error) bool

func (*NetworkError) Unwrap

func (e *NetworkError) Unwrap() error

type NotFoundError

type NotFoundError struct {
	Message    string
	StatusCode int
}

NotFoundError is returned for HTTP 404 responses.

func (*NotFoundError) Error

func (e *NotFoundError) Error() string

func (*NotFoundError) Is

func (e *NotFoundError) Is(target error) bool

type NotificationLevel

type NotificationLevel string

NotificationLevel is an ingest event severity level.

const (
	LevelInfo    NotificationLevel = "info"
	LevelSuccess NotificationLevel = "success"
	LevelWarning NotificationLevel = "warning"
	LevelError   NotificationLevel = "error"
)

type RateLimitError

type RateLimitError struct {
	Message    string
	StatusCode int
	Retryable  bool
	// contains filtered or unexported fields
}

RateLimitError is returned for HTTP 429 responses.

func (*RateLimitError) Error

func (e *RateLimitError) Error() string

func (*RateLimitError) Is

func (e *RateLimitError) Is(target error) bool

type SendEventRequest

type SendEventRequest struct {
	Channel         string            `json:"channel"`
	Title           string            `json:"title"`
	Description     string            `json:"description,omitempty"`
	ImageURL        string            `json:"image_url,omitempty"`
	URL             string            `json:"url,omitempty"`
	Level           NotificationLevel `json:"level,omitempty"`
	DeliveryUrgency DeliveryUrgency   `json:"delivery_urgency,omitempty"`
	EventType       string            `json:"event_type,omitempty"`
	IdempotencyKey  string            `json:"idempotency_key,omitempty"`
}

SendEventRequest is the payload for POST /v1/events.

type SendEventResult

type SendEventResult struct {
	Event     Event
	Duplicate bool // true when HTTP 200 (duplicate idempotency key)
}

SendEventResult is the parsed success response from POST /v1/events.

type TimeoutError

type TimeoutError struct {
	Message string
}

TimeoutError is returned when a request times out.

func (*TimeoutError) Error

func (e *TimeoutError) Error() string

func (*TimeoutError) Is

func (e *TimeoutError) Is(target error) bool

type ValidationError

type ValidationError struct {
	Message string
	Errors  ValidationErrors
}

ValidationError is returned for client-side or HTTP 422 validation failures.

func (*ValidationError) Error

func (e *ValidationError) Error() string

func (*ValidationError) Is

func (e *ValidationError) Is(target error) bool

type ValidationErrors

type ValidationErrors map[string][]string

ValidationErrors maps field names to validation messages.

Directories

Path Synopsis
examples
ai_agent command
Example: AI agent task completed notification.
Example: AI agent task completed notification.
basic command
Example: send a basic event to the general channel.
Example: send a basic event to the general channel.
cron_failed command
Example: notify when a cron job fails.
Example: notify when a cron job fails.
deploy_completed command
Example: canonical deploy-completed notification.
Example: canonical deploy-completed notification.
idempotency command
Example: idempotent event delivery with a deduplication key.
Example: idempotent event delivery with a deduplication key.
warning_event command
Example: warning-level event.
Example: warning-level event.
woocommerce_order command
Example: WooCommerce new order notification.
Example: WooCommerce new order notification.

Jump to

Keyboard shortcuts

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