trycourier 6.5.0 → 6.7.0

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/README.md +1 -1
  4. data/lib/courier/models/create_journey_request.rb +16 -1
  5. data/lib/courier/models/digest_day_of_week.rb +21 -0
  6. data/lib/courier/models/digest_frequency.rb +21 -0
  7. data/lib/courier/models/journey_conditions_field.rb +11 -1
  8. data/lib/courier/models/journey_node.rb +17 -2
  9. data/lib/courier/models/journey_response.rb +14 -1
  10. data/lib/courier/models/topic_digest_category.rb +71 -0
  11. data/lib/courier/models/topic_digest_release_request.rb +35 -0
  12. data/lib/courier/models/topic_digest_request.rb +75 -0
  13. data/lib/courier/models/topic_digest_response.rb +66 -0
  14. data/lib/courier/models/topic_digest_schedule_request.rb +99 -0
  15. data/lib/courier/models/topic_digest_schedule_response.rb +111 -0
  16. data/lib/courier/models/users/preference_update_or_create_topic_params.rb +13 -1
  17. data/lib/courier/models/users/topic_preference.rb +17 -1
  18. data/lib/courier/models/workspace_preference_topic_create_request.rb +97 -1
  19. data/lib/courier/models/workspace_preference_topic_get_response.rb +9 -1
  20. data/lib/courier/models/workspace_preference_topic_replace_request.rb +15 -1
  21. data/lib/courier/models/workspace_preferences/topic_delete_digest_params.rb +28 -0
  22. data/lib/courier/models/workspace_preferences/topic_release_digest_params.rb +28 -0
  23. data/lib/courier/models.rb +16 -0
  24. data/lib/courier/resources/digests/schedules.rb +1 -1
  25. data/lib/courier/resources/journeys.rb +9 -2
  26. data/lib/courier/resources/workspace_preferences/topics.rb +77 -4
  27. data/lib/courier/resources/workspace_preferences.rb +0 -2
  28. data/lib/courier/version.rb +1 -1
  29. data/lib/courier.rb +10 -0
  30. data/rbi/courier/models/create_journey_request.rbi +19 -0
  31. data/rbi/courier/models/digest_day_of_week.rbi +25 -0
  32. data/rbi/courier/models/digest_frequency.rbi +25 -0
  33. data/rbi/courier/models/journey_node.rbi +12 -1
  34. data/rbi/courier/models/journey_response.rbi +12 -0
  35. data/rbi/courier/models/topic_digest_category.rbi +116 -0
  36. data/rbi/courier/models/topic_digest_release_request.rbi +51 -0
  37. data/rbi/courier/models/topic_digest_request.rbi +126 -0
  38. data/rbi/courier/models/topic_digest_response.rbi +98 -0
  39. data/rbi/courier/models/topic_digest_schedule_request.rbi +147 -0
  40. data/rbi/courier/models/topic_digest_schedule_response.rbi +175 -0
  41. data/rbi/courier/models/users/preference_update_or_create_topic_params.rbi +16 -0
  42. data/rbi/courier/models/users/topic_preference.rbi +27 -0
  43. data/rbi/courier/models/workspace_preference_topic_create_request.rbi +172 -0
  44. data/rbi/courier/models/workspace_preference_topic_get_response.rbi +13 -0
  45. data/rbi/courier/models/workspace_preference_topic_replace_request.rbi +25 -0
  46. data/rbi/courier/models/workspace_preferences/topic_delete_digest_params.rbi +48 -0
  47. data/rbi/courier/models/workspace_preferences/topic_release_digest_params.rbi +48 -0
  48. data/rbi/courier/models.rbi +16 -0
  49. data/rbi/courier/resources/digests/schedules.rbi +5 -2
  50. data/rbi/courier/resources/journeys.rbi +14 -0
  51. data/rbi/courier/resources/workspace_preferences/topics.rbi +80 -2
  52. data/rbi/courier/resources/workspace_preferences.rbi +0 -2
  53. data/sig/courier/models/create_journey_request.rbs +7 -0
  54. data/sig/courier/models/digest_day_of_week.rbs +26 -0
  55. data/sig/courier/models/digest_frequency.rbs +19 -0
  56. data/sig/courier/models/journey_response.rbs +5 -0
  57. data/sig/courier/models/topic_digest_category.rbs +57 -0
  58. data/sig/courier/models/topic_digest_release_request.rbs +17 -0
  59. data/sig/courier/models/topic_digest_request.rbs +52 -0
  60. data/sig/courier/models/topic_digest_response.rbs +58 -0
  61. data/sig/courier/models/topic_digest_schedule_request.rbs +80 -0
  62. data/sig/courier/models/topic_digest_schedule_response.rbs +96 -0
  63. data/sig/courier/models/users/preference_update_or_create_topic_params.rbs +5 -0
  64. data/sig/courier/models/users/topic_preference.rbs +7 -0
  65. data/sig/courier/models/workspace_preference_topic_create_request.rbs +50 -0
  66. data/sig/courier/models/workspace_preference_topic_get_response.rbs +5 -0
  67. data/sig/courier/models/workspace_preference_topic_replace_request.rbs +5 -0
  68. data/sig/courier/models/workspace_preferences/topic_delete_digest_params.rbs +30 -0
  69. data/sig/courier/models/workspace_preferences/topic_release_digest_params.rbs +34 -0
  70. data/sig/courier/models.rbs +16 -0
  71. data/sig/courier/resources/journeys.rbs +2 -0
  72. data/sig/courier/resources/workspace_preferences/topics.rbs +16 -0
  73. metadata +32 -2
