activitysmith

package module
v1.1.0 Latest Latest
Warning

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

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

README

ActivitySmith Go SDK

The ActivitySmith Go SDK provides convenient access to the ActivitySmith API from Go applications.

Documentation

See API reference.

Installation

go get github.com/ActivitySmithHQ/activitysmith-go

Setup

package main

import (
	"log"

	activitysmithsdk "github.com/ActivitySmithHQ/activitysmith-go"
)

func main() {
	activitysmith, err := activitysmithsdk.New("YOUR_API_KEY")
	if err != nil {
		log.Fatal(err)
	}

	_ = activitysmith
}

Push Notifications

Send a Push Notification

Push notification example

Use activitysmith.Notifications.Send with either activitysmithsdk.PushNotificationInput for common notification fields or generated.PushNotificationRequest if you want full control over the generated model.

input := activitysmithsdk.PushNotificationInput{
	Title:   "New subscription 💸",
	Message: "Customer upgraded to Pro plan",
}

_, err := activitysmith.Notifications.Send(input)
if err != nil {
	log.Fatal(err)
}
Rich Push Notifications with Media

Rich push notification with image

input := activitysmithsdk.PushNotificationInput{
	Title:       "Homepage ready",
	Message:     "Your agent finished the redesign.",
	Media:       "https://cdn.example.com/output/homepage-v2.png",
	Redirection: "https://github.com/acme/web/pull/482",
}

_, err := activitysmith.Notifications.Send(input)
if err != nil {
	log.Fatal(err)
}

Send images, videos, or audio with your push notifications, press and hold to preview media directly from the notification, then tap through to open the linked content.

Rich push notification with audio

What will work:

  • direct image URL: .jpg, .png, .gif, etc.
  • direct audio file URL: .mp3, .m4a, etc.
  • direct video file URL: .mp4, .mov, etc.
  • URL that responds with a proper media Content-Type, even if the path has no extension
Actionable Push Notifications

Actionable push notification example

Actionable push notifications can open a URL on tap or trigger actions when someone long-presses the notification. Webhooks are executed by the ActivitySmith backend.

request := generated.NewPushNotificationRequest("New subscription 💸")
request.SetMessage("Customer upgraded to Pro plan")
request.SetRedirection("https://crm.example.com/customers/cus_9f3a1d") // Optional

crmAction := generated.NewPushNotificationAction(
	"Open CRM Profile",
	generated.PUSHNOTIFICATIONACTIONTYPE_OPEN_URL,
	"https://crm.example.com/customers/cus_9f3a1d",
)

onboardingAction := generated.NewPushNotificationAction(
	"Start Onboarding Workflow",
	generated.PUSHNOTIFICATIONACTIONTYPE_WEBHOOK,
	"https://hooks.example.com/activitysmith/onboarding/start",
)
onboardingAction.SetMethod(generated.PUSHNOTIFICATIONACTIONMETHOD_POST)
onboardingAction.SetBody(map[string]interface{}{
	"customer_id": "cus_9f3a1d",
	"plan": "pro",
})

request.SetActions([]generated.PushNotificationAction{
	*crmAction,
	*onboardingAction,
}) // Optional (max 4)

_, err := activitysmith.Notifications.Send(request)
if err != nil {
	log.Fatal(err)
}

Live Activities

Live Activities example

ActivitySmith supports two ways to drive Live Activities:

  • Recommended: stream updates with activitysmith.LiveActivities.Stream(...)
  • Advanced: manual lifecycle control with Start, Update, and End

Use stream updates when you want the easiest, stateless flow. You don't need to store activityID or manage lifecycle state yourself. Send the latest state for a stable streamKey and ActivitySmith will start or update the Live Activity for you. When the tracked process is over, call EndStream(...).

Use the manual lifecycle methods when you need direct control over a specific Live Activity instance.

Live Activity UI types:

  • metrics: best for live operational stats like server CPU and memory, queue depth, or replica lag
  • segmented_progress: best for step-based workflows like deployments, backups, and ETL pipelines
  • progress: best for continuous jobs like uploads, reindexes, and long-running migrations tracked as a percentage

Use a stable streamKey to identify the system or workflow you are tracking, such as a server, deployment, build pipeline, cron job, or charging session. This is especially useful for cron jobs and other scheduled tasks where you do not want to store activityID between runs.

Metrics

Metrics stream example

streamInput := activitysmithsdk.LiveActivityStreamInput{
	Title:    "Server Health",
	Subtitle: "prod-web-1",
	Type:     "metrics",
	Metrics: []generated.ActivityMetric{
		{Label: "CPU", Value: 9, Unit: generated.PtrString("%")},
		{Label: "MEM", Value: 45, Unit: generated.PtrString("%")},
	},
}

