Ejemplo n.º 1
0
def cs_job_opportunities(payload):
    """
    Lets you know about CS job opportunities from indeed
    Usage: /CSopportunities [OPTIONS, page_number=1, query="software internship"]
    """

    # Extract the text from the payload
    text = payload["text"].strip()

    # Attempt to extract options
    options = ""
    if "-r" in text:
        text = text.replace("-r", "")
        options += "&sort=date"

    # Attempt to extract the page number from the given text
    try:
        page_number = text.split()[0]
        page_number = int(page_number)
    except:
        page_number = 1

    # Attempt to extract the query from the given text
    query = text.lstrip('0123456789.- ')
    if query == "":
        query = "software internship"

    # Retrieve jobs
    message, jobs = utils.jobs_from_indeed(page_number, query, options)

    # Open modal with jobs
    client.views_open(trigger_id=payload["trigger_id"],
                      view=blocks.job_opportunities(query, message, jobs))
Ejemplo n.º 2
0
def open_standup_view(**kwargs):
    user_id = kwargs.get("user_id")
    data = kwargs.get("data", None)
    trigger_type = kwargs.get("trigger_type", constants.BUTTON_TRIGGER)

    try:
        user = User.query.filter_by(user_id=user_id).first()
        if trigger_type == constants.BUTTON_TRIGGER:
            team = (db.session.query(Team).join(
                User.team).filter(User.id == user.id).first())
        else:
            team_name = data.get("text")
            print(team_name)
            if not team_name:
                message = f"Slash command format is `/standup <team-name>`.\nYour commands: {', '.join(utils.get_user_slash_commands(user))}"
                client.chat_postMessage(channel=user.user_id, text=message)
            team = Team.query.filter_by(name=team_name).first()

        # TODO: Check if this user it allowed in this team's standup especially
        # in the case of slash command trigger.
        standup = team.standup

        if submission := utils.submission_exists(user, standup):
            client.views_open(trigger_id=data.get("trigger_id"),
                              view=open_edit_view(standup, submission))

        client.views_open(trigger_id=data.get("trigger_id"),
                          view=utils.get_standup_view(standup))
        return make_response("", 200)
Ejemplo n.º 3
0
def trivia_modal(trigger_id, user):
    user_info = client.users_info(user=user)['user']
    user_name = user_info['profile']['display_name_normalized'] if (
        user_info['profile']['display_name_normalized'] != ""
    ) else user_info['profile']['real_name_normalized']
    return client.views_open(trigger_id=trigger_id,
                             view=globalTriviaModal(user_name,
                                                    user))['view']['id']
Ejemplo n.º 4
0
def trivia_question_send(trigger_id, user, channel, question, qnum, view):
    if view is None:
        return client.views_open(trigger_id=trigger_id,
                                 view=triviaAskQuestion(user, question,
                                                        qnum))['view']['id']
    else:
        return client.views_update(view_id=view,
                                   view=triviaAskQuestion(
                                       user, question, qnum))['view']['id']
Ejemplo n.º 5
0
def open_configure_view(**kwargs):
    data = kwargs.get("data")
    config_blocks: List = dict(constants.CONFIGURE_VIEW)

    try:
        command, team_name = data.get("text").split(" ")
    except ValueError:
        return make_response(
            f"Slash command format is `/standup configure <team-name>`.",
            200,
        )

    team = Team.query.filter_by(name=team_name).first()

    if team:
        # Prepare standup question list to put in textfield
        standup_json = json.loads(team.standup.standup_blocks)

        blocks = standup_json.get("blocks", [])
        questions = filter(lambda block: block["type"] == "input", blocks)
        questions = map(lambda block: block["label"]["text"], questions)

        # Get all active users for this team
        users = (db.session.query(User).join(Team.user).filter(
            Team.id == team.id, User.is_active)).all()

        users_list = [user.user_id for user in users]

        # Add initial values
        users_input_block = config_blocks["blocks"][1]
        standup_input_block = config_blocks["blocks"][2]
        channel_block = config_blocks["blocks"][5]
        publish_time_block = config_blocks["blocks"][7]

        users_input_block["element"]["initial_users"] = users_list
        standup_input_block["element"]["initial_value"] = "\n".join(questions)
        channel_block["accessory"][
            "initial_channel"] = team.standup.publish_channel
        publish_time_block["accessory"]["initial_time"] = time.strftime(
            team.standup.publish_time, "%H:%M")

    config_blocks["callback_id"] = f"configure_standup%{team_name}"

    client.views_open(trigger_id=data.get("trigger_id"), view=config_blocks)
