75 lines
2.6 KiB
Python
75 lines
2.6 KiB
Python
|
|
import logging
|
||
|
|
|
||
|
|
import httpx
|
||
|
|
|
||
|
|
logger = logging.getLogger(__name__)
|
||
|
|
API_V2_BASE = "https://api.clickup.com/api/v2"
|
||
|
|
|
||
|
|
|
||
|
|
async def create_webhook(
|
||
|
|
workspace_id: str,
|
||
|
|
api_token: str,
|
||
|
|
endpoint_url: str,
|
||
|
|
events: list[str],
|
||
|
|
*,
|
||
|
|
space_id: str | None = None,
|
||
|
|
folder_id: str | None = None,
|
||
|
|
list_id: str | None = None,
|
||
|
|
) -> dict:
|
||
|
|
url = f"{API_V2_BASE}/team/{workspace_id}/webhook"
|
||
|
|
headers = {"Authorization": api_token, "Content-Type": "application/json"}
|
||
|
|
payload: dict = {
|
||
|
|
"endpoint": endpoint_url,
|
||
|
|
"events": events,
|
||
|
|
}
|
||
|
|
if space_id:
|
||
|
|
payload["space_id"] = space_id
|
||
|
|
if folder_id:
|
||
|
|
payload["folder_id"] = folder_id
|
||
|
|
if list_id:
|
||
|
|
payload["list_id"] = list_id
|
||
|
|
|
||
|
|
async with httpx.AsyncClient(timeout=15.0) as client:
|
||
|
|
resp = await client.post(url, json=payload, headers=headers)
|
||
|
|
if resp.status_code in (200, 201):
|
||
|
|
return resp.json()
|
||
|
|
error_text = resp.text[:500]
|
||
|
|
raise RuntimeError(f"创建 webhook 失败 (HTTP {resp.status_code}): {error_text}")
|
||
|
|
|
||
|
|
|
||
|
|
async def list_webhooks(workspace_id: str, api_token: str) -> list[dict]:
|
||
|
|
url = f"{API_V2_BASE}/team/{workspace_id}/webhook"
|
||
|
|
headers = {"Authorization": api_token}
|
||
|
|
|
||
|
|
async with httpx.AsyncClient(timeout=15.0) as client:
|
||
|
|
resp = await client.get(url, headers=headers)
|
||
|
|
if resp.status_code == 200:
|
||
|
|
data = resp.json()
|
||
|
|
return data.get("webhooks", [])
|
||
|
|
error_text = resp.text[:500]
|
||
|
|
raise RuntimeError(f"获取 webhook 列表失败 (HTTP {resp.status_code}): {error_text}")
|
||
|
|
|
||
|
|
|
||
|
|
async def update_webhook(webhook_id: str, api_token: str, **updates) -> dict:
|
||
|
|
url = f"{API_V2_BASE}/webhook/{webhook_id}"
|
||
|
|
headers = {"Authorization": api_token, "Content-Type": "application/json"}
|
||
|
|
|
||
|
|
async with httpx.AsyncClient(timeout=15.0) as client:
|
||
|
|
resp = await client.put(url, json=updates, headers=headers)
|
||
|
|
if resp.status_code == 200:
|
||
|
|
return resp.json()
|
||
|
|
error_text = resp.text[:500]
|
||
|
|
raise RuntimeError(f"更新 webhook 失败 (HTTP {resp.status_code}): {error_text}")
|
||
|
|
|
||
|
|
|
||
|
|
async def delete_webhook(webhook_id: str, api_token: str) -> dict:
|
||
|
|
url = f"{API_V2_BASE}/webhook/{webhook_id}"
|
||
|
|
headers = {"Authorization": api_token}
|
||
|
|
|
||
|
|
async with httpx.AsyncClient(timeout=15.0) as client:
|
||
|
|
resp = await client.delete(url, headers=headers)
|
||
|
|
if resp.status_code in (200, 204):
|
||
|
|
return {"deleted": True, "webhook_id": webhook_id}
|
||
|
|
error_text = resp.text[:500]
|
||
|
|
raise RuntimeError(f"删除 webhook 失败 (HTTP {resp.status_code}): {error_text}")
|