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

Add webhooks calls to SDK #44

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
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
16 changes: 16 additions & 0 deletions examples/webhooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import guru

g = guru.Guru(dry_run=False)

# make a new webhook.
g.create_webhook("https://someserver.com", "card-created,card-updated")

# get webhooks.
list_of_webhooks = g.get_webhooks()
# get webhook by ID
webhook_at_someserver = next((webhook for webhook in list_of_webhooks if webhook["target_url"] == "https://someserver.com"), None)
individual_webhook = g.get_webhook(webhook_at_someserver.id)

# delete the webhook.
g.delete_webhook(individual_webhook.id)

73 changes: 71 additions & 2 deletions guru/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from urlparse import quote

from guru.bundle import Bundle
from guru.data_objects import Board, BoardGroup, BoardPermission, Card, CardComment, Collection, CollectionAccess, Draft, Group, HomeBoard, Tag, User, Question, Framework
from guru.data_objects import Board, BoardGroup, BoardPermission, Card, CardComment, Collection, CollectionAccess, Draft, Group, HomeBoard, Tag, User, Question, Framework, Webhook
from guru.util import download_file, find_by_name_or_id, find_by_email, find_by_id, format_timestamp, TRACKING_HEADERS

# collection colors
Expand Down Expand Up @@ -2903,4 +2903,73 @@ def delete_knowledge_trigger(self, trigger_id):

url = "%s/newcontexts/%s" % (self.base_url, trigger_id)
response = self.__delete(url)
return status_to_bool(response.status_code)
return status_to_bool(response.status_code)

def get_webhooks(self, cache=True):
"""Gets a list of webhooks

Args:
cache (bool, optional): Boolean determining if we should cache the results or not. Defaults to True.

Returns:
[Webhook]: returns a List of Webhook object
"""
url = "%s/webhooks" % self.base_url
webhooks = self.__get_and_get_all(url, cache)
return [Webhook(w, guru=self) for w in webhooks]

def get_webhook(self, webhook_id):
"""Gets a webhook by ID

Args:
webhook_id (str): ID of webhook (e.g.: 11111111-aaaa-bbbb-cccc-2222dddd3333)

Returns:
Webhook: returns a Webhook object
"""
url = "%s/webhooks/%s" % (self.base_url, webhook_id)
response = self.__get(url)
return Webhook(response.json(), guru=self)

def create_webhook(self, target_url, webhook_filter, delivery_mode="BATCH", status="ENABLED"):
"""Creates a webhook

Args:
target_url (str): url of destination webhook server. The destination server must be active and ready to receive events. More details at https://developer.getguru.com/docs/creating-a-webhook.
webhook_filter (str): String of comma separate values, that correspond to the event to listen for. Maximum of 10 events allowed per webhook. (e.g: "card-created,card-to-pdf").
delivery_mode (str, optional): method of sending events, either BATCH or SINGLE (More details at https://developer.getguru.com/docs/creating-a-webhook.). Defaults to "BATCH".
status (str, optional): Either ENABLED or DISABLED (https://developer.getguru.com/docs/updating-a-webhook for more details). Defaults to "ENABLED".

Returns:
Webhook: returns a Webhook object
"""
if not target_url or not webhook_filter:
self.__log(make_red("Either target_url or webhook_filter was not provided, and is required."))
return
data = {
"deliveryMode": delivery_mode,
"targetUrl": target_url,
"status": status,
"filter": webhook_filter
}
url = "%s/webhooks" % self.base_url
response = self.__post(url, data=data)
return Webhook(response.json(), guru=self)

