repull 0.2.24 → 0.2.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/lib/repull/api/connect_api.rb +617 -0
  3. data/lib/repull/api/connections_api.rb +312 -0
  4. data/lib/repull/api/conversations_api.rb +151 -18
  5. data/lib/repull/api/health_api.rb +5 -5
  6. data/lib/repull/api/listings_api.rb +67 -4
  7. data/lib/repull/api/reviews_api.rb +2 -2
  8. data/lib/repull/models/apply_connection_mappings200_response.rb +167 -0
  9. data/lib/repull/models/apply_connection_mappings200_response_results_inner.rb +184 -0
  10. data/lib/repull/models/apply_connection_mappings_request.rb +175 -0
  11. data/lib/repull/models/apply_connection_mappings_request_mappings_inner.rb +193 -0
  12. data/lib/repull/models/auto_map_connection_units200_response.rb +176 -0
  13. data/lib/repull/models/auto_map_connection_units_request.rb +156 -0
  14. data/lib/repull/models/channel_market_state_item.rb +15 -4
  15. data/lib/repull/models/connect_status.rb +25 -5
  16. data/lib/repull/models/connect_status_accounts_inner.rb +71 -4
  17. data/lib/repull/models/conversation_capabilities.rb +260 -0
  18. data/lib/repull/models/conversation_detail.rb +14 -5
  19. data/lib/repull/models/create_connect_session_request.rb +23 -1
  20. data/lib/repull/models/create_conversation_special_offer201_response.rb +127 -4
  21. data/lib/repull/models/create_conversation_special_offer201_response_fees_inner.rb +166 -0
  22. data/lib/repull/models/create_conversation_special_offer201_response_lines_inner.rb +157 -0
  23. data/lib/repull/models/create_conversation_special_offer_request.rb +91 -52
  24. data/lib/repull/models/create_conversation_special_offer_request_fees_inner.rb +199 -0
  25. data/lib/repull/models/get_booking_extranet_login_config200_response.rb +147 -0
  26. data/lib/repull/models/get_booking_extranet_login_status200_response.rb +192 -0
  27. data/lib/repull/models/get_channel_health200_response.rb +190 -0
  28. data/lib/repull/models/get_channel_health200_response_vrbo.rb +197 -0
  29. data/lib/repull/models/get_connect_write_policy200_response.rb +166 -0
  30. data/lib/repull/models/get_listing_calendar_sync200_response.rb +192 -0
  31. data/lib/repull/models/get_listing_calendar_sync200_response_channels_inner.rb +331 -0
  32. data/lib/repull/models/get_listing_calendar_sync200_response_channels_inner_problems_inner.rb +157 -0
  33. data/lib/repull/models/get_listing_calendar_sync200_response_channels_inner_queue.rb +212 -0
  34. data/lib/repull/models/get_listing_calendar_sync200_response_channels_inner_queue_last_push.rb +268 -0
  35. data/lib/repull/models/invite_booking_extranet_user200_response.rb +174 -0
  36. data/lib/repull/models/invite_booking_extranet_user_request.rb +173 -0
  37. data/lib/repull/models/list_connection_units200_response.rb +242 -0
  38. data/lib/repull/models/list_connection_units200_response_listing_options_inner.rb +165 -0
  39. data/lib/repull/models/list_connection_units200_response_units_inner.rb +194 -0
  40. data/lib/repull/models/listing_publish_status_connection.rb +34 -1
  41. data/lib/repull/models/pms_write_policy.rb +191 -0
  42. data/lib/repull/models/pms_write_policy_calendar.rb +219 -0
  43. data/lib/repull/models/pms_write_policy_reservations.rb +219 -0
  44. data/lib/repull/models/preapprove_conversation201_response.rb +47 -6
  45. data/lib/repull/models/preapprove_conversation_request.rb +34 -5
  46. data/lib/repull/models/preview_conversation_special_offer_request.rb +231 -0
  47. data/lib/repull/models/preview_conversation_special_offer_request_fees_inner.rb +199 -0
  48. data/lib/repull/models/preview_conversation_special_offer_request_guests.rb +250 -0
  49. data/lib/repull/models/reply_to_review_request.rb +33 -4
  50. data/lib/repull/models/search_connect_session_listing_options200_response.rb +158 -0
  51. data/lib/repull/models/search_connect_session_listing_options200_response_data_inner.rb +166 -0
  52. data/lib/repull/models/search_connection_listing_options200_response.rb +159 -0
  53. data/lib/repull/models/send_message_request.rb +1 -1
  54. data/lib/repull/models/start_booking_extranet_login200_response.rb +174 -0
  55. data/lib/repull/models/start_booking_extranet_login_request.rb +225 -0
  56. data/lib/repull/models/submit_cloudbeds_credentials200_response.rb +10 -1
  57. data/lib/repull/models/submit_cloudbeds_credentials_request.rb +11 -1
  58. data/lib/repull/models/submit_mews_credentials200_response.rb +10 -1
  59. data/lib/repull/models/submit_mews_credentials_request.rb +11 -1
  60. data/lib/repull/models/update_connect_write_policy_request.rb +157 -0
  61. data/lib/repull/models/update_connect_write_policy_request_calendar.rb +165 -0
  62. data/lib/repull/models/update_connect_write_policy_request_reservations.rb +165 -0
  63. data/lib/repull/models/vrbo_import_status.rb +249 -0
  64. data/lib/repull/models/vrbo_login200_response.rb +235 -0
  65. data/lib/repull/models/vrbo_login_request.rb +271 -0
  66. data/lib/repull/models/withdraw_conversation_preapproval200_response.rb +226 -0
  67. data/lib/repull/models/withdraw_conversation_special_offer200_response.rb +29 -1
  68. data/lib/repull/version.rb +1 -1
  69. data/lib/repull.rb +44 -0
  70. data/openapi/v1.json +4693 -2114
  71. data/scripts/regen.sh +1 -1
  72. metadata +46 -2
