ClickUp API Client
Cliente completo e tipo-seguro para a API do ClickUp, com funcionalidades avançadas de busca inteligente (fuzzy matching) e tipos estruturados.
🎯 Features
- ✅ Type-Safe API: Structs tipadas para Task, Priority, Status, CustomField, User
- ✅ Smart Folder Finder: Busca inteligente de folders com fuzzy matching (Jaro-Winkler)
- ✅ Smart Assignee Finder: Busca de usuários por nome com cache
- ✅ Custom Field Manager: Gerenciamento automático de campos personalizados
- ✅ Task Manager: CRUD completo com assignees, status, subtasks, due dates, dependencies
- ✅ Webhook Manager: Gerenciamento completo de webhooks (create, list, update, delete)
- ✅ Webhook Signature Verification: Validação HMAC-SHA256 para segurança
- ✅ API v2: Usa exclusivamente a API v2 estável do ClickUp
- ✅ Error Handling: Tipos de erro específicos com
thiserror - ✅ Async/Await: Totalmente assíncrono com Tokio
- ✅ Cache: Sistema de cache in-memory para otimização
- ✅ Logging: Integração com
tracing - ✅ Testes: Testes unitários incluídos
📦 Instalação
Adicione ao Cargo.toml:
[]
= { = "crates/clickup" }
🚀 Uso Rápido
⚠️ IMPORTANTE: Configuração Segura
NUNCA hardcode tokens ou IDs no código! Use variáveis de ambiente:
# Configure as variáveis de ambiente
1. Criar Cliente
use ClickUpClient;
async
2. Criar Task com Tipos
use ;
use TaskManager;
let client = new?;
let task_manager = new;
// Criar task usando builder pattern
let task = new
.with_description
.with_priority
.with_list_id;
// Criar no ClickUp
let created_task = task_manager.create_task.await?;
println!;
3. Assignees, Status, Subtasks
// Atribuir usuário
let task = task_manager.assign_task.await?;
// Atualizar status
let task = task_manager.update_task_status.await?;
// Criar subtask
let subtask = new
.with_parent;
let created_subtask = task_manager.create_subtask.await?;
// Definir due date
let due_date_ms = 1730073600000i64; // Unix timestamp em milissegundos
let task = task_manager.set_due_date.await?;
// Adicionar dependência
task_manager.add_dependency.await?;
4. Buscar Folder Inteligente
use SmartFolderFinder;
let api_token = var
.expect;
let workspace_id = var
.expect;
let mut finder = from_token?;
let result = finder.find_folder_for_client.await?;
if let Some = result
5. Buscar Assignee (Responsável)
use SmartAssigneeFinder;
let mut finder = from_token?;
let result = finder.find_assignee_by_name.await?;
if let Some = result
6. Custom Fields
use CustomFieldManager;
use ;
let manager = from_token?;
// Garantir que opção existe no dropdown
let custom_field = manager
.ensure_client_solicitante_option
.await?;
// Criar custom fields tipados
let checkbox = checkbox;
let date = date; // milissegundos
let text = text;
7. Webhooks (Tempo Real)
use ;
let manager = from_token?;
// Criar webhook para receber eventos
let config = WebhookConfig ;
let webhook = manager.create_webhook.await?;
println!;
// Listar webhooks
let webhooks = manager.list_webhooks.await?;
// Criar ou atualizar (idempotente)
let webhook = manager.ensure_webhook.await?;
// Validar assinatura (segurança)
use WebhookPayload;
let is_valid = verify_signature;
Arquitetura Recomendada: Webhooks + Pub/Sub
Combine webhooks ClickUp com Google Cloud Pub/Sub para escalabilidade:
- Webhook recebe evento do ClickUp (tempo real)
- Valida assinatura (segurança)
- Publica no Pub/Sub (desacoplamento)
- Subscribers processam (escalabilidade)
- Retry automático (confiabilidade)
ClickUp → Webhook Handler → Pub/Sub Topic → Workers
↓ valida assinatura
↓ ACK < 100ms
✓ publicado
Eventos Disponíveis (30+ eventos):
- Task:
Created,Updated,Deleted,Moved,StatusUpdated,PriorityUpdated - List:
Created,Updated,Deleted - Folder:
Created,Updated,Deleted - Space:
Created,Updated,Deleted - Goal:
Created,Updated,Deleted
Ver WebhookEvent enum para lista completa.
🏗️ Arquitetura
Estrutura de Módulos
crates/clickup/src/
├── client.rs # Cliente HTTP híbrido v2+v3
├── error.rs # Tipos de erro (ClickUpError)
├── matching.rs # Fuzzy matching utilities (Jaro-Winkler)
├── folders.rs # SmartFolderFinder (588 linhas)
├── assignees.rs # SmartAssigneeFinder (340 linhas)
├── fields.rs # CustomFieldManager (302 linhas)
├── tasks.rs # TaskManager - CRUD completo (800+ linhas)
├── webhooks.rs # WebhookManager - create, list, update, delete (400+ linhas)
├── types/ # Tipos estruturados (1,400 linhas)
│ ├── mod.rs # Re-exports
│ ├── priority.rs # Priority enum (1-4)
│ ├── status.rs # Status struct
│ ├── user.rs # User struct
│ ├── custom_field.rs # 18 tipos de custom fields
│ └── task.rs # Task struct + builder
└── lib.rs # Re-exports públicos
API ClickUp v2
Este crate utiliza exclusivamente a API v2 do ClickUp que é estável e completa:
Cliente HTTP
Métodos disponíveis:
get_json(endpoint)- Requisição GET com JSONpost_json(endpoint, body)- Requisição POST com JSONput_json(endpoint, body)- Requisição PUT com JSONdelete_json(endpoint)- Requisição DELETE com JSON
Endpoints Principais
| Recurso | Endpoint API v2 |
|---|---|
| Spaces | /team/{team_id}/space |
| Folders | /space/{space_id}/folder |
| Lists | /folder/{folder_id}/list |
| Tasks | /list/{list_id}/task |
| Webhooks | /team/{team_id}/webhook |
| Custom Fields | /list/{list_id}/field |
Nomenclatura
Interno (código):
let workspace_id = "9013037641"; // workspace_id usado internamente
API calls:
// Internamente: workspace_id = "9013037641"
// Na API v2: /team/9013037641/space
let endpoint = format!;
📊 Tipos Estruturados
Priority
Custom Fields (18 tipos)
Atenção:
- Checkbox: Usa strings
"true"/"false", não boolean - Date/Timestamp: Usa i64 em milissegundos, não segundos
Task Builder
let task = new
.with_description
.with_list_id
.with_priority
.with_assignees
.with_due_date
.with_parent // Para subtasks
.with_custom_fields;
🧪 Testes
# Testes do crate
# Com output detalhado
# Teste específico
# Testes de integração
📊 Status de Implementação
| Módulo | Status | Linhas | Descrição |
|---|---|---|---|
| ✅ client | Completo | 293 | Cliente HTTP v2+v3 |
| ✅ error | Completo | 42 | Tipos de erro |
| ✅ matching | Completo | 164 | Fuzzy matching |
| ✅ folders | Completo | 588 | Smart folder finder |
| ✅ assignees | Completo | 340 | Smart assignee finder |
| ✅ fields | Completo | 302 | Custom field manager |
| ✅ tasks | Completo | 800+ | Task CRUD + features |
| ✅ webhooks | Completo | 400+ | Webhook management (create, list, update, delete) |
| ✅ types | Completo | 1,400 | Task, Priority, Status, CustomField |
Total: ~4,300 linhas de código Rust
✅ Migração Completa (Fases 1-5)
Fase 1: Types e Features
- ✅ Types module (1,400 linhas)
- ✅ OAuth2 fix (Bearer prefix)
- ✅ Assignees, status, subtasks, due dates, dependencies
Fase 2: Payload Migration
- ✅ payload.rs migrado para usar Task
- ✅ Handlers usam API tipada
Fase 3: Imports e Cleanup
- ✅ Services deletados (duplicatas)
- ✅ Imports atualizados para crates
Fase 4: Service Migration
- ✅ SmartFolderFinder migrado
- ✅ SmartAssigneeFinder migrado
- ✅ CustomFieldManager migrado
Fase 5: Validação
- ✅ 14 testes passando
- ✅ Build release OK (0 warnings)
- ✅ APIs idênticas validadas
🔧 Variáveis de Ambiente
Configuração Obrigatória
# Token de autenticação ClickUp (OBRIGATÓRIO)
# ID do Workspace (OBRIGATÓRIO)
Compatibilidade v2
# Fallback para código legado
# Mesmo valor, nome antigo
Como Obter os Valores
-
CLICKUP_API_TOKEN:
- Vá para: ClickUp → Settings → Apps → API Token
- Gere um Personal Token
- NUNCA commite este valor no git!
-
CLICKUP_WORKSPACE_ID:
- Na URL do ClickUp:
https://app.clickup.com/<WORKSPACE_ID>/... - Ou via API:
GET https://api.clickup.com/api/v2/team
- Na URL do ClickUp:
Produção com Google Secret Manager
# Armazenar secrets no GCP
# Usar no Cloud Run/Functions
🤝 Contribuindo
Este é um crate interno para o projeto ChatGuru-ClickUp middleware.
Convenções
- Nomenclatura: Use
workspace_id(nãoteam_id) - API Version: Endpoints v2 por padrão, v3 onde disponível
- Testes: Adicionar testes para novas funcionalidades
- Docs: Documentar funções públicas
- Errors: Usar
Result<T>com tipos específicos
📝 Licença
Propriedade da eLai Integration Team / Nordja.