@2byte/tgbot-framework 1.0.5 → 1.0.7

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.
Files changed (58) hide show
  1. package/README.md +300 -300
  2. package/bin/2byte-cli.ts +97 -97
  3. package/package.json +54 -54
  4. package/src/cli/CreateBotCommand.ts +181 -181
  5. package/src/cli/GenerateCommand.ts +195 -195
  6. package/src/cli/InitCommand.ts +107 -107
  7. package/src/cli/TgAccountManager.ts +50 -50
  8. package/src/console/migrate.ts +82 -82
  9. package/src/core/ApiService.ts +20 -20
  10. package/src/core/ApiServiceManager.ts +63 -63
  11. package/src/core/App.ts +1157 -1143
  12. package/src/core/BotArtisan.ts +79 -79
  13. package/src/core/BotMigration.ts +30 -30
  14. package/src/core/BotSeeder.ts +66 -66
  15. package/src/core/Model.ts +84 -84
  16. package/src/core/utils.ts +2 -2
  17. package/src/illumination/Artisan.ts +149 -149
  18. package/src/illumination/InlineKeyboard.ts +61 -61
  19. package/src/illumination/Message2Byte.ts +255 -255
  20. package/src/illumination/Message2ByteLiveProgressive.ts +278 -278
  21. package/src/illumination/Message2bytePool.ts +107 -107
  22. package/src/illumination/Migration.ts +186 -186
  23. package/src/illumination/RunSectionRoute.ts +85 -85
  24. package/src/illumination/Section.ts +410 -410
  25. package/src/illumination/SectionComponent.ts +64 -64
  26. package/src/illumination/Telegraf2byteContext.ts +32 -32
  27. package/src/index.ts +42 -42
  28. package/src/libs/TelegramAccountControl.ts +1140 -1140
  29. package/src/libs/TgSender.ts +53 -53
  30. package/src/models/Model.ts +67 -67
  31. package/src/models/Proxy.ts +217 -217
  32. package/src/models/TgAccount.ts +362 -362
  33. package/src/models/index.ts +2 -2
  34. package/src/types.ts +191 -191
  35. package/src/user/UserModel.ts +297 -297
  36. package/src/user/UserStore.ts +119 -119
  37. package/src/workflow/services/MassSendApiService.ts +80 -80
  38. package/templates/bot/.env.example +34 -23
  39. package/templates/bot/artisan.ts +8 -8
  40. package/templates/bot/bot.ts +82 -82
  41. package/templates/bot/database/dbConnector.ts +4 -4
  42. package/templates/bot/database/migrate.ts +9 -9
  43. package/templates/bot/database/migrations/001_create_users.sql +18 -18
  44. package/templates/bot/database/migrations/007_proxy.sql +27 -27
  45. package/templates/bot/database/migrations/008_tg_accounts.sql +32 -32
  46. package/templates/bot/database/seed.ts +14 -14
  47. package/templates/bot/docs/CLI_SERVICES.md +536 -536
  48. package/templates/bot/docs/INPUT_SYSTEM.md +211 -211
  49. package/templates/bot/docs/SERVICE_EXAMPLES.md +384 -384
  50. package/templates/bot/docs/TASK_SYSTEM.md +156 -156
  51. package/templates/bot/models/Model.ts +7 -7
  52. package/templates/bot/models/index.ts +1 -1
  53. package/templates/bot/package.json +30 -30
  54. package/templates/bot/sectionList.ts +9 -9
  55. package/templates/bot/sections/ExampleInputSection.ts +85 -85
  56. package/templates/bot/sections/ExampleLiveTaskerSection.ts +60 -60
  57. package/templates/bot/sections/HomeSection.ts +63 -63
  58. package/templates/bot/workflow/services/ExampleService.ts +23 -23