@@ -0,0 +1,166 @@
1
+ =begin
2
+ #Repull API
3
+
4
+ #The unified API for vacation rental tech. Connect to 50+ PMS platforms and 4 OTA channels through one REST API. Built-in AI operations for guest communication, pricing, and listing optimization. ## Designed for AI agents Every error response on this API includes machine-parseable fields so an LLM (Claude in MCP, Cursor, Cline, GPT, etc.) can self-recover without escalating to a human: - `error.code` — stable string identifier (e.g. `invalid_params`, `rate_limit_exceeded`) - `error.message` — human-readable cause - `error.fix` — exact recovery steps (e.g. \"Pass `check_in_after` as ISO 8601: `?check_in_after=2026-01-15`\") - `error.docs_url` — link to the canonical write-up at `https://repull.dev/docs/errors/{code}` - `error.request_id` — id to correlate with server-side logs - `error.field` / `error.value_received` / `error.valid_values` / `error.did_you_mean` — when the error is parameter-specific - `error.retry_after` — seconds to wait before retrying (rate-limit + transient upstream) `Access-Control-Expose-Headers` lists `x-request-id` and the `X-RateLimit-*` family so browsers can read them on cross-origin responses. ## Quick Start 1. Get an API key at https://repull.dev/dashboard 2. Connect a PMS: `POST /v1/connect/{provider}` 3. List properties: `GET /v1/properties` 4. Get reservations: `GET /v1/reservations` ## Authentication All requests require a Bearer token: ``` Authorization: Bearer sk_live_YOUR_API_KEY ``` ## Request Correlation (X-Request-ID) Every response carries an `X-Request-ID` header, e.g. `X-Request-ID: req_01HXY...`. Include this id in support tickets and bug reports — we can trace the full request lifecycle (auth, rate limit, handler, downstream calls, log row) from a single id. You may set the header on the inbound request to forward your own trace id; we will echo it back instead of generating a new one. Accepted format: `^[\\\\w.-]{1,128}$`. The id is also embedded in error envelopes as `request_id` so server-side log diffs work even when the response headers are stripped by an intermediate proxy. ## Rate Limits The public API enforces a per-API-key sliding-window rate limit on top of the per-tier monthly + daily-AI quotas. **Default policy:** 600 requests per 60 seconds, per API key. Sliding window — there is no fixed-minute boundary you can burst across. Every response includes: | Header | Meaning | |---|---| | `X-RateLimit-Limit` | Requests permitted in the current window. | | `X-RateLimit-Remaining` | Requests left in the current window after this call. | | `X-RateLimit-Reset` | Unix epoch (seconds) when the next slot opens. | | `X-RateLimit-Policy` | Machine-readable policy descriptor, e.g. `600;w=60`. | | `Retry-After` | Seconds to wait before retrying. **Only present on 429 responses.** | **On 429 (rate_limit_exceeded):** the response body matches the standard error envelope with `code: \"rate_limit_exceeded\"`, plus `limit`, `window_seconds`, `retry_after`, and `request_id` fields. SDKs MUST honor `Retry-After` and use exponential backoff with jitter on subsequent retries — never a tight loop. Recommended backoff: ``` sleep_ms = (Retry-After * 1000) + random(0..250) ``` Monthly + daily-AI tier quotas (`free`, `starter`, `custom`) are enforced separately and also surface as 429s; they include `tier`, `scope`, and `resetsAt` fields. ## Plan Limits (402 — `listings_limit_exceeded`) The Repull API also enforces a per-tier cap on **active listings**: | Tier | Active listings cap | |---|---| | `free` | 3 | | `starter` | 50 | | `custom` | unlimited | When a customer's active-listing count is above their tier cap, the API returns **`402 Payment Required`** with `error.code = \"listings_limit_exceeded\"` on every route EXCEPT: - `/v1/health` — uptime probes are never gated. - `/v1/usage/*` — so dashboards can render the over-cap state. - Any `DELETE` — so the customer can trim listings to get back under the cap without paying. Unlike 429, 402 is NOT a \"wait and retry\" condition — `Retry-After` is not set. The only paths back to 200 are: 1. `DELETE` enough listings to come back under the cap, or 2. Upgrade at `https://repull.dev/dashboard/billing`. The server-side usage cache is 60s, so the first 200 after an upgrade may take up to a minute. The envelope mirrors `rate_limit_exceeded` for SDK ergonomics: `tier`, `limit`, `active_listings`, `upgrade_url`, plus the standard `code` / `message` / `fix` / `docs_url` / `request_id`.
5
+
6
+ The version of the OpenAPI document: 1.0.0
7
+
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.22.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module Repull
17
+ class CreateConversationSpecialOffer201ResponseFeesInner < ApiModelBase
18
+ attr_accessor :type
19
+
20
+ attr_accessor :value
21
+
22
+ attr_accessor :label
23
+
24
+ # Attribute mapping from ruby-style variable name to JSON key.
25
+ def self.attribute_map
26
+ {
27
+ :'type' => :'type',
28
+ :'value' => :'value',
29
+ :'label' => :'label'
30
+ }
31
+ end
32
+
33
+ # Returns attribute mapping this model knows about
34
+ def self.acceptable_attribute_map
35
+ attribute_map
36
+ end
37
+
38
+ # Returns all the JSON keys this model knows about
39
+ def self.acceptable_attributes
40
+ acceptable_attribute_map.values
41
+ end
42
+
43
+ # Attribute type mapping.
44
+ def self.openapi_types
45
+ {
46
+ :'type' => :'String',
47
+ :'value' => :'Float',
48
+ :'label' => :'String'
49
+ }
50
+ end
51
+
52
+ # List of attributes with nullable: true
53
+ def self.openapi_nullable
54
+ Set.new([
55
+ :'label'
56
+ ])
57
+ end
58
+
59
+ # Initializes the object
60
+ # @param [Hash] attributes Model attributes in the form of hash
61
+ def initialize(attributes = {})
62
+ if (!attributes.is_a?(Hash))
63
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Repull::CreateConversationSpecialOffer201ResponseFeesInner` initialize method"
64
+ end
65
+
66
+ # check to see if the attribute exists and convert string to symbol for hash key
67
+ acceptable_attribute_map = self.class.acceptable_attribute_map
68
+ attributes = attributes.each_with_object({}) { |(k, v), h|
69
+ if (!acceptable_attribute_map.key?(k.to_sym))
70
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Repull::CreateConversationSpecialOffer201ResponseFeesInner`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
71
+ end
72
+ h[k.to_sym] = v
73
+ }
74
+
75
+ if attributes.key?(:'type')
76
+ self.type = attributes[:'type']
77
+ end
78
+
79
+ if attributes.key?(:'value')
80
+ self.value = attributes[:'value']
81
+ end
82
+
83
+ if attributes.key?(:'label')
84
+ self.label = attributes[:'label']
85
+ end
86
+ end
87
+
88
+ # Show invalid properties with the reasons. Usually used together with valid?
89
+ # @return Array for valid properties with the reasons
90
+ def list_invalid_properties
91
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
92
+ invalid_properties = Array.new
93
+ invalid_properties
94
+ end
95
+
96
+ # Check to see if the all the properties in the model are valid
97
+ # @return true if the model is valid
98
+ def valid?
99
+ warn '[DEPRECATED] the `valid?` method is obsolete'
100
+ true
101
+ end
102
+
103
+ # Checks equality by comparing each attribute.
104
+ # @param [Object] Object to be compared
105
+ def ==(o)
106
+ return true if self.equal?(o)
107
+ self.class == o.class &&
108
+ type == o.type &&
109
+ value == o.value &&
110
+ label == o.label
111
+ end
112
+
113
+ # @see the `==` method
114
+ # @param [Object] Object to be compared
115
+ def eql?(o)
116
+ self == o
117
+ end
118
+
119
+ # Calculates hash code according to all attributes.
120
+ # @return [Integer] Hash code
121
+ def hash
122
+ [type, value, label].hash
123
+ end
124
+
125
+ # Builds the object from hash
126
+ # @param [Hash] attributes Model attributes in the form of hash
127
+ # @return [Object] Returns the model itself
128
+ def self.build_from_hash(attributes)
129
+ return nil unless attributes.is_a?(Hash)
130
+ attributes = attributes.transform_keys(&:to_sym)
131
+ transformed_hash = {}
132
+ openapi_types.each_pair do |key, type|
133
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
134
+ transformed_hash["#{key}"] = nil
135
+ elsif type =~ /\AArray<(.*)>/i
136
+ # check to ensure the input is an array given that the attribute
137
+ # is documented as an array but the input is not
138
+ if attributes[attribute_map[key]].is_a?(Array)
139
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
140
+ end
141
+ elsif !attributes[attribute_map[key]].nil?
142
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
143
+ end
144
+ end
145
+ new(transformed_hash)
146
+ end
147
+
148
+ # Returns the object in the form of hash
149
+ # @return [Hash] Returns the object in the form of hash
150
+ def to_hash
151
+ hash = {}
152
+ self.class.attribute_map.each_pair do |attr, param|
153
+ value = self.send(attr)
154
+ if value.nil?
155
+ is_nullable = self.class.openapi_nullable.include?(attr)
156
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
157
+ end
158
+
159
+ hash[param] = _to_hash(value)
160
+ end
161
+ hash
162
+ end
163
+
164
+ end
165
+
166
+ end
@@ -0,0 +1,157 @@
1
+ =begin
2
+ #Repull API
3
+
4
+ #The unified API for vacation rental tech. Connect to 50+ PMS platforms and 4 OTA channels through one REST API. Built-in AI operations for guest communication, pricing, and listing optimization. ## Designed for AI agents Every error response on this API includes machine-parseable fields so an LLM (Claude in MCP, Cursor, Cline, GPT, etc.) can self-recover without escalating to a human: - `error.code` — stable string identifier (e.g. `invalid_params`, `rate_limit_exceeded`) - `error.message` — human-readable cause - `error.fix` — exact recovery steps (e.g. \"Pass `check_in_after` as ISO 8601: `?check_in_after=2026-01-15`\") - `error.docs_url` — link to the canonical write-up at `https://repull.dev/docs/errors/{code}` - `error.request_id` — id to correlate with server-side logs - `error.field` / `error.value_received` / `error.valid_values` / `error.did_you_mean` — when the error is parameter-specific - `error.retry_after` — seconds to wait before retrying (rate-limit + transient upstream) `Access-Control-Expose-Headers` lists `x-request-id` and the `X-RateLimit-*` family so browsers can read them on cross-origin responses. ## Quick Start 1. Get an API key at https://repull.dev/dashboard 2. Connect a PMS: `POST /v1/connect/{provider}` 3. List properties: `GET /v1/properties` 4. Get reservations: `GET /v1/reservations` ## Authentication All requests require a Bearer token: ``` Authorization: Bearer sk_live_YOUR_API_KEY ``` ## Request Correlation (X-Request-ID) Every response carries an `X-Request-ID` header, e.g. `X-Request-ID: req_01HXY...`. Include this id in support tickets and bug reports — we can trace the full request lifecycle (auth, rate limit, handler, downstream calls, log row) from a single id. You may set the header on the inbound request to forward your own trace id; we will echo it back instead of generating a new one. Accepted format: `^[\\\\w.-]{1,128}$`. The id is also embedded in error envelopes as `request_id` so server-side log diffs work even when the response headers are stripped by an intermediate proxy. ## Rate Limits The public API enforces a per-API-key sliding-window rate limit on top of the per-tier monthly + daily-AI quotas. **Default policy:** 600 requests per 60 seconds, per API key. Sliding window — there is no fixed-minute boundary you can burst across. Every response includes: | Header | Meaning | |---|---| | `X-RateLimit-Limit` | Requests permitted in the current window. | | `X-RateLimit-Remaining` | Requests left in the current window after this call. | | `X-RateLimit-Reset` | Unix epoch (seconds) when the next slot opens. | | `X-RateLimit-Policy` | Machine-readable policy descriptor, e.g. `600;w=60`. | | `Retry-After` | Seconds to wait before retrying. **Only present on 429 responses.** | **On 429 (rate_limit_exceeded):** the response body matches the standard error envelope with `code: \"rate_limit_exceeded\"`, plus `limit`, `window_seconds`, `retry_after`, and `request_id` fields. SDKs MUST honor `Retry-After` and use exponential backoff with jitter on subsequent retries — never a tight loop. Recommended backoff: ``` sleep_ms = (Retry-After * 1000) + random(0..250) ``` Monthly + daily-AI tier quotas (`free`, `starter`, `custom`) are enforced separately and also surface as 429s; they include `tier`, `scope`, and `resetsAt` fields. ## Plan Limits (402 — `listings_limit_exceeded`) The Repull API also enforces a per-tier cap on **active listings**: | Tier | Active listings cap | |---|---| | `free` | 3 | | `starter` | 50 | | `custom` | unlimited | When a customer's active-listing count is above their tier cap, the API returns **`402 Payment Required`** with `error.code = \"listings_limit_exceeded\"` on every route EXCEPT: - `/v1/health` — uptime probes are never gated. - `/v1/usage/*` — so dashboards can render the over-cap state. - Any `DELETE` — so the customer can trim listings to get back under the cap without paying. Unlike 429, 402 is NOT a \"wait and retry\" condition — `Retry-After` is not set. The only paths back to 200 are: 1. `DELETE` enough listings to come back under the cap, or 2. Upgrade at `https://repull.dev/dashboard/billing`. The server-side usage cache is 60s, so the first 200 after an upgrade may take up to a minute. The envelope mirrors `rate_limit_exceeded` for SDK ergonomics: `tier`, `limit`, `active_listings`, `upgrade_url`, plus the standard `code` / `message` / `fix` / `docs_url` / `request_id`.
5
+
6
+ The version of the OpenAPI document: 1.0.0
7
+
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.22.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module Repull
17
+ class CreateConversationSpecialOffer201ResponseLinesInner < ApiModelBase
18
+ attr_accessor :label
19
+
20
+ attr_accessor :value
21
+
22
+ # Attribute mapping from ruby-style variable name to JSON key.
23
+ def self.attribute_map
24
+ {
25
+ :'label' => :'label',
26
+ :'value' => :'value'
27
+ }
28
+ end
29
+
30
+ # Returns attribute mapping this model knows about
31
+ def self.acceptable_attribute_map
32
+ attribute_map
33
+ end
34
+
35
+ # Returns all the JSON keys this model knows about
36
+ def self.acceptable_attributes
37
+ acceptable_attribute_map.values
38
+ end
39
+
40
+ # Attribute type mapping.
41
+ def self.openapi_types
42
+ {
43
+ :'label' => :'String',
44
+ :'value' => :'String'
45
+ }
46
+ end
47
+
48
+ # List of attributes with nullable: true
49
+ def self.openapi_nullable
50
+ Set.new([
51
+ :'value'
52
+ ])
53
+ end
54
+
55
+ # Initializes the object
56
+ # @param [Hash] attributes Model attributes in the form of hash
57
+ def initialize(attributes = {})
58
+ if (!attributes.is_a?(Hash))
59
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Repull::CreateConversationSpecialOffer201ResponseLinesInner` initialize method"
60
+ end
61
+
62
+ # check to see if the attribute exists and convert string to symbol for hash key
63
+ acceptable_attribute_map = self.class.acceptable_attribute_map
64
+ attributes = attributes.each_with_object({}) { |(k, v), h|
65
+ if (!acceptable_attribute_map.key?(k.to_sym))
66
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Repull::CreateConversationSpecialOffer201ResponseLinesInner`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
67
+ end
68
+ h[k.to_sym] = v
69
+ }
70
+
71
+ if attributes.key?(:'label')
72
+ self.label = attributes[:'label']
73
+ end
74
+
75
+ if attributes.key?(:'value')
76
+ self.value = attributes[:'value']
77
+ end
78
+ end
79
+
80
+ # Show invalid properties with the reasons. Usually used together with valid?
81
+ # @return Array for valid properties with the reasons
82
+ def list_invalid_properties
83
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
84
+ invalid_properties = Array.new
85
+ invalid_properties
86
+ end
87
+
88
+ # Check to see if the all the properties in the model are valid
89
+ # @return true if the model is valid
90
+ def valid?
91
+ warn '[DEPRECATED] the `valid?` method is obsolete'
92
+ true
93
+ end
94
+
95
+ # Checks equality by comparing each attribute.
96
+ # @param [Object] Object to be compared
97
+ def ==(o)
98
+ return true if self.equal?(o)
99
+ self.class == o.class &&
100
+ label == o.label &&
101
+ value == o.value
102
+ end
103
+
104
+ # @see the `==` method
105
+ # @param [Object] Object to be compared
106
+ def eql?(o)
107
+ self == o
108
+ end
109
+
110
+ # Calculates hash code according to all attributes.
111
+ # @return [Integer] Hash code
112
+ def hash
113
+ [label, value].hash
114
+ end
115
+
116
+ # Builds the object from hash
117
+ # @param [Hash] attributes Model attributes in the form of hash
118
+ # @return [Object] Returns the model itself
119
+ def self.build_from_hash(attributes)
120
+ return nil unless attributes.is_a?(Hash)
121
+ attributes = attributes.transform_keys(&:to_sym)
122
+ transformed_hash = {}
123
+ openapi_types.each_pair do |key, type|
124
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
125
+ transformed_hash["#{key}"] = nil
126
+ elsif type =~ /\AArray<(.*)>/i
127
+ # check to ensure the input is an array given that the attribute
128
+ # is documented as an array but the input is not
129
+ if attributes[attribute_map[key]].is_a?(Array)
130
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
131
+ end
132
+ elsif !attributes[attribute_map[key]].nil?
133
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
134
+ end
135
+ end
136
+ new(transformed_hash)
137
+ end
138
+
139
+ # Returns the object in the form of hash
140
+ # @return [Hash] Returns the object in the form of hash
141
+ def to_hash
142
+ hash = {}
143
+ self.class.attribute_map.each_pair do |attr, param|
144
+ value = self.send(attr)
145
+ if value.nil?
146
+ is_nullable = self.class.openapi_nullable.include?(attr)
147
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
148
+ end
149
+
150
+ hash[param] = _to_hash(value)
151
+ end
152
+ hash
153
+ end
154
+
155
+ end
156
+
157
+ end
@@ -14,6 +14,7 @@ require 'date'
14
14
  require 'time'
