late-sdk 0.0.891 → 0.0.893

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f562746b718328fd8d6f0f4ffadb1e841b30ffc494dffeaeae2d1e4deb40e40
4
- data.tar.gz: 3d269d5d7149ba25c46d70a8f2c836fdd833bbff65cde06f02adcd469ccf813d
3
+ metadata.gz: 5fd86ce35443db934013c4d93c88919a14e76e18b33a8840e77b66df3e2b37c5
4
+ data.tar.gz: 6acff42012ff43c583b90aec95d96c1f478b718b824ffc27f3c77bf62f4e2f3f
5
5
  SHA512:
6
- metadata.gz: b1cfd089b27b371e9cf2033858045e9489e151f08dafee470fb874b1d4ea16e89287b0f2ffa03da57406c59de5bdf5e546e99b3fd1c473a033ded04bd48c72a3
7
- data.tar.gz: 393ba287e92510fe9a06c36e00c208b81d59a5728165fa2ad2579159226d297839aa255d00c4c2ce65c725c043943994adb227f37921692cf09f69de4d241296
6
+ metadata.gz: 79779669ded9119cee41725c590efdbc831ae40170b90ac51b007fe41e0510608942835ee39817cad5ba68cd2fab60a8cd09c4404d4378d061194f710fcaed99
7
+ data.tar.gz: ee18055cb92d12bf2b1d1845f9e0f5f50777a6649156a2f030bb25c5f4d2451296567366fdd95f18c5d07eed27adcbb025e65129498b1695d863bd2933862981
data/README.md CHANGED
@@ -979,7 +979,6 @@ Class | Method | HTTP request | Description
979
979
  - [Zernio::Connected](docs/Connected.md)
980
980
  - [Zernio::ConnectedAccount](docs/ConnectedAccount.md)
981
981
  - [Zernio::ConnectedApp](docs/ConnectedApp.md)
982
- - [Zernio::Conversation](docs/Conversation.md)
983
982
  - [Zernio::ConversionAction](docs/ConversionAction.md)
984
983
  - [Zernio::ConversionActionTagSnippetsInner](docs/ConversionActionTagSnippetsInner.md)
985
984
  - [Zernio::ConversionDestination](docs/ConversionDestination.md)
@@ -1655,6 +1654,7 @@ Class | Method | HTTP request | Description
1655
1654
  - [Zernio::InboxMessageEditHistoryEntry](docs/InboxMessageEditHistoryEntry.md)
1656
1655
  - [Zernio::InboxWebhookAccount](docs/InboxWebhookAccount.md)
1657
1656
  - [Zernio::InboxWebhookConversation](docs/InboxWebhookConversation.md)
1657
+ - [Zernio::InboxWebhookConversationDetail](docs/InboxWebhookConversationDetail.md)
1658
1658
  - [Zernio::InboxWebhookMessage](docs/InboxWebhookMessage.md)
1659
1659
  - [Zernio::InboxWebhookMessageAttachmentsInner](docs/InboxWebhookMessageAttachmentsInner.md)
1660
1660
  - [Zernio::InboxWebhookMessageSender](docs/InboxWebhookMessageSender.md)
@@ -2569,7 +2569,6 @@ Class | Method | HTTP request | Description
2569
2569
  - [Zernio::WebhookPayloadConversationControlChanged](docs/WebhookPayloadConversationControlChanged.md)
2570
2570
  - [Zernio::WebhookPayloadConversationControlChangedControl](docs/WebhookPayloadConversationControlChangedControl.md)
2571
2571
  - [Zernio::WebhookPayloadConversationStarted](docs/WebhookPayloadConversationStarted.md)
2572
- - [Zernio::WebhookPayloadConversationStartedConversation](docs/WebhookPayloadConversationStartedConversation.md)
2573
2572
  - [Zernio::WebhookPayloadExternalPost](docs/WebhookPayloadExternalPost.md)
2574
2573
  - [Zernio::WebhookPayloadLead](docs/WebhookPayloadLead.md)
2575
2574
  - [Zernio::WebhookPayloadLeadAccount](docs/WebhookPayloadLeadAccount.md)
data/docs/AnalyticsApi.md CHANGED
@@ -129,7 +129,7 @@ end
129
129
 
130
130
  Analytics changed since a cursor
131
131
 
132
- Cursor feed of the analytics snapshots that CHANGED, across every account you can read, in one paginated stream. Built for integrations that would otherwise call `GET /v1/analytics` once per connected account. Each page carries changes from many accounts at once, so your call count scales with how much actually changed rather than with how many accounts you have. Measured against a fleet of roughly 1,600 connected accounts: about 1,599 per-account analytics calls an hour became about 205 delta calls an hour, a 7.8x reduction. **Bootstrap once, then stay in sync.** Load your baseline from `GET /v1/analytics`, which is the historical endpoint. This one is a rolling 7-day change log and cannot replay history. Then call this endpoint with NO `cursor`: it answers with an empty `data` array plus the feed's current position in `nextCursor`. Send that `nextCursor` back on the next call and you receive everything written since. `nextCursor` is present on every response, empty pages included, so you always have something to advance with. **Ordering.** Entries come back oldest first, in the order the feed received them. That order is NOT `syncedAt`: `syncedAt` is stamped when an account's sync cycle started, and a slow cycle writes its rows after a faster cycle that started later, so `syncedAt` can go backwards between consecutive entries. Do not sort, filter or resume on it. The cursor is the only stable position, and it is opaque: pass it back verbatim, and do not parse, construct or compare cursors. **`hasMore: false` does not mean the feed ended.** This stream has no end and `nextCursor` is never null. `hasMore: true` means more changes are already waiting, so call again straight away. `hasMore: false` means you are caught up: keep the cursor and poll again on your normal interval. **The newest changes settle before they are served.** The feed deliberately holds back its last few seconds of writes, so that a row can never become visible behind a cursor you have already advanced past. A read issued the instant an `analytics.synced` webhook lands will therefore often return an empty page for that account. Do not read an empty page as \"nothing changed\": poll again with the SAME cursor you last used rather than advancing. **Repeats inside one instant.** A sync cycle occasionally records the same post twice at the same feed position. When that happens the feed delivers one of those rows, not both. Measured over a day of production traffic, about 1.3% of rows fall in such a group and 99.4% of those groups are identical rows, so this is far more often deduplication than loss. Metrics are absolute values rather than increments, so a later entry for the same post supersedes an earlier one. **Retention is 7 days.** Changes older than that leave the feed. A cursor older than 6 days is rejected with a `400` (a day of margin, because expiry is lazy). Recover by re-bootstrapping from `GET /v1/analytics` and taking a fresh cursor from a call to this endpoint with no `cursor`. A consumer that polls at least daily never reaches this. Pairs with the `analytics.synced` webhook, so changes can be read on notification instead of on a timer. That event carries no cursor of its own: keep using the `nextCursor` this endpoint gave you. Requires the same analytics access as `GET /v1/analytics`, and shares the stricter per-second rate-limit window applied to analytics endpoints.
132
+ Cursor feed of the analytics snapshots that CHANGED, across every account you can read, in one paginated stream. Built for integrations that would otherwise call `GET /v1/analytics` once per connected account. Each page carries changes from many accounts at once, so your call count scales with how much actually changed rather than with how many accounts you have. Measured against a fleet of roughly 1,600 connected accounts: about 1,599 per-account analytics calls an hour became about 205 delta calls an hour, a 7.8x reduction. **Bootstrap once, then stay in sync.** Take the cursor FIRST: call this endpoint with NO `cursor` and it answers with an empty `data` array plus the feed's current position in `nextCursor`. Then load your baseline from `GET /v1/analytics`, the historical endpoint, because this one is a rolling 7-day change log and cannot replay history. Then resume from the cursor you took before the baseline. Taking the cursor afterwards instead drops every change that lands while the baseline is loading: it is in neither the row you already read nor the feed you resume behind it. The overlap this order creates is safe, because metrics are absolute values rather than increments, so draining it leaves every post on its newest value. `nextCursor` is present on every response, empty pages included, so you always have something to advance with. **Ordering.** Entries come back oldest first, in the order the feed received them. That order is NOT `syncedAt`: `syncedAt` is stamped when an account's sync cycle started, and a slow cycle writes its rows after a faster cycle that started later, so `syncedAt` can go backwards between consecutive entries. Do not sort, filter or resume on it. The cursor is the only stable position, and it is opaque: pass it back verbatim, and do not parse, construct or compare cursors. **`hasMore: false` does not mean the feed ended.** This stream has no end and `nextCursor` is never null. `hasMore: true` means more changes are already waiting, so call again straight away. `hasMore: false` means you are caught up: keep the cursor and poll again on your normal interval. **The newest changes settle before they are served.** The feed deliberately holds back its last few seconds of writes, so that a row can never become visible behind a cursor you have already advanced past. A read issued the instant an `analytics.synced` webhook lands will therefore often return an empty page for that account. Do not read an empty page as \"nothing changed\": poll again with the SAME cursor you last used rather than advancing. **Repeats inside one instant.** A sync cycle occasionally records the same post twice at the same feed position. When that happens the feed delivers one of those rows, not both. Measured over a day of production traffic, about 1.3% of rows fall in such a group and 99.4% of those groups are identical rows, so this is far more often deduplication than loss. Metrics are absolute values rather than increments, so a later entry for the same post supersedes an earlier one. **Retention is 7 days.** Changes older than that leave the feed. A cursor older than 6 days is rejected with a `400` (a day of margin, because expiry is lazy). Recover the same way you bootstrapped: take a fresh cursor from a call to this endpoint with no `cursor`, then re-load from `GET /v1/analytics`, then resume from that cursor. A consumer that polls at least daily never reaches this. Pairs with the `analytics.synced` webhook, so changes can be read on notification instead of on a timer. That event carries no cursor of its own: keep using the `nextCursor` this endpoint gave you. Requires the same analytics access as `GET /v1/analytics`, and shares the stricter per-second rate-limit window applied to analytics endpoints.
133
133
 
