@ayush24k/telezipper 1.4.0 ā 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -75
- package/dist/bin/zipper.js +6 -4
- package/dist/src/chunking.js +2 -2
- package/dist/src/telegramUploader.js +58 -20
- package/dist/src/zipper.js +36 -16
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -44,106 +44,66 @@ Example:
|
|
|
44
44
|
telezipper ./my-folder -o ./output
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
###
|
|
47
|
+
### Chunking + Upload to Telegram (MTProto)
|
|
48
|
+
This tool now uses **MTProto** (the Telegram Client Protocol) to support **large file uploads (up to 2GB)** and faster speeds.
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
telezipper <source> -p <password> -o <output-directory>
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Example:
|
|
54
|
-
```bash
|
|
55
|
-
telezipper ./my-folder -p MySecurePassword123 -o ./output
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### With Telegram Upload
|
|
50
|
+
To use it, you need a `TELEGRAM_API_ID` and `TELEGRAM_API_HASH`. You can get these from [my.telegram.org](https://my.telegram.org).
|
|
59
51
|
|
|
60
|
-
You can
|
|
52
|
+
You can pass them as arguments or set them in a `.env` file.
|
|
61
53
|
|
|
62
|
-
|
|
54
|
+
### Usage Examples
|
|
63
55
|
|
|
56
|
+
#### 1. Basic Zip (No Password, No Telegram)
|
|
64
57
|
```bash
|
|
65
|
-
telezipper
|
|
58
|
+
telezipper ./my-folder
|
|
59
|
+
# Output: ./output/chunk_1.zip
|
|
66
60
|
```
|
|
67
61
|
|
|
68
|
-
|
|
62
|
+
#### 2. Zip with Password
|
|
69
63
|
```bash
|
|
70
|
-
telezipper ./my-folder
|
|
64
|
+
telezipper ./my-folder -p "secret123"
|
|
65
|
+
# Output: Encrypted zip files in ./output
|
|
71
66
|
```
|
|
72
67
|
|
|
73
|
-
####
|
|
74
|
-
|
|
75
|
-
|
|
68
|
+
#### 3. Zip + Upload to Telegram (Env Vars Set)
|
|
69
|
+
Assuming `.env` has credentials:
|
|
70
|
+
```bash
|
|
71
|
+
telezipper ./my-folder --telegram
|
|
72
|
+
```
|
|
76
73
|
|
|
74
|
+
#### 4. Zip + Upload to Telegram (CLI Args)
|
|
77
75
|
```bash
|
|
78
|
-
|
|
79
|
-
TELEGRAM_CHAT_ID=your_chat_id_here
|
|
76
|
+
telezipper ./my-folder --telegram --api-id 12345 --api-hash abcdef123 --chat-id -100123456789
|
|
80
77
|
```
|
|
81
78
|
|
|
82
|
-
|
|
79
|
+
#### 5. Password Protected Upload
|
|
83
80
|
```bash
|
|
84
|
-
telezipper ./my-folder --telegram
|
|
81
|
+
telezipper ./my-folder --telegram -p "mypassword"
|
|
85
82
|
```
|
|
86
83
|
|
|
84
|
+
### Logging In
|
|
85
|
+
- **User Login**: The tool will ask for your phone number and login code interactively. This session is saved locally in `.telegram_session`.
|
|
86
|
+
|
|
87
87
|
## Options
|
|
88
88
|
|
|
89
89
|
- `<source>` - File or folder to zip (required)
|
|
90
90
|
- `-o, --output <dir>` - Output directory (default: "output")
|
|
91
91
|
- `-p, --password <password>` - Password to protect zip files (optional)
|
|
92
92
|
- `--telegram` - Upload zip files to Telegram
|
|
93
|
-
- `--
|
|
94
|
-
- `--
|
|
93
|
+
- `--api-id <id>` - Telegram API ID (required for MTProto)
|
|
94
|
+
- `--api-hash <hash>` - Telegram API Hash (required for MTProto)
|
|
95
|
+
- `--chat-id <id>` - Chat ID to upload to (User ID or Channel/Group ID)
|
|
95
96
|
- `-h, --help` - Display help
|
|
96
97
|
|
|
97
|
-
##
|
|
98
|
-
|
|
99
|
-
### Zip a folder to the default output directory
|
|
100
|
-
```bash
|
|
101
|
-
telezipper ./my-project
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### Zip and specify custom output directory
|
|
105
|
-
```bash
|
|
106
|
-
telezipper ./my-project -o ./backups
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### Zip and upload to Telegram with inline credentials
|
|
110
|
-
```bash
|
|
111
|
-
telezipper ./my-project --telegram --bot-token 123456:ABC-DEF --chat-id 987654321
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### Zip and upload using environment variables
|
|
115
|
-
```bash
|
|
116
|
-
# Set environment variables first
|
|
117
|
-
export TELEGRAM_BOT_TOKEN=123456:ABC-DEF
|
|
118
|
-
export TELEGRAM_CHAT_ID=987654321
|
|
119
|
-
|
|
120
|
-
# Then run
|
|
121
|
-
telezipper ./my-project --telegram
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### Zip with password protection
|
|
125
|
-
```bash
|
|
126
|
-
telezipper ./my-project -p MySecurePassword123
|
|
127
|
-
```
|
|
98
|
+
## Features
|
|
128
99
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
100
|
+
- š **MTProto Support**: Uploads files >50MB (tested up to 2GB).
|
|
101
|
+
- š **Encrypted Zips**: Optional AES-256 password protection.
|
|
102
|
+
- ā” **Parallel Chunking**: Zips chunks in parallel for faster processing.
|
|
103
|
+
- āÆļø **Serial Uploads**: Uploads files one by one with a random delay (2-5s) to avoid flood limits.
|
|
104
|
+
- š¾ **Smart Chunking**: Splits large folders into zip chunks (max 2GB each).
|
|
105
|
+
- ā
**MTProto Auth**: Support for User accounts with session persistence.
|
|
133
106
|
|
|
134
107
|
## How to Get Telegram Credentials
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
2. **Chat ID**:
|
|
138
|
-
- Send a message to your bot
|
|
139
|
-
- Visit `https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates`
|
|
140
|
-
- Find your chat ID in the response
|
|
141
|
-
|
|
142
|
-
## Features
|
|
143
|
-
|
|
144
|
-
- ā
Automatically splits large folders into 50MB chunks
|
|
145
|
-
- ā
Creates zip files with maximum compression
|
|
146
|
-
- ā
Password protection with AES-256 encryption
|
|
147
|
-
- ā
Optional Telegram upload with progress bars
|
|
148
|
-
- ā
Works from any directory on your system
|
|
149
|
-
- ā
Flexible credential management (CLI args or env vars)
|
|
108
|
+
1. **API ID & Hash**: Go to [my.telegram.org](https://my.telegram.org), log in, and click "API development tools". Create a new application to get your `App api_id` and `App api_hash`.
|
|
109
|
+
2. **Chat ID**: You can get your Chat ID by forwarding a message to a bot like @userinfobot. For channels/groups, it usually starts with `-100`.
|
package/dist/bin/zipper.js
CHANGED
|
@@ -16,21 +16,23 @@ program
|
|
|
16
16
|
.option("-o, --output <dir>", "Output directory", "output")
|
|
17
17
|
.option("-p, --password <password>", "Password to protect zip files")
|
|
18
18
|
.option("--telegram", "Upload zip files to Telegram")
|
|
19
|
-
.option("--
|
|
19
|
+
.option("--api-id <id>", "Telegram API ID (required for MTProto)")
|
|
20
|
+
.option("--api-hash <hash>", "Telegram API Hash (required for MTProto)")
|
|
20
21
|
.option("--chat-id <id>", "Telegram chat ID (required if using --telegram)")
|
|
21
22
|
.parse();
|
|
22
23
|
(async () => {
|
|
23
24
|
const source = path_1.default.resolve(program.args[0]);
|
|
24
25
|
const outputDir = path_1.default.resolve(program.opts().output);
|
|
25
26
|
const useTelegram = program.opts().telegram || false;
|
|
26
|
-
const botToken = program.opts().botToken;
|
|
27
27
|
const chatId = program.opts().chatId;
|
|
28
28
|
const password = program.opts().password;
|
|
29
|
+
const apiId = program.opts().apiId;
|
|
30
|
+
const apiHash = program.opts().apiHash;
|
|
29
31
|
console.log(`\nšøļø Crawling files in ${source}...`);
|
|
30
32
|
const files = await (0, crawler_1.crawl)(source);
|
|
31
33
|
console.log(`š Found ${files.length} file${files.length !== 1 ? 's' : ''}`);
|
|
32
34
|
const chunks = (0, chunking_1.chunkFiles)(files);
|
|
33
|
-
console.log(`š¦ Created ${chunks.length} chunk${chunks.length !== 1 ? 's' : ''} (max
|
|
34
|
-
await (0, zipper_1.zipChunks)(chunks, outputDir, useTelegram,
|
|
35
|
+
console.log(`š¦ Created ${chunks.length} chunk${chunks.length !== 1 ? 's' : ''} (max 2GB each)${password ? ' š Password protected' : ''}\n`);
|
|
36
|
+
await (0, zipper_1.zipChunks)(chunks, outputDir, useTelegram, chatId, password, apiId, apiHash);
|
|
35
37
|
console.log(`\nš All done! ${useTelegram ? 'Files uploaded to Telegram.' : `Zips saved to ${outputDir}`}`);
|
|
36
38
|
})();
|
package/dist/src/chunking.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.chunkFiles = chunkFiles;
|
|
4
|
-
const CHUNK_SIZE =
|
|
4
|
+
const CHUNK_SIZE = 1.9 * 1024 * 1024 * 1024; // 1.9 GB
|
|
5
5
|
// groups files into chunks where the total size of each chunk does not exceed CHUNK_SIZE
|
|
6
6
|
function chunkFiles(files) {
|
|
7
7
|
const chunks = [];
|
|
@@ -9,7 +9,7 @@ function chunkFiles(files) {
|
|
|
9
9
|
let currentChunkSize = 0;
|
|
10
10
|
for (const file of files) {
|
|
11
11
|
if (file.size > CHUNK_SIZE) {
|
|
12
|
-
console.warn(`ā ļø Skipping file ${file.path} as it exceeds the maximum size of
|
|
12
|
+
console.warn(`ā ļø Skipping file ${file.path} as it exceeds the maximum size of 1.9GB (${(file.size / (1024 * 1024 * 1024)).toFixed(2)} GB).`);
|
|
13
13
|
continue;
|
|
14
14
|
}
|
|
15
15
|
if (currentChunkSize + file.size > CHUNK_SIZE) {
|
|
@@ -3,36 +3,74 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.initTelegramClient = initTelegramClient;
|
|
6
7
|
exports.uploadToTelegram = uploadToTelegram;
|
|
7
|
-
const
|
|
8
|
+
const telegram_1 = require("telegram");
|
|
9
|
+
const sessions_1 = require("telegram/sessions");
|
|
8
10
|
const fs_1 = __importDefault(require("fs"));
|
|
9
11
|
const path_1 = __importDefault(require("path"));
|
|
10
12
|
const cli_progress_1 = __importDefault(require("cli-progress"));
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
async function
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
if (!
|
|
18
|
-
throw new Error("ā Telegram
|
|
13
|
+
const input_1 = __importDefault(require("input"));
|
|
14
|
+
let client = null;
|
|
15
|
+
const sessionPath = path_1.default.join(process.cwd(), ".telegram_session");
|
|
16
|
+
async function initTelegramClient(apiId, apiHash) {
|
|
17
|
+
const API_ID = Number(apiId || process.env.TELEGRAM_API_ID);
|
|
18
|
+
const API_HASH = apiHash || process.env.TELEGRAM_API_HASH;
|
|
19
|
+
if (!API_ID || !API_HASH) {
|
|
20
|
+
throw new Error("ā Telegram API_ID and API_HASH are required for MTProto. Please set them in .env or provide as arguments.");
|
|
21
|
+
}
|
|
22
|
+
let sessionString = "";
|
|
23
|
+
if (fs_1.default.existsSync(sessionPath)) {
|
|
24
|
+
sessionString = fs_1.default.readFileSync(sessionPath, "utf-8");
|
|
25
|
+
}
|
|
26
|
+
const stringSession = new sessions_1.StringSession(sessionString);
|
|
27
|
+
client = new telegram_1.TelegramClient(stringSession, API_ID, API_HASH, {
|
|
28
|
+
connectionRetries: 5,
|
|
29
|
+
});
|
|
30
|
+
await client.start({
|
|
31
|
+
phoneNumber: async () => await input_1.default.text("Please enter your number: "),
|
|
32
|
+
password: async () => await input_1.default.text("Please enter your password: "),
|
|
33
|
+
phoneCode: async () => await input_1.default.text("Please enter the code you received: "),
|
|
34
|
+
onError: (err) => console.log(err),
|
|
35
|
+
});
|
|
36
|
+
// Save session
|
|
37
|
+
fs_1.default.writeFileSync(sessionPath, client.session.save());
|
|
38
|
+
console.log("ā
Connected to Telegram via MTProto!");
|
|
39
|
+
}
|
|
40
|
+
async function uploadToTelegram(zipPath, chatId) {
|
|
41
|
+
if (!client) {
|
|
42
|
+
throw new Error("ā Telegram client not initialized.");
|
|
43
|
+
}
|
|
44
|
+
const chat_id = chatId || process.env.TELEGRAM_CHAT_ID;
|
|
45
|
+
if (!chat_id) {
|
|
46
|
+
throw new Error("ā Chat ID is missing.");
|
|
19
47
|
}
|
|
20
|
-
const bot = new node_telegram_bot_api_1.default(bot_token, { polling: false });
|
|
21
|
-
const totalSize = fs_1.default.statSync(zipPath).size;
|
|
22
48
|
const fileName = path_1.default.basename(zipPath);
|
|
49
|
+
const totalSize = fs_1.default.statSync(zipPath).size;
|
|
23
50
|
const fileSizeMB = (totalSize / (1024 * 1024)).toFixed(2);
|
|
24
51
|
console.log(`\nš¤ Uploading ${fileName} (${fileSizeMB} MB)`);
|
|
25
52
|
const progressBar = new cli_progress_1.default.SingleBar({
|
|
26
53
|
format: "Uploading [{bar}] {percentage}% | {value}/{total} Bytes",
|
|
27
54
|
}, cli_progress_1.default.Presets.shades_classic);
|
|
28
55
|
progressBar.start(totalSize, 0);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
56
|
+
try {
|
|
57
|
+
await client.sendFile(chat_id, {
|
|
58
|
+
file: zipPath,
|
|
59
|
+
forceDocument: true,
|
|
60
|
+
progressCallback: (progress) => {
|
|
61
|
+
// progress is 0 to 1 (float)
|
|
62
|
+
// We need to map it to bytes for the progress bar, but GramJS progress is sometimes tricky.
|
|
63
|
+
// Assuming it's ratio.
|
|
64
|
+
progressBar.update(Math.floor(progress * totalSize));
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
progressBar.update(totalSize); // Ensure it finishes
|
|
68
|
+
progressBar.stop();
|
|
69
|
+
console.log(`ā
${fileName} uploaded successfully`);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
progressBar.stop();
|
|
73
|
+
console.error(`ā Failed to upload ${fileName}:`, error);
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
38
76
|
}
|
package/dist/src/zipper.js
CHANGED
|
@@ -13,17 +13,31 @@ const archiver_zip_encrypted_1 = __importDefault(require("archiver-zip-encrypted
|
|
|
13
13
|
const telegramUploader_1 = require("./telegramUploader");
|
|
14
14
|
// Register the encrypted format
|
|
15
15
|
archiver_1.default.registerFormat('zip-encrypted', archiver_zip_encrypted_1.default);
|
|
16
|
-
|
|
16
|
+
// Helper for serial execution
|
|
17
|
+
let uploadQueue = Promise.resolve();
|
|
18
|
+
const queueUpload = (action) => {
|
|
19
|
+
const next = uploadQueue.then(action).catch(err => {
|
|
20
|
+
console.error("Queue error:", err);
|
|
21
|
+
throw err;
|
|
22
|
+
});
|
|
23
|
+
uploadQueue = next.catch(() => { }); // Prevent queue from breaking on error, but we still throw for the caller
|
|
24
|
+
return next;
|
|
25
|
+
};
|
|
26
|
+
async function zipChunks(chunks, outputDir, useTelegram, chatId, password, apiId, apiHash) {
|
|
17
27
|
fs_1.default.mkdirSync(outputDir, { recursive: true });
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
if (useTelegram) {
|
|
29
|
+
console.log("š Initializing Telegram Client...");
|
|
30
|
+
await (0, telegramUploader_1.initTelegramClient)(apiId, apiHash);
|
|
31
|
+
}
|
|
32
|
+
// Process chunks in parallel (Zipping is parallel, Uploading is queued/serial)
|
|
33
|
+
await Promise.all(chunks.map(async (chunk, i) => {
|
|
20
34
|
const zipName = `chunk_${i + 1}.zip`;
|
|
21
35
|
const zipPath = path_1.default.join(outputDir, zipName);
|
|
22
|
-
console.log(`š¦ Zipping ${zipName}...`);
|
|
36
|
+
console.log(`š¦ Zipping ${zipName} (starting)...`);
|
|
23
37
|
const progressBar = new cli_progress_1.default.SingleBar({
|
|
24
38
|
format: `Zipping ${zipName} [{bar}] {percentage}% | {value}/{total} files`,
|
|
25
39
|
}, cli_progress_1.default.Presets.shades_classic);
|
|
26
|
-
progressBar.start(
|
|
40
|
+
progressBar.start(chunk.length, 0);
|
|
27
41
|
await new Promise((resolve, reject) => {
|
|
28
42
|
const output = fs_1.default.createWriteStream(zipPath);
|
|
29
43
|
// Use encrypted archiver if password is provided
|
|
@@ -37,22 +51,28 @@ async function zipChunks(chunks, outputDir, useTelegram, botToken, chatId, passw
|
|
|
37
51
|
archive.pipe(output);
|
|
38
52
|
output.on("close", () => {
|
|
39
53
|
progressBar.stop();
|
|
40
|
-
|
|
41
|
-
uploadQueue.push((0, telegramUploader_1.uploadToTelegram)(zipPath, botToken, chatId));
|
|
42
|
-
}
|
|
43
|
-
;
|
|
54
|
+
console.log(`ā
Zipped ${zipName}`);
|
|
44
55
|
resolve();
|
|
45
56
|
});
|
|
46
|
-
archive.on("error",
|
|
47
|
-
|
|
57
|
+
archive.on("error", (err) => {
|
|
58
|
+
progressBar.stop();
|
|
59
|
+
reject(err);
|
|
60
|
+
});
|
|
61
|
+
chunk.forEach((file) => {
|
|
48
62
|
archive.file(file.path, { name: path_1.default.basename(file.path) });
|
|
49
63
|
progressBar.increment();
|
|
50
64
|
});
|
|
51
65
|
archive.finalize();
|
|
52
66
|
});
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
67
|
+
if (useTelegram) {
|
|
68
|
+
// Queue the upload so it happens serially
|
|
69
|
+
await queueUpload(async () => {
|
|
70
|
+
// Random delay between 2 and 5 seconds
|
|
71
|
+
const delay = Math.floor(Math.random() * (5000 - 2000 + 1) + 2000);
|
|
72
|
+
console.log(`ā³ Waiting ${delay / 1000}s before uploading ${zipName}...`);
|
|
73
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
74
|
+
await (0, telegramUploader_1.uploadToTelegram)(zipPath, chatId);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}));
|
|
58
78
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ayush24k/telezipper",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Split folders into multiple 50MB zip files with optional Telegram upload made for personal use.",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
"cli-progress": "^3.12.0",
|
|
36
36
|
"commander": "^14.0.2",
|
|
37
37
|
"dotenv": "^17.2.3",
|
|
38
|
-
"
|
|
38
|
+
"input": "^1.0.1",
|
|
39
|
+
"telegram": "^2.26.22",
|
|
39
40
|
"tough-cookie": "^2.5.0"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"@types/archiver": "^7.0.0",
|
|
43
44
|
"@types/cli-progress": "^3.11.6",
|
|
44
45
|
"@types/node": "^25.1.0",
|
|
45
|
-
"@types/node-telegram-bot-api": "^0.64.13",
|
|
46
46
|
"typescript": "^5.9.3"
|
|
47
47
|
}
|
|
48
|
-
}
|
|
48
|
+
}
|