trycourier 4.18.2 → 4.19.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/lib/courier/models/publish_preferences_request.rb +40 -0
  4. data/lib/courier/models/users/bulk_preference_topic.rb +59 -0
  5. data/lib/courier/models/users/preference_bulk_replace_params.rb +93 -0
  6. data/lib/courier/models/users/preference_bulk_replace_response.rb +27 -0
  7. data/lib/courier/models/users/preference_bulk_update_params.rb +92 -0
  8. data/lib/courier/models/users/preference_bulk_update_response.rb +48 -0
  9. data/lib/courier/models/workspace_preference_create_request.rb +9 -1
  10. data/lib/courier/models/workspace_preference_get_response.rb +9 -1
  11. data/lib/courier/models/workspace_preference_publish_params.rb +1 -1
  12. data/lib/courier/models/workspace_preference_replace_request.rb +13 -1
  13. data/lib/courier/models/workspace_preference_topic_create_request.rb +9 -1
  14. data/lib/courier/models/workspace_preference_topic_get_response.rb +9 -1
  15. data/lib/courier/models/workspace_preference_topic_replace_request.rb +13 -1
  16. data/lib/courier/models.rb +2 -0
  17. data/lib/courier/resources/users/preferences.rb +96 -0
  18. data/lib/courier/resources/workspace_preferences/topics.rb +6 -2
  19. data/lib/courier/resources/workspace_preferences.rb +22 -4
  20. data/lib/courier/version.rb +1 -1
  21. data/lib/courier.rb +6 -0
  22. data/rbi/courier/models/publish_preferences_request.rbi +58 -0
  23. data/rbi/courier/models/users/bulk_preference_topic.rbi +99 -0
  24. data/rbi/courier/models/users/preference_bulk_replace_params.rbi +188 -0
  25. data/rbi/courier/models/users/preference_bulk_replace_response.rbi +50 -0
  26. data/rbi/courier/models/users/preference_bulk_update_params.rbi +186 -0
  27. data/rbi/courier/models/users/preference_bulk_update_response.rbi +94 -0
  28. data/rbi/courier/models/workspace_preference_create_request.rbi +8 -0
  29. data/rbi/courier/models/workspace_preference_get_response.rbi +8 -0
  30. data/rbi/courier/models/workspace_preference_publish_params.rbi +1 -1
  31. data/rbi/courier/models/workspace_preference_replace_request.rbi +10 -0
  32. data/rbi/courier/models/workspace_preference_topic_create_request.rbi +8 -0
  33. data/rbi/courier/models/workspace_preference_topic_get_response.rbi +8 -0
  34. data/rbi/courier/models/workspace_preference_topic_replace_request.rbi +10 -0
  35. data/rbi/courier/models.rbi +2 -0
  36. data/rbi/courier/resources/users/preferences.rbi +83 -0
  37. data/rbi/courier/resources/workspace_preferences/topics.rbi +7 -0
  38. data/rbi/courier/resources/workspace_preferences.rbi +23 -4
  39. data/sig/courier/models/publish_preferences_request.rbs +26 -0
  40. data/sig/courier/models/users/bulk_preference_topic.rbs +48 -0
  41. data/sig/courier/models/users/preference_bulk_replace_params.rbs +87 -0
  42. data/sig/courier/models/users/preference_bulk_replace_response.rbs +27 -0
  43. data/sig/courier/models/users/preference_bulk_update_params.rbs +87 -0
  44. data/sig/courier/models/users/preference_bulk_update_response.rbs +39 -0
  45. data/sig/courier/models/workspace_preference_create_request.rbs +5 -0
  46. data/sig/courier/models/workspace_preference_get_response.rbs +5 -0
  47. data/sig/courier/models/workspace_preference_publish_params.rbs +1 -1
  48. data/sig/courier/models/workspace_preference_replace_request.rbs +5 -0
  49. data/sig/courier/models/workspace_preference_topic_create_request.rbs +5 -0
  50. data/sig/courier/models/workspace_preference_topic_get_response.rbs +5 -0
  51. data/sig/courier/models/workspace_preference_topic_replace_request.rbs +5 -0
  52. data/sig/courier/models.rbs +2 -0
  53. data/sig/courier/resources/users/preferences.rbs +14 -0
  54. data/sig/courier/resources/workspace_preferences/topics.rbs +2 -0
  55. data/sig/courier/resources/workspace_preferences.rbs +5 -0
  56. metadata +19 -1
