rubjs 3.0.0 → 3.0.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 +8 -8
- package/lib/clients/VoiceChatClient.d.ts +4 -3
- package/lib/clients/VoiceChatClient.js +60 -92
- package/lib/clients/loginClient.d.ts +1 -1
- package/lib/clients/loginClient.js +1 -1
- package/lib/{core → clients}/network_login.js +1 -1
- package/lib/core/client.d.ts +10 -19
- package/lib/core/client.js +32 -20
- package/lib/{types → core/context}/activities.type.d.ts +2 -2
- package/lib/{types → core/context}/chat.type.d.ts +2 -2
- package/lib/core/context/contextConstructors.d.ts +10 -0
- package/lib/core/context/contextConstructors.js +16 -0
- package/lib/core/context/index.d.ts +5 -0
- package/lib/core/context/index.js +14 -0
- package/lib/{types → core/context}/message.type.d.ts +2 -2
- package/lib/{types → core/context}/notifications.type.d.ts +2 -2
- package/lib/core/methods/extras/onEditMessages.d.ts +1 -1
- package/lib/core/methods/groups/joinGroup.js +0 -1
- package/lib/core/methods/index.d.ts +4 -3
- package/lib/core/methods/index.js +8 -17
- package/lib/core/methods/utilities/download.d.ts +4 -0
- package/lib/core/methods/utilities/download.js +6 -0
- package/lib/core/methods/utilities/downloadProfilePicture.d.ts +4 -0
- package/lib/core/methods/utilities/downloadProfilePicture.js +28 -0
- package/lib/core/methods/utilities/index.d.ts +3 -3
- package/lib/core/methods/utilities/index.js +5 -5
- package/lib/core/methods/utilities/start.js +0 -1
- package/lib/core/network/api.d.ts +16 -0
- package/lib/core/network/api.js +95 -0
- package/lib/core/network/file.d.ts +3 -0
- package/lib/core/network/file.js +117 -0
- package/lib/core/network/index.d.ts +25 -0
- package/lib/core/network/index.js +31 -0
- package/lib/core/network/utils.d.ts +9 -0
- package/lib/core/network/utils.js +34 -0
- package/lib/core/network/websocket.d.ts +3 -0
- package/lib/core/network/websocket.js +190 -0
- package/lib/index.d.ts +7 -5
- package/lib/index.js +2 -4
- package/lib/types/client.type.d.ts +10 -12
- package/lib/types/index.type.d.ts +1 -3
- package/lib/types/index.type.js +1 -8
- package/package.json +1 -1
- package/lib/core/methods/utilities/runErrorMiddlewares.d.ts +0 -3
- package/lib/core/methods/utilities/runErrorMiddlewares.js +0 -13
- package/lib/core/methods/utilities/useError.d.ts +0 -4
- package/lib/core/methods/utilities/useError.js +0 -6
- package/lib/core/network.d.ts +0 -49
- package/lib/core/network.js +0 -436
- /package/lib/{core → clients}/network_login.d.ts +0 -0
- /package/lib/{types → core/context}/activities.type.js +0 -0
- /package/lib/{types → core/context}/chat.type.js +0 -0
- /package/lib/{types → core/context}/message.type.js +0 -0
- /package/lib/{types → core/context}/notifications.type.js +0 -0
- /package/lib/{core → utils}/utils.d.ts +0 -0
- /package/lib/{core → utils}/utils.js +0 -0
@@ -1,8 +1,8 @@
|
|
1
1
|
import Client from '../core/client';
|
2
|
-
import Chat from '
|
3
|
-
import
|
4
|
-
import Message from '
|
5
|
-
import Notifications from '
|
2
|
+
import Chat from '../core/context/chat.type';
|
3
|
+
import Activities from '../core/context/activities.type';
|
4
|
+
import Message from '../core/context/message.type';
|
5
|
+
import Notifications from '../core/context/notifications.type';
|
6
6
|
export interface Session {
|
7
7
|
iv: string;
|
8
8
|
enData: string;
|
@@ -17,17 +17,15 @@ export interface RubPlugin {
|
|
17
17
|
version?: string;
|
18
18
|
run: PluginFunction;
|
19
19
|
}
|
20
|
-
export
|
20
|
+
export interface ContextMap {
|
21
21
|
chat: Chat;
|
22
22
|
message: Message;
|
23
23
|
activities: Activities;
|
24
24
|
notifications: Notifications;
|
25
|
-
};
|
26
|
-
export type Middleware<C> = (ctx: C, next: () => Promise<void>) => Promise<void>;
|
27
|
-
export type Handler<C> = (ctx: C) => Promise<void>;
|
28
|
-
export type MiddlewareChain<C> = [...Middleware<C>[], Handler<C>];
|
29
|
-
export interface Command<C> {
|
30
|
-
pattern: string | RegExp;
|
31
|
-
middlewares: MiddlewareChain<C>;
|
32
25
|
}
|
26
|
+
export type Handler<T> = {
|
27
|
+
filters: Array<(ctx: T) => boolean | Promise<boolean>>;
|
28
|
+
handler: (ctx: T) => Promise<void>;
|
29
|
+
prefix?: string | RegExp;
|
30
|
+
};
|
33
31
|
export {};
|
@@ -2,6 +2,4 @@ import * as ClientTypes from './client.type';
|
|
2
2
|
import * as SessionTypes from './session.type';
|
3
3
|
import * as NetworkTypes from './network.type';
|
4
4
|
import * as DecoratorsTypes from './decorators.type';
|
5
|
-
|
6
|
-
import Activities from './activities.type';
|
7
|
-
export { ClientTypes, SessionTypes, NetworkTypes, DecoratorsTypes, Message, Activities, };
|
5
|
+
export { ClientTypes, SessionTypes, NetworkTypes, DecoratorsTypes, };
|
package/lib/types/index.type.js
CHANGED
@@ -32,11 +32,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
32
32
|
return result;
|
33
33
|
};
|
34
34
|
})();
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
37
|
-
};
|
38
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
39
|
-
exports.
|
36
|
+
exports.DecoratorsTypes = exports.NetworkTypes = exports.SessionTypes = exports.ClientTypes = void 0;
|
40
37
|
const ClientTypes = __importStar(require("./client.type"));
|
41
38
|
exports.ClientTypes = ClientTypes;
|
42
39
|
const SessionTypes = __importStar(require("./session.type"));
|
@@ -45,7 +42,3 @@ const NetworkTypes = __importStar(require("./network.type"));
|
|
45
42
|
exports.NetworkTypes = NetworkTypes;
|
46
43
|
const DecoratorsTypes = __importStar(require("./decorators.type"));
|
47
44
|
exports.DecoratorsTypes = DecoratorsTypes;
|
48
|
-
const message_type_1 = __importDefault(require("./message.type"));
|
49
|
-
exports.Message = message_type_1.default;
|
50
|
-
const activities_type_1 = __importDefault(require("./activities.type"));
|
51
|
-
exports.Activities = activities_type_1.default;
|
package/package.json
CHANGED
@@ -1,13 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
async function runErrorMiddlewares(error, data) {
|
4
|
-
for (const errMw of this.errorMiddlewares) {
|
5
|
-
try {
|
6
|
-
await errMw(error, data, async () => { });
|
7
|
-
}
|
8
|
-
catch (innerErr) {
|
9
|
-
console.error('[ErrorMiddleware] Error inside error handler:', innerErr);
|
10
|
-
}
|
11
|
-
}
|
12
|
-
}
|
13
|
-
exports.default = runErrorMiddlewares;
|
package/lib/core/network.d.ts
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
import { NetworkTypes } from '../types/index.type';
|
2
|
-
import Client from './client';
|
3
|
-
export default class Network {
|
4
|
-
private client;
|
5
|
-
headers: Record<string, string>;
|
6
|
-
userAgent: string;
|
7
|
-
defaultPlatform: NetworkTypes.Platform;
|
8
|
-
private apiVersion;
|
9
|
-
private agent;
|
10
|
-
private apiUrl?;
|
11
|
-
private wssUrl?;
|
12
|
-
private ws?;
|
13
|
-
private heartbeatInterval?;
|
14
|
-
private inactivityTimeout?;
|
15
|
-
private reconnecting;
|
16
|
-
constructor(client: Client);
|
17
|
-
/**
|
18
|
-
* Retrieves API and WSS server URLs
|
19
|
-
*/
|
20
|
-
getDcs(): Promise<boolean>;
|
21
|
-
/**
|
22
|
-
* Sends a POST request with retry logic and enhanced error reporting
|
23
|
-
*/
|
24
|
-
request(url: string, data: Record<string, any>): Promise<any>;
|
25
|
-
send({ input, method, tmp_session, }: {
|
26
|
-
input?: Record<string, any>;
|
27
|
-
method?: string;
|
28
|
-
tmp_session: boolean;
|
29
|
-
}): Promise<any>;
|
30
|
-
getUpdates(): Promise<void>;
|
31
|
-
handleConnect(): Promise<void>;
|
32
|
-
handleMessage(message: string): Promise<void>;
|
33
|
-
private runMiddlewareChain;
|
34
|
-
resetConnection(): Promise<void>;
|
35
|
-
private resetInactivityTimer;
|
36
|
-
uploadFile(filePath: string, chunkSize?: number): Promise<any>;
|
37
|
-
/**
|
38
|
-
* Delay utility
|
39
|
-
*/
|
40
|
-
delay(ms: number): Promise<void>;
|
41
|
-
/**
|
42
|
-
* Resolves platform configuration based on input
|
43
|
-
*/
|
44
|
-
private resolvePlatform;
|
45
|
-
/**
|
46
|
-
* Builds HTTP headers based on platform
|
47
|
-
*/
|
48
|
-
private buildHeaders;
|
49
|
-
}
|
package/lib/core/network.js
DELETED
@@ -1,436 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
const undici_1 = require("undici");
|
7
|
-
const user_agents_1 = __importDefault(require("user-agents"));
|
8
|
-
const index_type_1 = require("../types/index.type");
|
9
|
-
const crypto_1 = __importDefault(require("./crypto"));
|
10
|
-
const fs_1 = __importDefault(require("fs"));
|
11
|
-
const path_1 = __importDefault(require("path"));
|
12
|
-
const chat_type_1 = __importDefault(require("../types/chat.type"));
|
13
|
-
const notifications_type_1 = __importDefault(require("../types/notifications.type"));
|
14
|
-
const types = {
|
15
|
-
activities: 'show_activities',
|
16
|
-
chat: 'chat_updates',
|
17
|
-
message: 'message_updates',
|
18
|
-
notifications: 'show_notifications',
|
19
|
-
};
|
20
|
-
class Network {
|
21
|
-
constructor(client) {
|
22
|
-
this.client = client;
|
23
|
-
this.userAgent = new user_agents_1.default().toString();
|
24
|
-
this.apiVersion = '6';
|
25
|
-
this.reconnecting = false;
|
26
|
-
this.defaultPlatform = this.resolvePlatform(client.platform);
|
27
|
-
this.headers = this.buildHeaders(client.platform);
|
28
|
-
this.agent = new undici_1.Agent({
|
29
|
-
connect: {
|
30
|
-
rejectUnauthorized: false,
|
31
|
-
},
|
32
|
-
});
|
33
|
-
}
|
34
|
-
/**
|
35
|
-
* Retrieves API and WSS server URLs
|
36
|
-
*/
|
37
|
-
async getDcs() {
|
38
|
-
const url = 'https://getdcmess.iranlms.ir/';
|
39
|
-
const RETRY_DELAY = 3000;
|
40
|
-
while (true) {
|
41
|
-
try {
|
42
|
-
const res = await (0, undici_1.request)(url, {
|
43
|
-
method: 'GET',
|
44
|
-
dispatcher: this.agent,
|
45
|
-
});
|
46
|
-
if (res.statusCode === 200) {
|
47
|
-
const body = (await res.body.json());
|
48
|
-
if (body?.data) {
|
49
|
-
const dcs = body.data;
|
50
|
-
this.apiUrl = `${dcs.API[dcs.default_api]}/`;
|
51
|
-
this.wssUrl = dcs.socket[dcs.default_socket];
|
52
|
-
return true;
|
53
|
-
}
|
54
|
-
}
|
55
|
-
console.warn('[getDcs] Unexpected status or data format:', res.statusCode);
|
56
|
-
}
|
57
|
-
catch (error) {
|
58
|
-
console.error('[getDcs] Error:', error);
|
59
|
-
}
|
60
|
-
await this.delay(RETRY_DELAY);
|
61
|
-
}
|
62
|
-
}
|
63
|
-
/**
|
64
|
-
* Sends a POST request with retry logic and enhanced error reporting
|
65
|
-
*/
|
66
|
-
async request(url, data) {
|
67
|
-
const MAX_ATTEMPTS = 3;
|
68
|
-
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
69
|
-
try {
|
70
|
-
const res = await (0, undici_1.request)(url, {
|
71
|
-
method: 'POST',
|
72
|
-
headers: {
|
73
|
-
'content-type': 'application/json',
|
74
|
-
...this.headers,
|
75
|
-
},
|
76
|
-
body: JSON.stringify(data),
|
77
|
-
dispatcher: this.agent,
|
78
|
-
});
|
79
|
-
if (res.statusCode === 200) {
|
80
|
-
const responseData = await res.body.json();
|
81
|
-
return responseData;
|
82
|
-
}
|
83
|
-
else {
|
84
|
-
console.warn(`[request] Attempt ${attempt}: Unexpected status ${res.statusCode}`);
|
85
|
-
}
|
86
|
-
}
|
87
|
-
catch (error) {
|
88
|
-
console.error(`[request] Attempt ${attempt} failed:`, error);
|
89
|
-
}
|
90
|
-
await this.delay(1000);
|
91
|
-
}
|
92
|
-
throw new Error(`[request] Failed after ${MAX_ATTEMPTS} attempts: ${url}`);
|
93
|
-
}
|
94
|
-
async send({ input = {}, method = 'getUserInfo', tmp_session, }) {
|
95
|
-
while (!this.apiUrl) {
|
96
|
-
await this.getDcs();
|
97
|
-
await this.delay(1000);
|
98
|
-
}
|
99
|
-
const { auth, decode_auth, key, privateKey } = this.client;
|
100
|
-
if (!key)
|
101
|
-
return;
|
102
|
-
const credentialsKey = tmp_session ? 'tmp_session' : 'auth';
|
103
|
-
const credentialsValue = tmp_session ? auth : decode_auth;
|
104
|
-
const payload = {
|
105
|
-
api_version: this.apiVersion,
|
106
|
-
[credentialsKey]: credentialsValue,
|
107
|
-
};
|
108
|
-
const dataPayload = JSON.stringify({
|
109
|
-
client: this.defaultPlatform,
|
110
|
-
method,
|
111
|
-
input,
|
112
|
-
});
|
113
|
-
payload.data_enc = crypto_1.default.encrypt(dataPayload, key);
|
114
|
-
if (!tmp_session && privateKey) {
|
115
|
-
payload.sign = crypto_1.default.sign(payload.data_enc, privateKey);
|
116
|
-
}
|
117
|
-
return this.request(this.apiUrl, payload);
|
118
|
-
}
|
119
|
-
async getUpdates() {
|
120
|
-
while (!this.wssUrl) {
|
121
|
-
await this.getDcs();
|
122
|
-
await this.delay(1000);
|
123
|
-
}
|
124
|
-
this.ws = new undici_1.WebSocket(this.wssUrl);
|
125
|
-
this.ws.addEventListener('open', async () => {
|
126
|
-
await this.handleConnect();
|
127
|
-
this.resetInactivityTimer();
|
128
|
-
});
|
129
|
-
this.ws.addEventListener('message', async (event) => {
|
130
|
-
await this.handleMessage(event.data);
|
131
|
-
this.resetInactivityTimer();
|
132
|
-
});
|
133
|
-
this.ws.addEventListener('error', async (event) => {
|
134
|
-
if (!this.reconnecting) {
|
135
|
-
console.error('WebSocket error, reconnecting...');
|
136
|
-
this.reconnecting = true;
|
137
|
-
await this.resetConnection();
|
138
|
-
}
|
139
|
-
});
|
140
|
-
this.ws.addEventListener('close', async () => {
|
141
|
-
if (!this.reconnecting) {
|
142
|
-
console.warn('WebSocket closed, reconnecting...');
|
143
|
-
this.reconnecting = true;
|
144
|
-
await this.resetConnection();
|
145
|
-
}
|
146
|
-
});
|
147
|
-
}
|
148
|
-
async handleConnect() {
|
149
|
-
console.log('Start Bot..');
|
150
|
-
if (this.ws?.readyState === undici_1.WebSocket.OPEN) {
|
151
|
-
this.ws?.send(JSON.stringify({
|
152
|
-
api_version: '5',
|
153
|
-
auth: this.client.auth,
|
154
|
-
data: '',
|
155
|
-
method: 'handShake',
|
156
|
-
}));
|
157
|
-
}
|
158
|
-
if (this.heartbeatInterval)
|
159
|
-
clearInterval(this.heartbeatInterval);
|
160
|
-
this.heartbeatInterval = setInterval(() => {
|
161
|
-
if (this.ws?.readyState === WebSocket.OPEN) {
|
162
|
-
this.ws.send(JSON.stringify({}));
|
163
|
-
}
|
164
|
-
}, 30000);
|
165
|
-
}
|
166
|
-
async handleMessage(message) {
|
167
|
-
const { data_enc } = JSON.parse(message);
|
168
|
-
if (!data_enc || !this.client.key)
|
169
|
-
return;
|
170
|
-
const update = JSON.parse(crypto_1.default.decrypt(data_enc, this.client.key));
|
171
|
-
for (let [event, data] of Object.entries(this.client.handlers)) {
|
172
|
-
if (data.length === 0)
|
173
|
-
continue;
|
174
|
-
// has message
|
175
|
-
const updates = update[types[event]];
|
176
|
-
if (!Array.isArray(updates) || updates.length === 0)
|
177
|
-
continue;
|
178
|
-
// get user name
|
179
|
-
let username = null;
|
180
|
-
const notification = update.show_notifications?.[0];
|
181
|
-
const chatUpdate = update.chat_updates?.[0];
|
182
|
-
if (notification) {
|
183
|
-
const objectGuid = notification?.message_data?.object_guid;
|
184
|
-
if (objectGuid?.startsWith('u0'))
|
185
|
-
username = notification.title;
|
186
|
-
else if (objectGuid?.startsWith('g0'))
|
187
|
-
username = notification.text?.split(':')[0];
|
188
|
-
}
|
189
|
-
else if (chatUpdate) {
|
190
|
-
username =
|
191
|
-
chatUpdate.chat?.last_message?.author_title || 'Unknown User';
|
192
|
-
}
|
193
|
-
else
|
194
|
-
username = 'Unknown User';
|
195
|
-
// start handlers
|
196
|
-
for (let messageData of updates) {
|
197
|
-
messageData = {
|
198
|
-
client_guid: this.client.userGuid,
|
199
|
-
...messageData,
|
200
|
-
message: {
|
201
|
-
author_title: username,
|
202
|
-
...messageData.message,
|
203
|
-
},
|
204
|
-
};
|
205
|
-
for (const chain of data) {
|
206
|
-
await this.runMiddlewareChain(event, chain, messageData, this.client);
|
207
|
-
}
|
208
|
-
}
|
209
|
-
}
|
210
|
-
if (update?.message_updates) {
|
211
|
-
for (let ctx of update.message_updates) {
|
212
|
-
ctx = new index_type_1.Message(this.client, ctx);
|
213
|
-
for (const { middlewares, pattern } of this.client.cmd) {
|
214
|
-
const text = ctx.message?.text;
|
215
|
-
if (!text)
|
216
|
-
return;
|
217
|
-
if ((typeof pattern === 'string' && text === pattern) ||
|
218
|
-
(pattern instanceof RegExp && pattern.test(text))) {
|
219
|
-
await this.runMiddlewareChain('message', middlewares, ctx, this.client);
|
220
|
-
}
|
221
|
-
}
|
222
|
-
}
|
223
|
-
}
|
224
|
-
}
|
225
|
-
async runMiddlewareChain(event, middlewares, ctx, client) {
|
226
|
-
let index = -1;
|
227
|
-
if (event === 'message') {
|
228
|
-
ctx = new index_type_1.Message(client, ctx);
|
229
|
-
}
|
230
|
-
else if (event === 'chat') {
|
231
|
-
ctx = new chat_type_1.default(client, ctx);
|
232
|
-
}
|
233
|
-
else if (event === 'activities') {
|
234
|
-
ctx = new index_type_1.Activities(client, ctx);
|
235
|
-
}
|
236
|
-
else if (event === 'notifications') {
|
237
|
-
ctx = new notifications_type_1.default(client, ctx);
|
238
|
-
}
|
239
|
-
const dispatch = async (i) => {
|
240
|
-
if (i <= index)
|
241
|
-
throw new Error('next() called multiple times');
|
242
|
-
index = i;
|
243
|
-
if (i === middlewares.length)
|
244
|
-
return;
|
245
|
-
const fn = middlewares[i];
|
246
|
-
try {
|
247
|
-
await fn(ctx, () => dispatch(i + 1));
|
248
|
-
}
|
249
|
-
catch (err) {
|
250
|
-
await this.client.runErrorMiddlewares(err, ctx);
|
251
|
-
}
|
252
|
-
};
|
253
|
-
await dispatch(0);
|
254
|
-
}
|
255
|
-
async resetConnection() {
|
256
|
-
this.ws?.close();
|
257
|
-
this.ws = undefined;
|
258
|
-
setTimeout(async () => {
|
259
|
-
await this.getUpdates();
|
260
|
-
this.reconnecting = false;
|
261
|
-
}, 5000);
|
262
|
-
}
|
263
|
-
resetInactivityTimer() {
|
264
|
-
clearTimeout(this.inactivityTimeout);
|
265
|
-
this.inactivityTimeout = setTimeout(async () => {
|
266
|
-
console.warn('No updates received for 10 minutes. Reconnecting WebSocket...');
|
267
|
-
await this.resetConnection();
|
268
|
-
}, 10 * 60 * 1000);
|
269
|
-
}
|
270
|
-
async uploadFile(filePath, chunkSize = 1048576) {
|
271
|
-
if (!fs_1.default.existsSync(filePath))
|
272
|
-
throw new Error('File not found in the given path');
|
273
|
-
const stat = await fs_1.default.promises.stat(filePath);
|
274
|
-
const fileSize = stat.size;
|
275
|
-
const fileName = path_1.default.basename(filePath);
|
276
|
-
const mime = filePath.split('.').pop();
|
277
|
-
let result = await this.client.requestSendFile(fileName, fileSize, mime);
|
278
|
-
let id = result.id;
|
279
|
-
let dc_id = result.dc_id;
|
280
|
-
let upload_url = result.upload_url;
|
281
|
-
let access_hash_send = result.access_hash_send;
|
282
|
-
let totalParts = Math.ceil(fileSize / chunkSize);
|
283
|
-
const stream = fs_1.default.createReadStream(filePath, { highWaterMark: chunkSize });
|
284
|
-
let index = 0;
|
285
|
-
for await (const chunk of stream) {
|
286
|
-
try {
|
287
|
-
const res = await (0, undici_1.request)(upload_url, {
|
288
|
-
method: 'POST',
|
289
|
-
headers: {
|
290
|
-
auth: this.client.auth,
|
291
|
-
'file-id': id,
|
292
|
-
'total-part': totalParts.toString(),
|
293
|
-
'part-number': (index + 1).toString(),
|
294
|
-
'chunk-size': chunk.length.toString(),
|
295
|
-
'access-hash-send': access_hash_send,
|
296
|
-
},
|
297
|
-
body: chunk,
|
298
|
-
dispatcher: this.agent,
|
299
|
-
});
|
300
|
-
const response = await res.body.json();
|
301
|
-
if (response.status === 'ERROR_TRY_AGAIN') {
|
302
|
-
console.log('Retrying upload...');
|
303
|
-
stream.close();
|
304
|
-
result = await this.client.requestSendFile(fileName, fileSize, mime);
|
305
|
-
id = result.id;
|
306
|
-
dc_id = result.dc_id;
|
307
|
-
upload_url = result.upload_url;
|
308
|
-
access_hash_send = result.access_hash_send;
|
309
|
-
index = 0;
|
310
|
-
return this.uploadFile(filePath, chunkSize);
|
311
|
-
}
|
312
|
-
index++;
|
313
|
-
if (response.status === 'OK' &&
|
314
|
-
response.status_det === 'OK' &&
|
315
|
-
response.data?.access_hash_rec) {
|
316
|
-
return {
|
317
|
-
mime,
|
318
|
-
size: fileSize,
|
319
|
-
dc_id,
|
320
|
-
file_id: id,
|
321
|
-
file_name: fileName,
|
322
|
-
access_hash_rec: response.data.access_hash_rec,
|
323
|
-
};
|
324
|
-
}
|
325
|
-
}
|
326
|
-
catch (error) {
|
327
|
-
console.error('Upload error:', error);
|
328
|
-
await new Promise((resolve) => setTimeout(resolve, 5000));
|
329
|
-
}
|
330
|
-
}
|
331
|
-
throw new Error('Upload failed completely.');
|
332
|
-
}
|
333
|
-
// async download(
|
334
|
-
// dc_id: number,
|
335
|
-
// file_id: number,
|
336
|
-
// access_hash: string,
|
337
|
-
// size: number,
|
338
|
-
// chunk: number = 131072,
|
339
|
-
// callback?: (totalSize: number, downloadedSize: number) => Promise<void>,
|
340
|
-
// speed: boolean = false
|
341
|
-
// ): Promise<Buffer> {
|
342
|
-
// const headers = {
|
343
|
-
// auth: this.client.auth,
|
344
|
-
// "access-hash-rec": access_hash,
|
345
|
-
// "file-id": String(file_id),
|
346
|
-
// "user-agent": this.userAgent,
|
347
|
-
// };
|
348
|
-
// const base_url = `https://messenger${dc_id}.iranlms.ir`;
|
349
|
-
// const fetchChunk = async (
|
350
|
-
// start_index: number,
|
351
|
-
// last_index: number
|
352
|
-
// ): Promise<Buffer> => {
|
353
|
-
// const chunk_headers = {
|
354
|
-
// ...headers,
|
355
|
-
// "start-index": String(start_index),
|
356
|
-
// "last-index": String(last_index),
|
357
|
-
// };
|
358
|
-
// try {
|
359
|
-
// const config: AxiosRequestConfig = {
|
360
|
-
// headers: chunk_headers,
|
361
|
-
// responseType: "arraybuffer",
|
362
|
-
// };
|
363
|
-
// const response = await axios.post(
|
364
|
-
// `${base_url}/GetFile.ashx`,
|
365
|
-
// {},
|
366
|
-
// config
|
367
|
-
// );
|
368
|
-
// return Buffer.from(response.data);
|
369
|
-
// } catch (e) {
|
370
|
-
// return Buffer.alloc(0);
|
371
|
-
// }
|
372
|
-
// };
|
373
|
-
// if (speed) {
|
374
|
-
// const tasks: Promise<Buffer>[] = [];
|
375
|
-
// for (let start_index = 0; start_index < size; start_index += chunk) {
|
376
|
-
// const last_index = Math.min(start_index + chunk, size) - 1;
|
377
|
-
// tasks.push(fetchChunk(start_index, last_index));
|
378
|
-
// }
|
379
|
-
// const resultChunks = await Promise.all(tasks);
|
380
|
-
// const result = Buffer.concat(resultChunks);
|
381
|
-
// if (callback) {
|
382
|
-
// await callback(size, result.length);
|
383
|
-
// }
|
384
|
-
// return result;
|
385
|
-
// } else {
|
386
|
-
// let result = Buffer.alloc(0);
|
387
|
-
// let start_index = 0;
|
388
|
-
// while (start_index < size) {
|
389
|
-
// const last_index = Math.min(start_index + chunk, size) - 1;
|
390
|
-
// const data = await fetchChunk(start_index, last_index);
|
391
|
-
// if (data.length === 0) break;
|
392
|
-
// result = Buffer.concat([result, data]);
|
393
|
-
// start_index = last_index + 1;
|
394
|
-
// if (callback) {
|
395
|
-
// await callback(size, result.length);
|
396
|
-
// }
|
397
|
-
// }
|
398
|
-
// return result;
|
399
|
-
// }
|
400
|
-
// }
|
401
|
-
/**
|
402
|
-
* Delay utility
|
403
|
-
*/
|
404
|
-
delay(ms) {
|
405
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
406
|
-
}
|
407
|
-
/**
|
408
|
-
* Resolves platform configuration based on input
|
409
|
-
*/
|
410
|
-
resolvePlatform(platform) {
|
411
|
-
const isAndroid = platform?.toLowerCase() === 'android';
|
412
|
-
return {
|
413
|
-
app_name: 'Main',
|
414
|
-
app_version: isAndroid ? '3.6.4' : '4.4.9',
|
415
|
-
platform: isAndroid ? 'Android' : 'Web',
|
416
|
-
package: isAndroid ? 'app.rbmain.a' : 'web.rubika.ir',
|
417
|
-
lang_code: 'fa',
|
418
|
-
};
|
419
|
-
}
|
420
|
-
/**
|
421
|
-
* Builds HTTP headers based on platform
|
422
|
-
*/
|
423
|
-
buildHeaders(platform) {
|
424
|
-
const headers = {
|
425
|
-
'content-type': 'application/json',
|
426
|
-
connection: 'keep-alive',
|
427
|
-
'user-agent': new user_agents_1.default().toString(),
|
428
|
-
};
|
429
|
-
if (platform.toLowerCase() !== 'android') {
|
430
|
-
headers.origin = 'https://web.rubika.ir';
|
431
|
-
headers.referer = 'https://web.rubika.ir/';
|
432
|
-
}
|
433
|
-
return headers;
|
434
|
-
}
|
435
|
-
}
|
436
|
-
exports.default = Network;
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|