mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-04-02 08:58:11 +02:00
Immediate Mark Resolved SlackBot Option and Respond to Bots Option (#1031)
This commit is contained in:
parent
29e74c0877
commit
0060a1dd58
@ -20,6 +20,7 @@ from danswer.danswerbot.slack.constants import DISLIKE_BLOCK_ACTION_ID
|
||||
from danswer.danswerbot.slack.constants import FEEDBACK_DOC_BUTTON_BLOCK_ACTION_ID
|
||||
from danswer.danswerbot.slack.constants import FOLLOWUP_BUTTON_ACTION_ID
|
||||
from danswer.danswerbot.slack.constants import FOLLOWUP_BUTTON_RESOLVED_ACTION_ID
|
||||
from danswer.danswerbot.slack.constants import IMMEDIATE_RESOLVED_BUTTON_ACTION_ID
|
||||
from danswer.danswerbot.slack.constants import LIKE_BLOCK_ACTION_ID
|
||||
from danswer.danswerbot.slack.utils import build_feedback_id
|
||||
from danswer.danswerbot.slack.utils import remove_slack_text_interactions
|
||||
@ -279,11 +280,16 @@ def build_follow_up_block(message_id: int | None) -> ActionsBlock:
|
||||
return ActionsBlock(
|
||||
block_id=build_feedback_id(message_id) if message_id is not None else None,
|
||||
elements=[
|
||||
ButtonElement(
|
||||
action_id=IMMEDIATE_RESOLVED_BUTTON_ACTION_ID,
|
||||
style="primary",
|
||||
text="I'm all set!",
|
||||
),
|
||||
ButtonElement(
|
||||
action_id=FOLLOWUP_BUTTON_ACTION_ID,
|
||||
style="danger",
|
||||
text="I need more help from a human!",
|
||||
)
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
LIKE_BLOCK_ACTION_ID = "feedback-like"
|
||||
DISLIKE_BLOCK_ACTION_ID = "feedback-dislike"
|
||||
FEEDBACK_DOC_BUTTON_BLOCK_ACTION_ID = "feedback-doc-button"
|
||||
IMMEDIATE_RESOLVED_BUTTON_ACTION_ID = "immediate-resolved-button"
|
||||
FOLLOWUP_BUTTON_ACTION_ID = "followup-button"
|
||||
FOLLOWUP_BUTTON_RESOLVED_ACTION_ID = "followup-resolved-button"
|
||||
SLACK_CHANNEL_ID = "channel_id"
|
||||
|
@ -192,14 +192,11 @@ def handle_followup_button(
|
||||
)
|
||||
|
||||
|
||||
def handle_followup_resolved_button(
|
||||
def get_clicker_name(
|
||||
req: SocketModeRequest,
|
||||
client: SocketModeClient,
|
||||
) -> None:
|
||||
channel_id = req.payload["container"]["channel_id"]
|
||||
message_ts = req.payload["container"]["message_ts"]
|
||||
thread_ts = req.payload["container"]["thread_ts"]
|
||||
clicker_backup_name = req.payload.get("user", {}).get("name", "Someone")
|
||||
) -> str:
|
||||
clicker_name = req.payload.get("user", {}).get("name", "Someone")
|
||||
clicker_real_name = None
|
||||
try:
|
||||
clicker = client.web_client.users_info(user=req.payload["user"]["id"])
|
||||
@ -210,6 +207,23 @@ def handle_followup_resolved_button(
|
||||
# Likely a scope issue
|
||||
pass
|
||||
|
||||
if clicker_real_name:
|
||||
clicker_name = clicker_real_name
|
||||
|
||||
return clicker_name
|
||||
|
||||
|
||||
def handle_followup_resolved_button(
|
||||
req: SocketModeRequest,
|
||||
client: SocketModeClient,
|
||||
immediate: bool = False,
|
||||
) -> None:
|
||||
channel_id = req.payload["container"]["channel_id"]
|
||||
message_ts = req.payload["container"]["message_ts"]
|
||||
thread_ts = req.payload["container"]["thread_ts"]
|
||||
|
||||
clicker_name = get_clicker_name(req, client)
|
||||
|
||||
update_emote_react(
|
||||
emoji=DANSWER_FOLLOWUP_EMOJI,
|
||||
channel=channel_id,
|
||||
@ -218,20 +232,27 @@ def handle_followup_resolved_button(
|
||||
client=client.web_client,
|
||||
)
|
||||
|
||||
slack_call = make_slack_api_rate_limited(client.web_client.chat_delete)
|
||||
response = slack_call(
|
||||
channel=channel_id,
|
||||
ts=message_ts,
|
||||
)
|
||||
# Delete the message with the option to mark resolved
|
||||
if not immediate:
|
||||
slack_call = make_slack_api_rate_limited(client.web_client.chat_delete)
|
||||
response = slack_call(
|
||||
channel=channel_id,
|
||||
ts=message_ts,
|
||||
)
|
||||
|
||||
if not response.get("ok"):
|
||||
logger_base.error("Unable to delete message for resolved")
|
||||
if not response.get("ok"):
|
||||
logger_base.error("Unable to delete message for resolved")
|
||||
|
||||
resolved_block = SectionBlock(
|
||||
text=f"{clicker_real_name or clicker_backup_name} has marked this question as resolved! "
|
||||
f'\n\n You can always click the "I need more help button" to let the team '
|
||||
f"know that your problem still needs attention."
|
||||
)
|
||||
if immediate:
|
||||
msg_text = f"{clicker_name} has marked this question as resolved!"
|
||||
else:
|
||||
msg_text = (
|
||||
f"{clicker_name} has marked this question as resolved! "
|
||||
f'\n\n You can always click the "I need more help button" to let the team '
|
||||
f"know that your problem still needs attention."
|
||||
)
|
||||
|
||||
resolved_block = SectionBlock(text=msg_text)
|
||||
|
||||
respond_in_thread(
|
||||
client=client.web_client,
|
||||
|
@ -19,6 +19,7 @@ from danswer.danswerbot.slack.constants import DISLIKE_BLOCK_ACTION_ID
|
||||
from danswer.danswerbot.slack.constants import FEEDBACK_DOC_BUTTON_BLOCK_ACTION_ID
|
||||
from danswer.danswerbot.slack.constants import FOLLOWUP_BUTTON_ACTION_ID
|
||||
from danswer.danswerbot.slack.constants import FOLLOWUP_BUTTON_RESOLVED_ACTION_ID
|
||||
from danswer.danswerbot.slack.constants import IMMEDIATE_RESOLVED_BUTTON_ACTION_ID
|
||||
from danswer.danswerbot.slack.constants import LIKE_BLOCK_ACTION_ID
|
||||
from danswer.danswerbot.slack.constants import SLACK_CHANNEL_ID
|
||||
from danswer.danswerbot.slack.constants import VIEW_DOC_FEEDBACK_ID
|
||||
@ -87,8 +88,20 @@ def prefilter_requests(req: SocketModeRequest, client: SocketModeClient) -> bool
|
||||
return False
|
||||
|
||||
if event.get("bot_profile"):
|
||||
channel_specific_logger.info("Ignoring message from bot")
|
||||
return False
|
||||
channel_name, _ = get_channel_name_from_id(
|
||||
client=client.web_client, channel_id=channel
|
||||
)
|
||||
|
||||
engine = get_sqlalchemy_engine()
|
||||
with Session(engine) as db_session:
|
||||
slack_bot_config = get_slack_bot_config_for_channel(
|
||||
channel_name=channel_name, db_session=db_session
|
||||
)
|
||||
if not slack_bot_config or not slack_bot_config.channel_config.get(
|
||||
"respond_to_bots"
|
||||
):
|
||||
channel_specific_logger.info("Ignoring message from bot")
|
||||
return False
|
||||
|
||||
# Ignore things like channel_join, channel_leave, etc.
|
||||
# NOTE: "file_share" is just a message with a file attachment, so we
|
||||
@ -300,8 +313,10 @@ def action_routing(req: SocketModeRequest, client: SocketModeClient) -> None:
|
||||
return handle_doc_feedback_button(req, client)
|
||||
elif action["action_id"] == FOLLOWUP_BUTTON_ACTION_ID:
|
||||
return handle_followup_button(req, client)
|
||||
elif action["action_id"] == IMMEDIATE_RESOLVED_BUTTON_ACTION_ID:
|
||||
return handle_followup_resolved_button(req, client, immediate=True)
|
||||
elif action["action_id"] == FOLLOWUP_BUTTON_RESOLVED_ACTION_ID:
|
||||
return handle_followup_resolved_button(req, client)
|
||||
return handle_followup_resolved_button(req, client, immediate=False)
|
||||
|
||||
|
||||
def view_routing(req: SocketModeRequest, client: SocketModeClient) -> None:
|
||||
|
@ -786,6 +786,7 @@ class ChannelConfig(TypedDict):
|
||||
|
||||
channel_names: list[str]
|
||||
respond_tag_only: NotRequired[bool] # defaults to False
|
||||
respond_to_bots: NotRequired[bool] # defaults to False
|
||||
respond_team_member_list: NotRequired[list[str]]
|
||||
answer_filters: NotRequired[list[AllowedAnswerFilters]]
|
||||
# If None then no follow up
|
||||
|
@ -75,6 +75,7 @@ class SlackBotConfigCreationRequest(BaseModel):
|
||||
persona_id: int | None # NOTE: only one of `document_sets` / `persona_id` should be set
|
||||
channel_names: list[str]
|
||||
respond_tag_only: bool = False
|
||||
respond_to_bots: bool = False
|
||||
# If no team members, assume respond in the channel to everyone
|
||||
respond_team_member_list: list[str] = []
|
||||
answer_filters: list[AllowedAnswerFilters] = []
|
||||
|
@ -77,6 +77,10 @@ def _form_channel_config(
|
||||
if follow_up_tags is not None:
|
||||
channel_config["follow_up_tags"] = follow_up_tags
|
||||
|
||||
channel_config[
|
||||
"respond_to_bots"
|
||||
] = slack_bot_config_creation_request.respond_to_bots
|
||||
|
||||
return channel_config
|
||||
|
||||
|
||||
|
@ -69,6 +69,8 @@ export const SlackBotCreationForm = ({
|
||||
).includes("questionmark_prefilter"),
|
||||
respond_tag_only:
|
||||
existingSlackBotConfig?.channel_config?.respond_tag_only || false,
|
||||
respond_to_bots:
|
||||
existingSlackBotConfig?.channel_config?.respond_to_bots || false,
|
||||
respond_team_member_list:
|
||||
existingSlackBotConfig?.channel_config
|
||||
?.respond_team_member_list || ([] as string[]),
|
||||
@ -94,6 +96,7 @@ export const SlackBotCreationForm = ({
|
||||
answer_validity_check_enabled: Yup.boolean().required(),
|
||||
questionmark_prefilter_enabled: Yup.boolean().required(),
|
||||
respond_tag_only: Yup.boolean().required(),
|
||||
respond_to_bots: Yup.boolean().required(),
|
||||
respond_team_member_list: Yup.array().of(Yup.string()).required(),
|
||||
still_need_help_enabled: Yup.boolean().required(),
|
||||
follow_up_tags: Yup.array().of(Yup.string()),
|
||||
@ -187,6 +190,11 @@ export const SlackBotCreationForm = ({
|
||||
label="Respond to @DanswerBot Only"
|
||||
subtext="If set, DanswerBot will only respond when directly tagged"
|
||||
/>
|
||||
<BooleanFormField
|
||||
name="respond_to_bots"
|
||||
label="Responds to Bot messages"
|
||||
subtext="If not set, DanswerBot will always ignore messages from Bots"
|
||||
/>
|
||||
<TextArrayField
|
||||
name="respond_team_member_list"
|
||||
label="Team Members Emails"
|
||||
|
@ -8,6 +8,7 @@ interface SlackBotConfigCreationRequest {
|
||||
answer_validity_check_enabled: boolean;
|
||||
questionmark_prefilter_enabled: boolean;
|
||||
respond_tag_only: boolean;
|
||||
respond_to_bots: boolean;
|
||||
respond_team_member_list: string[];
|
||||
follow_up_tags?: string[];
|
||||
usePersona: boolean;
|
||||
@ -32,6 +33,7 @@ const buildRequestBodyFromCreationRequest = (
|
||||
return JSON.stringify({
|
||||
channel_names: creationRequest.channel_names,
|
||||
respond_tag_only: creationRequest.respond_tag_only,
|
||||
respond_to_bots: creationRequest.respond_to_bots,
|
||||
respond_team_member_list: creationRequest.respond_team_member_list,
|
||||
answer_filters: buildFiltersFromCreationRequest(creationRequest),
|
||||
follow_up_tags: creationRequest.follow_up_tags?.filter((tag) => tag !== ""),
|
||||
|
@ -351,6 +351,7 @@ export type AnswerFilterOption =
|
||||
export interface ChannelConfig {
|
||||
channel_names: string[];
|
||||
respond_tag_only?: boolean;
|
||||
respond_to_bots?: boolean;
|
||||
respond_team_member_list?: string[];
|
||||
answer_filters?: AnswerFilterOption[];
|
||||
follow_up_tags?: string[];
|
||||
|
Loading…
x
Reference in New Issue
Block a user