15
15
 
16
16
  module Repull
17
+ # Priced by `totalPrice` (Airbnb) OR by its parts — `rentalAmount`, `fees`, `damageDeposit` (VRBO) — never both. With `totalPrice`, `checkIn`, `checkOut` and `guests` are required.
17
18
  class CreateConversationSpecialOfferRequest < ApiModelBase
18
19
  # Repull listing id to offer. Defaults to the listing the conversation is about.
19
20
  attr_accessor :listing_id
@@ -25,9 +26,21 @@ module Repull
25
26
 
26
27
  attr_accessor :guests
27
28
 
28
- # Total the guest pays for the whole stay, in the listing’s Airbnb currency.
29
+ # Airbnb: the total the guest pays for the whole stay, in the listing’s Airbnb currency.
29
30
  attr_accessor :total_price
30
31
 
32
+ # VRBO: rent for the whole stay, excluding fees and taxes.
33
+ attr_accessor :rental_amount
34
+
35
+ # VRBO: the offer’s fees — replaces its fee list. `type` is VRBO’s fee type (`CLEANING`, `PET`, …).
36
+ attr_accessor :fees
37
+
38
+ # VRBO: refundable damage deposit; `null` for none.
39
+ attr_accessor :damage_deposit
40
+
41
+ # VRBO: the message sent to the guest with the offer (a friendly default otherwise).
42
+ attr_accessor :message
43
+
31
44
  # Attribute mapping from ruby-style variable name to JSON key.
32
45
  def self.attribute_map
33
46
  {
@@ -35,7 +48,11 @@ module Repull
35
48
  :'check_in' => :'checkIn',
36
49
  :'check_out' => :'checkOut',
37
50
  :'guests' => :'guests',
38
- :'total_price' => :'totalPrice'
51
+ :'total_price' => :'totalPrice',
52
+ :'rental_amount' => :'rentalAmount',
53
+ :'fees' => :'fees',
54
+ :'damage_deposit' => :'damageDeposit',
55
+ :'message' => :'message'
39
56
  }
40
57
  end
41
58
 
@@ -56,13 +73,18 @@ module Repull
56
73
  :'check_in' => :'Date',
57
74
  :'check_out' => :'Date',
58
75
  :'guests' => :'CreateConversationSpecialOfferRequestGuests',
59
- :'total_price' => :'Float'
76
+ :'total_price' => :'Float',
77
+ :'rental_amount' => :'Float',
78
+ :'fees' => :'Array<CreateConversationSpecialOfferRequestFeesInner>',
79
+ :'damage_deposit' => :'Float',
80
+ :'message' => :'String'
60
81
  }
61
82
  end
62
83
 
63
84
  # List of attributes with nullable: true
64
85
  def self.openapi_nullable
65
86
  Set.new([
87
+ :'damage_deposit',
66
88
  ])
