Skip to content

Sending Messages

django_slack_tools.slack_messages.shortcuts

Handy APIs for sending Slack messages.

slack_message(to, *, messenger_name=None, header=None, template=None, context=None, message=None)

slack_message(
    to: str,
    *,
    messenger_name: str | None = None,
    header: MessageHeader | dict[str, Any] | None = None,
    message: str,
) -> MessageResponse | None
slack_message(
    to: str,
    *,
    messenger_name: str | None = None,
    header: MessageHeader | dict[str, Any] | None = None,
    template: str | None = None,
    context: dict[str, Any] | None = None,
) -> MessageResponse | None

Shortcut for sending a Slack message.

Parameters:

Name Type Description Default
to str

Recipient.

required
messenger_name str | None

Messenger name. If not set, default messenger is used.

None
header MessageHeader | dict[str, Any] | None

Slack message control header.

None
template str | None

Message template key. Cannot be used with message.

None
context dict[str, Any] | None

Context for rendering the template. Only used with template.

None
message str | None

Simple message text. Cannot be used with template.

None

Returns:

Type Description
MessageResponse | None

Sent message instance or None.

Source code in django_slack_tools/slack_messages/shortcuts.py
def slack_message(  # noqa: PLR0913
    to: str,
    *,
    messenger_name: str | None = None,
    header: MessageHeader | dict[str, Any] | None = None,
    template: str | None = None,
    context: dict[str, Any] | None = None,
    message: str | None = None,
) -> MessageResponse | None:
    """Shortcut for sending a Slack message.

    Args:
        to: Recipient.
        messenger_name: Messenger name. If not set, default messenger is used.
        header: Slack message control header.
        template: Message template key. Cannot be used with `message`.
        context: Context for rendering the template. Only used with `template`.
        message: Simple message text. Cannot be used with `template`.

    Returns:
        Sent message instance or `None`.
    """
    if (template and message) or (not template and not message):
        msg = "Either `template` or `message` must be set, but not both."
        raise ValueError(msg)

    messenger = get_messenger(messenger_name)
    header = MessageHeader.from_any(header)

    if message:
        request = MessageRequest(
            channel=to,
            header=header,
            body=MessageBody(text=message),
            template_key=None,
            context={},
        )
        return messenger.send_request(request)

    context = context or {}
    return messenger.send(to, header=header, template=template, context=context)

django_slack_tools.slack_messages.request

MessageBody

Bases: BaseModel

Source code in django_slack_tools/slack_messages/request.py
class MessageBody(BaseModel):  # noqa: D101
    model_config = ConfigDict(extra="forbid")

    attachments: Optional[List[dict]] = None

    # See more about blocks at https://api.slack.com/reference/block-kit/blocks
    blocks: Optional[list[dict]] = None

    text: Optional[str] = None
    icon_emoji: Optional[str] = None
    icon_url: Optional[str] = None
    metadata: Optional[dict] = None
    username: Optional[str] = None

    @model_validator(mode="after")
    def _check_at_least_one_field_is_set(self) -> MessageBody:
        if not any((self.attachments, self.blocks, self.text)):
            msg = "At least one of `attachments`, `blocks` and `text` must set"
            raise ValueError(msg)

        return self

    @classmethod
    def from_any(cls, obj: str | MessageBody | dict[str, Any]) -> MessageBody:
        """Create instance from compatible types."""
        if isinstance(obj, cls):
            return obj

        if isinstance(obj, dict):
            return cls.model_validate(obj)

        if isinstance(obj, str):
            return cls(text=obj)

        msg = f"Unsupported type {type(obj)}"
        raise TypeError(msg)

from_any(obj) classmethod

Create instance from compatible types.

Source code in django_slack_tools/slack_messages/request.py
@classmethod
def from_any(cls, obj: str | MessageBody | dict[str, Any]) -> MessageBody:
    """Create instance from compatible types."""
    if isinstance(obj, cls):
        return obj

    if isinstance(obj, dict):
        return cls.model_validate(obj)

    if isinstance(obj, str):
        return cls(text=obj)

    msg = f"Unsupported type {type(obj)}"
    raise TypeError(msg)

MessageHeader

Bases: BaseModel

Source code in django_slack_tools/slack_messages/request.py
class MessageHeader(BaseModel):  # noqa: D101
    model_config = ConfigDict(extra="forbid")

    mrkdwn: Optional[str] = None
    parse: Optional[str] = None
    reply_broadcast: Optional[bool] = None
    thread_ts: Optional[str] = None
    unfurl_links: Optional[bool] = None
    unfurl_media: Optional[bool] = None

    @classmethod
    def from_any(cls, obj: MessageHeader | dict[str, Any] | None = None) -> MessageHeader:
        """Create instance from compatible types."""
        if isinstance(obj, cls):
            return obj

        if isinstance(obj, dict):
            return cls.model_validate(obj)

        if obj is None:
            return cls()

        msg = f"Unsupported type {type(obj)}"
        raise TypeError(msg)

from_any(obj=None) classmethod

Create instance from compatible types.

Source code in django_slack_tools/slack_messages/request.py
@classmethod
def from_any(cls, obj: MessageHeader | dict[str, Any] | None = None) -> MessageHeader:
    """Create instance from compatible types."""
    if isinstance(obj, cls):
        return obj

    if isinstance(obj, dict):
        return cls.model_validate(obj)

    if obj is None:
        return cls()

    msg = f"Unsupported type {type(obj)}"
    raise TypeError(msg)

MessageRequest

Bases: BaseModel

Message request object.

Source code in django_slack_tools/slack_messages/request.py
class MessageRequest(BaseModel):
    """Message request object."""

    model_config = ConfigDict(extra="forbid")

    id_: str = Field(default_factory=lambda: str(uuid.uuid4()))
    channel: Any

    # Template key is optional to allow lazy initialization of the template key
    template_key: Optional[str]

    context: Dict[str, Any]
    header: MessageHeader

    # Also, the body is optional because it is rendered from the template
    body: Optional[MessageBody] = None

django_slack_tools.slack_messages.response

MessageResponse

Bases: BaseModel

Response from a messaging backend.

Source code in django_slack_tools/slack_messages/response.py
class MessageResponse(BaseModel):
    """Response from a messaging backend."""

    request: Optional[MessageRequest] = None
    ok: bool
    error: Optional[Any] = None
    data: Any
    ts: Optional[str] = None
    parent_ts: Optional[str] = None