@@ -0,0 +1,186 @@
1
+ # typed: strong
2
+
3
+ module Courier
4
+ module Models
5
+ module Users
6
+ class PreferenceBulkUpdateParams < Courier::Internal::Type::BaseModel
7
+ extend Courier::Internal::Type::RequestParameters::Converter
8
+ include Courier::Internal::Type::RequestParameters
9
+
10
+ OrHash =
11
+ T.type_alias do
12
+ T.any(
13
+ Courier::Users::PreferenceBulkUpdateParams,
14
+ Courier::Internal::AnyHash
15
+ )
16
+ end
17
+
18
+ sig { returns(String) }
19
+ attr_accessor :user_id
20
+
21
+ # The topics to create or update. Between 1 and 50 topics may be provided in a
22
+ # single request.
23
+ sig do
24
+ returns(T::Array[Courier::Users::PreferenceBulkUpdateParams::Topic])
25
+ end
26
+ attr_accessor :topics
27
+
28
+ # Update the preferences of a user for this specific tenant context.
29
+ sig { returns(T.nilable(String)) }
30
+ attr_accessor :tenant_id
31
+
32
+ sig do
33
+ params(
34
+ user_id: String,
35
+ topics:
36
+ T::Array[
37
+ Courier::Users::PreferenceBulkUpdateParams::Topic::OrHash
38
+ ],
39
+ tenant_id: T.nilable(String),
40
+ request_options: Courier::RequestOptions::OrHash
41
+ ).returns(T.attached_class)
42
+ end
43
+ def self.new(
44
+ user_id:,
45
+ # The topics to create or update. Between 1 and 50 topics may be provided in a
46
+ # single request.
47
+ topics:,
48
+ # Update the preferences of a user for this specific tenant context.
49
+ tenant_id: nil,
50
+ request_options: {}
51
+ )
52
+ end
53
+
54
+ sig do
55
+ override.returns(
56
+ {
57
+ user_id: String,
58
+ topics:
59
+ T::Array[Courier::Users::PreferenceBulkUpdateParams::Topic],
60
+ tenant_id: T.nilable(String),
61
+ request_options: Courier::RequestOptions
62
+ }
63
+ )
64
+ end
65
+ def to_hash
66
+ end
67
+
68
+ class Topic < Courier::Internal::Type::BaseModel
69
+ OrHash =
70
+ T.type_alias do
71
+ T.any(
72
+ Courier::Users::PreferenceBulkUpdateParams::Topic,
73
+ Courier::Internal::AnyHash
74
+ )
75
+ end
76
+
77
+ # The subscription status to apply for this topic.
78
+ sig do
79
+ returns(
80
+ Courier::Users::PreferenceBulkUpdateParams::Topic::Status::OrSymbol
81
+ )
82
+ end
83
+ attr_accessor :status
84
+
85
+ # A unique identifier associated with a subscription topic.
86
+ sig { returns(String) }
87
+ attr_accessor :topic_id
88
+
89
+ # The channels a user has chosen to receive notifications through for this topic.
90
+ sig do
91
+ returns(
92
+ T.nilable(T::Array[Courier::ChannelClassification::OrSymbol])
93
+ )
94
+ end
95
+ attr_reader :custom_routing
96
+
97
+ sig do
98
+ params(
99
+ custom_routing: T::Array[Courier::ChannelClassification::OrSymbol]
100
+ ).void
101
+ end
102
+ attr_writer :custom_routing
103
+
104
+ # Whether the recipient has chosen specific delivery channels for this topic.
105
+ sig { returns(T.nilable(T::Boolean)) }
106
+ attr_reader :has_custom_routing
107
+
108
+ sig { params(has_custom_routing: T::Boolean).void }
109
+ attr_writer :has_custom_routing
110
+
111
+ sig do
112
+ params(
113
+ status:
114
+ Courier::Users::PreferenceBulkUpdateParams::Topic::Status::OrSymbol,
115
+ topic_id: String,
116
+ custom_routing:
117
+ T::Array[Courier::ChannelClassification::OrSymbol],
118
+ has_custom_routing: T::Boolean
119
+ ).returns(T.attached_class)
120
+ end
121
+ def self.new(
122
+ # The subscription status to apply for this topic.
123
+ status:,
124
+ # A unique identifier associated with a subscription topic.
125
+ topic_id:,
126
+ # The channels a user has chosen to receive notifications through for this topic.
127
+ custom_routing: nil,
128
+ # Whether the recipient has chosen specific delivery channels for this topic.
129
+ has_custom_routing: nil
130
+ )
131
+ end
132
+
133
+ sig do
134
+ override.returns(
135
+ {
136
+ status:
137
+ Courier::Users::PreferenceBulkUpdateParams::Topic::Status::OrSymbol,
138
+ topic_id: String,
139
+ custom_routing:
140
+ T::Array[Courier::ChannelClassification::OrSymbol],
141
+ has_custom_routing: T::Boolean
142
+ }
143
+ )
144
+ end
145
+ def to_hash
146
+ end
147
+
148
+ # The subscription status to apply for this topic.
149
+ module Status
150
+ extend Courier::Internal::Type::Enum
151
+
152
+ TaggedSymbol =
153
+ T.type_alias do
154
+ T.all(
155
+ Symbol,
156
+ Courier::Users::PreferenceBulkUpdateParams::Topic::Status
157
+ )
158
+ end
159
+ OrSymbol = T.type_alias { T.any(Symbol, String) }
160
+
161
+ OPTED_IN =
162
+ T.let(
163
+ :OPTED_IN,
164
+ Courier::Users::PreferenceBulkUpdateParams::Topic::Status::TaggedSymbol
165
+ )
166
+ OPTED_OUT =
167
+ T.let(
168
+ :OPTED_OUT,
169
+ Courier::Users::PreferenceBulkUpdateParams::Topic::Status::TaggedSymbol
170
+ )
171
+
172
+ sig do
173
+ override.returns(
174
+ T::Array[
175
+ Courier::Users::PreferenceBulkUpdateParams::Topic::Status::TaggedSymbol
176
+ ]
177
+ )
178
+ end
179
+ def self.values
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,94 @@
1
+ # typed: strong
2
+
3
+ module Courier
4
+ module Models
5
+ module Users
6
+ class PreferenceBulkUpdateResponse < Courier::Internal::Type::BaseModel
7
+ OrHash =
8
+ T.type_alias do
9
+ T.any(
10
+ Courier::Models::Users::PreferenceBulkUpdateResponse,
11
+ Courier::Internal::AnyHash
12
+ )
13
+ end
14
+
15
+ # The topics that could not be applied, each with a reason.
16
+ sig do
17
+ returns(
18
+ T::Array[
19
+ Courier::Models::Users::PreferenceBulkUpdateResponse::Error
20
+ ]
21
+ )
22
+ end
23
+ attr_accessor :errors
24
+
25
+ # The topics that were successfully created or updated.
26
+ sig { returns(T::Array[Courier::Users::BulkPreferenceTopic]) }
27
+ attr_accessor :items
28
+
29
+ sig do
30
+ params(
31
+ errors:
32
+ T::Array[
33
+ Courier::Models::Users::PreferenceBulkUpdateResponse::Error::OrHash
34
+ ],
35
+ items: T::Array[Courier::Users::BulkPreferenceTopic::OrHash]
36
+ ).returns(T.attached_class)
37
+ end
38
+ def self.new(
39
+ # The topics that could not be applied, each with a reason.
40
+ errors:,
41
+ # The topics that were successfully created or updated.
42
+ items:
43
+ )
44
+ end
45
+
46
+ sig do
47
+ override.returns(
48
+ {
49
+ errors:
50
+ T::Array[
51
+ Courier::Models::Users::PreferenceBulkUpdateResponse::Error
52
+ ],
53
+ items: T::Array[Courier::Users::BulkPreferenceTopic]
54
+ }
55
+ )
56
+ end
57
+ def to_hash
58
+ end
59
+
60
+ class Error < Courier::Internal::Type::BaseModel
61
+ OrHash =
62
+ T.type_alias do
63
+ T.any(
64
+ Courier::Models::Users::PreferenceBulkUpdateResponse::Error,
65
+ Courier::Internal::AnyHash
66
+ )
67
+ end
68
+
69
+ # A human-readable explanation of why the topic could not be applied.
70
+ sig { returns(String) }
71
+ attr_accessor :reason
72
+
73
+ sig { returns(String) }
74
+ attr_accessor :topic_id
75
+
76
+ # A single topic that could not be applied in a bulk preference request.
77
+ sig do
78
+ params(reason: String, topic_id: String).returns(T.attached_class)
79
+ end
80
+ def self.new(
81
+ # A human-readable explanation of why the topic could not be applied.
82
+ reason:,
83
+ topic_id:
84
+ )
85
+ end
86
+
87
+ sig { override.returns({ reason: String, topic_id: String }) }
88
+ def to_hash
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -15,6 +15,10 @@ module Courier
15
15
  sig { returns(String) }
