From 37031cb1f0fd53ddc57393831962e03f18dd03f8 Mon Sep 17 00:00:00 2001 From: bardonadam Date: Tue, 26 May 2026 18:43:42 +0700 Subject: [PATCH 1/4] Add alert live activity helpers --- lib/activitysmith/live_activities.rb | 87 ++++++++++++++++++++++++---- test/resources_test.rb | 39 +++++++++++++ 2 files changed, 116 insertions(+), 10 deletions(-) diff --git a/lib/activitysmith/live_activities.rb b/lib/activitysmith/live_activities.rb index 30dadb5..905b9ed 100644 --- a/lib/activitysmith/live_activities.rb +++ b/lib/activitysmith/live_activities.rb @@ -6,52 +6,104 @@ class LiveActivities TYPE_PROGRESS = "progress" TYPE_METRICS = "metrics" TYPE_STATS = "stats" + TYPE_ALERT = "alert" + + class << self + def content_state(title:, type: nil, subtitle: nil, message: nil, icon: nil, badge: nil, color: nil, **fields) + normalize_alert_content_state( + { + title: title, + type: type, + subtitle: subtitle, + message: message, + icon: icon, + badge: badge, + color: color + }.merge(fields).compact + ) + end + + def alert_icon(symbol, color: nil) + { symbol: symbol, color: color }.compact + end + + def alert_badge(title, color: nil) + { title: title, color: color }.compact + end + + private + + def normalize_alert_content_state(content_state) + return content_state unless content_state.is_a?(Hash) + + state = content_state.dup + state.delete(:color) if state[:type] == TYPE_ALERT || state["type"] == TYPE_ALERT + state.delete("color") if state[:type] == TYPE_ALERT || state["type"] == TYPE_ALERT + state + end + end def initialize(api) @api = api end def start(request, opts = {}) - @api.start_live_activity(normalize_channels_target(request), opts) + @api.start_live_activity(normalize_live_activity_request(normalize_channels_target(request)), opts) end def update(request, opts = {}) - @api.update_live_activity(request, opts) + @api.update_live_activity(normalize_live_activity_request(request), opts) end def end(request, opts = {}) - @api.end_live_activity(request, opts) + @api.end_live_activity(normalize_live_activity_request(request), opts) end def stream(stream_key, request, opts = {}) - @api.reconcile_live_activity_stream(stream_key, normalize_channels_target(request), opts) + @api.reconcile_live_activity_stream( + stream_key, + normalize_live_activity_request(normalize_channels_target(request)), + opts + ) end def end_stream(stream_key, request = nil, opts = {}) - @api.end_live_activity_stream(stream_key, { live_activity_stream_delete_request: request }.merge(opts)) + @api.end_live_activity_stream( + stream_key, + { live_activity_stream_delete_request: normalize_live_activity_request(request) }.merge(opts) + ) end # Backward-compatible aliases. def start_live_activity(live_activity_start_request, opts = {}) - @api.start_live_activity(normalize_channels_target(live_activity_start_request), opts) + @api.start_live_activity( + normalize_live_activity_request(normalize_channels_target(live_activity_start_request)), + opts + ) end def update_live_activity(live_activity_update_request, opts = {}) - @api.update_live_activity(live_activity_update_request, opts) + @api.update_live_activity(normalize_live_activity_request(live_activity_update_request), opts) end def end_live_activity(live_activity_end_request, opts = {}) - @api.end_live_activity(live_activity_end_request, opts) + @api.end_live_activity(normalize_live_activity_request(live_activity_end_request), opts) end def reconcile_live_activity_stream(stream_key, live_activity_stream_request, opts = {}) - @api.reconcile_live_activity_stream(stream_key, normalize_channels_target(live_activity_stream_request), opts) + @api.reconcile_live_activity_stream( + stream_key, + normalize_live_activity_request(normalize_channels_target(live_activity_stream_request)), + opts + ) end def end_live_activity_stream(stream_key, live_activity_stream_delete_request = nil, opts = {}) @api.end_live_activity_stream( stream_key, - { live_activity_stream_delete_request: live_activity_stream_delete_request }.merge(opts) + { + live_activity_stream_delete_request: normalize_live_activity_request(live_activity_stream_delete_request) + }.merge(opts) ) end @@ -67,6 +119,21 @@ def respond_to_missing?(name, include_private = false) private + def normalize_live_activity_request(request) + return request unless request.is_a?(Hash) + + hash = request.dup + content_state_key = if hash.key?(:content_state) + :content_state + elsif hash.key?("content_state") + "content_state" + end + if content_state_key + hash[content_state_key] = self.class.send(:normalize_alert_content_state, hash[content_state_key]) + end + hash + end + def normalize_channels_target(request) return request unless request.is_a?(Hash) diff --git a/test/resources_test.rb b/test/resources_test.rb index b38e82a..8496cb9 100644 --- a/test/resources_test.rb +++ b/test/resources_test.rb @@ -272,6 +272,45 @@ def test_live_activities_support_stats_payloads ) end + def test_live_activities_support_alert_helpers + api = FakeLiveApi.new + resource = ActivitySmith::LiveActivities.new(api) + + state = ActivitySmith::LiveActivities.content_state( + title: "Reactivation", + type: ActivitySmith::LiveActivities::TYPE_ALERT, + message: "Lumen came back after 2 weeks", + icon: ActivitySmith::LiveActivities.alert_icon("sparkles", color: "yellow"), + badge: ActivitySmith::LiveActivities.alert_badge("Customer", color: "magenta"), + color: "red" + ) + payload = { content_state: state } + + refute state.key?(:color) + + resource.stream("customer-ops", payload) + + assert_equal( + [ + [ + :reconcile_live_activity_stream, + "customer-ops", + { + content_state: { + title: "Reactivation", + type: ActivitySmith::LiveActivities::TYPE_ALERT, + message: "Lumen came back after 2 weeks", + icon: { symbol: "sparkles", color: "yellow" }, + badge: { title: "Customer", color: "magenta" } + } + }, + {} + ] + ], + api.calls + ) + end + def test_live_activities_stream_short_and_legacy_methods api = FakeLiveApi.new resource = ActivitySmith::LiveActivities.new(api) From 2e029618821d3b8bf1b9b3264da27cf51261d2c1 Mon Sep 17 00:00:00 2001 From: bardonadam Date: Wed, 27 May 2026 20:53:47 +0700 Subject: [PATCH 2/4] Prepare alert live activity helpers --- README.md | 37 ++++++++++++++++++++++++++- lib/activitysmith/live_activities.rb | 38 +++++++--------------------- lib/activitysmith/version.rb | 2 +- test/resources_test.rb | 7 +++-- 4 files changed, 49 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 4f0ab4b..cac6eb9 100644 --- a/README.md +++ b/README.md @@ -120,12 +120,13 @@ activitysmith.notifications.send( ## Live Activities -There are four types of Live Activities: +There are five 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 ### Start & Update Live Activity @@ -238,6 +239,39 @@ activitysmith.live_activities.stream( ) ``` +#### Alert + +