134
134
  ### Examples
135
135
 
@@ -1,4 +1,4 @@
1
- # Zernio::Conversation
1
+ # Zernio::InboxWebhookConversationDetail
2
2
 
3
3
  ## Properties
4
4
 
@@ -19,7 +19,7 @@
19
19
  ```ruby
20
20
  require 'zernio-sdk'
21
21
 
22
- instance = Zernio::Conversation.new(
22
+ instance = Zernio::InboxWebhookConversationDetail.new(
23
23
  id: null,
24
24
  platform: null,
25
25
  platform_conversation_id: null,
@@ -6,7 +6,7 @@
6
6
  | ---- | ---- | ----------- | ----- |
7
7
  | **id** | **String** | Stable webhook event ID | |
8
8
  | **event** | **String** | | |
9
- | **conversation** | [**WebhookPayloadConversationStartedConversation**](WebhookPayloadConversationStartedConversation.md) | | |
9
+ | **conversation** | [**InboxWebhookConversationDetail**](InboxWebhookConversationDetail.md) | | |
10
10
  | **account** | [**InboxWebhookAccount**](InboxWebhookAccount.md) | | |
11
11
  | **control** | [**WebhookPayloadConversationControlChangedControl**](WebhookPayloadConversationControlChangedControl.md) | | |
12
12
  | **changed_at** | **Time** | | |
@@ -6,7 +6,7 @@
6
6
  | ---- | ---- | ----------- | ----- |
7
7
  | **id** | **String** | Stable webhook event ID | |
8
8
  | **event** | **String** | | |
9
- | **conversation** | [**WebhookPayloadConversationStartedConversation**](WebhookPayloadConversationStartedConversation.md) | | |
9
+ | **conversation** | [**InboxWebhookConversationDetail**](InboxWebhookConversationDetail.md) | | |
10
10
  | **account** | [**InboxWebhookAccount**](InboxWebhookAccount.md) | | |
11
11
  | **started_at** | **Time** | When the conversation document was created. | |
12
12
  | **timestamp** | **Time** | UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt. | |
@@ -134,7 +134,7 @@ module Zernio
134
134
  end
135
135
 
136
136
  # Analytics changed since a cursor
137
- # Cursor feed of the analytics snapshots that CHANGED, across every account you can read, in one paginated stream. Built for integrations that would otherwise call `GET /v1/analytics` once per connected account. Each page carries changes from many accounts at once, so your call count scales with how much actually changed rather than with how many accounts you have. Measured against a fleet of roughly 1,600 connected accounts: about 1,599 per-account analytics calls an hour became about 205 delta calls an hour, a 7.8x reduction. **Bootstrap once, then stay in sync.** Load your baseline from `GET /v1/analytics`, which is the historical endpoint. This one is a rolling 7-day change log and cannot replay history. Then call this endpoint with NO `cursor`: it answers with an empty `data` array plus the feed's current position in `nextCursor`. Send that `nextCursor` back on the next call and you receive everything written since. `nextCursor` is present on every response, empty pages included, so you always have something to advance with. **Ordering.** Entries come back oldest first, in the order the feed received them. That order is NOT `syncedAt`: `syncedAt` is stamped when an account's sync cycle started, and a slow cycle writes its rows after a faster cycle that started later, so `syncedAt` can go backwards between consecutive entries. Do not sort, filter or resume on it. The cursor is the only stable position, and it is opaque: pass it back verbatim, and do not parse, construct or compare cursors. **`hasMore: false` does not mean the feed ended.** This stream has no end and `nextCursor` is never null. `hasMore: true` means more changes are already waiting, so call again straight away. `hasMore: false` means you are caught up: keep the cursor and poll again on your normal interval. **The newest changes settle before they are served.** The feed deliberately holds back its last few seconds of writes, so that a row can never become visible behind a cursor you have already advanced past. A read issued the instant an `analytics.synced` webhook lands will therefore often return an empty page for that account. Do not read an empty page as \"nothing changed\": poll again with the SAME cursor you last used rather than advancing. **Repeats inside one instant.** A sync cycle occasionally records the same post twice at the same feed position. When that happens the feed delivers one of those rows, not both. Measured over a day of production traffic, about 1.3% of rows fall in such a group and 99.4% of those groups are identical rows, so this is far more often deduplication than loss. Metrics are absolute values rather than increments, so a later entry for the same post supersedes an earlier one. **Retention is 7 days.** Changes older than that leave the feed. A cursor older than 6 days is rejected with a `400` (a day of margin, because expiry is lazy). Recover by re-bootstrapping from `GET /v1/analytics` and taking a fresh cursor from a call to this endpoint with no `cursor`. A consumer that polls at least daily never reaches this. Pairs with the `analytics.synced` webhook, so changes can be read on notification instead of on a timer. That event carries no cursor of its own: keep using the `nextCursor` this endpoint gave you. Requires the same analytics access as `GET /v1/analytics`, and shares the stricter per-second rate-limit window applied to analytics endpoints.
137
+ # Cursor feed of the analytics snapshots that CHANGED, across every account you can read, in one paginated stream. Built for integrations that would otherwise call `GET /v1/analytics` once per connected account. Each page carries changes from many accounts at once, so your call count scales with how much actually changed rather than with how many accounts you have. Measured against a fleet of roughly 1,600 connected accounts: about 1,599 per-account analytics calls an hour became about 205 delta calls an hour, a 7.8x reduction. **Bootstrap once, then stay in sync.** Take the cursor FIRST: call this endpoint with NO `cursor` and it answers with an empty `data` array plus the feed's current position in `nextCursor`. Then load your baseline from `GET /v1/analytics`, the historical endpoint, because this one is a rolling 7-day change log and cannot replay history. Then resume from the cursor you took before the baseline. Taking the cursor afterwards instead drops every change that lands while the baseline is loading: it is in neither the row you already read nor the feed you resume behind it. The overlap this order creates is safe, because metrics are absolute values rather than increments, so draining it leaves every post on its newest value. `nextCursor` is present on every response, empty pages included, so you always have something to advance with. **Ordering.** Entries come back oldest first, in the order the feed received them. That order is NOT `syncedAt`: `syncedAt` is stamped when an account's sync cycle started, and a slow cycle writes its rows after a faster cycle that started later, so `syncedAt` can go backwards between consecutive entries. Do not sort, filter or resume on it. The cursor is the only stable position, and it is opaque: pass it back verbatim, and do not parse, construct or compare cursors. **`hasMore: false` does not mean the feed ended.** This stream has no end and `nextCursor` is never null. `hasMore: true` means more changes are already waiting, so call again straight away. `hasMore: false` means you are caught up: keep the cursor and poll again on your normal interval. **The newest changes settle before they are served.** The feed deliberately holds back its last few seconds of writes, so that a row can never become visible behind a cursor you have already advanced past. A read issued the instant an `analytics.synced` webhook lands will therefore often return an empty page for that account. Do not read an empty page as \"nothing changed\": poll again with the SAME cursor you last used rather than advancing. **Repeats inside one instant.** A sync cycle occasionally records the same post twice at the same feed position. When that happens the feed delivers one of those rows, not both. Measured over a day of production traffic, about 1.3% of rows fall in such a group and 99.4% of those groups are identical rows, so this is far more often deduplication than loss. Metrics are absolute values rather than increments, so a later entry for the same post supersedes an earlier one. **Retention is 7 days.** Changes older than that leave the feed. A cursor older than 6 days is rejected with a `400` (a day of margin, because expiry is lazy). Recover the same way you bootstrapped: take a fresh cursor from a call to this endpoint with no `cursor`, then re-load from `GET /v1/analytics`, then resume from that cursor. A consumer that polls at least daily never reaches this. Pairs with the `analytics.synced` webhook, so changes can be read on notification instead of on a timer. That event carries no cursor of its own: keep using the `nextCursor` this endpoint gave you. Requires the same analytics access as `GET /v1/analytics`, and shares the stricter per-second rate-limit window applied to analytics endpoints.
138
138
  # @param [Hash] opts the optional parameters
139
139
  # @option opts [String] :cursor Opaque cursor from a previous response's `nextCursor`. Omit it to start from now: the response is then an empty page carrying the feed's current position. Rejected with a `400` when malformed, or when older than the retention window.
140
140
  # @option opts [Integer] :limit Page size. Out-of-range values are a 400, never a silent clamp. (default to 50)
@@ -147,7 +147,7 @@ module Zernio
147
147
  end
148
148
 
149
149
  # Analytics changed since a cursor
150
- # Cursor feed of the analytics snapshots that CHANGED, across every account you can read, in one paginated stream. Built for integrations that would otherwise call `GET /v1/analytics` once per connected account. Each page carries changes from many accounts at once, so your call count scales with how much actually changed rather than with how many accounts you have. Measured against a fleet of roughly 1,600 connected accounts: about 1,599 per-account analytics calls an hour became about 205 delta calls an hour, a 7.8x reduction. **Bootstrap once, then stay in sync.** Load your baseline from `GET /v1/analytics`, which is the historical endpoint. This one is a rolling 7-day change log and cannot replay history. Then call this endpoint with NO `cursor`: it answers with an empty `data` array plus the feed's current position in `nextCursor`. Send that `nextCursor` back on the next call and you receive everything written since. `nextCursor` is present on every response, empty pages included, so you always have something to advance with. **Ordering.** Entries come back oldest first, in the order the feed received them. That order is NOT `syncedAt`: `syncedAt` is stamped when an account's sync cycle started, and a slow cycle writes its rows after a faster cycle that started later, so `syncedAt` can go backwards between consecutive entries. Do not sort, filter or resume on it. The cursor is the only stable position, and it is opaque: pass it back verbatim, and do not parse, construct or compare cursors. **`hasMore: false` does not mean the feed ended.** This stream has no end and `nextCursor` is never null. `hasMore: true` means more changes are already waiting, so call again straight away. `hasMore: false` means you are caught up: keep the cursor and poll again on your normal interval. **The newest changes settle before they are served.** The feed deliberately holds back its last few seconds of writes, so that a row can never become visible behind a cursor you have already advanced past. A read issued the instant an `analytics.synced` webhook lands will therefore often return an empty page for that account. Do not read an empty page as \"nothing changed\": poll again with the SAME cursor you last used rather than advancing. **Repeats inside one instant.** A sync cycle occasionally records the same post twice at the same feed position. When that happens the feed delivers one of those rows, not both. Measured over a day of production traffic, about 1.3% of rows fall in such a group and 99.4% of those groups are identical rows, so this is far more often deduplication than loss. Metrics are absolute values rather than increments, so a later entry for the same post supersedes an earlier one. **Retention is 7 days.** Changes older than that leave the feed. A cursor older than 6 days is rejected with a `400` (a day of margin, because expiry is lazy). Recover by re-bootstrapping from `GET /v1/analytics` and taking a fresh cursor from a call to this endpoint with no `cursor`. A consumer that polls at least daily never reaches this. Pairs with the `analytics.synced` webhook, so changes can be read on notification instead of on a timer. That event carries no cursor of its own: keep using the `nextCursor` this endpoint gave you. Requires the same analytics access as `GET /v1/analytics`, and shares the stricter per-second rate-limit window applied to analytics endpoints.
150
+ # Cursor feed of the analytics snapshots that CHANGED, across every account you can read, in one paginated stream. Built for integrations that would otherwise call `GET /v1/analytics` once per connected account. Each page carries changes from many accounts at once, so your call count scales with how much actually changed rather than with how many accounts you have. Measured against a fleet of roughly 1,600 connected accounts: about 1,599 per-account analytics calls an hour became about 205 delta calls an hour, a 7.8x reduction. **Bootstrap once, then stay in sync.** Take the cursor FIRST: call this endpoint with NO `cursor` and it answers with an empty `data` array plus the feed's current position in `nextCursor`. Then load your baseline from `GET /v1/analytics`, the historical endpoint, because this one is a rolling 7-day change log and cannot replay history. Then resume from the cursor you took before the baseline. Taking the cursor afterwards instead drops every change that lands while the baseline is loading: it is in neither the row you already read nor the feed you resume behind it. The overlap this order creates is safe, because metrics are absolute values rather than increments, so draining it leaves every post on its newest value. `nextCursor` is present on every response, empty pages included, so you always have something to advance with. **Ordering.** Entries come back oldest first, in the order the feed received them. That order is NOT `syncedAt`: `syncedAt` is stamped when an account's sync cycle started, and a slow cycle writes its rows after a faster cycle that started later, so `syncedAt` can go backwards between consecutive entries. Do not sort, filter or resume on it. The cursor is the only stable position, and it is opaque: pass it back verbatim, and do not parse, construct or compare cursors. **`hasMore: false` does not mean the feed ended.** This stream has no end and `nextCursor` is never null. `hasMore: true` means more changes are already waiting, so call again straight away. `hasMore: false` means you are caught up: keep the cursor and poll again on your normal interval. **The newest changes settle before they are served.** The feed deliberately holds back its last few seconds of writes, so that a row can never become visible behind a cursor you have already advanced past. A read issued the instant an `analytics.synced` webhook lands will therefore often return an empty page for that account. Do not read an empty page as \"nothing changed\": poll again with the SAME cursor you last used rather than advancing. **Repeats inside one instant.** A sync cycle occasionally records the same post twice at the same feed position. When that happens the feed delivers one of those rows, not both. Measured over a day of production traffic, about 1.3% of rows fall in such a group and 99.4% of those groups are identical rows, so this is far more often deduplication than loss. Metrics are absolute values rather than increments, so a later entry for the same post supersedes an earlier one. **Retention is 7 days.** Changes older than that leave the feed. A cursor older than 6 days is rejected with a `400` (a day of margin, because expiry is lazy). Recover the same way you bootstrapped: take a fresh cursor from a call to this endpoint with no `cursor`, then re-load from `GET /v1/analytics`, then resume from that cursor. A consumer that polls at least daily never reaches this. Pairs with the `analytics.synced` webhook, so changes can be read on notification instead of on a timer. That event carries no cursor of its own: keep using the `nextCursor` this endpoint gave you. Requires the same analytics access as `GET /v1/analytics`, and shares the stricter per-second rate-limit window applied to analytics endpoints.
151
151
  # @param [Hash] opts the optional parameters
152
152
  # @option opts [String] :cursor Opaque cursor from a previous response's `nextCursor`. Omit it to start from now: the response is then an empty page carrying the feed's current position. Rejected with a `400` when malformed, or when older than the retention window.
153
153
  # @option opts [Integer] :limit Page size. Out-of-range values are a 400, never a silent clamp. (default to 50)
@@ -14,7 +14,8 @@ require 'date'
14
14
  require 'time'
15
15
 
16
16
  module Zernio
17
- class Conversation < ApiModelBase
17
+ # The conversation object included in conversation lifecycle webhook payloads (conversation.started, conversation.control_changed).
18
+ class InboxWebhookConversationDetail < ApiModelBase
18
19
  # Internal conversation ID
19
20
  attr_accessor :id
20
21
 
@@ -109,14 +110,14 @@ module Zernio
109
110
  # @param [Hash] attributes Model attributes in the form of hash
110
111
  def initialize(attributes = {})
111
112
  if (!attributes.is_a?(Hash))
112
- fail ArgumentError, "The input argument (attributes) must be a hash in `Zernio::Conversation` initialize method"
113
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Zernio::InboxWebhookConversationDetail` initialize method"
113
114
  end