16
16
  attr_accessor :name
17
17
 
18
+ # Optional description shown under the section on the hosted preferences page.
19
+ sig { returns(T.nilable(String)) }
20
+ attr_accessor :description
21
+
18
22
  # Whether the workspace preference defines custom routing for its topics.
19
23
  sig { returns(T.nilable(T::Boolean)) }
20
24
  attr_accessor :has_custom_routing
@@ -29,6 +33,7 @@ module Courier
29
33
  sig do
30
34
  params(
31
35
  name: String,
36
+ description: T.nilable(String),
32
37
  has_custom_routing: T.nilable(T::Boolean),
33
38
  routing_options:
34
39
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol])
@@ -37,6 +42,8 @@ module Courier
37
42
  def self.new(
38
43
  # Human-readable name for the workspace preference.
39
44
  name:,
45
+ # Optional description shown under the section on the hosted preferences page.
46
+ description: nil,
40
47
  # Whether the workspace preference defines custom routing for its topics.
41
48
  has_custom_routing: nil,
42
49
  # Default channels for the workspace preference. Defaults to empty if omitted.
@@ -48,6 +55,7 @@ module Courier
48
55
  override.returns(
49
56
  {
50
57
  name: String,
58
+ description: T.nilable(String),
51
59
  has_custom_routing: T.nilable(T::Boolean),
52
60
  routing_options:
53
61
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol])
@@ -39,6 +39,10 @@ module Courier
39
39
  sig { returns(T.nilable(String)) }
40
40
  attr_accessor :creator
41
41
 
42
+ # Optional description shown under the section on the hosted preferences page.
43
+ sig { returns(T.nilable(String)) }
44
+ attr_accessor :description
45
+
42
46
  # ISO-8601 timestamp of the last update.
43
47
  sig { returns(T.nilable(String)) }
44
48
  attr_accessor :updated
@@ -58,6 +62,7 @@ module Courier
58
62
  topics:
59
63
  T::Array[Courier::WorkspacePreferenceTopicGetResponse::OrHash],
60
64
  creator: T.nilable(String),
65
+ description: T.nilable(String),
61
66
  updated: T.nilable(String),
62
67
  updater: T.nilable(String)
63
68
  ).returns(T.attached_class)