67
89
  end
68
90
 
@@ -88,26 +110,36 @@ module Repull
88
110
 
89
111
  if attributes.key?(:'check_in')
90
112
  self.check_in = attributes[:'check_in']
91
- else
92
- self.check_in = nil
93
113
  end
94
114
 
95
115
  if attributes.key?(:'check_out')
96
116
  self.check_out = attributes[:'check_out']
97
- else
98
- self.check_out = nil
99
117
  end
100
118
 
101
119
  if attributes.key?(:'guests')
102
120
  self.guests = attributes[:'guests']
103
- else
104
- self.guests = nil
105
121
  end
106
122
 
107
123
  if attributes.key?(:'total_price')
108
124
  self.total_price = attributes[:'total_price']
109
- else
110
- self.total_price = nil
125
+ end
126
+
127
+ if attributes.key?(:'rental_amount')
128
+ self.rental_amount = attributes[:'rental_amount']
129
+ end
130
+
131
+ if attributes.key?(:'fees')
132
+ if (value = attributes[:'fees']).is_a?(Array)
133
+ self.fees = value
134
+ end
135
+ end
136
+
137
+ if attributes.key?(:'damage_deposit')
138
+ self.damage_deposit = attributes[:'damage_deposit']
139
+ end
140
+
141
+ if attributes.key?(:'message')
142
+ self.message = attributes[:'message']
111
143
  end
