-
Notifications
You must be signed in to change notification settings - Fork 6
feat: Slack pairings #553
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat: Slack pairings #553
Changes from 1 commit
4abe871
0c9f9b2
f76a14a
eb3ff7d
6c07dc3
8b47828
ee7b640
09d3bdb
0d35701
128ae06
4d39fe4
0b9f76a
36fea81
d2e2b87
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,63 @@ | ||||||||||||||||
| """Match two Launchpad member for a private conversation""" | ||||||||||||||||
| from slack import WebClient | ||||||||||||||||
| from interface.slack import Bot | ||||||||||||||||
| from random import shuffle | ||||||||||||||||
| from .base import ModuleBase | ||||||||||||||||
| from typing import Dict, List, Tuple, Any | ||||||||||||||||
| from flask import Flask | ||||||||||||||||
| from config import Config | ||||||||||||||||
| from db.facade import DBFacade | ||||||||||||||||
| import logging | ||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
| class Pairing(ModuleBase): | ||||||||||||||||
| """Module that matches 2 launchpad members each week""" | ||||||||||||||||
|
|
||||||||||||||||
| NAME = 'Match launch pad members randomly' | ||||||||||||||||
|
tarikeshaq marked this conversation as resolved.
Outdated
|
||||||||||||||||
|
|
||||||||||||||||
| def __init__(self, | ||||||||||||||||
| flask_app: Flask, | ||||||||||||||||
| config: Config, | ||||||||||||||||
| facade: DBFacade): | ||||||||||||||||
| """Initialize the object.""" | ||||||||||||||||
| self.bot = Bot(WebClient(config.slack_api_token), | ||||||||||||||||
| config.slack_notification_channel) | ||||||||||||||||
| self.channel_id = self.bot.get_channel_id(config.slack_pairing_channel) | ||||||||||||||||
| self.facade = facade | ||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
| def get_job_args(self) -> Dict[str, Any]: | ||||||||||||||||
| """Get job configuration arguments for apscheduler.""" | ||||||||||||||||
| return {'trigger': 'cron', | ||||||||||||||||
| 'minute': '*', | ||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm guessing this is just temporary for testing, but could also just make this a configuration option!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alrighty made it an env variable as a cron job string... not the cleanest so happy for recommendations! |
||||||||||||||||
| 'name': self.NAME} | ||||||||||||||||
|
|
||||||||||||||||
| def do_it(self): | ||||||||||||||||
| """Pair users together, and create a private chat for them""" | ||||||||||||||||
| users = self.bot.get_channel_users(self.channel_id) | ||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably want to stop execution when we find out that there are no users in the channel (it also removes a check in |
||||||||||||||||
| logging.debug(f"users of the pairing channel are {users}") | ||||||||||||||||
| matched_user_pairs = self.__pair_users(users) | ||||||||||||||||
| for pair in matched_user_pairs: | ||||||||||||||||
| group_name = self.bot.create_private_chat(pair) | ||||||||||||||||
| logging.info(f"The name of the created group name is {group_name}") | ||||||||||||||||
| self.bot.send_to_channel("Hello! You have been matched by Rocket. " + | ||||||||||||||||
| "please use this channel to get to know each other!", group_name) | ||||||||||||||||
|
|
||||||||||||||||
| def __pair_users(self, users: List[str]) -> List[List[str]]: | ||||||||||||||||
| """ | ||||||||||||||||
| Creates pairs of users that haven't been matched before | ||||||||||||||||
| """ | ||||||||||||||||
| shuffle(users) | ||||||||||||||||
| pairs = [] | ||||||||||||||||
| pair = [] | ||||||||||||||||
| for i, user in enumerate(users): | ||||||||||||||||
| pair.append(user) | ||||||||||||||||
| if i % 2 != 0: | ||||||||||||||||
| pairs.append(pair) | ||||||||||||||||
| pair = [] | ||||||||||||||||
| # If we have an odd number of people that is not 1 | ||||||||||||||||
| # We put the odd person out in one of the groups | ||||||||||||||||
| # So we might have a group of 3 | ||||||||||||||||
|
Comment on lines
+85
to
+87
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||
| if len(pair) == 1 and len(pairs) > 0: | ||||||||||||||||
| pairs[len(pairs) - 1].append(pair[0]) | ||||||||||||||||
| return pairs | ||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -110,6 +110,43 @@ def send_event_notif(self, message): | |||||
| logging.error("Webhook notif failed to send due to {} error.". | ||||||
| format(se.error)) | ||||||
|
|
||||||
| def create_private_chat(self, users: List[str]) -> str: | ||||||
| """ | ||||||
| Create a private chat with the given users | ||||||
|
|
||||||
| :param users: the list of users to add to the private chat | ||||||
|
|
||||||
| :raise SlackAPIError if the slack API returned error openning the chat | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| :return The name of of the private chat created | ||||||
| """ | ||||||
| logging.debug(f"Attempting to open a private conversation with users {users}") | ||||||
| response = self.sc.conversations_open(users = users) | ||||||
| if response['ok']: | ||||||
| logging.debug(f"Successfly opened a converation with the name {response['channel']['name']}") | ||||||
| return response['channel']['name'] | ||||||
| raise SlackAPIError(response['error']) | ||||||
|
|
||||||
| def get_channel_id(self, channel_name: str) -> str: | ||||||
| """ | ||||||
| Retrieves a channel's id given it's name | ||||||
|
|
||||||
| :param channel_name: The name of the channel | ||||||
|
|
||||||
| :raise SlackAPIError if no channels were found with the name `channel_name` | ||||||
|
|
||||||
| :return the slack id of the channel | ||||||
| """ | ||||||
| # We strip away the "#" in case it was provided with the channel name | ||||||
| channel_name = channel_name.replace("#", "") | ||||||
|
tarikeshaq marked this conversation as resolved.
Outdated
|
||||||
| logging.debug(f"Attempting to get the id of channel {channel_name}") | ||||||
| channels = list(filter(lambda c: c['name'] == channel_name, self.get_channels())) | ||||||
| if len(channels) == 0: | ||||||
| raise SlackAPIError(f"No channels found with the name{channel_name}") | ||||||
| if len(channels) != 1: | ||||||
| logging.warning(f"Somehow there is more than one channel with the name {channel_name}") | ||||||
| return channels[0]['id'] | ||||||
|
|
||||||
|
|
||||||
| class SlackAPIError(Exception): | ||||||
| """Exception representing an error while calling Slack API.""" | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.