@@ -77,6 +82,8 @@ module Courier
77
82
  topics:,
78
83
  # Id of the creator.
79
84
  creator: nil,
85
+ # Optional description shown under the section on the hosted preferences page.
86
+ description: nil,
80
87
  # ISO-8601 timestamp of the last update.
81
88
  updated: nil,
82
89
  # Id of the last updater.
@@ -95,6 +102,7 @@ module Courier
95
102
  T::Array[Courier::ChannelClassification::TaggedSymbol],
96
103
  topics: T::Array[Courier::WorkspacePreferenceTopicGetResponse],
97
104
  creator: T.nilable(String),
105
+ description: T.nilable(String),
98
106
  updated: T.nilable(String),
99
107
  updater: T.nilable(String)
100
108
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Courier
4
4
  module Models
5
- class WorkspacePreferencePublishParams < Courier::Internal::Type::BaseModel
5
+ class WorkspacePreferencePublishParams < Courier::Models::PublishPreferencesRequest
6
6
  extend Courier::Internal::Type::RequestParameters::Converter
7
7
  include Courier::Internal::Type::RequestParameters
8
8
 
@@ -15,6 +15,11 @@ module Courier
15
15
  sig { returns(String) }
16
16
  attr_accessor :name
17
17
 
18
+ # Optional description shown under the section on the hosted preferences page.
19
+ # Omit to clear.
20
+ sig { returns(T.nilable(String)) }
21
+ attr_accessor :description
22
+
18
23
  # Whether the workspace preference defines custom routing for its topics.