@@ -1,297 +1,297 @@
1
- import { Model } from '../core/Model';
2
- import { UserAttributes, UserRegistrationData, UserServiceAttributes } from '../types';
3
- import { UserStore } from './UserStore';
4
-
5
- export class UserModel extends Model {
6
- static tableName = 'users';
7
- attributes: UserAttributes;
8
- serviceAttributes: UserServiceAttributes = {
9
- lastActive: new Date(),
10
- lastMessageIds: [],
11
- };
12
-
13
- private userSession: UserStore | null = null;
14
-
15
- constructor(attributes: UserAttributes) {
16
- super();
17
- this.attributes = attributes;
18
- }
19
-
20
- static getAll(): UserModel[] {
21
- const usersData = this.query(`SELECT * FROM ${this.tableName}`);
22
- return usersData.map((data: any) => UserModel.make(data));
23
- }
24
-
25
- setSessionStorage(storage: UserStore): this {
26
- this.userSession = storage;
27
- return this;
28
- }
29
-
30
- upActive(): void {
31
- this.serviceAttributes.lastActive = new Date();
32
- }
33
-
34
- storeMessageId(messageId: number, limit: number): this {
35
- if (this.serviceAttributes.lastMessageIds.indexOf(messageId) === -1) {
36
- this.serviceAttributes.lastMessageIds.push(messageId);
37
- }
38
-
39
- if (this.serviceAttributes.lastMessageIds.length > limit) {
40
- this.serviceAttributes.lastMessageIds.shift();
41
- }
42
-
43
- return this;
44
- }
45
-
46
- getAttributes(): UserAttributes {
47
- return this.attributes;
48
- }
49
-
50
- get id(): number | undefined {
51
- return this.attributes.id;
52
- }
53
-
54
- get lastMessageIds(): number[] {
55
- return this.serviceAttributes.lastMessageIds;
56
- }
57
-
58
- get lastMessageId(): number | undefined {
59
- const ids = this.serviceAttributes.lastMessageIds;
60
- return ids.length ? ids[ids.length - 1] : undefined;
61
- }
62
-
63
- removeMessageId(messageId: number): this {
64
- const index = this.serviceAttributes.lastMessageIds.indexOf(messageId);
65
- if (index !== -1) {
66
- this.serviceAttributes.lastMessageIds.splice(index, 1);
67
- }
68
- return this;
69
- }
70
-
71
- static async existsOnServer(tgUsername: string, tgId: number): Promise<boolean> {
72
- // Здесь должен быть запрос к API, но мы оставим это для будущей реализации
73
- // const user = await api.fetch("user/get/" + tgUsername + "/" + tgId);
74
- // return !user.error;
75
- return false;
76
- }
77
-
78
- static async register(params: UserRegistrationData): Promise<UserModel> {
79
- // Здесь должен быть запрос к API, но мы оставим это для будущей реализации
80
- // let resApi = await api.fetch("user/register", "post", {
81
- // tg_username: params.tgUsername,
82
- // tg_id: params.tgId,
83
- // tg_first_name: params.tgFirstName,
84
- // tg_last_name: params.tgLastName,
85
- // user_refid: params.userRefid,
86
- // role: params.role || 'user',
87
- // language: params.language || 'en'
88
- // });
89
-
90
- // return UserModel.make(resApi.data);
91
- this.resolveDb();
92
-
93
- if (this.db && !this.exists('WHERE tg_id = ?', [params.tg_id])) {
94
- const result = this.run(
95
- `INSERT INTO ${this.tableName} (tg_id, tg_username, tg_first_name, tg_last_name, user_refid, role, language)
96
- VALUES (?, ?, ?, ?, ?, ?, ?)`,
97
- [
98
- params.tg_id,
99
- params.tg_username,
100
- params.tg_first_name,
101
- params.tg_last_name || null,
102
- params.user_refid || null,
103
- params.role || 'user',
104
- params.language || 'en',
105
- ]
106
- );
107
-
108
- if (!result || !result.lastInsertRowid) {
109
- throw new Error("Failed to register user in the database.");
110
- }
111
-
112
- return UserModel.make({
113
- id: result.lastInsertRowid as number,
114
- tg_id: params.tg_id,
115
- tg_username: params.tg_username,
116
- tg_first_name: params.tg_first_name,
117
- tg_last_name: params.tg_last_name,
118
- user_refid: params.user_refid,
119
- role: params.role || 'user',
120
- language: params.language || 'en',
121
- created_at: new Date().toISOString(),
122
- updated_at: new Date().toISOString()
123
- });
124
- }
125
-
126
- const user = this.findByUsername(params.tg_username);
127
-
128
- if (user) {
129
- return user;
130
- }
131
-
132
- throw new Error("Error not found user params:" + JSON.stringify(params));
133
- }
134
-
135
- static findByUsername(tgUsername: string): UserModel | undefined {
136
- if (this.db) {
137
- const userData = this.queryOne(`SELECT * FROM ${this.tableName} WHERE tg_username = ?`, [tgUsername]);
138
-
139
- if (userData) {
140
- return UserModel.make(userData);
141
- }
142
- } else {
143
- throw new Error("Database connection is not set.");
144
- }
145
-
146
- return undefined;
147
- }
148
-
149
- static async findOnServer(tgUsername: string): Promise<UserModel> {
150
- // Здесь должен быть запрос к API, но мы оставим это для будущей реализации
151
- // const user = await api.fetch("user/get/" + tgUsername);
152
- // return UserModel.make(user.data);
153
-
154
- const now = new Date().toISOString();
155
- return UserModel.make({
156
- tg_id: 0,
157
- tg_username: tgUsername,
158
- tg_first_name: tgUsername,
159
- role: 'user',
160
- language: 'en',
161
- created_at: now,
162
- updated_at: now
163
- });
164
- }
165
-
166
- async refresh(): Promise<boolean> {
167
- if (this.userSession) {
168
- return this.userSession.add(
169
- this.attributes.tg_username,
170
- await UserModel.findOnServer(this.attributes.tg_username)
171
- );
172
- }
173
- return false;
174
- }
175
-
176
- async refreshAttributes(): Promise<this> {
177
- this.attributes = (await UserModel.findOnServer(this.attributes.tg_username)).attributes;
178
- return this;
179
- }
180
-
181
- static make(attributes: UserAttributes): UserModel {
182
- return new UserModel(attributes);
183
- }
184
-
185
- static errorHandler(error: any, metaInfo?: any): void {
186
- if (error instanceof Error) {
187
- if (metaInfo) {
188
- console.error("Error addons:", metaInfo);
189
- }
190
-
191
- throw error;
192
- }
193
- }
194
-
195
- get username(): string {
196
- return this.attributes.tg_username;
197
- }
198
-
199
- get tgId(): number {
200
- return this.attributes.tg_id;
201
- }
202
-
203
- get firstName(): string {
204
- return this.attributes.tg_first_name;
205
- }
206
-
207
- get lastName(): string | undefined {
208
- return this.attributes.tg_last_name;
209
- }
210
-
211
- get fullName(): string {
212
- const firstName = this.attributes.tg_first_name || '';
213
- const lastName = this.attributes.tg_last_name || '';
214
- return `${firstName} ${lastName}`.trim();
215
- }
216
-
217
- get role(): 'user' | 'admin' {
218
- return this.attributes.role;
219
- }
220
-
221
- get language(): string {
222
- return this.attributes.language;
223
- }
224
-
225
- get isBannedByUser(): boolean {
226
- return this.attributes.is_banned_by_user || false;
227
- }
228
-
229
- get isBannedByAdmin(): boolean {
230
- return this.attributes.is_banned_by_admin || false;
231
- }
232
-
233
- get bannedReason(): string | undefined {
234
- return this.attributes.bunned_reason;
235
- }
236
-
237
- get userRefId(): number | undefined {
238
- return this.attributes.user_refid;
239
- }
240
-
241
- get createdAt(): string {
242
- return this.attributes.created_at;
243
- }
244
-
245
- get updatedAt(): string {
246
- return this.attributes.updated_at;
247
- }
248
-
249
- setRole(role: 'user' | 'admin'): this {
250
- this.attributes.role = role;
251
- return this;
252
- }
253
-
254
- setLanguage(language: string): this {
255
- this.attributes.language = language;
256
- return this;
257
- }
258
-
259
- banByAdmin(reason?: string): this {
260
- this.attributes.is_banned_by_admin = true;
261
- if (reason) {
262
- this.attributes.bunned_reason = reason;
263
- }
264
- return this;
265
- }
266
-
267
- unbanByAdmin(): this {
268
- this.attributes.is_banned_by_admin = false;
269
- this.attributes.bunned_reason = undefined;
270
- return this;
271
- }
272
-
273
- banByUser(): this {
274
- this.attributes.is_banned_by_user = true;
275
- return this;
276
- }
277
-
278
- unbanByUser(): this {
279
- this.attributes.is_banned_by_user = false;
280
- return this;
281
- }
282
-
283
- updateFirstName(firstName: string): this {
284
- this.attributes.tg_first_name = firstName;
285
- return this;
286
- }
287
-
288
- updateLastName(lastName: string): this {
289
- this.attributes.tg_last_name = lastName;
290
- return this;
291
- }
292
-
293
- updateUsername(username: string): this {
294
- this.attributes.tg_username = username;
295
- return this;
296
- }
297
- }
1
+ import { Model } from '../core/Model';
2
+ import { UserAttributes, UserRegistrationData, UserServiceAttributes } from '../types';
3
+ import { UserStore } from './UserStore';
4
+
5
+ export class UserModel extends Model {
6
+ static tableName = 'users';
7
+ attributes: UserAttributes;
8
+ serviceAttributes: UserServiceAttributes = {
9
+ lastActive: new Date(),
10
+ lastMessageIds: [],
11
+ };
12
+
13
+ private userSession: UserStore | null = null;
14
+
15
+ constructor(attributes: UserAttributes) {
16
+ super();
17
+ this.attributes = attributes;
18
+ }
19
+
20
+ static getAll(): UserModel[] {
21
+ const usersData = this.query(`SELECT * FROM ${this.tableName}`);
22
+ return usersData.map((data: any) => UserModel.make(data));
23
+ }
24
+
25
+ setSessionStorage(storage: UserStore): this {
26
+ this.userSession = storage;
27
+ return this;
28
+ }
29
+
30
+ upActive(): void {
31
+ this.serviceAttributes.lastActive = new Date();
32
+ }
33
+
34
+ storeMessageId(messageId: number, limit: number): this {
35
+ if (this.serviceAttributes.lastMessageIds.indexOf(messageId) === -1) {
36
+ this.serviceAttributes.lastMessageIds.push(messageId);
37
+ }
38
+
39
+ if (this.serviceAttributes.lastMessageIds.length > limit) {
40
+ this.serviceAttributes.lastMessageIds.shift();
41
+ }
42
+
43
+ return this;
44
+ }
45
+
46
+ getAttributes(): UserAttributes {
47
+ return this.attributes;
48
+ }
49
+
50
+ get id(): number | undefined {
51
+ return this.attributes.id;
52
+ }
53
+
54
+ get lastMessageIds(): number[] {
55
+ return this.serviceAttributes.lastMessageIds;
56
+ }
57
+
58
+ get lastMessageId(): number | undefined {
59
+ const ids = this.serviceAttributes.lastMessageIds;
60
+ return ids.length ? ids[ids.length - 1] : undefined;
61
+ }
62
+
63
+ removeMessageId(messageId: number): this {
64
+ const index = this.serviceAttributes.lastMessageIds.indexOf(messageId);
65
+ if (index !== -1) {
66
+ this.serviceAttributes.lastMessageIds.splice(index, 1);
67
+ }
68
+ return this;
69
+ }
70
+
71
+ static async existsOnServer(tgUsername: string, tgId: number): Promise<boolean> {
72
+ // Здесь должен быть запрос к API, но мы оставим это для будущей реализации
73
+ // const user = await api.fetch("user/get/" + tgUsername + "/" + tgId);
74
+ // return !user.error;
75
+ return false;
76
+ }
77
+
78
+ static async register(params: UserRegistrationData): Promise<UserModel> {
79
+ // Здесь должен быть запрос к API, но мы оставим это для будущей реализации
80
+ // let resApi = await api.fetch("user/register", "post", {
81
+ // tg_username: params.tgUsername,
82
+ // tg_id: params.tgId,
83
+ // tg_first_name: params.tgFirstName,
84
+ // tg_last_name: params.tgLastName,
85
+ // user_refid: params.userRefid,
86
+ // role: params.role || 'user',
87
+ // language: params.language || 'en'
88
+ // });
89
+
90
+ // return UserModel.make(resApi.data);
91
+ this.resolveDb();
92
+
93
+ if (this.db && !this.exists('WHERE tg_id = ?', [params.tg_id])) {
94
+ const result = this.run(
95
+ `INSERT INTO ${this.tableName} (tg_id, tg_username, tg_first_name, tg_last_name, user_refid, role, language)
96
+ VALUES (?, ?, ?, ?, ?, ?, ?)`,
97
+ [
98
+ params.tg_id,
99
+ params.tg_username,
100
+ params.tg_first_name,
101
+ params.tg_last_name || null,
102
+ params.user_refid || null,
103
+ params.role || 'user',
104
+ params.language || 'en',
105
+ ]
106
+ );
107
+
108
+ if (!result || !result.lastInsertRowid) {
109
+ throw new Error("Failed to register user in the database.");
110
+ }
111
+
112
+ return UserModel.make({
113
+ id: result.lastInsertRowid as number,
114
+ tg_id: params.tg_id,
115
+ tg_username: params.tg_username,
116
+ tg_first_name: params.tg_first_name,
117
+ tg_last_name: params.tg_last_name,
118
+ user_refid: params.user_refid,
119
+ role: params.role || 'user',
120
+ language: params.language || 'en',
121
+ created_at: new Date().toISOString(),
122
+ updated_at: new Date().toISOString()
123
+ });
124
+ }
125
+
126
+ const user = this.findByUsername(params.tg_username);
127
+
128
+ if (user) {
129
+ return user;
130
+ }
131
+
132
+ throw new Error("Error not found user params:" + JSON.stringify(params));
133
+ }
134
+
135
+ static findByUsername(tgUsername: string): UserModel | undefined {
136
+ if (this.db) {
137
+ const userData = this.queryOne(`SELECT * FROM ${this.tableName} WHERE tg_username = ?`, [tgUsername]);
138
+
139
+ if (userData) {
140
+ return UserModel.make(userData);
141
+ }
142
+ } else {
143
+ throw new Error("Database connection is not set.");
144
+ }
145
+
146
+ return undefined;
147
+ }
148
+
149
+ static async findOnServer(tgUsername: string): Promise<UserModel> {
150
+ // Здесь должен быть запрос к API, но мы оставим это для будущей реализации
151
+ // const user = await api.fetch("user/get/" + tgUsername);
152
+ // return UserModel.make(user.data);
153
+
154
+ const now = new Date().toISOString();
155
+ return UserModel.make({
156
+ tg_id: 0,
157
+ tg_username: tgUsername,
158
+ tg_first_name: tgUsername,
159
+ role: 'user',
160
+ language: 'en',
161
+ created_at: now,
162
+ updated_at: now
163
+ });
164
+ }
165
+
166
+ async refresh(): Promise<boolean> {
167
+ if (this.userSession) {
168
+ return this.userSession.add(
169
+ this.attributes.tg_username,
170
+ await UserModel.findOnServer(this.attributes.tg_username)
171
+ );
172
+ }
173
+ return false;
174
+ }
175
+
176
+ async refreshAttributes(): Promise<this> {
177
+ this.attributes = (await UserModel.findOnServer(this.attributes.tg_username)).attributes;
178
+ return this;
179
+ }
180
+
181
+ static make(attributes: UserAttributes): UserModel {
182
+ return new UserModel(attributes);
183
+ }
184
+
185
+ static errorHandler(error: any, metaInfo?: any): void {
186
+ if (error instanceof Error) {
187
+ if (metaInfo) {
188
+ console.error("Error addons:", metaInfo);
189
+ }
190
+
191
+ throw error;
192
+ }
193
+ }
194
+
195
+ get username(): string {
196
+ return this.attributes.tg_username;
197
+ }
198
+
199
+ get tgId(): number {
200
+ return this.attributes.tg_id;
201
+ }
202
+
203
+ get firstName(): string {
204
+ return this.attributes.tg_first_name;
205
+ }
206
+
207
+ get lastName(): string | undefined {
208
+ return this.attributes.tg_last_name;
209
+ }
210
+
211
+ get fullName(): string {
212
+ const firstName = this.attributes.tg_first_name || '';
213
+ const lastName = this.attributes.tg_last_name || '';
214
+ return `${firstName} ${lastName}`.trim();
215
+ }
216
+
217
+ get role(): 'user' | 'admin' {
218
+ return this.attributes.role;
219
+ }
220
+
221
+ get language(): string {
222
+ return this.attributes.language;
223
+ }
224
+
225
+ get isBannedByUser(): boolean {
226
+ return this.attributes.is_banned_by_user || false;
227
+ }
228
+
229
+ get isBannedByAdmin(): boolean {
230
+ return this.attributes.is_banned_by_admin || false;
231
+ }
232
+
233
+ get bannedReason(): string | undefined {
234
+ return this.attributes.bunned_reason;
235
+ }
236
+
237
+ get userRefId(): number | undefined {
238
+ return this.attributes.user_refid;
239
+ }
240
+
241
+ get createdAt(): string {
242
+ return this.attributes.created_at;
243
+ }
244
+
245
+ get updatedAt(): string {
246
+ return this.attributes.updated_at;
247
+ }
248
+
249
+ setRole(role: 'user' | 'admin'): this {
250
+ this.attributes.role = role;
251
+ return this;
252
+ }
253
+
254
+ setLanguage(language: string): this {
255
+ this.attributes.language = language;
256
+ return this;
257
+ }
258
+
259
+ banByAdmin(reason?: string): this {
260
+ this.attributes.is_banned_by_admin = true;
261
+ if (reason) {
262
+ this.attributes.bunned_reason = reason;
263
+ }
264
+ return this;
265
+ }
266
+
267
+ unbanByAdmin(): this {
268
+ this.attributes.is_banned_by_admin = false;
269
+ this.attributes.bunned_reason = undefined;
270
+ return this;
271
+ }
272
+
273
+ banByUser(): this {
274
+ this.attributes.is_banned_by_user = true;
275
+ return this;
276
+ }
277
+
278
+ unbanByUser(): this {
279
+ this.attributes.is_banned_by_user = false;
280
+ return this;
281
+ }
282
+
283
+ updateFirstName(firstName: string): this {
284
+ this.attributes.tg_first_name = firstName;
285
+ return this;
286
+ }
287
+
288
+ updateLastName(lastName: string): this {
289
+ this.attributes.tg_last_name = lastName;
290
+ return this;
291
+ }
292
+
293
+ updateUsername(username: string): this {
294
+ this.attributes.tg_username = username;
295
+ return this;
296
+ }
297
+ }