@@ -0,0 +1,147 @@
1
+ # typed: strong
2
+
3
+ module Courier
4
+ module Models
5
+ class TopicDigestScheduleRequest < Courier::Internal::Type::BaseModel
6
+ OrHash =
7
+ T.type_alias do
8
+ T.any(Courier::TopicDigestScheduleRequest, Courier::Internal::AnyHash)
9
+ end
10
+
11
+ # How often a digest is delivered. `instant` delivers immediately without
12
+ # batching, and is the one value that takes no `time`.
13
+ sig { returns(Courier::DigestFrequency::OrSymbol) }
14
+ attr_accessor :frequency
15
+
16
+ # Required when `frequency` is `monthly`.
17
+ sig { returns(T.nilable(Integer)) }
18
+ attr_reader :day_of_month
19
+
20
+ sig { params(day_of_month: Integer).void }
21
+ attr_writer :day_of_month
22
+
23
+ # Required when `frequency` is `weekly`.
24
+ sig { returns(T.nilable(Courier::DigestDayOfWeek::OrSymbol)) }
25
+ attr_reader :day_of_week
26
+
27
+ sig { params(day_of_week: Courier::DigestDayOfWeek::OrSymbol).void }
28
+ attr_writer :day_of_week
29
+
30
+ # Required when `frequency` is `custom_days`.
31
+ sig { returns(T.nilable(T::Array[Courier::DigestDayOfWeek::OrSymbol])) }
32
+ attr_reader :days_of_week
33
+
34
+ sig do
35
+ params(days_of_week: T::Array[Courier::DigestDayOfWeek::OrSymbol]).void
36
+ end
37
+ attr_writer :days_of_week
38
+
39
+ # Whether the schedule is disabled.
40
+ sig { returns(T.nilable(T::Boolean)) }
41
+ attr_reader :disabled
42
+
43
+ sig { params(disabled: T::Boolean).void }
44
+ attr_writer :disabled
45
+
46
+ # The schedule recipients are placed on when they have not chosen one. Set this
47
+ # explicitly rather than relying on array position.
48
+ sig { returns(T.nilable(T::Boolean)) }
49
+ attr_reader :is_default
50
+
51
+ sig { params(is_default: T::Boolean).void }
52
+ attr_writer :is_default
53
+
54
+ # Identifier of an existing schedule to update. Omit when creating a new one.
55
+ sig { returns(T.nilable(String)) }
56
+ attr_reader :schedule_id
57
+
58
+ sig { params(schedule_id: String).void }
59
+ attr_writer :schedule_id
60
+
61
+ # 24-hour local delivery time, `HH:MM`. Required for every frequency except
62
+ # `instant`.
63
+ sig { returns(T.nilable(String)) }
64
+ attr_reader :time
65
+
66
+ sig { params(time: String).void }
67
+ attr_writer :time
68
+
69
+ # IANA timezone the `time` and day fields are expressed in, e.g.
70
+ # `America/New_York`. Absent means UTC. Delivery follows the same local wall-clock
71
+ # across daylight-saving changes.
72
+ sig { returns(T.nilable(String)) }
73
+ attr_reader :timezone
74
+
75
+ sig { params(timezone: String).void }
76
+ attr_writer :timezone
77
+
78
+ # One delivery cadence for a topic's digest. Supply `schedule_id` to update an
79
+ # existing schedule in place; omit it and one is assigned and returned. The
80
+ # `schedules` array is a full replacement, so a stored schedule absent from it is
81
+ # deleted along with its delivery rule.
82
+ #
83
+ # Updating by `schedule_id` replaces that schedule rather than merging into it:
84
+ # any field you leave out is cleared. Two of those change delivery silently — an
85
+ # omitted `timezone` reverts the schedule to UTC, and an omitted `is_default` can
86
+ # leave the topic with no default schedule, which is what recipients who have not
87
+ # chosen one fall back to. Restate every field you want to keep.
88
+ sig do
89
+ params(
90
+ frequency: Courier::DigestFrequency::OrSymbol,
91
+ day_of_month: Integer,
92
+ day_of_week: Courier::DigestDayOfWeek::OrSymbol,
93
+ days_of_week: T::Array[Courier::DigestDayOfWeek::OrSymbol],
94
+ disabled: T::Boolean,
95
+ is_default: T::Boolean,
96
+ schedule_id: String,
97
+ time: String,
98
+ timezone: String
99
+ ).returns(T.attached_class)
100
+ end
101
+ def self.new(
102
+ # How often a digest is delivered. `instant` delivers immediately without
103
+ # batching, and is the one value that takes no `time`.
104
+ frequency:,
105
+ # Required when `frequency` is `monthly`.
106
+ day_of_month: nil,
107
+ # Required when `frequency` is `weekly`.
108
+ day_of_week: nil,
109
+ # Required when `frequency` is `custom_days`.
110
+ days_of_week: nil,
111
+ # Whether the schedule is disabled.
112
+ disabled: nil,
113
+ # The schedule recipients are placed on when they have not chosen one. Set this
114
+ # explicitly rather than relying on array position.
115
+ is_default: nil,
116
+ # Identifier of an existing schedule to update. Omit when creating a new one.
117
+ schedule_id: nil,
118
+ # 24-hour local delivery time, `HH:MM`. Required for every frequency except
119
+ # `instant`.
120
+ time: nil,
121
+ # IANA timezone the `time` and day fields are expressed in, e.g.
122
+ # `America/New_York`. Absent means UTC. Delivery follows the same local wall-clock
123
+ # across daylight-saving changes.
124
+ timezone: nil
125
+ )
126
+ end
127
+
128
+ sig do
129
+ override.returns(
130
+ {
131
+ frequency: Courier::DigestFrequency::OrSymbol,
132
+ day_of_month: Integer,
133
+ day_of_week: Courier::DigestDayOfWeek::OrSymbol,
134
+ days_of_week: T::Array[Courier::DigestDayOfWeek::OrSymbol],
135
+ disabled: T::Boolean,
136
+ is_default: T::Boolean,
137
+ schedule_id: String,
138
+ time: String,
139
+ timezone: String
140
+ }
141
+ )
142
+ end
143
+ def to_hash
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,175 @@
1
+ # typed: strong
2
+
3
+ module Courier
4
+ module Models
5
+ class TopicDigestScheduleResponse < Courier::Internal::Type::BaseModel
6
+ OrHash =
7
+ T.type_alias do
8
+ T.any(
9
+ Courier::TopicDigestScheduleResponse,
10
+ Courier::Internal::AnyHash
11
+ )
12
+ end
13
+
14
+ # The schedule's identifier, assigned by the server. This is the value the
15
+ # `/digests/schedules/{schedule_id}` endpoints are keyed by.
16
+ #
17
+ # Two formats are in circulation and only one is safe to drop into a URL.
18
+ # Schedules created through the API are `sch_01m26xfcn3endt3nxy4e2kx2rh` and need
19
+ # no encoding. Schedules created in the Preferences Editor before that format are
20
+ # `sch/{uuid}` and contain a literal `/`, so they must be URL-encoded as
21
+ # `sch%2F{uuid}` — unencoded, the path does not match the route and the response
22
+ # is a bare `404` that reads like a broken endpoint. Existing ids are never
23
+ # migrated.
24
+ sig { returns(String) }
25
+ attr_accessor :schedule_id
26
+
27
+ # ISO-8601 timestamp of when the schedule was created.
28
+ sig { returns(T.nilable(String)) }
29
+ attr_reader :created
30
+
31
+ sig { params(created: String).void }
32
+ attr_writer :created
33
+
34
+ # Day of the month, 1-31.
35
+ sig { returns(T.nilable(Integer)) }
36
+ attr_reader :day_of_month
37
+
38
+ sig { params(day_of_month: Integer).void }
39
+ attr_writer :day_of_month
40
+
41
+ # A day of the week. Accepted case-insensitively, returned lowercase.
42
+ sig { returns(T.nilable(Courier::DigestDayOfWeek::TaggedSymbol)) }
43
+ attr_reader :day_of_week
44
+
45
+ sig { params(day_of_week: Courier::DigestDayOfWeek::OrSymbol).void }
46
+ attr_writer :day_of_week
47
+
48
+ sig do
49
+ returns(T.nilable(T::Array[Courier::DigestDayOfWeek::TaggedSymbol]))
50
+ end
51
+ attr_reader :days_of_week
52
+
53
+ sig do
54
+ params(days_of_week: T::Array[Courier::DigestDayOfWeek::OrSymbol]).void
55
+ end
56
+ attr_writer :days_of_week
57
+
58
+ # Whether the schedule is disabled.
59
+ sig { returns(T.nilable(T::Boolean)) }
60
+ attr_reader :disabled
61
+
62
+ sig { params(disabled: T::Boolean).void }
63
+ attr_writer :disabled
64
+
65
+ # Omitted for a stored schedule this enum cannot express. Those schedules never
66
+ # fire, but their `schedule_id` is still returned so the `/digests/*` endpoints
67
+ # remain reachable for them.
68
+ sig { returns(T.nilable(Courier::DigestFrequency::TaggedSymbol)) }
69
+ attr_reader :frequency
70
+
71
+ sig { params(frequency: Courier::DigestFrequency::OrSymbol).void }
72
+ attr_writer :frequency
73
+
74
+ # Whether this is the schedule recipients are placed on by default.
75
+ sig { returns(T.nilable(T::Boolean)) }
76
+ attr_reader :is_default
77
+
78
+ sig { params(is_default: T::Boolean).void }
79
+ attr_writer :is_default
80
+
81
+ # 24-hour local delivery time, `HH:MM`.
82
+ sig { returns(T.nilable(String)) }
83
+ attr_reader :time
84
+
85
+ sig { params(time: String).void }
86
+ attr_writer :time
87
+
88
+ # IANA timezone the schedule is expressed in. Absent means UTC.
89
+ sig { returns(T.nilable(String)) }
90
+ attr_reader :timezone
91
+
92
+ sig { params(timezone: String).void }
93
+ attr_writer :timezone
94
+
95
+ # ISO-8601 timestamp of the last update.
96
+ sig { returns(T.nilable(String)) }
97
+ attr_reader :updated
98
+
99
+ sig { params(updated: String).void }
100
+ attr_writer :updated
101
+
102
+ # A delivery cadence for a topic's digest, with its assigned id.
103
+ sig do
104
+ params(
105
+ schedule_id: String,
106
+ created: String,
107
+ day_of_month: Integer,
108
+ day_of_week: Courier::DigestDayOfWeek::OrSymbol,
109
+ days_of_week: T::Array[Courier::DigestDayOfWeek::OrSymbol],
110
+ disabled: T::Boolean,
111
+ frequency: Courier::DigestFrequency::OrSymbol,
112
+ is_default: T::Boolean,
113
+ time: String,
114
+ timezone: String,
115
+ updated: String
116
+ ).returns(T.attached_class)
117
+ end
118
+ def self.new(
119
+ # The schedule's identifier, assigned by the server. This is the value the
120
+ # `/digests/schedules/{schedule_id}` endpoints are keyed by.
121
+ #
122
+ # Two formats are in circulation and only one is safe to drop into a URL.
123
+ # Schedules created through the API are `sch_01m26xfcn3endt3nxy4e2kx2rh` and need
124
+ # no encoding. Schedules created in the Preferences Editor before that format are
125
+ # `sch/{uuid}` and contain a literal `/`, so they must be URL-encoded as
126
+ # `sch%2F{uuid}` — unencoded, the path does not match the route and the response
127
+ # is a bare `404` that reads like a broken endpoint. Existing ids are never
128
+ # migrated.
129
+ schedule_id:,
130
+ # ISO-8601 timestamp of when the schedule was created.
131
+ created: nil,
132
+ # Day of the month, 1-31.
133
+ day_of_month: nil,
134
+ # A day of the week. Accepted case-insensitively, returned lowercase.
135
+ day_of_week: nil,
136
+ days_of_week: nil,
137
+ # Whether the schedule is disabled.
138
+ disabled: nil,
139
+ # Omitted for a stored schedule this enum cannot express. Those schedules never
140
+ # fire, but their `schedule_id` is still returned so the `/digests/*` endpoints
141
+ # remain reachable for them.
142
+ frequency: nil,
143
+ # Whether this is the schedule recipients are placed on by default.
144
+ is_default: nil,
145
+ # 24-hour local delivery time, `HH:MM`.
146
+ time: nil,
147
+ # IANA timezone the schedule is expressed in. Absent means UTC.
148
+ timezone: nil,
149
+ # ISO-8601 timestamp of the last update.
150
+ updated: nil
151
+ )
152
+ end
153
+
154
+ sig do
155
+ override.returns(
156
+ {
157
+ schedule_id: String,
158
+ created: String,
159
+ day_of_month: Integer,
160
+ day_of_week: Courier::DigestDayOfWeek::TaggedSymbol,
161
+ days_of_week: T::Array[Courier::DigestDayOfWeek::TaggedSymbol],
162
+ disabled: T::Boolean,
163
+ frequency: Courier::DigestFrequency::TaggedSymbol,
164
+ is_default: T::Boolean,
165
+ time: String,
166
+ timezone: String,
167
+ updated: String
168
+ }
169
+ )
170
+ end
171
+ def to_hash
172
+ end
173
+ end
174
+ end
175
+ end
@@ -96,6 +96,14 @@ module Courier
96
96
  end
