Skip to content

Commit

Permalink
- add slack settings tab on user's settings page
Browse files Browse the repository at this point in the history
- send same messages to user's slack as to gitcoin's slack

Fixes: gitcoinco#259
  • Loading branch information
darkdarkdragon committed Apr 21, 2018
1 parent 07903ba commit aae7d84
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 5 deletions.
1 change: 1 addition & 0 deletions app/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@
url(r'^settings/privacy/?', marketing.views.privacy_settings, name='privacy_settings'),
url(r'^settings/matching/?', marketing.views.matching_settings, name='matching_settings'),
url(r'^settings/feedback/?', marketing.views.feedback_settings, name='feedback_settings'),
url(r'^settings/slack/?', marketing.views.slack_settings, name='slack_settings'),
url(r'^settings/(.*)?', marketing.views.email_settings, name='feedback_settings'),

# marketing views
Expand Down
3 changes: 3 additions & 0 deletions app/dashboard/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from dashboard.models import Bounty, BountyFulfillment, BountySyncRequest, UserAction
from dashboard.notifications import (
maybe_market_to_email, maybe_market_to_github, maybe_market_to_slack, maybe_market_to_twitter,
maybe_market_to_user_slack,
)
from economy.utils import convert_amount
from github.utils import _AUTH
Expand Down Expand Up @@ -556,6 +557,7 @@ def process_bounty_changes(old_bounty, new_bounty):
print("============ posting ==============")
did_post_to_twitter = maybe_market_to_twitter(new_bounty, event_name)
did_post_to_slack = maybe_market_to_slack(new_bounty, event_name)
did_post_to_user_slack = maybe_market_to_user_slack(new_bounty, event_name)
did_post_to_github = maybe_market_to_github(new_bounty, event_name, profile_pairs)
did_post_to_email = maybe_market_to_email(new_bounty, event_name)
print("============ done posting ==============")
Expand All @@ -566,6 +568,7 @@ def process_bounty_changes(old_bounty, new_bounty):
'did_post_to_email': did_post_to_email,
'did_post_to_github': did_post_to_github,
'did_post_to_slack': did_post_to_slack,
'did_post_to_user_slack': did_post_to_user_slack,
'did_post_to_twitter': did_post_to_twitter,
}

Expand Down
64 changes: 60 additions & 4 deletions app/dashboard/notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,27 +171,83 @@ def maybe_market_to_slack(bounty, event_name):
if bounty.network != settings.ENABLE_NOTIFICATIONS_ON_NETWORK:
return False

msg = build_message_for_slack(bounty, event_name)
if not msg:
return False

try:
channel = 'notif-gitcoin'
sc = SlackClient(settings.SLACK_TOKEN)
sc.api_call("chat.postMessage", channel=channel, text=msg)
except Exception as e:
print(e)
return False
return True


def build_message_for_slack(bounty, event_name):
conv_details = ""
usdt_details = ""
try:
conv_details = f"@ (${round(convert_token_to_usdt(bounty.token_name),2)}/{bounty.token_name})"
usdt_details = f"({bounty.value_in_usdt_now} USD {conv_details} "
except Exception:
pass # no USD conversion rate
except Exception as e:
print(e)
return False

title = bounty.title if bounty.title else bounty.github_url
msg = f"{event_name.replace('bounty', 'funded_issue')} worth {round(bounty.get_natural_value(), 4)} {bounty.token_name} " \
f"{usdt_details}" \
f"{bounty.token_name}: {title} \n\n{bounty.get_absolute_url()}"
return msg


def maybe_market_to_user_slack(bounty, event_name):
"""Send a Slack message to the user's slack channel for the specified Bounty.
Args:
bounty (dashboard.models.Bounty): The Bounty to be marketed.
event_name (str): The name of the event.
Returns:
bool: Whether or not the Slack notification was sent successfully.
"""
from marketing.models import EmailSubscriber
if bounty.get_natural_value() < 0.0001:
return False
if bounty.network != settings.ENABLE_NOTIFICATIONS_ON_NETWORK:
return False

msg = build_message_for_slack(bounty, event_name)
if not msg:
return False

url = bounty.github_url
uri = parse(url).path
uri_array = uri.split('/')
sent = False
try:
channel = 'notif-gitcoin'
sc = SlackClient(settings.SLACK_TOKEN)
sc.api_call("chat.postMessage", channel=channel, text=msg)
username = uri_array[1]
repo = uri_array[2]
subscribers = EmailSubscriber.objects.filter(profile__handle=username, repos__contains=[repo])
subscribers = subscribers & EmailSubscriber.objects.exclude(slack_token='', slack_channel='')
for subscriber in subscribers:
try:
sc = SlackClient(subscriber.slack_token)
sc.api_call("chat.postMessage", channel=subscriber.slack_channel, text=msg)
sent = True
except Exception as e:
print(e)
except IndexError:
return False
except Exception as e:
print(e)
return False
return True

return sent