19
24
  sig { returns(T.nilable(T::Boolean)) }
20
25
  attr_accessor :has_custom_routing
@@ -30,6 +35,7 @@ module Courier
30
35
  sig do
31
36
  params(
32
37
  name: String,
38
+ description: T.nilable(String),
33
39
  has_custom_routing: T.nilable(T::Boolean),
34
40
  routing_options:
35
41
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol])
@@ -38,6 +44,9 @@ module Courier
38
44
  def self.new(
39
45
  # Human-readable name for the workspace preference.
40
46
  name:,
47
+ # Optional description shown under the section on the hosted preferences page.
48
+ # Omit to clear.
49
+ description: nil,
41
50
  # Whether the workspace preference defines custom routing for its topics.
42
51
  has_custom_routing: nil,
43
52
  # Default channels for the workspace preference. Omit to clear.
@@ -49,6 +58,7 @@ module Courier
49
58
  override.returns(
50
59
  {
51
60
  name: String,
61
+ description: T.nilable(String),
52
62
  has_custom_routing: T.nilable(T::Boolean),
53
63
  routing_options:
54
64
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol])
@@ -36,6 +36,10 @@ module Courier
36
36
  end
37
37
  attr_accessor :allowed_preferences
38
38
 
39
+ # Optional description shown under the topic on the hosted preferences page.
40
+ sig { returns(T.nilable(String)) }
41
+ attr_accessor :description
42
+
39
43
  # Whether to include a list-unsubscribe header on emails for this topic.
40
44
  sig { returns(T.nilable(T::Boolean)) }
41
45
  attr_accessor :include_unsubscribe_header
@@ -62,6 +66,7 @@ module Courier
62
66
  Courier::WorkspacePreferenceTopicCreateRequest::AllowedPreference::OrSymbol
63
67
  ]
64
68
  ),
69
+ description: T.nilable(String),
65
70
  include_unsubscribe_header: T.nilable(T::Boolean),
66
71
  routing_options:
67
72
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol]),
@@ -76,6 +81,8 @@ module Courier
76
81
  # Preference controls a recipient may customize for this topic. Defaults to empty
77
82
  # if omitted.
78
83
  allowed_preferences: nil,
84
+ # Optional description shown under the topic on the hosted preferences page.
85
+ description: nil,
79
86
  # Whether to include a list-unsubscribe header on emails for this topic.
80
87
  include_unsubscribe_header: nil,
81
88
  # Default channels delivered for this topic. Defaults to empty if omitted.
@@ -97,6 +104,7 @@ module Courier
97
104
  Courier::WorkspacePreferenceTopicCreateRequest::AllowedPreference::OrSymbol
98
105
  ]
99
106
  ),
107
+ description: T.nilable(String),
100
108
  include_unsubscribe_header: T.nilable(T::Boolean),
101
109
  routing_options:
102
110
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol]),
@@ -61,6 +61,10 @@ module Courier
61
61
  sig { returns(T.nilable(String)) }
62
62
  attr_accessor :creator
63
63
 
64
+ # Optional description shown under the topic on the hosted preferences page.
65
+ sig { returns(T.nilable(String)) }
66
+ attr_accessor :description
67
+
64
68
  # Id of the last updater.
65
69
  sig { returns(T.nilable(String)) }
66
70
  attr_accessor :updater
@@ -82,6 +86,7 @@ module Courier
82
86
  topic_data: T::Hash[Symbol, T.anything],
83
87
  updated: String,
84
88
  creator: T.nilable(String),
89
+ description: T.nilable(String),
85
90
  updater: T.nilable(String)
86
91
  ).returns(T.attached_class)
87
92
  end
@@ -106,6 +111,8 @@ module Courier
106
111
  updated:,
107
112
  # Id of the creator.
108
113
  creator: nil,
114
+ # Optional description shown under the topic on the hosted preferences page.
115
+ description: nil,
109
116
  # Id of the last updater.
110
117
  updater: nil
111
118
  )
