diff --git a/CHANGELOG.md b/CHANGELOG.md index 9485214..0118f44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.10.0 + +### New Features + +- **New Feature: Tags** — Organize and filter your Push Notification and Live Activity history using one or more tags. + ## 1.9.0 ### New Features diff --git a/README.md b/README.md index ad2cf0e..f2aefbb 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ See [API reference](https://activitysmith.com/docs/api-reference/introduction). - [Widgets](#widgets) - [App Icon Badge Count](#app-icon-badge-count) - [Channels](#channels) +- [Tags](#tags) ## Installation @@ -616,6 +617,20 @@ activitysmith.live_activities.start( activitysmith.badge_count(3, channels: ["sales", "customer-success"]) ``` +## Tags + +Use `tags` to organize and filter your Push Notification and Live Activity history. Tags are created automatically when you first use them. + +```ruby +activitysmith.notifications.send( + { + title: "New subscription 💸", + message: "Customer upgraded to Pro plan", + tags: ["user:382", "billing"] + } +) +``` + ## Error Handling ```ruby diff --git a/generated/activitysmith_openapi/api/app_icon_badges_api.rb b/generated/activitysmith_openapi/api/app_icon_badges_api.rb index 0ee813e..a1deb11 100644 --- a/generated/activitysmith_openapi/api/app_icon_badges_api.rb +++ b/generated/activitysmith_openapi/api/app_icon_badges_api.rb @@ -19,8 +19,8 @@ class AppIconBadgesApi def initialize(api_client = ApiClient.default) @api_client = api_client end - # Update App Icon Badge Count - # Updates the App Icon Badge Count on devices matched by API key scope and optional target channels. Send `badge: 0` to clear the count. Badge updates are independent of push notifications and do not create a push notification history item. + # Set App Icon Badge Count + # Shows a number on the ActivitySmith app icon. # @param app_icon_badge_count_update_request [AppIconBadgeCountUpdateRequest] # @param [Hash] opts the optional parameters # @return [AppIconBadgeCountUpdateResponse] @@ -29,8 +29,8 @@ def update_app_icon_badge_count(app_icon_badge_count_update_request, opts = {}) data end - # Update App Icon Badge Count - # Updates the App Icon Badge Count on devices matched by API key scope and optional target channels. Send `badge: 0` to clear the count. Badge updates are independent of push notifications and do not create a push notification history item. + # Set App Icon Badge Count + # Shows a number on the ActivitySmith app icon. # @param app_icon_badge_count_update_request [AppIconBadgeCountUpdateRequest] # @param [Hash] opts the optional parameters # @return [Array<(AppIconBadgeCountUpdateResponse, Integer, Hash)>] AppIconBadgeCountUpdateResponse data, response status code and response headers diff --git a/generated/activitysmith_openapi/api/live_activities_api.rb b/generated/activitysmith_openapi/api/live_activities_api.rb index 175ad8c..18c7cb4 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, 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. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities only. + # 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. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities. # @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, 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. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities only. + # 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. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities. # @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 @@ -88,7 +88,7 @@ def end_live_activity_with_http_info(live_activity_end_request, opts = {}) end # End a stream - # Use this endpoint when the process you are tracking is finished and you no longer want the Live Activity on your devices. ActivitySmith ends the current Live Activity for this stream and dismisses it from devices. If you need direct lifecycle control, use /live-activity/start, /live-activity/update, and /live-activity/end instead. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities only. + # Use this endpoint when the process you are tracking is finished and you no longer want the Live Activity on your devices. ActivitySmith ends the current Live Activity for this stream and dismisses it from devices. If you need direct lifecycle control, use /live-activity/start, /live-activity/update, and /live-activity/end instead. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities. # @param stream_key [String] Stable identifier for one ongoing thing. Allowed characters: letters, numbers, underscores, and hyphens. # @param [Hash] opts the optional parameters # @option opts [LiveActivityStreamDeleteRequest] :live_activity_stream_delete_request @@ -99,7 +99,7 @@ def end_live_activity_stream(stream_key, opts = {}) end # End a stream - # Use this endpoint when the process you are tracking is finished and you no longer want the Live Activity on your devices. ActivitySmith ends the current Live Activity for this stream and dismisses it from devices. If you need direct lifecycle control, use /live-activity/start, /live-activity/update, and /live-activity/end instead. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities only. + # Use this endpoint when the process you are tracking is finished and you no longer want the Live Activity on your devices. ActivitySmith ends the current Live Activity for this stream and dismisses it from devices. If you need direct lifecycle control, use /live-activity/start, /live-activity/update, and /live-activity/end instead. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities. # @param stream_key [String] Stable identifier for one ongoing thing. Allowed characters: letters, numbers, underscores, and hyphens. # @param [Hash] opts the optional parameters # @option opts [LiveActivityStreamDeleteRequest] :live_activity_stream_delete_request @@ -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. For timer streams, send duration_seconds to start or reset the timer; omit duration_seconds on later updates to preserve the existing timer window. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities only. + # 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. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities. Optional tags to organize and filter notification history. On later stream updates, omit tags to keep the current tags, send tags again to replace them, or send an empty array to clear them. # @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 @@ -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. For timer streams, send duration_seconds to start or reset the timer; omit duration_seconds on later updates to preserve the existing timer window. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities only. + # 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. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities. Optional tags to organize and filter notification history. On later stream updates, omit tags to keep the current tags, send tags again to replace them, or send an empty array to clear them. # @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 @@ -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, 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. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities only. + # 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. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities. Optional tags to organize and filter notification history. # @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, 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. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities only. + # 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. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities. Optional tags to organize and filter notification history. # @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, 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. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities only. + # 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. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities. # @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, 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. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities only. + # 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. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities. # @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/api/push_notifications_api.rb b/generated/activitysmith_openapi/api/push_notifications_api.rb index ee2ab0b..8eb5e90 100644 --- a/generated/activitysmith_openapi/api/push_notifications_api.rb +++ b/generated/activitysmith_openapi/api/push_notifications_api.rb @@ -20,7 +20,7 @@ def initialize(api_client = ApiClient.default) @api_client = api_client end # Send a push notification - # Sends a push notification to devices matched by API key scope and optional target channels. Supports optional redirection URL, optional media preview or playback when the notification is expanded, and up to 4 interactive actions. `media` cannot be combined with `actions`. + # Sends a push notification to devices matched by API key scope and optional target channels. Supports optional redirection URL, optional media preview or playback when the notification is expanded, and up to 4 interactive actions. `media` cannot be combined with `actions`. Optional tags to organize and filter notification history. # @param push_notification_request [PushNotificationRequest] # @param [Hash] opts the optional parameters # @return [PushNotificationResponse] @@ -30,7 +30,7 @@ def send_push_notification(push_notification_request, opts = {}) end # Send a push notification - # Sends a push notification to devices matched by API key scope and optional target channels. Supports optional redirection URL, optional media preview or playback when the notification is expanded, and up to 4 interactive actions. `media` cannot be combined with `actions`. + # Sends a push notification to devices matched by API key scope and optional target channels. Supports optional redirection URL, optional media preview or playback when the notification is expanded, and up to 4 interactive actions. `media` cannot be combined with `actions`. Optional tags to organize and filter notification history. # @param push_notification_request [PushNotificationRequest] # @param [Hash] opts the optional parameters # @return [Array<(PushNotificationResponse, Integer, Hash)>] PushNotificationResponse data, response status code and response headers diff --git a/generated/activitysmith_openapi/models/app_icon_badge_count_update_request.rb b/generated/activitysmith_openapi/models/app_icon_badge_count_update_request.rb index 090f14d..8d55d24 100644 --- a/generated/activitysmith_openapi/models/app_icon_badge_count_update_request.rb +++ b/generated/activitysmith_openapi/models/app_icon_badge_count_update_request.rb @@ -14,7 +14,6 @@ require 'time' module OpenapiClient - # App Icon Badge Count update. Send badge 0 to clear the count. class AppIconBadgeCountUpdateRequest # The count to show on the ActivitySmith app icon. Send 0 to clear it. attr_accessor :badge diff --git a/generated/activitysmith_openapi/models/live_activity_action.rb b/generated/activitysmith_openapi/models/live_activity_action.rb index c4f1e42..682acfe 100644 --- a/generated/activitysmith_openapi/models/live_activity_action.rb +++ b/generated/activitysmith_openapi/models/live_activity_action.rb @@ -21,7 +21,7 @@ class LiveActivityAction attr_accessor :type - # Action URL. For open_url, use an HTTPS URL or a shortcuts://run-shortcut?name=... URL that runs a specific iPhone Shortcut. For webhook, use an HTTPS URL called by the ActivitySmith backend. + # Action URL. For open_url, use an HTTP or HTTPS URL or a shortcuts://run-shortcut?name=... URL that runs a specific iPhone Shortcut. For webhook, use an HTTPS URL called by the ActivitySmith backend. attr_accessor :url # Webhook HTTP method. Used only when type=webhook. diff --git a/generated/activitysmith_openapi/models/live_activity_end_request.rb b/generated/activitysmith_openapi/models/live_activity_end_request.rb index 13d1fcb..40b43c2 100644 --- a/generated/activitysmith_openapi/models/live_activity_end_request.rb +++ b/generated/activitysmith_openapi/models/live_activity_end_request.rb @@ -22,7 +22,7 @@ class LiveActivityEndRequest attr_accessor :action - # Optional secondary action button. Supported only for alert, progress, and segmented_progress Live Activities. Uses the same open_url, shortcuts://, and webhook shapes as action. + # Optional secondary action button. Supported for alert, progress, and segmented_progress Live Activities. Uses the same open_url, shortcuts://, and webhook shapes as action. attr_accessor :secondary_action # Attribute mapping from ruby-style variable name to JSON key. diff --git a/generated/activitysmith_openapi/models/live_activity_start_request.rb b/generated/activitysmith_openapi/models/live_activity_start_request.rb index 02d1445..7297a28 100644 --- a/generated/activitysmith_openapi/models/live_activity_start_request.rb +++ b/generated/activitysmith_openapi/models/live_activity_start_request.rb @@ -20,13 +20,16 @@ class LiveActivityStartRequest attr_accessor :action - # Optional secondary action button. Supported only for alert, progress, and segmented_progress Live Activities. Uses the same open_url, shortcuts://, and webhook shapes as action. + # Optional secondary action button. Supported for alert, progress, and segmented_progress Live Activities. Uses the same open_url, shortcuts://, and webhook shapes as action. attr_accessor :secondary_action attr_accessor :alert attr_accessor :target + # Optional tags to organize and filter notification history. + attr_accessor :tags + # Attribute mapping from ruby-style variable name to JSON key. def self.attribute_map { @@ -34,7 +37,8 @@ def self.attribute_map :'action' => :'action', :'secondary_action' => :'secondary_action', :'alert' => :'alert', - :'target' => :'target' + :'target' => :'target', + :'tags' => :'tags' } end @@ -50,7 +54,8 @@ def self.openapi_types :'action' => :'LiveActivityAction', :'secondary_action' => :'LiveActivityAction', :'alert' => :'AlertPayload', - :'target' => :'ChannelTarget' + :'target' => :'ChannelTarget', + :'tags' => :'Array' } end @@ -96,6 +101,12 @@ def initialize(attributes = {}) if attributes.key?(:'target') self.target = attributes[:'target'] end + + if attributes.key?(:'tags') + if (value = attributes[:'tags']).is_a?(Array) + self.tags = value + end + end end # Show invalid properties with the reasons. Usually used together with valid? @@ -127,7 +138,8 @@ def ==(o) action == o.action && secondary_action == o.secondary_action && alert == o.alert && - target == o.target + target == o.target && + tags == o.tags end # @see the `==` method @@ -139,7 +151,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [content_state, action, secondary_action, alert, target].hash + [content_state, action, secondary_action, alert, target, tags].hash end # Builds the object from hash diff --git a/generated/activitysmith_openapi/models/live_activity_start_response.rb b/generated/activitysmith_openapi/models/live_activity_start_response.rb index cbb3288..d16624c 100644 --- a/generated/activitysmith_openapi/models/live_activity_start_response.rb +++ b/generated/activitysmith_openapi/models/live_activity_start_response.rb @@ -26,6 +26,9 @@ class LiveActivityStartResponse attr_accessor :effective_channel_slugs + # Optional tags to organize and filter notification history. + attr_accessor :tags + attr_accessor :timestamp # Attribute mapping from ruby-style variable name to JSON key. @@ -36,6 +39,7 @@ def self.attribute_map :'users_notified' => :'users_notified', :'activity_id' => :'activity_id', :'effective_channel_slugs' => :'effective_channel_slugs', + :'tags' => :'tags', :'timestamp' => :'timestamp' } end @@ -53,6 +57,7 @@ def self.openapi_types :'users_notified' => :'Integer', :'activity_id' => :'String', :'effective_channel_slugs' => :'Array', + :'tags' => :'Array', :'timestamp' => :'Time' } end @@ -104,6 +109,12 @@ def initialize(attributes = {}) end end + if attributes.key?(:'tags') + if (value = attributes[:'tags']).is_a?(Array) + self.tags = value + end + end + if attributes.key?(:'timestamp') self.timestamp = attributes[:'timestamp'] else @@ -151,6 +162,7 @@ def ==(o) users_notified == o.users_notified && activity_id == o.activity_id && effective_channel_slugs == o.effective_channel_slugs && + tags == o.tags && timestamp == o.timestamp end @@ -163,7 +175,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [success, devices_notified, users_notified, activity_id, effective_channel_slugs, timestamp].hash + [success, devices_notified, users_notified, activity_id, effective_channel_slugs, tags, timestamp].hash end # Builds the object from hash diff --git a/generated/activitysmith_openapi/models/live_activity_stream_delete_request.rb b/generated/activitysmith_openapi/models/live_activity_stream_delete_request.rb index d9009e3..97f1dd2 100644 --- a/generated/activitysmith_openapi/models/live_activity_stream_delete_request.rb +++ b/generated/activitysmith_openapi/models/live_activity_stream_delete_request.rb @@ -20,7 +20,7 @@ class LiveActivityStreamDeleteRequest attr_accessor :action - # Optional secondary action button. Supported only for alert, progress, and segmented_progress Live Activities. Uses the same open_url, shortcuts://, and webhook shapes as action. + # Optional secondary action button. Supported for alert, progress, and segmented_progress Live Activities. Uses the same open_url, shortcuts://, and webhook shapes as action. attr_accessor :secondary_action attr_accessor :alert diff --git a/generated/activitysmith_openapi/models/live_activity_stream_put_response.rb b/generated/activitysmith_openapi/models/live_activity_stream_put_response.rb index f195c0d..a0a2cd4 100644 --- a/generated/activitysmith_openapi/models/live_activity_stream_put_response.rb +++ b/generated/activitysmith_openapi/models/live_activity_stream_put_response.rb @@ -34,6 +34,9 @@ class LiveActivityStreamPutResponse attr_accessor :effective_channel_slugs + # Optional tags to organize and filter notification history. + attr_accessor :tags + attr_accessor :timestamp class EnumAttributeValidator @@ -70,6 +73,7 @@ def self.attribute_map :'devices_queued' => :'devices_queued', :'users_notified' => :'users_notified', :'effective_channel_slugs' => :'effective_channel_slugs', + :'tags' => :'tags', :'timestamp' => :'timestamp' } end @@ -91,6 +95,7 @@ def self.openapi_types :'devices_queued' => :'Integer', :'users_notified' => :'Integer', :'effective_channel_slugs' => :'Array', + :'tags' => :'Array', :'timestamp' => :'Time' } end @@ -161,6 +166,12 @@ def initialize(attributes = {}) end end + if attributes.key?(:'tags') + if (value = attributes[:'tags']).is_a?(Array) + self.tags = value + end + end + if attributes.key?(:'timestamp') self.timestamp = attributes[:'timestamp'] else @@ -229,6 +240,7 @@ def ==(o) devices_queued == o.devices_queued && users_notified == o.users_notified && effective_channel_slugs == o.effective_channel_slugs && + tags == o.tags && timestamp == o.timestamp end @@ -241,7 +253,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [success, operation, stream_key, activity_id, previous_activity_id, devices_notified, devices_queued, users_notified, effective_channel_slugs, timestamp].hash + [success, operation, stream_key, activity_id, previous_activity_id, devices_notified, devices_queued, users_notified, effective_channel_slugs, tags, timestamp].hash end # Builds the object from hash diff --git a/generated/activitysmith_openapi/models/live_activity_stream_request.rb b/generated/activitysmith_openapi/models/live_activity_stream_request.rb index 925f1d3..d2581d7 100644 --- a/generated/activitysmith_openapi/models/live_activity_stream_request.rb +++ b/generated/activitysmith_openapi/models/live_activity_stream_request.rb @@ -20,7 +20,7 @@ class LiveActivityStreamRequest attr_accessor :action - # Optional secondary action button. Supported only for alert, progress, and segmented_progress Live Activities. Uses the same open_url, shortcuts://, and webhook shapes as action. + # Optional secondary action button. Supported for alert, progress, and segmented_progress Live Activities. Uses the same open_url, shortcuts://, and webhook shapes as action. attr_accessor :secondary_action attr_accessor :alert @@ -30,6 +30,9 @@ class LiveActivityStreamRequest attr_accessor :target + # Optional tags to organize and filter notification history. + attr_accessor :tags + # Attribute mapping from ruby-style variable name to JSON key. def self.attribute_map { @@ -38,7 +41,8 @@ def self.attribute_map :'secondary_action' => :'secondary_action', :'alert' => :'alert', :'channels' => :'channels', - :'target' => :'target' + :'target' => :'target', + :'tags' => :'tags' } end @@ -55,7 +59,8 @@ def self.openapi_types :'secondary_action' => :'LiveActivityAction', :'alert' => :'AlertPayload', :'channels' => :'Array', - :'target' => :'ChannelTarget' + :'target' => :'ChannelTarget', + :'tags' => :'Array' } end @@ -107,6 +112,12 @@ def initialize(attributes = {}) if attributes.key?(:'target') self.target = attributes[:'target'] end + + if attributes.key?(:'tags') + if (value = attributes[:'tags']).is_a?(Array) + self.tags = value + end + end end # Show invalid properties with the reasons. Usually used together with valid? @@ -158,7 +169,8 @@ def ==(o) secondary_action == o.secondary_action && alert == o.alert && channels == o.channels && - target == o.target + target == o.target && + tags == o.tags end # @see the `==` method @@ -170,7 +182,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [content_state, action, secondary_action, alert, channels, target].hash + [content_state, action, secondary_action, alert, channels, target, tags].hash end # Builds the object from hash diff --git a/generated/activitysmith_openapi/models/live_activity_update_request.rb b/generated/activitysmith_openapi/models/live_activity_update_request.rb index f6ca992..b952430 100644 --- a/generated/activitysmith_openapi/models/live_activity_update_request.rb +++ b/generated/activitysmith_openapi/models/live_activity_update_request.rb @@ -22,7 +22,7 @@ class LiveActivityUpdateRequest attr_accessor :action - # Optional secondary action button. Supported only for alert, progress, and segmented_progress Live Activities. Uses the same open_url, shortcuts://, and webhook shapes as action. + # Optional secondary action button. Supported for alert, progress, and segmented_progress Live Activities. Uses the same open_url, shortcuts://, and webhook shapes as action. attr_accessor :secondary_action # Attribute mapping from ruby-style variable name to JSON key. diff --git a/generated/activitysmith_openapi/models/push_notification_action.rb b/generated/activitysmith_openapi/models/push_notification_action.rb index f64fe47..d29eb66 100644 --- a/generated/activitysmith_openapi/models/push_notification_action.rb +++ b/generated/activitysmith_openapi/models/push_notification_action.rb @@ -20,7 +20,7 @@ class PushNotificationAction attr_accessor :type - # Action URL. For open_url, use an HTTPS URL or a shortcuts://run-shortcut?name=... URL that runs a specific iPhone Shortcut. For webhook, use an HTTPS URL called by the ActivitySmith backend. + # Action URL. For open_url, use an HTTP or HTTPS URL or a shortcuts://run-shortcut?name=... URL that runs a specific iPhone Shortcut. For webhook, use an HTTPS URL called by the ActivitySmith backend. attr_accessor :url # Webhook HTTP method. Used only when type=webhook. diff --git a/generated/activitysmith_openapi/models/push_notification_request.rb b/generated/activitysmith_openapi/models/push_notification_request.rb index effcb1b..cfba9e2 100644 --- a/generated/activitysmith_openapi/models/push_notification_request.rb +++ b/generated/activitysmith_openapi/models/push_notification_request.rb @@ -24,7 +24,7 @@ class PushNotificationRequest # Optional HTTPS URL for an image, audio file, or video that users can preview or play when they expand the notification. If `redirection` is omitted, tapping the notification opens this URL. Cannot be combined with `actions`. attr_accessor :media - # Optional HTTPS URL or shortcuts://run-shortcut?name=... URL opened when the user taps the notification body. Use shortcuts://run-shortcut?name=... to run a specific iPhone Shortcut that already exists on the user's device. Overrides the default tap target from `media` when both are provided. + # Optional HTTP URL, HTTPS URL, or shortcuts://run-shortcut?name=... URL opened when the user taps the notification body. Use shortcuts://run-shortcut?name=... to run a specific iPhone Shortcut that already exists on the user's device. Overrides the default tap target from `media` when both are provided. attr_accessor :redirection # Optional interactive actions shown when users expand the notification. Cannot be combined with `media`. @@ -38,6 +38,9 @@ class PushNotificationRequest attr_accessor :target + # Optional tags to organize and filter notification history. + attr_accessor :tags + # Attribute mapping from ruby-style variable name to JSON key. def self.attribute_map { @@ -50,7 +53,8 @@ def self.attribute_map :'payload' => :'payload', :'badge' => :'badge', :'sound' => :'sound', - :'target' => :'target' + :'target' => :'target', + :'tags' => :'tags' } end @@ -71,7 +75,8 @@ def self.openapi_types :'payload' => :'Object', :'badge' => :'Integer', :'sound' => :'String', - :'target' => :'ChannelTarget' + :'target' => :'ChannelTarget', + :'tags' => :'Array' } end @@ -139,6 +144,12 @@ def initialize(attributes = {}) if attributes.key?(:'target') self.target = attributes[:'target'] end + + if attributes.key?(:'tags') + if (value = attributes[:'tags']).is_a?(Array) + self.tags = value + end + end end # Show invalid properties with the reasons. Usually used together with valid? @@ -155,7 +166,7 @@ def list_invalid_properties invalid_properties.push("invalid value for \"media\", must conform to the pattern #{pattern}.") end - pattern = Regexp.new(/^(https|shortcuts):\/\//) + pattern = Regexp.new(/^(http|https|shortcuts):\/\//) if !@redirection.nil? && @redirection !~ pattern invalid_properties.push("invalid value for \"redirection\", must conform to the pattern #{pattern}.") end @@ -173,7 +184,7 @@ def valid? warn '[DEPRECATED] the `valid?` method is obsolete' return false if @title.nil? return false if !@media.nil? && @media !~ Regexp.new(/^https:\/\//) - return false if !@redirection.nil? && @redirection !~ Regexp.new(/^(https|shortcuts):\/\//) + return false if !@redirection.nil? && @redirection !~ Regexp.new(/^(http|https|shortcuts):\/\//) return false if !@actions.nil? && @actions.length > 4 true end @@ -200,7 +211,7 @@ def redirection=(redirection) fail ArgumentError, 'redirection cannot be nil' end - pattern = Regexp.new(/^(https|shortcuts):\/\//) + pattern = Regexp.new(/^(http|https|shortcuts):\/\//) if redirection !~ pattern fail ArgumentError, "invalid value for \"redirection\", must conform to the pattern #{pattern}." end @@ -236,7 +247,8 @@ def ==(o) payload == o.payload && badge == o.badge && sound == o.sound && - target == o.target + target == o.target && + tags == o.tags end # @see the `==` method @@ -248,7 +260,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [title, message, subtitle, media, redirection, actions, payload, badge, sound, target].hash + [title, message, subtitle, media, redirection, actions, payload, badge, sound, target, tags].hash end # Builds the object from hash diff --git a/generated/activitysmith_openapi/models/push_notification_response.rb b/generated/activitysmith_openapi/models/push_notification_response.rb index 9b1a3ca..06733f2 100644 --- a/generated/activitysmith_openapi/models/push_notification_response.rb +++ b/generated/activitysmith_openapi/models/push_notification_response.rb @@ -23,6 +23,9 @@ class PushNotificationResponse attr_accessor :effective_channel_slugs + # Optional tags to organize and filter notification history. + attr_accessor :tags + attr_accessor :timestamp # Attribute mapping from ruby-style variable name to JSON key. @@ -32,6 +35,7 @@ def self.attribute_map :'devices_notified' => :'devices_notified', :'users_notified' => :'users_notified', :'effective_channel_slugs' => :'effective_channel_slugs', + :'tags' => :'tags', :'timestamp' => :'timestamp' } end @@ -48,6 +52,7 @@ def self.openapi_types :'devices_notified' => :'Integer', :'users_notified' => :'Integer', :'effective_channel_slugs' => :'Array', + :'tags' => :'Array', :'timestamp' => :'Time' } end @@ -93,6 +98,12 @@ def initialize(attributes = {}) end end + if attributes.key?(:'tags') + if (value = attributes[:'tags']).is_a?(Array) + self.tags = value + end + end + if attributes.key?(:'timestamp') self.timestamp = attributes[:'timestamp'] else @@ -134,6 +145,7 @@ def ==(o) devices_notified == o.devices_notified && users_notified == o.users_notified && effective_channel_slugs == o.effective_channel_slugs && + tags == o.tags && timestamp == o.timestamp end @@ -146,7 +158,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [success, devices_notified, users_notified, effective_channel_slugs, timestamp].hash + [success, devices_notified, users_notified, effective_channel_slugs, tags, timestamp].hash end # Builds the object from hash diff --git a/generated/activitysmith_openapi/version.rb b/generated/activitysmith_openapi/version.rb index 5e27329..77eed2b 100644 --- a/generated/activitysmith_openapi/version.rb +++ b/generated/activitysmith_openapi/version.rb @@ -11,5 +11,5 @@ =end module OpenapiClient - VERSION = '1.8.0' + VERSION = '1.10.0' end diff --git a/lib/activitysmith/live_activities.rb b/lib/activitysmith/live_activities.rb index 5735c70..173ca9f 100644 --- a/lib/activitysmith/live_activities.rb +++ b/lib/activitysmith/live_activities.rb @@ -38,8 +38,13 @@ def initialize(api) @api = api end - def start(request, opts = {}) - @api.start_live_activity(normalize_live_activity_request(normalize_channels_target(request)), opts) + def start(request = nil, opts = {}, tags: nil, **request_fields) + @api.start_live_activity( + normalize_live_activity_request( + normalize_channels_target(with_tags(combine_request(request, request_fields), tags)) + ), + opts + ) end def update(request, opts = {}) @@ -50,10 +55,12 @@ def end(request, opts = {}) @api.end_live_activity(normalize_live_activity_request(request), opts) end - def stream(stream_key, request, opts = {}) + def stream(stream_key, request = nil, opts = {}, tags: nil, **request_fields) @api.reconcile_live_activity_stream( stream_key, - normalize_live_activity_request(normalize_channels_target(request)), + normalize_live_activity_request( + normalize_channels_target(with_tags(combine_request(request, request_fields), tags)) + ), opts ) end @@ -66,9 +73,9 @@ def end_stream(stream_key, request = nil, opts = {}) end # Backward-compatible aliases. - def start_live_activity(live_activity_start_request, opts = {}) + def start_live_activity(live_activity_start_request, opts = {}, tags: nil) @api.start_live_activity( - normalize_live_activity_request(normalize_channels_target(live_activity_start_request)), + normalize_live_activity_request(normalize_channels_target(with_tags(live_activity_start_request, tags))), opts ) end @@ -81,10 +88,10 @@ def 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 = {}) + def reconcile_live_activity_stream(stream_key, live_activity_stream_request, opts = {}, tags: nil) @api.reconcile_live_activity_stream( stream_key, - normalize_live_activity_request(normalize_channels_target(live_activity_stream_request)), + normalize_live_activity_request(normalize_channels_target(with_tags(live_activity_stream_request, tags))), opts ) end @@ -110,6 +117,21 @@ def respond_to_missing?(name, include_private = false) private + def combine_request(request, request_fields) + return request if request_fields.empty? + return request_fields if request.nil? + raise ArgumentError, "ActivitySmith: keyword request fields can only be combined with a Hash request" unless request.is_a?(Hash) + + request.merge(request_fields) + end + + def with_tags(request, tags) + return request if tags.nil? + raise ArgumentError, "ActivitySmith: tags can only be combined with a Hash request" unless request.is_a?(Hash) + + request.merge(tags: tags) + end + def normalize_live_activity_request(request) return request unless request.is_a?(Hash) diff --git a/lib/activitysmith/notifications.rb b/lib/activitysmith/notifications.rb index f875d68..411a30f 100644 --- a/lib/activitysmith/notifications.rb +++ b/lib/activitysmith/notifications.rb @@ -6,15 +6,15 @@ def initialize(api) @api = api end - def send(request, opts = {}) - normalized = normalize_channels_target(request) + def send(request = nil, opts = {}, tags: nil, **request_fields) + normalized = normalize_channels_target(with_tags(combine_request(request, request_fields), tags)) assert_valid_media_actions!(normalized) @api.send_push_notification(normalized, opts) end # Backward-compatible alias. - def send_push_notification(push_notification_request, opts = {}) - normalized = normalize_channels_target(push_notification_request) + def send_push_notification(push_notification_request, opts = {}, tags: nil) + normalized = normalize_channels_target(with_tags(push_notification_request, tags)) assert_valid_media_actions!(normalized) @api.send_push_notification(normalized, opts) end @@ -31,6 +31,21 @@ def respond_to_missing?(name, include_private = false) private + def combine_request(request, request_fields) + return request if request_fields.empty? + return request_fields if request.nil? + raise ArgumentError, "ActivitySmith: keyword request fields can only be combined with a Hash request" unless request.is_a?(Hash) + + request.merge(request_fields) + end + + def with_tags(request, tags) + return request if tags.nil? + raise ArgumentError, "ActivitySmith: tags can only be combined with a Hash request" unless request.is_a?(Hash) + + request.merge(tags: tags) + end + def normalize_channels_target(request) return request unless request.is_a?(Hash) diff --git a/lib/activitysmith/version.rb b/lib/activitysmith/version.rb index 6795883..700e5aa 100644 --- a/lib/activitysmith/version.rb +++ b/lib/activitysmith/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module ActivitySmith - VERSION = "1.9.0" + VERSION = "1.10.0" end diff --git a/test/resources_test.rb b/test/resources_test.rb index 6caf1df..31f4125 100644 --- a/test/resources_test.rb +++ b/test/resources_test.rb @@ -111,6 +111,32 @@ def test_notifications_map_channels_to_target ) end + def test_notifications_add_tags + api = FakePushApi.new + resource = ActivitySmith::Notifications.new(api) + + resource.send( + { title: "Build Failed" }, + tags: ["user:382", "environment:production"] + ) + resource.send_push_notification( + { title: "Build Failed" }, + tags: ["user:382", "environment:production"] + ) + + expected = { + title: "Build Failed", + tags: ["user:382", "environment:production"] + } + assert_equal( + [ + [:send_push_notification, expected, {}], + [:send_push_notification, expected, {}] + ], + api.calls + ) + end + def test_notifications_preserve_media_and_redirection api = FakePushApi.new resource = ActivitySmith::Notifications.new(api) @@ -292,6 +318,52 @@ def test_live_activities_start_maps_channels_to_target ) end + def test_live_activities_add_tags + api = FakeLiveApi.new + resource = ActivitySmith::LiveActivities.new(api) + payload = { + content_state: { + title: "Deploy", + number_of_steps: 4, + current_step: 1, + type: "segmented_progress" + } + } + + resource.start(payload, tags: ["user:382", "deployment"]) + resource.start_live_activity(payload, tags: ["user:382", "deployment"]) + resource.stream( + "deploy", + payload, + tags: ["user:382", "environment:production"] + ) + resource.reconcile_live_activity_stream( + "deploy", + payload, + tags: ["user:382", "environment:production"] + ) + + assert_equal( + [ + [:start_live_activity, payload.merge(tags: ["user:382", "deployment"]), {}], + [:start_live_activity, payload.merge(tags: ["user:382", "deployment"]), {}], + [ + :reconcile_live_activity_stream, + "deploy", + payload.merge(tags: ["user:382", "environment:production"]), + {} + ], + [ + :reconcile_live_activity_stream, + "deploy", + payload.merge(tags: ["user:382", "environment:production"]), + {} + ] + ], + api.calls + ) + end + def test_live_activities_support_progress_payloads api = FakeLiveApi.new resource = ActivitySmith::LiveActivities.new(api)