status, err := activitysmith.LiveActivities.Stream("prod-web-1", streamInput)
if err != nil {
	log.Fatal(err)
}
Segmented progress

Segmented progress stream example

streamInput := activitysmithsdk.LiveActivityStreamInput{
	Title:         "Nightly Backup",
	Subtitle:      "upload archive",
	Type:          "segmented_progress",
	NumberOfSteps: 3,
	CurrentStep:   2,
}

_, err := activitysmith.LiveActivities.Stream("nightly-backup", streamInput)
if err != nil {
	log.Fatal(err)
}
Progress

Progress stream example

streamInput := activitysmithsdk.LiveActivityStreamInput{
	Title:      "Search Reindex",
	Subtitle:   "catalog-v2",
	Type:       "progress",
	Percentage: 42,
}

_, err := activitysmith.LiveActivities.Stream("search-reindex", streamInput)
if err != nil {
	log.Fatal(err)
}

Call Stream(...) again with the same streamKey whenever the state changes.

End a stream

Use this when the tracked process is finished and you no longer want the Live Activity on devices. content_state is optional here; include it if you want to end the stream with a final state.

endInput := activitysmithsdk.LiveActivityStreamEndInput{
	Title:    "Server Health",
	Subtitle: "prod-web-1",
	Type:     "metrics",
	Metrics: []generated.ActivityMetric{
		{Label: "CPU", Value: 7, Unit: generated.PtrString("%")},
		{Label: "MEM", Value: 38, Unit: generated.PtrString("%")},
	},
}

_, err := activitysmith.LiveActivities.EndStream("prod-web-1", endInput)
if err != nil {
	log.Fatal(err)
}

If you later send another Stream(...) request with the same streamKey, ActivitySmith starts a new Live Activity for that stream again.

Stream responses include an Operation field:

  • started: ActivitySmith started a new Live Activity for this streamKey
  • updated: ActivitySmith updated the current Live Activity
  • rotated: ActivitySmith ended the previous Live Activity and started a new one
  • noop: the incoming state matched the current state, so no update was sent
  • paused: the stream is paused, so no Live Activity was started or updated
  • ended: returned by EndStream(...) after the stream is ended
Advanced: Manual lifecycle control

Use these methods when you want to manage the Live Activity lifecycle yourself.

Shared flow
  1. Call activitysmith.LiveActivities.Start(...).
  2. Save the returned activityID.
  3. Call activitysmith.LiveActivities.Update(...) as progress changes.
  4. Call activitysmith.LiveActivities.End(...) when the work is finished.
Metrics Type

Use metrics when you want to keep a small set of live stats visible, such as server health, queue pressure, or database load.

Start

Metrics start example

startInput := activitysmithsdk.LiveActivityStartInput{
	Title:    "Server Health",
	Subtitle: "prod-web-1",
	Type:     "metrics",
	Metrics: []generated.ActivityMetric{
		{Label: "CPU", Value: 9, Unit: generated.PtrString("%")},
		{Label: "MEM", Value: 45, Unit: generated.PtrString("%")},
	},
}

start, err := activitysmith.LiveActivities.Start(startInput)
if err != nil {
	log.Fatal(err)
}

activityID := start.GetActivityId()
Update

Metrics update example

updateInput := activitysmithsdk.LiveActivityUpdateInput{
	ActivityID: activityID,
	Title:      "Server Health",
	Subtitle:   "prod-web-1",
	Type:       "metrics",
	Metrics: []generated.ActivityMetric{
		{Label: "CPU", Value: 76, Unit: generated.PtrString("%")},
		{Label: "MEM", Value: 52, Unit: generated.PtrString("%")},
	},
}

_, err := activitysmith.LiveActivities.Update(updateInput)
if err != nil {
	log.Fatal(err)
}
End

Metrics end example

endInput := activitysmithsdk.LiveActivityEndInput{
	ActivityID: activityID,
	Title:      "Server Health",
	Subtitle:   "prod-web-1",
	Type:       "metrics",
	Metrics: []generated.ActivityMetric{
		{Label: "CPU", Value: 7, Unit: generated.PtrString("%")},
		{Label: "MEM", Value: 38, Unit: generated.PtrString("%")},
	},
	AutoDismissMinutes: 2,
}

_, err := activitysmith.LiveActivities.End(endInput)
if err != nil {
	log.Fatal(err)
}
Segmented Progress Type

