trycourier 6.4.4 → 6.6.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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/README.md +1 -1
  4. data/lib/courier/models/digest_day_of_week.rb +21 -0
  5. data/lib/courier/models/digest_frequency.rb +21 -0
  6. data/lib/courier/models/email_footer.rb +114 -7
  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/topic_digest_category.rb +71 -0
  10. data/lib/courier/models/topic_digest_release_request.rb +35 -0
  11. data/lib/courier/models/topic_digest_request.rb +63 -0
  12. data/lib/courier/models/topic_digest_response.rb +66 -0
  13. data/lib/courier/models/topic_digest_schedule_request.rb +93 -0
  14. data/lib/courier/models/topic_digest_schedule_response.rb +103 -0
  15. data/lib/courier/models/users/preference_update_or_create_topic_params.rb +13 -1
  16. data/lib/courier/models/users/token_add_single_params.rb +13 -5
  17. data/lib/courier/models/users/token_update_params.rb +30 -4
  18. data/lib/courier/models/users/topic_preference.rb +12 -1
  19. data/lib/courier/models/users/user_token.rb +13 -5
  20. data/lib/courier/models/workspace_preference_topic_create_request.rb +15 -1
  21. data/lib/courier/models/workspace_preference_topic_get_response.rb +9 -1
  22. data/lib/courier/models/workspace_preference_topic_replace_request.rb +15 -1
  23. data/lib/courier/models/workspace_preferences/topic_delete_digest_params.rb +28 -0
  24. data/lib/courier/models/workspace_preferences/topic_release_digest_params.rb +28 -0
  25. data/lib/courier/models.rb +16 -0
  26. data/lib/courier/resources/digests/schedules.rb +1 -1
  27. data/lib/courier/resources/users/tokens.rb +1 -1
  28. data/lib/courier/resources/workspace_preferences/topics.rb +77 -4
  29. data/lib/courier/resources/workspace_preferences.rb +0 -2
  30. data/lib/courier/version.rb +1 -1
  31. data/lib/courier.rb +10 -0
  32. data/rbi/courier/models/digest_day_of_week.rbi +25 -0
  33. data/rbi/courier/models/digest_frequency.rbi +25 -0
  34. data/rbi/courier/models/email_footer.rbi +229 -7
  35. data/rbi/courier/models/journey_node.rbi +12 -1
  36. data/rbi/courier/models/topic_digest_category.rbi +116 -0
  37. data/rbi/courier/models/topic_digest_release_request.rbi +51 -0
  38. data/rbi/courier/models/topic_digest_request.rbi +95 -0
  39. data/rbi/courier/models/topic_digest_response.rbi +98 -0
  40. data/rbi/courier/models/topic_digest_schedule_request.rbi +141 -0
  41. data/rbi/courier/models/topic_digest_schedule_response.rbi +159 -0
  42. data/rbi/courier/models/users/preference_update_or_create_topic_params.rbi +16 -0
  43. data/rbi/courier/models/users/token_add_single_params.rbi +18 -6
  44. data/rbi/courier/models/users/token_update_params.rbi +59 -7
  45. data/rbi/courier/models/users/topic_preference.rbi +17 -0
  46. data/rbi/courier/models/users/user_token.rbi +18 -6
  47. data/rbi/courier/models/workspace_preference_topic_create_request.rbi +25 -0
  48. data/rbi/courier/models/workspace_preference_topic_get_response.rbi +13 -0
  49. data/rbi/courier/models/workspace_preference_topic_replace_request.rbi +25 -0
  50. data/rbi/courier/models/workspace_preferences/topic_delete_digest_params.rbi +48 -0
  51. data/rbi/courier/models/workspace_preferences/topic_release_digest_params.rbi +48 -0
  52. data/rbi/courier/models.rbi +16 -0
  53. data/rbi/courier/resources/digests/schedules.rbi +5 -2
  54. data/rbi/courier/resources/users/tokens.rbi +6 -2
  55. data/rbi/courier/resources/workspace_preferences/topics.rbi +72 -2
  56. data/rbi/courier/resources/workspace_preferences.rbi +0 -2
  57. data/sig/courier/models/digest_day_of_week.rbs +26 -0
  58. data/sig/courier/models/digest_frequency.rbs +19 -0
  59. data/sig/courier/models/email_footer.rbs +107 -5
  60. data/sig/courier/models/topic_digest_category.rbs +57 -0
  61. data/sig/courier/models/topic_digest_release_request.rbs +17 -0
  62. data/sig/courier/models/topic_digest_request.rbs +48 -0
  63. data/sig/courier/models/topic_digest_response.rbs +58 -0
  64. data/sig/courier/models/topic_digest_schedule_request.rbs +80 -0
  65. data/sig/courier/models/topic_digest_schedule_response.rbs +96 -0
  66. data/sig/courier/models/users/preference_update_or_create_topic_params.rbs +5 -0
  67. data/sig/courier/models/users/token_update_params.rbs +27 -4
  68. data/sig/courier/models/users/topic_preference.rbs +7 -0
  69. data/sig/courier/models/workspace_preference_topic_create_request.rbs +5 -0
  70. data/sig/courier/models/workspace_preference_topic_get_response.rbs +5 -0
  71. data/sig/courier/models/workspace_preference_topic_replace_request.rbs +5 -0
  72. data/sig/courier/models/workspace_preferences/topic_delete_digest_params.rbs +30 -0
  73. data/sig/courier/models/workspace_preferences/topic_release_digest_params.rbs +34 -0
  74. data/sig/courier/models.rbs +16 -0
  75. data/sig/courier/resources/workspace_preferences/topics.rbs +16 -0
  76. metadata +32 -2
data/lib/courier.rb CHANGED
@@ -94,6 +94,7 @@ require_relative "courier/models/workspace_preference_create_request"
94
94
  require_relative "courier/models/publish_preferences_request"
95
95
  require_relative "courier/models/workspace_preference_replace_request"
96
96
  require_relative "courier/models/workspace_preference_topic_create_request"
97
+ require_relative "courier/models/topic_digest_release_request"
97
98
  require_relative "courier/models/workspace_preference_topic_replace_request"
98
99
  require_relative "courier/models/airship_profile"
99
100
  require_relative "courier/models/airship_profile_audience"
@@ -175,6 +176,8 @@ require_relative "courier/models/check"
175
176
  require_relative "courier/models/default_preferences"
176
177
  require_relative "courier/models/device_type"
177
178
  require_relative "courier/models/digest_category"
179
+ require_relative "courier/models/digest_day_of_week"
180
+ require_relative "courier/models/digest_frequency"
178
181
  require_relative "courier/models/digest_instance"
179
182
  require_relative "courier/models/digest_instance_list_response"
180
183
  require_relative "courier/models/digests/schedule_list_instances_params"
@@ -421,6 +424,11 @@ require_relative "courier/models/tenant_update_params"
421
424
  require_relative "courier/models/text_style"
422
425
  require_relative "courier/models/timeouts"
423
426
  require_relative "courier/models/token"
427
+ require_relative "courier/models/topic_digest_category"
428
+ require_relative "courier/models/topic_digest_request"
429
+ require_relative "courier/models/topic_digest_response"
430
+ require_relative "courier/models/topic_digest_schedule_request"
431
+ require_relative "courier/models/topic_digest_schedule_response"
424
432
  require_relative "courier/models/translation_retrieve_params"
425
433
  require_relative "courier/models/translation_retrieve_response"
426
434
  require_relative "courier/models/translation_update_params"
@@ -473,7 +481,9 @@ require_relative "courier/models/workspace_preference_replace_params"
473
481
  require_relative "courier/models/workspace_preference_retrieve_params"
474
482
  require_relative "courier/models/workspace_preferences/topic_archive_params"
475
483
  require_relative "courier/models/workspace_preferences/topic_create_params"
484
+ require_relative "courier/models/workspace_preferences/topic_delete_digest_params"
476
485
  require_relative "courier/models/workspace_preferences/topic_list_params"
486
+ require_relative "courier/models/workspace_preferences/topic_release_digest_params"
477
487
  require_relative "courier/models/workspace_preferences/topic_replace_params"
478
488
  require_relative "courier/models/workspace_preferences/topic_retrieve_params"
479
489
  require_relative "courier/models/workspace_preference_topic_get_response"
@@ -0,0 +1,25 @@
1
+ # typed: strong
2
+
3
+ module Courier
4
+ module Models
5
+ # A day of the week. Accepted case-insensitively, returned lowercase.
6
+ module DigestDayOfWeek
7
+ extend Courier::Internal::Type::Enum
8
+
9
+ TaggedSymbol = T.type_alias { T.all(Symbol, Courier::DigestDayOfWeek) }
10
+ OrSymbol = T.type_alias { T.any(Symbol, String) }
11
+
12
+ SUNDAY = T.let(:sunday, Courier::DigestDayOfWeek::TaggedSymbol)
13
+ MONDAY = T.let(:monday, Courier::DigestDayOfWeek::TaggedSymbol)
14
+ TUESDAY = T.let(:tuesday, Courier::DigestDayOfWeek::TaggedSymbol)
15
+ WEDNESDAY = T.let(:wednesday, Courier::DigestDayOfWeek::TaggedSymbol)
16
+ THURSDAY = T.let(:thursday, Courier::DigestDayOfWeek::TaggedSymbol)
17
+ FRIDAY = T.let(:friday, Courier::DigestDayOfWeek::TaggedSymbol)
18
+ SATURDAY = T.let(:saturday, Courier::DigestDayOfWeek::TaggedSymbol)
19
+
20
+ sig { override.returns(T::Array[Courier::DigestDayOfWeek::TaggedSymbol]) }
21
+ def self.values
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # typed: strong
2
+
3
+ module Courier
4
+ module Models
5
+ # How often a digest is delivered. `instant` delivers immediately without
6
+ # batching, and is the one value that takes no `time`.
7
+ module DigestFrequency
8
+ extend Courier::Internal::Type::Enum
9
+
10
+ TaggedSymbol = T.type_alias { T.all(Symbol, Courier::DigestFrequency) }
11
+ OrSymbol = T.type_alias { T.any(Symbol, String) }
12
+
13
+ INSTANT = T.let(:instant, Courier::DigestFrequency::TaggedSymbol)
14
+ DAILY = T.let(:daily, Courier::DigestFrequency::TaggedSymbol)
15
+ WEEKDAYS = T.let(:weekdays, Courier::DigestFrequency::TaggedSymbol)
16
+ WEEKLY = T.let(:weekly, Courier::DigestFrequency::TaggedSymbol)
17
+ CUSTOM_DAYS = T.let(:custom_days, Courier::DigestFrequency::TaggedSymbol)
18
+ MONTHLY = T.let(:monthly, Courier::DigestFrequency::TaggedSymbol)
19
+
20
+ sig { override.returns(T::Array[Courier::DigestFrequency::TaggedSymbol]) }
21
+ def self.values
22
+ end
23
+ end
24
+ end
25
+ end
@@ -6,28 +6,250 @@ module Courier
6
6
  OrHash =
7
7
  T.type_alias { T.any(Courier::EmailFooter, Courier::Internal::AnyHash) }
8
8
 
9
- sig { returns(T.nilable(String)) }
10
- attr_accessor :content
11
-
12
9
  sig { returns(T.nilable(T::Boolean)) }
13
10
  attr_accessor :inherit_default
14
11
 
12
+ # The footer body, as markdown. This is the field the API returns and accepts; it
13
+ # is omitted entirely when no footer body is set. Sending null is accepted and
14
+ # treated as no footer body.
15
+ sig { returns(T.nilable(String)) }
16
+ attr_accessor :markdown
17
+
18
+ # Social links rendered in the email footer.
19
+ sig { returns(T.nilable(Courier::EmailFooter::Social)) }
20
+ attr_reader :social
21
+
22
+ sig do
23
+ params(social: T.nilable(Courier::EmailFooter::Social::OrHash)).void
24
+ end
25
+ attr_writer :social
26
+
15
27
  sig do
16
28
  params(
17
- content: T.nilable(String),
18
- inherit_default: T.nilable(T::Boolean)
29
+ inherit_default: T.nilable(T::Boolean),
30
+ markdown: T.nilable(String),
31
+ social: T.nilable(Courier::EmailFooter::Social::OrHash)
19
32
  ).returns(T.attached_class)
20
33
  end
21
- def self.new(content: nil, inherit_default: nil)
34
+ def self.new(
35
+ inherit_default: nil,
36
+ # The footer body, as markdown. This is the field the API returns and accepts; it
37
+ # is omitted entirely when no footer body is set. Sending null is accepted and
38
+ # treated as no footer body.
39
+ markdown: nil,
40
+ # Social links rendered in the email footer.
41
+ social: nil
42
+ )
22
43
  end
23
44
 
24
45
  sig do
25
46
  override.returns(
26
- { content: T.nilable(String), inherit_default: T.nilable(T::Boolean) }
47
+ {
48
+ inherit_default: T.nilable(T::Boolean),
49
+ markdown: T.nilable(String),
50
+ social: T.nilable(Courier::EmailFooter::Social)
51
+ }
27
52
  )
28
53
  end
29
54
  def to_hash
30
55
  end
56
+
57
+ class Social < Courier::Internal::Type::BaseModel
58
+ OrHash =
59
+ T.type_alias do
60
+ T.any(Courier::EmailFooter::Social, Courier::Internal::AnyHash)
61
+ end
62
+
63
+ sig { returns(T.nilable(Courier::EmailFooter::Social::Facebook)) }
64
+ attr_reader :facebook
65
+
66
+ sig do
67
+ params(
68
+ facebook: T.nilable(Courier::EmailFooter::Social::Facebook::OrHash)
69
+ ).void
70
+ end
71
+ attr_writer :facebook
72
+
73
+ sig { returns(T.nilable(Courier::EmailFooter::Social::Instagram)) }
74
+ attr_reader :instagram
75
+
76
+ sig do
77
+ params(
78
+ instagram:
79
+ T.nilable(Courier::EmailFooter::Social::Instagram::OrHash)
80
+ ).void
81
+ end
82
+ attr_writer :instagram
83
+
84
+ sig { returns(T.nilable(Courier::EmailFooter::Social::Linkedin)) }
85
+ attr_reader :linkedin
86
+
87
+ sig do
88
+ params(
89
+ linkedin: T.nilable(Courier::EmailFooter::Social::Linkedin::OrHash)
90
+ ).void
91
+ end
92
+ attr_writer :linkedin
93
+
94
+ sig { returns(T.nilable(Courier::EmailFooter::Social::Medium)) }
95
+ attr_reader :medium
96
+
97
+ sig do
98
+ params(
99
+ medium: T.nilable(Courier::EmailFooter::Social::Medium::OrHash)
100
+ ).void
101
+ end
102
+ attr_writer :medium
103
+
104
+ sig { returns(T.nilable(Courier::EmailFooter::Social::Twitter)) }
105
+ attr_reader :twitter
106
+
107
+ sig do
108
+ params(
109
+ twitter: T.nilable(Courier::EmailFooter::Social::Twitter::OrHash)
110
+ ).void
111
+ end
112
+ attr_writer :twitter
113
+
114
+ # Social links rendered in the email footer.
115
+ sig do
116
+ params(
117
+ facebook: T.nilable(Courier::EmailFooter::Social::Facebook::OrHash),
118
+ instagram:
119
+ T.nilable(Courier::EmailFooter::Social::Instagram::OrHash),
120
+ linkedin: T.nilable(Courier::EmailFooter::Social::Linkedin::OrHash),
121
+ medium: T.nilable(Courier::EmailFooter::Social::Medium::OrHash),
122
+ twitter: T.nilable(Courier::EmailFooter::Social::Twitter::OrHash)
123
+ ).returns(T.attached_class)
124
+ end
125
+ def self.new(
126
+ facebook: nil,
127
+ instagram: nil,
128
+ linkedin: nil,
129
+ medium: nil,
130
+ twitter: nil
131
+ )
132
+ end
133
+
134
+ sig do
135
+ override.returns(
136
+ {
137
+ facebook: T.nilable(Courier::EmailFooter::Social::Facebook),
138
+ instagram: T.nilable(Courier::EmailFooter::Social::Instagram),
139
+ linkedin: T.nilable(Courier::EmailFooter::Social::Linkedin),
140
+ medium: T.nilable(Courier::EmailFooter::Social::Medium),
141
+ twitter: T.nilable(Courier::EmailFooter::Social::Twitter)
142
+ }
143
+ )
144
+ end
145
+ def to_hash
146
+ end
147
+
148
+ class Facebook < Courier::Internal::Type::BaseModel
149
+ OrHash =
150
+ T.type_alias do
151
+ T.any(
152
+ Courier::EmailFooter::Social::Facebook,
153
+ Courier::Internal::AnyHash
154
+ )
155
+ end
156
+
157
+ sig { returns(T.nilable(String)) }
158
+ attr_accessor :url
159
+
160
+ sig { params(url: T.nilable(String)).returns(T.attached_class) }
161
+ def self.new(url: nil)
162
+ end
163
+
164
+ sig { override.returns({ url: T.nilable(String) }) }
165
+ def to_hash
166
+ end
167
+ end
168
+
169
+ class Instagram < Courier::Internal::Type::BaseModel
170
+ OrHash =
171
+ T.type_alias do
172
+ T.any(
173
+ Courier::EmailFooter::Social::Instagram,
174
+ Courier::Internal::AnyHash
175
+ )
176
+ end
177
+
178
+ sig { returns(T.nilable(String)) }
179
+ attr_accessor :url
180
+
181
+ sig { params(url: T.nilable(String)).returns(T.attached_class) }
182
+ def self.new(url: nil)
183
+ end
184
+
185
+ sig { override.returns({ url: T.nilable(String) }) }
186
+ def to_hash
187
+ end
188
+ end
189
+
190
+ class Linkedin < Courier::Internal::Type::BaseModel
191
+ OrHash =
192
+ T.type_alias do
193
+ T.any(
194
+ Courier::EmailFooter::Social::Linkedin,
195
+ Courier::Internal::AnyHash
196
+ )
197
+ end
198
+
199
+ sig { returns(T.nilable(String)) }
200
+ attr_accessor :url
201
+
202
+ sig { params(url: T.nilable(String)).returns(T.attached_class) }
203
+ def self.new(url: nil)
204
+ end
205
+
206
+ sig { override.returns({ url: T.nilable(String) }) }
207
+ def to_hash
208
+ end
209
+ end
210
+
211
+ class Medium < Courier::Internal::Type::BaseModel
212
+ OrHash =
213
+ T.type_alias do
214
+ T.any(
215
+ Courier::EmailFooter::Social::Medium,
216
+ Courier::Internal::AnyHash
217
+ )
218
+ end
219
+
220
+ sig { returns(T.nilable(String)) }
221
+ attr_accessor :url
222
+
223
+ sig { params(url: T.nilable(String)).returns(T.attached_class) }
224
+ def self.new(url: nil)
225
+ end
226
+
227
+ sig { override.returns({ url: T.nilable(String) }) }
228
+ def to_hash
229
+ end
230
+ end
231
+
232
+ class Twitter < Courier::Internal::Type::BaseModel
233
+ OrHash =
234
+ T.type_alias do
235
+ T.any(
236
+ Courier::EmailFooter::Social::Twitter,
237
+ Courier::Internal::AnyHash
238
+ )
239
+ end
240
+
241
+ sig { returns(T.nilable(String)) }
242
+ attr_accessor :url
243
+
244
+ sig { params(url: T.nilable(String)).returns(T.attached_class) }
245
+ def self.new(url: nil)
246
+ end
247
+
248
+ sig { override.returns({ url: T.nilable(String) }) }
249
+ def to_hash
250
+ end
251
+ end
252
+ end
31
253
  end
32
254
  end
33
255
  end
@@ -398,7 +398,18 @@ module Courier
398
398
 
399
399
  # Add the current event to a digest keyed by the given subscription topic. The
400
400
  # digest accumulates events and releases them on the schedule configured for the
401
- # topic.
401
+ # topic, using the notification template configured on that topic. This node's
402
+ # `type` value is `add-to-digest`.
403
+ #
404
+ # **The topic must have a template configured.** If the topic has no template when
405
+ # the first event reaches this node, the journey run fails immediately: the run is
406
+ # marked `ERROR`, no digest instance is created, and the journey does not continue
407
+ # past this node. Configure the topic's template before using the topic in a
408
+ # journey.
409
+ #
410
+ # If the journey run is scoped to a tenant, digests are kept separate per tenant:
411
+ # two runs for the same user under different tenants accumulate and release as
412
+ # separate digests, even on the same topic.
402
413
  sig do
403
414
  params(
404
415
  subscription_topic_id: String,
@@ -0,0 +1,116 @@
1
+ # typed: strong
2
+
3
+ module Courier
4
+ module Models
5
+ class TopicDigestCategory < Courier::Internal::Type::BaseModel
6
+ OrHash =
7
+ T.type_alias do
8
+ T.any(Courier::TopicDigestCategory, Courier::Internal::AnyHash)
9
+ end
10
+
11
+ # The key that identifies the category within the digest.
12
+ sig { returns(String) }
13
+ attr_accessor :category_key
14
+
15
+ # How many collected events are carried into the rendered digest. Defaults to 10.
16
+ #
17
+ # Events beyond the limit are discarded, not held back for the next digest: the
18
+ # release consumes everything collected so far and only `limit` of them appear.
19
+ # `retain` decides which ones those are.
20
+ sig { returns(T.nilable(Integer)) }
21
+ attr_reader :limit
22
+
23
+ sig { params(limit: Integer).void }
24
+ attr_writer :limit
25
+
26
+ # Which collected events survive the `limit`. `FIRST` and `LOWEST` keep the
27
+ # earliest or smallest; `LAST` and `HIGHEST` keep the latest or largest. Accepted
28
+ # case-insensitively, returned uppercase.
29
+ sig { returns(T.nilable(Courier::TopicDigestCategory::Retain::OrSymbol)) }
30
+ attr_reader :retain
31
+
32
+ sig do
33
+ params(retain: Courier::TopicDigestCategory::Retain::OrSymbol).void
34
+ end
35
+ attr_writer :retain
36
+
37
+ # The data key used to rank events. Required when `retain` is `HIGHEST` or
38
+ # `LOWEST`.
39
+ sig { returns(T.nilable(String)) }
40
+ attr_reader :sort_key
41
+
42
+ sig { params(sort_key: String).void }
43
+ attr_writer :sort_key
44
+
45
+ # How events collected under a category key are retained when a digest holds more
46
+ # than it will render.
47
+ sig do
48
+ params(
49
+ category_key: String,
50
+ limit: Integer,
51
+ retain: Courier::TopicDigestCategory::Retain::OrSymbol,
52
+ sort_key: String
53
+ ).returns(T.attached_class)
54
+ end
55
+ def self.new(
56
+ # The key that identifies the category within the digest.
57
+ category_key:,
58
+ # How many collected events are carried into the rendered digest. Defaults to 10.
59
+ #
60
+ # Events beyond the limit are discarded, not held back for the next digest: the
61
+ # release consumes everything collected so far and only `limit` of them appear.
62
+ # `retain` decides which ones those are.
63
+ limit: nil,
64
+ # Which collected events survive the `limit`. `FIRST` and `LOWEST` keep the
65
+ # earliest or smallest; `LAST` and `HIGHEST` keep the latest or largest. Accepted
66
+ # case-insensitively, returned uppercase.
67
+ retain: nil,
68
+ # The data key used to rank events. Required when `retain` is `HIGHEST` or
69
+ # `LOWEST`.
70
+ sort_key: nil
71
+ )
72
+ end
73
+
74
+ sig do
75
+ override.returns(
76
+ {
77
+ category_key: String,
78
+ limit: Integer,
79
+ retain: Courier::TopicDigestCategory::Retain::OrSymbol,
80
+ sort_key: String
81
+ }
82
+ )
83
+ end
84
+ def to_hash
85
+ end
86
+
87
+ # Which collected events survive the `limit`. `FIRST` and `LOWEST` keep the
88
+ # earliest or smallest; `LAST` and `HIGHEST` keep the latest or largest. Accepted
89
+ # case-insensitively, returned uppercase.
90
+ module Retain
91
+ extend Courier::Internal::Type::Enum
92
+
93
+ TaggedSymbol =
94
+ T.type_alias { T.all(Symbol, Courier::TopicDigestCategory::Retain) }
95
+ OrSymbol = T.type_alias { T.any(Symbol, String) }
96
+
97
+ FIRST =
98
+ T.let(:FIRST, Courier::TopicDigestCategory::Retain::TaggedSymbol)
99
+ LAST = T.let(:LAST, Courier::TopicDigestCategory::Retain::TaggedSymbol)
100
+ HIGHEST =
101
+ T.let(:HIGHEST, Courier::TopicDigestCategory::Retain::TaggedSymbol)
102
+ LOWEST =
103
+ T.let(:LOWEST, Courier::TopicDigestCategory::Retain::TaggedSymbol)
104
+ NONE = T.let(:NONE, Courier::TopicDigestCategory::Retain::TaggedSymbol)
105
+
106
+ sig do
107
+ override.returns(
108
+ T::Array[Courier::TopicDigestCategory::Retain::TaggedSymbol]
109
+ )
110
+ end
111
+ def self.values
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,51 @@
1
+ # typed: strong
2
+
3
+ module Courier
4
+ module Models
5
+ class TopicDigestReleaseRequest < Courier::Internal::Type::BaseModel
6
+ OrHash =
7
+ T.type_alias do
8
+ T.any(Courier::TopicDigestReleaseRequest, Courier::Internal::AnyHash)
9
+ end
10
+
11
+ # The recipient whose digest to release. Required: there is no "release everyone
12
+ # on this topic" form, because a whole-schedule flush already has its own endpoint
13
+ # and a body-shaped difference between one recipient and all of them is too easy
14
+ # to get wrong.
15
+ sig { returns(String) }
16
+ attr_accessor :user_id
17
+
18
+ # The recipient's tenant, when they were sent to as part of one -- the same value
19
+ # returned as `tenant_id` on a digest instance and sent as
20
+ # `message.context.tenant_id`. It is part of the held digest's key, so a tenanted
21
+ # recipient cannot be found without it. Omit for an ordinary recipient.
22
+ sig { returns(T.nilable(String)) }
23
+ attr_reader :tenant_id
24
+
25
+ sig { params(tenant_id: String).void }
26
+ attr_writer :tenant_id
27
+
28
+ # Which recipient's held digest to release.
29
+ sig do
30
+ params(user_id: String, tenant_id: String).returns(T.attached_class)
31
+ end
32
+ def self.new(
33
+ # The recipient whose digest to release. Required: there is no "release everyone
34
+ # on this topic" form, because a whole-schedule flush already has its own endpoint
35
+ # and a body-shaped difference between one recipient and all of them is too easy
36
+ # to get wrong.
37
+ user_id:,
38
+ # The recipient's tenant, when they were sent to as part of one -- the same value
39
+ # returned as `tenant_id` on a digest instance and sent as
40
+ # `message.context.tenant_id`. It is part of the held digest's key, so a tenanted
41
+ # recipient cannot be found without it. Omit for an ordinary recipient.
42
+ tenant_id: nil
43
+ )
44
+ end
45
+
46
+ sig { override.returns({ user_id: String, tenant_id: String }) }
47
+ def to_hash
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,95 @@
1
+ # typed: strong
2
+
3
+ module Courier
4
+ module Models
5
+ class TopicDigestRequest < Courier::Internal::Type::BaseModel
6
+ OrHash =
7
+ T.type_alias do
8
+ T.any(Courier::TopicDigestRequest, Courier::Internal::AnyHash)
9
+ end
10
+
11
+ # The cadences this digest delivers on. At least one is required: a digest with no
12
+ # schedule collects events into an instance that can never fire. Omitting the key
13
+ # on a replace leaves stored schedules untouched; sending `[]` is a `400`.
14
+ sig { returns(T::Array[Courier::TopicDigestScheduleRequest]) }
15
+ attr_accessor :schedules
16
+
17
+ # The notification template that renders the digest. A digest with no template
18
+ # collects nothing, so this is required.
19
+ sig { returns(String) }
20
+ attr_accessor :template_id
21
+
22
+ # Optional audience the digest is scoped to.
23
+ sig { returns(T.nilable(String)) }
24
+ attr_reader :audience_id
25
+
26
+ sig { params(audience_id: String).void }
27
+ attr_writer :audience_id
28
+
29
+ # Retention rules per category key. Defaults to a single `digest` category
30
+ # retaining `FIRST`.
31
+ sig { returns(T.nilable(T::Array[Courier::TopicDigestCategory])) }
32
+ attr_reader :categories
33
+
34
+ sig do
35
+ params(categories: T::Array[Courier::TopicDigestCategory::OrHash]).void
36
+ end
37
+ attr_writer :categories
38
+
39
+ # Whether to deliver the digest even when nothing was collected.
40
+ sig { returns(T.nilable(T::Boolean)) }
41
+ attr_reader :trigger_empty
42
+
43
+ sig { params(trigger_empty: T::Boolean).void }
44
+ attr_writer :trigger_empty
45
+
46
+ # A topic's digest configuration: the template that renders it, the cadences it
47
+ # delivers on, and how collected events are retained.
48
+ #
49
+ # Send `null` for the whole object to turn a digest off, which unlinks the
50
+ # template and removes its schedules. There is no `enabled` flag, and
51
+ # `schedules: []` is rejected, because both states are un-deliverable rather than
52
+ # merely off.
53
+ sig do
54
+ params(
55
+ schedules: T::Array[Courier::TopicDigestScheduleRequest::OrHash],
56
+ template_id: String,
57
+ audience_id: String,
58
+ categories: T::Array[Courier::TopicDigestCategory::OrHash],
59
+ trigger_empty: T::Boolean
60
+ ).returns(T.attached_class)
61
+ end
62
+ def self.new(
63
+ # The cadences this digest delivers on. At least one is required: a digest with no
64
+ # schedule collects events into an instance that can never fire. Omitting the key
65
+ # on a replace leaves stored schedules untouched; sending `[]` is a `400`.
66
+ schedules:,
67
+ # The notification template that renders the digest. A digest with no template
68
+ # collects nothing, so this is required.
69
+ template_id:,
70
+ # Optional audience the digest is scoped to.
71
+ audience_id: nil,
72
+ # Retention rules per category key. Defaults to a single `digest` category
73
+ # retaining `FIRST`.
74
+ categories: nil,
75
+ # Whether to deliver the digest even when nothing was collected.
76
+ trigger_empty: nil
77
+ )
78
+ end
79
+
80
+ sig do
81
+ override.returns(
82
+ {
83
+ schedules: T::Array[Courier::TopicDigestScheduleRequest],
84
+ template_id: String,
85
+ audience_id: String,
86
+ categories: T::Array[Courier::TopicDigestCategory],
87
+ trigger_empty: T::Boolean
88
+ }
89
+ )
90
+ end
91
+ def to_hash
92
+ end
93
+ end
94
+ end
95
+ end