97
97
  attr_accessor :custom_routing
98
98
 
99
+ # Put this recipient on one of the topic's digest schedules. Send `null` to clear
100
+ # the choice and return them to the topic's default. Omit to leave an existing
101
+ # choice alone, unlike the routing fields, which this endpoint replaces. An id
102
+ # that is not an active schedule on the topic is rejected with a `400` before
103
+ # anything is written.
104
+ sig { returns(T.nilable(String)) }
105
+ attr_accessor :digest_schedule_id
106
+
99
107
  # Set to true to route this topic to the channels in custom_routing instead of the
100
108
  # topic's default routing.
101
109
  sig { returns(T.nilable(T::Boolean)) }
@@ -106,6 +114,7 @@ module Courier
106
114
  status: Courier::PreferenceStatus::OrSymbol,
107
115
  custom_routing:
108
116
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol]),
117
+ digest_schedule_id: T.nilable(String),
109
118
  has_custom_routing: T.nilable(T::Boolean)
110
119
  ).returns(T.attached_class)
111
120
  end
@@ -117,6 +126,12 @@ module Courier
117
126
  # The channels to deliver this topic on when has_custom_routing is true. One or
118
127
  # more of: direct_message, email, push, sms, webhook, inbox.
119
128
  custom_routing: nil,