Use segmented_progress when progress is easier to follow as steps instead of a raw percentage. It fits jobs like backups, deployments, ETL pipelines, and checklists where "step 2 of 3" is more useful than "67%". NumberOfSteps is dynamic, so you can increase or decrease it later if the workflow changes.

Start

Segmented progress start example

startInput := activitysmithsdk.LiveActivityStartInput{
	Title:         "Nightly database backup",
	Subtitle:      "create snapshot",
	NumberOfSteps: 3,
	CurrentStep:   1,
	Type:          "segmented_progress",
	Color:         "yellow",
}

start, err := activitysmith.LiveActivities.Start(startInput)
if err != nil {
	log.Fatal(err)
}

activityID := start.GetActivityId()
Update

Segmented progress update example

updateInput := activitysmithsdk.LiveActivityUpdateInput{
	ActivityID:    activityID,
	Title:         "Nightly database backup",
	Subtitle:      "upload archive",
	NumberOfSteps: 3,
	CurrentStep:   2,
}

_, err := activitysmith.LiveActivities.Update(updateInput)
if err != nil {
	log.Fatal(err)
}
End

Segmented progress end example

endInput := activitysmithsdk.LiveActivityEndInput{
	ActivityID:         activityID,
	Title:              "Nightly database backup",
	Subtitle:           "verify restore",
	NumberOfSteps:      3,
	CurrentStep:        3,
	AutoDismissMinutes: 2,
}

_, err := activitysmith.LiveActivities.End(endInput)
if err != nil {
	log.Fatal(err)
}
Progress Type

Use progress when the state is naturally continuous. It fits charging, downloads, sync jobs, uploads, timers, and any flow where a percentage or numeric range is the clearest signal.

Start

Progress start example

startInput := activitysmithsdk.LiveActivityStartInput{
	Title:      "EV Charging",
	Subtitle:   "Added 30 mi range",
	Type:       "progress",
	Percentage: 15,
}

start, err := activitysmith.LiveActivities.Start(startInput)
if err != nil {
	log.Fatal(err)
}

activityID := start.GetActivityId()
Update

Progress update example

updateInput := activitysmithsdk.LiveActivityUpdateInput{
	ActivityID: activityID,
	Title:      "EV Charging",
	Subtitle:   "Added 120 mi range",
	Percentage: 60,
}

_, err := activitysmith.LiveActivities.Update(updateInput)
if err != nil {
	log.Fatal(err)
}
End

Progress end example

endInput := activitysmithsdk.LiveActivityEndInput{
	ActivityID:         activityID,
	Title:              "EV Charging",
	Subtitle:           "Added 200 mi range",
	Percentage:         100,
	AutoDismissMinutes: 2,
}

_, err := activitysmith.LiveActivities.End(endInput)
if err != nil {
	log.Fatal(err)
}
Live Activity Action

Just like Actionable Push Notifications, Live Activities can have a button that opens a URL in a browser or triggers a webhook. Webhooks are executed by the ActivitySmith backend.

Metrics Live Activity with action

Open URL action
startInput := activitysmithsdk.LiveActivityStartInput{
	Title:    "Server Health",
	Subtitle: "prod-web-1",
	Type:     "metrics",
	Metrics: []generated.ActivityMetric{
		{Label: "CPU", Value: 76, Unit: generated.PtrString("%")},
		{Label: "MEM", Value: 52, Unit: generated.PtrString("%")},
	},
	Action: &activitysmithsdk.LiveActivityActionInput{
		Title: "Open Dashboard",
		Type:  "open_url",
		URL:   "https://ops.example.com/servers/prod-web-1",
	},
}

start, err := activitysmith.LiveActivities.Start(startInput)
if err != nil {
	log.Fatal(err)
}

activityID := start.GetActivityId()
Webhook action
updateInput := activitysmithsdk.LiveActivityUpdateInput{
	ActivityID: activityID,
	Title:      "Server Health",
	Subtitle:   "prod-web-1",
	Type:       "metrics",
	Metrics: []generated.ActivityMetric{
		{Label: "CPU", Value: 91, Unit: generated.PtrString("%")},
		{Label: "MEM", Value: 57, Unit: generated.PtrString("%")},
	},
	Action: &activitysmithsdk.LiveActivityActionInput{
		Title:  "Restart Service",
		Type:   "webhook",
		URL:    "https://ops.example.com/hooks/servers/prod-web-1/restart",
		Method: "POST",
		Body: map[string]interface{}{
			"server_id":    "prod-web-1",
			"requested_by": "activitysmith-go",
		},
	},
}