Ejemplo n.º 6
0
def events(payload):
    """
    Display a list of events using linkup
    """
    # print(payload)
    # Extract the text from the payload
    text = payload["text"].strip()
    keyword = text.split()[0] if text != "" else "cse"
    page_num = text.split()[1] if len(text.split()) >= 2 else "0"

    if keyword != "cse" and keyword != "unsw":
        client.views_open(trigger_id=payload["trigger_id"],
                          view=blocks.error_message("Invalid keyword"))
        return

    if not page_num.isnumeric():
        client.views_open(trigger_id=payload["trigger_id"],
                          view=blocks.error_message("Invalid page number"))
        return

    page_num = int(page_num)

    events = utils.retrieve_event_details(keyword, page_num)

    client.views_open(trigger_id=payload["trigger_id"],
                      view=blocks.events_modal(events, keyword, page_num))
Ejemplo n.º 7
0
def purge(payload):
    """
    Mass delete unwanted messages.
    Usage: /purge <number of messages> [user, time_period, text_snippet]
    """

    # Retrieve permission level of user_id
    perm_level, _ = utils.retrieve_highest_permission_level(payload["user_id"])

    # Deny request if user doesn't have enough permission
    if perm_level <= 0:
        client.views_open(trigger_id=payload["trigger_id"],
                          view=blocks.permission_denied())
        return

    # Extract number of messages
    text = payload["text"].strip()
    try:
        number_of_messages = int(text.split()[0])
        text = text.replace(str(number_of_messages), "", 1).strip()
        if number_of_messages <= 0:
            raise ValueError
    except:
        client.views_open(
            trigger_id=payload["trigger_id"],
            view=blocks.error_message("Invalid number of messages"))
        return

    # Extract user from arguments
    user = ""
    if text != "" and utils.re.search("^<@[A-Z0-9]+|.*>$", text.split()[0]):
        user = text.split()[0]
        text = text.replace(user, "").strip()

    # Extract time period from arguments
    time_period = -1
    if text != "" and utils.re.search("^[0-9]+$", text.split()[0]):
        time_period = int(text.split()[0])
        text = text.replace(str(time_period), "", 1).strip()

    # Extract text snippet from arguments
    text_snippet = text

    # Open purge confirmation modal
    client.views_open(trigger_id=payload["trigger_id"],
                      view=blocks.purge_confirmation(number_of_messages, user,
                                                     time_period,
                                                     payload["channel_id"],
                                                     text_snippet))
Ejemplo n.º 8
0
def trivia_ongoing(trigger_id):
    client.views_open(trigger_id=trigger_id, view=triviaOngoing())
Ejemplo n.º 9
0
def trivia_custom_questions_modal(view_id, trigger_id, user, q_number):
    # client.views_update(view_id=view_id, view=triviaCustomQuestions(user, q_number))
    # client.views_push(trigger_id=trigger_id, view=triviaCustomQuestions(user, q_number))
    client.views_open(trigger_id=trigger_id,
                      view=triviaCustomQuestions(user, q_number))
Ejemplo n.º 10
0
def review_modal(trigger_id, course_code, user_id):
    return client.views_open(trigger_id=trigger_id,
                             view=reviewModal(course_code,
                                              user_id))['view']['id']
Ejemplo n.º 11
0
def help_modal(trigger_id, user):
    user_info = client.users_info(user=user)['user']
    user_name = user_info['profile']['display_name_normalized'] if (
        user_info['profile']['display_name_normalized'] != ""
    ) else user_info['profile']['real_name_normalized']
    client.views_open(trigger_id=trigger_id, view=helpModal(user_name))