129
+ # Put this recipient on one of the topic's digest schedules. Send `null` to clear
130
+ # the choice and return them to the topic's default. Omit to leave an existing
131
+ # choice alone, unlike the routing fields, which this endpoint replaces. An id
132
+ # that is not an active schedule on the topic is rejected with a `400` before
133
+ # anything is written.
134
+ digest_schedule_id: nil,
120
135
  # Set to true to route this topic to the channels in custom_routing instead of the
121
136
  # topic's default routing.
122
137
  has_custom_routing: nil
@@ -129,6 +144,7 @@ module Courier
129
144
  status: Courier::PreferenceStatus::OrSymbol,
130
145
  custom_routing:
131
146
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol]),
147
+ digest_schedule_id: T.nilable(String),
132
148
  has_custom_routing: T.nilable(T::Boolean)
133
149
  }
134
150
  )
@@ -38,6 +38,21 @@ module Courier
38
38
  end
39
39
  attr_accessor :custom_routing
40
40
 
41
+ # The digest schedule this recipient is on for the topic. Omitted rather than null
42
+ # when they have not chosen one, in which case the topic's default schedule
43
+ # applies. Ids come from the topic's digest configuration, returned on any read of
44
+ # the topic.
45
+ #
46
+ # Also omitted when the schedule they chose has since been deleted or disabled:
47
+ # the recipient is on the topic's default from that point on, which is how a send
48
+ # already resolves it, so the field reports what would actually be used rather
49
+ # than a dead id.
50
+ sig { returns(T.nilable(String)) }
51
+ attr_reader :digest_schedule_id
52
+
53
+ sig { params(digest_schedule_id: String).void }
54
+ attr_writer :digest_schedule_id
55
+
41
56
  # Whether the user has chosen specific delivery channels for this topic (listed in
