Pre-requisites
- Using Node.js
- In project folder install Axios (npm install axios)
- In project folder, install
dotenv
to use .env
- .create .env file
.env File Structure
CLIENT_ID=your_client_id_here
CLIENT_SECRET=your_client_secret_here
REFRESH_TOKEN=your_refresh_token_here
ACCESS_TOKEN=your_access_token_here
deleteRecords.js
require('dotenv').config(); // Load environment variables from .env file
const axios = require("axios");
// Load sensitive info from the .env file
const CLIENT_ID = process.env.CLIENT_ID;
const CLIENT_SECRET = process.env.CLIENT_SECRET;
const REFRESH_TOKEN = process.env.REFRESH_TOKEN;
const MODULE_NAME = "Leads"; // Change to Contacts, Deals, etc.
let ACCESS_TOKEN = ''; // Variable to hold the current access token
// Function to refresh the access token using the refresh token
async function refreshAccessToken() {
try {
params: {
refresh_token: REFRESH_TOKEN,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
grant_type: 'refresh_token',
},
});
// Store the new access token
ACCESS_TOKEN = response.data.access_token;
console.log('New Access Token:', ACCESS_TOKEN);
return ACCESS_TOKEN;
} catch (error) {
console.error('Error refreshing access token:', error.response?.data || error.message);
return null;
}
}
// Function to fetch record IDs based on criteria with pagination
async function getRecordIds(criteria = 'Lead_Status:equals:Qualified') {
let page = 1; // Start from page 1
let allRecordIds = []; // Array to hold all record IDs
let hasNextPage = true; // Flag to check if there are more pages
while (hasNextPage) {
try {
const response = await axios.get(`${BASE_URL}/${MODULE_NAME}/search`, {
headers: {
Authorization: `Zoho-oauthtoken ${ACCESS_TOKEN}`,
},
params: {
criteria: criteria,
page: page, // Current page
},
});
// Log the response for debugging purposes
console.log(`Fetched page ${page}:`, response.data);
// If there are records, extract the record IDs and add to the array
if (response.data && response.data.data && Array.isArray(response.data.data)) {
const recordIds = response.data.data.map(record => record.id);
allRecordIds = allRecordIds.concat(recordIds); // Add new IDs to the list
console.log(`Fetched ${recordIds.length} records from page ${page}.`);
}
// Check if there are more records (next page)
hasNextPage = response.data.info && response.data.info.next_page;
page++; // Move to the next page if more records exist
} catch (error) {
if (error.response && error.response.status === 401) {
// Access token is expired or invalid, refresh it and retry
console.log("Access token expired. Refreshing the token...");
const newAccessToken = await refreshAccessToken();
if (newAccessToken) {
ACCESS_TOKEN = newAccessToken;
// Retry the request after refreshing the token
return getRecordIds(criteria); // Retry fetching records
}
}
console.error("Error fetching records:", error.response?.data || error.message);
hasNextPage = false; // Stop pagination on error
}
}
console.log("All Record IDs fetched:", allRecordIds);
return allRecordIds; // Return all fetched IDs
}
// Function to delete records in bulk
async function deleteRecords(recordIds) {
if (recordIds.length === 0) {
console.log("No records found to delete.");
return;
}
try {
const response = await axios.delete(`${BASE_URL}/${MODULE_NAME}`, {
headers: {
Authorization: `Zoho-oauthtoken ${ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
data: { ids: recordIds },
});
console.log(`Successfully deleted ${recordIds.length} records.`);
} catch (error) {
console.error("Error deleting records:", error.response?.data || error.message);
}
}
// Execute - Get record IDs and delete them if needed
getRecordIds('Lead_Status:equals:Qualified') // You can change criteria here
.then(recordIds => {
if (recordIds.length > 0) {
// Uncomment to delete records if needed
// deleteRecords(recordIds);
} else {
console.log("No records found matching the criteria.");
}
});