def maybe_market_tip_to_email(tip, emails):
"""Send an email for the specified Tip.
Expand Down
5 changes: 4 additions & 1 deletion app/dashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
)
from dashboard.notifications import (
maybe_market_tip_to_email, maybe_market_tip_to_github, maybe_market_tip_to_slack, maybe_market_to_slack,
maybe_market_to_twitter,
maybe_market_to_twitter, maybe_market_to_user_slack,
)
from dashboard.utils import get_bounty, get_bounty_id, has_tx_mined, web3_process_bounty
from gas.utils import conf_time_spread, eth_usd_conv_rate, recommend_min_gas_price_to_confirm_in_time
Expand Down Expand Up @@ -114,6 +114,7 @@ def create_new_interest_helper(bounty, user):
bounty.interested.add(interest)
record_user_action(user, 'start_work', interest)
maybe_market_to_slack(bounty, 'start_work')
maybe_market_to_user_slack(bounty, 'start_work')
maybe_market_to_twitter(bounty, 'start_work')
return interest

Expand Down Expand Up @@ -230,6 +231,7 @@ def remove_interest(request, bounty_id):
bounty.interested.remove(interest)
interest.delete()
maybe_market_to_slack(bounty, 'stop_work')
maybe_market_to_user_slack(bounty, 'stop_work')
maybe_market_to_twitter(bounty, 'stop_work')
except Interest.DoesNotExist:
return JsonResponse({
Expand Down Expand Up @@ -279,6 +281,7 @@ def uninterested(request, bounty_id, profile_id):
interest = Interest.objects.get(profile_id=profile_id, bounty=bounty)
bounty.interested.remove(interest)
maybe_market_to_slack(bounty, 'stop_work')
maybe_market_to_user_slack(bounty, 'stop_work')
interest.delete()
except Interest.DoesNotExist:
return JsonResponse({
Expand Down
30 changes: 30 additions & 0 deletions app/marketing/migrations/0022_auto_20180419_1517.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 2.0.4 on 2018-04-19 15:17

import django.contrib.postgres.fields
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('marketing', '0021_emailsubscriber_profile'),
]

operations = [
migrations.AddField(
model_name='emailsubscriber',
name='repos',
field=django.contrib.postgres.fields.ArrayField(
base_field=models.CharField(max_length=200), blank=True, default=[], size=None),
),
migrations.AddField(
model_name='emailsubscriber',
name='slack_channel',
field=models.CharField(default='', max_length=255),
),
migrations.AddField(
model_name='emailsubscriber',
name='slack_token',
field=models.CharField(default='', max_length=255),
),
]
3 changes: 3 additions & 0 deletions app/marketing/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class EmailSubscriber(SuperModel):
priv = models.CharField(max_length=30, default='')
github = models.CharField(max_length=255, default='')
keywords = ArrayField(models.CharField(max_length=200), blank=True, default=[])
repos = ArrayField(models.CharField(max_length=200), blank=True, default=[])
slack_token = models.CharField(max_length=255, default='')
slack_channel = models.CharField(max_length=255, default='')
profile = models.ForeignKey(
'dashboard.Profile',
on_delete=models.CASCADE,
Expand Down
42 changes: 42 additions & 0 deletions app/marketing/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,10 @@ def funnel(request):
'body': 'Feedback',
'href': '/settings/feedback',
},
{
'body': 'Slack',
'href': '/settings/slack',
},
]


Expand Down Expand Up @@ -615,6 +619,44 @@ def email_settings(request, key):
return TemplateResponse(request, 'settings/email.html', context)


def slack_settings(request):

# setup
profile, es, user, is_logged_in = settings_helper_get_auth(request)
if not es:
login_redirect = redirect('/login/github?next=' + request.get_full_path())
return login_redirect

msg = ''

if request.POST and request.POST.get('submit'):
token = request.POST.get('token', '')
repos = request.POST.get('repos').split(',')
channel = request.POST.get('channel', '')
es.slack_token = token
es.repos = repos
es.slack_channel = channel
ip = get_ip(request)
if not es.metadata.get('ip', False):
es.metadata['ip'] = [ip]
else:
es.metadata['ip'].append(ip)
es.save()
msg = "Updated your preferences. "

context = {
'repos': ",".join(es.repos),
'is_logged_in': is_logged_in,
'nav': 'internal',
'active': '/settings/slack',
'title': _('Slack Settings'),
'navs': settings_navs,
'es': es,
'msg': msg,
}
return TemplateResponse(request, 'settings/slack.html', context)


def _leaderboard(request):
return leaderboard(request, '')

Expand Down
23 changes: 23 additions & 0 deletions app/retail/templates/settings/slack.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{% extends 'settings/settings.html' %}
{% load i18n static %}

{% block settings_content %}
<form id="settings" method="POST">
<div class="form-group">
<h5>{% trans "Slack Integration" %}</h5>
<label class="form__label" for="token">{% trans "Slack API token" %}</label>
<input type="text" name="token" class="form__input" placeholder='API token' value="{{ es.slack_token }}">
</div>
<div class="form-group">
<label class="form__label" for="repos">{% trans "Github repos to monitor" %}</label>
<input type="text" name="repos" class="form__input" placeholder='comma, separated, list' value="{{ repos }}">
</div>
<div class="form-group">
<label class="form__label" for="channel">{% trans "Slack channel to post to" %}</label>
<input type="text" name="channel" class="form__input" value="{{ es.slack_channel }}">
</div>
{% csrf_token %}
<input class='button button--primary' type='submit' name='submit' value="Go">
</form>
</div>
{% endblock %}

0 comments on commit aae7d84

Please sign in to comment.