42
57
  # custom_routing) rather than the topic's default routing.
43
58
  sig { returns(T.nilable(T::Boolean)) }
@@ -69,6 +84,7 @@ module Courier
69
84
  topic_name: String,
70
85
  custom_routing:
71
86
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol]),
87
+ digest_schedule_id: String,
72
88
  has_custom_routing: T.nilable(T::Boolean),
73
89
  section_id: String,
74
90
  section_name: String
@@ -90,6 +106,16 @@ module Courier
90
106
  # has_custom_routing is true. One or more of: direct_message, email, push, sms,
91
107
  # webhook, inbox.
92
108
  custom_routing: nil,
109
+ # The digest schedule this recipient is on for the topic. Omitted rather than null
110
+ # when they have not chosen one, in which case the topic's default schedule
111
+ # applies. Ids come from the topic's digest configuration, returned on any read of
112
+ # the topic.
113
+ #
114
+ # Also omitted when the schedule they chose has since been deleted or disabled:
115
+ # the recipient is on the topic's default from that point on, which is how a send
116
+ # already resolves it, so the field reports what would actually be used rather
117
+ # than a dead id.
118
+ digest_schedule_id: nil,
93
119
  # Whether the user has chosen specific delivery channels for this topic (listed in
94
120
  # custom_routing) rather than the topic's default routing.