112
144
  end
113
145
 
@@ -116,24 +148,20 @@ module Repull
116
148
  def list_invalid_properties
117
149
  warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
118
150
  invalid_properties = Array.new
119
- if @check_in.nil?
120
- invalid_properties.push('invalid value for "check_in", check_in cannot be nil.')
121
- end
122
-
123
- if @check_out.nil?
124
- invalid_properties.push('invalid value for "check_out", check_out cannot be nil.')
151
+ if !@total_price.nil? && @total_price <= 0
152
+ invalid_properties.push('invalid value for "total_price", must be greater than 0.')
125
153
  end
126
154
 
127
- if @guests.nil?
128
- invalid_properties.push('invalid value for "guests", guests cannot be nil.')
155
+ if !@rental_amount.nil? && @rental_amount <= 0
156
+ invalid_properties.push('invalid value for "rental_amount", must be greater than 0.')
129
157
  end
130
158
 
131
- if @total_price.nil?
132
- invalid_properties.push('invalid value for "total_price", total_price cannot be nil.')
159
+ if !@damage_deposit.nil? && @damage_deposit < 0
160
+ invalid_properties.push('invalid value for "damage_deposit", must be greater than or equal to 0.')
133
161
  end
134
162
 
135
- if @total_price <= 0
136
- invalid_properties.push('invalid value for "total_price", must be greater than 0.')
163
+ if !@message.nil? && @message.to_s.length > 2000
164
+ invalid_properties.push('invalid value for "message", the character length must be smaller than or equal to 2000.')
137
165
  end