Ejemplo n.º 12
0
def interactions(payload):
    """
    The main function for enabling interactions with shortcuts, modals, or
    interactive components (such as buttons, select menus, and datepickers).
    See https://api.slack.com/reference/interaction-payloads for more details
    on how to handle interaction payloads.
    """

    # Extract data
    trigger_id = payload["trigger_id"]
    user = payload["user"]["id"]
    # Received when a user clicks a Block Kit interactive component.
    if payload["type"] == "shortcut":

        callback_id = payload["callback_id"]

        # Opens the "edit_profile" view with prefilled information
        if callback_id == "anonymous_messaging":
            client.views_open(trigger_id=trigger_id,
                              view=get_anonymous_modal())
        elif callback_id == "trivia":
            init_trivia(trigger_id, user)

    # Received when a modal is submitted.
    if payload["type"] == "view_submission":
        # if 'trivia_start_' in payload['view']['callback_id']:
        #     try:
        #         game_id = payload['view']['callback_id'].replace('trivia_start_', '')
        #         trivia_q_number(game_id, int(payload['view']['state']['values']['number_questions']['number_questions']['value']))
        #         trivia_player_list(game_id, payload['view']['state']['values']['users_playing']['users_playing']['selected_users'])
        #         if trivia_finalise(game_id, trigger_id):
        #             try:
        #                 with a.app_context():
        #                     resp = jsonify({'response_action': 'push', 'view': trivia_customs(game_id, trigger_id)})
        #                     resp.headers['Authorization'] = Config.SLACK_BOT_TOKEN
        #                     return resp
        #             except Exception as err:
        #                 print(err)
        #     except:
        #         trivia_failure(game_id, trigger_id)
        # if 'custom_questions_' in payload['view']['callback_id']:
        #     trivia_custom_questions(payload['view']['callback_id'].replace('custom_questions_', ''), payload['view']['state']['values'])
        if 'course_review_' in payload['view']['callback_id']:
            u_id = payload['view']['callback_id'].replace("course_review_", "")
            course = review_submit(u_id, payload['view']['state']['values'])
            review_confirm(u_id, course)

        view = payload["view"]
        callback_id = view["callback_id"]
        state = view["state"]

        # Store submitted profile data
        if callback_id == "edit_profile_modal":
            values = view["state"]["values"]
            for key in ["favourite_course", "favourite_programming_language", "favourite_netflix_show",
                        "favourite_food", \
                        "overrated", "underrated", "biggest_flex", "enrolled_courses", "completed_courses",
                        "general_interests"]:
                value = utils.extract_value(values, key, key)
                utils.add_profile_details(user, key, value)
            app_home({"user": user})

        # Purge messages
        if callback_id == "purge_confirmation":
            # Extract metadata
            metadata = blocks.json.loads(view["private_metadata"])

            # Signal the purge is starting
            client.chat_postEphemeral(channel=metadata["channel_id"],
                                      user=user,
                                      text="Purging messages...")

            # Retrieve data from metadata
            number_of_messages = metadata["number_of_messages"]
            target_user_id = metadata["user"][2:13]
            oldest = int(
                utils.time.time()
            ) - metadata["time_period"] if metadata["time_period"] != -1 else 0
            channel_id = metadata["channel_id"]
            text_snippet = metadata["text_snippet"]

            # Get messages from channel
            conversations_history = client.conversations_history(
                channel=channel_id, oldest=oldest).data

            # Iterate through messages and delete messages until we run out of messages to delete or reach our target
            count_deleted = 0
            while count_deleted < number_of_messages:

                # Iterate through messages
                for msg in conversations_history["messages"]:

                    # Skip messages that are not actual messages (e.g event messages)
                    if msg["type"] != "message":
                        continue

                    # Delete if no user specified or user of message matches target
                    if (target_user_id == "" or target_user_id == msg["user"]
                        ) and (text_snippet == ""
                               or text_snippet in blocks.json.dumps(msg)):
                        try:
                            user_client.chat_delete(channel=channel_id,
                                                    ts=msg["ts"])
                            count_deleted += 1
                        except Exception as e:
                            # Serve error back to user for debugging
                            client.chat_postEphemeral(
                                channel=metadata["channel_id"],
                                user=user,
                                text=str(e))
                            quit()

                    # Break loop if target number of messages is reached
                    if count_deleted >= number_of_messages:
                        break

                # Check that there are more messages to retrieve
                if conversations_history["has_more"] is False:
                    break

                # Retrieve next set of messages
                cursor = conversations_history["response_metadata"][
                    "next_cursor"]
                conversations_history = client.conversations_history(
                    channel=channel_id, oldest=oldest, cursor=cursor)

            # Signal the purge is complete
            client.chat_postEphemeral(channel=metadata["channel_id"],
                                      user=user,
                                      text="Purge complete")

        # Store submitted profile data
        if callback_id == "anonymous_messaging_modal":
            print(view["state"])
            controls = []
            # Unwrap control
            for control in list(state["values"].items()):
                control = control[1]
                control = list(control.items())[0][1]
                print(control)
                controls.append(control)

            users = controls[0]["selected_users"]
            message = controls[1]["value"]
            msg_ids = utils.create_anon_message(user, users, message)
            for i, selected_user in enumerate(users):
                block = get_anonymous_message(message, msg_ids[i])
                client.chat_postMessage(channel=selected_user, blocks=block)
        elif callback_id.startswith("anonymous_messaging_modal_reply"):
            view = payload["view"]
            state = view["state"]
            message_id = callback_id.split("=")[1]
            # Unwrap control
            control = list(state["values"].items())
            control = control[0][1]
            control = list(control.items())[0][1]
            reply_msg = control["value"]
            print(reply_msg)
            reply = utils.reply_anon_message(user, message_id, reply_msg)
            block = get_anonymous_message(reply_msg, reply.id)
            client.chat_postMessage(channel=reply.target_id, blocks=block)
        elif callback_id.startswith("report_messaging_modal_reply"):
            view = payload["view"]
            state = view["state"]
            message_id = callback_id.split("=")[1]
            # Unwrap control
            control = list(state["values"].items())
            control = control[0][1]
            control = list(control.items())[0][1]
            report_msg = control["value"]
            print(report_msg)
            report_id = utils.report_message(message_id, report_msg)
            client.chat_postMessage(
                channel=payload["user"]["id"],
                text="Message Reported, to follow up "
                "provide the following report id: R{}".format(report_id))

    if payload["type"] == "block_actions":
        print(payload)
        if "trivia_custom_" in payload['actions'][0]['action_id']:
            trivia_customs(
                payload['actions'][0]['action_id'].replace(
                    "trivia_custom_", ""), payload['trigger_id'])
            return
        elif "accept_trivia_" in payload['actions'][0]['action_id']:
            trivia_reply(
                payload['user']['id'], True,
                payload['actions'][0]['action_id'].replace(
                    "accept_trivia_", ""), payload['trigger_id'])
            return
        elif "forfeit_trivia_" in payload['actions'][0]['action_id']:
            trivia_reply(
                payload['user']['id'], False,
                payload['actions'][0]['action_id'].replace(
                    "forfeit_trivia_", ""), payload['trigger_id'])
            return
        elif 'view' in payload and "trivia_start_" in payload['view'][
                'callback_id']:
            if "default_trivia_" in payload['actions'][0]['action_id']:
                trivia_set_qs(
                    payload['actions'][0]['action_id'].replace(
                        "default_trivia_", ""), payload['actions'][0]
                    ['selected_option']['value'] == "true")
                return
            elif 'view' in payload and "trivia_channel_" in payload['actions'][
                    0]['action_id']:
                trivia_set_channel(
                    payload['actions'][0]['action_id'].replace(
                        "trivia_channel_", ""),
                    payload['actions'][0]['selected_channel'])
                return
        elif 'view' in payload and "trivia_question_" in payload['view'][
                'callback_id']:
            trivia_response(payload['user']['id'],
                            payload['actions'][0]['value'] == 'correct',
                            payload['trigger_id'])
            return
        elif "course_overall_" in payload['actions'][0]['action_id']:
            review_overall(
                payload['actions'][0]['action_id'].replace(
                    "course_overall_", ""),
                payload['actions'][0]['selected_option']['value'])
        elif "course_difficulty_" in payload['actions'][0]['action_id']:
            review_difficulty(
                payload['actions'][0]['action_id'].replace(
                    "course_difficulty_", ""),
                payload['actions'][0]['selected_option']['value'])
        elif "course_time_" in payload['actions'][0]['action_id']:
            review_time(
                payload['actions'][0]['action_id'].replace("course_time_", ""),
                payload['actions'][0]['selected_option']['value'])

        # Received when a user clicks a Block Kit interactive component.
        actions = payload["actions"]
        value = actions[0]["value"]

        # Opens the "report" view
        if value == "click_report":
            message_id = payload["message"]["blocks"][0]["block_id"]
            client.views_open(trigger_id=trigger_id,
                              view=get_report_modal(message_id))

        # Opens the "anonymous_reply" modal
        if value == "click_reply":
            message_id = payload["message"]["blocks"][0]["block_id"]
            client.views_open(trigger_id=trigger_id,
                              view=get_anonymous_reply_modal(message_id))

        # Close Report
        if value.startswith("remove_report_"):
            report_id = value.split("_")[-1]
            utils.close_report(report_id)
            client.chat_postMessage(
                channel=payload["user"]["id"],
                text="Successfully removed report R{}".format(report_id))

        # No modal is expected
        if value == "pass":
            pass

        # Opens the "commands_help" view
        if value == "commands_help":
            client.views_open(trigger_id=trigger_id,
                              view=blocks.commands_help())

        # Opens the "edit_profile" view with prefilled information
        if value == "edit_profile":
            values = utils.retrieve_profile_details(user)
            client.views_open(trigger_id=trigger_id,
                              view=blocks.edit_profile(values))