95
121
  has_custom_routing: nil,
@@ -115,6 +141,7 @@ module Courier
115
141
  T.nilable(
116
142
  T::Array[Courier::ChannelClassification::TaggedSymbol]
117
143
  ),
144
+ digest_schedule_id: String,
118
145
  has_custom_routing: T.nilable(T::Boolean),
119
146
  section_id: String,
120
147
  section_name: String
@@ -40,6 +40,35 @@ module Courier
40
40
  sig { returns(T.nilable(String)) }
41
41
  attr_accessor :description
42
42
 
43
+ # A topic's digest, as supplied when the topic itself is created: the template
44
+ # that renders it, the cadences it delivers on, and how collected events are
45
+ # retained.
46
+ #
47
+ # Identical to `TopicDigestRequest`, which a replace uses, except that `schedules`
48
+ # is required — a topic being created has no stored schedules for an absent key to
49
+ # leave alone.
50
+ #
51
+ # Send `null` for the whole object to turn a digest off, which unlinks the
52
+ # template and removes its schedules. There is no `enabled` flag, and
53
+ # `schedules: []` is rejected, because both states are un-deliverable rather than
54
+ # merely off.
55
+ sig do
56
+ returns(
57
+ T.nilable(Courier::WorkspacePreferenceTopicCreateRequest::Digest)
58
+ )
59
+ end
60
+ attr_reader :digest
61
+
62
+ sig do
63
+ params(
64
+ digest:
65
+ T.nilable(
66
+ Courier::WorkspacePreferenceTopicCreateRequest::Digest::OrHash
67
+ )
68
+ ).void
69
+ end
70
+ attr_writer :digest
71
+
43
72
  # Whether to include a list-unsubscribe header on emails for this topic.
44
73
  sig { returns(T.nilable(T::Boolean)) }
45
74
  attr_accessor :include_unsubscribe_header
@@ -67,6 +96,10 @@ module Courier
67
96
  ]
68
97
  ),
69
98
  description: T.nilable(String),
