(sock, chatId, message, zipOverride)
| 127 | } |
| 128 | |
| 129 | async function updateViaZip(sock, chatId, message, zipOverride) { |
| 130 | const zipUrl = (zipOverride || settings.updateZipUrl || process.env.UPDATE_ZIP_URL || '').trim(); |
| 131 | if (!zipUrl) { |
| 132 | throw new Error('No ZIP URL configured. Set settings.updateZipUrl or UPDATE_ZIP_URL env.'); |
| 133 | } |
| 134 | const tmpDir = path.join(process.cwd(), 'tmp'); |
| 135 | if (!fs.existsSync(tmpDir)) fs.mkdirSync(tmpDir, { recursive: true }); |
| 136 | const zipPath = path.join(tmpDir, 'update.zip'); |
| 137 | await downloadFile(zipUrl, zipPath); |
| 138 | const extractTo = path.join(tmpDir, 'update_extract'); |
| 139 | if (fs.existsSync(extractTo)) fs.rmSync(extractTo, { recursive: true, force: true }); |
| 140 | await extractZip(zipPath, extractTo); |
| 141 | |
| 142 | // Find the top-level extracted folder (GitHub zips create REPO-branch folder) |
| 143 | const [root] = fs.readdirSync(extractTo).map(n => path.join(extractTo, n)); |
| 144 | const srcRoot = fs.existsSync(root) && fs.lstatSync(root).isDirectory() ? root : extractTo; |
| 145 | |
| 146 | // Copy over while preserving runtime dirs/files |
| 147 | const ignore = ['node_modules', '.git', 'session', 'tmp', 'tmp/', 'temp', 'data', 'baileys_store.json']; |
| 148 | const copied = []; |
| 149 | // Preserve ownerNumber from existing settings.js if present |
| 150 | let preservedOwner = null; |
| 151 | let preservedBotOwner = null; |
| 152 | try { |
| 153 | const currentSettings = require('../settings'); |
| 154 | preservedOwner = currentSettings && currentSettings.ownerNumber ? String(currentSettings.ownerNumber) : null; |
| 155 | preservedBotOwner = currentSettings && currentSettings.botOwner ? String(currentSettings.botOwner) : null; |
| 156 | } catch {} |
| 157 | copyRecursive(srcRoot, process.cwd(), ignore, '', copied); |
| 158 | if (preservedOwner) { |
| 159 | try { |
| 160 | const settingsPath = path.join(process.cwd(), 'settings.js'); |
| 161 | if (fs.existsSync(settingsPath)) { |
| 162 | let text = fs.readFileSync(settingsPath, 'utf8'); |
| 163 | text = text.replace(/ownerNumber:\s*'[^']*'/, `ownerNumber: '${preservedOwner}'`); |
| 164 | if (preservedBotOwner) { |
| 165 | text = text.replace(/botOwner:\s*'[^']*'/, `botOwner: '${preservedBotOwner}'`); |
| 166 | } |
| 167 | fs.writeFileSync(settingsPath, text); |
| 168 | } |
| 169 | } catch {} |
| 170 | } |
| 171 | // Cleanup extracted directory |
| 172 | try { fs.rmSync(extractTo, { recursive: true, force: true }); } catch {} |
| 173 | try { fs.rmSync(zipPath, { force: true }); } catch {} |
| 174 | return { copiedFiles: copied }; |
| 175 | } |
| 176 | |
| 177 | async function restartProcess(sock, chatId, message) { |
| 178 | try { |
no test coverage detected