def delete_webhook(self, webhook_id):
"""Deletes a webhook by ID

Args:
webhook_id (str): ID of webhook (e.g.: 11111111-aaaa-bbbb-cccc-2222dddd3333)

Returns:
status (bool): Boolean telling whether the delete action was successful or not, based on the response's status code.
"""
# check if webhook exist, then delete
url = "%s/webhooks/%s" % (self.base_url, webhook_id)
get_response = self.__get(url)
if not status_to_bool(get_response.status_code):
self.__log(make_red("could not find webhook:", webhook_id))
return
delete_response = self.__delete(url)
return status_to_bool(delete_response.status_code)
13 changes: 13 additions & 0 deletions guru/data_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -1323,3 +1323,16 @@ def dismiss(self):
bool: True if it was successful and False otherwise.
"""
return self.guru.delete_question(self)

class Webhook:
"""Represents a webhook"""
def __init__(self, data, guru=None):
self.guru = guru
self.owner = User(data.get("owner"))
self.filter = data.get("filter")
self.id = data.get("id")
self.status = data.get("status")
self.date_created = data.get("dateCreated")
self.target_url = data.get("targetUrl")
self.last_modified_date = data.get("dateLastModified")
self.delivery_mode = data.get("deliveryMode")
160 changes: 160 additions & 0 deletions tests/test_webhooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import unittest
import responses

from tests.util import use_guru, get_calls

import guru


class TestCore(unittest.TestCase):
@use_guru()
@responses.activate
def test_get_webhooks(self, g):
responses.add(responses.GET, "https://api.getguru.com/api/v1/webhooks", json=[{
"owner": {
"status": "ACTIVE",
"email": "[email protected]",
"firstName": "beth",
"lastName": "jones",
"profilePicUrl": "https://lh3.googleusercontent.com/a-/beth"
},
"filter": "card-to-pdf",
"id": "2222",
"status": "ENABLED",
"deliveryMode": "BATCH",
"dateCreated": "2021-05-10T17:05:32.245+0000",
"team": {
"id": "17724bbf-b6b2-4f78-b3db-91188cac3444",
"status": "ACTIVE",
"dateCreated": "2019-11-05T18:48:38.821+0000",
"profilePicUrl": "https://assets.getguru.com/default-team-logo.png",
"name": "TestImageTeam"
},
"dateLastModified": "2021-05-10T17:05:32.245+0000",
"targetUrl": "https://someotherserver.com/"
}])

webhooks = g.get_webhooks()

self.assertEqual(webhooks[0].id, "2222")

self.assertEqual(get_calls(), [{
"method": "GET",
"url": "https://api.getguru.com/api/v1/webhooks",
}])


@use_guru()
@responses.activate
def test_get_webhook(self, g):
responses.add(responses.GET, "https://api.getguru.com/api/v1/webhooks/1111", json={
"owner": {
"status": "ACTIVE",
"email": "[email protected]",
"firstName": "bob",
"lastName": "smith",
"profilePicUrl": "https://lh3.googleusercontent.com/a-/bob"
},
"filter": "card-created",
"id": "1111",
"status": "ENABLED",
"deliveryMode": "BATCH",
"dateCreated": "2021-05-10T17:05:32.245+0000",
"team": {
"id": "17724bbf-b6b2-4f78-b3db-91188cac3444",
"status": "ACTIVE",
"dateCreated": "2019-11-05T18:48:38.821+0000",
"profilePicUrl": "https://assets.getguru.com/default-team-logo.png",
"name": "TestImageTeam"
},
"dateLastModified": "2021-05-10T17:05:32.245+0000",
"targetUrl": "https://someserver.com/"
})

webhook = g.get_webhook("1111")

self.assertEqual(webhook.id, "1111")

self.assertEqual(get_calls(), [{
"method": "GET",
"url": "https://api.getguru.com/api/v1/webhooks/1111"
}])

@use_guru()
@responses.activate
def test_delete_webhook(self, g):
responses.add(responses.GET, "https://api.getguru.com/api/v1/webhooks/1111", status=200, json=[{
"owner": {
"status": "ACTIVE",
"email": "[email protected]",
"firstName": "bob",
"lastName": "smith",
"profilePicUrl": "https://lh3.googleusercontent.com/a-/bob"
},
"filter": "card-created",
"id": "1111",
"status": "ENABLED",
"deliveryMode": "BATCH",
"dateCreated": "2021-05-10T17:05:32.245+0000",
"team": {
"id": "17724bbf-b6b2-4f78-b3db-91188cac3444",
"status": "ACTIVE",
"dateCreated": "2019-11-05T18:48:38.821+0000",
"profilePicUrl": "https://assets.getguru.com/default-team-logo.png",
"name": "TestImageTeam"
},
"dateLastModified": "2021-05-10T17:05:32.245+0000",
"targetUrl": "https://someserver.com/"
}])
responses.add(responses.DELETE, "https://api.getguru.com/api/v1/webhooks/1111")

delete_status = g.delete_webhook("1111")

self.assertEqual(get_calls(), [{
"method": "GET",
"url": "https://api.getguru.com/api/v1/webhooks/1111"
},{
"method": "DELETE",
"url": "https://api.getguru.com/api/v1/webhooks/1111",
}])

@use_guru()
@responses.activate
def test_create_webhook(self, g):
responses.add(responses.POST, "https://api.getguru.com/api/v1/webhooks", json={
"owner": {
"status": "ACTIVE",
"email": "[email protected]",
"firstName": "bob",
"lastName": "smith",
"profilePicUrl": "https://lh3.googleusercontent.com/a-/bob"
},
"filter": "card-created,card-to-pdf",
"id": "1111",
"status": "ENABLED",
"deliveryMode": "BATCH",
"dateCreated": "2021-05-10T17:05:32.245+0000",
"team": {
"id": "17724bbf-b6b2-4f78-b3db-91188cac3444",
"status": "ACTIVE",
"dateCreated": "2019-11-05T18:48:38.821+0000",
"profilePicUrl": "https://assets.getguru.com/default-team-logo.png",
"name": "TestImageTeam"
},
"dateLastModified": "2021-05-10T17:05:32.245+0000",
"targetUrl": "https://someserver.com"
})

result = g.create_webhook("https://someserver.com", "card-created,card-to-pdf")

self.assertEqual(result.target_url, "https://someserver.com")
self.assertEqual(get_calls(), [{
"method": "POST",
"url": "https://api.getguru.com/api/v1/webhooks",
"body": {
"deliveryMode": "BATCH",
"targetUrl": "https://someserver.com",
"status": "ENABLED",
"filter": "card-created,card-to-pdf"
}
}])