From ca173040accf05dd785ced0ab8e89cd79887b21c Mon Sep 17 00:00:00 2001 From: Richard Date: Sat, 31 Aug 2019 16:49:58 -0600 Subject: [PATCH 1/3] Adds suggested channels greeting message This feature will check if new slack users have profile information which we use to suggest matching slack channels Currently looks for a 1:1 match with profile text to slack channel name. --- pybot/endpoints/slack/events.py | 7 ++ pybot/endpoints/slack/utils/event_messages.py | 7 ++ pybot/endpoints/slack/utils/event_utils.py | 71 ++++++++++++++++++- 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/pybot/endpoints/slack/events.py b/pybot/endpoints/slack/events.py index fecd80d..2f87f21 100644 --- a/pybot/endpoints/slack/events.py +++ b/pybot/endpoints/slack/events.py @@ -10,6 +10,8 @@ link_backend_user, send_community_notification, send_user_greetings, + get_profile_suggestions, + build_suggestion_messages, ) logger = logging.getLogger(__name__) @@ -42,3 +44,8 @@ async def team_join(event: Event, app: SirBot) -> None: headers = await get_backend_auth_headers(app.http_session) if headers: await link_backend_user(user_id, headers, slack_api, app.http_session) + + suggested_channels = get_profile_suggestions(slack_api) + if suggested_channels: + suggestion_messages = build_suggestion_messages(user_id, suggested_channels) + await asyncio.wait([send_user_greetings(suggestion_messages, slack_api)]) diff --git a/pybot/endpoints/slack/utils/event_messages.py b/pybot/endpoints/slack/utils/event_messages.py index 73e14c0..05a604b 100644 --- a/pybot/endpoints/slack/utils/event_messages.py +++ b/pybot/endpoints/slack/utils/event_messages.py @@ -100,3 +100,10 @@ def base_resources(): ], }, ] + + +def profile_suggestion_message(channels): + message = "We found some channels that you might be interested in based on your profile information.\n" + for channel, name in channels: + message += f"<#{channel}|{name}> " + return message diff --git a/pybot/endpoints/slack/utils/event_utils.py b/pybot/endpoints/slack/utils/event_utils.py index f8412fe..afbde7a 100644 --- a/pybot/endpoints/slack/utils/event_utils.py +++ b/pybot/endpoints/slack/utils/event_utils.py @@ -18,6 +18,7 @@ external_button_attachments, second_team_join_message, team_join_initial_message, + profile_suggestion_message, ) logger = logging.getLogger(__name__) @@ -32,7 +33,9 @@ def base_user_message(user_id: str) -> Message: def build_messages(user_id) -> Tuple[Message, Message, Message, Message]: initial_message = base_user_message(user_id) - initial_message["text"] = team_join_initial_message(user_id) + initial_message["text"] = team_join_initial_message( + user_id + ) # <--- Initial message is built second_message = base_user_message(user_id) second_message["text"] = second_team_join_message() @@ -103,3 +106,69 @@ async def get_backend_auth_headers(session: ClientSession) -> Dict[str, str]: data = await response.json() headers = {"Authorization": f"Bearer {data['token']}"} return headers + + +async def get_profile_suggestions( + slack_id: int, + auth_header: Dict[str, str], + slack_api: SlackAPI, + session: ClientSession, +) -> List[(str, str)]: + """ + Generates a list of slack channels to suggest + + :param slack_id: The slack_id to return profile information from + :return: A list of slack channel names to suggest for the user + """ + results = [] + + # Get profile data that we want to build suggestions from. + user_info = await slack_api.query(methods.USERS_INFO, {"user": slack_id}) + email = user_info["user"]["profile"]["email"] + + async with session.get( + f"{BACKEND_URL}/auth/profile/admin/", + headers=auth_header, + params={"email": email}, + ) as response: + data = await response.json() + logger.info(f"Retrieved profile data from email: {email}") + + # Get the names of all public, non-archived channels + channels = await slack_api.query( + methods.CONVERSATION_LIST, {"exclude_archived": True} + ) + + # Get a list of all the profile data we want to compare + possible_suggestions = parse_suggestions_from_profile(data) + + # For each value in the profile data, check that we have a channel name that matches. + for info in possible_suggestions: + for channel in channels: + if info in channel[1]: + results.append((channel[0], channel[1])) + break + + return results + + +def parse_suggestions_from_profile(profile: Dict) -> List[str]: + # To use more profile fields add them here. + suggestible_fields = ["city", "state", "interests"] + data = [] + + for field in suggestible_fields: + if field in profile.keys() and profile[field] is not None: + if field in ["interests", "programming_languages", "disciplines"]: + for word in profile[field].lower().split(","): + data.append(word) + else: + data.append(profile[field]) + return data + + +def build_suggestion_messages(user_id: str, channels: List[(str, str)]) -> Message: + suggestion_message = base_user_message(user_id) + message = profile_suggestion_message(channels) + suggestion_message["text"] = message + return suggestion_message From ea3fffba6d20eae2932d33cf2106c6b26aa5ca59 Mon Sep 17 00:00:00 2001 From: Richard Date: Sat, 31 Aug 2019 16:59:01 -0600 Subject: [PATCH 2/3] Fixes hint typing error --- pybot/endpoints/slack/utils/event_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pybot/endpoints/slack/utils/event_utils.py b/pybot/endpoints/slack/utils/event_utils.py index afbde7a..e823796 100644 --- a/pybot/endpoints/slack/utils/event_utils.py +++ b/pybot/endpoints/slack/utils/event_utils.py @@ -113,7 +113,7 @@ async def get_profile_suggestions( auth_header: Dict[str, str], slack_api: SlackAPI, session: ClientSession, -) -> List[(str, str)]: +) -> List[Tuple[str, str]]: """ Generates a list of slack channels to suggest @@ -167,7 +167,7 @@ def parse_suggestions_from_profile(profile: Dict) -> List[str]: return data -def build_suggestion_messages(user_id: str, channels: List[(str, str)]) -> Message: +def build_suggestion_messages(user_id: str, channels: List[Tuple[str, str]]) -> Message: suggestion_message = base_user_message(user_id) message = profile_suggestion_message(channels) suggestion_message["text"] = message From 87277d1eb25853208337fb34942341af3f6dd912 Mon Sep 17 00:00:00 2001 From: Richard Date: Sat, 31 Aug 2019 17:15:16 -0600 Subject: [PATCH 3/3] Add suggestions for programming languages and disciplines --- pybot/endpoints/slack/utils/event_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pybot/endpoints/slack/utils/event_utils.py b/pybot/endpoints/slack/utils/event_utils.py index e823796..28ae03f 100644 --- a/pybot/endpoints/slack/utils/event_utils.py +++ b/pybot/endpoints/slack/utils/event_utils.py @@ -154,7 +154,7 @@ async def get_profile_suggestions( def parse_suggestions_from_profile(profile: Dict) -> List[str]: # To use more profile fields add them here. - suggestible_fields = ["city", "state", "interests"] + suggestible_fields = ["city", "state", "interests", "programming_languages", "disciplines"] data = [] for field in suggestible_fields: