Skip to content

Commit 7e67490

Browse files
committed
adding slack channel creation (WIP)
1 parent 054155a commit 7e67490

6 files changed

Lines changed: 103 additions & 9 deletions

File tree

custom_slack_provider/slack.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import json
1+
import re
22
import requests
33
from requests.auth import AuthBase
44

@@ -24,6 +24,7 @@ class CustomSlackClient():
2424
identity_url = 'https://slack.com/api/users.identity'
2525
user_detail_url = 'https://slack.com/api/users.info'
2626
create_conversation_url = 'https://slack.com/api/conversations.create'
27+
invite_conversation_url = 'https://slack.com/api/conversations.invite'
2728

2829
def __init__(self, token):
2930
self.token = token
@@ -64,3 +65,20 @@ def create_slack_channel(self, channel_name, is_private=True):
6465
new_channel = self._make_slack_post_request(
6566
self.create_conversation_url, data=data)
6667
return new_channel.get('channel', {})
68+
69+
def _extract_userid_from_username(self, username):
70+
""" Extracts the Slack userid from a hackathon platform userid
71+
when Slack is enabled and the account was created with a valid userid
72+
schema: [SLACK_USER_ID]_[WORKSPACE_TEAM_ID]"""
73+
if not re.match(r'[A-Z0-9]*[_]T[A-Z0-9]*', username):
74+
raise SlackException('Error adding user to channel')
75+
return username.split('_')[0]
76+
77+
def add_user_to_slack_channel(self, username, channel_id):
78+
data = {
79+
"user": self._extract_userid_from_username(username),
80+
"channel": channel_id,
81+
}
82+
user_added = self._make_slack_post_request(
83+
self.invite_conversation_url, data=data)
84+
return user_added

custom_slack_provider/tests.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from .provider import SlackProvider
88
from custom_slack_provider.slack import CustomSlackClient, SlackException
99
from django.core.management import call_command
10+
from
1011

1112

1213
class SlackOAuth2Tests(OAuth2TestsMixin, TestCase):
@@ -60,14 +61,37 @@ def test__make_slack_post_request(self, post):
6061
mock_response.json.return_value = {'ok': False,
6162
'error': 'Slack Error'}
6263
try:
63-
client._make_slack_get_request(url='test')
64+
client._make_slack_post_request(url='test', data={})
6465
except SlackException as e:
6566
self.assertTrue(isinstance(e, SlackException))
6667
self.assertEquals(e.message, 'Slack Error')
6768

68-
@patch('custom_slack_provider.slack.CustomSlackClient._make_slack_get_request')
69+
@patch('custom_slack_provider.slack.CustomSlackClient._make_slack_get_request') # noqa: 501
6970
def test_get_identity(self, _make_slack_get_request):
7071
_make_slack_get_request.return_value = {'user': {'id': 1}}
7172
client = CustomSlackClient(self.token)
7273
response = client.get_identity()
7374
self.assertEqual(response['user']['id'], 1)
75+
76+
def test__extract_userid_from_username(self):
77+
valid_username = 'US123123_T123123'
78+
invalid_username = 'bob@bob.com'
79+
client = CustomSlackClient(self.token)
80+
userid = client._extract_userid_from_username(valid_username)
81+
self.assertEqual(userid, 'US123123')
82+
try:
83+
userid = client._extract_userid_from_username(invalid_username)
84+
except SlackException as e:
85+
self.assertTrue(isinstance(e, SlackException))
86+
self.assertEquals(e.message, 'Error adding user to channel')
87+
88+
@patch('custom_slack_provider.slack.CustomSlackClient._make_slack_post_request') # noqa: 501
89+
def test_add_user_to_slack_channel(self, _make_slack_post_request):
90+
_make_slack_post_request.return_value = {
91+
'ok': True,
92+
'channel': {'id': 'CH123123'}
93+
}
94+
client = CustomSlackClient(self.token)
95+
response = client.add_user_to_slack_channel(username='UA123123_T15666',
96+
channel_id='CH123123')
97+
self.assertEqual(response['channel']['id'], 'CH123123')

