diff --git a/api.md b/api.md index 9f1f001..0adc9fa 100644 --- a/api.md +++ b/api.md @@ -16,18 +16,25 @@ from courier.types import ( ChannelPreference, DeviceType, Discord, + ElementalActionNode, ElementalActionNodeWithType, ElementalBaseNode, ElementalChannelNode, ElementalChannelNodeWithType, ElementalContent, ElementalContentSugar, + ElementalDividerNode, ElementalDividerNodeWithType, + ElementalHTMLNode, ElementalHTMLNodeWithType, + ElementalImageNode, ElementalImageNodeWithType, + ElementalMetaNode, ElementalMetaNodeWithType, ElementalNode, + ElementalQuoteNode, ElementalQuoteNodeWithType, + ElementalTextNode, ElementalTextNodeWithType, Expo, FilterConfig, @@ -36,6 +43,7 @@ from courier.types import ( ListFilter, ListPatternRecipient, ListRecipient, + Locales, MessageChannels, MessageContext, MessageProviders, diff --git a/pyproject.toml b/pyproject.toml index fa4e800..ba6226f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "trycourier" -version = "9.4.0" +version = "9.3.0" description = "The official Python library for the Courier API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/courier/_version.py b/src/courier/_version.py index 7f2bcec..5895db1 100644 --- a/src/courier/_version.py +++ b/src/courier/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "courier" -__version__ = "9.4.0" # x-release-please-version +__version__ = "9.3.0" # x-release-please-version diff --git a/src/courier/types/__init__.py b/src/courier/types/__init__.py index 1633652..66c84a8 100644 --- a/src/courier/types/__init__.py +++ b/src/courier/types/__init__.py @@ -30,6 +30,7 @@ Paging as Paging, Channel as Channel, Discord as Discord, + Locales as Locales, MsTeams as MsTeams, Intercom as Intercom, Metadata as Metadata, @@ -66,17 +67,24 @@ AudienceRecipient as AudienceRecipient, ChannelPreference as ChannelPreference, ElementalBaseNode as ElementalBaseNode, + ElementalHTMLNode as ElementalHTMLNode, + ElementalMetaNode as ElementalMetaNode, + ElementalTextNode as ElementalTextNode, IntercomRecipient as IntercomRecipient, SendDirectMessage as SendDirectMessage, SendToSlackUserID as SendToSlackUserID, + ElementalImageNode as ElementalImageNode, + ElementalQuoteNode as ElementalQuoteNode, PagerdutyRecipient as PagerdutyRecipient, SendToMsTeamsEmail as SendToMsTeamsEmail, SendToSlackChannel as SendToSlackChannel, WebhookProfileType as WebhookProfileType, + ElementalActionNode as ElementalActionNode, SendToMsTeamsUserID as SendToMsTeamsUserID, SlackBaseProperties as SlackBaseProperties, AudienceFilterConfig as AudienceFilterConfig, ElementalChannelNode as ElementalChannelNode, + ElementalDividerNode as ElementalDividerNode, ListPatternRecipient as ListPatternRecipient, MessageProvidersType as MessageProvidersType, RecipientPreferences as RecipientPreferences, diff --git a/src/courier/types/shared/__init__.py b/src/courier/types/shared/__init__.py index f4a06a8..2fabc91 100644 --- a/src/courier/types/shared/__init__.py +++ b/src/courier/types/shared/__init__.py @@ -10,6 +10,7 @@ from .aws_sns import AwsSns as AwsSns from .channel import Channel as Channel from .discord import Discord as Discord +from .locales import Locales as Locales from .intercom import Intercom as Intercom from .metadata import Metadata as Metadata from .ms_teams import MsTeams as MsTeams @@ -46,10 +47,16 @@ from .intercom_recipient import IntercomRecipient as IntercomRecipient from .ms_teams_recipient import MsTeamsRecipient as MsTeamsRecipient from .elemental_base_node import ElementalBaseNode as ElementalBaseNode +from .elemental_html_node import ElementalHTMLNode as ElementalHTMLNode +from .elemental_meta_node import ElementalMetaNode as ElementalMetaNode +from .elemental_text_node import ElementalTextNode as ElementalTextNode from .pagerduty_recipient import PagerdutyRecipient as PagerdutyRecipient from .send_direct_message import SendDirectMessage as SendDirectMessage from .send_to_slack_email import SendToSlackEmail as SendToSlackEmail +from .elemental_image_node import ElementalImageNode as ElementalImageNode +from .elemental_quote_node import ElementalQuoteNode as ElementalQuoteNode from .webhook_profile_type import WebhookProfileType as WebhookProfileType +from .elemental_action_node import ElementalActionNode as ElementalActionNode from .recipient_preferences import RecipientPreferences as RecipientPreferences from .send_to_slack_channel import SendToSlackChannel as SendToSlackChannel from .send_to_slack_user_id import SendToSlackUserID as SendToSlackUserID @@ -57,6 +64,7 @@ from .audience_filter_config import AudienceFilterConfig as AudienceFilterConfig from .channel_classification import ChannelClassification as ChannelClassification from .elemental_channel_node import ElementalChannelNode as ElementalChannelNode +from .elemental_divider_node import ElementalDividerNode as ElementalDividerNode from .list_pattern_recipient import ListPatternRecipient as ListPatternRecipient from .message_providers_type import MessageProvidersType as MessageProvidersType from .send_to_ms_teams_email import SendToMsTeamsEmail as SendToMsTeamsEmail diff --git a/src/courier/types/shared/elemental_action_node.py b/src/courier/types/shared/elemental_action_node.py new file mode 100644 index 0000000..e5df683 --- /dev/null +++ b/src/courier/types/shared/elemental_action_node.py @@ -0,0 +1,58 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from .locales import Locales +from .alignment import Alignment +from .elemental_base_node import ElementalBaseNode + +__all__ = ["ElementalActionNode"] + + +class ElementalActionNode(ElementalBaseNode): + """Allows the user to execute an action. Can be a button or a link.""" + + content: str + """The text content of the action shown to the user.""" + + href: str + """The target URL of the action.""" + + action_id: Optional[str] = None + """A unique id used to identify the action when it is executed.""" + + align: Optional[Alignment] = None + """The alignment of the action button. Defaults to "center".""" + + background_color: Optional[str] = None + """The background color of the action button.""" + + border_radius: Optional[str] = None + """CSS border-radius applied to the action button. For example, `4px`""" + + border_size: Optional[str] = None + """CSS border width applied to the action button. For example, `1px`""" + + disable_tracking: Optional[bool] = None + """ + When true, the action's href is not rewritten for click-through tracking, even + when click-through tracking is enabled for the workspace. + """ + + font_size: Optional[str] = None + """CSS font-size applied to the action button label. For example, `14px`""" + + locales: Optional[Locales] = None + """Region specific content. + + See + [locales docs](https://www.courier.com/docs/platform/content/elemental/locales/) + for more details. + """ + + padding: Optional[str] = None + """CSS padding applied to the action button. For example, `8px 16px`""" + + style: Optional[Literal["button", "link"]] = None + """Defaults to `button`.""" diff --git a/src/courier/types/shared/elemental_action_node_with_type.py b/src/courier/types/shared/elemental_action_node_with_type.py index f0420ac..a92802f 100644 --- a/src/courier/types/shared/elemental_action_node_with_type.py +++ b/src/courier/types/shared/elemental_action_node_with_type.py @@ -3,10 +3,12 @@ from typing import Optional from typing_extensions import Literal -from .elemental_base_node import ElementalBaseNode +from .elemental_action_node import ElementalActionNode __all__ = ["ElementalActionNodeWithType"] -class ElementalActionNodeWithType(ElementalBaseNode): +class ElementalActionNodeWithType(ElementalActionNode): + """Allows the user to execute an action. Can be a button or a link.""" + type: Optional[Literal["action"]] = None diff --git a/src/courier/types/shared/elemental_channel_node.py b/src/courier/types/shared/elemental_channel_node.py index e820088..439a566 100644 --- a/src/courier/types/shared/elemental_channel_node.py +++ b/src/courier/types/shared/elemental_channel_node.py @@ -9,14 +9,7 @@ class ElementalChannelNode(ElementalBaseNode): """ - The channel element allows a notification to be customized based on which channel it is sent through. - For example, you may want to display a detailed message when the notification is sent through email, - and a more concise message in a push notification. Channel elements are only valid as top-level - elements; you cannot nest channel elements. If there is a channel element specified at the top-level - of the document, all sibling elements must be channel elements. - Note: As an alternative, most elements support a `channel` property. Which allows you to selectively - display an individual element on a per channel basis. See the - [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) for more details. + The channel element allows a notification to be customized based on which channel it is sent through. For example, you may want to display a detailed message when the notification is sent through email, and a more concise message in a push notification. Channel elements are only valid as top-level elements; you cannot nest channel elements. If there is a channel element specified at the top-level of the document, all sibling elements must be channel elements. Note: As an alternative, most elements support a `channel` property. Which allows you to selectively display an individual element on a per channel basis. See the [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) for more details. """ channel: Optional[str] = None diff --git a/src/courier/types/shared/elemental_channel_node_with_type.py b/src/courier/types/shared/elemental_channel_node_with_type.py index 91dd5c0..2ff43b3 100644 --- a/src/courier/types/shared/elemental_channel_node_with_type.py +++ b/src/courier/types/shared/elemental_channel_node_with_type.py @@ -10,14 +10,7 @@ class ElementalChannelNodeWithType(ElementalChannelNode): """ - The channel element allows a notification to be customized based on which channel it is sent through. - For example, you may want to display a detailed message when the notification is sent through email, - and a more concise message in a push notification. Channel elements are only valid as top-level - elements; you cannot nest channel elements. If there is a channel element specified at the top-level - of the document, all sibling elements must be channel elements. - Note: As an alternative, most elements support a `channel` property. Which allows you to selectively - display an individual element on a per channel basis. See the - [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) for more details. + The channel element allows a notification to be customized based on which channel it is sent through. For example, you may want to display a detailed message when the notification is sent through email, and a more concise message in a push notification. Channel elements are only valid as top-level elements; you cannot nest channel elements. If there is a channel element specified at the top-level of the document, all sibling elements must be channel elements. Note: As an alternative, most elements support a `channel` property. Which allows you to selectively display an individual element on a per channel basis. See the [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) for more details. """ type: Optional[Literal["channel"]] = None diff --git a/src/courier/types/shared/elemental_divider_node.py b/src/courier/types/shared/elemental_divider_node.py new file mode 100644 index 0000000..a66f3a6 --- /dev/null +++ b/src/courier/types/shared/elemental_divider_node.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from .elemental_base_node import ElementalBaseNode + +__all__ = ["ElementalDividerNode"] + + +class ElementalDividerNode(ElementalBaseNode): + """Renders a dividing line between elements.""" + + color: Optional[str] = None + """The CSS color to render the line with. For example, `#fff`""" diff --git a/src/courier/types/shared/elemental_divider_node_with_type.py b/src/courier/types/shared/elemental_divider_node_with_type.py index 6b5725e..fceccba 100644 --- a/src/courier/types/shared/elemental_divider_node_with_type.py +++ b/src/courier/types/shared/elemental_divider_node_with_type.py @@ -3,10 +3,12 @@ from typing import Optional from typing_extensions import Literal -from .elemental_base_node import ElementalBaseNode +from .elemental_divider_node import ElementalDividerNode __all__ = ["ElementalDividerNodeWithType"] -class ElementalDividerNodeWithType(ElementalBaseNode): +class ElementalDividerNodeWithType(ElementalDividerNode): + """Renders a dividing line between elements.""" + type: Optional[Literal["divider"]] = None diff --git a/src/courier/types/shared/elemental_html_node.py b/src/courier/types/shared/elemental_html_node.py new file mode 100644 index 0000000..866bcea --- /dev/null +++ b/src/courier/types/shared/elemental_html_node.py @@ -0,0 +1,26 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from .locales import Locales +from .elemental_base_node import ElementalBaseNode + +__all__ = ["ElementalHTMLNode"] + + +class ElementalHTMLNode(ElementalBaseNode): + """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. + """ + + content: str + """Raw HTML string to render inside the notification.""" + + locales: Optional[Locales] = None + """Region specific content. + + See + [locales docs](https://www.courier.com/docs/platform/content/elemental/locales/) + for more details. + """ diff --git a/src/courier/types/shared/elemental_html_node_with_type.py b/src/courier/types/shared/elemental_html_node_with_type.py index 3df93b2..b0a5ad4 100644 --- a/src/courier/types/shared/elemental_html_node_with_type.py +++ b/src/courier/types/shared/elemental_html_node_with_type.py @@ -3,10 +3,15 @@ from typing import Optional from typing_extensions import Literal -from .elemental_base_node import ElementalBaseNode +from .elemental_html_node import ElementalHTMLNode __all__ = ["ElementalHTMLNodeWithType"] -class ElementalHTMLNodeWithType(ElementalBaseNode): +class ElementalHTMLNodeWithType(ElementalHTMLNode): + """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. + """ + type: Optional[Literal["html"]] = None diff --git a/src/courier/types/shared/elemental_image_node.py b/src/courier/types/shared/elemental_image_node.py new file mode 100644 index 0000000..9c2691e --- /dev/null +++ b/src/courier/types/shared/elemental_image_node.py @@ -0,0 +1,38 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .alignment import Alignment +from .elemental_base_node import ElementalBaseNode + +__all__ = ["ElementalImageNode"] + + +class ElementalImageNode(ElementalBaseNode): + """Used to embed an image into the notification.""" + + src: str + """The source of the image.""" + + align: Optional[Alignment] = None + """The alignment of the image.""" + + alt_text: Optional[str] = FieldInfo(alias="altText", default=None) + """Alternate text for the image.""" + + border_color: Optional[str] = None + """CSS border color applied to the image. For example, `#ccc`""" + + border_size: Optional[str] = None + """CSS border width applied to the image. For example, `1px`""" + + href: Optional[str] = None + """A URL to link to when the image is clicked.""" + + padding: Optional[str] = None + """CSS padding applied around the image. For example, `10px`""" + + width: Optional[str] = None + """CSS width properties to apply to the image. For example, 50px""" diff --git a/src/courier/types/shared/elemental_image_node_with_type.py b/src/courier/types/shared/elemental_image_node_with_type.py index 48daaa3..8dc2288 100644 --- a/src/courier/types/shared/elemental_image_node_with_type.py +++ b/src/courier/types/shared/elemental_image_node_with_type.py @@ -3,10 +3,12 @@ from typing import Optional from typing_extensions import Literal -from .elemental_base_node import ElementalBaseNode +from .elemental_image_node import ElementalImageNode __all__ = ["ElementalImageNodeWithType"] -class ElementalImageNodeWithType(ElementalBaseNode): +class ElementalImageNodeWithType(ElementalImageNode): + """Used to embed an image into the notification.""" + type: Optional[Literal["image"]] = None diff --git a/src/courier/types/shared/elemental_meta_node.py b/src/courier/types/shared/elemental_meta_node.py new file mode 100644 index 0000000..22fca60 --- /dev/null +++ b/src/courier/types/shared/elemental_meta_node.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from .elemental_base_node import ElementalBaseNode + +__all__ = ["ElementalMetaNode"] + + +class ElementalMetaNode(ElementalBaseNode): + """ + 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. + """ + + title: Optional[str] = None + """The title to be displayed by supported channels. + + For example, the email subject. + """ diff --git a/src/courier/types/shared/elemental_meta_node_with_type.py b/src/courier/types/shared/elemental_meta_node_with_type.py index 0f8b5c0..e59ef91 100644 --- a/src/courier/types/shared/elemental_meta_node_with_type.py +++ b/src/courier/types/shared/elemental_meta_node_with_type.py @@ -3,10 +3,14 @@ from typing import Optional from typing_extensions import Literal -from .elemental_base_node import ElementalBaseNode +from .elemental_meta_node import ElementalMetaNode __all__ = ["ElementalMetaNodeWithType"] -class ElementalMetaNodeWithType(ElementalBaseNode): +class ElementalMetaNodeWithType(ElementalMetaNode): + """ + 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. + """ + type: Optional[Literal["meta"]] = None diff --git a/src/courier/types/shared/elemental_quote_node.py b/src/courier/types/shared/elemental_quote_node.py new file mode 100644 index 0000000..3c4cb5f --- /dev/null +++ b/src/courier/types/shared/elemental_quote_node.py @@ -0,0 +1,47 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .locales import Locales +from .alignment import Alignment +from .text_style import TextStyle +from .elemental_base_node import ElementalBaseNode + +__all__ = ["ElementalQuoteNode"] + + +class ElementalQuoteNode(ElementalBaseNode): + """Renders a quote block.""" + + content: str + """The text value of the quote.""" + + align: Optional[Alignment] = None + """Alignment of the quote.""" + + border_color: Optional[str] = FieldInfo(alias="borderColor", default=None) + """CSS border color property. For example, `#fff`""" + + font_size: Optional[str] = None + """CSS px font size for this quote block, e.g. + + `16px`. Overrides the size of the `text_style` preset. Email only. + """ + + line_height: Optional[str] = None + """ + CSS line height for this quote block, as a px value or a unitless multiplier, + e.g. `24px` or `1.5`. Email only. + """ + + locales: Optional[Locales] = None + """Region specific content. + + See + [locales docs](https://www.courier.com/docs/platform/content/elemental/locales/) + for more details. + """ + + text_style: Optional[TextStyle] = None diff --git a/src/courier/types/shared/elemental_quote_node_with_type.py b/src/courier/types/shared/elemental_quote_node_with_type.py index 9323d61..b8291a3 100644 --- a/src/courier/types/shared/elemental_quote_node_with_type.py +++ b/src/courier/types/shared/elemental_quote_node_with_type.py @@ -3,10 +3,12 @@ from typing import Optional from typing_extensions import Literal -from .elemental_base_node import ElementalBaseNode +from .elemental_quote_node import ElementalQuoteNode __all__ = ["ElementalQuoteNodeWithType"] -class ElementalQuoteNodeWithType(ElementalBaseNode): +class ElementalQuoteNodeWithType(ElementalQuoteNode): + """Renders a quote block.""" + type: Optional[Literal["quote"]] = None diff --git a/src/courier/types/shared/elemental_text_node.py b/src/courier/types/shared/elemental_text_node.py new file mode 100644 index 0000000..d96c7a7 --- /dev/null +++ b/src/courier/types/shared/elemental_text_node.py @@ -0,0 +1,64 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from .locales import Locales +from .text_style import TextStyle +from .elemental_base_node import ElementalBaseNode + +__all__ = ["ElementalTextNode"] + + +class ElementalTextNode(ElementalBaseNode): + """Represents a body of text to be rendered inside of the notification.""" + + content: str + """The text content displayed in the notification. + + Either this field must be specified, or the elements field + """ + + align: Optional[Literal["left", "center", "right"]] = None + """Text alignment.""" + + bold: Optional[str] = None + """Apply bold to the text""" + + color: Optional[str] = None + """Specifies the color of text. Can be any valid css color value""" + + font_size: Optional[str] = None + """CSS px font size for this text block, e.g. + + `16px`. Overrides the size of the `text_style` preset. Email only. + """ + + format: Optional[Literal["markdown"]] = None + + italic: Optional[str] = None + """Apply italics to the text""" + + line_height: Optional[str] = None + """CSS line height for this text block, as a px value or a unitless multiplier, + e.g. + + `24px` or `1.5`. Email only. + """ + + locales: Optional[Locales] = None + """Region specific content. + + See + [locales docs](https://www.courier.com/docs/platform/content/elemental/locales/) + for more details. + """ + + strikethrough: Optional[str] = None + """Apply a strike through the text""" + + text_style: Optional[TextStyle] = None + """Allows the text to be rendered as a heading level.""" + + underline: Optional[str] = None + """Apply an underline to the text""" diff --git a/src/courier/types/shared/elemental_text_node_with_type.py b/src/courier/types/shared/elemental_text_node_with_type.py index 5e5fd4e..de4400c 100644 --- a/src/courier/types/shared/elemental_text_node_with_type.py +++ b/src/courier/types/shared/elemental_text_node_with_type.py @@ -3,10 +3,12 @@ from typing import Optional from typing_extensions import Literal -from .elemental_base_node import ElementalBaseNode +from .elemental_text_node import ElementalTextNode __all__ = ["ElementalTextNodeWithType"] -class ElementalTextNodeWithType(ElementalBaseNode): +class ElementalTextNodeWithType(ElementalTextNode): + """Represents a body of text to be rendered inside of the notification.""" + type: Optional[Literal["text"]] = None diff --git a/src/courier/types/shared/locales.py b/src/courier/types/shared/locales.py new file mode 100644 index 0000000..d110147 --- /dev/null +++ b/src/courier/types/shared/locales.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict +from typing_extensions import TypeAlias + +from ..._models import BaseModel + +__all__ = ["Locales", "LocalesItem"] + + +class LocalesItem(BaseModel): + content: str + + +Locales: TypeAlias = Dict[str, LocalesItem] diff --git a/src/courier/types/shared_params/__init__.py b/src/courier/types/shared_params/__init__.py index 8ccef58..2464b94 100644 --- a/src/courier/types/shared_params/__init__.py +++ b/src/courier/types/shared_params/__init__.py @@ -4,11 +4,14 @@ from .rule import Rule as Rule from .slack import Slack as Slack from .channel import Channel as Channel +from .locales import Locales as Locales from .metadata import Metadata as Metadata from .ms_teams import MsTeams as MsTeams from .timeouts import Timeouts as Timeouts +from .alignment import Alignment as Alignment from .pagerduty import Pagerduty as Pagerduty from .preference import Preference as Preference +from .text_style import TextStyle as TextStyle from .list_filter import ListFilter as ListFilter from .filter_config import FilterConfig as FilterConfig from .elemental_node import ElementalNode as ElementalNode @@ -31,15 +34,22 @@ from .channel_preference import ChannelPreference as ChannelPreference from .ms_teams_recipient import MsTeamsRecipient as MsTeamsRecipient from .elemental_base_node import ElementalBaseNode as ElementalBaseNode +from .elemental_html_node import ElementalHTMLNode as ElementalHTMLNode +from .elemental_meta_node import ElementalMetaNode as ElementalMetaNode +from .elemental_text_node import ElementalTextNode as ElementalTextNode from .pagerduty_recipient import PagerdutyRecipient as PagerdutyRecipient from .send_to_slack_email import SendToSlackEmail as SendToSlackEmail +from .elemental_image_node import ElementalImageNode as ElementalImageNode +from .elemental_quote_node import ElementalQuoteNode as ElementalQuoteNode from .webhook_profile_type import WebhookProfileType as WebhookProfileType +from .elemental_action_node import ElementalActionNode as ElementalActionNode from .recipient_preferences import RecipientPreferences as RecipientPreferences from .send_to_slack_channel import SendToSlackChannel as SendToSlackChannel from .send_to_slack_user_id import SendToSlackUserID as SendToSlackUserID from .audience_filter_config import AudienceFilterConfig as AudienceFilterConfig from .channel_classification import ChannelClassification as ChannelClassification from .elemental_channel_node import ElementalChannelNode as ElementalChannelNode +from .elemental_divider_node import ElementalDividerNode as ElementalDividerNode from .list_pattern_recipient import ListPatternRecipient as ListPatternRecipient from .message_providers_type import MessageProvidersType as MessageProvidersType from .send_to_ms_teams_email import SendToMsTeamsEmail as SendToMsTeamsEmail diff --git a/src/courier/types/shared_params/alignment.py b/src/courier/types/shared_params/alignment.py new file mode 100644 index 0000000..48a16a5 --- /dev/null +++ b/src/courier/types/shared_params/alignment.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypeAlias + +__all__ = ["Alignment"] + +Alignment: TypeAlias = Literal["center", "left", "right", "full"] diff --git a/src/courier/types/shared_params/elemental_action_node.py b/src/courier/types/shared_params/elemental_action_node.py new file mode 100644 index 0000000..33f342d --- /dev/null +++ b/src/courier/types/shared_params/elemental_action_node.py @@ -0,0 +1,60 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal, Required + +from .locales import Locales +from ..shared.alignment import Alignment +from .elemental_base_node import ElementalBaseNode + +__all__ = ["ElementalActionNode"] + + +class ElementalActionNode(ElementalBaseNode, total=False): + """Allows the user to execute an action. Can be a button or a link.""" + + content: Required[str] + """The text content of the action shown to the user.""" + + href: Required[str] + """The target URL of the action.""" + + action_id: Optional[str] + """A unique id used to identify the action when it is executed.""" + + align: Optional[Alignment] + """The alignment of the action button. Defaults to "center".""" + + background_color: Optional[str] + """The background color of the action button.""" + + border_radius: Optional[str] + """CSS border-radius applied to the action button. For example, `4px`""" + + border_size: Optional[str] + """CSS border width applied to the action button. For example, `1px`""" + + disable_tracking: Optional[bool] + """ + When true, the action's href is not rewritten for click-through tracking, even + when click-through tracking is enabled for the workspace. + """ + + font_size: Optional[str] + """CSS font-size applied to the action button label. For example, `14px`""" + + locales: Optional[Locales] + """Region specific content. + + See + [locales docs](https://www.courier.com/docs/platform/content/elemental/locales/) + for more details. + """ + + padding: Optional[str] + """CSS padding applied to the action button. For example, `8px 16px`""" + + style: Optional[Literal["button", "link"]] + """Defaults to `button`.""" diff --git a/src/courier/types/shared_params/elemental_action_node_with_type.py b/src/courier/types/shared_params/elemental_action_node_with_type.py index 5be216c..c50cad8 100644 --- a/src/courier/types/shared_params/elemental_action_node_with_type.py +++ b/src/courier/types/shared_params/elemental_action_node_with_type.py @@ -4,10 +4,12 @@ from typing_extensions import Literal -from .elemental_base_node import ElementalBaseNode +from .elemental_action_node import ElementalActionNode __all__ = ["ElementalActionNodeWithType"] -class ElementalActionNodeWithType(ElementalBaseNode, total=False): +class ElementalActionNodeWithType(ElementalActionNode, total=False): + """Allows the user to execute an action. Can be a button or a link.""" + type: Literal["action"] diff --git a/src/courier/types/shared_params/elemental_channel_node.py b/src/courier/types/shared_params/elemental_channel_node.py index e26c8ae..ec63f40 100644 --- a/src/courier/types/shared_params/elemental_channel_node.py +++ b/src/courier/types/shared_params/elemental_channel_node.py @@ -11,14 +11,7 @@ class ElementalChannelNode(ElementalBaseNode, total=False): """ - The channel element allows a notification to be customized based on which channel it is sent through. - For example, you may want to display a detailed message when the notification is sent through email, - and a more concise message in a push notification. Channel elements are only valid as top-level - elements; you cannot nest channel elements. If there is a channel element specified at the top-level - of the document, all sibling elements must be channel elements. - Note: As an alternative, most elements support a `channel` property. Which allows you to selectively - display an individual element on a per channel basis. See the - [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) for more details. + The channel element allows a notification to be customized based on which channel it is sent through. For example, you may want to display a detailed message when the notification is sent through email, and a more concise message in a push notification. Channel elements are only valid as top-level elements; you cannot nest channel elements. If there is a channel element specified at the top-level of the document, all sibling elements must be channel elements. Note: As an alternative, most elements support a `channel` property. Which allows you to selectively display an individual element on a per channel basis. See the [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) for more details. """ channel: str diff --git a/src/courier/types/shared_params/elemental_channel_node_with_type.py b/src/courier/types/shared_params/elemental_channel_node_with_type.py index 777b021..33f046f 100644 --- a/src/courier/types/shared_params/elemental_channel_node_with_type.py +++ b/src/courier/types/shared_params/elemental_channel_node_with_type.py @@ -11,14 +11,7 @@ class ElementalChannelNodeWithType(ElementalChannelNode, total=False): """ - The channel element allows a notification to be customized based on which channel it is sent through. - For example, you may want to display a detailed message when the notification is sent through email, - and a more concise message in a push notification. Channel elements are only valid as top-level - elements; you cannot nest channel elements. If there is a channel element specified at the top-level - of the document, all sibling elements must be channel elements. - Note: As an alternative, most elements support a `channel` property. Which allows you to selectively - display an individual element on a per channel basis. See the - [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) for more details. + The channel element allows a notification to be customized based on which channel it is sent through. For example, you may want to display a detailed message when the notification is sent through email, and a more concise message in a push notification. Channel elements are only valid as top-level elements; you cannot nest channel elements. If there is a channel element specified at the top-level of the document, all sibling elements must be channel elements. Note: As an alternative, most elements support a `channel` property. Which allows you to selectively display an individual element on a per channel basis. See the [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) for more details. """ type: Literal["channel"] diff --git a/src/courier/types/shared_params/elemental_divider_node.py b/src/courier/types/shared_params/elemental_divider_node.py new file mode 100644 index 0000000..c602a87 --- /dev/null +++ b/src/courier/types/shared_params/elemental_divider_node.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional + +from .elemental_base_node import ElementalBaseNode + +__all__ = ["ElementalDividerNode"] + + +class ElementalDividerNode(ElementalBaseNode, total=False): + """Renders a dividing line between elements.""" + + color: Optional[str] + """The CSS color to render the line with. For example, `#fff`""" diff --git a/src/courier/types/shared_params/elemental_divider_node_with_type.py b/src/courier/types/shared_params/elemental_divider_node_with_type.py index 67cc64e..101b391 100644 --- a/src/courier/types/shared_params/elemental_divider_node_with_type.py +++ b/src/courier/types/shared_params/elemental_divider_node_with_type.py @@ -4,10 +4,12 @@ from typing_extensions import Literal -from .elemental_base_node import ElementalBaseNode +from .elemental_divider_node import ElementalDividerNode __all__ = ["ElementalDividerNodeWithType"] -class ElementalDividerNodeWithType(ElementalBaseNode, total=False): +class ElementalDividerNodeWithType(ElementalDividerNode, total=False): + """Renders a dividing line between elements.""" + type: Literal["divider"] diff --git a/src/courier/types/shared_params/elemental_html_node.py b/src/courier/types/shared_params/elemental_html_node.py new file mode 100644 index 0000000..45373b6 --- /dev/null +++ b/src/courier/types/shared_params/elemental_html_node.py @@ -0,0 +1,29 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Required + +from .locales import Locales +from .elemental_base_node import ElementalBaseNode + +__all__ = ["ElementalHTMLNode"] + + +class ElementalHTMLNode(ElementalBaseNode, total=False): + """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. + """ + + content: Required[str] + """Raw HTML string to render inside the notification.""" + + locales: Optional[Locales] + """Region specific content. + + See + [locales docs](https://www.courier.com/docs/platform/content/elemental/locales/) + for more details. + """ diff --git a/src/courier/types/shared_params/elemental_html_node_with_type.py b/src/courier/types/shared_params/elemental_html_node_with_type.py index 65f5fab..90735bb 100644 --- a/src/courier/types/shared_params/elemental_html_node_with_type.py +++ b/src/courier/types/shared_params/elemental_html_node_with_type.py @@ -4,10 +4,15 @@ from typing_extensions import Literal -from .elemental_base_node import ElementalBaseNode +from .elemental_html_node import ElementalHTMLNode __all__ = ["ElementalHTMLNodeWithType"] -class ElementalHTMLNodeWithType(ElementalBaseNode, total=False): +class ElementalHTMLNodeWithType(ElementalHTMLNode, total=False): + """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. + """ + type: Literal["html"] diff --git a/src/courier/types/shared_params/elemental_image_node.py b/src/courier/types/shared_params/elemental_image_node.py new file mode 100644 index 0000000..ed4d58e --- /dev/null +++ b/src/courier/types/shared_params/elemental_image_node.py @@ -0,0 +1,40 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Required, Annotated + +from ..._utils import PropertyInfo +from ..shared.alignment import Alignment +from .elemental_base_node import ElementalBaseNode + +__all__ = ["ElementalImageNode"] + + +class ElementalImageNode(ElementalBaseNode, total=False): + """Used to embed an image into the notification.""" + + src: Required[str] + """The source of the image.""" + + align: Optional[Alignment] + """The alignment of the image.""" + + alt_text: Annotated[Optional[str], PropertyInfo(alias="altText")] + """Alternate text for the image.""" + + border_color: Optional[str] + """CSS border color applied to the image. For example, `#ccc`""" + + border_size: Optional[str] + """CSS border width applied to the image. For example, `1px`""" + + href: Optional[str] + """A URL to link to when the image is clicked.""" + + padding: Optional[str] + """CSS padding applied around the image. For example, `10px`""" + + width: Optional[str] + """CSS width properties to apply to the image. For example, 50px""" diff --git a/src/courier/types/shared_params/elemental_image_node_with_type.py b/src/courier/types/shared_params/elemental_image_node_with_type.py index 2f2a0f9..04961f9 100644 --- a/src/courier/types/shared_params/elemental_image_node_with_type.py +++ b/src/courier/types/shared_params/elemental_image_node_with_type.py @@ -4,10 +4,12 @@ from typing_extensions import Literal -from .elemental_base_node import ElementalBaseNode +from .elemental_image_node import ElementalImageNode __all__ = ["ElementalImageNodeWithType"] -class ElementalImageNodeWithType(ElementalBaseNode, total=False): +class ElementalImageNodeWithType(ElementalImageNode, total=False): + """Used to embed an image into the notification.""" + type: Literal["image"] diff --git a/src/courier/types/shared_params/elemental_meta_node.py b/src/courier/types/shared_params/elemental_meta_node.py new file mode 100644 index 0000000..9fec6aa --- /dev/null +++ b/src/courier/types/shared_params/elemental_meta_node.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional + +from .elemental_base_node import ElementalBaseNode + +__all__ = ["ElementalMetaNode"] + + +class ElementalMetaNode(ElementalBaseNode, total=False): + """ + 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. + """ + + title: Optional[str] + """The title to be displayed by supported channels. + + For example, the email subject. + """ diff --git a/src/courier/types/shared_params/elemental_meta_node_with_type.py b/src/courier/types/shared_params/elemental_meta_node_with_type.py index c7ae4c1..c42679e 100644 --- a/src/courier/types/shared_params/elemental_meta_node_with_type.py +++ b/src/courier/types/shared_params/elemental_meta_node_with_type.py @@ -4,10 +4,14 @@ from typing_extensions import Literal -from .elemental_base_node import ElementalBaseNode +from .elemental_meta_node import ElementalMetaNode __all__ = ["ElementalMetaNodeWithType"] -class ElementalMetaNodeWithType(ElementalBaseNode, total=False): +class ElementalMetaNodeWithType(ElementalMetaNode, total=False): + """ + 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. + """ + type: Literal["meta"] diff --git a/src/courier/types/shared_params/elemental_quote_node.py b/src/courier/types/shared_params/elemental_quote_node.py new file mode 100644 index 0000000..33817ff --- /dev/null +++ b/src/courier/types/shared_params/elemental_quote_node.py @@ -0,0 +1,49 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Required, Annotated + +from .locales import Locales +from ..._utils import PropertyInfo +from ..shared.alignment import Alignment +from ..shared.text_style import TextStyle +from .elemental_base_node import ElementalBaseNode + +__all__ = ["ElementalQuoteNode"] + + +class ElementalQuoteNode(ElementalBaseNode, total=False): + """Renders a quote block.""" + + content: Required[str] + """The text value of the quote.""" + + align: Optional[Alignment] + """Alignment of the quote.""" + + border_color: Annotated[Optional[str], PropertyInfo(alias="borderColor")] + """CSS border color property. For example, `#fff`""" + + font_size: Optional[str] + """CSS px font size for this quote block, e.g. + + `16px`. Overrides the size of the `text_style` preset. Email only. + """ + + line_height: Optional[str] + """ + CSS line height for this quote block, as a px value or a unitless multiplier, + e.g. `24px` or `1.5`. Email only. + """ + + locales: Optional[Locales] + """Region specific content. + + See + [locales docs](https://www.courier.com/docs/platform/content/elemental/locales/) + for more details. + """ + + text_style: TextStyle diff --git a/src/courier/types/shared_params/elemental_quote_node_with_type.py b/src/courier/types/shared_params/elemental_quote_node_with_type.py index de0ea24..1456cfe 100644 --- a/src/courier/types/shared_params/elemental_quote_node_with_type.py +++ b/src/courier/types/shared_params/elemental_quote_node_with_type.py @@ -4,10 +4,12 @@ from typing_extensions import Literal -from .elemental_base_node import ElementalBaseNode +from .elemental_quote_node import ElementalQuoteNode __all__ = ["ElementalQuoteNodeWithType"] -class ElementalQuoteNodeWithType(ElementalBaseNode, total=False): +class ElementalQuoteNodeWithType(ElementalQuoteNode, total=False): + """Renders a quote block.""" + type: Literal["quote"] diff --git a/src/courier/types/shared_params/elemental_text_node.py b/src/courier/types/shared_params/elemental_text_node.py new file mode 100644 index 0000000..d13a765 --- /dev/null +++ b/src/courier/types/shared_params/elemental_text_node.py @@ -0,0 +1,66 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal, Required + +from .locales import Locales +from ..shared.text_style import TextStyle +from .elemental_base_node import ElementalBaseNode + +__all__ = ["ElementalTextNode"] + + +class ElementalTextNode(ElementalBaseNode, total=False): + """Represents a body of text to be rendered inside of the notification.""" + + content: Required[str] + """The text content displayed in the notification. + + Either this field must be specified, or the elements field + """ + + align: Literal["left", "center", "right"] + """Text alignment.""" + + bold: Optional[str] + """Apply bold to the text""" + + color: Optional[str] + """Specifies the color of text. Can be any valid css color value""" + + font_size: Optional[str] + """CSS px font size for this text block, e.g. + + `16px`. Overrides the size of the `text_style` preset. Email only. + """ + + format: Optional[Literal["markdown"]] + + italic: Optional[str] + """Apply italics to the text""" + + line_height: Optional[str] + """CSS line height for this text block, as a px value or a unitless multiplier, + e.g. + + `24px` or `1.5`. Email only. + """ + + locales: Optional[Locales] + """Region specific content. + + See + [locales docs](https://www.courier.com/docs/platform/content/elemental/locales/) + for more details. + """ + + strikethrough: Optional[str] + """Apply a strike through the text""" + + text_style: Optional[TextStyle] + """Allows the text to be rendered as a heading level.""" + + underline: Optional[str] + """Apply an underline to the text""" diff --git a/src/courier/types/shared_params/elemental_text_node_with_type.py b/src/courier/types/shared_params/elemental_text_node_with_type.py index ffd8940..8c774b4 100644 --- a/src/courier/types/shared_params/elemental_text_node_with_type.py +++ b/src/courier/types/shared_params/elemental_text_node_with_type.py @@ -4,10 +4,12 @@ from typing_extensions import Literal -from .elemental_base_node import ElementalBaseNode +from .elemental_text_node import ElementalTextNode __all__ = ["ElementalTextNodeWithType"] -class ElementalTextNodeWithType(ElementalBaseNode, total=False): +class ElementalTextNodeWithType(ElementalTextNode, total=False): + """Represents a body of text to be rendered inside of the notification.""" + type: Literal["text"] diff --git a/src/courier/types/shared_params/locales.py b/src/courier/types/shared_params/locales.py new file mode 100644 index 0000000..ec43959 --- /dev/null +++ b/src/courier/types/shared_params/locales.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Required, TypeAlias, TypedDict + +__all__ = ["Locales", "LocalesItem"] + + +class LocalesItem(TypedDict, total=False): + content: Required[str] + + +Locales: TypeAlias = Dict[str, LocalesItem] diff --git a/src/courier/types/shared_params/text_style.py b/src/courier/types/shared_params/text_style.py new file mode 100644 index 0000000..8f7f2c4 --- /dev/null +++ b/src/courier/types/shared_params/text_style.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypeAlias + +__all__ = ["TextStyle"] + +TextStyle: TypeAlias = Literal["text", "h1", "h2", "subtext"] diff --git a/tests/api_resources/journeys/test_templates.py b/tests/api_resources/journeys/test_templates.py index bde3602..dd103a1 100644 --- a/tests/api_resources/journeys/test_templates.py +++ b/tests/api_resources/journeys/test_templates.py @@ -51,15 +51,7 @@ def test_method_create_with_all_params(self, client: Courier) -> None: notification={ "brand": {"id": "id"}, "content": { - "elements": [ - { - "channels": ["string"], - "if": "if", - "loop": "loop", - "ref": "ref", - "type": "text", - } - ], + "elements": [{"type": "text"}], "version": "2022-01-01", "scope": "default", }, @@ -594,15 +586,7 @@ def test_method_replace_with_all_params(self, client: Courier) -> None: notification={ "brand": {"id": "id"}, "content": { - "elements": [ - { - "channels": ["string"], - "if": "if", - "loop": "loop", - "ref": "ref", - "type": "text", - } - ], + "elements": [{"type": "text"}], "version": "2022-01-01", "scope": "default", }, @@ -793,15 +777,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCourier) - notification={ "brand": {"id": "id"}, "content": { - "elements": [ - { - "channels": ["string"], - "if": "if", - "loop": "loop", - "ref": "ref", - "type": "text", - } - ], + "elements": [{"type": "text"}], "version": "2022-01-01", "scope": "default", }, @@ -1336,15 +1312,7 @@ async def test_method_replace_with_all_params(self, async_client: AsyncCourier) notification={ "brand": {"id": "id"}, "content": { - "elements": [ - { - "channels": ["string"], - "if": "if", - "loop": "loop", - "ref": "ref", - "type": "text", - } - ], + "elements": [{"type": "text"}], "version": "2022-01-01", "scope": "default", }, diff --git a/tests/api_resources/tenants/test_templates.py b/tests/api_resources/tenants/test_templates.py index bf78691..876b3bc 100644 --- a/tests/api_resources/tenants/test_templates.py +++ b/tests/api_resources/tenants/test_templates.py @@ -265,15 +265,7 @@ def test_method_replace_with_all_params(self, client: Courier) -> None: tenant_id="tenant_id", template={ "content": { - "elements": [ - { - "channels": ["string"], - "if": "if", - "loop": "loop", - "ref": "ref", - "type": "text", - } - ], + "elements": [{"type": "text"}], "version": "2022-01-01", }, "channels": { @@ -637,15 +629,7 @@ async def test_method_replace_with_all_params(self, async_client: AsyncCourier) tenant_id="tenant_id", template={ "content": { - "elements": [ - { - "channels": ["string"], - "if": "if", - "loop": "loop", - "ref": "ref", - "type": "text", - } - ], + "elements": [{"type": "text"}], "version": "2022-01-01", }, "channels": { diff --git a/tests/api_resources/test_broadcasts.py b/tests/api_resources/test_broadcasts.py index cc57f88..0b95d49 100644 --- a/tests/api_resources/test_broadcasts.py +++ b/tests/api_resources/test_broadcasts.py @@ -325,22 +325,7 @@ def test_method_put_content_with_all_params(self, client: Courier) -> None: broadcast = client.broadcasts.put_content( broadcast_id="broadcastId", content={ - "elements": [ - { - "channels": ["string"], - "if": "if", - "loop": "loop", - "ref": "ref", - "type": "meta", - }, - { - "channels": ["string"], - "if": "if", - "loop": "loop", - "ref": "ref", - "type": "text", - }, - ], + "elements": [{"type": "meta"}, {"type": "text"}], "version": "2022-01-01", }, state="DRAFT", @@ -860,22 +845,7 @@ async def test_method_put_content_with_all_params(self, async_client: AsyncCouri broadcast = await async_client.broadcasts.put_content( broadcast_id="broadcastId", content={ - "elements": [ - { - "channels": ["string"], - "if": "if", - "loop": "loop", - "ref": "ref", - "type": "meta", - }, - { - "channels": ["string"], - "if": "if", - "loop": "loop", - "ref": "ref", - "type": "text", - }, - ], + "elements": [{"type": "meta"}, {"type": "text"}], "version": "2022-01-01", }, state="DRAFT",