Files
OPEN_CODEX_API/src/services/asana.ts
T

345 lines
9.7 KiB
TypeScript

export interface AsanaWorkspaceResponse {
gid: string;
resource_type: string;
name: string;
}
export interface AsanaWorkspacesResponse {
data: AsanaWorkspaceResponse[];
}
export interface AsanaWorkspace {
id: string;
name: string;
}
export interface AsanaUserResponse {
gid: string;
name: string;
resource_type: string;
}
export interface AsanaUsersResponse {
data: AsanaUserResponse[];
}
export interface AsanaUser {
id: string;
name: string;
}
export interface AsanaIntegrationResponse {
success: boolean;
integracao_id?: string;
id?: string;
api_key?: string;
workspace_gid?: string;
workspace_nome?: string;
usuario_asana_gid?: string;
usuario_asana_nome?: string;
}
export interface AsanaIntegrationRequest {
user_id?: string;
api_key: string;
workspace_gid: string;
workspace_nome: string;
usuario_asana_gid: string;
usuario_asana_nome: string;
}
class AsanaService {
private readonly ASANA_BASE_URL = 'https://app.asana.com/api/1.0';
async getWorkspaces(token: string): Promise<AsanaWorkspace[]> {
if (!token || token.trim().length === 0) {
throw {
success: false,
message: 'Token do Asana é obrigatório',
};
}
try {
const axios = (await import('axios')).default;
const headers: Record<string, string> = {
'accept': 'application/json',
'authorization': `Bearer ${token.trim()}`,
};
const response = await axios.get<AsanaWorkspacesResponse>(
`${this.ASANA_BASE_URL}/workspaces`,
{ headers }
);
return response.data.data.map((workspace) => ({
id: workspace.gid,
name: workspace.name,
}));
} catch (error: unknown) {
console.error('Erro ao buscar workspaces do Asana:', error);
if (error && typeof error === 'object' && 'response' in error) {
const axiosError = error as { response?: { data?: any; status?: number } };
if (axiosError.response?.status === 401) {
throw {
success: false,
message: 'Token inválido ou expirado. Verifique sua chave de API.',
};
}
if (axiosError.response?.data) {
throw {
success: false,
message: axiosError.response.data.message || 'Erro ao buscar workspaces do Asana',
};
}
}
throw {
success: false,
message: error instanceof Error ? error.message : 'Erro ao buscar workspaces do Asana',
};
}
}
async getUsers(token: string, workspaceId: string): Promise<AsanaUser[]> {
if (!token || token.trim().length === 0) {
throw {
success: false,
message: 'Token do Asana é obrigatório',
};
}
if (!workspaceId || workspaceId.trim().length === 0) {
throw {
success: false,
message: 'ID do workspace é obrigatório',
};
}
try {
const axios = (await import('axios')).default;
const headers: Record<string, string> = {
'accept': 'application/json',
'authorization': `Bearer ${token.trim()}`,
};
const response = await axios.get<AsanaUsersResponse>(
`${this.ASANA_BASE_URL}/users?workspace=${workspaceId}`,
{ headers }
);
// Converte a resposta da API para o formato esperado pelo componente
// A API retorna gid, mas o componente espera id
return response.data.data.map((user) => ({
id: user.gid,
name: user.name,
}));
} catch (error: unknown) {
console.error('Erro ao buscar usuários do Asana:', error);
if (error && typeof error === 'object' && 'response' in error) {
const axiosError = error as { response?: { data?: any; status?: number } };
if (axiosError.response?.status === 401) {
throw {
success: false,
message: 'Token inválido ou expirado. Verifique sua chave de API.',
};
}
if (axiosError.response?.data) {
throw {
success: false,
message: axiosError.response.data.message || 'Erro ao buscar usuários do Asana',
};
}
}
throw {
success: false,
message: error instanceof Error ? error.message : 'Erro ao buscar usuários do Asana',
};
}
}
async getIntegration(userId: string): Promise<AsanaIntegrationResponse | null> {
if (!userId || userId.trim().length === 0) {
throw {
success: false,
message: 'ID do usuário é obrigatório',
};
}
try {
const axios = (await import('axios')).default;
const { GlobalFunctions } = await import('@/GlobalFunctions');
const token = await GlobalFunctions.getToken();
const apiKey = import.meta.env.VITE_API_KEY || '';
const headers: Record<string, string> = {
'Content-Type': 'application/json',
'accept': 'application/json',
};
if (apiKey) {
headers['apikey'] = apiKey;
}
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
const response = await axios.get<AsanaIntegrationResponse>(
`https://prod-hgtx-intelligence-n8n.hgtx.com.br/webhook/c898beff-84cb-44df-a69c-6eff27ccd7aa/codex/agente-pessoal/integracoes/asana/${userId}`,
{ headers }
);
if (!response.data.success) {
return null;
}
return response.data;
} catch (error: unknown) {
console.error('Erro ao buscar integração do Asana:', error);
// Se o erro for 404 ou similar, significa que não tem integração cadastrada
if (error && typeof error === 'object' && 'response' in error) {
const axiosError = error as { response?: { status?: number } };
if (axiosError.response?.status === 404) {
return null;
}
}
return null;
}
}
async createIntegration(request: AsanaIntegrationRequest): Promise<AsanaIntegrationResponse> {
if (!request.user_id || !request.api_key || !request.workspace_gid || !request.usuario_asana_gid) {
throw {
success: false,
message: 'Dados incompletos para criar integração',
};
}
try {
const axios = (await import('axios')).default;
const { GlobalFunctions } = await import('@/GlobalFunctions');
// Obtém o token JWT para autenticação
const token = await GlobalFunctions.getToken();
const apiKey = import.meta.env.VITE_API_KEY || '';
const headers: Record<string, string> = {
'Content-Type': 'application/json',
'accept': 'application/json',
};
// Adiciona API key (obrigatória)
if (apiKey) {
headers['apikey'] = apiKey;
}
// Adiciona token JWT se disponível
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
const response = await axios.post<AsanaIntegrationResponse>(
`https://prod-hgtx-intelligence-n8n.hgtx.com.br/webhook/codex/agente-pessoal/integracoes/asana`,
request,
{ headers }
);
return response.data;
} catch (error: unknown) {
console.error('Erro ao criar integração do Asana:', error);
// Retorna o erro da API se existir
if (error && typeof error === 'object' && 'response' in error) {
const axiosError = error as { response?: { data?: any; status?: number } };
if (axiosError.response?.data) {
const errorData = axiosError.response.data;
throw {
success: false,
message: errorData.message || 'Erro ao criar integração do Asana',
};
}
}
throw {
success: false,
message: error instanceof Error ? error.message : 'Erro ao criar integração do Asana',
};
}
}
async updateIntegration(integracaoId: string, request: Omit<AsanaIntegrationRequest, 'user_id'>): Promise<AsanaIntegrationResponse> {
if (!integracaoId || !request.api_key || !request.workspace_gid || !request.usuario_asana_gid) {
throw {
success: false,
message: 'Dados incompletos para atualizar integração',
};
}
try {
const axios = (await import('axios')).default;
const { GlobalFunctions } = await import('@/GlobalFunctions');
const token = await GlobalFunctions.getToken();
const apiKey = import.meta.env.VITE_API_KEY || '';
const headers: Record<string, string> = {
'Content-Type': 'application/json',
'accept': 'application/json',
};
if (apiKey) {
headers['apikey'] = apiKey;
}
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
const url = `https://prod-hgtx-intelligence-n8n.hgtx.com.br/webhook/c898beff-84cb-44df-a69c-6eff27ccd7aa/codex/agente-pessoal/integracoes/asana/${integracaoId}`;
const response = await axios.post<AsanaIntegrationResponse>(
url,
request,
{ headers }
);
return response.data;
} catch (error: unknown) {
console.error('Erro ao atualizar integração do Asana:', error);
// Retorna o erro da API se existir
if (error && typeof error === 'object' && 'response' in error) {
const axiosError = error as { response?: { data?: any; status?: number } };
if (axiosError.response?.data) {
const errorData = axiosError.response.data;
throw {
success: false,
message: errorData.message || 'Erro ao atualizar integração do Asana',
};
}
}
throw {
success: false,
message: error instanceof Error ? error.message : 'Erro ao atualizar integração do Asana',
};
}
}
}
// Exporta instância única (Singleton)
export const asanaService = new AsanaService();