slack ¤
admin ¤
ConversationAdmin ¤
Bases: ModelAdmin[Conversation]
get_queryset ¤
Restrict the queryset to only include conversations that are not IncidentChannels. Incident channels are managed in the IncidentChannelAdmin.
Source code in src/firefighter/slack/admin.py
ask_key_timestamps ¤
ask_key_timestamps(self: firefighter.incidents.admin.IncidentAdmin, request: HttpRequest, queryset: QuerySet[Incident]) -> None
Will send a message to the Incident conversation (if it exists) to ask for key events. TODO Error handling.
Source code in src/firefighter/slack/admin.py
messages ¤
base ¤
SlackMessageStrategy ¤
Bases: Enum
Define how should the message be posted.
append
: add the message to the channel, even if a message with the same type has already been posted.replace
: replace the last message with the same type (push new one, delete old one)update
: update in place the last message with the same type
SlackMessageSurface ¤
Bases: ABC
Base class for Slack messages, which are sent to a channel or a user.
This provides a common interface to send messages with text, blocks and metadata.
This is helpful to send messages but also to save them in DB.
Source code in src/firefighter/slack/messages/base.py
strategy
class-attribute
instance-attribute
¤
Alphanumeric ID, starting with a letter, that may contain underscores.
get_blocks ¤
Returns the blocks of the message.
Returns:
-
list[Block]
–list[Block]: List of Slack Blocks for the message. Default is the text as a SectionBlock.
get_metadata ¤
The value of event_type
should be an alphanumeric string, and human-readable. The value of this field may appear in the UI to developers, so keep this in mind when choosing a value. Developers should make an effort to name with the pattern
Returns:
-
Metadata
(Metadata
) –Slack Metadata for the message.
Source code in src/firefighter/slack/messages/base.py
get_text
abstractmethod
¤
post_message ¤
post_message(conversation_id: str, client: WebClient = DefaultWebClient, **kwargs: Never) -> SlackResponse
Deprecated. Only use for Global Channel, until the global channel is set in DB.
Source code in src/firefighter/slack/messages/base.py
slack_messages ¤
SlackMessageIncidentDeclaredAnnouncementGeneral ¤
Bases: SlackMessageSurface
Parameters:
-
incident
(Incident
) –Your incident
Source code in src/firefighter/slack/messages/slack_messages.py
strategy
class-attribute
instance-attribute
¤
Alphanumeric ID, starting with a letter, that may contain underscores.
get_metadata ¤
The value of event_type
should be an alphanumeric string, and human-readable. The value of this field may appear in the UI to developers, so keep this in mind when choosing a value. Developers should make an effort to name with the pattern
Returns:
-
Metadata
(Metadata
) –Slack Metadata for the message.
Source code in src/firefighter/slack/messages/base.py
post_message ¤
post_message(conversation_id: str, client: WebClient = DefaultWebClient, **kwargs: Never) -> SlackResponse
Deprecated. Only use for Global Channel, until the global channel is set in DB.
Source code in src/firefighter/slack/messages/base.py
SlackMessageIncidentRolesUpdated ¤
SlackMessageIncidentRolesUpdated(
incident: Incident, incident_update: IncidentUpdate | None, *, first_update: bool = False, updated_fields: list[str] | None = None
)
Bases: SlackMessageSurface
The message to post in the incident channel when the roles are updated.
Parameters:
-
incident
(Incident
) –Your incident.
-
incident_update
(IncidentUpdate
) –The opening incident update.
-
first_update
(bool
, default:False
) –Whether this is the first update of the incident. Defaults to False.
-
updated_fields
(list[str]
, default:None
) –The fields that were updated. Defaults to None.
Source code in src/firefighter/slack/messages/slack_messages.py
strategy
class-attribute
instance-attribute
¤
Alphanumeric ID, starting with a letter, that may contain underscores.
post_message ¤
post_message(conversation_id: str, client: WebClient = DefaultWebClient, **kwargs: Never) -> SlackResponse
Deprecated. Only use for Global Channel, until the global channel is set in DB.
Source code in src/firefighter/slack/messages/base.py
models ¤
conversation ¤
Conversation ¤
Bases: Model
Model a Slack API Conversation. A Slack Conversation can be a public channel, a private channel, a direct message, or a multi-person direct message. Reference: https://api.slack.com/types/conversation.
add_bookmark ¤
add_bookmark(
title: str,
_type: str = "link",
emoji: str | None = None,
entity_id: str | None = None,
link: str | None = None,
parent_id: str | None = None,
client: WebClient = DefaultWebClient,
**kwargs: Any
) -> None
Convenience method to add a bookmark on this conversation.
Source code in src/firefighter/slack/models/conversation.py
send_message ¤
send_message(
text: str | None = None, blocks: Sequence[dict[str, Any] | Block] | None = None, client: WebClient = DefaultWebClient, **kwargs: Any
) -> None
Convenience method to send a message on this conversation.
Source code in src/firefighter/slack/models/conversation.py
send_message_and_save ¤
send_message_and_save(
message: SlackMessageSurface,
client: WebClient = DefaultWebClient,
strategy: SlackMessageStrategy | None = None,
strategy_args: dict[str, Any] | None = None,
*,
pin: bool = False
) -> SlackResponse
Convenience method to send a message on this conversation.
Source code in src/firefighter/slack/models/conversation.py
send_message_ephemeral ¤
send_message_ephemeral(message: SlackMessageSurface, user: SlackUser | str, client: WebClient = DefaultWebClient, **kwargs: Any) -> None
Convenience method to send an ephemeral message on this conversation.
user
, channel
, blocks
, text
and metadata
should not be passed in kwargs.
Source code in src/firefighter/slack/models/conversation.py
incident_channel ¤
IncidentChannel ¤
Bases: Conversation
add_bookmark ¤
add_bookmark(
title: str,
_type: str = "link",
emoji: str | None = None,
entity_id: str | None = None,
link: str | None = None,
parent_id: str | None = None,
client: WebClient = DefaultWebClient,
**kwargs: Any
) -> None
Convenience method to add a bookmark on this conversation.
Source code in src/firefighter/slack/models/conversation.py
invite_users ¤
Invite users to the conversation, if they have a Slack user linked and are active.
Try to invite all users as batch, but if some fail, continue individually.
Source code in src/firefighter/slack/models/incident_channel.py
send_message ¤
send_message(
text: str | None = None, blocks: Sequence[dict[str, Any] | Block] | None = None, client: WebClient = DefaultWebClient, **kwargs: Any
) -> None
Convenience method to send a message on this conversation.
Source code in src/firefighter/slack/models/conversation.py
send_message_and_save ¤
send_message_and_save(
message: SlackMessageSurface,
client: WebClient = DefaultWebClient,
strategy: SlackMessageStrategy | None = None,
strategy_args: dict[str, Any] | None = None,
*,
pin: bool = False
) -> SlackResponse
Convenience method to send a message on this conversation.
Source code in src/firefighter/slack/models/conversation.py
send_message_ephemeral ¤
send_message_ephemeral(message: SlackMessageSurface, user: SlackUser | str, client: WebClient = DefaultWebClient, **kwargs: Any) -> None
Convenience method to send an ephemeral message on this conversation.
user
, channel
, blocks
, text
and metadata
should not be passed in kwargs.
Source code in src/firefighter/slack/models/conversation.py
message ¤
Message ¤
Bases: Model
Model a Slack API Conversation. A Slack Conversation can be a public channel, a private channel, a direct message, or a multi-person direct message. Reference: https://api.slack.com/types/conversation.
sos ¤
Sos ¤
Bases: Model
A SOS is a target with a name, a conversation, and optionally a user group.
Incident responders can use it with /incident sos
to ask for help to a specific group of people.
Helpers will be notified in the selected conversation, and the user group will be mentioned (or @here
if no user group is selected)
usergroup_slack_fmt
property
¤
Returns either @usergroup
or @here
depending on usergroup presence.
user ¤
SlackUser ¤
Bases: Model
Holds data about a Slack User, linked to an :model:incidents.user
.
slack_id field is not used as PK, as it is only guaranteed by Slack to be unique in pair with a team_id.
url
property
¤
Returns an HTTPS ULR to the Slack user's profile. For deep linking, use link
instead.
send_private_message ¤
send_private_message(message: SlackMessageSurface, client: WebClient = DefaultWebClient, **kwargs: Any) -> None
Send a private message to the user.
Source code in src/firefighter/slack/models/user.py
SlackUserManager ¤
Bases: Manager['SlackUser']
get_user_by_slack_id ¤
get_user_by_slack_id(slack_id: str, defaults: dict[str, str] | None = None, client: WebClient = DefaultWebClient) -> User | None
Returns a User from DB if it exists, or fetch its info from Slack, save it to DB and returns it.
Source code in src/firefighter/slack/models/user.py
unpack_user_info
staticmethod
¤
Returns a dict contains fields for the SlackUser, from a SlackResponse. email, name and id should always be returned.
Source code in src/firefighter/slack/models/user.py
upsert_by_email ¤
Returns a User from DB if it exists, or fetch its info from Slack, save it to DB and returns it.
Source code in src/firefighter/slack/models/user.py
user_group ¤
UserGroup ¤
UserGroupManager ¤
Bases: Manager['UserGroup']
fetch_all_usergroups_data
staticmethod
¤
fetch_all_usergroups_data(client: WebClient = DefaultWebClient, *, include_users: bool = False) -> list[dict[str, Any]]
Fetch all usergroups from firefighter.slack.
Returns the list of usergroups
Source code in src/firefighter/slack/models/user_group.py
fetch_usergroup
staticmethod
¤
fetch_usergroup(
group_slack_id: str | None = None, group_handle: str | None = None, client: WebClient = DefaultWebClient, **kwargs: Any
) -> UserGroup | None
Import a "usergroup" from Slack and return its UserGroup model. Either group_slack_id or group_handle must be provided.
Parameters:
-
group_slack_id
(str | None
, default:None
) –The Slack usergroup id of the usergroup to import. Usually starts with
S
. Defaults to None. -
group_handle
(str | None
, default:None
) –Handle (@xxx) of the usergroup to import. Defaults to None.
-
client
(WebClient
, default:DefaultWebClient
) –Slack client. Defaults to DefaultWebClient.
-
**kwargs
(Any
, default:{}
) –Additional keyword arguments to pass to created UserGroup model.
Returns:
-
UserGroup | None
–UserGroup | None: UserGroup model or None if not found
Source code in src/firefighter/slack/models/user_group.py
rules ¤
Rules for publishing incidents in channels.
This module may be removed in a future version.
signals ¤
create_incident_conversation ¤
This module contains the logic to open an incident channel and invite responders.
XXX It might be divided into two signals/tasks, one for creating, one for inviting. XXX Sending the end signal should be done by this signal's caller, not by this signal receiver directly.
create_incident_slack_conversation ¤
Main process to open an incident channel, set it up and invite responders. It MUST be called when an incident is created.
Parameters:
-
incident
(Incident
) –The incident to open. It should be saved before calling this function, and have its first incident update created.
Source code in src/firefighter/slack/signals/create_incident_conversation.py
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
|
get_users ¤
get_invites_from_slack ¤
New version using cached users instead of querying Slack API.
Source code in src/firefighter/slack/signals/get_users.py
handle_incident_channel_done ¤
incident_closed ¤
incident_updated ¤
publish_status_update ¤
publish_status_update(
incident: Incident, incident_update: IncidentUpdate, *, status_changed: bool = False, old_priority: Priority | None = None
) -> None
Publishes an update to the incident status.
Source code in src/firefighter/slack/signals/incident_updated.py
postmortem_created ¤
roles_reminders ¤
slack_app ¤
SlackApp ¤
Bases: App
Subclass of the Slack App, as a singleton.
slack_client ¤
Adds a Slack client in client
kwargs, if none is provided.
Can be used as a decorator with @slack_client
or as a function with slack_client(function)
.
Source code in src/firefighter/slack/slack_app.py
slack_incident_context ¤
get_incident_from_app_home_element ¤
Get an incident from an action, found in app home accessory.
Source code in src/firefighter/slack/slack_incident_context.py
get_incident_from_body_channel_id_in_command ¤
Get an incident from a channel_id, found in commands.
Source code in src/firefighter/slack/slack_incident_context.py
get_incident_from_body_channel_id_in_message_shortcut ¤
Get an incident from a channel.id, found in message shortcut.
Source code in src/firefighter/slack/slack_incident_context.py
get_incident_from_button_value ¤
Try to get the incident ID from button value.
Source code in src/firefighter/slack/slack_incident_context.py
get_incident_from_context ¤
Returns an Incident or None, from a Slack body.
Source code in src/firefighter/slack/slack_incident_context.py
get_incident_from_view_action ¤
Get incident id from select incident in modal.
Source code in src/firefighter/slack/slack_incident_context.py
get_incident_from_view_submission_metadata ¤
get_incident_from_view_submission_metadata(body: dict[str, Any]) -> Incident | Literal[False] | None
Get incident id from view modal metadata.
Source code in src/firefighter/slack/slack_incident_context.py
get_incident_from_view_submission_selected ¤
get_incident_from_view_submission_selected(body: dict[str, Any]) -> Incident | Literal[False] | None
Get incident id from select incident in modal.
Source code in src/firefighter/slack/slack_incident_context.py
get_user_from_context ¤
Returns a User or None, from a Slack body.
Source code in src/firefighter/slack/slack_incident_context.py
slack_templating ¤
date_time
cached
¤
md_quote_filter ¤
shorten_long ¤
Shorten text while keeping newlines and most formatting.
Source code in src/firefighter/slack/slack_templating.py
user_slack_handle_or_name ¤
Returns the Slack handle of the user in Slack MD format (<@SLACK_ID>
) or the user full name.
Source code in src/firefighter/slack/slack_templating.py
tasks ¤
fetch_conversations_members ¤
fetch_conversations_members_from_slack ¤
fetch_conversations_members_from_slack(
client: WebClient = DefaultWebClient, queryset: QuerySet[Conversation] | None = None
) -> list[Conversation]
Update the members and metadata of Slack Conversations in DB, from Slack API.
Only fetches conversations that are not IncidentChannels.
Parameters:
-
client
(WebClient
, default:DefaultWebClient
) –Slack SDK client. Defaults to DefaultWebClient.
-
queryset
(Optional[QuerySet[Conversation]]
, default:None
) –Conversation to update. Defaults to None. If None, all applicable
Returns:
-
list[Conversation]
–list[Conversation]: List of conversations that could not be updated.
Raises:
-
TypeError
–If the members list is not a list.
Source code in src/firefighter/slack/tasks/fetch_conversations_members.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
|
fetch_conversations_members_from_slack_celery ¤
fetch_conversations_members_from_slack_celery(
*_args: Any, queryset: QuerySet[Conversation] | None = None, **_options: Any
) -> dict[str, list[str]]
Wrapper around the actual task, as Celery doesn't support passing Django models.
Source code in src/firefighter/slack/tasks/fetch_conversations_members.py
reminder_postmortem ¤
publish_postmortem_reminder ¤
XXX Should return a message object, not send it.
Source code in src/firefighter/slack/tasks/reminder_postmortem.py
send_message ¤
send_message ¤
send_message(client: WebClient = DefaultWebClient, *args: Any, **kwargs: Any) -> dict[str, Any] | bytes
Sends a message to a channel. All arguments are passed to the Slack API.
Source code in src/firefighter/slack/tasks/send_message.py
send_reminders ¤
slack_save_reminder_message ¤
slack_save_reminder_message(message_response_data: SlackResponse, *args: int, **_kwargs: Any) -> bool
Save the firefighter.slack.models.Message from a Slack response. First args
is an firefighter.incidents.models.Incident ID.
Parameters:
-
message_response_data
(dict
) –SlackResponse data.
-
*args
(int
, default:()
) –Expect one value, the firefighter.incidents.models.Incident ID.
-
**_kwargs
(Any
, default:{}
) –Ignored.
Source code in src/firefighter/slack/tasks/send_reminders.py
sync_users ¤
sync_users ¤
Retrieves users from Slack and updates the database (e.g. name, new profile picture, email, active status...).
Source code in src/firefighter/slack/tasks/sync_users.py
update_usergroups_members ¤
update_usergroups_members_from_slack_celery ¤
update_usergroups_members_from_slack_celery(*args: Any, **options: Any) -> dict[str, list[str | None]]
Wrapper around the actual task, as Celery doesn't support passing Django models.
Source code in src/firefighter/slack/tasks/update_usergroups_members.py
update_users ¤
update_users_from_slack ¤
Retrieves users from Slack and updates the database (e.g. name, new profile picture, email, active status...).
Source code in src/firefighter/slack/tasks/update_users.py
urls ¤
utils ¤
channel_name_from_incident ¤
Lowercase, truncated at 80 chars, this is obviously the channel #name.
Source code in src/firefighter/slack/utils.py
get_slack_user_id_from_body ¤
Get the slack user id from the body of a Slack request, in user_id
or user.id
.
respond ¤
respond(
body: dict[str, Any], text: str = "", blocks: str | Sequence[dict[str, Any] | Block] | None = None, client: WebClient = DefaultWebClient
) -> None
Respond to the user, depending on where the message was coming from.
Source code in src/firefighter/slack/utils.py
views ¤
events ¤
handle_message_events_ignore ¤
Ignore other message events. Must be the last event handler for message.
actions_and_shortcuts ¤
open_link ¤
update_update_modal ¤
Reacts to the selection of an incident, in the select modal.
Source code in src/firefighter/slack/views/events/actions_and_shortcuts.py
channel_archive ¤
channel_id_changed ¤
channel_rename ¤
channel_shared ¤
channel_unarchive ¤
channel_unshared ¤
commands ¤
SLACK_BUILTIN_COMMANDS
module-attribute
¤
SLACK_BUILTIN_COMMANDS = (
"/archive",
"/call",
"/collapse",
"/dm",
"/expand",
"/feed",
"/invite",
"/leave",
"/msg",
"/remind",
"/remove",
"/rename",
"/search",
"/shrug",
"/status",
"/topic",
)
List of all Slack built-in commands (https://slack.com/help/articles/201259356 checked August 2022)
register_commands ¤
Register the command with its aliases. Commands are checked: - Fix commands that does not start with a slash, contain spaces, uppercase characters or are longer than 32 characters. - Ignore commands which names are built-in Slack commands.
⚠️ Don't forget to add the command and its aliases on your Slack App settings.
Source code in src/firefighter/slack/views/events/commands.py
home ¤
member_joined_channel ¤
member_joined_channel ¤
When a user joins a channel, we add it to the list of conversations.
API Reference: https://api.slack.com/events/member_joined_channel
Source code in src/firefighter/slack/views/events/member_joined_channel.py
member_left_channel ¤
member_left_channel ¤
When a user leaves a channel, we remove it from the list of conversations.
API Reference: https://api.slack.com/events/member_left_channel
Source code in src/firefighter/slack/views/events/member_left_channel.py
message ¤
handle_message_events_ignore ¤
Ignore other message events. Must be the last event handler for message.
message_deleted ¤
modals ¤
base_modal ¤
base ¤
MessageForm ¤
Bases: SlackModal
, Generic[T]
Form wrapper to use a Django form in a Slack message.
Provided a Django form in form_class, it will handle: - generation of Slack Blocks - validation and submission of the form
Source code in src/firefighter/slack/views/modals/base_modal/base.py
class-attribute
instance-attribute
¤Slack shortcut to open the modal.
ModalForm ¤
Bases: SlackModal
, Generic[T]
Specific SlackModal to handle a Django form.
Provided a Django form in form_class, it will handle: - generation of Slack Blocks - validation and submission of the form
Source code in src/firefighter/slack/views/modals/base_modal/base.py
class-attribute
instance-attribute
¤Slack shortcut to open the modal.
SlackModal ¤
Two main responsibilities:
- Register the modal on Slack to open it with shortcuts or actions
- Provide useful context for build_modal_fn
and handle_modal_fn
, such as body, incident, user, etc.
Source code in src/firefighter/slack/views/modals/base_modal/base.py
class-attribute
instance-attribute
¤Slack shortcut to open the modal.
form_utils ¤
SafeOption ¤
SafeOption(
*,
value: str,
label: str | None = None,
text: str | dict[str, Any] | TextObject | None = None,
description: str | dict[str, Any] | TextObject | None = None,
url: str | None = None,
**others: dict[str, Any]
)
Bases: Option
Make sure we are creating valid Option, warn otherwise.
Source code in src/firefighter/slack/views/modals/base_modal/form_utils.py
SlackForm ¤
Bases: Generic[T]
Source code in src/firefighter/slack/views/modals/base_modal/form_utils.py
slack_blocks(block_wrapper: Literal['section_accessory', 'input', 'action'] = 'input') -> list[Block]
Return the list of blocks from a SlackForm.
Parameters:
-
block_wrapper
(str
, default:'input'
) –Type of blocks destination. Defaults to "input".
Raises:
-
ValueError
–Raised if one of the initial value does not match the field type.
Returns:
-
list[Block]
–list[Block]: The List of Slack Blocks.
Source code in src/firefighter/slack/views/modals/base_modal/form_utils.py
SlackFormJSONEncoder ¤
Bases: JSONEncoder
JSON encoder that can handle UUIDs and Django models. Used to serialize the form data to JSON for Slack modal private_metadata.
slack_view_submission_to_dict ¤
Returns a dict of the form data from a Slack view submission.
Source code in src/firefighter/slack/views/modals/base_modal/form_utils.py
mixins ¤
modal_utils ¤
close ¤
CloseModal ¤
Bases: IncidentSelectableModalMixin
, ModalForm[CloseIncidentFormSlack]
Source code in src/firefighter/slack/views/modals/base_modal/base.py
handle_modal_fn ¤
Handle response from /incident close modal.
Source code in src/firefighter/slack/views/modals/close.py
downgrade_workflow ¤
key_event_message ¤
KeyEvents ¤
Bases: MessageForm[IncidentUpdateKeyEventsForm]
Source code in src/firefighter/slack/views/modals/base_modal/base.py
open_shortcut
class-attribute
instance-attribute
¤
Slack shortcut to open the modal.
handle_modal_fn ¤
Handle the time and date inputs for the key events.
Source code in src/firefighter/slack/views/modals/key_event_message.py
open ¤
OpenModal ¤
Bases: SlackModal
Source code in src/firefighter/slack/views/modals/base_modal/base.py
get_details_modal_form_class
staticmethod
¤
get_details_modal_form_class(open_incident_context: OpeningData, incident_type_value: str | None) -> type[SetIncidentDetails[Any]] | None
Get the details modal form class based on the incident type.
Returns None if no incident type is selected.
Source code in src/firefighter/slack/views/modals/open.py
handle_modal_fn ¤
Handle response from /incident open modal.
Source code in src/firefighter/slack/views/modals/open.py
opening ¤
check_current_incidents ¤
select_impact ¤
SelectImpactModal ¤
Bases: IncidentSelectableModalMixin
, ModalForm[SelectImpactFormSlack]
TODO: The detailed impacts selected should be saved on the incident.
Source code in src/firefighter/slack/views/modals/base_modal/base.py
set_details ¤
SetIncidentDetails ¤
Bases: ModalForm[T]
, Generic[T]
Source code in src/firefighter/slack/views/modals/opening/set_details.py
class-attribute
instance-attribute
¤Slack shortcut to open the modal.
Handle response from /incident open modal.
Source code in src/firefighter/slack/views/modals/opening/set_details.py
types ¤
postmortem ¤
select ¤
send_sos ¤
status ¤
trigger_oncall ¤
OnCallModal ¤
Bases: IncidentSelectableModalMixin
, SlackModal
Source code in src/firefighter/slack/views/modals/base_modal/base.py
open_shortcut
class-attribute
instance-attribute
¤
Slack shortcut to open the modal.
build_modal_fn ¤
XXX Should get an incident ID instead of an incident.