Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,14 @@ activitysmith.notifications.send(

## Live Activities

There are five types of Live Activities:
There are six types of Live Activities:

- `stats`: best for showing business numbers side by side, such as revenue, sales, new users, conversion, refunds, or any other value you want visible at a glance
- `metrics`: best for live percentage values that change often, like server CPU, memory usage, disk usage, or error rate
- `segmented_progress`: best for anything that moves through clear stages, like deployments, onboarding flows, backups, ETL pipelines, migrations, and AI agent runs
- `progress`: best for tracking real-time progress with percentage, like tasks, backups, migrations, syncs, or uploads
- `alert`: best for status updates, such as feature adoption, reactivation, onboarding blockers, incidents, escalations, and other operational states
- `timer`: best for countdowns and elapsed runtime, like benchmark runs, uploads, backups, transcodes, and long-running jobs

### Start & Update Live Activity

Expand Down Expand Up @@ -271,6 +272,35 @@ activitysmith.live_activities.stream(
)
```

#### Timer

<p align="center">
<img
src="https://cdn.activitysmith.com/features/timer-live-activity.png"
alt="Timer Live Activity showing a benchmark run countdown"
width="680"
/>
</p>

```ruby
activitysmith.live_activities.stream(
"benchmark-run",
{
content_state: {
title: "Benchmark Run",
subtitle: "sampling",
type: "timer",
duration_seconds: 300,
color: "cyan"
}
}
)
```

For a countdown, send `duration_seconds`. You can update `title`, `subtitle`, `color`, or any other visible field as the work changes. Leave `duration_seconds` out unless you want to change the timer.

To start at 00:00 and count up, set `counts_down: false` and leave out `duration_seconds`.

### End Live Activity

Call `end_stream(...)` with the same `stream_key` to dismiss the Live Activity. You can include final values before it is removed. By default, iOS removes the Live Activity after two minutes. Set `auto_dismiss_minutes` to choose a different dismissal time, including `0` for immediate dismissal.
Expand Down Expand Up @@ -388,7 +418,7 @@ Add more context to Live Activities with icons and badges.

#### Icon

Supported Live Activity types: `stats`, `metrics`, `progress`, `segmented_progress`, and `alert`.
Supported Live Activity types: `stats`, `metrics`, `progress`, `segmented_progress`, `alert`, and `timer`.

<p align="center">
<img
Expand Down
16 changes: 8 additions & 8 deletions generated/activitysmith_openapi/api/live_activities_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def initialize(api_client = ApiClient.default)
@api_client = api_client
end
# End a Live Activity (legacy manual lifecycle)
# Legacy manual lifecycle endpoint. For new integrations, use DELETE /live-activity/stream/{stream_key} to end a managed Live Activity stream. This endpoint remains supported for existing integrations and advanced lifecycle control. Ends a Live Activity and archives its lifecycle. Supports segmented_progress, progress, metrics, stats, and alert activity types. For segmented_progress activities, you can send the latest number_of_steps here if the workflow changed after start.
# Legacy manual lifecycle endpoint. For new integrations, use DELETE /live-activity/stream/{stream_key} to end a managed Live Activity stream. This endpoint remains supported for existing integrations and advanced lifecycle control. Ends a Live Activity and archives its lifecycle. Supports segmented_progress, progress, metrics, stats, alert, and timer activity types. For segmented_progress activities, you can send the latest number_of_steps here if the workflow changed after start.
# @param live_activity_end_request [LiveActivityEndRequest]
# @param [Hash] opts the optional parameters
# @return [LiveActivityEndResponse]
Expand All @@ -30,7 +30,7 @@ def end_live_activity(live_activity_end_request, opts = {})
end

# End a Live Activity (legacy manual lifecycle)
# Legacy manual lifecycle endpoint. For new integrations, use DELETE /live-activity/stream/{stream_key} to end a managed Live Activity stream. This endpoint remains supported for existing integrations and advanced lifecycle control. Ends a Live Activity and archives its lifecycle. Supports segmented_progress, progress, metrics, stats, and alert activity types. For segmented_progress activities, you can send the latest number_of_steps here if the workflow changed after start.
# Legacy manual lifecycle endpoint. For new integrations, use DELETE /live-activity/stream/{stream_key} to end a managed Live Activity stream. This endpoint remains supported for existing integrations and advanced lifecycle control. Ends a Live Activity and archives its lifecycle. Supports segmented_progress, progress, metrics, stats, alert, and timer activity types. For segmented_progress activities, you can send the latest number_of_steps here if the workflow changed after start.
# @param live_activity_end_request [LiveActivityEndRequest]
# @param [Hash] opts the optional parameters
# @return [Array<(LiveActivityEndResponse, Integer, Hash)>] LiveActivityEndResponse data, response status code and response headers
Expand Down Expand Up @@ -167,7 +167,7 @@ def end_live_activity_stream_with_http_info(stream_key, opts = {})
end

# Start a new Live Activity or update an existing one
# Use a stable stream_key for each ongoing thing you want to show as a Live Activity. Send the latest content_state whenever it changes, and ActivitySmith will keep the Live Activity in sync.
# Use a stable stream_key for each ongoing thing you want to show as a Live Activity. Send the latest content_state whenever it changes, and ActivitySmith will keep the Live Activity in sync. For timer streams, send duration_seconds to start or reset the timer; omit duration_seconds on later updates to preserve the existing timer window.
# @param stream_key [String] Stable identifier for one ongoing thing. Allowed characters: letters, numbers, underscores, and hyphens.
# @param live_activity_stream_request [LiveActivityStreamRequest]
# @param [Hash] opts the optional parameters
Expand All @@ -178,7 +178,7 @@ def reconcile_live_activity_stream(stream_key, live_activity_stream_request, opt
end

# Start a new Live Activity or update an existing one
# Use a stable stream_key for each ongoing thing you want to show as a Live Activity. Send the latest content_state whenever it changes, and ActivitySmith will keep the Live Activity in sync.
# Use a stable stream_key for each ongoing thing you want to show as a Live Activity. Send the latest content_state whenever it changes, and ActivitySmith will keep the Live Activity in sync. For timer streams, send duration_seconds to start or reset the timer; omit duration_seconds on later updates to preserve the existing timer window.
# @param stream_key [String] Stable identifier for one ongoing thing. Allowed characters: letters, numbers, underscores, and hyphens.
# @param live_activity_stream_request [LiveActivityStreamRequest]
# @param [Hash] opts the optional parameters
Expand Down Expand Up @@ -250,7 +250,7 @@ def reconcile_live_activity_stream_with_http_info(stream_key, live_activity_stre
end

# Start a Live Activity (legacy manual lifecycle)
# Legacy manual lifecycle endpoint. For new integrations, use PUT /live-activity/stream/{stream_key} so ActivitySmith can manage start, update, rotation, and end state for you. This endpoint remains supported for existing integrations and advanced lifecycle control. Starts a Live Activity on devices matched by API key scope and optional target channels. Supports segmented_progress, progress, metrics, stats, and alert activity types. For segmented_progress activities, number_of_steps can be changed later during update or end calls if the workflow changes.
# Legacy manual lifecycle endpoint. For new integrations, use PUT /live-activity/stream/{stream_key} so ActivitySmith can manage start, update, rotation, and end state for you. This endpoint remains supported for existing integrations and advanced lifecycle control. Starts a Live Activity on devices matched by API key scope and optional target channels. Supports segmented_progress, progress, metrics, stats, alert, and timer activity types. For segmented_progress activities, number_of_steps can be changed later during update or end calls if the workflow changes.
# @param live_activity_start_request [LiveActivityStartRequest]
# @param [Hash] opts the optional parameters
# @return [LiveActivityStartResponse]
Expand All @@ -260,7 +260,7 @@ def start_live_activity(live_activity_start_request, opts = {})
end

# Start a Live Activity (legacy manual lifecycle)
# Legacy manual lifecycle endpoint. For new integrations, use PUT /live-activity/stream/{stream_key} so ActivitySmith can manage start, update, rotation, and end state for you. This endpoint remains supported for existing integrations and advanced lifecycle control. Starts a Live Activity on devices matched by API key scope and optional target channels. Supports segmented_progress, progress, metrics, stats, and alert activity types. For segmented_progress activities, number_of_steps can be changed later during update or end calls if the workflow changes.
# Legacy manual lifecycle endpoint. For new integrations, use PUT /live-activity/stream/{stream_key} so ActivitySmith can manage start, update, rotation, and end state for you. This endpoint remains supported for existing integrations and advanced lifecycle control. Starts a Live Activity on devices matched by API key scope and optional target channels. Supports segmented_progress, progress, metrics, stats, alert, and timer activity types. For segmented_progress activities, number_of_steps can be changed later during update or end calls if the workflow changes.
# @param live_activity_start_request [LiveActivityStartRequest]
# @param [Hash] opts the optional parameters
# @return [Array<(LiveActivityStartResponse, Integer, Hash)>] LiveActivityStartResponse data, response status code and response headers
Expand Down Expand Up @@ -318,7 +318,7 @@ def start_live_activity_with_http_info(live_activity_start_request, opts = {})
end

# Update a Live Activity (legacy manual lifecycle)
# Legacy manual lifecycle endpoint. For new integrations, use PUT /live-activity/stream/{stream_key} so ActivitySmith can manage start, update, rotation, and end state for you. This endpoint remains supported for existing integrations and advanced lifecycle control. Updates an existing Live Activity. If the per-activity token is not registered yet, the update is queued. Supports segmented_progress, progress, metrics, stats, and alert activity types. For segmented_progress activities, you can increase or decrease number_of_steps here as the workflow changes.
# Legacy manual lifecycle endpoint. For new integrations, use PUT /live-activity/stream/{stream_key} so ActivitySmith can manage start, update, rotation, and end state for you. This endpoint remains supported for existing integrations and advanced lifecycle control. Updates an existing Live Activity. If the per-activity token is not registered yet, the update is queued. Supports segmented_progress, progress, metrics, stats, alert, and timer activity types. For segmented_progress activities, you can increase or decrease number_of_steps here as the workflow changes. For timer activities, send duration_seconds only when you want to reset the timer window; omit it to keep the current timer running.
# @param live_activity_update_request [LiveActivityUpdateRequest]
# @param [Hash] opts the optional parameters
# @return [LiveActivityUpdateResponse]
Expand All @@ -328,7 +328,7 @@ def update_live_activity(live_activity_update_request, opts = {})
end

# Update a Live Activity (legacy manual lifecycle)
# Legacy manual lifecycle endpoint. For new integrations, use PUT /live-activity/stream/{stream_key} so ActivitySmith can manage start, update, rotation, and end state for you. This endpoint remains supported for existing integrations and advanced lifecycle control. Updates an existing Live Activity. If the per-activity token is not registered yet, the update is queued. Supports segmented_progress, progress, metrics, stats, and alert activity types. For segmented_progress activities, you can increase or decrease number_of_steps here as the workflow changes.
# Legacy manual lifecycle endpoint. For new integrations, use PUT /live-activity/stream/{stream_key} so ActivitySmith can manage start, update, rotation, and end state for you. This endpoint remains supported for existing integrations and advanced lifecycle control. Updates an existing Live Activity. If the per-activity token is not registered yet, the update is queued. Supports segmented_progress, progress, metrics, stats, alert, and timer activity types. For segmented_progress activities, you can increase or decrease number_of_steps here as the workflow changes. For timer activities, send duration_seconds only when you want to reset the timer window; omit it to keep the current timer running.
# @param live_activity_update_request [LiveActivityUpdateRequest]
# @param [Hash] opts the optional parameters
# @return [Array<(LiveActivityUpdateResponse, Integer, Hash)>] LiveActivityUpdateResponse data, response status code and response headers
Expand Down
46 changes: 40 additions & 6 deletions generated/activitysmith_openapi/models/content_state_end.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
require 'time'

module OpenapiClient
# End payload requires title. For segmented_progress include current_step and optionally number_of_steps. For progress include percentage or value with upper_limit. For metrics and stats include a non-empty metrics array. For alert include message. Optional icon is supported by all Live Activity types. Optional badge is supported by alert, progress, and segmented_progress. Type is optional when ending an existing activity. You can send an updated number_of_steps here if the workflow changed after start.
# End payload requires title. For segmented_progress include current_step and optionally number_of_steps. For progress include percentage or value with upper_limit. For metrics and stats include a non-empty metrics array. For alert include message. For timer, omit duration_seconds to preserve and freeze the latest timer state. Optional icon is supported by all Live Activity types. Optional badge is supported by alert, progress, and segmented_progress. Type is optional when ending an existing activity. You can send an updated number_of_steps here if the workflow changed after start.
class ContentStateEnd
attr_accessor :title

Expand All @@ -35,13 +35,22 @@ class ContentStateEnd
# Maximum progress value. Use with value for type=progress.
attr_accessor :upper_limit

# Timer duration in seconds. For type=timer, omit duration_seconds on end to preserve and freeze the latest timer state.
attr_accessor :duration_seconds

# Use with type=timer. When true or omitted, the timer counts down from duration_seconds. Set false for an elapsed timer; omit duration_seconds for an open-ended elapsed timer.
attr_accessor :counts_down

# Use with type=timer. Defaults to true. Set false to pause/freeze via API; set true on a paused timer to resume.
attr_accessor :is_running

# Use for type=metrics or type=stats.
attr_accessor :metrics

# Alert message. Use for type=alert.
attr_accessor :message

# Optional SF Symbol icon. Supported by alert, progress, segmented_progress, metrics, and stats.
# Optional SF Symbol icon. Supported by alert, progress, segmented_progress, metrics, stats, and timer.
attr_accessor :icon

# Optional badge. Supported by alert, progress, and segmented_progress.
Expand All @@ -50,7 +59,7 @@ class ContentStateEnd
# Optional. When omitted, the API uses the existing Live Activity type.
attr_accessor :type

# Optional. Accent color for progress, segmented_progress, and metrics Live Activities. For Alert Live Activities, this tints the action button when action is included.
# Optional. Accent color for progress, segmented_progress, metrics, and timer Live Activities. For Alert Live Activities, this tints the action button when action is included.
attr_accessor :color

# Optional. Overrides color for the current step. Only applies to type=segmented_progress.
Expand Down Expand Up @@ -94,6 +103,9 @@ def self.attribute_map
:'percentage' => :'percentage',
:'value' => :'value',
:'upper_limit' => :'upper_limit',
:'duration_seconds' => :'duration_seconds',
:'counts_down' => :'counts_down',
:'is_running' => :'is_running',
:'metrics' => :'metrics',
:'message' => :'message',
:'icon' => :'icon',
Expand Down Expand Up @@ -121,6 +133,9 @@ def self.openapi_types
:'percentage' => :'Float',
:'value' => :'Float',
:'upper_limit' => :'Float',
:'duration_seconds' => :'Float',
:'counts_down' => :'Boolean',
:'is_running' => :'Boolean',
:'metrics' => :'Array<ActivityMetric>',
:'message' => :'String',
:'icon' => :'LiveActivityAlertIcon',
Expand Down Expand Up @@ -184,6 +199,22 @@ def initialize(attributes = {})
self.upper_limit = attributes[:'upper_limit']
end

if attributes.key?(:'duration_seconds')
self.duration_seconds = attributes[:'duration_seconds']
end

if attributes.key?(:'counts_down')
self.counts_down = attributes[:'counts_down']
else
self.counts_down = true
end

if attributes.key?(:'is_running')
self.is_running = attributes[:'is_running']
else
self.is_running = true
end

if attributes.key?(:'metrics')
if (value = attributes[:'metrics']).is_a?(Array)
self.metrics = value
Expand Down Expand Up @@ -283,7 +314,7 @@ def valid?
return false if !@metrics.nil? && @metrics.length > 8
return false if !@metrics.nil? && @metrics.length < 1
return false if !@message.nil? && @message.to_s.length < 1
type_validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats", "alert"])
type_validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats", "alert", "timer"])
return false unless type_validator.valid?(@type)
color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"])
return false unless color_validator.valid?(@color)
Expand Down Expand Up @@ -374,7 +405,7 @@ def message=(message)
# Custom attribute writer method checking allowed values (enum).
# @param [Object] type Object to be assigned
def type=(type)
validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats", "alert"])
validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats", "alert", "timer"])
unless validator.valid?(type)
fail ArgumentError, "invalid value for \"type\", must be one of #{validator.allowable_values}."
end
Expand Down Expand Up @@ -427,6 +458,9 @@ def ==(o)
percentage == o.percentage &&
value == o.value &&
upper_limit == o.upper_limit &&
duration_seconds == o.duration_seconds &&
counts_down == o.counts_down &&
is_running == o.is_running &&
metrics == o.metrics &&
message == o.message &&
icon == o.icon &&
Expand All @@ -447,7 +481,7 @@ def eql?(o)
# Calculates hash code according to all attributes.
# @return [Integer] Hash code
def hash
[title, subtitle, number_of_steps, current_step, percentage, value, upper_limit, metrics, message, icon, badge, type, color, step_color, step_colors, auto_dismiss_minutes].hash
[title, subtitle, number_of_steps, current_step, percentage, value, upper_limit, duration_seconds, counts_down, is_running, metrics, message, icon, badge, type, color, step_color, step_colors, auto_dismiss_minutes].hash
end

# Builds the object from hash
Expand Down
Loading