99
+ digest:
100
+ T.nilable(
101
+ Courier::WorkspacePreferenceTopicCreateRequest::Digest::OrHash
102
+ ),
70
103
  include_unsubscribe_header: T.nilable(T::Boolean),
71
104
  routing_options:
72
105
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol]),
@@ -83,6 +116,19 @@ module Courier
83
116
  allowed_preferences: nil,
84
117
  # Optional description shown under the topic on the hosted preferences page.
85
118
  description: nil,
119
+ # A topic's digest, as supplied when the topic itself is created: the template
120
+ # that renders it, the cadences it delivers on, and how collected events are
121
+ # retained.
122
+ #
123
+ # Identical to `TopicDigestRequest`, which a replace uses, except that `schedules`
124
+ # is required — a topic being created has no stored schedules for an absent key to
125
+ # leave alone.
126
+ #
127
+ # Send `null` for the whole object to turn a digest off, which unlinks the
128
+ # template and removes its schedules. There is no `enabled` flag, and
129
+ # `schedules: []` is rejected, because both states are un-deliverable rather than
130
+ # merely off.
131
+ digest: nil,
86
132
  # Whether to include a list-unsubscribe header on emails for this topic.
87
133
  include_unsubscribe_header: nil,
88
134
  # Default channels delivered for this topic. Defaults to empty if omitted.
@@ -105,6 +151,8 @@ module Courier
105
151
  ]
106
152
  ),
107
153
  description: T.nilable(String),
154
+ digest:
155
+ T.nilable(Courier::WorkspacePreferenceTopicCreateRequest::Digest),
108
156
  include_unsubscribe_header: T.nilable(T::Boolean),
109
157
  routing_options:
110
158
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol]),
@@ -189,6 +237,130 @@ module Courier
189
237
  def self.values
190
238
  end
191
239
  end
