windmill/f/clickup/get_task.deno.ts

206 lines
4.3 KiB
TypeScript

// clickup/get_task.ts
interface TaskResponse {
id: string;
name: string;
description?: string;
text_content?: string;
status?: {
status: string;
color: string;
orderindex: number;
type: "open" | "closed" | "custom";
};
orderindex?: string;
date_created?: string;
date_updated?: string;
date_closed?: string | null;
date_done?: string | null;
archived?: boolean;
creator?: {
id: number;
username: string;
email: string;
color: string;
profilePicture?: string;
};
assignees?: Array<{
id: number;
username: string;
email: string;
color: string;
initials: string;
profilePicture?: string;
}>;
watchers?: Array<{
id: number;
username: string;
email: string;
color: string;
initials: string;
profilePicture?: string;
}>;
checklists?: Array<{
id: string;
name: string;
orderindex: number;
resolved: number;
unresolved: number;
items: Array<{
id: string;
name: string;
orderindex: number;
assignee?: number;
resolved: boolean;
parent?: string;
date_created: string;
children?: string[];
}>;
}>;
tags?: Array<{
name: string;
tag_fg: string;
tag_bg: string;
creator?: number;
}>;
parent?: string | null;
priority?: {
id: string;
priority: "urgent" | "high" | "normal" | "low";
color: string;
};
due_date?: string | null;
start_date?: string | null;
time_estimate?: number | null;
time_spent?: number | null;
custom_fields?: Array<{
id: string;
name: string;
type: string;
type_config: Record<string, any>;
value: any;
}>;
list?: {
id: string;
name: string;
access: boolean;
};
project?: {
id: string;
name: string;
hidden: boolean;
access: boolean;
};
folder?: {
id: string;
name: string;
hidden: boolean;
access: boolean;
};
space?: {
id: string;
name: string;
};
url?: string;
permission_level?: string;
custom_item_id?: number | null;
custom_task_ids?: Array<{
custom_task_id: string;
team_id: string;
}>;
dependencies?: Array<{
task_id: string;
depends_on: string;
type: number;
date_created: string;
userid: string;
}>;
linked_tasks?: Array<{
task_id: string;
link_id: string;
date_created: string;
userid: string;
}>;
team_id?: string;
custom_id?: string | null;
attachments?: Array<{
id: string;
version: string;
date: string;
title: string;
extension: string;
thumbnail_small: string;
thumbnail_large: string;
size: number;
}>;
shared?: Array<{
id: string;
name: string;
type: string;
access_level: string;
team_id: string;
}>;
followers?: Array<{
id: number;
username: string;
email: string;
color: string;
initials: string;
profilePicture?: string;
}>;
[key: string]: any; // For future API additions
}
type FieldSelector = Array<keyof TaskResponse | string>;
// All we need here is the access token.
type ClickupCredentials = {
access_token: string;
};
export async function main(
task_id: string,
fields: FieldSelector = ["id", "name", "status", "date_created"],
credentials: ClickupCredentials,
) {
// Input validation
if (!task_id?.trim()) throw new Error("Task ID is required");
// API call
const response = await fetch(
`https://api.clickup.com/api/v2/task/${task_id}`,
{
headers: {
"Authorization": credentials.access_token,
},
},
);
if (!response.ok) {
const error = await response.text();
throw new Error(`ClickUp Error ${response.status}: ${error}`);
}
// Full response parsing
const fullTask = await response.json();
// Field filtering
return fields.length > 0 ? filterFields(fullTask, fields) : fullTask;
}
// Recursive field filtering function
function filterFields(obj: any, fields: FieldSelector): any {
return fields.reduce((acc, field) => {
const [root, ...nested] = (field as string).split(".");
if (obj[root] !== undefined) {
if (nested.length > 0 && typeof obj[root] === "object") {
acc[root] = filterFields(obj[root], [nested.join(".")]);
} else {
acc[root] = obj[root];
}
}
return acc;
}, {} as Record<string, any>);
}