From f52a759dd9c67387698516ba59bfd3d55ddaf171 Mon Sep 17 00:00:00 2001 From: OneSignal Date: Wed, 3 Jun 2026 19:17:55 +0000 Subject: [PATCH] feat: add v5.6.0 package updates --- docs/DefaultApi.md | 401 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 312 insertions(+), 89 deletions(-) diff --git a/docs/DefaultApi.md b/docs/DefaultApi.md index 17c905b..35b944a 100644 --- a/docs/DefaultApi.md +++ b/docs/DefaultApi.md @@ -49,6 +49,34 @@ All URIs are relative to *https://api.onesignal.com* | [**view_template**](DefaultApi.md#view_template) | **GET** /templates/{template_id} | View template | | [**view_templates**](DefaultApi.md#view_templates) | **GET** /templates | View templates | +## Common patterns + +The per-endpoint examples below illustrate one specific call each. This section covers patterns that apply to most operations. + +### Authentication + +Every operation requires either a **REST API Key** (App-scoped, used by ~77% of endpoints) or an **Organization API Key** (used by the remaining ~23% — the app-management endpoints `get_apps` / `create_app` / `get_app` / `update_app` / `copy_template_to_app`, plus the API-key administration endpoints `view_api_keys` / `create_api_key` / `delete_api_key` / `update_api_key` / `rotate_api_key`). The two are not interchangeable. The "Authorization" row on each endpoint below lists the exact scheme. + +### Idempotency + +`POST /notifications` accepts a top-level `idempotency_key` (UUIDv4) that the server uses for request dedup within a **30-day window**. Pass a freshly-generated UUID per logical send so that network-level retries are safe. Never reuse a key across distinct sends — the server returns the original response instead of acting on the new payload. The hero `create_notification` example below demonstrates the call. + +### Error handling + +When a request fails, the SDK raises `OneSignal::ApiError`. The HTTP status code is `e.code` (Integer); the parsed error body is `e.response_body` (String — the raw JSON envelope). Response headers are available via `e.response_headers`. Most envelopes match `{ "errors": ["..."] }` (an array of strings) but a few endpoints return `{ "errors": [{"code": ..., "title": ..., "meta": {...}}] }` (an array of structured error objects — used by `POST /apps/{app_id}/users` 409 conflict, see `CreateUserConflictResponse`), `{ "errors": "..." }` (string), or `{ "success": false }` (no `errors` field at all). Robust error-handling code should tolerate all four shapes. + +### Polymorphic 200 from POST /notifications + +`CreateNotificationSuccessResponse` has two distinct shapes that share the same schema; branch on `id`: +- **Success** — `id` is a non-empty UUID. `errors`, if present, is an object keyed by recipient-identifier type (`invalid_player_ids`, `invalid_external_user_ids`, `invalid_aliases`, ...) listing recipients that were skipped (partial-success path). +- **No-send** — `id` is the empty string `""`. `errors` is a string array with the sentinel reason, typically `["All included players are not subscribed"]`. + +The hero `create_notification` example below demonstrates the branch pattern explicitly. + +### Targeting users by External ID + +Set `include_aliases.external_id` to a list of External IDs and set `target_channel` to `push` / `email` / `sms`. The alias label must be the literal string `external_id` — camelCase variants such as `externalId` are silently ignored and yield zero recipients. **Do not confuse** this with the deprecated top-level `external_id` notification field — a separate correlation/idempotency field with its own 30-day dedup keyspace (parallel to `idempotency_key`, not an alias) and no targeting effect. + ## cancel_notification @@ -70,8 +98,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -notification_id = 'notification_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +notification_id = 'b3a0c8bd-3a4c-4b22-9a73-3f1a8c2d1b88' # String | begin # Stop a scheduled or currently outgoing notification @@ -79,6 +107,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->cancel_notification: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -97,6 +127,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->cancel_notification_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -141,8 +173,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -template_id = 'template_id_example' # String | -app_id = 'app_id_example' # String | +template_id = 'e4d3c2b1-a09f-4f1e-8d7c-6b5a4f3e2d1c' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | copy_template_request = OneSignal::CopyTemplateRequest.new({target_app_id: 'target_app_id_example'}) # CopyTemplateRequest | begin @@ -151,6 +183,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->copy_template_to_app: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -169,6 +203,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->copy_template_to_app_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -214,9 +250,9 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -alias_label = 'alias_label_example' # String | -alias_id = 'alias_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +alias_label = 'external_id' # String | +alias_id = 'YOUR_USER_EXTERNAL_ID' # String | user_identity_body = OneSignal::UserIdentityBody.new # UserIdentityBody | begin @@ -225,6 +261,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_alias: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -243,6 +281,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_alias_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -289,8 +329,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -subscription_id = 'subscription_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +subscription_id = '7e4c5b9a-1f60-4d07-9b1a-2e8c8d2cae51' # String | user_identity_body = OneSignal::UserIdentityBody.new # UserIdentityBody | begin @@ -299,6 +339,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_alias_by_subscription: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -317,6 +359,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_alias_by_subscription_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -362,7 +406,7 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | create_api_key_request = OneSignal::CreateApiKeyRequest.new # CreateApiKeyRequest | begin @@ -371,6 +415,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_api_key: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -389,6 +435,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_api_key_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -441,6 +489,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_app: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -459,6 +509,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_app_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -502,7 +554,7 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | Your OneSignal App ID in UUID v4 format. +app_id = '00000000-0000-0000-0000-000000000000' # String | Your OneSignal App ID in UUID v4 format. custom_events_request = OneSignal::CustomEventsRequest.new({events: [OneSignal::CustomEvent.new({name: 'name_example'})]}) # CustomEventsRequest | begin @@ -511,6 +563,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_custom_events: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -529,6 +583,8 @@ begin p data # => Object rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_custom_events_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -573,18 +629,39 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new +require 'securerandom' + notification = OneSignal::Notification.new notification.app_id = 'YOUR_APP_ID' notification.contents = OneSignal::LanguageStringMap.new({ en: 'Hello from OneSignal!' }) notification.include_aliases = { 'external_id' => ['YOUR_USER_EXTERNAL_ID'] } notification.target_channel = 'push' +# Idempotency key: a client-generated UUID that lets you safely retry on network failure. +# If two requests arrive with the same key inside the 30-day window, only the first is sent +# and the second returns the original response. Use SecureRandom.uuid — DO NOT reuse keys +# across logically distinct sends. +notification.idempotency_key = SecureRandom.uuid begin # Create notification result = api_instance.create_notification(notification) - p result + # `result.id` discriminates the two HTTP 200 shapes. An empty string means no + # notification was created (e.g. all targets were unreachable / not subscribed). + # `result.errors` is polymorphic: an `Array` in the no-subscribers case, or + # a Hash keyed by recipient-identifier type (`invalid_player_ids`, + # `invalid_external_user_ids`, `invalid_aliases`, ...) when the notification WAS + # created but some recipients were skipped. + if result.id.to_s.empty? + puts "Notification was not sent: #{result.errors}" + elsif result.errors + puts "Notification created: #{result.id} (partial failures: #{result.errors})" + else + puts "Notification created: #{result.id}" + end rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_notification: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -603,6 +680,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_notification_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -646,7 +725,7 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | The OneSignal App ID for your app. Available in Keys & IDs. +app_id = '00000000-0000-0000-0000-000000000000' # String | The OneSignal App ID for your app. Available in Keys & IDs. opts = { segment: OneSignal::Segment.new({name: 'name_example', filters: [OneSignal::Filter.new]}) # Segment | } @@ -657,6 +736,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_segment: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -675,6 +756,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_segment_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -719,9 +802,9 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -alias_label = 'alias_label_example' # String | -alias_id = 'alias_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +alias_label = 'external_id' # String | +alias_id = 'YOUR_USER_EXTERNAL_ID' # String | subscription_body = OneSignal::SubscriptionBody.new # SubscriptionBody | begin @@ -730,6 +813,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_subscription: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -748,6 +833,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_subscription_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -802,6 +889,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_template: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -820,6 +909,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_template_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -863,7 +954,7 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | user = OneSignal::User.new # User | begin @@ -872,6 +963,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_user: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -890,6 +983,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->create_user_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -934,10 +1029,10 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -alias_label = 'alias_label_example' # String | -alias_id = 'alias_id_example' # String | -alias_label_to_delete = 'alias_label_to_delete_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +alias_label = 'external_id' # String | +alias_id = 'YOUR_USER_EXTERNAL_ID' # String | +alias_label_to_delete = 'external_id' # String | begin @@ -945,6 +1040,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->delete_alias: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -963,6 +1060,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->delete_alias_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1009,8 +1108,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -token_id = 'token_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +token_id = '0aa1b2c3-d4e5-46f7-8899-aabbccddeeff' # String | begin # Delete API key @@ -1018,6 +1117,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->delete_api_key: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1036,6 +1137,8 @@ begin p data # => Object rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->delete_api_key_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1080,8 +1183,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | The OneSignal App ID for your app. Available in Keys & IDs. -segment_id = 'segment_id_example' # String | The segment_id can be found in the URL of the segment when viewing it in the dashboard. +app_id = '00000000-0000-0000-0000-000000000000' # String | The OneSignal App ID for your app. Available in Keys & IDs. +segment_id = 'd6c5a3e1-9f17-44a1-9d10-7c0e4a2b1c8e' # String | The segment_id can be found in the URL of the segment when viewing it in the dashboard. begin # Delete Segment @@ -1089,6 +1192,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->delete_segment: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1107,6 +1212,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->delete_segment_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1151,14 +1258,16 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -subscription_id = 'subscription_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +subscription_id = '7e4c5b9a-1f60-4d07-9b1a-2e8c8d2cae51' # String | begin api_instance.delete_subscription(app_id, subscription_id) rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->delete_subscription: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1177,6 +1286,8 @@ begin p data # => nil rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->delete_subscription_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1221,8 +1332,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -template_id = 'template_id_example' # String | -app_id = 'app_id_example' # String | +template_id = 'e4d3c2b1-a09f-4f1e-8d7c-6b5a4f3e2d1c' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | begin # Delete template @@ -1230,6 +1341,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->delete_template: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1248,6 +1361,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->delete_template_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1292,15 +1407,17 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -alias_label = 'alias_label_example' # String | -alias_id = 'alias_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +alias_label = 'external_id' # String | +alias_id = 'YOUR_USER_EXTERNAL_ID' # String | begin api_instance.delete_user(app_id, alias_label, alias_id) rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->delete_user: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1319,6 +1436,8 @@ begin p data # => nil rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->delete_user_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1364,8 +1483,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -notification_id = 'notification_id_example' # String | The ID of the notification to export events from. -app_id = 'app_id_example' # String | The ID of the app that the notification belongs to. +notification_id = 'b3a0c8bd-3a4c-4b22-9a73-3f1a8c2d1b88' # String | The ID of the notification to export events from. +app_id = '00000000-0000-0000-0000-000000000000' # String | The ID of the app that the notification belongs to. begin # Export CSV of Events @@ -1373,6 +1492,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->export_events: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1391,6 +1512,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->export_events_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1435,7 +1558,7 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | The app ID that you want to export devices from +app_id = '00000000-0000-0000-0000-000000000000' # String | The app ID that you want to export devices from opts = { export_subscriptions_request_body: OneSignal::ExportSubscriptionsRequestBody.new # ExportSubscriptionsRequestBody | } @@ -1446,6 +1569,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->export_subscriptions: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1464,6 +1589,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->export_subscriptions_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1508,9 +1635,9 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -alias_label = 'alias_label_example' # String | -alias_id = 'alias_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +alias_label = 'external_id' # String | +alias_id = 'YOUR_USER_EXTERNAL_ID' # String | begin @@ -1518,6 +1645,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_aliases: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1536,6 +1665,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_aliases_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1581,8 +1712,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -subscription_id = 'subscription_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +subscription_id = '7e4c5b9a-1f60-4d07-9b1a-2e8c8d2cae51' # String | begin @@ -1590,6 +1721,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_aliases_by_subscription: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1608,6 +1741,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_aliases_by_subscription_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1652,7 +1787,7 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | An app id +app_id = '00000000-0000-0000-0000-000000000000' # String | An app id begin # View an app @@ -1660,6 +1795,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_app: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1678,6 +1815,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_app_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1728,6 +1867,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_apps: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1746,6 +1887,8 @@ begin p data # => > rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_apps_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1787,8 +1930,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -notification_id = 'notification_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +notification_id = 'b3a0c8bd-3a4c-4b22-9a73-3f1a8c2d1b88' # String | begin # View notification @@ -1796,6 +1939,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_notification: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1814,6 +1959,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_notification_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1858,7 +2005,7 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -notification_id = 'notification_id_example' # String | The \"id\" of the message found in the Notification object +notification_id = 'b3a0c8bd-3a4c-4b22-9a73-3f1a8c2d1b88' # String | The \"id\" of the message found in the Notification object get_notification_history_request_body = OneSignal::GetNotificationHistoryRequestBody.new # GetNotificationHistoryRequestBody | begin @@ -1867,6 +2014,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_notification_history: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1885,6 +2034,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_notification_history_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1929,10 +2080,10 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | The app ID that you want to view notifications from +app_id = '00000000-0000-0000-0000-000000000000' # String | The app ID that you want to view notifications from opts = { - limit: 56, # Integer | How many notifications to return. Max is 50. Default is 50. - offset: 56, # Integer | Page offset. Default is 0. Results are sorted by queued_at in descending order. queued_at is a representation of the time that the notification was queued at. + limit: 10, # Integer | How many notifications to return. Max is 50. Default is 50. + offset: 0, # Integer | Page offset. Default is 0. Results are sorted by queued_at in descending order. queued_at is a representation of the time that the notification was queued at. kind: 0 # Integer | Kind of notifications returned: * unset - All notification types (default) * `0` - Dashboard only * `1` - API only * `3` - Automated only } @@ -1942,6 +2093,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_notifications: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -1960,6 +2113,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_notifications_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2006,13 +2161,13 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | The OneSignal App ID for your app. Available in Keys & IDs. -outcome_names = 'outcome_names_example' # String | Required Comma-separated list of names and the value (sum/count) for the returned outcome data. Note: Clicks only support count aggregation. For out-of-the-box OneSignal outcomes such as click and session duration, please use the \"os\" prefix with two underscores. For other outcomes, please use the name specified by the user. Example:os__session_duration.count,os__click.count,CustomOutcomeName.sum +app_id = '00000000-0000-0000-0000-000000000000' # String | The OneSignal App ID for your app. Available in Keys & IDs. +outcome_names = 'os__session_duration.count,os__click.count' # String | Required Comma-separated list of names and the value (sum/count) for the returned outcome data. Note: Clicks only support count aggregation. For out-of-the-box OneSignal outcomes such as click and session duration, please use the \"os\" prefix with two underscores. For other outcomes, please use the name specified by the user. Example:os__session_duration.count,os__click.count,CustomOutcomeName.sum opts = { - outcome_names2: 'outcome_names_example', # String | Optional If outcome names contain any commas, then please specify only one value at a time. Example: outcome_names[]=os__click.count&outcome_names[]=Sales, Purchase.count where \"Sales, Purchase\" is the custom outcomes with a comma in the name. - outcome_time_range: 'outcome_time_range_example', # String | Optional Time range for the returned data. The values can be 1h (for the last 1 hour data), 1d (for the last 1 day data), or 1mo (for the last 1 month data). Default is 1h if the parameter is omitted. - outcome_platforms: 'outcome_platforms_example', # String | Optional Platform id. Refer device's platform ids for values. Example: outcome_platform=0 for iOS outcome_platform=7,8 for Safari and Firefox Default is data from all platforms if the parameter is omitted. - outcome_attribution: 'outcome_attribution_example' # String | Optional Attribution type for the outcomes. The values can be direct or influenced or unattributed. Example: outcome_attribution=direct Default is total (returns direct+influenced+unattributed) if the parameter is omitted. + outcome_names2: 'os__session_duration.count', # String | Optional If outcome names contain any commas, then please specify only one value at a time. Example: outcome_names[]=os__click.count&outcome_names[]=Sales, Purchase.count where \"Sales, Purchase\" is the custom outcomes with a comma in the name. + outcome_time_range: '1d', # String | Optional Time range for the returned data. The values can be 1h (for the last 1 hour data), 1d (for the last 1 day data), or 1mo (for the last 1 month data). Default is 1h if the parameter is omitted. + outcome_platforms: '0,1', # String | Optional Platform id. Refer device's platform ids for values. Example: outcome_platform=0 for iOS outcome_platform=7,8 for Safari and Firefox Default is data from all platforms if the parameter is omitted. + outcome_attribution: 'direct' # String | Optional Attribution type for the outcomes. The values can be direct or influenced or unattributed. Example: outcome_attribution=direct Default is total (returns direct+influenced+unattributed) if the parameter is omitted. } begin @@ -2021,6 +2176,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_outcomes: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2039,6 +2196,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_outcomes_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2087,10 +2246,10 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | The OneSignal App ID for your app. Available in Keys & IDs. +app_id = '00000000-0000-0000-0000-000000000000' # String | The OneSignal App ID for your app. Available in Keys & IDs. opts = { - offset: 56, # Integer | Segments are listed in ascending order of created_at date. offset will omit that number of segments from the beginning of the list. Eg offset 5, will remove the 5 earliest created Segments. - limit: 56 # Integer | The amount of Segments in the response. Maximum 300. + offset: 0, # Integer | Segments are listed in ascending order of created_at date. offset will omit that number of segments from the beginning of the list. Eg offset 5, will remove the 5 earliest created Segments. + limit: 10 # Integer | The amount of Segments in the response. Maximum 300. } begin @@ -2099,6 +2258,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_segments: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2117,6 +2278,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_segments_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2162,9 +2325,9 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -alias_label = 'alias_label_example' # String | -alias_id = 'alias_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +alias_label = 'external_id' # String | +alias_id = 'YOUR_USER_EXTERNAL_ID' # String | begin @@ -2172,6 +2335,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_user: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2190,6 +2355,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->get_user_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2235,8 +2402,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -token_id = 'token_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +token_id = '0aa1b2c3-d4e5-46f7-8899-aabbccddeeff' # String | begin # Rotate API key @@ -2244,6 +2411,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->rotate_api_key: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2262,6 +2431,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->rotate_api_key_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2306,8 +2477,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | Your OneSignal App ID in UUID v4 format. -activity_type = 'activity_type_example' # String | The name of the Live Activity defined in your app. This should match the attributes struct used in your app's Live Activity implementation. +app_id = '00000000-0000-0000-0000-000000000000' # String | Your OneSignal App ID in UUID v4 format. +activity_type = 'order_status' # String | The name of the Live Activity defined in your app. This should match the attributes struct used in your app's Live Activity implementation. start_live_activity_request = OneSignal::StartLiveActivityRequest.new({name: 'name_example', event: 'start', activity_id: 'activity_id_example', event_attributes: 3.56, event_updates: 3.56, contents: OneSignal::LanguageStringMap.new, headings: OneSignal::LanguageStringMap.new}) # StartLiveActivityRequest | begin @@ -2316,6 +2487,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->start_live_activity: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2334,6 +2507,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->start_live_activity_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2379,8 +2554,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -subscription_id = 'subscription_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +subscription_id = '7e4c5b9a-1f60-4d07-9b1a-2e8c8d2cae51' # String | transfer_subscription_request_body = OneSignal::TransferSubscriptionRequestBody.new # TransferSubscriptionRequestBody | begin @@ -2389,6 +2564,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->transfer_subscription: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2407,6 +2584,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->transfer_subscription_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2452,9 +2631,9 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | The OneSignal App ID for your app. Available in Keys & IDs. -notification_id = 'notification_id_example' # String | The id of the message found in the creation notification POST response, View Notifications GET response, or URL within the Message Report. -token = 'token_example' # String | The unsubscribe token that is generated via liquid syntax in {{subscription.unsubscribe_token}} when personalizing an email. +app_id = '00000000-0000-0000-0000-000000000000' # String | The OneSignal App ID for your app. Available in Keys & IDs. +notification_id = 'b3a0c8bd-3a4c-4b22-9a73-3f1a8c2d1b88' # String | The id of the message found in the creation notification POST response, View Notifications GET response, or URL within the Message Report. +token = 'YOUR_TOKEN_ID' # String | The unsubscribe token that is generated via liquid syntax in {{subscription.unsubscribe_token}} when personalizing an email. begin # Unsubscribe with token @@ -2462,6 +2641,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->unsubscribe_email_with_token: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2480,6 +2661,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->unsubscribe_email_with_token_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2525,8 +2708,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -token_id = 'token_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +token_id = '0aa1b2c3-d4e5-46f7-8899-aabbccddeeff' # String | update_api_key_request = OneSignal::UpdateApiKeyRequest.new # UpdateApiKeyRequest | begin @@ -2535,6 +2718,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->update_api_key: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2553,6 +2738,8 @@ begin p data # => Object rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->update_api_key_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2598,7 +2785,7 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | An app id +app_id = '00000000-0000-0000-0000-000000000000' # String | An app id app = OneSignal::App.new # App | begin @@ -2607,6 +2794,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->update_app: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2625,6 +2814,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->update_app_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2669,8 +2860,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | The OneSignal App ID for your app. Available in Keys & IDs. -activity_id = 'activity_id_example' # String | Live Activity record ID +app_id = '00000000-0000-0000-0000-000000000000' # String | The OneSignal App ID for your app. Available in Keys & IDs. +activity_id = '12345' # String | Live Activity record ID update_live_activity_request = OneSignal::UpdateLiveActivityRequest.new({name: 'name_example', event: 'update', event_updates: 3.56}) # UpdateLiveActivityRequest | begin @@ -2679,6 +2870,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->update_live_activity: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2697,6 +2890,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->update_live_activity_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2742,8 +2937,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -subscription_id = 'subscription_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +subscription_id = '7e4c5b9a-1f60-4d07-9b1a-2e8c8d2cae51' # String | subscription_body = OneSignal::SubscriptionBody.new # SubscriptionBody | begin @@ -2751,6 +2946,8 @@ begin api_instance.update_subscription(app_id, subscription_id, subscription_body) rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->update_subscription: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2769,6 +2966,8 @@ begin p data # => nil rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->update_subscription_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2814,9 +3013,9 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | Your OneSignal App ID in UUID v4 format. -token_type = 'token_type_example' # String | The type of token to use when looking up the subscription. See Subscription Types. -token = 'token_example' # String | The value of the token to lookup by (e.g., email address, phone number). +app_id = '00000000-0000-0000-0000-000000000000' # String | Your OneSignal App ID in UUID v4 format. +token_type = 'Email' # String | The type of token to use when looking up the subscription. See Subscription Types. +token = 'user@example.com' # String | The value of the token to lookup by (e.g., email address, phone number). subscription_body = OneSignal::SubscriptionBody.new # SubscriptionBody | begin @@ -2825,6 +3024,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->update_subscription_by_token: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2843,6 +3044,8 @@ begin p data # => Object rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->update_subscription_by_token_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2889,8 +3092,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -template_id = 'template_id_example' # String | -app_id = 'app_id_example' # String | +template_id = 'e4d3c2b1-a09f-4f1e-8d7c-6b5a4f3e2d1c' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | update_template_request = OneSignal::UpdateTemplateRequest.new # UpdateTemplateRequest | begin @@ -2899,6 +3102,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->update_template: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2917,6 +3122,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->update_template_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2962,9 +3169,9 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | -alias_label = 'alias_label_example' # String | -alias_id = 'alias_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | +alias_label = 'external_id' # String | +alias_id = 'YOUR_USER_EXTERNAL_ID' # String | update_user_request = OneSignal::UpdateUserRequest.new # UpdateUserRequest | begin @@ -2973,6 +3180,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->update_user: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -2991,6 +3200,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->update_user_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -3037,7 +3248,7 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | begin # View API keys @@ -3045,6 +3256,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->view_api_keys: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -3063,6 +3276,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->view_api_keys_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -3106,8 +3321,8 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -template_id = 'template_id_example' # String | -app_id = 'app_id_example' # String | +template_id = 'e4d3c2b1-a09f-4f1e-8d7c-6b5a4f3e2d1c' # String | +app_id = '00000000-0000-0000-0000-000000000000' # String | begin # View template @@ -3115,6 +3330,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->view_template: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -3133,6 +3350,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->view_template_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -3177,10 +3396,10 @@ OneSignal.configure do |config| end api_instance = OneSignal::DefaultApi.new -app_id = 'app_id_example' # String | Your OneSignal App ID in UUID v4 format. +app_id = '00000000-0000-0000-0000-000000000000' # String | Your OneSignal App ID in UUID v4 format. opts = { - limit: 56, # Integer | Maximum number of templates. Default and max is 50. - offset: 56, # Integer | Pagination offset. + limit: 10, # Integer | Maximum number of templates. Default and max is 50. + offset: 0, # Integer | Pagination offset. channel: 'push' # String | Filter by delivery channel. } @@ -3190,6 +3409,8 @@ begin p result rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->view_templates: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ``` @@ -3208,6 +3429,8 @@ begin p data # => rescue OneSignal::ApiError => e puts "Error when calling DefaultApi->view_templates_with_http_info: #{e}" + puts "Status Code: #{e.code}" + puts "Response Body: #{e.response_body}" end ```