_, err = activitysmith.LiveActivities.Update(updateInput)
if err != nil {
	log.Fatal(err)
}

Channels

Channels are used to target specific team members or devices. Can be used for both push notifications and live activities.

request := generated.NewPushNotificationRequest("New subscription 💸")
request.SetMessage("Customer upgraded to Pro plan")
request.SetTarget(generated.ChannelTarget{Channels: []string{"sales", "customer-success"}}) // Optional

_, err := activitysmith.Notifications.Send(request)
if err != nil {
	log.Fatal(err)
}

Error Handling

SDK methods return (response, error). Always check error on each call.

Requirements

  • Go 1.22+

License

MIT

Documentation

Index

Constants

View Source
const Version = "1.0.0"

Variables

View Source
var ErrAPIKeyRequired = errors.New("activitysmith: apiKey is required")
View Source
var ErrPushNotificationMediaActionsConflict = errors.New("activitysmith: media cannot be combined with actions")

Functions

This section is empty.

Types

type Client

type Client struct {
	Notifications  *NotificationsService
	LiveActivities *LiveActivitiesService
	// contains filtered or unexported fields
}

func New

func New(apiKey string, opts ...*Options) (*Client, error)

func (*Client) APIClient

func (c *Client) APIClient() *generated.APIClient

func (*Client) Context

func (c *Client) Context() context.Context

type LiveActivitiesService

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

func (*LiveActivitiesService) End

func (*LiveActivitiesService) EndLiveActivity

func (*LiveActivitiesService) EndLiveActivityStream added in v1.1.0

func (*LiveActivitiesService) EndStream added in v1.1.0

func (*LiveActivitiesService) ReconcileLiveActivityStream added in v1.1.0

func (s *LiveActivitiesService) ReconcileLiveActivityStream(streamKey string, request generated.LiveActivityStreamRequest) (*generated.LiveActivityStreamPutResponse, error)

func (*LiveActivitiesService) Start

func (*LiveActivitiesService) StartLiveActivity

Backward-compatible aliases.

func (*LiveActivitiesService) Stream added in v1.1.0

func (*LiveActivitiesService) Update

func (*LiveActivitiesService) UpdateLiveActivity

type LiveActivityActionInput added in v1.0.0

type LiveActivityActionInput struct {
	Title  string
	Type   string
	URL    string
	Method string
	Body   map[string]interface{}
}

LiveActivityActionInput is a handwritten DX input for the optional Live Activity button.

type LiveActivityEndInput added in v0.1.1

type LiveActivityEndInput struct {
	ActivityID         string
	Title              string
	CurrentStep        int32
	Percentage         float32
	Value              float32
	UpperLimit         float32
	Type               string
	Subtitle           string
	Color              string
	StepColor          string
	NumberOfSteps      int32
	AutoDismissMinutes int32
	Action             *LiveActivityActionInput
	// contains filtered or unexported fields
}

LiveActivityEndInput is a handwritten DX input with plain optional values.

func (LiveActivityEndInput) WithAction added in v1.0.0

func (LiveActivityEndInput) WithAutoDismissMinutes added in v0.1.1

func (in LiveActivityEndInput) WithAutoDismissMinutes(v int32) LiveActivityEndInput

WithAutoDismissMinutes forces inclusion of auto_dismiss_minutes, including explicit zero.

func (LiveActivityEndInput) WithNumberOfSteps added in v0.1.1

func (in LiveActivityEndInput) WithNumberOfSteps(v int32) LiveActivityEndInput

WithNumberOfSteps forces inclusion of number_of_steps, including explicit zero.

func (LiveActivityEndInput) WithPercentage added in v0.1.7

func (in LiveActivityEndInput) WithPercentage(v float32) LiveActivityEndInput

WithPercentage forces inclusion of percentage, including explicit zero.

func (LiveActivityEndInput) WithUpperLimit added in v0.1.7

func (in LiveActivityEndInput) WithUpperLimit(v float32) LiveActivityEndInput

WithUpperLimit forces inclusion of upper_limit, including explicit zero.

func (LiveActivityEndInput) WithValue added in v0.1.7

WithValue forces inclusion of value, including explicit zero.

type LiveActivityStartInput added in v0.1.1

type LiveActivityStartInput struct {
	Title         string
	NumberOfSteps int32
	CurrentStep   int32
	Percentage    float32
	Value         float32
	UpperLimit    float32
	Type          string
	Subtitle      string
	Color         string
	StepColor     string
	Action        *LiveActivityActionInput
	Channels      []string
	// contains filtered or unexported fields
}