138
166
 
139
167
  invalid_properties
@@ -143,56 +171,63 @@ module Repull
143
171
  # @return true if the model is valid
144
172
  def valid?
145
173
  warn '[DEPRECATED] the `valid?` method is obsolete'
146
- return false if @check_in.nil?
147
- return false if @check_out.nil?
148
- return false if @guests.nil?
149
- return false if @total_price.nil?
150
- return false if @total_price <= 0
174
+ return false if !@total_price.nil? && @total_price <= 0
175
+ return false if !@rental_amount.nil? && @rental_amount <= 0
176
+ return false if !@damage_deposit.nil? && @damage_deposit < 0
177
+ return false if !@message.nil? && @message.to_s.length > 2000
151
178
  true
152
179
  end
153
180
 
154
181
  # Custom attribute writer method with validation
155
- # @param [Object] check_in Value to be assigned
156
- def check_in=(check_in)
157
- if check_in.nil?
158
- fail ArgumentError, 'check_in cannot be nil'
182
+ # @param [Object] total_price Value to be assigned
183
+ def total_price=(total_price)
184
+ if total_price.nil?
185
+ fail ArgumentError, 'total_price cannot be nil'
159
186
  end
160
187
 
161
- @check_in = check_in
188
+ if total_price <= 0
189
+ fail ArgumentError, 'invalid value for "total_price", must be greater than 0.'
190
+ end
191
+
192
+ @total_price = total_price
162
193
  end