hackathon/tasks.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
from accounts.models import CustomUser as User
1616
from hackathon.models import Hackathon
17-
from custom_slack_provider.slack import CustomSlackClient
17+
from custom_slack_provider.slack import CustomSlackClient, SlackException
1818

1919
logger = logging.getLogger(__name__)
2020
logger.setLevel(logging.INFO)
@@ -61,8 +61,10 @@ def create_new_slack_channel(hackathon_id, channel_name):
6161
f"{hackathon.display_name} in Slack Workspace "
6262
f"{settings.SLACK_WORKSPACE}({settings.SLACK_TEAM_ID})"))
6363
slack_client = CustomSlackClient(settings.SLACK_BOT_TOKEN)
64-
channel_id = slack_client.create_slack_channel(
64+
channel = slack_client.create_slack_channel(
6565
channel_name, is_private=True)
66+
67+
channel_id = channel.get('id')
6668
logger.info(f"Channel with id {channel_id} created.")
6769

6870
if not channel_id:
@@ -73,3 +75,11 @@ def create_new_slack_channel(hackathon_id, channel_name):
7375
hackathon.channel_url = channel_url
7476
hackathon.save()
7577
logger.info(f"Hackathon {hackathon.display_name} updated successfully.")
78+
79+
logger.info("Adding channel admins")
80+
for admin in hackathon.channel_admins.all():
81+
try:
82+
slack_client.add_user_to_slack_channel(admin.username, channel_id)
83+
except SlackException:
84+
logger.exception((f"Could not add user with id {admin.id} "
85+
f"to channel {channel_id}."))

hackathon/tests/task_tests.py

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,46 @@
1-
from django.test import TestCase
1+
from datetime import datetime
2+
3+
from django.conf import settings
4+
from django.test import TestCase, override_settings
5+
import responses
6+
from unittest.mock import patch, Mock
7+
8+
from accounts.models import Organisation, CustomUser as User
9+
from hackathon.models import Hackathon
10+
from hackathon.tasks import create_new_slack_channel
11+
212

313
class TaskTests(TestCase):
4-
def test_simple_task(self):
5-
pass
14+
def setUp(self):
15+
organisation = Organisation.objects.create()
16+
self.user = User.objects.create(
17+
username="U213123_T123123",
18+
slack_display_name="bob",
19+
organisation=organisation,
20+
)
21+
self.hackathon = Hackathon.objects.create(
22+
created_by=self.user,
23+
display_name="hacktest",
24+
description="lorem ipsum",
25+
start_date=f'{datetime.now()}',
26+
end_date=f'{datetime.now()}')
27+
self.hackathon.channel_admins.add(self.user)
28+
29+
@override_settings(CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
30+
CELERY_ALWAYS_EAGER=True,
31+
BROKER_BACKEND='memory')
32+
def test_create_new_slack_channel(self):
33+
channel_id = 'CH123123'
34+
responses.add(
35+
responses.POST, 'https://slack.com/api/conversations.create',
36+
json={'ok': True, 'channel': {'id': channel_id}}, status=200)
37+
responses.add(
38+
responses.POST, 'https://slack.com/api/conversations.invite',
39+
json={'ok': True}, status=200)
40+
create_new_slack_channel.apply_async(args=[
41+
self.hackathon.id, self.user.username])
42+
43+
import time; time.sleep(3)
44+
self.assertEquals(
45+
self.hackathon.channel_url,
46+
f'https://{settings.SLACK_WORKSPACE}.slack.com/archives/{channel_id}')

hackathon/tests/test_models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def setUp(self):
3636
created_by=user,
3737
display_name="testaward",
3838
description="lorem ipsum")
39-
39+
4040
hack_award = HackAward.objects.create(
4141
created_by=user,
4242
hack_award_category=award_category,

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pytz==2020.4
5252
redis==4.1.1
5353
requests==2.24.0
5454
requests-oauthlib==1.3.0
55+
responses==0.17.0
5556
retrying==1.3.3
5657
sentry-sdk==0.10.2
5758
six==1.15.0

0 commit comments

Comments
 (0)