LiveActivityStartInput is a handwritten DX input with plain optional values.

func (LiveActivityStartInput) WithAction added in v1.0.0

func (LiveActivityStartInput) WithNumberOfSteps added in v0.1.7

func (in LiveActivityStartInput) WithNumberOfSteps(v int32) LiveActivityStartInput

WithNumberOfSteps forces inclusion of number_of_steps, including explicit zero.

func (LiveActivityStartInput) WithPercentage added in v0.1.7

WithPercentage forces inclusion of percentage, including explicit zero.

func (LiveActivityStartInput) WithUpperLimit added in v0.1.7

WithUpperLimit forces inclusion of upper_limit, including explicit zero.

func (LiveActivityStartInput) WithValue added in v0.1.7

WithValue forces inclusion of value, including explicit zero.

type LiveActivityStreamEndInput added in v1.1.0

type LiveActivityStreamEndInput struct {
	Title         string
	NumberOfSteps int32
	CurrentStep   int32
	Percentage    float32
	Value         float32
	UpperLimit    float32
	Type          string
	Subtitle      string
	Color         string
	StepColor     string
	Metrics       []generated.ActivityMetric
	Action        *LiveActivityActionInput
	Alert         *generated.AlertPayload
	// contains filtered or unexported fields
}

LiveActivityStreamEndInput is an optional payload for ending a managed stream.

func (LiveActivityStreamEndInput) WithAction added in v1.1.0

func (LiveActivityStreamEndInput) WithNumberOfSteps added in v1.1.0

func (LiveActivityStreamEndInput) WithPercentage added in v1.1.0

func (LiveActivityStreamEndInput) WithUpperLimit added in v1.1.0

func (LiveActivityStreamEndInput) WithValue added in v1.1.0

type LiveActivityStreamInput added in v1.1.0

type LiveActivityStreamInput struct {
	Title         string
	NumberOfSteps int32
	CurrentStep   int32
	Percentage    float32
	Value         float32
	UpperLimit    float32
	Type          string
	Subtitle      string
	Color         string
	StepColor     string
	Metrics       []generated.ActivityMetric
	Action        *LiveActivityActionInput
	Alert         *generated.AlertPayload
	Channels      []string
	// contains filtered or unexported fields
}

LiveActivityStreamInput is a handwritten DX input with plain optional values.

func (LiveActivityStreamInput) WithAction added in v1.1.0

func (LiveActivityStreamInput) WithNumberOfSteps added in v1.1.0

func (in LiveActivityStreamInput) WithNumberOfSteps(v int32) LiveActivityStreamInput

func (LiveActivityStreamInput) WithPercentage added in v1.1.0

func (LiveActivityStreamInput) WithUpperLimit added in v1.1.0

func (LiveActivityStreamInput) WithValue added in v1.1.0

type LiveActivityUpdateInput added in v0.1.1

type LiveActivityUpdateInput struct {
	ActivityID    string
	Title         string
	CurrentStep   int32
	Percentage    float32
	Value         float32
	UpperLimit    float32
	Type          string
	Subtitle      string
	Color         string
	StepColor     string
	NumberOfSteps int32
	Action        *LiveActivityActionInput
	// contains filtered or unexported fields
}

LiveActivityUpdateInput is a handwritten DX input with plain optional values.

func (LiveActivityUpdateInput) WithAction added in v1.0.0

func (LiveActivityUpdateInput) WithNumberOfSteps added in v0.1.1

func (in LiveActivityUpdateInput) WithNumberOfSteps(v int32) LiveActivityUpdateInput

WithNumberOfSteps forces inclusion of number_of_steps, including explicit zero.

func (LiveActivityUpdateInput) WithPercentage added in v0.1.7

WithPercentage forces inclusion of percentage, including explicit zero.

func (LiveActivityUpdateInput) WithUpperLimit added in v0.1.7

WithUpperLimit forces inclusion of upper_limit, including explicit zero.

func (LiveActivityUpdateInput) WithValue added in v0.1.7

WithValue forces inclusion of value, including explicit zero.

type NotificationsService

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

func (*NotificationsService) Send

func (*NotificationsService) SendPushNotification

Backward-compatible alias.

type Options

type Options struct {
	Context context.Context
}

type PushNotificationInput added in v0.1.1

type PushNotificationInput struct {
	Title       string
	Message     string
	Subtitle    string
	Media       string
	Redirection string
	Actions     []generated.PushNotificationAction
	Channels    []string
}

PushNotificationInput is a handwritten DX input with plain optional values.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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