@@ -129,6 +136,7 @@ module Courier
129
136
  topic_data: T::Hash[Symbol, T.anything],
130
137
  updated: String,
131
138
  creator: T.nilable(String),
139
+ description: T.nilable(String),
132
140
  updater: T.nilable(String)
133
141
  }
134
142
  )
@@ -35,6 +35,11 @@ module Courier
35
35
  end
36
36
  attr_accessor :allowed_preferences
37
37
 
38
+ # Optional description shown under the topic on the hosted preferences page. Omit
39
+ # to clear.
40
+ sig { returns(T.nilable(String)) }
41
+ attr_accessor :description
42
+
38
43
  # Whether to include a list-unsubscribe header on emails for this topic.
39
44
  sig { returns(T.nilable(T::Boolean)) }
40
45
  attr_accessor :include_unsubscribe_header
@@ -62,6 +67,7 @@ module Courier
62
67
  Courier::WorkspacePreferenceTopicReplaceRequest::AllowedPreference::OrSymbol
63
68
  ]
64
69
  ),
70
+ description: T.nilable(String),
65
71
  include_unsubscribe_header: T.nilable(T::Boolean),
66
72
  routing_options:
67
73
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol]),
@@ -75,6 +81,9 @@ module Courier
75
81
  name:,
76
82
  # Preference controls a recipient may customize. Omit to clear.
77
83
  allowed_preferences: nil,
84
+ # Optional description shown under the topic on the hosted preferences page. Omit
85
+ # to clear.
86
+ description: nil,
78
87
  # Whether to include a list-unsubscribe header on emails for this topic.
79
88
  include_unsubscribe_header: nil,
80
89
  # Default channels delivered for this topic. Omit to clear.
@@ -96,6 +105,7 @@ module Courier
96
105
  Courier::WorkspacePreferenceTopicReplaceRequest::AllowedPreference::OrSymbol
97
106
  ]
98
107
  ),
108
+ description: T.nilable(String),
99
109
  include_unsubscribe_header: T.nilable(T::Boolean),
100
110
  routing_options:
101
111
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol]),
@@ -423,6 +423,8 @@ module Courier
423
423
 
424
424
  ProviderUpdateParams = Courier::Models::ProviderUpdateParams
425
425
 
426
+ PublishPreferencesRequest = Courier::Models::PublishPreferencesRequest
427
+
426
428
  PublishPreferencesResponse = Courier::Models::PublishPreferencesResponse
427
429
 
428
430
  PutSubscriptionsRecipient = Courier::Models::PutSubscriptionsRecipient
@@ -22,6 +22,89 @@ module Courier
22
22
  )
23
23
  end
24
24
 