114
115
 
115
116
  # check to see if the attribute exists and convert string to symbol for hash key
116
117
  acceptable_attribute_map = self.class.acceptable_attribute_map
117
118
  attributes = attributes.each_with_object({}) { |(k, v), h|
118
119
  if (!acceptable_attribute_map.key?(k.to_sym))
119
- fail ArgumentError, "`#{k}` is not a valid attribute in `Zernio::Conversation`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
120
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Zernio::InboxWebhookConversationDetail`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
120
121
  end
121
122
  h[k.to_sym] = v
122
123
  }
@@ -82,7 +82,7 @@ module Zernio
82
82
  {
83
83
  :'id' => :'String',
84
84
  :'event' => :'String',
85
- :'conversation' => :'WebhookPayloadConversationStartedConversation',
85
+ :'conversation' => :'InboxWebhookConversationDetail',
86
86
  :'account' => :'InboxWebhookAccount',
87
87
  :'control' => :'WebhookPayloadConversationControlChangedControl',
88
88
  :'changed_at' => :'Time',
@@ -80,7 +80,7 @@ module Zernio
80
80
  {
81
81
  :'id' => :'String',
82
82
  :'event' => :'String',
83
- :'conversation' => :'WebhookPayloadConversationStartedConversation',
83
+ :'conversation' => :'InboxWebhookConversationDetail',
84
84
  :'account' => :'InboxWebhookAccount',
85
85
  :'started_at' => :'Time',
86
86
  :'timestamp' => :'Time'
@@ -11,5 +11,5 @@ Generator version: 7.19.0
11
11
  =end
12
12
 
13
13
  module Zernio
14
- VERSION = '0.0.891'
14
+ VERSION = '0.0.893'
15
15
  end
data/lib/zernio-sdk.rb CHANGED
@@ -238,7 +238,6 @@ require 'zernio-sdk/models/connect_whats_app_embedded_signup_request'
238
238
  require 'zernio-sdk/models/connected'
239
239
  require 'zernio-sdk/models/connected_account'
240
240
  require 'zernio-sdk/models/connected_app'
241
- require 'zernio-sdk/models/conversation'
242
241
  require 'zernio-sdk/models/conversion_action'
243
242
  require 'zernio-sdk/models/conversion_action_tag_snippets_inner'
244
243
  require 'zernio-sdk/models/conversion_destination'
@@ -914,6 +913,7 @@ require 'zernio-sdk/models/inbox_message_edit_attachment'
914
913
  require 'zernio-sdk/models/inbox_message_edit_history_entry'
915
914
  require 'zernio-sdk/models/inbox_webhook_account'
916
915
  require 'zernio-sdk/models/inbox_webhook_conversation'
916
+ require 'zernio-sdk/models/inbox_webhook_conversation_detail'
917
917
  require 'zernio-sdk/models/inbox_webhook_message'
918
918
  require 'zernio-sdk/models/inbox_webhook_message_attachments_inner'
919
919
  require 'zernio-sdk/models/inbox_webhook_message_sender'
@@ -1828,7 +1828,6 @@ require 'zernio-sdk/models/webhook_payload_comment_post'
1828
1828
  require 'zernio-sdk/models/webhook_payload_conversation_control_changed'
1829
1829
  require 'zernio-sdk/models/webhook_payload_conversation_control_changed_control'
1830
1830
  require 'zernio-sdk/models/webhook_payload_conversation_started'
1831
- require 'zernio-sdk/models/webhook_payload_conversation_started_conversation'
1832
1831
  require 'zernio-sdk/models/webhook_payload_external_post'
1833
1832
  require 'zernio-sdk/models/webhook_payload_lead'
1834
1833
  require 'zernio-sdk/models/webhook_payload_lead_account'
data/openapi.yaml CHANGED
@@ -3599,6 +3599,32 @@ components:
3599
3599
  integrators join any inbox webhook back to the CRM Contact without
3600
3600
  needing to look at the sender, which matters for outgoing and
3601
3601
  delivery-status events whose sender is the business.
3602
+ InboxWebhookConversationDetail:
3603
+ type: object
3604
+ description: The conversation object included in conversation lifecycle webhook payloads (conversation.started, conversation.control_changed).
3605
+ required: [id, platform, platformConversationId, participantName, status]
3606
+ properties:
3607
+ id: { type: string, description: Internal conversation ID }
3608
+ platform:
3609
+ type: string
3610
+ enum: [instagram, facebook, telegram, whatsapp, twitter, reddit, bluesky, sms, slack]
3611
+ platformConversationId: { type: string }
3612
+ participantId: { type: string, description: "Contact's platform identifier (IGSID, PSID, wa_id, etc.)" }
3613
+ participantName: { type: string }
3614
+ participantUsername: { type: string, description: Contact's handle when the platform exposes one }
3615
+ participantPicture: { type: string }
3616
+ status:
3617
+ type: string
3618
+ enum: [active, archived]
3619
+ contactId:
3620
+ type: string
3621
+ description: |
3622
+ Zernio CRM Contact ID for the participant, when one exists. Resolved by
3623
+ joining `participantId` to the ContactChannel collection (same join
3624
+ used by message.*, reaction.received, and call.* webhooks). Best-effort:
3625
+ omitted when no channel matches or `participantId` is absent. Lets
3626
+ integrators seed the CRM straight from `conversation.started` without
3627
+ waiting for the first `message.*` event.
3602
3628
  InboxWebhookAccount:
3603
3629
  type: object
3604
3630
  description: The account context included in inbox webhook payloads.
@@ -4518,30 +4544,7 @@ components:
4518
4544
  type: string
4519
4545
  enum: [conversation.started]
4520
4546
  conversation:
4521
- type: object
4522
- required: [id, platform, platformConversationId, participantName, status]
4523
- properties:
4524
- id: { type: string, description: Internal conversation ID }
4525
- platform:
4526
- type: string
4527
- enum: [instagram, facebook, telegram, whatsapp, twitter, reddit, bluesky, sms, slack]
4528
- platformConversationId: { type: string }
4529
- participantId: { type: string, description: "Contact's platform identifier (IGSID, PSID, wa_id, etc.)" }
4530
- participantName: { type: string }
4531
- participantUsername: { type: string, description: Contact's handle when the platform exposes one }
4532
- participantPicture: { type: string }
4533
- status:
4534
- type: string
4535
- enum: [active, archived]
4536
- contactId:
4537
- type: string
4538
- description: |
4539
- Zernio CRM Contact ID for the participant, when one exists. Resolved by
4540
- joining `participantId` to the ContactChannel collection (same join
4541
- used by message.*, reaction.received, and call.* webhooks). Best-effort:
4542
- omitted when no channel matches or `participantId` is absent. Lets
4543
- integrators seed the CRM straight from `conversation.started` without
4544
- waiting for the first `message.*` event.
4547
+ $ref: '#/components/schemas/InboxWebhookConversationDetail'
4545
4548
  account:
4546
4549
  $ref: '#/components/schemas/InboxWebhookAccount'
4547
4550
  startedAt:
@@ -4564,7 +4567,7 @@ components:
4564
4567
  type: string
4565
4568
  enum: [conversation.control_changed]
4566
4569
  conversation:
4567
- $ref: '#/components/schemas/WebhookPayloadConversationStarted/properties/conversation'
4570
+ $ref: '#/components/schemas/InboxWebhookConversationDetail'
4568
4571
  account:
4569
4572
  $ref: '#/components/schemas/InboxWebhookAccount'
4570
4573
  control:
@@ -11778,13 +11781,17 @@ paths:
11778
11781
  1,600 connected accounts: about 1,599 per-account analytics calls an hour became
11779
11782
  about 205 delta calls an hour, a 7.8x reduction.
11780
11783
 
11781
- **Bootstrap once, then stay in sync.** Load your baseline from
11782
- `GET /v1/analytics`, which is the historical endpoint. This one is a rolling
11783
- 7-day change log and cannot replay history. Then call this endpoint with NO
11784
- `cursor`: it answers with an empty `data` array plus the feed's current position
11785
- in `nextCursor`. Send that `nextCursor` back on the next call and you receive
11786
- everything written since. `nextCursor` is present on every response, empty pages
11787
- included, so you always have something to advance with.
11784
+ **Bootstrap once, then stay in sync.** Take the cursor FIRST: call this endpoint
11785
+ with NO `cursor` and it answers with an empty `data` array plus the feed's current
11786
+ position in `nextCursor`. Then load your baseline from `GET /v1/analytics`, the
11787
+ historical endpoint, because this one is a rolling 7-day change log and cannot
11788
+ replay history. Then resume from the cursor you took before the baseline. Taking
11789
+ the cursor afterwards instead drops every change that lands while the baseline is
11790
+ loading: it is in neither the row you already read nor the feed you resume behind
11791
+ it. The overlap this order creates is safe, because metrics are absolute values
11792
+ rather than increments, so draining it leaves every post on its newest value.
11793
+ `nextCursor` is present on every response, empty pages included, so you always
11794
+ have something to advance with.
11788
11795
 
11789
11796
  **Ordering.** Entries come back oldest first, in the order the feed received
11790
11797
  them. That order is NOT `syncedAt`: `syncedAt` is stamped when an account's sync
@@ -11814,9 +11821,9 @@ paths:
11814
11821
 
11815
11822
  **Retention is 7 days.** Changes older than that leave the feed. A cursor older
11816
11823
  than 6 days is rejected with a `400` (a day of margin, because expiry is lazy).
11817
- Recover by re-bootstrapping from `GET /v1/analytics` and taking a fresh cursor
11818
- from a call to this endpoint with no `cursor`. A consumer that polls at least
11819
- daily never reaches this.
11824
+ Recover the same way you bootstrapped: take a fresh cursor from a call to this
11825
+ endpoint with no `cursor`, then re-load from `GET /v1/analytics`, then resume
11826
+ from that cursor. A consumer that polls at least daily never reaches this.
11820
11827
 
11821
11828
  Pairs with the `analytics.synced` webhook, so changes can be read on notification
11822
11829
  instead of on a timer. That event carries no cursor of its own: keep using the
@@ -56,7 +56,7 @@ describe 'AnalyticsApi' do
56
56
 
57
57
  # unit tests for get_analytics_delta
58
58
  # Analytics changed since a cursor
59
- # Cursor feed of the analytics snapshots that CHANGED, across every account you can read, in one paginated stream. Built for integrations that would otherwise call &#x60;GET /v1/analytics&#x60; once per connected account. Each page carries changes from many accounts at once, so your call count scales with how much actually changed rather than with how many accounts you have. Measured against a fleet of roughly 1,600 connected accounts: about 1,599 per-account analytics calls an hour became about 205 delta calls an hour, a 7.8x reduction. **Bootstrap once, then stay in sync.** Load your baseline from &#x60;GET /v1/analytics&#x60;, which is the historical endpoint. This one is a rolling 7-day change log and cannot replay history. Then call this endpoint with NO &#x60;cursor&#x60;: it answers with an empty &#x60;data&#x60; array plus the feed&#39;s current position in &#x60;nextCursor&#x60;. Send that &#x60;nextCursor&#x60; back on the next call and you receive everything written since. &#x60;nextCursor&#x60; is present on every response, empty pages included, so you always have something to advance with. **Ordering.** Entries come back oldest first, in the order the feed received them. That order is NOT &#x60;syncedAt&#x60;: &#x60;syncedAt&#x60; is stamped when an account&#39;s sync cycle started, and a slow cycle writes its rows after a faster cycle that started later, so &#x60;syncedAt&#x60; can go backwards between consecutive entries. Do not sort, filter or resume on it. The cursor is the only stable position, and it is opaque: pass it back verbatim, and do not parse, construct or compare cursors. **&#x60;hasMore: false&#x60; does not mean the feed ended.** This stream has no end and &#x60;nextCursor&#x60; is never null. &#x60;hasMore: true&#x60; means more changes are already waiting, so call again straight away. &#x60;hasMore: false&#x60; means you are caught up: keep the cursor and poll again on your normal interval. **The newest changes settle before they are served.** The feed deliberately holds back its last few seconds of writes, so that a row can never become visible behind a cursor you have already advanced past. A read issued the instant an &#x60;analytics.synced&#x60; webhook lands will therefore often return an empty page for that account. Do not read an empty page as \&quot;nothing changed\&quot;: poll again with the SAME cursor you last used rather than advancing. **Repeats inside one instant.** A sync cycle occasionally records the same post twice at the same feed position. When that happens the feed delivers one of those rows, not both. Measured over a day of production traffic, about 1.3% of rows fall in such a group and 99.4% of those groups are identical rows, so this is far more often deduplication than loss. Metrics are absolute values rather than increments, so a later entry for the same post supersedes an earlier one. **Retention is 7 days.** Changes older than that leave the feed. A cursor older than 6 days is rejected with a &#x60;400&#x60; (a day of margin, because expiry is lazy). Recover by re-bootstrapping from &#x60;GET /v1/analytics&#x60; and taking a fresh cursor from a call to this endpoint with no &#x60;cursor&#x60;. A consumer that polls at least daily never reaches this. Pairs with the &#x60;analytics.synced&#x60; webhook, so changes can be read on notification instead of on a timer. That event carries no cursor of its own: keep using the &#x60;nextCursor&#x60; this endpoint gave you. Requires the same analytics access as &#x60;GET /v1/analytics&#x60;, and shares the stricter per-second rate-limit window applied to analytics endpoints.
59
+ # Cursor feed of the analytics snapshots that CHANGED, across every account you can read, in one paginated stream. Built for integrations that would otherwise call &#x60;GET /v1/analytics&#x60; once per connected account. Each page carries changes from many accounts at once, so your call count scales with how much actually changed rather than with how many accounts you have. Measured against a fleet of roughly 1,600 connected accounts: about 1,599 per-account analytics calls an hour became about 205 delta calls an hour, a 7.8x reduction. **Bootstrap once, then stay in sync.** Take the cursor FIRST: call this endpoint with NO &#x60;cursor&#x60; and it answers with an empty &#x60;data&#x60; array plus the feed&#39;s current position in &#x60;nextCursor&#x60;. Then load your baseline from &#x60;GET /v1/analytics&#x60;, the historical endpoint, because this one is a rolling 7-day change log and cannot replay history. Then resume from the cursor you took before the baseline. Taking the cursor afterwards instead drops every change that lands while the baseline is loading: it is in neither the row you already read nor the feed you resume behind it. The overlap this order creates is safe, because metrics are absolute values rather than increments, so draining it leaves every post on its newest value. &#x60;nextCursor&#x60; is present on every response, empty pages included, so you always have something to advance with. **Ordering.** Entries come back oldest first, in the order the feed received them. That order is NOT &#x60;syncedAt&#x60;: &#x60;syncedAt&#x60; is stamped when an account&#39;s sync cycle started, and a slow cycle writes its rows after a faster cycle that started later, so &#x60;syncedAt&#x60; can go backwards between consecutive entries. Do not sort, filter or resume on it. The cursor is the only stable position, and it is opaque: pass it back verbatim, and do not parse, construct or compare cursors. **&#x60;hasMore: false&#x60; does not mean the feed ended.** This stream has no end and &#x60;nextCursor&#x60; is never null. &#x60;hasMore: true&#x60; means more changes are already waiting, so call again straight away. &#x60;hasMore: false&#x60; means you are caught up: keep the cursor and poll again on your normal interval. **The newest changes settle before they are served.** The feed deliberately holds back its last few seconds of writes, so that a row can never become visible behind a cursor you have already advanced past. A read issued the instant an &#x60;analytics.synced&#x60; webhook lands will therefore often return an empty page for that account. Do not read an empty page as \&quot;nothing changed\&quot;: poll again with the SAME cursor you last used rather than advancing. **Repeats inside one instant.** A sync cycle occasionally records the same post twice at the same feed position. When that happens the feed delivers one of those rows, not both. Measured over a day of production traffic, about 1.3% of rows fall in such a group and 99.4% of those groups are identical rows, so this is far more often deduplication than loss. Metrics are absolute values rather than increments, so a later entry for the same post supersedes an earlier one. **Retention is 7 days.** Changes older than that leave the feed. A cursor older than 6 days is rejected with a &#x60;400&#x60; (a day of margin, because expiry is lazy). Recover the same way you bootstrapped: take a fresh cursor from a call to this endpoint with no &#x60;cursor&#x60;, then re-load from &#x60;GET /v1/analytics&#x60;, then resume from that cursor. A consumer that polls at least daily never reaches this. Pairs with the &#x60;analytics.synced&#x60; webhook, so changes can be read on notification instead of on a timer. That event carries no cursor of its own: keep using the &#x60;nextCursor&#x60; this endpoint gave you. Requires the same analytics access as &#x60;GET /v1/analytics&#x60;, and shares the stricter per-second rate-limit window applied to analytics endpoints.
60
60
  # @param [Hash] opts the optional parameters
61
61
  # @option opts [String] :cursor Opaque cursor from a previous response&#39;s &#x60;nextCursor&#x60;. Omit it to start from now: the response is then an empty page carrying the feed&#39;s current position. Rejected with a &#x60;400&#x60; when malformed, or when older than the retention window.
62
62
  # @option opts [Integer] :limit Page size. Out-of-range values are a 400, never a silent clamp.
@@ -14,16 +14,16 @@ require 'spec_helper'
14
14
  require 'json'
15
15
  require 'date'
16
16
 
17
- # Unit tests for Zernio::Conversation
17
+ # Unit tests for Zernio::InboxWebhookConversationDetail
18
18
  # Automatically generated by openapi-generator (https://openapi-generator.tech)
19
19
  # Please update as you see appropriate
20
- describe Zernio::Conversation do
21
- #let(:instance) { Zernio::Conversation.new }
20
+ describe Zernio::InboxWebhookConversationDetail do
21
+ #let(:instance) { Zernio::InboxWebhookConversationDetail.new }
22
22
 
23
- describe 'test an instance of Conversation' do
24
- it 'should create an instance of Conversation' do
23
+ describe 'test an instance of InboxWebhookConversationDetail' do
24
+ it 'should create an instance of InboxWebhookConversationDetail' do
25
25
  # uncomment below to test the instance creation
26
- #expect(instance).to be_instance_of(Zernio::Conversation)
26
+ #expect(instance).to be_instance_of(Zernio::InboxWebhookConversationDetail)
27
27
  end
28
28
  end
29
29
 
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: late-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.891
4
+ version: 0.0.893
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenAPI-Generator
@@ -309,7 +309,6 @@ files:
309
309
  - docs/ConnectedApp.md
310
310
  - docs/ConnectedAppsApi.md
311
311
  - docs/ContactsApi.md
312
- - docs/Conversation.md
313
312
  - docs/ConversionAction.md
314
313
  - docs/ConversionActionTagSnippetsInner.md
315
314
  - docs/ConversionDestination.md
@@ -997,6 +996,7 @@ files:
997
996
  - docs/InboxMessageEditHistoryEntry.md
998
997
  - docs/InboxWebhookAccount.md
999
998
  - docs/InboxWebhookConversation.md
999
+ - docs/InboxWebhookConversationDetail.md
1000
1000
  - docs/InboxWebhookMessage.md
1001
1001
  - docs/InboxWebhookMessageAttachmentsInner.md
1002
1002
  - docs/InboxWebhookMessageSender.md
@@ -1938,7 +1938,6 @@ files:
1938
1938
  - docs/WebhookPayloadConversationControlChanged.md
1939
1939
  - docs/WebhookPayloadConversationControlChangedControl.md
1940
1940
  - docs/WebhookPayloadConversationStarted.md
1941
- - docs/WebhookPayloadConversationStartedConversation.md
1942
1941
  - docs/WebhookPayloadExternalPost.md
1943
1942
  - docs/WebhookPayloadLead.md
1944
1943
  - docs/WebhookPayloadLeadAccount.md
@@ -2360,7 +2359,6 @@ files:
2360
2359
  - lib/zernio-sdk/models/connected.rb
2361
2360
  - lib/zernio-sdk/models/connected_account.rb
2362
2361
  - lib/zernio-sdk/models/connected_app.rb
2363
- - lib/zernio-sdk/models/conversation.rb
2364
2362
  - lib/zernio-sdk/models/conversion_action.rb
2365
2363
  - lib/zernio-sdk/models/conversion_action_tag_snippets_inner.rb
2366
2364
  - lib/zernio-sdk/models/conversion_destination.rb
@@ -3036,6 +3034,7 @@ files:
3036
3034
  - lib/zernio-sdk/models/inbox_message_edit_history_entry.rb
3037
3035
  - lib/zernio-sdk/models/inbox_webhook_account.rb
3038
3036
  - lib/zernio-sdk/models/inbox_webhook_conversation.rb
3037
+ - lib/zernio-sdk/models/inbox_webhook_conversation_detail.rb
3039
3038
  - lib/zernio-sdk/models/inbox_webhook_message.rb
3040
3039
  - lib/zernio-sdk/models/inbox_webhook_message_attachments_inner.rb
3041
3040
  - lib/zernio-sdk/models/inbox_webhook_message_sender.rb
@@ -3950,7 +3949,6 @@ files:
3950
3949
  - lib/zernio-sdk/models/webhook_payload_conversation_control_changed.rb
3951
3950
  - lib/zernio-sdk/models/webhook_payload_conversation_control_changed_control.rb
3952
3951
  - lib/zernio-sdk/models/webhook_payload_conversation_started.rb
3953
- - lib/zernio-sdk/models/webhook_payload_conversation_started_conversation.rb
3954
3952
  - lib/zernio-sdk/models/webhook_payload_external_post.rb
3955
3953
  - lib/zernio-sdk/models/webhook_payload_lead.rb
3956
3954
  - lib/zernio-sdk/models/webhook_payload_lead_account.rb
@@ -4358,7 +4356,6 @@ files:
4358
4356
  - spec/models/connected_account_spec.rb
4359
4357
  - spec/models/connected_app_spec.rb
4360
4358
  - spec/models/connected_spec.rb
4361
- - spec/models/conversation_spec.rb
4362
4359
  - spec/models/conversion_action_spec.rb
4363
4360
  - spec/models/conversion_action_tag_snippets_inner_spec.rb
4364
4361
  - spec/models/conversion_destination_spec.rb
@@ -5033,6 +5030,7 @@ files:
5033
5030
  - spec/models/inbox_message_edit_attachment_spec.rb
5034
5031
  - spec/models/inbox_message_edit_history_entry_spec.rb
5035
5032
  - spec/models/inbox_webhook_account_spec.rb
5033
+ - spec/models/inbox_webhook_conversation_detail_spec.rb
5036
5034
  - spec/models/inbox_webhook_conversation_spec.rb
5037
5035
  - spec/models/inbox_webhook_message_attachments_inner_spec.rb
5038
5036
  - spec/models/inbox_webhook_message_sender_instagram_profile_spec.rb
@@ -5946,7 +5944,6 @@ files:
5946
5944
  - spec/models/webhook_payload_comment_spec.rb
5947
5945
  - spec/models/webhook_payload_conversation_control_changed_control_spec.rb
5948
5946
  - spec/models/webhook_payload_conversation_control_changed_spec.rb
5949
- - spec/models/webhook_payload_conversation_started_conversation_spec.rb
5950
5947
  - spec/models/webhook_payload_conversation_started_spec.rb
5951
5948
  - spec/models/webhook_payload_external_post_spec.rb
5952
5949
  - spec/models/webhook_payload_lead_account_spec.rb
@@ -6067,7 +6064,7 @@ files:
6067
6064
  - spec/models/you_tube_video_retention_response_retention_curve_inner_spec.rb
6068
6065
  - spec/models/you_tube_video_retention_response_spec.rb
6069
6066
  - spec/spec_helper.rb
6070
- - zernio-sdk-0.0.891.gem
6067
+ - zernio-sdk-0.0.893.gem
6071
6068
  - zernio-sdk.gemspec
6072
6069
  homepage: https://openapi-generator.tech
6073
6070
  licenses:
@@ -6941,7 +6938,6 @@ test_files:
6941
6938
  - spec/models/list_inbox_conversation_analytics200_response_spec.rb
6942
6939
  - spec/models/targeting_spec_excluded_locations_places_inner_spec.rb
6943
6940
  - spec/models/list_high_demand_periods200_response_spec.rb
6944
- - spec/models/conversation_spec.rb
6945
6941
  - spec/models/create_voice_call200_response_spec.rb
6946
6942
  - spec/models/create_standalone_ad_request_dynamic_creative_spec.rb
6947
6943
  - spec/models/inbox_webhook_message_sender_instagram_profile_spec.rb
@@ -7751,6 +7747,7 @@ test_files:
7751
7747
  - spec/models/get_whats_app_sdk_config200_response_spec.rb
7752
7748
  - spec/models/whats_app_carousel_component_cards_inner_spec.rb
7753
7749
  - spec/models/get_inbox_conversation_messages200_response_messages_inner_attachments_inner_spec.rb
7750
+ - spec/models/inbox_webhook_conversation_detail_spec.rb
7754
7751
  - spec/models/validate_post_request_spec.rb
7755
7752
  - spec/models/list_users200_response_spec.rb
7756
7753
  - spec/models/ad_keyword_metrics_spec.rb
@@ -8023,7 +8020,6 @@ test_files:
8023
8020
  - spec/models/webhook_payload_call_received_spec.rb
8024
8021
  - spec/models/update_discord_settings200_response_account_spec.rb
8025
8022
  - spec/models/get_whats_app_business_profile200_response_spec.rb
8026
- - spec/models/webhook_payload_conversation_started_conversation_spec.rb
8027
8023
  - spec/models/get_inbox_conversation_messages200_response_spec.rb
8028
8024
  - spec/models/get_google_business_reviews200_response_spec.rb
8029
8025
  - spec/models/list_whats_app_flow_versions200_response_spec.rb
@@ -1,34 +0,0 @@
1
- # Zernio::WebhookPayloadConversationStartedConversation
2
-
3
- ## Properties
4
-
5
- | Name | Type | Description | Notes |
6
- | ---- | ---- | ----------- | ----- |
7
- | **id** | **String** | Internal conversation ID | |
8
- | **platform** | **String** | | |
9
- | **platform_conversation_id** | **String** | | |
10
- | **participant_id** | **String** | Contact&#39;s platform identifier (IGSID, PSID, wa_id, etc.) | [optional] |
11
- | **participant_name** | **String** | | |
12
- | **participant_username** | **String** | Contact&#39;s handle when the platform exposes one | [optional] |
13
- | **participant_picture** | **String** | | [optional] |
14
- | **status** | **String** | | |
15
- | **contact_id** | **String** | Zernio CRM Contact ID for the participant, when one exists. Resolved by joining &#x60;participantId&#x60; to the ContactChannel collection (same join used by message.*, reaction.received, and call.* webhooks). Best-effort: omitted when no channel matches or &#x60;participantId&#x60; is absent. Lets integrators seed the CRM straight from &#x60;conversation.started&#x60; without waiting for the first &#x60;message.*&#x60; event. | [optional] |
16
-
17
- ## Example
18
-
19
- ```ruby
20
- require 'zernio-sdk'
21
-
22
- instance = Zernio::WebhookPayloadConversationStartedConversation.new(
23
- id: null,
24
- platform: null,
25
- platform_conversation_id: null,
26
- participant_id: null,
27
- participant_name: null,
28
- participant_username: null,
29
- participant_picture: null,
30
- status: null,
31
- contact_id: null
32
- )
33
- ```
34
-
@@ -1,334 +0,0 @@
1
- =begin
2
- #Zernio API
3
-
4
- #API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal. Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema).
5
-
6
- The version of the OpenAPI document: 1.0.4
7
- Contact: support@zernio.com
8
- Generated by: https://openapi-generator.tech
9
- Generator version: 7.19.0
10
-
11
- =end
12
-
13
- require 'date'
14
- require 'time'
15
-
16
- module Zernio
17
- class WebhookPayloadConversationStartedConversation < ApiModelBase
18
- # Internal conversation ID
19
- attr_accessor :id
20
-
21
- attr_accessor :platform
22
-
23
- attr_accessor :platform_conversation_id
24
-
25
- # Contact's platform identifier (IGSID, PSID, wa_id, etc.)
26
- attr_accessor :participant_id
27
-
28
- attr_accessor :participant_name
29
-
30
- # Contact's handle when the platform exposes one
31
- attr_accessor :participant_username
32
-
33
- attr_accessor :participant_picture
34
-
35
- attr_accessor :status
36
-
37
- # Zernio CRM Contact ID for the participant, when one exists. Resolved by joining `participantId` to the ContactChannel collection (same join used by message.*, reaction.received, and call.* webhooks). Best-effort: omitted when no channel matches or `participantId` is absent. Lets integrators seed the CRM straight from `conversation.started` without waiting for the first `message.*` event.
38
- attr_accessor :contact_id
39
-
40
- class EnumAttributeValidator
41
- attr_reader :datatype
42
- attr_reader :allowable_values
43
-
44
- def initialize(datatype, allowable_values)
45
- @allowable_values = allowable_values.map do |value|
46
- case datatype.to_s
47
- when /Integer/i
48
- value.to_i
49
- when /Float/i
50
- value.to_f
51
- else
52
- value
53
- end
54
- end
55
- end
56
-
57
- def valid?(value)
58
- !value || allowable_values.include?(value)
59
- end
60
- end
61
-
62
- # Attribute mapping from ruby-style variable name to JSON key.
63
- def self.attribute_map
64
- {
65
- :'id' => :'id',
66
- :'platform' => :'platform',
67
- :'platform_conversation_id' => :'platformConversationId',
68
- :'participant_id' => :'participantId',
69
- :'participant_name' => :'participantName',
70
- :'participant_username' => :'participantUsername',
71
- :'participant_picture' => :'participantPicture',
72
- :'status' => :'status',
73
- :'contact_id' => :'contactId'
74
- }
75
- end
76
-
77
- # Returns attribute mapping this model knows about
78
- def self.acceptable_attribute_map
79
- attribute_map
80
- end
81
-
82
- # Returns all the JSON keys this model knows about
83
- def self.acceptable_attributes
84
- acceptable_attribute_map.values
85
- end
86
-
87
- # Attribute type mapping.
88
- def self.openapi_types
89
- {
90
- :'id' => :'String',
91
- :'platform' => :'String',
92
- :'platform_conversation_id' => :'String',
93
- :'participant_id' => :'String',
94
- :'participant_name' => :'String',
95
- :'participant_username' => :'String',
96
- :'participant_picture' => :'String',
97
- :'status' => :'String',
98
- :'contact_id' => :'String'
99
- }
100
- end
101
-
102
- # List of attributes with nullable: true
103
- def self.openapi_nullable
104
- Set.new([
105
- ])
106
- end
107
-
108
- # Initializes the object
109
- # @param [Hash] attributes Model attributes in the form of hash
110
- def initialize(attributes = {})
111
- if (!attributes.is_a?(Hash))
112
- fail ArgumentError, "The input argument (attributes) must be a hash in `Zernio::WebhookPayloadConversationStartedConversation` initialize method"
113
- end
114
-
115
- # check to see if the attribute exists and convert string to symbol for hash key
116
- acceptable_attribute_map = self.class.acceptable_attribute_map
117
- attributes = attributes.each_with_object({}) { |(k, v), h|
118
- if (!acceptable_attribute_map.key?(k.to_sym))
119
- fail ArgumentError, "`#{k}` is not a valid attribute in `Zernio::WebhookPayloadConversationStartedConversation`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
120
- end
121
- h[k.to_sym] = v
122
- }
123
-
124
- if attributes.key?(:'id')
125
- self.id = attributes[:'id']
126
- else
127
- self.id = nil
128
- end
129
-
130
- if attributes.key?(:'platform')
131
- self.platform = attributes[:'platform']
132
- else
133
- self.platform = nil
134
- end
135
-
136
- if attributes.key?(:'platform_conversation_id')
137
- self.platform_conversation_id = attributes[:'platform_conversation_id']
138
- else
139
- self.platform_conversation_id = nil
140
- end
141
-
142
- if attributes.key?(:'participant_id')
143
- self.participant_id = attributes[:'participant_id']
144
- end
145
-
146
- if attributes.key?(:'participant_name')
147
- self.participant_name = attributes[:'participant_name']
148
- else
149
- self.participant_name = nil
150
- end
151
-
152
- if attributes.key?(:'participant_username')
153
- self.participant_username = attributes[:'participant_username']
154
- end
155
-
156
- if attributes.key?(:'participant_picture')
157
- self.participant_picture = attributes[:'participant_picture']
158
- end
159
-
160
- if attributes.key?(:'status')
161
- self.status = attributes[:'status']
162
- else
163
- self.status = nil
164
- end
165
-
166
- if attributes.key?(:'contact_id')
167
- self.contact_id = attributes[:'contact_id']
168
- end
169
- end
170
-
171
- # Show invalid properties with the reasons. Usually used together with valid?
172
- # @return Array for valid properties with the reasons
173
- def list_invalid_properties
174
- warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
175
- invalid_properties = Array.new
176
- if @id.nil?
177
- invalid_properties.push('invalid value for "id", id cannot be nil.')
178
- end
179
-
180
- if @platform.nil?
181
- invalid_properties.push('invalid value for "platform", platform cannot be nil.')
182
- end
183
-
184
- if @platform_conversation_id.nil?
185
- invalid_properties.push('invalid value for "platform_conversation_id", platform_conversation_id cannot be nil.')
186
- end
187
-
188
- if @participant_name.nil?
189
- invalid_properties.push('invalid value for "participant_name", participant_name cannot be nil.')
190
- end
191
-
192
- if @status.nil?
193
- invalid_properties.push('invalid value for "status", status cannot be nil.')
194
- end
195
-
196
- invalid_properties
197
- end
198
-
199
- # Check to see if the all the properties in the model are valid
200
- # @return true if the model is valid
201
- def valid?
202
- warn '[DEPRECATED] the `valid?` method is obsolete'
203
- return false if @id.nil?
204
- return false if @platform.nil?
205
- platform_validator = EnumAttributeValidator.new('String', ["instagram", "facebook", "telegram", "whatsapp", "twitter", "reddit", "bluesky", "sms", "slack"])
206
- return false unless platform_validator.valid?(@platform)
207
- return false if @platform_conversation_id.nil?
208
- return false if @participant_name.nil?
209
- return false if @status.nil?
210
- status_validator = EnumAttributeValidator.new('String', ["active", "archived"])
211
- return false unless status_validator.valid?(@status)
212
- true
213
- end
214
-
215
- # Custom attribute writer method with validation
216
- # @param [Object] id Value to be assigned
217
- def id=(id)
218
- if id.nil?
219
- fail ArgumentError, 'id cannot be nil'
220
- end
221
-
222
- @id = id
223
- end
224
-
225
- # Custom attribute writer method checking allowed values (enum).
226
- # @param [Object] platform Object to be assigned
227
- def platform=(platform)
228
- validator = EnumAttributeValidator.new('String', ["instagram", "facebook", "telegram", "whatsapp", "twitter", "reddit", "bluesky", "sms", "slack"])
229
- unless validator.valid?(platform)
230
- fail ArgumentError, "invalid value for \"platform\", must be one of #{validator.allowable_values}."
231
- end
232
- @platform = platform
233
- end
234
-
235
- # Custom attribute writer method with validation
236
- # @param [Object] platform_conversation_id Value to be assigned
237
- def platform_conversation_id=(platform_conversation_id)
238
- if platform_conversation_id.nil?
239
- fail ArgumentError, 'platform_conversation_id cannot be nil'
240
- end
241
-
242
- @platform_conversation_id = platform_conversation_id
243
- end
244
-
245
- # Custom attribute writer method with validation
246
- # @param [Object] participant_name Value to be assigned
247
- def participant_name=(participant_name)
248
- if participant_name.nil?
249
- fail ArgumentError, 'participant_name cannot be nil'
250
- end
251
-
252
- @participant_name = participant_name
253
- end
254
-
255
- # Custom attribute writer method checking allowed values (enum).
256
- # @param [Object] status Object to be assigned
257
- def status=(status)
258
- validator = EnumAttributeValidator.new('String', ["active", "archived"])
259
- unless validator.valid?(status)
260
- fail ArgumentError, "invalid value for \"status\", must be one of #{validator.allowable_values}."
261
- end
262
- @status = status
263
- end
264
-
265
- # Checks equality by comparing each attribute.
266
- # @param [Object] Object to be compared
267
- def ==(o)
268
- return true if self.equal?(o)
269
- self.class == o.class &&
270
- id == o.id &&
271
- platform == o.platform &&
272
- platform_conversation_id == o.platform_conversation_id &&
273
- participant_id == o.participant_id &&
274
- participant_name == o.participant_name &&
275
- participant_username == o.participant_username &&
276
- participant_picture == o.participant_picture &&
277
- status == o.status &&
278
- contact_id == o.contact_id
279
- end
280
-
281
- # @see the `==` method
282
- # @param [Object] Object to be compared
283
- def eql?(o)
284
- self == o
285
- end
286
-
287
- # Calculates hash code according to all attributes.
288
- # @return [Integer] Hash code
289
- def hash
290
- [id, platform, platform_conversation_id, participant_id, participant_name, participant_username, participant_picture, status, contact_id].hash
291
- end
292
-
293
- # Builds the object from hash
294
- # @param [Hash] attributes Model attributes in the form of hash
295
- # @return [Object] Returns the model itself
296
- def self.build_from_hash(attributes)
297
- return nil unless attributes.is_a?(Hash)
298
- attributes = attributes.transform_keys(&:to_sym)
299
- transformed_hash = {}
300
- openapi_types.each_pair do |key, type|
301
- if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
302
- transformed_hash["#{key}"] = nil
303
- elsif type =~ /\AArray<(.*)>/i
304
- # check to ensure the input is an array given that the attribute
305
- # is documented as an array but the input is not
306
- if attributes[attribute_map[key]].is_a?(Array)
307
- transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
308
- end
309
- elsif !attributes[attribute_map[key]].nil?
310
- transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
311
- end
312
- end
313
- new(transformed_hash)
314
- end
315
-
316
- # Returns the object in the form of hash
317
- # @return [Hash] Returns the object in the form of hash
318
- def to_hash
319
- hash = {}
320
- self.class.attribute_map.each_pair do |attr, param|
321
- value = self.send(attr)
322
- if value.nil?
323
- is_nullable = self.class.openapi_nullable.include?(attr)
324
- next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
325
- end
326
-
327
- hash[param] = _to_hash(value)
328
- end
329
- hash
330
- end
331
-
332
- end
333
-
334
- end
@@ -1,92 +0,0 @@
1
- =begin
2
- #Zernio API
3
-
4
- #API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal. Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema).
5
-
6
- The version of the OpenAPI document: 1.0.4
7
- Contact: support@zernio.com
8
- Generated by: https://openapi-generator.tech
9
- Generator version: 7.19.0
10
-
11
- =end
12
-
13
- require 'spec_helper'
14
- require 'json'
15
- require 'date'
16
-
17
- # Unit tests for Zernio::WebhookPayloadConversationStartedConversation
18
- # Automatically generated by openapi-generator (https://openapi-generator.tech)
19
- # Please update as you see appropriate
20
- describe Zernio::WebhookPayloadConversationStartedConversation do
21
- #let(:instance) { Zernio::WebhookPayloadConversationStartedConversation.new }
22
-
23
- describe 'test an instance of WebhookPayloadConversationStartedConversation' do
24
- it 'should create an instance of WebhookPayloadConversationStartedConversation' do
25
- # uncomment below to test the instance creation
26
- #expect(instance).to be_instance_of(Zernio::WebhookPayloadConversationStartedConversation)
27
- end
28
- end
29
-
30
- describe 'test attribute "id"' do
31
- it 'should work' do
32
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
33
- end
34
- end
35
-
36
- describe 'test attribute "platform"' do
37
- it 'should work' do
38
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
39
- # validator = Petstore::EnumTest::EnumAttributeValidator.new('String', ["instagram", "facebook", "telegram", "whatsapp", "twitter", "reddit", "bluesky", "sms", "slack"])
40
- # validator.allowable_values.each do |value|
41
- # expect { instance.platform = value }.not_to raise_error
42
- # end
43
- end
44
- end
45
-
46
- describe 'test attribute "platform_conversation_id"' do
47
- it 'should work' do
48
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
49
- end
50
- end
51
-
52
- describe 'test attribute "participant_id"' do
53
- it 'should work' do
54
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
55
- end
56
- end
57
-
58
- describe 'test attribute "participant_name"' do
59
- it 'should work' do
60
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
61
- end
62
- end
63
-
64
- describe 'test attribute "participant_username"' do
65
- it 'should work' do
66
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
67
- end
68
- end
69
-
70
- describe 'test attribute "participant_picture"' do
71
- it 'should work' do
72
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
73
- end
74
- end
75
-
76
- describe 'test attribute "status"' do
77
- it 'should work' do
78
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
79
- # validator = Petstore::EnumTest::EnumAttributeValidator.new('String', ["active", "archived"])
80
- # validator.allowable_values.each do |value|
81
- # expect { instance.status = value }.not_to raise_error
82
- # end
83
- end
84
- end
85
-
86
- describe 'test attribute "contact_id"' do
87
- it 'should work' do
88
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
89
- end
90
- end
91
-
92
- end
Binary file