Skip to content
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

GITC-49: Adds notion integration to support sybil-hunting #9176

Merged
merged 2 commits into from
Jun 28, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/app/local.env
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ GOOGLE_CLIENT_SECRET=
FACEBOOK_CLIENT_ID=
FACEBOOK_CLIENT_SECRET=

# For notion integration (on grant creation)
NOTION_API_KEY=
NOTION_SYBIL_DB=

INFURA_USE_V3=True

SUPRESS_DEBUG_TOOLBAR=1
Expand Down
4 changes: 4 additions & 0 deletions app/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,10 @@ def callback(request):
FACEBOOK_CLIENT_ID = env('FACEBOOK_CLIENT_ID', default='')
FACEBOOK_CLIENT_SECRET = env('FACEBOOK_CLIENT_SECRET', default='')

# Notion
NOTION_API_KEY = env('NOTION_API_KEY', default='')
NOTION_SYBIL_DB = env('NOTION_SYBIL_DB', default='')

# Kudos revenue account
KUDOS_REVENUE_ACCOUNT_ADDRESS = env('KUDOS_REVENUE_ACCOUNT_ADDRESS', default='0xAD278911Ad07534F921eD7D757b6c0e6730FCB16')

Expand Down
45 changes: 45 additions & 0 deletions app/app/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import email
import functools
import imaplib
import json
import logging
import multiprocessing.pool
import os
Expand Down Expand Up @@ -535,3 +536,47 @@ def func_wrapper(*args, **kwargs):
return func_wrapper

return timeout_decorator


def notion_write(database_id='', payload=None):
# write to the pages api (https://developers.notion.com/reference/post-page)
url = "https://api.notion.com/v1/pages"
# define the parent (database) that we're writing to and set the properties (row content)
body = {
"parent": {
"type": "database_id",
"database_id": database_id
},
"properties": payload
}

# return success as dict
return notion_api_call(url, body)


def notion_read(database_id, payload=None):
# read from the database query api (https://developers.notion.com/docs/working-with-databases)
url = f"https://api.notion.com/v1/databases/{database_id}/query"

# return success as dict
return notion_api_call(url, payload)


def notion_api_call(url='', payload=None):
# retrieve auth from headers
headers = {
"Authorization": f"Bearer {settings.NOTION_API_KEY}",
"Content-Type": "application/json",
"Notion-Version": "2021-05-13"
}
# default the body to empty dict
body = payload if isinstance(payload, dict) else {}
# print({'url':url, 'headers':json.dumps(headers), 'data':json.dumps(body)})
response = requests.post(url=url, headers=headers, data=json.dumps(body))

# throw exception if we dont get a 200 response
if response.status_code != 200:
raise Exception("Failed to set to/get from notion")

# return success as dict
return response
52 changes: 52 additions & 0 deletions app/grants/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

from app import settings
from app.settings import BASE_DIR, BASE_URL, MEDIA_URL, STATIC_HOST, STATIC_URL
from app.utils import notion_write
from avatar.utils import convert_img
from economy.utils import ConversionRateNotFoundError, convert_amount
from gas.utils import eth_usd_conv_rate
Expand Down Expand Up @@ -338,3 +339,54 @@ def sync_payout(contribution):
return None

tenant_payout_mapper[subscription.tenant](contribution)


def save_grant_to_notion(title, url):
"""Post an insert to notions sybil-db table"""
# check for notion credentials before attempting insert
if settings.NOTION_SYBIL_DB and settings.NOTION_API_KEY:
# fully qualified url
fullUrl = settings.BASE_URL.rstrip('/') + url

# write to NOTION_SYBIL_DB following the defined schema (returns dict of new object)
return notion_write(settings.NOTION_SYBIL_DB, {
'Current Status': {
'id': 'ea{s',
'type': 'select',
'select': {
'id': '002e021f-3dde-4282-96e6-b2ce1c3a8380',
'name': 'PENDING - Steward Review',
'color': 'yellow'
}
},
'URL': {
'id': 'ThRE',
'type': 'rich_text',
'rich_text': [{
'type': 'text',
'text': {
'content': url,
'link': {
'url': fullUrl
}
},
'plain_text': url,
'href': fullUrl
}]
},
'Grant Name': {
"id": "title",
"type": "title",
"title": [{
"type": "text",
"text": {
"content": title,
"link": {
"url": fullUrl
}
},
"plain_text": title,
"href": fullUrl
}]
}
})
11 changes: 10 additions & 1 deletion app/grants/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
from grants.tasks import process_grant_creation_admin_email, process_grant_creation_email, update_grant_metadata
from grants.utils import (
emoji_codes, generate_collection_thumbnail, generate_img_thumbnail_helper, get_clr_rounds_metadata, get_user_code,
is_grant_team_member, sync_payout,
is_grant_team_member, save_grant_to_notion, sync_payout,
)
from kudos.models import BulkTransferCoupon, Token
from marketing.mails import grant_cancellation, new_grant_flag_admin
Expand Down Expand Up @@ -1864,6 +1864,15 @@ def grant_new(request):

grant = Grant.objects.create(**grant_kwargs)

try:
# record to notion for sybil-hunters
save_grant_to_notion(title, grant.url)
except:
# delete the newly created grant and error if we can't save to notion
grant.delete()
gdixon marked this conversation as resolved.
Show resolved Hide resolved
response['message'] = 'error: Grant creation failed, please try again'
return JsonResponse(response)

hackathon_project_id = request.GET.get('related_hackathon_project_id')
if hackathon_project_id:
hackathon_project = HackathonProject.objects.filter(id=hackathon_project_id).first()
Expand Down