345 lines
9.7 KiB
TypeScript
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();
|