dm_mac.slack_handler module¶
- class dm_mac.slack_handler.Message(text: str, user_id: str, user_name: str, user_handle: str, channel_id: str, channel_name: str)¶
Bases:
objectRepresent an incoming message.
- property as_dict: Dict[str, Any]¶
- class dm_mac.slack_handler.SlackHandler(quart_app: Quart)¶
Bases:
objectHandle Slack integration.
- HELP_RESPONSE: str = 'Hi, I\'m the Machine Access Control slack bot.\nMention my username followed by one of these commands:\n"status" - list all machines and their status\n"oops <machine name>" - set Oops state on this machine immediately\n"lock <machine name>" - set maintenance lockout on this machine\n"clear <machine name>" - clear oops and/or maintenance lockout on this machine\n\nMachine names and aliases are matched case-insensitively.\nYou can also use the "/oops-clear" slash command (in the control channel) to\nclear a machine, optionally with no machine name to pick one from a menu.\n\nI am Free and Open Source software:\nhttps://github.com/Decaturmakers/machine-access-control'¶
- MODAL_ACTION_ID: str = 'machine_select'¶
action_idof the machine-selectionstatic_selectelement.
- MODAL_BLOCK_ID: str = 'machine_block'¶
block_idof the machine-selection input block in the modal.
- MODAL_CALLBACK_ID: str = 'oops_clear_modal'¶
Block Kit
callback_idfor the/oops-clearselection modal; used both when opening the modal and when routing its submission.
- static _both_relays_suffix(machine: Machine) str¶
Return ‘ (both relays)’ if machine has second_relay, else empty.
- _build_clear_modal(machines: List[Machine]) Dict[str, Any]¶
Build the
/oops-clearBlock Kit selection modal.The modal has a single required input: a
static_selectdropdown of the given machines (option text = display name, value = machine name) with no default selection.
- async _clear_machine(mach: Machine) str | None¶
Clear oops and/or maintenance lock-out status on a machine.
Returns
Noneif something was cleared (the resulting Slack channel posts fromMachine.unoops()/Machine.unlock()cover the outcome), or a human-readable message string if the machine was already clear (so the caller can surface it to the requester).
- static _invalid_machine_msg(name_or_alias: str) str¶
Return the standard ‘invalid machine name or alias’ message.
- async admin_log(message: str) None¶
Log a string to the admin channel only.
This uses
asyncio.create_task()to fire-and-forget the Slack postMessage call, so that we don’t block on communication with Slack. Otherwise, updates to the relay/LCD/LED would be delayed by at least the timeout trying to post to Slack.
- async app_mention(body: Dict[str, Any], say: AsyncSay) None¶
Handle an at-mention of our app in Slack.
Body is a dict with string keys, which is documented at <https://api.slack.com/events/app_mention>. The important bits are in the
eventnested dict.The parts of the
eventdict withinbodythat are of interest to us are:user- the user ID (string beginning with “U”) of the person who mentioned us.text- the string text of the message that mentioned us.channel- the channel ID (string beginning with “C”) of the channel that the message was in.
- async log_lock(machine: Machine, source: str) None¶
Log when a machine is locked.
This uses
asyncio.create_task()to fire-and-forget the Slack postMessage call, so that we don’t block on communication with Slack. Otherwise, updates to the relay/LCD/LED would be delayed by at least the timeout trying to post to Slack.
- async log_oops(machine: Machine, source: str, user_name: str | None = 'unknown user') None¶
Log when a machine is oopsed.
This uses
asyncio.create_task()to fire-and-forget the Slack postMessage call, so that we don’t block on communication with Slack. Otherwise, updates to the relay/LCD/LED would be delayed by at least the timeout trying to post to Slack.
- async log_override_login(machine: Machine, user_name: str) None¶
Log an override login to the admin channel only.
This uses
asyncio.create_task()to fire-and-forget the Slack postMessage call, so that we don’t block on communication with Slack.
- async log_unlock(machine: Machine, source: str) None¶
Log when a machine is un-locked.
This uses
asyncio.create_task()to fire-and-forget the Slack postMessage call, so that we don’t block on communication with Slack. Otherwise, updates to the relay/LCD/LED would be delayed by at least the timeout trying to post to Slack.
- async log_unoops(machine: Machine, source: str) None¶
Log when a machine is un-oopsed.
This uses
asyncio.create_task()to fire-and-forget the Slack postMessage call, so that we don’t block on communication with Slack. Otherwise, updates to the relay/LCD/LED would be delayed by at least the timeout trying to post to Slack.
- async machine_status(say: AsyncSay) None¶
Respond with machine status.
- async oops_clear_command(ack: AsyncAck, command: Dict[str, Any], client: AsyncWebClient) None¶
Handle the
/oops-clearslash command.Usable only from the control channel. With an argument (
/oops-clear <machine name>) it clears that machine directly. With no argument it opens a Block Kit modal to pick a machine to clear.ackis always called promptly so Slack does not report the command as failed; error/edge cases respond with an ephemeral message, while a successful clear acks silently (the resulting channel posts cover the outcome).
- async oops_clear_modal_submit(ack: AsyncAck, view: Dict[str, Any]) None¶
Handle submission of the
/oops-clearselection modal.Acknowledges promptly to close the modal, then clears the selected machine. The machine may have been cleared between opening and submitting the modal; that and any unexpected missing selection are handled gracefully (no error raised).