163
194
 
164
195
  # Custom attribute writer method with validation
165
- # @param [Object] check_out Value to be assigned
166
- def check_out=(check_out)
167
- if check_out.nil?
168
- fail ArgumentError, 'check_out cannot be nil'
196
+ # @param [Object] rental_amount Value to be assigned
197
+ def rental_amount=(rental_amount)
198
+ if rental_amount.nil?
199
+ fail ArgumentError, 'rental_amount cannot be nil'
169
200
  end
170
201
 
171
- @check_out = check_out
202
+ if rental_amount <= 0
203
+ fail ArgumentError, 'invalid value for "rental_amount", must be greater than 0.'
204
+ end
205
+
206
+ @rental_amount = rental_amount
172
207
  end
173
208
 
174
209
  # Custom attribute writer method with validation
175
- # @param [Object] guests Value to be assigned
176
- def guests=(guests)
177
- if guests.nil?
178
- fail ArgumentError, 'guests cannot be nil'
210
+ # @param [Object] damage_deposit Value to be assigned
211
+ def damage_deposit=(damage_deposit)
212
+ if !damage_deposit.nil? && damage_deposit < 0
213
+ fail ArgumentError, 'invalid value for "damage_deposit", must be greater than or equal to 0.'
179
214
  end
180
215
 
181
- @guests = guests
216
+ @damage_deposit = damage_deposit
182
217
  end
183
218
 
184
219
  # Custom attribute writer method with validation
185
- # @param [Object] total_price Value to be assigned
186
- def total_price=(total_price)
187
- if total_price.nil?
188
- fail ArgumentError, 'total_price cannot be nil'
220
+ # @param [Object] message Value to be assigned
221
+ def message=(message)
222
+ if message.nil?
223
+ fail ArgumentError, 'message cannot be nil'
189
224
  end
190
225
 
191
- if total_price <= 0
192
- fail ArgumentError, 'invalid value for "total_price", must be greater than 0.'
226
+ if message.to_s.length > 2000
227
+ fail ArgumentError, 'invalid value for "message", the character length must be smaller than or equal to 2000.'
193
228
  end
194
229
 
195
- @total_price = total_price
230
+ @message = message
196
231
  end
197
232
 
198
233
  # Checks equality by comparing each attribute.
@@ -204,7 +239,11 @@ module Repull
204
239
  check_in == o.check_in &&
205
240
  check_out == o.check_out &&
206
241
  guests == o.guests &&
207
- total_price == o.total_price
242
+ total_price == o.total_price &&
243
+ rental_amount == o.rental_amount &&
244
+ fees == o.fees &&
245
+ damage_deposit == o.damage_deposit &&
246
+ message == o.message
208
247
  end
209
248
 
210
249
  # @see the `==` method
@@ -216,7 +255,7 @@ module Repull
216
255
  # Calculates hash code according to all attributes.
217
256
  # @return [Integer] Hash code
218
257
  def hash
219
- [listing_id, check_in, check_out, guests, total_price].hash
258
+ [listing_id, check_in, check_out, guests, total_price, rental_amount, fees, damage_deposit, message].hash
220
259
  end
221
260
 
222
261
  # Builds the object from hash