Skip to content
This repository was archived by the owner on Sep 3, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions src/dispatch/case/flows.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,19 +184,19 @@ def case_remove_participant_flow(
)

# we also try to remove the user from the Slack conversation
try:
slack_conversation_plugin = plugin_service.get_active_instance(
db_session=db_session, project_id=case.project.id, plugin_type="conversation"
)
slack_conversation_plugin = plugin_service.get_active_instance(
db_session=db_session, project_id=case.project.id, plugin_type="conversation"
)

if not slack_conversation_plugin:
log.warning(f"{user_email} not updated. No conversation plugin enabled.")
return
if not slack_conversation_plugin:
log.warning(f"{user_email} not updated. No conversation plugin enabled.")
return

if not case.conversation:
log.warning("No conversation enabled for this case.")
return
if not case.conversation:
log.warning("No conversation enabled for this case.")
return

try:
slack_conversation_plugin.instance.remove_user(
conversation_id=case.conversation.channel_id,
user_email=user_email
Expand Down
20 changes: 10 additions & 10 deletions src/dispatch/incident/flows.py
Original file line number Diff line number Diff line change
Expand Up @@ -1178,19 +1178,19 @@ def incident_remove_participant_flow(
)

# we also try to remove the user from the Slack conversation
try:
slack_conversation_plugin = plugin_service.get_active_instance(
db_session=db_session, project_id=incident.project.id, plugin_type="conversation"
)
slack_conversation_plugin = plugin_service.get_active_instance(
db_session=db_session, project_id=incident.project.id, plugin_type="conversation"
)

if not slack_conversation_plugin:
log.warning(f"{user_email} not updated. No conversation plugin enabled.")
return
if not slack_conversation_plugin:
log.warning(f"{user_email} not updated. No conversation plugin enabled.")
return

if not incident.conversation:
log.warning("No conversation enabled for this incident.")
return
if not incident.conversation:
log.warning("No conversation enabled for this incident.")
return

try:
slack_conversation_plugin.instance.remove_user(
conversation_id=incident.conversation.channel_id,
user_email=user_email
Expand Down
34 changes: 30 additions & 4 deletions src/dispatch/plugins/dispatch_slack/case/interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,23 @@ def engage(
return

engagement = form_data[DefaultBlockIds.description_input]
user = client.users_lookupByEmail(email=user_email)

try:
user = client.users_lookupByEmail(email=user_email)
except SlackApiError as e:
if e.response.get("error") == SlackAPIErrorCode.USERS_NOT_FOUND:
log.warning(
f"Failed to find Slack user for email {user_email}. "
"User may have been deactivated or never had Slack access."
)
client.chat_postMessage(
text=f"Unable to engage user {user_email} - user not found in Slack workspace.",
channel=case.conversation.channel_id,
thread_ts=case.conversation.thread_id if case.has_thread else None,
)
return
else:
raise

result = client.chat_postMessage(
text="Engaging user...",
Expand Down Expand Up @@ -1983,9 +1999,19 @@ def edit_button_click(
ack()
case = case_service.get(db_session=db_session, case_id=int(context["subject"].id))

assignee_initial_user = client.users_lookupByEmail(email=case.assignee.individual.email)[
"user"
]["id"]
try:
assignee_initial_user = client.users_lookupByEmail(email=case.assignee.individual.email)[
"user"
]["id"]
except SlackApiError as e:
if e.response.get("error") == SlackAPIErrorCode.USERS_NOT_FOUND:
log.warning(
f"Assignee {case.assignee.individual.email} not found in Slack workspace. "
"Using None for initial assignee selection."
)
assignee_initial_user = None
else:
raise

blocks = [
title_input(initial_value=case.title),
Expand Down
47 changes: 41 additions & 6 deletions src/dispatch/plugins/dispatch_slack/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,13 +390,48 @@ def set_description(self, conversation_id: str, description: str):
return set_conversation_description(client, conversation_id, description)

def remove_user(self, conversation_id: str, user_email: str):
"""Removes a user from a conversation."""
"""Removes a user from a conversation.

Args:
conversation_id: The Slack conversation/channel ID
user_email: The email address of the user to remove

Returns:
The API response if successful, None if user not found

Raises:
SlackApiError: For non-recoverable Slack API errors
"""
client = create_slack_client(self.configuration)
user_id = resolve_user(client, user_email).get("id")
if user_id:
return remove_member_from_channel(
client=client, conversation_id=conversation_id, user_id=user_id
)

try:
user_info = resolve_user(client, user_email)
user_id = user_info.get("id")

if user_id:
return remove_member_from_channel(
client=client, conversation_id=conversation_id, user_id=user_id
)
else:
logger.warning(
"Cannot remove user %s from conversation %s: "
"User ID not found in resolve_user response",
user_email, conversation_id
)
return None

except SlackApiError as e:
if e.response.get("error") == SlackAPIErrorCode.USERS_NOT_FOUND:
logger.warning(
"User %s not found in Slack workspace. "
"Cannot remove from conversation %s. "
"User may have been deactivated or never had Slack access.",
user_email, conversation_id
)
return None
else:
# Re-raise for other Slack API errors
raise

def add_bookmark(self, conversation_id: str, weblink: str, title: str):
"""Adds a bookmark to the conversation."""
Expand Down
Loading