Skip to content

Commit f9d033c

Browse files
committed
integrations: Add ClickUp integration.
Creates an incoming webhook integration for ClickUp. The main use case is getting notifications when new ClickUp items such as task, list, folder, space, goals are created, updated or deleted. Fixes zulip#26529.
1 parent 93e0561 commit f9d033c

37 files changed

+1365
-0
lines changed
Loading
27.6 KB
Loading
Lines changed: 1 addition & 0 deletions
Loading

zerver/lib/integrations.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ def __init__(self, name: str, *args: Any, **kwargs: Any) -> None:
375375
WebhookIntegration("buildbot", ["continuous-integration"], display_name="Buildbot"),
376376
WebhookIntegration("canarytoken", ["monitoring"], display_name="Thinkst Canarytokens"),
377377
WebhookIntegration("circleci", ["continuous-integration"], display_name="CircleCI"),
378+
WebhookIntegration("clickup", ["project-management"], display_name="ClickUp"),
378379
WebhookIntegration("clubhouse", ["project-management"]),
379380
WebhookIntegration("codeship", ["continuous-integration", "deployment"]),
380381
WebhookIntegration("crashlytics", ["monitoring"]),
@@ -726,6 +727,7 @@ def __init__(self, name: str, *args: Any, **kwargs: Any) -> None:
726727
ScreenshotConfig("bitbucket_job_completed.json", image_name="001.png"),
727728
ScreenshotConfig("github_job_completed.json", image_name="002.png"),
728729
],
730+
"clickup": [ScreenshotConfig("task_moved.json")],
729731
"clubhouse": [ScreenshotConfig("story_create.json")],
730732
"codeship": [ScreenshotConfig("error_build.json")],
731733
"crashlytics": [ScreenshotConfig("issue_message.json")],

