rubika 1.2.0 → 1.2.3
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 +20 -33
- package/bot/bot.ts +1 -1
- package/bot/methods/advanced/builder.ts +6 -6
- package/bot/methods/files/uploadFile.ts +1 -1
- package/bot/methods/utilities/webhook.ts +3 -1
- package/bot/network.ts +1 -1
- package/client/client.ts +3 -3
- package/client/contexts/contextConstructors.ts +14 -11
- package/client/methods/advanced/builder.ts +25 -25
- package/client/methods/auth/registerDevice.ts +1 -1
- package/client/methods/index.ts +1238 -1241
- package/client/methods/messages/sendMessage.ts +2 -2
- package/client/methods/utilities/start.ts +1 -1
- package/client/methods/utilities/thumbnail.ts +5 -5
- package/client/network/api.ts +2 -2
- package/client/network/file.ts +2 -2
- package/client/network/index.ts +3 -2
- package/client/network/utils.ts +24 -22
- package/client/network/websocket.ts +4 -4
- package/client/types/client.type.ts +7 -6
- package/client/types/methods.ts +224 -0
- package/package.json +1 -1
|
@@ -48,7 +48,7 @@ async function sendMessage(
|
|
|
48
48
|
}
|
|
49
49
|
file_inline = await fs.promises.readFile(fileName);
|
|
50
50
|
} else if (!Buffer.isBuffer(file_inline)) {
|
|
51
|
-
|
|
51
|
+
return this.logger.error(
|
|
52
52
|
"File argument must be a file path or bytes",
|
|
53
53
|
"warn",
|
|
54
54
|
);
|
|
@@ -70,7 +70,7 @@ async function sendMessage(
|
|
|
70
70
|
thumb = false;
|
|
71
71
|
if (audio_info) {
|
|
72
72
|
if (!optionalMusicMetadata) {
|
|
73
|
-
|
|
73
|
+
return new Error(
|
|
74
74
|
"music-metadata module is not installed. Some features may be disabled.",
|
|
75
75
|
);
|
|
76
76
|
}
|
|
@@ -16,7 +16,7 @@ async function start(this: Client): Promise<void> {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
try {
|
|
19
|
-
if (!this.auth)
|
|
19
|
+
if (!this.auth) return Error("[start] Error auth is not set");
|
|
20
20
|
this.key = Buffer.from(Crypto.passphrase(this.auth), "utf8");
|
|
21
21
|
this.decode_auth = Crypto.decode_auth(this.auth);
|
|
22
22
|
const result = await this.getUserInfo();
|
|
@@ -8,7 +8,7 @@ const ffmpeg = optionalImport<typeof import("fluent-ffmpeg")>("fluent-ffmpeg");
|
|
|
8
8
|
class ThumbnailGenerator {
|
|
9
9
|
static async getTime(videoPath: string): Promise<number> {
|
|
10
10
|
if (!ffmpeg) {
|
|
11
|
-
|
|
11
|
+
return new Error(
|
|
12
12
|
"fluent-ffmpeg module is not installed. Some features may be disabled.",
|
|
13
13
|
);
|
|
14
14
|
}
|
|
@@ -28,7 +28,7 @@ class ThumbnailGenerator {
|
|
|
28
28
|
|
|
29
29
|
static async fromVideo(videoPath: string): Promise<string> {
|
|
30
30
|
if (!ffmpeg) {
|
|
31
|
-
|
|
31
|
+
return new Error(
|
|
32
32
|
"fluent-ffmpeg module is not installed. Some features may be disabled.",
|
|
33
33
|
);
|
|
34
34
|
}
|
|
@@ -57,7 +57,7 @@ class ThumbnailGenerator {
|
|
|
57
57
|
return base64Thumbnail;
|
|
58
58
|
} catch (error) {
|
|
59
59
|
console.error("Error generating video thumbnail:", error);
|
|
60
|
-
|
|
60
|
+
return error;
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -66,7 +66,7 @@ class ThumbnailGenerator {
|
|
|
66
66
|
width: number = 320,
|
|
67
67
|
): Promise<string> {
|
|
68
68
|
if (!sharp) {
|
|
69
|
-
|
|
69
|
+
return new Error(
|
|
70
70
|
"sharp module is not installed. Some features may be disabled.",
|
|
71
71
|
);
|
|
72
72
|
}
|
|
@@ -76,7 +76,7 @@ class ThumbnailGenerator {
|
|
|
76
76
|
return buffer.toString("base64");
|
|
77
77
|
} catch (error) {
|
|
78
78
|
console.error("Error generating image thumbnail:", error);
|
|
79
|
-
|
|
79
|
+
return error;
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
}
|
package/client/network/api.ts
CHANGED
|
@@ -20,7 +20,7 @@ interface SendPayloadInputs {
|
|
|
20
20
|
* Retrieves API and WSS server URLs
|
|
21
21
|
*/
|
|
22
22
|
export async function getDcs(network: Network): Promise<boolean> {
|
|
23
|
-
const url = "
|
|
23
|
+
const url = `https://${network.client.application === "Shad" ? "sh" : ""}getdcmess.iranlms.ir/`;
|
|
24
24
|
const RETRY_DELAY = 3000;
|
|
25
25
|
|
|
26
26
|
while (true) {
|
|
@@ -86,7 +86,7 @@ export async function sendRequest(network: Network, url: string, data: any) {
|
|
|
86
86
|
|
|
87
87
|
await network.delay(1000);
|
|
88
88
|
}
|
|
89
|
-
|
|
89
|
+
return network.client.logger.error(
|
|
90
90
|
`[request] Failed after ${MAX_ATTEMPTS} attempts: ${url}`,
|
|
91
91
|
"warn",
|
|
92
92
|
);
|
package/client/network/file.ts
CHANGED
|
@@ -8,7 +8,7 @@ export async function uploadFile(
|
|
|
8
8
|
chunkSize: number = 1048576,
|
|
9
9
|
): Promise<any> {
|
|
10
10
|
if (!fs.existsSync(filePath))
|
|
11
|
-
|
|
11
|
+
return new Error("File not found in the given path");
|
|
12
12
|
|
|
13
13
|
const stat = await fs.promises.stat(filePath);
|
|
14
14
|
const fileSize = stat.size;
|
|
@@ -81,7 +81,7 @@ export async function uploadFile(
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
return new Error("Upload failed completely.");
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
export async function download(
|
package/client/network/index.ts
CHANGED
|
@@ -20,8 +20,9 @@ export default class Network {
|
|
|
20
20
|
public reconnecting: boolean = false;
|
|
21
21
|
|
|
22
22
|
constructor(public client: Client) {
|
|
23
|
-
|
|
24
|
-
this.
|
|
23
|
+
const isShad = client.application === "Shad";
|
|
24
|
+
this.defaultPlatform = resolvePlatform(client.platform , isShad);
|
|
25
|
+
this.headers = buildHeaders(client.platform , isShad);
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
getDcs = () => getDcs(this);
|
package/client/network/utils.ts
CHANGED
|
@@ -1,30 +1,32 @@
|
|
|
1
|
-
import UserAgent from
|
|
1
|
+
import UserAgent from "user-agents";
|
|
2
2
|
|
|
3
3
|
export function delay(ms: number) {
|
|
4
|
-
|
|
4
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
export function resolvePlatform(platform: string) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
export function resolvePlatform(platform: string, isShad: boolean) {
|
|
8
|
+
const isAndroid = platform?.toLowerCase() === "android";
|
|
9
|
+
return {
|
|
10
|
+
app_name: "Main",
|
|
11
|
+
app_version: isAndroid ? "3.6.4" : "4.4.9",
|
|
12
|
+
platform: isAndroid ? "Android" : "Web",
|
|
13
|
+
package: isAndroid
|
|
14
|
+
? `app.${isShad ? "sh" : "rb"}main.a`
|
|
15
|
+
: `web.${isShad ? "shad" : "rubika"}.ir`,
|
|
16
|
+
lang_code: "fa",
|
|
17
|
+
};
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
export function buildHeaders(platform: string) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
export function buildHeaders(platform: string, isShad: boolean) {
|
|
21
|
+
const headers: Record<string, string> = {
|
|
22
|
+
"content-type": "application/json",
|
|
23
|
+
connection: "keep-alive",
|
|
24
|
+
"user-agent": new UserAgent().toString(),
|
|
25
|
+
};
|
|
26
|
+
if (platform.toLowerCase() !== "android") {
|
|
27
|
+
headers.origin = `https://web.${isShad ? "shad" : "rubika"}.ir`;
|
|
28
|
+
headers.referer = `https://web.${isShad ? "shad" : "rubika"}.ir/`;
|
|
29
|
+
}
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
return headers;
|
|
30
32
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Network from ".";
|
|
2
2
|
import Crypto from "../crypto";
|
|
3
|
-
import {
|
|
3
|
+
import { ContextMapCon, Handler } from "../types/client.type";
|
|
4
4
|
import { ContextConstructors } from "../contexts/contextConstructors";
|
|
5
5
|
import Message from "../contexts/message.type";
|
|
6
6
|
import { checkFilters } from "../../utils";
|
|
@@ -143,9 +143,9 @@ async function getMessage(message: string, network: Network) {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
async function handleCategory<T extends keyof
|
|
146
|
+
async function handleCategory<T extends keyof ContextMapCon>(
|
|
147
147
|
type: T,
|
|
148
|
-
handlers: Handler<
|
|
148
|
+
handlers: Handler<ContextMapCon[T]>[],
|
|
149
149
|
updates: any[],
|
|
150
150
|
network: Network,
|
|
151
151
|
author_title: string,
|
|
@@ -161,7 +161,7 @@ async function handleCategory<T extends keyof ContextMap>(
|
|
|
161
161
|
update.client_guid = network.client.userGuid;
|
|
162
162
|
update.message.author_title = author_title;
|
|
163
163
|
|
|
164
|
-
const ctx = new CtxClass(network.client, update) as
|
|
164
|
+
const ctx = new CtxClass(network.client, update) as ContextMapCon[T];
|
|
165
165
|
|
|
166
166
|
for (const { filters, handler, prefix } of handlers) {
|
|
167
167
|
const passed = await checkFilters(ctx, filters);
|
|
@@ -17,12 +17,6 @@ export type TypeUpdate = "activities" | "chat" | "message" | "notifications";
|
|
|
17
17
|
export type SessionType = string | Session;
|
|
18
18
|
export type PlatformType = "Android" | "Web";
|
|
19
19
|
|
|
20
|
-
export type ErrorMiddleware = (
|
|
21
|
-
error: any,
|
|
22
|
-
ctx: Message,
|
|
23
|
-
next: () => Promise<void>,
|
|
24
|
-
) => Promise<void>;
|
|
25
|
-
|
|
26
20
|
// پلاگین
|
|
27
21
|
type PluginFunction = (client: Client) => Promise<void>;
|
|
28
22
|
|
|
@@ -43,6 +37,13 @@ export interface ContextMap {
|
|
|
43
37
|
};
|
|
44
38
|
}
|
|
45
39
|
|
|
40
|
+
export interface ContextMapCon {
|
|
41
|
+
chat: Chat;
|
|
42
|
+
message: Message;
|
|
43
|
+
activities: Activities;
|
|
44
|
+
notifications: Notifications;
|
|
45
|
+
}
|
|
46
|
+
|
|
46
47
|
export type Handler<T> = {
|
|
47
48
|
filters: Array<(ctx: T) => boolean | Promise<boolean>>;
|
|
48
49
|
handler: (ctx: T) => Promise<void>;
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { Message } from "./decorators.type";
|
|
2
|
+
|
|
3
|
+
type OnlineTimeType =
|
|
4
|
+
| "Exact"
|
|
5
|
+
| "Recently"
|
|
6
|
+
| "LastWeek"
|
|
7
|
+
| "LastMonth"
|
|
8
|
+
| "Offline";
|
|
9
|
+
type FileId = string | number;
|
|
10
|
+
|
|
11
|
+
interface AvatarThumbnail {
|
|
12
|
+
file_id: FileId;
|
|
13
|
+
mime: string;
|
|
14
|
+
dc_id: string;
|
|
15
|
+
access_hash_rec: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface MusicTrack {
|
|
19
|
+
file_id: FileId;
|
|
20
|
+
mime: string;
|
|
21
|
+
dc_id: string;
|
|
22
|
+
access_hash_rec: string;
|
|
23
|
+
file_name: string;
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
time: number;
|
|
27
|
+
size: number;
|
|
28
|
+
type: string;
|
|
29
|
+
music_performer: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface BaseUser {
|
|
33
|
+
user_guid: string;
|
|
34
|
+
first_name: string;
|
|
35
|
+
last_name: string;
|
|
36
|
+
phone: string;
|
|
37
|
+
username?: string;
|
|
38
|
+
avatar_thumbnail?: AvatarThumbnail;
|
|
39
|
+
last_online: number;
|
|
40
|
+
bio: string;
|
|
41
|
+
is_deleted: boolean;
|
|
42
|
+
is_verified: boolean;
|
|
43
|
+
online_time: { type: OnlineTimeType | string; exact_time?: number };
|
|
44
|
+
birth_date?: string;
|
|
45
|
+
saved_music_last_track?: MusicTrack;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface GetUserInfoResponse {
|
|
49
|
+
user: BaseUser;
|
|
50
|
+
chat: {
|
|
51
|
+
object_guid: string;
|
|
52
|
+
access: string[];
|
|
53
|
+
count_unseen: number;
|
|
54
|
+
is_mute: boolean;
|
|
55
|
+
is_pinned: boolean;
|
|
56
|
+
time_string: string;
|
|
57
|
+
last_message?: {
|
|
58
|
+
message_id: string;
|
|
59
|
+
type: string;
|
|
60
|
+
text?: string;
|
|
61
|
+
author_object_guid: string;
|
|
62
|
+
is_mine: boolean;
|
|
63
|
+
author_title: string;
|
|
64
|
+
author_type: string;
|
|
65
|
+
};
|
|
66
|
+
last_seen_my_mid: string;
|
|
67
|
+
last_seen_peer_mid: string;
|
|
68
|
+
status: string;
|
|
69
|
+
time: number;
|
|
70
|
+
abs_object: {
|
|
71
|
+
object_guid: string;
|
|
72
|
+
type: string;
|
|
73
|
+
first_name?: string;
|
|
74
|
+
last_name?: string;
|
|
75
|
+
avatar_thumbnail?: AvatarThumbnail;
|
|
76
|
+
is_verified: boolean;
|
|
77
|
+
is_deleted: boolean;
|
|
78
|
+
};
|
|
79
|
+
is_blocked: boolean;
|
|
80
|
+
last_message_id: string;
|
|
81
|
+
last_deleted_mid?: string;
|
|
82
|
+
has_schedule: boolean;
|
|
83
|
+
auto_delete: string;
|
|
84
|
+
};
|
|
85
|
+
timestamp: string;
|
|
86
|
+
can_receive_call: boolean;
|
|
87
|
+
can_video_call: boolean;
|
|
88
|
+
user_additional_info: {
|
|
89
|
+
is_in_contact: boolean;
|
|
90
|
+
can_receive_call: boolean;
|
|
91
|
+
can_video_call: boolean;
|
|
92
|
+
photo_changed_time?: number;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface SendCodeResponse {
|
|
97
|
+
phone_code_hash: string;
|
|
98
|
+
status: "OK" | string;
|
|
99
|
+
code_digits_count: number;
|
|
100
|
+
has_confirmed_recovery_email: boolean;
|
|
101
|
+
no_recovery_alert?: string;
|
|
102
|
+
send_type: "SMS" | string;
|
|
103
|
+
hint_pass_key: string
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface SignInResponse {
|
|
107
|
+
status: "OK" | string;
|
|
108
|
+
auth: string;
|
|
109
|
+
user: BaseUser;
|
|
110
|
+
timestamp: string;
|
|
111
|
+
two_step_enabled?: boolean;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export interface AddChannelResponse {
|
|
115
|
+
channel: {
|
|
116
|
+
channel_guid: string;
|
|
117
|
+
channel_title: string;
|
|
118
|
+
count_members: number;
|
|
119
|
+
description: string;
|
|
120
|
+
is_deleted: boolean;
|
|
121
|
+
is_verified: boolean;
|
|
122
|
+
channel_type: string;
|
|
123
|
+
sign_messages: boolean;
|
|
124
|
+
chat_reaction_setting: {
|
|
125
|
+
reaction_type: string;
|
|
126
|
+
};
|
|
127
|
+
is_restricted_content: boolean;
|
|
128
|
+
};
|
|
129
|
+
chat_update: {
|
|
130
|
+
object_guid: string;
|
|
131
|
+
action: string;
|
|
132
|
+
chat: {
|
|
133
|
+
object_guid: string;
|
|
134
|
+
access: string[];
|
|
135
|
+
count_unseen: number;
|
|
136
|
+
is_mute: boolean;
|
|
137
|
+
is_pinned: boolean;
|
|
138
|
+
time_string: string;
|
|
139
|
+
last_message?: {
|
|
140
|
+
message_id: string;
|
|
141
|
+
type: string;
|
|
142
|
+
text: string;
|
|
143
|
+
is_mine: boolean;
|
|
144
|
+
};
|
|
145
|
+
last_seen_my_mid: string;
|
|
146
|
+
last_seen_peer_mid: string;
|
|
147
|
+
status: string;
|
|
148
|
+
time: number;
|
|
149
|
+
abs_object: {
|
|
150
|
+
object_guid: string;
|
|
151
|
+
type: string;
|
|
152
|
+
title: string;
|
|
153
|
+
is_verified: boolean;
|
|
154
|
+
is_deleted: boolean;
|
|
155
|
+
};
|
|
156
|
+
is_blocked: boolean;
|
|
157
|
+
last_message_id: string;
|
|
158
|
+
last_deleted_mid?: string;
|
|
159
|
+
show_ask_spam?: boolean;
|
|
160
|
+
auto_delete: string;
|
|
161
|
+
};
|
|
162
|
+
updated_parameters: any[];
|
|
163
|
+
timestamp: string;
|
|
164
|
+
type: string;
|
|
165
|
+
};
|
|
166
|
+
message_update?: Message;
|
|
167
|
+
timestamp: string;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface GetChannelInfoResponse {
|
|
171
|
+
channel: {
|
|
172
|
+
channel_guid: string;
|
|
173
|
+
channel_title: string;
|
|
174
|
+
avatar_thumbnail?: AvatarThumbnail;
|
|
175
|
+
count_members: number;
|
|
176
|
+
description: string;
|
|
177
|
+
username?: string;
|
|
178
|
+
is_deleted: boolean;
|
|
179
|
+
is_verified: boolean;
|
|
180
|
+
share_url?: string;
|
|
181
|
+
channel_type: string;
|
|
182
|
+
sign_messages: boolean;
|
|
183
|
+
chat_reaction_setting: {
|
|
184
|
+
reaction_type: string;
|
|
185
|
+
selected_reactions: string[];
|
|
186
|
+
};
|
|
187
|
+
is_restricted_content: boolean;
|
|
188
|
+
};
|
|
189
|
+
chat: {
|
|
190
|
+
object_guid: string;
|
|
191
|
+
access: string[];
|
|
192
|
+
count_unseen: number;
|
|
193
|
+
is_mute: boolean;
|
|
194
|
+
is_pinned: boolean;
|
|
195
|
+
time_string: string;
|
|
196
|
+
last_message?: {
|
|
197
|
+
message_id: string;
|
|
198
|
+
type: string;
|
|
199
|
+
text: string;
|
|
200
|
+
is_mine: boolean;
|
|
201
|
+
};
|
|
202
|
+
last_seen_my_mid: string;
|
|
203
|
+
last_seen_peer_mid: string;
|
|
204
|
+
status: string;
|
|
205
|
+
time: number;
|
|
206
|
+
abs_object: {
|
|
207
|
+
object_guid: string;
|
|
208
|
+
type: string;
|
|
209
|
+
title?: string;
|
|
210
|
+
avatar_thumbnail?: AvatarThumbnail;
|
|
211
|
+
is_verified: boolean;
|
|
212
|
+
is_deleted: boolean;
|
|
213
|
+
};
|
|
214
|
+
is_blocked: boolean;
|
|
215
|
+
last_message_id: string;
|
|
216
|
+
last_deleted_mid?: string;
|
|
217
|
+
show_ask_spam?: boolean;
|
|
218
|
+
is_archived?: boolean;
|
|
219
|
+
auto_delete: string;
|
|
220
|
+
};
|
|
221
|
+
timestamp: string;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
|