240
+
241
+ class Digest < Courier::Internal::Type::BaseModel
242
+ OrHash =
243
+ T.type_alias do
244
+ T.any(
245
+ Courier::WorkspacePreferenceTopicCreateRequest::Digest,
246
+ Courier::Internal::AnyHash
247
+ )
248
+ end
249
+
250
+ # The cadences this digest delivers on.
251
+ #
252
+ # The array replaces the stored schedules wholesale, so a schedule you leave out
253
+ # of it is deleted along with its delivery rule. Omit the key entirely to leave
254
+ # the stored schedules untouched — useful for changing `template_id` or
255
+ # `categories` without restating every schedule.
256
+ #
257
+ # A digest must end up with at least one schedule, because one with none collects
258
+ # events into an instance that can never fire. So sending `[]` is always a `400`,
259
+ # and so is omitting the key on a topic that has no schedules stored yet.
260
+ #
261
+ # On **create** the key is required outright: a topic being created has nothing
262
+ # stored to leave alone, and the topic row is written before its digest, so
263
+ # rejecting it any later would leave the topic behind and let a retry duplicate
264
+ # it.
265
+ sig { returns(T::Array[Courier::TopicDigestScheduleRequest]) }
266
+ attr_accessor :schedules
267
+
268
+ # The notification template that renders the digest. A digest with no template
269
+ # collects nothing, so this is required.
270
+ sig { returns(String) }
271
+ attr_accessor :template_id
272
+
273
+ # Optional audience the digest is scoped to.
274
+ sig { returns(T.nilable(String)) }
275
+ attr_reader :audience_id
276
+
277
+ sig { params(audience_id: String).void }
278
+ attr_writer :audience_id
279
+
280
+ # Retention rules per category key. Defaults to a single `digest` category
281
+ # retaining `FIRST`.
282
+ sig { returns(T.nilable(T::Array[Courier::TopicDigestCategory])) }
283
+ attr_reader :categories
284
+
285
+ sig do
286
+ params(
287
+ categories: T::Array[Courier::TopicDigestCategory::OrHash]
288
+ ).void
289
+ end
290
+ attr_writer :categories
291
+
292
+ # Whether to deliver the digest even when nothing was collected.
293
+ sig { returns(T.nilable(T::Boolean)) }
294
+ attr_reader :trigger_empty
295
+
296
+ sig { params(trigger_empty: T::Boolean).void }
297
+ attr_writer :trigger_empty
298
+
299
+ # A topic's digest, as supplied when the topic itself is created: the template
300
+ # that renders it, the cadences it delivers on, and how collected events are
301
+ # retained.
302
+ #
303
+ # Identical to `TopicDigestRequest`, which a replace uses, except that `schedules`
304
+ # is required — a topic being created has no stored schedules for an absent key to
305
+ # leave alone.
306
+ #
307
+ # Send `null` for the whole object to turn a digest off, which unlinks the
308
+ # template and removes its schedules. There is no `enabled` flag, and
309
+ # `schedules: []` is rejected, because both states are un-deliverable rather than
310
+ # merely off.
311
+ sig do
312
+ params(
313
+ schedules: T::Array[Courier::TopicDigestScheduleRequest::OrHash],
314
+ template_id: String,
315
+ audience_id: String,
316
+ categories: T::Array[Courier::TopicDigestCategory::OrHash],
317
+ trigger_empty: T::Boolean
318
+ ).returns(T.attached_class)
319
+ end
320
+ def self.new(
321
+ # The cadences this digest delivers on.
322
+ #
323
+ # The array replaces the stored schedules wholesale, so a schedule you leave out
324
+ # of it is deleted along with its delivery rule. Omit the key entirely to leave
325
+ # the stored schedules untouched — useful for changing `template_id` or
326
+ # `categories` without restating every schedule.
327
+ #
328
+ # A digest must end up with at least one schedule, because one with none collects
329
+ # events into an instance that can never fire. So sending `[]` is always a `400`,
330
+ # and so is omitting the key on a topic that has no schedules stored yet.
331
+ #
332
+ # On **create** the key is required outright: a topic being created has nothing
333
+ # stored to leave alone, and the topic row is written before its digest, so
334
+ # rejecting it any later would leave the topic behind and let a retry duplicate
335
+ # it.
336
+ schedules:,
337
+ # The notification template that renders the digest. A digest with no template
338
+ # collects nothing, so this is required.
339
+ template_id:,
340
+ # Optional audience the digest is scoped to.
341
+ audience_id: nil,
342
+ # Retention rules per category key. Defaults to a single `digest` category
343
+ # retaining `FIRST`.
344
+ categories: nil,
345
+ # Whether to deliver the digest even when nothing was collected.
346
+ trigger_empty: nil
347
+ )
348
+ end
349
+
350
+ sig do
351
+ override.returns(
352
+ {
353
+ schedules: T::Array[Courier::TopicDigestScheduleRequest],
354
+ template_id: String,
355
+ audience_id: String,
356
+ categories: T::Array[Courier::TopicDigestCategory],
357
+ trigger_empty: T::Boolean
358
+ }
359
+ )
360
+ end
361
+ def to_hash
362
+ end
363
+ end
192
364
  end
193
365
  end
194
366
  end
@@ -65,6 +65,15 @@ module Courier
65
65
  sig { returns(T.nilable(String)) }
66
66
  attr_accessor :description
67
67
 
68
+ # A topic's digest configuration.
69
+ sig { returns(T.nilable(Courier::TopicDigestResponse)) }
70
+ attr_reader :digest
71
+
72
+ sig do
73
+ params(digest: T.nilable(Courier::TopicDigestResponse::OrHash)).void
74
+ end
75
+ attr_writer :digest
76
+
68
77
  # Id of the last updater.
69
78
  sig { returns(T.nilable(String)) }
70
79
  attr_accessor :updater
@@ -87,6 +96,7 @@ module Courier
87
96
  updated: String,
88
97
  creator: T.nilable(String),
89
98
  description: T.nilable(String),
99
+ digest: T.nilable(Courier::TopicDigestResponse::OrHash),
90
100
  updater: T.nilable(String)
91
101
  ).returns(T.attached_class)
92
102
  end
@@ -113,6 +123,8 @@ module Courier
113
123
  creator: nil,
114
124
  # Optional description shown under the topic on the hosted preferences page.
115
125
  description: nil,
126
+ # A topic's digest configuration.
127
+ digest: nil,
116
128
  # Id of the last updater.
117
129
  updater: nil
118
130
  )
@@ -137,6 +149,7 @@ module Courier
137
149
  updated: String,
138
150
  creator: T.nilable(String),
139
151
  description: T.nilable(String),
152
+ digest: T.nilable(Courier::TopicDigestResponse),
140
153
  updater: T.nilable(String)
141
154
  }
142
155
  )