zoho projects api created
This commit is contained in:
parent
b137f8cc1a
commit
3df5c84d3a
@ -113,4 +113,94 @@ async function getAllProjectTasks(req, res) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { getData, getServices, getResources, getPortals, getAllProjects, getAllProjectTasks };
|
async function getAllProjectTaskLists(req, res) {
|
||||||
|
try {
|
||||||
|
const { provider, page, limit, filters, portal_id } = req.query;
|
||||||
|
|
||||||
|
if (provider !== 'zoho') {
|
||||||
|
return res.status(400).json(failure('All project task lists are only available for Zoho provider', 'INVALID_PROVIDER'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!portal_id) {
|
||||||
|
return res.status(400).json(failure('portal_id is required in query parameters', 'MISSING_PORTAL_ID'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const integrationService = new IntegrationService(req.user.id);
|
||||||
|
const params = { page, limit };
|
||||||
|
if (filters) {
|
||||||
|
try {
|
||||||
|
params.filters = JSON.parse(filters);
|
||||||
|
} catch (e) {
|
||||||
|
return res.status(400).json(failure('Invalid filters format', 'INVALID_FILTERS'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const taskLists = await integrationService.getAllProjectTaskLists(provider, portal_id, params);
|
||||||
|
res.json(success('All Zoho project task lists retrieved successfully', taskLists));
|
||||||
|
} catch (error) {
|
||||||
|
res.status(400).json(failure(error.message, 'INTEGRATION_ERROR'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getAllProjectIssues(req, res) {
|
||||||
|
try {
|
||||||
|
const { provider, page, limit, filters, portal_id } = req.query;
|
||||||
|
console.log('req query is', req.query)
|
||||||
|
|
||||||
|
if (provider !== 'zoho') {
|
||||||
|
return res.status(400).json(failure('All project issues are only available for Zoho provider', 'INVALID_PROVIDER'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!portal_id) {
|
||||||
|
return res.status(400).json(failure('portal_id is required in query parameters', 'MISSING_PORTAL_ID'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const integrationService = new IntegrationService(req.user.id);
|
||||||
|
const params = { page, limit };
|
||||||
|
if (filters) {
|
||||||
|
try {
|
||||||
|
params.filters = JSON.parse(filters);
|
||||||
|
} catch (e) {
|
||||||
|
return res.status(400).json(failure('Invalid filters format', 'INVALID_FILTERS'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const issues = await integrationService.getAllProjectIssues(provider, portal_id, params);
|
||||||
|
|
||||||
|
|
||||||
|
res.json(success('All Zoho project issues retrieved successfully', issues));
|
||||||
|
} catch (error) {
|
||||||
|
res.status(400).json(failure(error.message, 'INTEGRATION_ERROR'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getAllProjectPhases(req, res) {
|
||||||
|
try {
|
||||||
|
const { provider, page, limit, filters, portal_id } = req.query;
|
||||||
|
|
||||||
|
if (provider !== 'zoho') {
|
||||||
|
return res.status(400).json(failure('All project phases are only available for Zoho provider', 'INVALID_PROVIDER'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!portal_id) {
|
||||||
|
return res.status(400).json(failure('portal_id is required in query parameters', 'MISSING_PORTAL_ID'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const integrationService = new IntegrationService(req.user.id);
|
||||||
|
const params = { page, limit };
|
||||||
|
if (filters) {
|
||||||
|
try {
|
||||||
|
params.filters = JSON.parse(filters);
|
||||||
|
} catch (e) {
|
||||||
|
return res.status(400).json(failure('Invalid filters format', 'INVALID_FILTERS'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const phases = await integrationService.getAllProjectPhases(provider, portal_id, params);
|
||||||
|
res.json(success('All Zoho project phases retrieved successfully', phases));
|
||||||
|
} catch (error) {
|
||||||
|
res.status(400).json(failure(error.message, 'INTEGRATION_ERROR'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { getData, getServices, getResources, getPortals, getAllProjects, getAllProjectTasks, getAllProjectTaskLists, getAllProjectIssues, getAllProjectPhases };
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const Joi = require('joi');
|
const Joi = require('joi');
|
||||||
const { getData, getServices, getResources, getPortals, getAllProjects, getAllProjectTasks } = require('../controllers/integrationController');
|
const { getData, getServices, getResources, getPortals, getAllProjects, getAllProjectTasks, getAllProjectTaskLists, getAllProjectIssues, getAllProjectPhases } = require('../controllers/integrationController');
|
||||||
const auth = require('../middlewares/auth');
|
const auth = require('../middlewares/auth');
|
||||||
const ZohoHandler = require('../../integrations/zoho/handler');
|
const ZohoHandler = require('../../integrations/zoho/handler');
|
||||||
|
|
||||||
@ -83,6 +83,39 @@ const allProjectTasksSchema = Joi.object({
|
|||||||
|
|
||||||
router.get('/all-project-tasks', auth, validate(allProjectTasksSchema), getAllProjectTasks);
|
router.get('/all-project-tasks', auth, validate(allProjectTasksSchema), getAllProjectTasks);
|
||||||
|
|
||||||
|
// Get all project task lists for a specific portal
|
||||||
|
const allProjectTaskListsSchema = Joi.object({
|
||||||
|
provider: Joi.string().valid('zoho').required(),
|
||||||
|
portal_id: Joi.string().required(),
|
||||||
|
page: Joi.number().min(1).default(1),
|
||||||
|
limit: Joi.number().min(1).max(100).default(20),
|
||||||
|
filters: Joi.string().optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/all-project-tasklists', auth, validate(allProjectTaskListsSchema), getAllProjectTaskLists);
|
||||||
|
|
||||||
|
// Get all project issues for a specific portal
|
||||||
|
const allProjectIssuesSchema = Joi.object({
|
||||||
|
provider: Joi.string().valid('zoho').required(),
|
||||||
|
portal_id: Joi.string().required(),
|
||||||
|
page: Joi.number().min(1).default(1),
|
||||||
|
limit: Joi.number().min(1).max(100).default(20),
|
||||||
|
filters: Joi.string().optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/all-project-issues', auth, validate(allProjectIssuesSchema), getAllProjectIssues);
|
||||||
|
|
||||||
|
// Get all project phases for a specific portal
|
||||||
|
const allProjectPhasesSchema = Joi.object({
|
||||||
|
provider: Joi.string().valid('zoho').required(),
|
||||||
|
portal_id: Joi.string().required(),
|
||||||
|
page: Joi.number().min(1).default(1),
|
||||||
|
limit: Joi.number().min(1).max(100).default(20),
|
||||||
|
filters: Joi.string().optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/all-project-phases', auth, validate(allProjectPhasesSchema), getAllProjectPhases);
|
||||||
|
|
||||||
// Webhook endpoints (no auth required - uses signature verification)
|
// Webhook endpoints (no auth required - uses signature verification)
|
||||||
const zohoHandler = new ZohoHandler();
|
const zohoHandler = new ZohoHandler();
|
||||||
router.post('/webhooks/zoho/crm', zohoHandler.handleCrmWebhook.bind(zohoHandler));
|
router.post('/webhooks/zoho/crm', zohoHandler.handleCrmWebhook.bind(zohoHandler));
|
||||||
|
|||||||
@ -27,12 +27,19 @@ class ZohoClient {
|
|||||||
|
|
||||||
async makeRequest(endpoint, options = {}, service = 'crm') {
|
async makeRequest(endpoint, options = {}, service = 'crm') {
|
||||||
const { accessToken } = await this.getTokens();
|
const { accessToken } = await this.getTokens();
|
||||||
console.log('i am in make request with token',accessToken)
|
|
||||||
const baseUrl = this.baseUrls[service] || this.baseUrls.crm;
|
const baseUrl = this.baseUrls[service] || this.baseUrls.crm;
|
||||||
const url = `${baseUrl}${endpoint}`;
|
const url = `${baseUrl}${endpoint}`;
|
||||||
|
|
||||||
|
// Transform limit to per_page for Zoho APIs
|
||||||
|
let params = options.params || {};
|
||||||
|
if (params.limit) {
|
||||||
|
params.per_page = params.limit;
|
||||||
|
delete params.limit;
|
||||||
|
}
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
...options,
|
...options,
|
||||||
|
params,
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Zoho-oauthtoken ${accessToken}`,
|
'Authorization': `Zoho-oauthtoken ${accessToken}`,
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@ -42,6 +49,7 @@ class ZohoClient {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios(url, config);
|
const response = await axios(url, config);
|
||||||
|
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.response?.status === 401) {
|
if (error.response?.status === 401) {
|
||||||
@ -132,7 +140,6 @@ class ZohoClient {
|
|||||||
try {
|
try {
|
||||||
const projectsResponse = await this.getProjects(portal.id, params);
|
const projectsResponse = await this.getProjects(portal.id, params);
|
||||||
const projects = projectsResponse.data;
|
const projects = projectsResponse.data;
|
||||||
console.log('all projects', projects);
|
|
||||||
|
|
||||||
// Add portal information to each project
|
// Add portal information to each project
|
||||||
const projectsWithPortal = projects.map(project => ({
|
const projectsWithPortal = projects.map(project => ({
|
||||||
@ -167,10 +174,26 @@ class ZohoClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getAllProjectTasks(portalId, params = {}) {
|
async getAllProjectTasks(portalId, params = {}) {
|
||||||
const response = await this.makeRequest(`/api/v3/portal/${portalId}/all-tasklists`, { params }, 'projects');
|
const response = await this.makeRequest(`/api/v3/portal/${portalId}/tasks`, { params }, 'projects');
|
||||||
return ZohoMapper.mapApiResponse(response, 'tasks');
|
return ZohoMapper.mapApiResponse(response, 'tasks');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getAllProjectTaskLists(portalId, params = {}) {
|
||||||
|
const response = await this.makeRequest(`/api/v3/portal/${portalId}/all-tasklists`, { params }, 'projects');
|
||||||
|
return ZohoMapper.mapApiResponse(response, 'tasklists');
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAllProjectIssues(portalId, params = {}) {
|
||||||
|
const response = await this.makeRequest(`/api/v3/portal/${portalId}/issues`, { params }, 'projects');
|
||||||
|
console.log('issues response i got',response)
|
||||||
|
return ZohoMapper.mapApiResponse(response, 'issues');
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAllProjectPhases(portalId, params = {}) {
|
||||||
|
const response = await this.makeRequest(`/api/v3/portal/${portalId}/phases`, { params }, 'projects');
|
||||||
|
return ZohoMapper.mapApiResponse(response, 'phases');
|
||||||
|
}
|
||||||
|
|
||||||
// Service discovery
|
// Service discovery
|
||||||
getAvailableServices() {
|
getAvailableServices() {
|
||||||
return ['crm', 'people', 'projects'];
|
return ['crm', 'people', 'projects'];
|
||||||
|
|||||||
@ -152,7 +152,7 @@ class ZohoMapper {
|
|||||||
|
|
||||||
case 'tasks':
|
case 'tasks':
|
||||||
// Tasks response has tasklists array and page_info
|
// Tasks response has tasklists array and page_info
|
||||||
records = zohoResponse.tasklists || [];
|
records = zohoResponse.tasks || [];
|
||||||
pageInfo = {
|
pageInfo = {
|
||||||
count: zohoResponse.page_info?.per_page || records.length,
|
count: zohoResponse.page_info?.per_page || records.length,
|
||||||
moreRecords: zohoResponse.page_info?.has_next_page || false,
|
moreRecords: zohoResponse.page_info?.has_next_page || false,
|
||||||
@ -161,6 +161,28 @@ class ZohoMapper {
|
|||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'phases':
|
||||||
|
// Tasks response has tasklists array and page_info
|
||||||
|
records = zohoResponse.milestones || [];
|
||||||
|
pageInfo = {
|
||||||
|
count: zohoResponse.page_info?.per_page || records.length,
|
||||||
|
moreRecords: zohoResponse.page_info?.has_next_page || false,
|
||||||
|
page: zohoResponse.page_info?.page || 1,
|
||||||
|
pageCount: zohoResponse.page_info?.page_count || 1
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'tasklists':
|
||||||
|
// Tasks response has tasklists array and page_info
|
||||||
|
records = zohoResponse.tasklists || [];
|
||||||
|
pageInfo = {
|
||||||
|
count: zohoResponse.page_info?.per_page || records.length,
|
||||||
|
moreRecords: zohoResponse.page_info?.has_next_page || false,
|
||||||
|
page: zohoResponse.page_info?.page || 1,
|
||||||
|
pageCount: zohoResponse.page_info?.page_count || 1
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
case 'portals':
|
case 'portals':
|
||||||
// Portals response is directly an array
|
// Portals response is directly an array
|
||||||
records = zohoResponse || [];
|
records = zohoResponse || [];
|
||||||
@ -171,6 +193,39 @@ class ZohoMapper {
|
|||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'issues':
|
||||||
|
// Issues response structure (assuming similar to tasks with page_info)
|
||||||
|
records = zohoResponse.issues || zohoResponse.data || [];
|
||||||
|
pageInfo = {
|
||||||
|
count: zohoResponse.page_info?.per_page || records.length,
|
||||||
|
moreRecords: zohoResponse.page_info?.has_next_page || false,
|
||||||
|
page: zohoResponse.page_info?.page || 1,
|
||||||
|
pageCount: zohoResponse.page_info?.page_count || 1
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'tasklists':
|
||||||
|
// Task lists response structure (assuming similar to tasks with page_info)
|
||||||
|
records = zohoResponse.tasklists || zohoResponse.data || [];
|
||||||
|
pageInfo = {
|
||||||
|
count: zohoResponse.page_info?.per_page || records.length,
|
||||||
|
moreRecords: zohoResponse.page_info?.has_next_page || false,
|
||||||
|
page: zohoResponse.page_info?.page || 1,
|
||||||
|
pageCount: zohoResponse.page_info?.page_count || 1
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'phases':
|
||||||
|
// Phases response structure (assuming similar to tasks with page_info)
|
||||||
|
records = zohoResponse.phases || zohoResponse.data || [];
|
||||||
|
pageInfo = {
|
||||||
|
count: zohoResponse.page_info?.per_page || records.length,
|
||||||
|
moreRecords: zohoResponse.page_info?.has_next_page || false,
|
||||||
|
page: zohoResponse.page_info?.page || 1,
|
||||||
|
pageCount: zohoResponse.page_info?.page_count || 1
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Default CRM response structure (leads, contacts, deals, employees)
|
// Default CRM response structure (leads, contacts, deals, employees)
|
||||||
records = zohoResponse.data || [];
|
records = zohoResponse.data || [];
|
||||||
|
|||||||
@ -101,6 +101,39 @@ class IntegrationService {
|
|||||||
}
|
}
|
||||||
return await client.getAllProjectTasks(portalId, params);
|
return await client.getAllProjectTasks(portalId, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getAllProjectTaskLists(provider, portalId, params = {}) {
|
||||||
|
const client = this.clients[provider];
|
||||||
|
if (!client) {
|
||||||
|
throw new Error(`Provider ${provider} not supported`);
|
||||||
|
}
|
||||||
|
if (provider !== 'zoho') {
|
||||||
|
throw new Error('All project task lists are only available for Zoho provider');
|
||||||
|
}
|
||||||
|
return await client.getAllProjectTaskLists(portalId, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAllProjectIssues(provider, portalId, params = {}) {
|
||||||
|
const client = this.clients[provider];
|
||||||
|
if (!client) {
|
||||||
|
throw new Error(`Provider ${provider} not supported`);
|
||||||
|
}
|
||||||
|
if (provider !== 'zoho') {
|
||||||
|
throw new Error('All project issues are only available for Zoho provider');
|
||||||
|
}
|
||||||
|
return await client.getAllProjectIssues(portalId, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAllProjectPhases(provider, portalId, params = {}) {
|
||||||
|
const client = this.clients[provider];
|
||||||
|
if (!client) {
|
||||||
|
throw new Error(`Provider ${provider} not supported`);
|
||||||
|
}
|
||||||
|
if (provider !== 'zoho') {
|
||||||
|
throw new Error('All project phases are only available for Zoho provider');
|
||||||
|
}
|
||||||
|
return await client.getAllProjectPhases(portalId, params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = IntegrationService;
|
module.exports = IntegrationService;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user