25
+ # Replace a user's complete set of preference overrides in a single request. The
26
+ # topics in the request body become the recipient's entire set of overrides:
27
+ # listed topics are created or updated, and every existing override that is not
28
+ # included in the body is reset to its topic default. Submitting an empty `topics`
29
+ # array is a valid clear-all that resets every existing override.
30
+ #
31
+ # This operation is validation-atomic (all-or-nothing): structural validation
32
+ # fails fast with a single `400`, and if any topic is semantically invalid (an
33
+ # unknown topic, a `REQUIRED` topic that cannot be opted out, or a custom routing
34
+ # request that is not available on the workspace's plan) the request returns a
35
+ # single `400` aggregating every failure in `errors` and writes nothing. On
36
+ # success it returns `200` with `items` (the complete resulting override set) and
37
+ # `deleted` (the ids of the overrides that were reset to default).
38
+ #
39
+ # Every `topic_id` in the response — in `items`, `deleted`, and any `errors` — is
40
+ # returned in Courier's canonical topic id form, regardless of the form supplied
41
+ # in the request.
42
+ sig do
43
+ params(
44
+ user_id: String,
45
+ topics:
46
+ T::Array[
47
+ Courier::Users::PreferenceBulkReplaceParams::Topic::OrHash
48
+ ],
49
+ tenant_id: T.nilable(String),
50
+ request_options: Courier::RequestOptions::OrHash
51
+ ).returns(Courier::Models::Users::PreferenceBulkReplaceResponse)
52
+ end
53
+ def bulk_replace(
54
+ # Path param: A unique identifier associated with the user whose preferences you
55
+ # wish to update.
56
+ user_id,
57
+ # Body param: The complete set of topic overrides for the user. Up to 50 topics
58
+ # may be provided. Any existing override not listed here is reset to its topic
59
+ # default; an empty array resets every existing override.
60
+ topics:,
61
+ # Query param: Update the preferences of a user for this specific tenant context.
62
+ tenant_id: nil,
63
+ request_options: {}
64
+ )
65
+ end
66
+
67
+ # Additively create or update a user's preferences for one or more subscription
68
+ # topics in a single request. Only the topics included in the request body are
69
+ # created or updated; any existing overrides for topics not listed are left
70
+ # untouched.
71
+ #
72
+ # Structural validation of the request body fails fast with a single `400`. Beyond
73
+ # that, each topic is processed independently (partial-success, not
74
+ # all-or-nothing): valid topics are written and returned in `items`, while topics
75
+ # that cannot be applied are collected in `errors` with a per-topic `reason` (for
76
+ # example an unknown topic, a `REQUIRED` topic that cannot be opted out, a custom
77
+ # routing request that is not available on the workspace's plan, or a write
78
+ # failure). The request therefore returns `200` with both lists whenever the body
79
+ # is structurally valid.
80
+ #
81
+ # Every `topic_id` in the response — in both `items` and `errors` — is returned in
82
+ # Courier's canonical topic id form, regardless of the form supplied in the
83
+ # request.
84
+ sig do
85
+ params(
86
+ user_id: String,
87
+ topics:
88
+ T::Array[
89
+ Courier::Users::PreferenceBulkUpdateParams::Topic::OrHash
90
+ ],
91
+ tenant_id: T.nilable(String),
92
+ request_options: Courier::RequestOptions::OrHash
93
+ ).returns(Courier::Models::Users::PreferenceBulkUpdateResponse)
94
+ end
95
+ def bulk_update(
96
+ # Path param: A unique identifier associated with the user whose preferences you
97
+ # wish to update.
98
+ user_id,
99
+ # Body param: The topics to create or update. Between 1 and 50 topics may be
100
+ # provided in a single request.
101
+ topics:,
102
+ # Query param: Update the preferences of a user for this specific tenant context.
103
+ tenant_id: nil,
104
+ request_options: {}
105
+ )
106
+ end
107
+
25
108
  # Remove a user's preferences for a specific subscription topic, resetting the
26
109
  # topic to its effective default. This operation is idempotent: deleting a
27
110
  # preference that does not exist succeeds with no error.
@@ -19,6 +19,7 @@ module Courier
19
19
  Courier::WorkspacePreferenceTopicCreateRequest::AllowedPreference::OrSymbol
20
20
  ]
21
21
  ),
22
+ description: T.nilable(String),
22
23
  include_unsubscribe_header: T.nilable(T::Boolean),
23
24
  routing_options:
24
25
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol]),
@@ -36,6 +37,8 @@ module Courier
36
37
  # Preference controls a recipient may customize for this topic. Defaults to empty
37
38
  # if omitted.
38
39
  allowed_preferences: nil,
40
+ # Optional description shown under the topic on the hosted preferences page.
41
+ description: nil,
39
42
  # Whether to include a list-unsubscribe header on emails for this topic.
40
43
  include_unsubscribe_header: nil,
41
44
  # Default channels delivered for this topic. Defaults to empty if omitted.
@@ -112,6 +115,7 @@ module Courier
112
115
  Courier::WorkspacePreferenceTopicReplaceRequest::AllowedPreference::OrSymbol
113
116
  ]
114
117
  ),
118
+ description: T.nilable(String),
115
119
  include_unsubscribe_header: T.nilable(T::Boolean),
116
120
  routing_options:
117
121
  T.nilable(T::Array[Courier::ChannelClassification::OrSymbol]),
@@ -131,6 +135,9 @@ module Courier
131
135
  name:,
132
136
  # Body param: Preference controls a recipient may customize. Omit to clear.
133
137
  allowed_preferences: nil,
138
+ # Body param: Optional description shown under the topic on the hosted preferences
139
+ # page. Omit to clear.
140
+ description: nil,
134
141
  # Body param: Whether to include a list-unsubscribe header on emails for this
135
142
  # topic.
136
143
  include_unsubscribe_header: nil,