3 * Fetch WHMCS data via WHM API (no MySQL connection needed)
4 * Uses WHM API to list accounts and export data
7require('dotenv').config();
8const https = require('https');
9const fs = require('fs');
10const path = require('path');
12const WHM_HOST = 'precisewebhosting.com.au';
14const WHM_TOKEN = process.env.WHM_TOKEN;
15const EXPORT_DIR = path.join(__dirname, '../exports');
17// Ensure export directory exists
18if (!fs.existsSync(EXPORT_DIR)) {
19 fs.mkdirSync(EXPORT_DIR, { recursive: true });
23 * Make WHM API request
27function whmApiRequest(endpoint, params = {}) {
28 return new Promise((resolve, reject) => {
29 const queryString = new URLSearchParams(params).toString();
30 const url = `https://${WHM_HOST}:${WHM_PORT}/json-api/${endpoint}?${queryString}`;
35 path: `/json-api/${endpoint}?${queryString}`,
38 'Authorization': `WHM root:${WHM_TOKEN}`
40 rejectUnauthorized: false // Skip SSL verification
43 console.log(`[WHM API] ${endpoint}`);
45 const req = https.request(options, (res) => {
48 res.on('data', (chunk) => {
54 const json = JSON.parse(data);
55 if (json.metadata && json.metadata.result === 0) {
56 reject(new Error(json.metadata.reason || 'WHM API error'));
61 reject(new Error(`Failed to parse WHM response: ${err.message}`));
66 req.on('error', (err) => {
75 * Main export function
77async function exportFromWHM() {
79 console.log('========================================');
80 console.log('WHM Data Export (Direct API Access)');
81 console.log('========================================\n');
84 throw new Error('WHM_TOKEN not configured in .env');
87 console.log(`Connecting to WHM: ${WHM_HOST}:${WHM_PORT}\n`);
90 console.log('Fetching cPanel accounts...');
91 const accounts = await whmApiRequest('listaccts');
93 if (!accounts.data || !accounts.data.acct) {
94 throw new Error('No accounts found in WHM');
97 console.log(`Found ${accounts.data.acct.length} cPanel accounts\n`);
100 console.log('Extracting domain information...');
101 const domains = accounts.data.acct.map(acct => ({
106 created: acct.startdate,
107 suspended: acct.suspended,
108 disk_used: acct.diskused,
109 disk_limit: acct.disklimit
112 // Save accounts export
113 const accountsPath = path.join(EXPORT_DIR, 'whm_accounts.json');
114 fs.writeFileSync(accountsPath, JSON.stringify(accounts.data.acct, null, 2));
115 console.log(`ā
Accounts saved: ${accountsPath}`);
119 'username,domain,email,plan,created,suspended,disk_used,disk_limit',
120 ...domains.map(d => `"${d.username}","${d.domain}","${d.email}","${d.plan}",${d.created},${d.suspended},"${d.disk_used}","${d.disk_limit}"`)
123 const domainsPath = path.join(EXPORT_DIR, 'whm_domains.csv');
124 fs.writeFileSync(domainsPath, domainsCsv);
125 console.log(`ā
Domains CSV saved: ${domainsPath}`);
128 console.log('\n========================================');
129 console.log('Export Summary');
130 console.log('========================================');
131 console.log(`Total Accounts: ${accounts.data.acct.length}`);
132 console.log(`Active Domains: ${domains.filter(d => !d.suspended).length}`);
133 console.log(`Suspended: ${domains.filter(d => d.suspended).length}`);
134 console.log('========================================\n');
137 console.log('Sample Domains (first 5):');
138 domains.slice(0, 5).forEach(d => {
139 console.log(` ${d.domain} (${d.email}) - ${d.suspended ? 'SUSPENDED' : 'Active'}`);
143 console.log('ā
Export complete!');
144 console.log('\nNote: This exported cPanel/WHM accounts.');
145 console.log('To get WHMCS customer data, you still need MySQL access.');
146 console.log('Options:');
147 console.log(' 1. Add IP 210.56.255.66 to MySQL remote access in WHM');
148 console.log(' 2. Or export WHMCS data directly on the server\n');
151 console.error('\nā Export failed:', error.message);
152 console.error(error.stack);
157// Run if called directly
158if (require.main === module) {
162module.exports = { exportFromWHM };