trycourier 6.4.3 → 6.5.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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/README.md +1 -1
  4. data/lib/courier/models/elemental_channel_node.rb +13 -1
  5. data/lib/courier/models/elemental_node_non_channel.rb +188 -0
  6. data/lib/courier/models/email_footer.rb +114 -7
  7. data/lib/courier/models/notification_template_update_request.rb +6 -3
  8. data/lib/courier/models/users/token_add_single_params.rb +13 -5
  9. data/lib/courier/models/users/token_update_params.rb +30 -4
  10. data/lib/courier/models/users/user_token.rb +13 -5
  11. data/lib/courier/models.rb +2 -0
  12. data/lib/courier/resources/journeys/templates.rb +7 -0
  13. data/lib/courier/resources/notifications.rb +10 -0
  14. data/lib/courier/resources/tenants/templates.rb +10 -0
  15. data/lib/courier/resources/users/tokens.rb +1 -1
  16. data/lib/courier/version.rb +1 -1
  17. data/lib/courier.rb +1 -0
  18. data/rbi/courier/models/elemental_channel_node.rbi +54 -0
  19. data/rbi/courier/models/elemental_node_non_channel.rbi +561 -0
  20. data/rbi/courier/models/email_footer.rbi +229 -7
  21. data/rbi/courier/models/notification_template_update_request.rbi +6 -3
  22. data/rbi/courier/models/users/token_add_single_params.rbi +18 -6
  23. data/rbi/courier/models/users/token_update_params.rbi +59 -7
  24. data/rbi/courier/models/users/user_token.rbi +18 -6
  25. data/rbi/courier/models.rbi +2 -0
  26. data/rbi/courier/resources/journeys/templates.rbi +7 -0
  27. data/rbi/courier/resources/notifications.rbi +10 -0
  28. data/rbi/courier/resources/tenants/templates.rbi +10 -0
  29. data/rbi/courier/resources/users/tokens.rbi +6 -2
  30. data/sig/courier/models/elemental_channel_node.rbs +9 -0
  31. data/sig/courier/models/elemental_node_non_channel.rbs +221 -0
  32. data/sig/courier/models/email_footer.rbs +107 -5
  33. data/sig/courier/models/users/token_update_params.rbs +27 -4
  34. data/sig/courier/models.rbs +2 -0
  35. metadata +5 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8b8d37f136533933d8866b7f9c65690f4a7f97c858fcfe8a59b22f9207258e3
4
- data.tar.gz: 5109857a74cebd79366d2cfe314cacebef0c42e6501cfc225e294a7c03e3b9bf
3
+ metadata.gz: aec72cc2e6e742c57ffd2f2c5f8fde487e6597a34d0351cf4613abc3f369ab07
4
+ data.tar.gz: 037cfdab670141377df8fa5a5443c24b8d66e98b6ccc56b68c5db6176139bbb9
5
5
  SHA512:
6
- metadata.gz: 999317f439a918452c23d3e626c1412afc02f921e26d5323d8c56d46d17bff8705edf5ef69c98c47eeb0247dad214e6d74e8c62241c63295da98517e58b5b1fc
7
- data.tar.gz: 28ed1d47648060561af1be5579193eb16d52c40a8d460919f046d9617e5d45ae2b34dadc16418822e8f327e442c456e1ea5cd81b3deba123ce95dcdc12346187
6
+ metadata.gz: f9355b12ee2ed402c0f2e13d1f20b23cf5e3ee63e23e627894f66f517cf0522f866626b28485d3a5c98cfd021869f3fea6aeb3112a3e2208d65abc2733b0b10a
7
+ data.tar.gz: 45f4b13f45dbb29cdc1ed14845e7ff243fa90f215f45a6c4fcc324a3c725ed750d907da8571e4eb2ccf7b894aa7b9884bba71892454bc0f36f9d0f8036668695
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [6.5.0](https://github.com/trycourier/courier-ruby/compare/v6.4.4...v6.5.0) (2026-09-04)
4
+
5
+
6
+ ### Features
7
+
8
+ * **api:** document the expiry_date contract and allow boolean patch values ([#148](https://github.com/trycourier/courier-ruby/issues/148)) ([191cec0](https://github.com/trycourier/courier-ruby/commit/191cec0ef235a855add991f9b935c1d90e0239f8))
9
+
10
+ ## [6.4.4](https://github.com/trycourier/courier-ruby/compare/v6.4.3...v6.4.4) (2026-09-03)
11
+
12
+
13
+ ### Documentation
14
+
15
+ * **api:** document the channel-block requirement on template creation ([#146](https://github.com/trycourier/courier-ruby/issues/146)) ([95749c6](https://github.com/trycourier/courier-ruby/commit/95749c6db1bd5e1b07d28d1f59970652b5cb2c49))
16
+
3
17
  ## [6.4.3](https://github.com/trycourier/courier-ruby/compare/v6.4.2...v6.4.3) (2026-08-29)
4
18
 
5
19
 
data/README.md CHANGED
@@ -9,7 +9,7 @@ Add the gem to your `Gemfile`:
9
9
  <!-- x-release-please-start-version -->
10
10
 
11
11
  ```ruby
12
- gem "trycourier", "~> 6.4.3"
12
+ gem "trycourier", "~> 6.5.0"
13
13
  ```
14
14
 
15
15
  <!-- x-release-please-end -->
@@ -10,6 +10,16 @@ module Courier
10
10
  # @return [String, nil]
11
11
  optional :channel, String
12
12
 
13
+ # @!attribute elements
14
+ # An array of elements to apply to the channel. If `raw` has not been specified,
15
+ # `elements` is `required`. Channel elements cannot nest, so these are any node
16
+ # except another channel block.
17
+ #
18
+ # @return [Array<Courier::Models::ElementalNodeNonChannel::UnionMember0, Courier::Models::ElementalNodeNonChannel::UnionMember1, Courier::Models::ElementalNodeNonChannel::UnionMember2, Courier::Models::ElementalNodeNonChannel::UnionMember3, Courier::Models::ElementalNodeNonChannel::UnionMember4, Courier::Models::ElementalNodeNonChannel::UnionMember5, Courier::Models::ElementalNodeNonChannel::UnionMember6>, nil]
19
+ optional :elements,
20
+ -> { Courier::Internal::Type::ArrayOf[union: Courier::ElementalNodeNonChannel] },
21
+ nil?: true
22
+
13
23
  # @!attribute font_size
14
24
  # Email only. Document-level base font size (CSS px, e.g. `16px`) for body content
15
25
  # — text, quote, list and action button labels. Heading styles (`h1`/`h2`/`h3`)
@@ -39,7 +49,7 @@ module Courier
39
49
  # @return [Hash{Symbol=>Object}, nil]
40
50
  optional :raw, Courier::Internal::Type::HashOf[Courier::Internal::Type::Unknown], nil?: true
41
51
 
42
- # @!method initialize(channel: nil, font_size: nil, line_height: nil, padding: nil, raw: nil)
52
+ # @!method initialize(channel: nil, elements: nil, font_size: nil, line_height: nil, padding: nil, raw: nil)
43
53
  # Some parameter documentations has been truncated, see
44
54
  # {Courier::Models::ElementalChannelNode} for more details.
45
55
  #
@@ -56,6 +66,8 @@ module Courier
56
66
  #
57
67
  # @param channel [String] The channel the contents of this element should be applied to. Can be `email`, `
58
68
  #
69
+ # @param elements [Array<Courier::Models::ElementalNodeNonChannel::UnionMember0, Courier::Models::ElementalNodeNonChannel::UnionMember1, Courier::Models::ElementalNodeNonChannel::UnionMember2, Courier::Models::ElementalNodeNonChannel::UnionMember3, Courier::Models::ElementalNodeNonChannel::UnionMember4, Courier::Models::ElementalNodeNonChannel::UnionMember5, Courier::Models::ElementalNodeNonChannel::UnionMember6>, nil] An array of elements to apply to the channel. If `raw` has not been
70
+ #
59
71
  # @param font_size [String, nil] Email only. Document-level base font size (CSS px, e.g. `16px`) for body content
60
72
  #
61
73
  # @param line_height [String, nil] Email only. Document-level line height (CSS px or unitless multiplier, e.g. `24p
@@ -0,0 +1,188 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Courier
4
+ module Models
5
+ # Any Elemental node except a channel block. Channel elements are only valid as
6
+ # top-level elements, so the `elements` nested inside one can never be another
7
+ # channel. Keeping this union channel-free also keeps the schema acyclic; a
8
+ # recursive `$ref` here breaks the generated Python models.
9
+ module ElementalNodeNonChannel
10
+ extend Courier::Internal::Type::Union
11
+
12
+ # Represents a body of text to be rendered inside of the notification.
13
+ variant -> { Courier::ElementalNodeNonChannel::UnionMember0 }
14
+
15
+ # The meta element contains information describing the notification that may be used by a particular channel or provider. One important field is the title field which will be used as the title for channels that support it.
16
+ variant -> { Courier::ElementalNodeNonChannel::UnionMember1 }
17
+
18
+ # Used to embed an image into the notification.
19
+ variant -> { Courier::ElementalNodeNonChannel::UnionMember2 }
20
+
21
+ # Allows the user to execute an action. Can be a button or a link.
22
+ variant -> { Courier::ElementalNodeNonChannel::UnionMember3 }
23
+
24
+ # Renders a dividing line between elements.
25
+ variant -> { Courier::ElementalNodeNonChannel::UnionMember4 }
26
+
27
+ # Renders a quote block.
28
+ variant -> { Courier::ElementalNodeNonChannel::UnionMember5 }
29
+
30
+ # Raw HTML string inside an Elemental document. When rendering a message, this node is turned into output only for the email channel; for other channels it produces no blocks.
31
+ variant -> { Courier::ElementalNodeNonChannel::UnionMember6 }
32
+
33
+ class UnionMember0 < Courier::Models::ElementalTextNode
34
+ # @!attribute type
35
+ #
36
+ # @return [Symbol, Courier::Models::ElementalNodeNonChannel::UnionMember0::Type, nil]
37
+ optional :type, enum: -> { Courier::ElementalNodeNonChannel::UnionMember0::Type }
38
+
39
+ # @!method initialize(type: nil)
40
+ # Represents a body of text to be rendered inside of the notification.
41
+ #
42
+ # @param type [Symbol, Courier::Models::ElementalNodeNonChannel::UnionMember0::Type]
43
+
44
+ module Type
45
+ extend Courier::Internal::Type::Enum
46
+
47
+ TEXT = :text
48
+
49
+ # @!method self.values
50
+ # @return [Array<Symbol>]
51
+ end
52
+ end
53
+
54
+ class UnionMember1 < Courier::Models::ElementalMetaNode
55
+ # @!attribute type
56
+ #
57
+ # @return [Symbol, Courier::Models::ElementalNodeNonChannel::UnionMember1::Type, nil]
58
+ optional :type, enum: -> { Courier::ElementalNodeNonChannel::UnionMember1::Type }
59
+
60
+ # @!method initialize(type: nil)
61
+ # The meta element contains information describing the notification that may be
62
+ # used by a particular channel or provider. One important field is the title field
63
+ # which will be used as the title for channels that support it.
64
+ #
65
+ # @param type [Symbol, Courier::Models::ElementalNodeNonChannel::UnionMember1::Type]
66
+
67
+ module Type
68
+ extend Courier::Internal::Type::Enum
69
+
70
+ META = :meta
71
+
72
+ # @!method self.values
73
+ # @return [Array<Symbol>]
74
+ end
75
+ end
76
+
77
+ class UnionMember2 < Courier::Models::ElementalImageNode
78
+ # @!attribute type
79
+ #
80
+ # @return [Symbol, Courier::Models::ElementalNodeNonChannel::UnionMember2::Type, nil]
81
+ optional :type, enum: -> { Courier::ElementalNodeNonChannel::UnionMember2::Type }
82
+
83
+ # @!method initialize(type: nil)
84
+ # Used to embed an image into the notification.
85
+ #
86
+ # @param type [Symbol, Courier::Models::ElementalNodeNonChannel::UnionMember2::Type]
87
+
88
+ module Type
89
+ extend Courier::Internal::Type::Enum
90
+
91
+ IMAGE = :image
92
+
93
+ # @!method self.values
94
+ # @return [Array<Symbol>]
95
+ end
96
+ end
97
+
98
+ class UnionMember3 < Courier::Models::ElementalActionNode
99
+ # @!attribute type
100
+ #
101
+ # @return [Symbol, Courier::Models::ElementalNodeNonChannel::UnionMember3::Type, nil]
102
+ optional :type, enum: -> { Courier::ElementalNodeNonChannel::UnionMember3::Type }
103
+
104
+ # @!method initialize(type: nil)
105
+ # Allows the user to execute an action. Can be a button or a link.
106
+ #
107
+ # @param type [Symbol, Courier::Models::ElementalNodeNonChannel::UnionMember3::Type]
108
+
109
+ module Type
110
+ extend Courier::Internal::Type::Enum
111
+
112
+ ACTION = :action
113
+
114
+ # @!method self.values
115
+ # @return [Array<Symbol>]
116
+ end
117
+ end
118
+
119
+ class UnionMember4 < Courier::Models::ElementalDividerNode
120
+ # @!attribute type
121
+ #
122
+ # @return [Symbol, Courier::Models::ElementalNodeNonChannel::UnionMember4::Type, nil]
123
+ optional :type, enum: -> { Courier::ElementalNodeNonChannel::UnionMember4::Type }
124
+
125
+ # @!method initialize(type: nil)
126
+ # Renders a dividing line between elements.
127
+ #
128
+ # @param type [Symbol, Courier::Models::ElementalNodeNonChannel::UnionMember4::Type]
129
+
130
+ module Type
131
+ extend Courier::Internal::Type::Enum
132
+
133
+ DIVIDER = :divider
134
+
135
+ # @!method self.values
136
+ # @return [Array<Symbol>]
137
+ end
138
+ end
139
+
140
+ class UnionMember5 < Courier::Models::ElementalQuoteNode
141
+ # @!attribute type
142
+ #
143
+ # @return [Symbol, Courier::Models::ElementalNodeNonChannel::UnionMember5::Type, nil]
144
+ optional :type, enum: -> { Courier::ElementalNodeNonChannel::UnionMember5::Type }
145
+
146
+ # @!method initialize(type: nil)
147
+ # Renders a quote block.
148
+ #
149
+ # @param type [Symbol, Courier::Models::ElementalNodeNonChannel::UnionMember5::Type]
150
+
151
+ module Type
152
+ extend Courier::Internal::Type::Enum
153
+
154
+ QUOTE = :quote
155
+
156
+ # @!method self.values
157
+ # @return [Array<Symbol>]
158
+ end
159
+ end
160
+
161
+ class UnionMember6 < Courier::Models::ElementalHTMLNode
162
+ # @!attribute type
163
+ #
164
+ # @return [Symbol, Courier::Models::ElementalNodeNonChannel::UnionMember6::Type, nil]
165
+ optional :type, enum: -> { Courier::ElementalNodeNonChannel::UnionMember6::Type }
166
+
167
+ # @!method initialize(type: nil)
168
+ # Raw HTML string inside an Elemental document. When rendering a message, this
169
+ # node is turned into output only for the email channel; for other channels it
170
+ # produces no blocks.
171
+ #
172
+ # @param type [Symbol, Courier::Models::ElementalNodeNonChannel::UnionMember6::Type]
173
+
174
+ module Type
175
+ extend Courier::Internal::Type::Enum
176
+
177
+ HTML = :html
178
+
179
+ # @!method self.values
180
+ # @return [Array<Symbol>]
181
+ end
182
+ end
183
+
184
+ # @!method self.variants
185
+ # @return [Array(Courier::Models::ElementalNodeNonChannel::UnionMember0, Courier::Models::ElementalNodeNonChannel::UnionMember1, Courier::Models::ElementalNodeNonChannel::UnionMember2, Courier::Models::ElementalNodeNonChannel::UnionMember3, Courier::Models::ElementalNodeNonChannel::UnionMember4, Courier::Models::ElementalNodeNonChannel::UnionMember5, Courier::Models::ElementalNodeNonChannel::UnionMember6)]
186
+ end
187
+ end
188
+ end
@@ -3,19 +3,126 @@
3
3
  module Courier
4
4
  module Models
5
5
  class EmailFooter < Courier::Internal::Type::BaseModel
6
- # @!attribute content
7
- #
8
- # @return [String, nil]
9
- optional :content, String, nil?: true
10
-
11
6
  # @!attribute inherit_default
12
7
  #
13
8
  # @return [Boolean, nil]
14
9
  optional :inherit_default, Courier::Internal::Type::Boolean, api_name: :inheritDefault, nil?: true
15
10
 
16
- # @!method initialize(content: nil, inherit_default: nil)
17
- # @param content [String, nil]
11
+ # @!attribute markdown
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
+ #
16
+ # @return [String, nil]
17
+ optional :markdown, String, nil?: true
18
+
19
+ # @!attribute social
20
+ # Social links rendered in the email footer.
21
+ #
22
+ # @return [Courier::Models::EmailFooter::Social, nil]
23
+ optional :social, -> { Courier::EmailFooter::Social }, nil?: true
24
+
25
+ # @!method initialize(inherit_default: nil, markdown: nil, social: nil)
26
+ # Some parameter documentations has been truncated, see
27
+ # {Courier::Models::EmailFooter} for more details.
28
+ #
18
29
  # @param inherit_default [Boolean, nil]
30
+ #
31
+ # @param markdown [String, nil] The footer body, as markdown. This is the field the API returns and accepts; it
32
+ #
33
+ # @param social [Courier::Models::EmailFooter::Social, nil] Social links rendered in the email footer.
34
+
35
+ # @see Courier::Models::EmailFooter#social
36
+ class Social < Courier::Internal::Type::BaseModel
37
+ # @!attribute facebook
38
+ #
39
+ # @return [Courier::Models::EmailFooter::Social::Facebook, nil]
40
+ optional :facebook, -> { Courier::EmailFooter::Social::Facebook }, nil?: true
41
+
42
+ # @!attribute instagram
43
+ #
44
+ # @return [Courier::Models::EmailFooter::Social::Instagram, nil]
45
+ optional :instagram, -> { Courier::EmailFooter::Social::Instagram }, nil?: true
46
+
47
+ # @!attribute linkedin
48
+ #
49
+ # @return [Courier::Models::EmailFooter::Social::Linkedin, nil]
50
+ optional :linkedin, -> { Courier::EmailFooter::Social::Linkedin }, nil?: true
51
+
52
+ # @!attribute medium
53
+ #
54
+ # @return [Courier::Models::EmailFooter::Social::Medium, nil]
55
+ optional :medium, -> { Courier::EmailFooter::Social::Medium }, nil?: true
56
+
57
+ # @!attribute twitter
58
+ #
59
+ # @return [Courier::Models::EmailFooter::Social::Twitter, nil]
60
+ optional :twitter, -> { Courier::EmailFooter::Social::Twitter }, nil?: true
61
+
62
+ # @!method initialize(facebook: nil, instagram: nil, linkedin: nil, medium: nil, twitter: nil)
63
+ # Social links rendered in the email footer.
64
+ #
65
+ # @param facebook [Courier::Models::EmailFooter::Social::Facebook, nil]
66
+ # @param instagram [Courier::Models::EmailFooter::Social::Instagram, nil]
67
+ # @param linkedin [Courier::Models::EmailFooter::Social::Linkedin, nil]
68
+ # @param medium [Courier::Models::EmailFooter::Social::Medium, nil]
69
+ # @param twitter [Courier::Models::EmailFooter::Social::Twitter, nil]
70
+
71
+ # @see Courier::Models::EmailFooter::Social#facebook
72
+ class Facebook < Courier::Internal::Type::BaseModel
73
+ # @!attribute url
74
+ #
75
+ # @return [String, nil]
76
+ optional :url, String, nil?: true
77
+
78
+ # @!method initialize(url: nil)
79
+ # @param url [String, nil]
80
+ end
81
+
82
+ # @see Courier::Models::EmailFooter::Social#instagram
83
+ class Instagram < Courier::Internal::Type::BaseModel
84
+ # @!attribute url
85
+ #
86
+ # @return [String, nil]
87
+ optional :url, String, nil?: true
88
+
89
+ # @!method initialize(url: nil)
90
+ # @param url [String, nil]
91
+ end
92
+
93
+ # @see Courier::Models::EmailFooter::Social#linkedin
94
+ class Linkedin < Courier::Internal::Type::BaseModel
95
+ # @!attribute url
96
+ #
97
+ # @return [String, nil]
98
+ optional :url, String, nil?: true
99
+
100
+ # @!method initialize(url: nil)
101
+ # @param url [String, nil]
102
+ end
103
+
104
+ # @see Courier::Models::EmailFooter::Social#medium
105
+ class Medium < Courier::Internal::Type::BaseModel
106
+ # @!attribute url
107
+ #
108
+ # @return [String, nil]
109
+ optional :url, String, nil?: true
110
+
111
+ # @!method initialize(url: nil)
112
+ # @param url [String, nil]
113
+ end
114
+
115
+ # @see Courier::Models::EmailFooter::Social#twitter
116
+ class Twitter < Courier::Internal::Type::BaseModel
117
+ # @!attribute url
118
+ #
119
+ # @return [String, nil]
120
+ optional :url, String, nil?: true
121
+
122
+ # @!method initialize(url: nil)
123
+ # @param url [String, nil]
124
+ end
125
+ end
19
126
  end
20
127
  end
21
128
  end
@@ -21,9 +21,12 @@ module Courier
21
21
  # Some parameter documentations has been truncated, see
22
22
  # {Courier::Models::NotificationTemplateUpdateRequest} for more details.
23
23
  #
24
- # Request body for replacing a notification template. Same shape as create. All
25
- # fields required (PUT = full replacement), except `alias`, whose omission means
26
- # "leave the existing aliases alone".
24
+ # Request body for replacing a notification template. All fields are required,
25
+ # since `PUT` is a full replacement, except `alias`, whose omission leaves the
26
+ # existing aliases in place. Unlike `NotificationTemplateCreateRequest`,
27
+ # `notification.content` is not required to place its elements inside a channel
28
+ # block: the requirement applies to creation only, so templates already stored
29
+ # without one stay editable.
27
30
  #
28
31
  # @param notification [Courier::Models::NotificationTemplateWritePayload] Template fields accepted in POST and PUT request bodies, nested under a `notific
29
32
  #
@@ -30,8 +30,12 @@ module Courier
30
30
  optional :device, -> { Courier::Users::TokenAddSingleParams::Device }, nil?: true
31
31
 
32
32
  # @!attribute expiry_date
33
- # ISO 8601 formatted date the token expires. Defaults to 2 months. Set to false to
34
- # disable expiration.
33
+ # When the token expires. Accepts a date, or the boolean `false` to disable
34
+ # expiration entirely. ISO 8601 is recommended (for example
35
+ # `2026-10-25T00:00:00.000Z`). A value that cannot be parsed as a date is
36
+ # rejected; it is not treated as "no expiration" and does not fall back to the
37
+ # default. `true` is not a supported value. Omit the field to use the default,
38
+ # which expires a token that has not been re-registered for 60 days.
35
39
  #
36
40
  # @return [String, Boolean, nil]
37
41
  optional :expiry_date, union: -> { Courier::Users::TokenAddSingleParams::ExpiryDate }, nil?: true
@@ -60,7 +64,7 @@ module Courier
60
64
  #
61
65
  # @param device [Courier::Models::Users::TokenAddSingleParams::Device, nil] Information about the device the token came from.
62
66
  #
63
- # @param expiry_date [String, Boolean, nil] ISO 8601 formatted date the token expires. Defaults to 2 months. Set to false to
67
+ # @param expiry_date [String, Boolean, nil] When the token expires. Accepts a date, or the boolean `false` to disable expira
64
68
  #
65
69
  # @param properties [Object] Properties about the token.
66
70
  #
@@ -133,8 +137,12 @@ module Courier
133
137
  # @param platform [String, nil] The device platform i.e. android, ios, web
134
138
  end
135
139
 
136
- # ISO 8601 formatted date the token expires. Defaults to 2 months. Set to false to
137
- # disable expiration.
140
+ # When the token expires. Accepts a date, or the boolean `false` to disable
141
+ # expiration entirely. ISO 8601 is recommended (for example
142
+ # `2026-10-25T00:00:00.000Z`). A value that cannot be parsed as a date is
143
+ # rejected; it is not treated as "no expiration" and does not fall back to the
144
+ # default. `true` is not a supported value. Omit the field to use the default,
145
+ # which expires a token that has not been re-registered for 60 days.
138
146
  module ExpiryDate
139
147
  extend Courier::Internal::Type::Union
140
148
 
@@ -43,17 +43,43 @@ module Courier
43
43
  required :path, String
44
44
 
45
45
  # @!attribute value
46
- # The value for the operation.
46
+ # The value for the operation. A string for most fields; boolean `false` when
47
+ # disabling token expiration via `expiry_date`, which cannot be expressed as a
48
+ # string.
47
49
  #
48
- # @return [String, nil]
49
- optional :value, String, nil?: true
50
+ # @return [String, Boolean, Hash{Symbol=>Object}, nil]
51
+ optional :value, union: -> { Courier::Users::TokenUpdateParams::Patch::Value }, nil?: true
50
52
 
51
53
  # @!method initialize(op:, path:, value: nil)
54
+ # Some parameter documentations has been truncated, see
55
+ # {Courier::Models::Users::TokenUpdateParams::Patch} for more details.
56
+ #
52
57
  # @param op [String] The operation to perform.
53
58
  #
54
59
  # @param path [String] The JSON path specifying the part of the profile to operate on.
55
60
  #
56
- # @param value [String, nil] The value for the operation.
61
+ # @param value [String, Boolean, Hash{Symbol=>Object}, nil] The value for the operation. A string for most fields; boolean `false` when disa
62
+
63
+ # The value for the operation. A string for most fields; boolean `false` when
64
+ # disabling token expiration via `expiry_date`, which cannot be expressed as a
65
+ # string.
66
+ #
67
+ # @see Courier::Models::Users::TokenUpdateParams::Patch#value
68
+ module Value
69
+ extend Courier::Internal::Type::Union
70
+
71
+ variant String
72
+
73
+ variant Courier::Internal::Type::Boolean
74
+
75
+ variant -> { Courier::Models::Users::TokenUpdateParams::Patch::Value::UnionMember2Map }
76
+
77
+ # @!method self.variants
78
+ # @return [Array(String, Boolean, Hash{Symbol=>Object})]
79
+
80
+ # @type [Courier::Internal::Type::Converter]
81
+ UnionMember2Map = Courier::Internal::Type::HashOf[Courier::Internal::Type::Unknown]
82
+ end
57
83
  end
58
84
  end
59
85
  end
@@ -22,8 +22,12 @@ module Courier
22
22
  optional :device, -> { Courier::Users::UserToken::Device }, nil?: true
23
23
 
24
24
  # @!attribute expiry_date
25
- # ISO 8601 formatted date the token expires. Defaults to 2 months. Set to false to
26
- # disable expiration.
25
+ # When the token expires. Accepts a date, or the boolean `false` to disable
26
+ # expiration entirely. ISO 8601 is recommended (for example
27
+ # `2026-10-25T00:00:00.000Z`). A value that cannot be parsed as a date is
28
+ # rejected; it is not treated as "no expiration" and does not fall back to the
29
+ # default. `true` is not a supported value. Omit the field to use the default,
30
+ # which expires a token that has not been re-registered for 60 days.
27
31
  #
28
32
  # @return [String, Boolean, nil]
29
33
  optional :expiry_date, union: -> { Courier::Users::UserToken::ExpiryDate }, nil?: true
@@ -50,7 +54,7 @@ module Courier
50
54
  #
51
55
  # @param device [Courier::Models::Users::UserToken::Device, nil] Information about the device the token came from.
52
56
  #
53
- # @param expiry_date [String, Boolean, nil] ISO 8601 formatted date the token expires. Defaults to 2 months. Set to false to
57
+ # @param expiry_date [String, Boolean, nil] When the token expires. Accepts a date, or the boolean `false` to disable expira
54
58
  #
55
59
  # @param properties [Object] Properties about the token.
56
60
  #
@@ -123,8 +127,12 @@ module Courier
123
127
  # @param platform [String, nil] The device platform i.e. android, ios, web
124
128
  end
125
129
 
126
- # ISO 8601 formatted date the token expires. Defaults to 2 months. Set to false to
127
- # disable expiration.
130
+ # When the token expires. Accepts a date, or the boolean `false` to disable
131
+ # expiration entirely. ISO 8601 is recommended (for example
132
+ # `2026-10-25T00:00:00.000Z`). A value that cannot be parsed as a date is
133
+ # rejected; it is not treated as "no expiration" and does not fall back to the
134
+ # default. `true` is not a supported value. Omit the field to use the default,
135
+ # which expires a token that has not been re-registered for 60 days.
128
136
  #
129
137
  # @see Courier::Models::Users::UserToken#expiry_date
130
138
  module ExpiryDate
@@ -227,6 +227,8 @@ module Courier
227
227
 
228
228
  ElementalNode = Courier::Models::ElementalNode
229
229
 
230
+ ElementalNodeNonChannel = Courier::Models::ElementalNodeNonChannel
231
+
230
232
  ElementalQuoteNode = Courier::Models::ElementalQuoteNode
231
233
 
232
234
  ElementalQuoteNodeWithType = Courier::Models::ElementalQuoteNodeWithType
@@ -12,6 +12,13 @@ module Courier
12
12
  # Create a notification template scoped to this journey. Defaults to `DRAFT`
13
13
  # state; pass `state: "PUBLISHED"` to publish on create.
14
14
  #
15
+ # The content tree must contain exactly one channel block whose `channel` matches
16
+ # the `channel` on the request — a journey-scoped template carries a single
17
+ # channel. Top-level elements, or a block for a different channel, return `400`.
18
+ # The template designer renders only the channel block matching the tab it draws,
19
+ # so content stored without one cannot be opened. An empty `elements` array is
20
+ # accepted.
21
+ #
15
22
  # @overload create(template_id, channel:, notification:, provider_key: nil, state: nil, idempotency_key: nil, x_idempotency_expiration: nil, request_options: {})
16
23
  #
17
24
  # @param template_id [String] Path param: Journey id
@@ -16,6 +16,16 @@ module Courier
16
16
  # Create a notification template. Requires all fields in the notification object.
17
17
  # Templates are created in draft state by default.
18
18
  #
19
+ # Content must place its elements inside a channel block —
20
+ # `{ "type": "channel", "channel": "email", "elements": [...] }` — or the request
21
+ # returns `400`. The template designer renders only the channel block matching the
22
+ # tab it draws, so content stored without one cannot be opened. An empty
23
+ # `elements` array is accepted, and the requirement applies to creation only:
24
+ # `PUT /notifications/{id}` still accepts unwrapped content. Note this endpoint
25
+ # takes versioned content only — the `{ title, body }` shorthand accepted by
26
+ # `/send` is rejected here with an `invalid_request_error` on
27
+ # `notification.content.version`.
28
+ #
19
29
  # @overload create(notification:, state: nil, idempotency_key: nil, x_idempotency_expiration: nil, request_options: {})
20
30
  #
21
31
  # @param notification [Courier::Models::NotificationTemplateWritePayload] Body param: Template fields accepted in POST and PUT request bodies, nested unde
@@ -135,6 +135,16 @@ module Courier
135
135
  # Creates or updates a notification template scoped to one tenant, letting a
136
136
  # tenant override the content the workspace template would send.
137
137
  #
138
+ # This is an upsert: it creates when the tenant has no template under
139
+ # `template_id`, and updates when it does. On the create half, content must place
140
+ # its elements inside a channel block —
141
+ # `{ "type": "channel", "channel": "email", "elements": [...] }` — or the request
142
+ # returns `400`. The template designer renders only the channel block matching the
143
+ # tab it draws, so content stored without one cannot be opened. An empty
144
+ # `elements` array is accepted, as is the `{ title, body }` shorthand, which has
145
+ # no elements to wrap. Updates are not checked, so tenant templates already stored
146
+ # without a wrapper stay editable.
147
+ #
138
148
  # @overload replace(template_id, tenant_id:, template:, published: nil, request_options: {})
139
149
  #
140
150
  # @param template_id [String] Path param: Id of the template to be created or updated.
@@ -151,7 +151,7 @@ module Courier
151
151
  #
152
152
  # @param device [Courier::Models::Users::TokenAddSingleParams::Device, nil] Body param: Information about the device the token came from.
153
153
  #
154
- # @param expiry_date [String, Boolean, nil] Body param: ISO 8601 formatted date the token expires. Defaults to 2 months. Set
154
+ # @param expiry_date [String, Boolean, nil] Body param: When the token expires. Accepts a date, or the boolean `false` to di
155
155
  #
156
156
  # @param properties [Object] Body param: Properties about the token.
157
157
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Courier
4
- VERSION = "6.4.3"
4
+ VERSION = "6.5.0"
5
5
  end
data/lib/courier.rb CHANGED
@@ -189,6 +189,7 @@ require_relative "courier/models/elemental_html_node_with_type"
189
189
  require_relative "courier/models/elemental_image_node_with_type"
190
190
  require_relative "courier/models/elemental_meta_node_with_type"
191
191
  require_relative "courier/models/elemental_node"
192
+ require_relative "courier/models/elemental_node_non_channel"
192
193
  require_relative "courier/models/elemental_quote_node_with_type"
193
194
  require_relative "courier/models/elemental_text_node_with_type"
194
195
  require_relative "courier/models/element_with_checksums"