zerver/webhooks/clickup/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from typing import Any
2+
from urllib.parse import urljoin
3+
4+
import requests
5+
6+
7+
def get_clickup_api_data(clickup_api_path: str, **kwargs: Any) -> dict[str, Any]:
8+
if not kwargs.get("token"):
9+
raise AssertionError("ClickUp API 'token' missing in kwargs")
10+
token = kwargs.pop("token")
11+
12+
base_url = "https://api.clickup.com/api/v2/"
13+
api_endpoint = urljoin(base_url, clickup_api_path)
14+
response = requests.get(
15+
api_endpoint,
16+
headers={
17+
"Content-Type": "application/json",
18+
"Authorization": token,
19+
},
20+
params=kwargs,
21+
)
22+
if response.status_code == requests.codes.ok:
23+
return response.json()
24+
else:
25+
raise Exception(f"HTTP error accessing the ClickUp API. Error: {response.status_code}")
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"id": "457",
3+
"name": "Lord Foldemort",
4+
"orderindex": 0,
5+
"override_statuses": false,
6+
"hidden": false,
7+
"space": {
8+
"id": "789",
9+
"name": "Space Name",
10+
"access": true
11+
},
12+
"task_count": "0",
13+
"lists": []
14+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"goal": {
3+
"id": "e53a033c-900e-462d-a849-4a216b06d930",
4+
"name": "hat-trick",
5+
"team_id": "512",
6+
"date_created": "1568044355026",
7+
"start_date": null,
8+
"due_date": "1568036964079",
9+
"description": "Updated Goal Description",
10+
"private": false,
11+
"archived": false,
12+
"creator": 183,
13+
"color": "#32a852",
14+
"pretty_id": "6",
15+
"multiple_owners": true,
16+
"folder_id": null,
17+
"members": [],
18+
"owners": [
19+
{
20+
"id": 182,
21+
"username": "Pieter CK",
22+
"email": "[email protected]",
23+
"color": "#7b68ee",
24+
"initials": "PK",
25+
"profilePicture": "https://attachments-public.clickup.com/profilePictures/182_abc.jpg"
26+
}
27+
],
28+
"key_results": [],
29+
"percent_completed": 0,
30+
"history": [],
31+
"pretty_url": "https://app.clickup.com/512/goals/6"
32+
}
33+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"id": "124",
3+
"name": "Listener",
4+
"orderindex": 1,
5+
"content": "Updated List Content",
6+
"status": {
7+
"status": "red",
8+
"color": "#e50000",
9+
"hide_label": true
10+
},
11+
"priority": {
12+
"priority": "high",
13+
"color": "#f50000"
14+
},
15+
"assignee": null,
16+
"due_date": "1567780450202",
17+
"due_date_time": true,
18+
"start_date": null,
19+
"start_date_time": null,
20+
"folder": {
21+
"id": "456",
22+
"name": "Folder Name",
23+
"hidden": false,
24+
"access": true
25+
},
26+
"space": {
27+
"id": "789",
28+
"name": "Space Name",
29+
"access": true
30+
},
31+
"inbound_address": "add.task.124.ac725f.31518a6a-05bb-4997-92a6-1dcfe2f527ca@tasks.clickup.com",
32+
"archived": false,
33+
"override_statuses": false,
34+
"statuses": [
35+
{
36+
"status": "to do",
37+
"orderindex": 0,
38+
"color": "#d3d3d3",
39+
"type": "open"
40+
},
41+
{
42+
"status": "complete",
43+
"orderindex": 1,
44+
"color": "#6bc950",
45+
"type": "closed"
46+
}
47+
],
48+
"permission_level": "create"
49+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"id": "790",
3+
"name": "the Milky Way",
4+
"private": false,
5+
"statuses": [
6+
{
7+
"status": "to do",
8+
"type": "open",
9+
"orderindex": 0,
10+
"color": "#d3d3d3"
11+
},
12+
{
13+
"status": "complete",
14+
"type": "closed",
15+
"orderindex": 1,
16+
"color": "#6bc950"
17+
}
18+
],
19+
"multiple_assignees": false,
20+
"features": {
21+
"due_dates": {
22+
"enabled": false,
23+
"start_date": false,
24+
"remap_due_dates": false,
25+
"remap_closed_due_date": false
26+
},
27+
"time_tracking": {
28+
"enabled": false
29+
},
30+
"tags": {
31+
"enabled": false
32+
},
33+
"time_estimates": {
34+
"enabled": false
35+
},
36+
"checklists": {
37+
"enabled": true
38+
},
39+
"custom_fields": {
40+
"enabled": true
41+
},
42+
"remap_dependencies": {
43+
"enabled": false
44+
},
45+
"dependency_warning": {
46+
"enabled": false
47+
},
48+
"portfolios": {
49+
"enabled": false
50+
}
51+
}
52+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"id": "string",
3+
"custom_id": "string",
4+
"custom_item_id": 0,
5+
"name": "Tanswer",
6+
"text_content": "string",
7+
"description": "string",
8+
"status": {
9+
"status": "in progress",
10+
"color": "#d3d3d3",
11+
"orderindex": 1,
12+
"type": "custom"
13+
},
14+
"orderindex": "string",
15+
"date_created": "string",
16+
"date_updated": "string",
17+
"date_closed": "string",
18+
"creator": {
19+
"id": 183,
20+
"username": "Pieter CK",
21+
"color": "#827718",
22+
"profilePicture": "https://attachments-public.clickup.com/profilePictures/183_abc.jpg"
23+
},
24+
"assignees": ["string"],
25+
"checklists": ["string"],
26+
"tags": ["string"],
27+
"parent": "string",
28+
"priority": "string",
29+
"due_date": "string",
30+
"start_date": "string",
31+
"time_estimate": "string",
32+
"time_spent": "string",
33+
"custom_fields": [
34+
{
35+
"id": "string",
36+
"name": "string",
37+
"type": "string",
38+
"type_config": {},
39+
"date_created": "string",
40+
"hide_from_guests": true,
41+
"value": {
42+
"id": 183,
43+
"username": "Pieter CK",
44+
"email": "[email protected]",
45+
"color": "#7b68ee",
46+
"initials": "PK",
47+
"profilePicture": null
48+
},
49+
"required": true
50+
}
51+
],
52+
"list": {
53+
"id": "123"
54+
},
55+
"folder": {
56+
"id": "456"
57+
},
58+
"space": {
59+
"id": "789"
60+
},
61+
"url": "https://app.clickup.com/XXXXXXXX/home",
62+
"markdown_description": "string"
63+
}