+ Alert Live Activity stream example +

+ +```ruby +activitysmith.live_activities.stream( + "customer-ops", + { + content_state: ActivitySmith::LiveActivities.content_state( + title: "Reactivation", + message: "Lumen came back after 2 weeks", + type: ActivitySmith::LiveActivities::TYPE_ALERT, + icon: ActivitySmith::LiveActivities.alert_icon("cloud.sun", color: "yellow"), + badge: ActivitySmith::LiveActivities.alert_badge("Customer", color: "magenta") + ) + } +) +``` + +The `icon` symbol value is an Apple SF Symbol name. Browse the catalog with one of these tools: + +- [ActivitySmith app](https://apps.apple.com/us/app/activitysmith/id6752254835) - Open Settings -> SF Symbols to browse 45 hand-picked icons ready to use +- [SF Symbols](https://developer.apple.com/sf-symbols/) - Apple's official macOS app +- [Interactful](https://apps.apple.com/app/interactful/id1528095640) - free third-party iOS app listing all SF Symbols under Foundations -> Iconography + +`icon` and `badge` are optional. If you omit either one, that element is not shown in the Live Activity. + ### 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. @@ -263,6 +297,7 @@ activitysmith.live_activities.end_stream( ### Live Activity Action Live Activities can include one optional action button. Use it to open a URL from the Live Activity or trigger a backend webhook. +For alert Live Activities, set `color` in `content_state` to tint the action button. Icon and badge colors only affect the icon and badge.

Date: Wed, 27 May 2026 11:15:37 +0000 Subject: [PATCH 3/4] chore: regenerate SDK --- generated/activitysmith_openapi.rb | 3 + .../api/live_activities_api.rb | 12 +- .../models/activity_metric.rb | 4 +- .../models/content_state_end.rb | 69 ++++- .../models/content_state_start.rb | 69 ++++- .../models/content_state_update.rb | 69 ++++- .../models/live_activity_alert_badge.rb | 273 +++++++++++++++++ .../models/live_activity_alert_icon.rb | 274 ++++++++++++++++++ .../models/live_activity_color.rb | 48 +++ .../models/stream_content_state.rb | 69 ++++- 10 files changed, 838 insertions(+), 52 deletions(-) create mode 100644 generated/activitysmith_openapi/models/live_activity_alert_badge.rb create mode 100644 generated/activitysmith_openapi/models/live_activity_alert_icon.rb create mode 100644 generated/activitysmith_openapi/models/live_activity_color.rb diff --git a/generated/activitysmith_openapi.rb b/generated/activitysmith_openapi.rb index e7af8db..7d5aee2 100644 --- a/generated/activitysmith_openapi.rb +++ b/generated/activitysmith_openapi.rb @@ -28,6 +28,9 @@ require 'activitysmith_openapi/models/forbidden_error' require 'activitysmith_openapi/models/live_activity_action' require 'activitysmith_openapi/models/live_activity_action_type' +require 'activitysmith_openapi/models/live_activity_alert_badge' +require 'activitysmith_openapi/models/live_activity_alert_icon' +require 'activitysmith_openapi/models/live_activity_color' require 'activitysmith_openapi/models/live_activity_end_request' require 'activitysmith_openapi/models/live_activity_end_response' require 'activitysmith_openapi/models/live_activity_limit_error' diff --git a/generated/activitysmith_openapi/api/live_activities_api.rb b/generated/activitysmith_openapi/api/live_activities_api.rb index 765dfab..08b9772 100644 --- a/generated/activitysmith_openapi/api/live_activities_api.rb +++ b/generated/activitysmith_openapi/api/live_activities_api.rb @@ -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, and stats 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, and alert 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] @@ -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, and stats 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, and alert 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 @@ -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, and stats 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, and alert 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] @@ -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, and stats 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, and alert 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 @@ -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, and stats 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, and alert activity types. For segmented_progress activities, you can increase or decrease number_of_steps here as the workflow changes. # @param live_activity_update_request [LiveActivityUpdateRequest] # @param [Hash] opts the optional parameters # @return [LiveActivityUpdateResponse] @@ -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, and stats 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, and alert activity types. For segmented_progress activities, you can increase or decrease number_of_steps here as the workflow changes. # @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 diff --git a/generated/activitysmith_openapi/models/activity_metric.rb b/generated/activitysmith_openapi/models/activity_metric.rb index 67c8b2e..864825a 100644 --- a/generated/activitysmith_openapi/models/activity_metric.rb +++ b/generated/activitysmith_openapi/models/activity_metric.rb @@ -140,7 +140,7 @@ def valid? return false if @label.nil? return false if @label.to_s.length < 1 return false if @value.nil? - color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) return false unless color_validator.valid?(@color) true end @@ -162,7 +162,7 @@ def label=(label) # Custom attribute writer method checking allowed values (enum). # @param [Object] color Object to be assigned def color=(color) - validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) unless validator.valid?(color) fail ArgumentError, "invalid value for \"color\", must be one of #{validator.allowable_values}." end diff --git a/generated/activitysmith_openapi/models/content_state_end.rb b/generated/activitysmith_openapi/models/content_state_end.rb index 6edc4df..fcf8287 100644 --- a/generated/activitysmith_openapi/models/content_state_end.rb +++ b/generated/activitysmith_openapi/models/content_state_end.rb @@ -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. 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, with optional icon and badge. 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 @@ -38,10 +38,19 @@ class ContentStateEnd # Use for type=metrics or type=stats. attr_accessor :metrics + # Alert message. Use for type=alert. + attr_accessor :message + + # Optional SF Symbol icon for type=alert. + attr_accessor :icon + + # Optional badge for type=alert. + attr_accessor :badge + # Optional. When omitted, the API uses the existing Live Activity type. attr_accessor :type - # Optional. Accent color for the Live Activity. Defaults to blue. + # Optional. Accent color for progress, segmented_progress, and metrics 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. @@ -86,6 +95,9 @@ def self.attribute_map :'value' => :'value', :'upper_limit' => :'upper_limit', :'metrics' => :'metrics', + :'message' => :'message', + :'icon' => :'icon', + :'badge' => :'badge', :'type' => :'type', :'color' => :'color', :'step_color' => :'step_color', @@ -110,6 +122,9 @@ def self.openapi_types :'value' => :'Float', :'upper_limit' => :'Float', :'metrics' => :'Array', + :'message' => :'String', + :'icon' => :'LiveActivityAlertIcon', + :'badge' => :'LiveActivityAlertBadge', :'type' => :'String', :'color' => :'String', :'step_color' => :'String', @@ -175,14 +190,24 @@ def initialize(attributes = {}) end end + if attributes.key?(:'message') + self.message = attributes[:'message'] + end + + if attributes.key?(:'icon') + self.icon = attributes[:'icon'] + end + + if attributes.key?(:'badge') + self.badge = attributes[:'badge'] + end + if attributes.key?(:'type') self.type = attributes[:'type'] end if attributes.key?(:'color') self.color = attributes[:'color'] - else - self.color = 'blue' end if attributes.key?(:'step_color') @@ -235,6 +260,10 @@ def list_invalid_properties invalid_properties.push('invalid value for "metrics", number of items must be greater than or equal to 1.') end + if !@message.nil? && @message.to_s.length < 1 + invalid_properties.push('invalid value for "message", the character length must be great than or equal to 1.') + end + if !@auto_dismiss_minutes.nil? && @auto_dismiss_minutes < 0 invalid_properties.push('invalid value for "auto_dismiss_minutes", must be greater than or equal to 0.') end @@ -253,11 +282,12 @@ def valid? return false if !@percentage.nil? && @percentage < 0 return false if !@metrics.nil? && @metrics.length > 8 return false if !@metrics.nil? && @metrics.length < 1 - type_validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats"]) + return false if !@message.nil? && @message.to_s.length < 1 + type_validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats", "alert"]) return false unless type_validator.valid?(@type) - color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) return false unless color_validator.valid?(@color) - step_color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + step_color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) return false unless step_color_validator.valid?(@step_color) return false if !@auto_dismiss_minutes.nil? && @auto_dismiss_minutes < 0 true @@ -327,10 +357,24 @@ def metrics=(metrics) @metrics = metrics end + # Custom attribute writer method with validation + # @param [Object] message Value to be assigned + def message=(message) + if message.nil? + fail ArgumentError, 'message cannot be nil' + end + + if message.to_s.length < 1 + fail ArgumentError, 'invalid value for "message", the character length must be great than or equal to 1.' + end + + @message = message + end + # 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"]) + validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats", "alert"]) unless validator.valid?(type) fail ArgumentError, "invalid value for \"type\", must be one of #{validator.allowable_values}." end @@ -340,7 +384,7 @@ def type=(type) # Custom attribute writer method checking allowed values (enum). # @param [Object] color Object to be assigned def color=(color) - validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) unless validator.valid?(color) fail ArgumentError, "invalid value for \"color\", must be one of #{validator.allowable_values}." end @@ -350,7 +394,7 @@ def color=(color) # Custom attribute writer method checking allowed values (enum). # @param [Object] step_color Object to be assigned def step_color=(step_color) - validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) unless validator.valid?(step_color) fail ArgumentError, "invalid value for \"step_color\", must be one of #{validator.allowable_values}." end @@ -384,6 +428,9 @@ def ==(o) value == o.value && upper_limit == o.upper_limit && metrics == o.metrics && + message == o.message && + icon == o.icon && + badge == o.badge && type == o.type && color == o.color && step_color == o.step_color && @@ -400,7 +447,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, type, color, step_color, step_colors, auto_dismiss_minutes].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 end # Builds the object from hash diff --git a/generated/activitysmith_openapi/models/content_state_start.rb b/generated/activitysmith_openapi/models/content_state_start.rb index 1ad141a..02f8d8a 100644 --- a/generated/activitysmith_openapi/models/content_state_start.rb +++ b/generated/activitysmith_openapi/models/content_state_start.rb @@ -14,7 +14,7 @@ require 'time' module OpenapiClient - # Start payload requires title and type. For segmented_progress include number_of_steps and current_step. For progress include percentage or value with upper_limit. For metrics and stats include a non-empty metrics array. For segmented_progress, number_of_steps is not locked and can be changed in later update or end calls. + # Start payload requires title and type. For segmented_progress include number_of_steps and current_step. For progress include percentage or value with upper_limit. For metrics and stats include a non-empty metrics array. For alert include message, with optional icon and badge. For segmented_progress, number_of_steps is not locked and can be changed in later update or end calls. class ContentStateStart attr_accessor :title @@ -38,9 +38,18 @@ class ContentStateStart # Use for type=metrics or type=stats. attr_accessor :metrics + # Required for type=alert. + attr_accessor :message + + # Optional SF Symbol icon for type=alert. + attr_accessor :icon + + # Optional badge for type=alert. + attr_accessor :badge + attr_accessor :type - # Optional. Accent color for the Live Activity. Defaults to blue. + # Optional. Accent color for progress, segmented_progress, and metrics 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. @@ -82,6 +91,9 @@ def self.attribute_map :'value' => :'value', :'upper_limit' => :'upper_limit', :'metrics' => :'metrics', + :'message' => :'message', + :'icon' => :'icon', + :'badge' => :'badge', :'type' => :'type', :'color' => :'color', :'step_color' => :'step_color', @@ -105,6 +117,9 @@ def self.openapi_types :'value' => :'Float', :'upper_limit' => :'Float', :'metrics' => :'Array', + :'message' => :'String', + :'icon' => :'LiveActivityAlertIcon', + :'badge' => :'LiveActivityAlertBadge', :'type' => :'String', :'color' => :'String', :'step_color' => :'String', @@ -169,6 +184,18 @@ def initialize(attributes = {}) end end + if attributes.key?(:'message') + self.message = attributes[:'message'] + end + + if attributes.key?(:'icon') + self.icon = attributes[:'icon'] + end + + if attributes.key?(:'badge') + self.badge = attributes[:'badge'] + end + if attributes.key?(:'type') self.type = attributes[:'type'] else @@ -177,8 +204,6 @@ def initialize(attributes = {}) if attributes.key?(:'color') self.color = attributes[:'color'] - else - self.color = 'blue' end if attributes.key?(:'step_color') @@ -225,6 +250,10 @@ def list_invalid_properties invalid_properties.push('invalid value for "metrics", number of items must be greater than or equal to 1.') end + if !@message.nil? && @message.to_s.length < 1 + invalid_properties.push('invalid value for "message", the character length must be great than or equal to 1.') + end + if @type.nil? invalid_properties.push('invalid value for "type", type cannot be nil.') end @@ -243,12 +272,13 @@ def valid? return false if !@percentage.nil? && @percentage < 0 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 return false if @type.nil? - type_validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats"]) + type_validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats", "alert"]) return false unless type_validator.valid?(@type) - color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) return false unless color_validator.valid?(@color) - step_color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + step_color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) return false unless step_color_validator.valid?(@step_color) true end @@ -317,10 +347,24 @@ def metrics=(metrics) @metrics = metrics end + # Custom attribute writer method with validation + # @param [Object] message Value to be assigned + def message=(message) + if message.nil? + fail ArgumentError, 'message cannot be nil' + end + + if message.to_s.length < 1 + fail ArgumentError, 'invalid value for "message", the character length must be great than or equal to 1.' + end + + @message = message + end + # 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"]) + validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats", "alert"]) unless validator.valid?(type) fail ArgumentError, "invalid value for \"type\", must be one of #{validator.allowable_values}." end @@ -330,7 +374,7 @@ def type=(type) # Custom attribute writer method checking allowed values (enum). # @param [Object] color Object to be assigned def color=(color) - validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) unless validator.valid?(color) fail ArgumentError, "invalid value for \"color\", must be one of #{validator.allowable_values}." end @@ -340,7 +384,7 @@ def color=(color) # Custom attribute writer method checking allowed values (enum). # @param [Object] step_color Object to be assigned def step_color=(step_color) - validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) unless validator.valid?(step_color) fail ArgumentError, "invalid value for \"step_color\", must be one of #{validator.allowable_values}." end @@ -360,6 +404,9 @@ def ==(o) value == o.value && upper_limit == o.upper_limit && metrics == o.metrics && + message == o.message && + icon == o.icon && + badge == o.badge && type == o.type && color == o.color && step_color == o.step_color && @@ -375,7 +422,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, type, color, step_color, step_colors].hash + [title, subtitle, number_of_steps, current_step, percentage, value, upper_limit, metrics, message, icon, badge, type, color, step_color, step_colors].hash end # Builds the object from hash diff --git a/generated/activitysmith_openapi/models/content_state_update.rb b/generated/activitysmith_openapi/models/content_state_update.rb index be4fd7c..1b67af9 100644 --- a/generated/activitysmith_openapi/models/content_state_update.rb +++ b/generated/activitysmith_openapi/models/content_state_update.rb @@ -14,7 +14,7 @@ require 'time' module OpenapiClient - # Update 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. Type is optional when updating an existing activity. You can increase or decrease number_of_steps during updates. + # Update 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, with optional icon and badge. Type is optional when updating an existing activity. You can increase or decrease number_of_steps during updates. class ContentStateUpdate attr_accessor :title @@ -38,10 +38,19 @@ class ContentStateUpdate # Use for type=metrics or type=stats. attr_accessor :metrics + # Alert message. Use for type=alert. + attr_accessor :message + + # Optional SF Symbol icon for type=alert. + attr_accessor :icon + + # Optional badge for type=alert. + attr_accessor :badge + # Optional. When omitted, the API uses the existing Live Activity type. attr_accessor :type - # Optional. Accent color for the Live Activity. Defaults to blue. + # Optional. Accent color for progress, segmented_progress, and metrics 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. @@ -83,6 +92,9 @@ def self.attribute_map :'value' => :'value', :'upper_limit' => :'upper_limit', :'metrics' => :'metrics', + :'message' => :'message', + :'icon' => :'icon', + :'badge' => :'badge', :'type' => :'type', :'color' => :'color', :'step_color' => :'step_color', @@ -106,6 +118,9 @@ def self.openapi_types :'value' => :'Float', :'upper_limit' => :'Float', :'metrics' => :'Array', + :'message' => :'String', + :'icon' => :'LiveActivityAlertIcon', + :'badge' => :'LiveActivityAlertBadge', :'type' => :'String', :'color' => :'String', :'step_color' => :'String', @@ -170,14 +185,24 @@ def initialize(attributes = {}) end end + if attributes.key?(:'message') + self.message = attributes[:'message'] + end + + if attributes.key?(:'icon') + self.icon = attributes[:'icon'] + end + + if attributes.key?(:'badge') + self.badge = attributes[:'badge'] + end + if attributes.key?(:'type') self.type = attributes[:'type'] end if attributes.key?(:'color') self.color = attributes[:'color'] - else - self.color = 'blue' end if attributes.key?(:'step_color') @@ -224,6 +249,10 @@ def list_invalid_properties invalid_properties.push('invalid value for "metrics", number of items must be greater than or equal to 1.') end + if !@message.nil? && @message.to_s.length < 1 + invalid_properties.push('invalid value for "message", the character length must be great than or equal to 1.') + end + invalid_properties end @@ -238,11 +267,12 @@ def valid? return false if !@percentage.nil? && @percentage < 0 return false if !@metrics.nil? && @metrics.length > 8 return false if !@metrics.nil? && @metrics.length < 1 - type_validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats"]) + return false if !@message.nil? && @message.to_s.length < 1 + type_validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats", "alert"]) return false unless type_validator.valid?(@type) - color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) return false unless color_validator.valid?(@color) - step_color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + step_color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) return false unless step_color_validator.valid?(@step_color) true end @@ -311,10 +341,24 @@ def metrics=(metrics) @metrics = metrics end + # Custom attribute writer method with validation + # @param [Object] message Value to be assigned + def message=(message) + if message.nil? + fail ArgumentError, 'message cannot be nil' + end + + if message.to_s.length < 1 + fail ArgumentError, 'invalid value for "message", the character length must be great than or equal to 1.' + end + + @message = message + end + # 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"]) + validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats", "alert"]) unless validator.valid?(type) fail ArgumentError, "invalid value for \"type\", must be one of #{validator.allowable_values}." end @@ -324,7 +368,7 @@ def type=(type) # Custom attribute writer method checking allowed values (enum). # @param [Object] color Object to be assigned def color=(color) - validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) unless validator.valid?(color) fail ArgumentError, "invalid value for \"color\", must be one of #{validator.allowable_values}." end @@ -334,7 +378,7 @@ def color=(color) # Custom attribute writer method checking allowed values (enum). # @param [Object] step_color Object to be assigned def step_color=(step_color) - validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) unless validator.valid?(step_color) fail ArgumentError, "invalid value for \"step_color\", must be one of #{validator.allowable_values}." end @@ -354,6 +398,9 @@ def ==(o) value == o.value && upper_limit == o.upper_limit && metrics == o.metrics && + message == o.message && + icon == o.icon && + badge == o.badge && type == o.type && color == o.color && step_color == o.step_color && @@ -369,7 +416,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, type, color, step_color, step_colors].hash + [title, subtitle, number_of_steps, current_step, percentage, value, upper_limit, metrics, message, icon, badge, type, color, step_color, step_colors].hash end # Builds the object from hash diff --git a/generated/activitysmith_openapi/models/live_activity_alert_badge.rb b/generated/activitysmith_openapi/models/live_activity_alert_badge.rb new file mode 100644 index 0000000..3870746 --- /dev/null +++ b/generated/activitysmith_openapi/models/live_activity_alert_badge.rb @@ -0,0 +1,273 @@ +=begin +#ActivitySmith API + +#Send push notifications and Live Activities to your own devices via a single API key. + +The version of the OpenAPI document: 1.0.0 + +Generated by: https://openapi-generator.tech +Generator version: 7.7.0 + +=end + +require 'date' +require 'time' + +module OpenapiClient + # Optional badge for alert Live Activities. + class LiveActivityAlertBadge + attr_accessor :title + + # Optional badge color. + attr_accessor :color + + class EnumAttributeValidator + attr_reader :datatype + attr_reader :allowable_values + + def initialize(datatype, allowable_values) + @allowable_values = allowable_values.map do |value| + case datatype.to_s + when /Integer/i + value.to_i + when /Float/i + value.to_f + else + value + end + end + end + + def valid?(value) + !value || allowable_values.include?(value) + end + end + + # Attribute mapping from ruby-style variable name to JSON key. + def self.attribute_map + { + :'title' => :'title', + :'color' => :'color' + } + end + + # Returns all the JSON keys this model knows about + def self.acceptable_attributes + attribute_map.values + end + + # Attribute type mapping. + def self.openapi_types + { + :'title' => :'String', + :'color' => :'LiveActivityColor' + } + end + + # List of attributes with nullable: true + def self.openapi_nullable + Set.new([ + ]) + end + + # Initializes the object + # @param [Hash] attributes Model attributes in the form of hash + def initialize(attributes = {}) + if (!attributes.is_a?(Hash)) + fail ArgumentError, "The input argument (attributes) must be a hash in `OpenapiClient::LiveActivityAlertBadge` initialize method" + end + + # check to see if the attribute exists and convert string to symbol for hash key + attributes = attributes.each_with_object({}) { |(k, v), h| + if (!self.class.attribute_map.key?(k.to_sym)) + fail ArgumentError, "`#{k}` is not a valid attribute in `OpenapiClient::LiveActivityAlertBadge`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect + end + h[k.to_sym] = v + } + + if attributes.key?(:'title') + self.title = attributes[:'title'] + else + self.title = nil + end + + if attributes.key?(:'color') + self.color = attributes[:'color'] + end + end + + # Show invalid properties with the reasons. Usually used together with valid? + # @return Array for valid properties with the reasons + def list_invalid_properties + warn '[DEPRECATED] the `list_invalid_properties` method is obsolete' + invalid_properties = Array.new + if @title.nil? + invalid_properties.push('invalid value for "title", title cannot be nil.') + end + + if @title.to_s.length < 1 + invalid_properties.push('invalid value for "title", the character length must be great than or equal to 1.') + end + + invalid_properties + end + + # Check to see if the all the properties in the model are valid + # @return true if the model is valid + def valid? + warn '[DEPRECATED] the `valid?` method is obsolete' + return false if @title.nil? + return false if @title.to_s.length < 1 + true + end + + # Custom attribute writer method with validation + # @param [Object] title Value to be assigned + def title=(title) + if title.nil? + fail ArgumentError, 'title cannot be nil' + end + + if title.to_s.length < 1 + fail ArgumentError, 'invalid value for "title", the character length must be great than or equal to 1.' + end + + @title = title + end + + # Checks equality by comparing each attribute. + # @param [Object] Object to be compared + def ==(o) + return true if self.equal?(o) + self.class == o.class && + title == o.title && + color == o.color + end + + # @see the `==` method + # @param [Object] Object to be compared + def eql?(o) + self == o + end + + # Calculates hash code according to all attributes. + # @return [Integer] Hash code + def hash + [title, color].hash + end + + # Builds the object from hash + # @param [Hash] attributes Model attributes in the form of hash + # @return [Object] Returns the model itself + def self.build_from_hash(attributes) + return nil unless attributes.is_a?(Hash) + attributes = attributes.transform_keys(&:to_sym) + transformed_hash = {} + openapi_types.each_pair do |key, type| + if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil? + transformed_hash["#{key}"] = nil + elsif type =~ /\AArray<(.*)>/i + # check to ensure the input is an array given that the attribute + # is documented as an array but the input is not + if attributes[attribute_map[key]].is_a?(Array) + transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) } + end + elsif !attributes[attribute_map[key]].nil? + transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]]) + end + end + new(transformed_hash) + end + + # Deserializes the data based on type + # @param string type Data type + # @param string value Value to be deserialized + # @return [Object] Deserialized data + def self._deserialize(type, value) + case type.to_sym + when :Time + Time.parse(value) + when :Date + Date.parse(value) + when :String + value.to_s + when :Integer + value.to_i + when :Float + value.to_f + when :Boolean + if value.to_s =~ /\A(true|t|yes|y|1)\z/i + true + else + false + end + when :Object + # generic object (usually a Hash), return directly + value + when /\AArray<(?.+)>\z/ + inner_type = Regexp.last_match[:inner_type] + value.map { |v| _deserialize(inner_type, v) } + when /\AHash<(?.+?), (?.+)>\z/ + k_type = Regexp.last_match[:k_type] + v_type = Regexp.last_match[:v_type] + {}.tap do |hash| + value.each do |k, v| + hash[_deserialize(k_type, k)] = _deserialize(v_type, v) + end + end + else # model + # models (e.g. Pet) or oneOf + klass = OpenapiClient.const_get(type) + klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value) + end + end + + # Returns the string representation of the object + # @return [String] String presentation of the object + def to_s + to_hash.to_s + end + + # to_body is an alias to to_hash (backward compatibility) + # @return [Hash] Returns the object in the form of hash + def to_body + to_hash + end + + # Returns the object in the form of hash + # @return [Hash] Returns the object in the form of hash + def to_hash + hash = {} + self.class.attribute_map.each_pair do |attr, param| + value = self.send(attr) + if value.nil? + is_nullable = self.class.openapi_nullable.include?(attr) + next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}")) + end + + hash[param] = _to_hash(value) + end + hash + end + + # Outputs non-array value in the form of hash + # For object, use to_hash. Otherwise, just return the value + # @param [Object] value Any valid value + # @return [Hash] Returns the value in the form of hash + def _to_hash(value) + if value.is_a?(Array) + value.compact.map { |v| _to_hash(v) } + elsif value.is_a?(Hash) + {}.tap do |hash| + value.each { |k, v| hash[k] = _to_hash(v) } + end + elsif value.respond_to? :to_hash + value.to_hash + else + value + end + end + + end + +end diff --git a/generated/activitysmith_openapi/models/live_activity_alert_icon.rb b/generated/activitysmith_openapi/models/live_activity_alert_icon.rb new file mode 100644 index 0000000..98a985a --- /dev/null +++ b/generated/activitysmith_openapi/models/live_activity_alert_icon.rb @@ -0,0 +1,274 @@ +=begin +#ActivitySmith API + +#Send push notifications and Live Activities to your own devices via a single API key. + +The version of the OpenAPI document: 1.0.0 + +Generated by: https://openapi-generator.tech +Generator version: 7.7.0 + +=end + +require 'date' +require 'time' + +module OpenapiClient + # Optional SF Symbol icon for alert Live Activities. + class LiveActivityAlertIcon + # Apple SF Symbol name. + attr_accessor :symbol + + # Optional icon color. + attr_accessor :color + + class EnumAttributeValidator + attr_reader :datatype + attr_reader :allowable_values + + def initialize(datatype, allowable_values) + @allowable_values = allowable_values.map do |value| + case datatype.to_s + when /Integer/i + value.to_i + when /Float/i + value.to_f + else + value + end + end + end + + def valid?(value) + !value || allowable_values.include?(value) + end + end + + # Attribute mapping from ruby-style variable name to JSON key. + def self.attribute_map + { + :'symbol' => :'symbol', + :'color' => :'color' + } + end + + # Returns all the JSON keys this model knows about + def self.acceptable_attributes + attribute_map.values + end + + # Attribute type mapping. + def self.openapi_types + { + :'symbol' => :'String', + :'color' => :'LiveActivityColor' + } + end + + # List of attributes with nullable: true + def self.openapi_nullable + Set.new([ + ]) + end + + # Initializes the object + # @param [Hash] attributes Model attributes in the form of hash + def initialize(attributes = {}) + if (!attributes.is_a?(Hash)) + fail ArgumentError, "The input argument (attributes) must be a hash in `OpenapiClient::LiveActivityAlertIcon` initialize method" + end + + # check to see if the attribute exists and convert string to symbol for hash key + attributes = attributes.each_with_object({}) { |(k, v), h| + if (!self.class.attribute_map.key?(k.to_sym)) + fail ArgumentError, "`#{k}` is not a valid attribute in `OpenapiClient::LiveActivityAlertIcon`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect + end + h[k.to_sym] = v + } + + if attributes.key?(:'symbol') + self.symbol = attributes[:'symbol'] + else + self.symbol = nil + end + + if attributes.key?(:'color') + self.color = attributes[:'color'] + end + end + + # Show invalid properties with the reasons. Usually used together with valid? + # @return Array for valid properties with the reasons + def list_invalid_properties + warn '[DEPRECATED] the `list_invalid_properties` method is obsolete' + invalid_properties = Array.new + if @symbol.nil? + invalid_properties.push('invalid value for "symbol", symbol cannot be nil.') + end + + if @symbol.to_s.length < 1 + invalid_properties.push('invalid value for "symbol", the character length must be great than or equal to 1.') + end + + invalid_properties + end + + # Check to see if the all the properties in the model are valid + # @return true if the model is valid + def valid? + warn '[DEPRECATED] the `valid?` method is obsolete' + return false if @symbol.nil? + return false if @symbol.to_s.length < 1 + true + end + + # Custom attribute writer method with validation + # @param [Object] symbol Value to be assigned + def symbol=(symbol) + if symbol.nil? + fail ArgumentError, 'symbol cannot be nil' + end + + if symbol.to_s.length < 1 + fail ArgumentError, 'invalid value for "symbol", the character length must be great than or equal to 1.' + end + + @symbol = symbol + end + + # Checks equality by comparing each attribute. + # @param [Object] Object to be compared + def ==(o) + return true if self.equal?(o) + self.class == o.class && + symbol == o.symbol && + color == o.color + end + + # @see the `==` method + # @param [Object] Object to be compared + def eql?(o) + self == o + end + + # Calculates hash code according to all attributes. + # @return [Integer] Hash code + def hash + [symbol, color].hash + end + + # Builds the object from hash + # @param [Hash] attributes Model attributes in the form of hash + # @return [Object] Returns the model itself + def self.build_from_hash(attributes) + return nil unless attributes.is_a?(Hash) + attributes = attributes.transform_keys(&:to_sym) + transformed_hash = {} + openapi_types.each_pair do |key, type| + if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil? + transformed_hash["#{key}"] = nil + elsif type =~ /\AArray<(.*)>/i + # check to ensure the input is an array given that the attribute + # is documented as an array but the input is not + if attributes[attribute_map[key]].is_a?(Array) + transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) } + end + elsif !attributes[attribute_map[key]].nil? + transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]]) + end + end + new(transformed_hash) + end + + # Deserializes the data based on type + # @param string type Data type + # @param string value Value to be deserialized + # @return [Object] Deserialized data + def self._deserialize(type, value) + case type.to_sym + when :Time + Time.parse(value) + when :Date + Date.parse(value) + when :String + value.to_s + when :Integer + value.to_i + when :Float + value.to_f + when :Boolean + if value.to_s =~ /\A(true|t|yes|y|1)\z/i + true + else + false + end + when :Object + # generic object (usually a Hash), return directly + value + when /\AArray<(?.+)>\z/ + inner_type = Regexp.last_match[:inner_type] + value.map { |v| _deserialize(inner_type, v) } + when /\AHash<(?.+?), (?.+)>\z/ + k_type = Regexp.last_match[:k_type] + v_type = Regexp.last_match[:v_type] + {}.tap do |hash| + value.each do |k, v| + hash[_deserialize(k_type, k)] = _deserialize(v_type, v) + end + end + else # model + # models (e.g. Pet) or oneOf + klass = OpenapiClient.const_get(type) + klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value) + end + end + + # Returns the string representation of the object + # @return [String] String presentation of the object + def to_s + to_hash.to_s + end + + # to_body is an alias to to_hash (backward compatibility) + # @return [Hash] Returns the object in the form of hash + def to_body + to_hash + end + + # Returns the object in the form of hash + # @return [Hash] Returns the object in the form of hash + def to_hash + hash = {} + self.class.attribute_map.each_pair do |attr, param| + value = self.send(attr) + if value.nil? + is_nullable = self.class.openapi_nullable.include?(attr) + next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}")) + end + + hash[param] = _to_hash(value) + end + hash + end + + # Outputs non-array value in the form of hash + # For object, use to_hash. Otherwise, just return the value + # @param [Object] value Any valid value + # @return [Hash] Returns the value in the form of hash + def _to_hash(value) + if value.is_a?(Array) + value.compact.map { |v| _to_hash(v) } + elsif value.is_a?(Hash) + {}.tap do |hash| + value.each { |k, v| hash[k] = _to_hash(v) } + end + elsif value.respond_to? :to_hash + value.to_hash + else + value + end + end + + end + +end diff --git a/generated/activitysmith_openapi/models/live_activity_color.rb b/generated/activitysmith_openapi/models/live_activity_color.rb new file mode 100644 index 0000000..f0a3161 --- /dev/null +++ b/generated/activitysmith_openapi/models/live_activity_color.rb @@ -0,0 +1,48 @@ +=begin +#ActivitySmith API + +#Send push notifications and Live Activities to your own devices via a single API key. + +The version of the OpenAPI document: 1.0.0 + +Generated by: https://openapi-generator.tech +Generator version: 7.7.0 + +=end + +require 'date' +require 'time' + +module OpenapiClient + class LiveActivityColor + LIME = "lime".freeze + GREEN = "green".freeze + CYAN = "cyan".freeze + BLUE = "blue".freeze + PURPLE = "purple".freeze + MAGENTA = "magenta".freeze + RED = "red".freeze + ORANGE = "orange".freeze + YELLOW = "yellow".freeze + GRAY = "gray".freeze + + def self.all_vars + @all_vars ||= [LIME, GREEN, CYAN, BLUE, PURPLE, MAGENTA, RED, ORANGE, YELLOW, GRAY].freeze + end + + # Builds the enum from string + # @param [String] The enum value in the form of the string + # @return [String] The enum value + def self.build_from_hash(value) + new.build_from_hash(value) + end + + # Builds the enum from string + # @param [String] The enum value in the form of the string + # @return [String] The enum value + def build_from_hash(value) + return value if LiveActivityColor.all_vars.include?(value) + raise "Invalid ENUM value #{value} for class #LiveActivityColor" + end + end +end diff --git a/generated/activitysmith_openapi/models/stream_content_state.rb b/generated/activitysmith_openapi/models/stream_content_state.rb index a03569f..8640803 100644 --- a/generated/activitysmith_openapi/models/stream_content_state.rb +++ b/generated/activitysmith_openapi/models/stream_content_state.rb @@ -14,7 +14,7 @@ require 'time' module OpenapiClient - # Current state for a managed Live Activity stream. Include type on the first PUT, and whenever the stream may need to start a fresh activity. Supports segmented_progress, progress, metrics, and stats types. + # Current state for a managed Live Activity stream. Include type on the first PUT, and whenever the stream may need to start a fresh activity. Supports segmented_progress, progress, metrics, stats, and alert types. class StreamContentState attr_accessor :title @@ -38,7 +38,7 @@ class StreamContentState # Required on the first PUT or whenever the stream cannot infer the current activity type. attr_accessor :type - # Optional. Accent color for the Live Activity. Defaults to blue. + # Optional. Accent color for progress, segmented_progress, and metrics 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 segmented_progress. @@ -50,6 +50,15 @@ class StreamContentState # Use for metrics and stats activities. attr_accessor :metrics + # Required for type=alert. + attr_accessor :message + + # Optional SF Symbol icon for type=alert. + attr_accessor :icon + + # Optional badge for type=alert. + attr_accessor :badge + # Optional. Seconds before the ended Live Activity is dismissed. attr_accessor :auto_dismiss_seconds @@ -93,6 +102,9 @@ def self.attribute_map :'step_color' => :'step_color', :'step_colors' => :'step_colors', :'metrics' => :'metrics', + :'message' => :'message', + :'icon' => :'icon', + :'badge' => :'badge', :'auto_dismiss_seconds' => :'auto_dismiss_seconds', :'auto_dismiss_minutes' => :'auto_dismiss_minutes' } @@ -118,6 +130,9 @@ def self.openapi_types :'step_color' => :'String', :'step_colors' => :'Array', :'metrics' => :'Array', + :'message' => :'String', + :'icon' => :'LiveActivityAlertIcon', + :'badge' => :'LiveActivityAlertBadge', :'auto_dismiss_seconds' => :'Integer', :'auto_dismiss_minutes' => :'Integer' } @@ -180,8 +195,6 @@ def initialize(attributes = {}) if attributes.key?(:'color') self.color = attributes[:'color'] - else - self.color = 'blue' end if attributes.key?(:'step_color') @@ -200,6 +213,18 @@ def initialize(attributes = {}) end end + if attributes.key?(:'message') + self.message = attributes[:'message'] + end + + if attributes.key?(:'icon') + self.icon = attributes[:'icon'] + end + + if attributes.key?(:'badge') + self.badge = attributes[:'badge'] + end + if attributes.key?(:'auto_dismiss_seconds') self.auto_dismiss_seconds = attributes[:'auto_dismiss_seconds'] end @@ -242,6 +267,10 @@ def list_invalid_properties invalid_properties.push('invalid value for "metrics", number of items must be greater than or equal to 1.') end + if !@message.nil? && @message.to_s.length < 1 + invalid_properties.push('invalid value for "message", the character length must be great than or equal to 1.') + end + if !@auto_dismiss_seconds.nil? && @auto_dismiss_seconds < 0 invalid_properties.push('invalid value for "auto_dismiss_seconds", must be greater than or equal to 0.') end @@ -262,14 +291,15 @@ def valid? return false if !@current_step.nil? && @current_step < 1 return false if !@percentage.nil? && @percentage > 100 return false if !@percentage.nil? && @percentage < 0 - type_validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats"]) + type_validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats", "alert"]) return false unless type_validator.valid?(@type) - color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) return false unless color_validator.valid?(@color) - step_color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + step_color_validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) return false unless step_color_validator.valid?(@step_color) 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 return false if !@auto_dismiss_seconds.nil? && @auto_dismiss_seconds < 0 return false if !@auto_dismiss_minutes.nil? && @auto_dismiss_minutes < 0 true @@ -324,7 +354,7 @@ def percentage=(percentage) # 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"]) + validator = EnumAttributeValidator.new('String', ["segmented_progress", "progress", "metrics", "stats", "alert"]) unless validator.valid?(type) fail ArgumentError, "invalid value for \"type\", must be one of #{validator.allowable_values}." end @@ -334,7 +364,7 @@ def type=(type) # Custom attribute writer method checking allowed values (enum). # @param [Object] color Object to be assigned def color=(color) - validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) unless validator.valid?(color) fail ArgumentError, "invalid value for \"color\", must be one of #{validator.allowable_values}." end @@ -344,7 +374,7 @@ def color=(color) # Custom attribute writer method checking allowed values (enum). # @param [Object] step_color Object to be assigned def step_color=(step_color) - validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow"]) + validator = EnumAttributeValidator.new('String', ["lime", "green", "cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "gray"]) unless validator.valid?(step_color) fail ArgumentError, "invalid value for \"step_color\", must be one of #{validator.allowable_values}." end @@ -369,6 +399,20 @@ def metrics=(metrics) @metrics = metrics end + # Custom attribute writer method with validation + # @param [Object] message Value to be assigned + def message=(message) + if message.nil? + fail ArgumentError, 'message cannot be nil' + end + + if message.to_s.length < 1 + fail ArgumentError, 'invalid value for "message", the character length must be great than or equal to 1.' + end + + @message = message + end + # Custom attribute writer method with validation # @param [Object] auto_dismiss_seconds Value to be assigned def auto_dismiss_seconds=(auto_dismiss_seconds) @@ -414,6 +458,9 @@ def ==(o) step_color == o.step_color && step_colors == o.step_colors && metrics == o.metrics && + message == o.message && + icon == o.icon && + badge == o.badge && auto_dismiss_seconds == o.auto_dismiss_seconds && auto_dismiss_minutes == o.auto_dismiss_minutes end @@ -427,7 +474,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, type, color, step_color, step_colors, metrics, auto_dismiss_seconds, auto_dismiss_minutes].hash + [title, subtitle, number_of_steps, current_step, percentage, value, upper_limit, type, color, step_color, step_colors, metrics, message, icon, badge, auto_dismiss_seconds, auto_dismiss_minutes].hash end # Builds the object from hash From ecdb9d2277d48f7726af869cff2ca84135614897 Mon Sep 17 00:00:00 2001 From: bardonadam Date: Thu, 28 May 2026 15:34:40 +0700 Subject: [PATCH 4/4] docs: title-case Alert Live Activity references Why: - Alert Live Activity should use product-style casing in SDK docs and generated API comments. How: - Update README wording and generated OpenAPI-derived descriptions from alert Live Activities to Alert Live Activities. Verification: - git diff --check Initiated-by: user Implemented-by: codex --- README.md | 2 +- generated/activitysmith_openapi/models/content_state_end.rb | 2 +- generated/activitysmith_openapi/models/content_state_start.rb | 2 +- generated/activitysmith_openapi/models/content_state_update.rb | 2 +- .../activitysmith_openapi/models/live_activity_alert_badge.rb | 2 +- .../activitysmith_openapi/models/live_activity_alert_icon.rb | 2 +- generated/activitysmith_openapi/models/stream_content_state.rb | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index cac6eb9..818a875 100644 --- a/README.md +++ b/README.md @@ -297,7 +297,7 @@ activitysmith.live_activities.end_stream( ### Live Activity Action Live Activities can include one optional action button. Use it to open a URL from the Live Activity or trigger a backend webhook. -For alert Live Activities, set `color` in `content_state` to tint the action button. Icon and badge colors only affect the icon and badge. +For Alert Live Activities, set `color` in `content_state` to tint the action button. Icon and badge colors only affect the icon and badge.