zerver/webhooks/clickup/doc.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Zulip ClickUp integration
2+
3+
Get Zulip notifications for your ClickUp space!
4+
5+
{start_tabs}
6+
7+
1. {!create-channel.md!}
8+
9+
1. {!create-an-incoming-webhook.md!}
10+
11+
1. {!generate-webhook-url-basic.md!}
12+
13+
1. Collect your ClickUp **Team ID** by going to your ClickUp home view.
14+
The URL should look like `https://app.clickup.com/<TEAM_ID>/home`.
15+
Note down the `<TEAM_ID>`.
16+
17+
1. Collect your ClickUp **Client ID** and **Client Secret** by following these steps:
18+
19+
- Go to your [ClickUp API menu][1] and click **Create an App**.
20+
21+
- You will be prompted for **Redirect URL(s)**, enter the URL for your Zulip organization.
22+
e.g., `{{ zulip_url }}`.
23+
24+
- Note down the **Client ID** and **Client Secret**
25+
26+
1. Download [zulip-clickup.py][2]. `Ctrl+s` or `Cmd+s` on that page should
27+
work in most browsers.
28+
29+
1. Make sure you have a working copy of [Python](https://realpython.com/installing-python/),
30+
it will be needed to run the script.
31+
32+
1. Run the `zulip-clickup.py` script in a terminal, after replacing the all caps
33+
arguments with the values collected above.
34+
35+
```
36+
python zulip-clickup.py --clickup-team-id <clickup_team_id> \
37+
--clickup-client-id <clickup_client_id> \
38+
--clickup-client-secret <clickup_client_secret> \
39+
--zulip-webhook-url "<zulip_webhook_url>"
40+
```
41+
42+
1. Follow the instructions in the terminal and keep an eye on your browser as you
43+
will be redirected to a ClickUp authorization page.
44+
45+
{end_tabs}
46+
47+
{!congrats.md!}
48+
49+
![](/static/images/integrations/clickup/001.png)
50+
51+
### Related documentation
52+
53+
{!webhooks-url-specification.md!}
54+
55+
[1]: https://app.clickup.com/settings/team/clickup-api
56+
57+
[2]: https://raw.githubusercontent.com/zulip/python-zulip-api/main/zulip/integrations/clickup/zulip_clickup.py
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"event": "folderCreated",
3+
"folder_id": "96772212",
4+
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"event": "folderDeleted",
3+
"folder_id": "96772212",
4+
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"event": "folderUpdated",
3+
"folder_id": "96772212",
4+
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"event": "goalCreated",
3+
"goal_id": "a23e5a3d-74b5-44c2-ab53-917ebe85045a",
4+
"webhook_id": "d5eddb2d-db2b-49e9-87d4-bc6cfbe2313b"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"event": "goalDeleted",
3+
"goal_id": "a23e5a3d-74b5-44c2-ab53-917ebe85045a",
4+
"webhook_id": "d5eddb2d-db2b-49e9-87d4-bc6cfbe2313b"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"event": "goalUpdated",
3+
"goal_id": "a23e5a3d-74b5-44c2-ab53-917ebe85045a",
4+
"webhook_id": "d5eddb2d-db2b-49e9-87d4-bc6cfbe2313b"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"event": "listCreated",
3+
"list_id": "901601848935",
4+
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"event": "listDeleted",
3+
"list_id": "901601848935",
4+
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
5+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"event": "listUpdated",
3+
"history_items": [
4+
{
5+
"id": "8a2f82db-7718-4fdb-9493-4849e67f009d",
6+
"type": 6,
7+
"date": "1642740510345",
8+
"field": "name",
9+
"parent_id": "162641285",
10+
"data": {},
11+
"source": null,
12+
"user": {
13+
"id": 183,
14+
"username": "Pieter",
15+
"email": "[email protected]",
16+
"color": "#7b68ee",
17+
"initials": "P",
18+
"profilePicture": null
19+
},
20+
"before": "webhook payloads 2",
21+
"after": "Webhook payloads round 2"
22+
}
23+
],
24+
"list_id": "901601848935",
25+
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
26+
}

0 commit comments

Comments
 (0)