evogram-gramjs 1.0.3 → 1.1.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/.evogram/{7878190870 → 8539886557}/database.db +0 -0
- package/evogramjs.sqlite +0 -0
- package/lib/commands/AddAccount.command.d.ts +13 -0
- package/lib/commands/AddAccount.command.js +303 -12
- package/lib/commands/index.d.ts +2 -0
- package/lib/commands/index.js +4 -0
- package/lib/sessions/SessionAuth.d.ts +10 -0
- package/lib/sessions/SessionAuth.js +162 -0
- package/lib/test.d.ts +1 -0
- package/lib/test.js +144 -0
- package/package-lock.json +3938 -4
- package/package.json +4 -3
- package/qr-code-qr-auth-1769097743188.png +0 -0
- package/src/EvogramGramJS.ts +0 -98
- package/src/commands/Accounts.command.ts +0 -89
- package/src/commands/AddAccount.command.ts +0 -171
- package/src/commands/index.ts +0 -0
- package/src/commands/managment/DeleteAccount.command.ts +0 -13
- package/src/config/database.config.ts +0 -75
- package/src/entities/Session.entity.ts +0 -58
- package/src/entities/SessionEventLog.entity.ts +0 -41
- package/src/index.ts +0 -7
- package/src/services/DatabaseService.ts +0 -82
- package/src/services/ImageUploadService.ts +0 -49
- package/src/sessions/Session.ts +0 -21
- package/src/sessions/SessionAuth.ts +0 -173
- package/src/sessions/SessionLogger.ts +0 -208
- package/src/sessions/SessionManager.ts +0 -211
- package/src/types/auth.types.ts +0 -94
- package/src/types/session.types.ts +0 -96
- package/src/utils/Deferrer.ts +0 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "evogram-gramjs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"main": "./lib/index.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"dependencies": {
|
|
@@ -12,13 +12,14 @@
|
|
|
12
12
|
"typeorm": "^0.3.20"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"evogram": "^2.10.4",
|
|
16
15
|
"telegram": "^2.26.22"
|
|
17
16
|
},
|
|
18
17
|
"devDependencies": {
|
|
19
18
|
"@types/lodash": "^4.17.21",
|
|
20
19
|
"@types/node": "^24.3.0",
|
|
21
|
-
"
|
|
20
|
+
"@types/qrcode": "^1.5.6",
|
|
21
|
+
"evogram": "2.10.4",
|
|
22
|
+
"qrcode": "^1.5.4",
|
|
22
23
|
"telegram": "^2.26.22"
|
|
23
24
|
},
|
|
24
25
|
"optionalDependencies": {
|
|
Binary file
|
package/src/EvogramGramJS.ts
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { DatabaseConfig } from './config/database.config'
|
|
2
|
-
import { DatabaseService } from './services/DatabaseService'
|
|
3
|
-
import { SessionManager } from './sessions/SessionManager'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Главный статический класс для работы с EvogramGramJS
|
|
7
|
-
* Управляет сессиями Telegram и базой данных
|
|
8
|
-
*/
|
|
9
|
-
export class EvogramGramJS {
|
|
10
|
-
private static _sessionManager: SessionManager | null = null
|
|
11
|
-
private static _databaseService: DatabaseService | null = null
|
|
12
|
-
private static _telegramAppId: number | null = null
|
|
13
|
-
private static _telegramAppHash: string | null = null
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Инициализирует EvogramGramJS
|
|
17
|
-
*
|
|
18
|
-
* @param telegramAppId API ID из Telegram
|
|
19
|
-
* @param telegramAppHash API Hash из Telegram
|
|
20
|
-
* @param databaseConfig Конфигурация базы данных (опционально)
|
|
21
|
-
*/
|
|
22
|
-
static initialize(telegramAppId: number, telegramAppHash: string, databaseConfig?: DatabaseConfig): void {
|
|
23
|
-
this._telegramAppId = telegramAppId
|
|
24
|
-
this._telegramAppHash = telegramAppHash
|
|
25
|
-
|
|
26
|
-
// Инициализируем сервис базы данных
|
|
27
|
-
this._databaseService = new DatabaseService()
|
|
28
|
-
|
|
29
|
-
// Инициализируем менеджер сессий с поддержкой БД
|
|
30
|
-
this._sessionManager = new SessionManager(telegramAppId, telegramAppHash, this._databaseService)
|
|
31
|
-
|
|
32
|
-
// Инициализируем базу данных асинхронно
|
|
33
|
-
if (databaseConfig) {
|
|
34
|
-
this._databaseService
|
|
35
|
-
.initialize(databaseConfig)
|
|
36
|
-
.then(async () => {
|
|
37
|
-
// Автоматически загружаем сессии из базы данных после инициализации
|
|
38
|
-
if (this._sessionManager) await this._sessionManager.initialize()
|
|
39
|
-
})
|
|
40
|
-
.catch((error) => {
|
|
41
|
-
console.error('Ошибка инициализации базы данных:', error)
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Получает менеджер сессий
|
|
48
|
-
*
|
|
49
|
-
* @returns SessionManager
|
|
50
|
-
* @throws Error если EvogramGramJS не инициализирован
|
|
51
|
-
*/
|
|
52
|
-
static get sessionManager(): SessionManager {
|
|
53
|
-
if (!this._sessionManager) throw new Error('EvogramGramJS не инициализирован. Вызовите EvogramGramJS.initialize() сначала.')
|
|
54
|
-
|
|
55
|
-
return this._sessionManager
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Получает сервис базы данных
|
|
60
|
-
*
|
|
61
|
-
* @returns DatabaseService
|
|
62
|
-
* @throws Error если EvogramGramJS не инициализирован
|
|
63
|
-
*/
|
|
64
|
-
static get databaseService(): DatabaseService {
|
|
65
|
-
if (!this._databaseService) throw new Error('EvogramGramJS не инициализирован. Вызовите EvogramGramJS.initialize() сначала.')
|
|
66
|
-
|
|
67
|
-
return this._databaseService
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Инициализирует базу данных
|
|
72
|
-
*
|
|
73
|
-
* @param config Конфигурация базы данных
|
|
74
|
-
*/
|
|
75
|
-
static async initializeDatabase(config: DatabaseConfig): Promise<void> {
|
|
76
|
-
if (!this._databaseService) throw new Error('EvogramGramJS не инициализирован. Вызовите EvogramGramJS.initialize() сначала.')
|
|
77
|
-
await this._databaseService.initialize(config)
|
|
78
|
-
|
|
79
|
-
// Автоматически загружаем сессии из базы данных после инициализации
|
|
80
|
-
if (this._sessionManager) await this._sessionManager.initialize()
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Закрывает подключение к базе данных
|
|
85
|
-
*/
|
|
86
|
-
static async closeDatabase(): Promise<void> {
|
|
87
|
-
if (this._databaseService) await this._databaseService.close()
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Проверяет, инициализирован ли EvogramGramJS
|
|
92
|
-
*
|
|
93
|
-
* @returns true, если инициализирован
|
|
94
|
-
*/
|
|
95
|
-
static isInitialized(): boolean {
|
|
96
|
-
return this._sessionManager !== null && this._databaseService !== null
|
|
97
|
-
}
|
|
98
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { Command, CommandArgument, CommandContext, CommandD, CommandUpdate, InlineQueryContext, MessageContext, Pagination } from 'evogram'
|
|
2
|
-
import { EvogramGramJS } from '../EvogramGramJS'
|
|
3
|
-
import { AddAccountCommand } from './AddAccount.command'
|
|
4
|
-
|
|
5
|
-
@CommandD({ name: 'accounts', backButton: 'Главное меню' })
|
|
6
|
-
export class AccountsCommand extends Command {
|
|
7
|
-
public async execute(context: CommandContext, @CommandArgument('sessionId?') sessionId?: string, @CommandArgument('page?') page?: number) {
|
|
8
|
-
if (!sessionId) {
|
|
9
|
-
const sessions = await EvogramGramJS.sessionManager.getAllLoadedSessions()
|
|
10
|
-
|
|
11
|
-
//@ts-ignore
|
|
12
|
-
return context[context.callbackQuery ? 'edit' : 'send']?.({
|
|
13
|
-
// prettier-ignore
|
|
14
|
-
text:
|
|
15
|
-
'<blockquote><b>📊 Список аккаунтов</b></blockquote>\n\n' +
|
|
16
|
-
|
|
17
|
-
'<i>Панель управлениями Вашими аккаунтами</i>',
|
|
18
|
-
parse_mode: 'HTML',
|
|
19
|
-
reply_markup: {
|
|
20
|
-
inline_keyboard: [
|
|
21
|
-
[
|
|
22
|
-
{ text: '📋 Список аккаунтов', switch_inline_query_current_chat: ' ', command: AccountsCommand },
|
|
23
|
-
{ text: '➕ Добавить аккаунт', command: AddAccountCommand },
|
|
24
|
-
],
|
|
25
|
-
...sessions.slice((Number(page) || 0) * 10, (Number(page) || 0) * 10 + 10).map((x) => [{ text: `[${x.db?.error ? '❌' : '✅'}] ${x.db?.firstName || x.db?.username || 'Безымянный'}`, command: AccountsCommand, payload: { sessionId: x.sessionId } }]),
|
|
26
|
-
Pagination({ pages: Math.ceil(sessions.length / 10), currentPage: Number(page) || 0, command: AccountsCommand }),
|
|
27
|
-
],
|
|
28
|
-
},
|
|
29
|
-
})
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const session = EvogramGramJS.sessionManager.getSession(sessionId)
|
|
33
|
-
const db = await session?.db()
|
|
34
|
-
const me = await session?.client
|
|
35
|
-
.getMe()
|
|
36
|
-
.then((x) => x)
|
|
37
|
-
.catch(() => null)
|
|
38
|
-
|
|
39
|
-
//@ts-ignore
|
|
40
|
-
return context[context.callbackQuery ? 'edit' : 'send']?.({
|
|
41
|
-
// prettier-ignore
|
|
42
|
-
text:
|
|
43
|
-
`<blockquote><b>👤 Аккаунт <a href="tg://user?id=${db?.userId}">${db?.firstName}</a></b></blockquote>\n\n` +
|
|
44
|
-
|
|
45
|
-
`<i>— ID: ${db?.userId}</i>\n` +
|
|
46
|
-
`<i>— Phone: ${db?.phoneNumber}</i>\n\n` +
|
|
47
|
-
|
|
48
|
-
`<b>${me ? '✅ Активен и доступен к работе' : db?.error ? `❌ ${db?.error}` : '❌ Неавторизованный'}</b>`,
|
|
49
|
-
parse_mode: 'HTML',
|
|
50
|
-
})
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
@CommandUpdate('message')
|
|
54
|
-
public async handleMessage(context: CommandContext, message: MessageContext) {
|
|
55
|
-
if (!message.viaBot) return
|
|
56
|
-
|
|
57
|
-
message.delete().catch(() => null)
|
|
58
|
-
return context.redirect(AccountsCommand, { sessionId: message.text })
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
public async inlineExecute(context: InlineQueryContext) {
|
|
62
|
-
const accounts = EvogramGramJS.sessionManager.getAllSessions()
|
|
63
|
-
|
|
64
|
-
context.answer(
|
|
65
|
-
await Promise.all(
|
|
66
|
-
accounts.map(async (x) => {
|
|
67
|
-
const db = await x.db()
|
|
68
|
-
|
|
69
|
-
return {
|
|
70
|
-
type: 'article',
|
|
71
|
-
id: x.sessionId,
|
|
72
|
-
title: db ? `${db?.firstName} ${db?.lastName || ''}` : 'Безымянный',
|
|
73
|
-
description: db?.error ? `❌ ${db?.error}` : db ? '✅ Аккаунт активен' : '❌ Неавторизованный',
|
|
74
|
-
thumbnail_url: db?.avatarUrl || undefined,
|
|
75
|
-
input_message_content: {
|
|
76
|
-
message_text: x.sessionId,
|
|
77
|
-
},
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
),
|
|
81
|
-
{
|
|
82
|
-
switch_pm_text: accounts.length > 0 ? `Добавлено ${accounts.length} аккаунтов` : 'Нет доступных аккаунтов',
|
|
83
|
-
switch_pm_parameter: 'accounts',
|
|
84
|
-
cache_time: 0,
|
|
85
|
-
is_personal: true,
|
|
86
|
-
}
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
}
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { Command, CommandContext, CommandD, CommandStorageArgument, CommandUpdate, MessageContext } from 'evogram'
|
|
2
|
-
import { EvogramGramJS } from '../EvogramGramJS'
|
|
3
|
-
import { AuthState } from '../types/auth.types'
|
|
4
|
-
|
|
5
|
-
@CommandD({ name: 'addaccount', argsMethod: 'parameterized', backButton: 'Список аккаунтов' })
|
|
6
|
-
export class AddAccountCommand extends Command {
|
|
7
|
-
public async execute(
|
|
8
|
-
context: CommandContext,
|
|
9
|
-
@CommandStorageArgument('phone', async ({ context, value }) => {
|
|
10
|
-
if (value) {
|
|
11
|
-
if (!(await context.storage.get('session'))) {
|
|
12
|
-
const session = await EvogramGramJS.sessionManager.addSession({
|
|
13
|
-
sessionId: value,
|
|
14
|
-
logging: {
|
|
15
|
-
enabled: true,
|
|
16
|
-
logsDirectory: './logs',
|
|
17
|
-
},
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
const result = await session.auth.start(value)
|
|
21
|
-
if (result.success) {
|
|
22
|
-
await context.storage.set('stage', 'code')
|
|
23
|
-
await context.storage.set('session', session.sessionId)
|
|
24
|
-
|
|
25
|
-
return value
|
|
26
|
-
} else {
|
|
27
|
-
context.state.command = undefined
|
|
28
|
-
await context.storage.clearAll()
|
|
29
|
-
|
|
30
|
-
//@ts-ignore
|
|
31
|
-
context[context.callbackQuery ? 'edit' : 'send']?.({
|
|
32
|
-
// prettier-ignore
|
|
33
|
-
text:
|
|
34
|
-
'<blockquote><b>❗️Произошла ошибка при добавлении аккаунта</b></blockquote>\n\n' +
|
|
35
|
-
|
|
36
|
-
result.error,
|
|
37
|
-
parse_mode: 'HTML',
|
|
38
|
-
})
|
|
39
|
-
}
|
|
40
|
-
} else return value
|
|
41
|
-
} else {
|
|
42
|
-
//@ts-ignore
|
|
43
|
-
context[context.callbackQuery ? 'edit' : 'send']?.({
|
|
44
|
-
// prettier-ignore
|
|
45
|
-
text:
|
|
46
|
-
'<blockquote><b>➕ Добавление аккаунта</b></blockquote>\n\n' +
|
|
47
|
-
|
|
48
|
-
'<i>Отправьте номер телефона в следующем сообщении</i>',
|
|
49
|
-
parse_mode: 'HTML',
|
|
50
|
-
})
|
|
51
|
-
}
|
|
52
|
-
})
|
|
53
|
-
phone: string,
|
|
54
|
-
@CommandStorageArgument('code', async ({ context, value }) => {
|
|
55
|
-
if (value) {
|
|
56
|
-
const session = EvogramGramJS.sessionManager.getSession(await context.storage.get('session'))!
|
|
57
|
-
if (session.auth.state?.stage !== AuthState.WAITING_CODE) return value
|
|
58
|
-
|
|
59
|
-
const result = await session.auth.setCode(value)
|
|
60
|
-
|
|
61
|
-
if (result.success) {
|
|
62
|
-
await context.storage.set('stage', 'password')
|
|
63
|
-
return value
|
|
64
|
-
} else {
|
|
65
|
-
//@ts-ignore
|
|
66
|
-
context[context.callbackQuery ? 'edit' : 'send']?.({
|
|
67
|
-
// prettier-ignore
|
|
68
|
-
text:
|
|
69
|
-
'<blockquote><b>➕ Добавление аккаунта</b></blockquote>\n\n' +
|
|
70
|
-
|
|
71
|
-
'<i>Отправьте код подтверждения, отправленный на аккаунт, в следующем сообщении</i>\n\n' +
|
|
72
|
-
|
|
73
|
-
`<blockquote><b>❗️Произошла ошибка</b></blockquote>\n\n` +
|
|
74
|
-
|
|
75
|
-
result.error,
|
|
76
|
-
parse_mode: 'HTML',
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
return null
|
|
80
|
-
}
|
|
81
|
-
} else {
|
|
82
|
-
//@ts-ignore
|
|
83
|
-
context[context.callbackQuery ? 'edit' : 'send']?.({
|
|
84
|
-
// prettier-ignore
|
|
85
|
-
text:
|
|
86
|
-
'<blockquote><b>➕ Добавление аккаунта</b></blockquote>\n\n' +
|
|
87
|
-
|
|
88
|
-
'<i>Отправьте код подтверждения, отправленный на аккаунт, в следующем сообщении</i>',
|
|
89
|
-
parse_mode: 'HTML',
|
|
90
|
-
})
|
|
91
|
-
}
|
|
92
|
-
})
|
|
93
|
-
code: string,
|
|
94
|
-
@CommandStorageArgument('password', async ({ context, value }) => {
|
|
95
|
-
const session = EvogramGramJS.sessionManager.getSession(await context.storage.get('session'))!
|
|
96
|
-
|
|
97
|
-
const isRequired = await session.auth.isRequiredPassword()
|
|
98
|
-
if (!isRequired || value === 'none') return 'none'
|
|
99
|
-
|
|
100
|
-
if (value) {
|
|
101
|
-
const session = EvogramGramJS.sessionManager.getSession(await context.storage.get('session'))!
|
|
102
|
-
const result = await session.auth.setPassword(value)
|
|
103
|
-
|
|
104
|
-
if (result.success) {
|
|
105
|
-
return value
|
|
106
|
-
} else {
|
|
107
|
-
//@ts-ignore
|
|
108
|
-
context[context.callbackQuery ? 'edit' : 'send']?.({
|
|
109
|
-
// prettier-ignore
|
|
110
|
-
text:
|
|
111
|
-
'<blockquote><b>➕ Добавление аккаунта</b></blockquote>\n\n' +
|
|
112
|
-
|
|
113
|
-
'<i>На аккаунте включен 2FA. Отправьте пароль для 2FA в следующем сообщении</i>\n\n' +
|
|
114
|
-
|
|
115
|
-
`<blockquote><b>❗️Произошла ошибка</b></blockquote>\n\n` +
|
|
116
|
-
|
|
117
|
-
result.error,
|
|
118
|
-
parse_mode: 'HTML',
|
|
119
|
-
})
|
|
120
|
-
}
|
|
121
|
-
} else {
|
|
122
|
-
//@ts-ignore
|
|
123
|
-
context[context.callbackQuery ? 'edit' : 'send']?.({
|
|
124
|
-
// prettier-ignore
|
|
125
|
-
text:
|
|
126
|
-
'<blockquote><b>➕ Добавление аккаунта</b></blockquote>\n\n' +
|
|
127
|
-
|
|
128
|
-
'<i>На аккаунте включен 2FA. Отправьте пароль для 2FA в следующем сообщении</i>',
|
|
129
|
-
parse_mode: 'HTML',
|
|
130
|
-
})
|
|
131
|
-
}
|
|
132
|
-
})
|
|
133
|
-
password: string
|
|
134
|
-
) {
|
|
135
|
-
const session = EvogramGramJS.sessionManager.getSession(await context.storage.get('session'))!
|
|
136
|
-
|
|
137
|
-
context.send(
|
|
138
|
-
`Вы успешно добавили аккаунт ${await session.client
|
|
139
|
-
.getMe()
|
|
140
|
-
.then((user) => user.username)
|
|
141
|
-
.catch(() => 'unknown')}`
|
|
142
|
-
)
|
|
143
|
-
await context.storage.clearAll()
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
@CommandUpdate('message')
|
|
147
|
-
async handleMessage(context: CommandContext, message: MessageContext) {
|
|
148
|
-
if (!message?.text) return
|
|
149
|
-
|
|
150
|
-
console.log({ session: await context.storage.get('session'), phone: await context.storage.get('phone'), code: await context.storage.get('code'), password: await context.storage.get('password'), command: context.state.command, stage: await context.storage.get('stage') })
|
|
151
|
-
|
|
152
|
-
await context.edit('⏳').catch(() => {})
|
|
153
|
-
await message.delete().catch(() => {})
|
|
154
|
-
|
|
155
|
-
if (!(await context.storage.get('phone'))) context.redirect(AddAccountCommand, { phone: message.text })
|
|
156
|
-
else if ((await context.storage.get('stage')) === 'code') context.redirect(AddAccountCommand, { code: message.text })
|
|
157
|
-
else if ((await context.storage.get('stage')) === 'password') context.redirect(AddAccountCommand, { password: message.text })
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
onError(context: CommandContext, error: Error) {
|
|
161
|
-
//@ts-ignore
|
|
162
|
-
context[context.callbackQuery ? 'edit' : 'send']?.({
|
|
163
|
-
// prettier-ignore
|
|
164
|
-
text:
|
|
165
|
-
'<blockquote><b>❗️Произошла ошибка при добавлении аккаунта</b></blockquote>\n\n' +
|
|
166
|
-
|
|
167
|
-
error.message,
|
|
168
|
-
parse_mode: 'HTML',
|
|
169
|
-
})
|
|
170
|
-
}
|
|
171
|
-
}
|
package/src/commands/index.ts
DELETED
|
File without changes
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// import { Command, CommandArgument, CommandContext, CommandD } from 'evogram'
|
|
2
|
-
// import { EvogramGramJS } from '../../EvogramGramJS'
|
|
3
|
-
|
|
4
|
-
// @CommandD({ name: 'deleteaccount', argsMethod: 'parameterized' })
|
|
5
|
-
// export class DeleteAccountCommand extends Command {
|
|
6
|
-
// public async execute(context: CommandContext, @CommandArgument('sessionId') sessionId: string) {
|
|
7
|
-
// const session = EvogramGramJS.sessionManager.getSession(sessionId)
|
|
8
|
-
// if (!session) return context.send('Сессия не найдена')
|
|
9
|
-
|
|
10
|
-
// await EvogramGramJS.databaseService.deleteSession(sessionId)
|
|
11
|
-
// return context.send('Сессия успешно удалена')
|
|
12
|
-
// }
|
|
13
|
-
// }
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { DataSourceOptions } from 'typeorm'
|
|
2
|
-
import { Session } from '../entities/Session.entity'
|
|
3
|
-
import { SessionEventLog } from '../entities/SessionEventLog.entity'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Конфигурация базы данных
|
|
7
|
-
*/
|
|
8
|
-
export interface DatabaseConfig {
|
|
9
|
-
/** Тип базы данных */
|
|
10
|
-
type?: 'sqlite' | 'postgres' | 'mysql' | 'mariadb'
|
|
11
|
-
/** Путь к файлу БД (для SQLite) или строка подключения */
|
|
12
|
-
database?: string
|
|
13
|
-
/** Хост БД (для PostgreSQL/MySQL) */
|
|
14
|
-
host?: string
|
|
15
|
-
/** Порт БД (для PostgreSQL/MySQL) */
|
|
16
|
-
port?: number
|
|
17
|
-
/** Имя пользователя БД */
|
|
18
|
-
username?: string
|
|
19
|
-
/** Пароль БД */
|
|
20
|
-
password?: string
|
|
21
|
-
/** Включить синхронизацию схемы (только для разработки) */
|
|
22
|
-
synchronize?: boolean
|
|
23
|
-
/** Включить логирование SQL запросов */
|
|
24
|
-
logging?: boolean
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Создает конфигурацию DataSource для TypeORM
|
|
29
|
-
*/
|
|
30
|
-
export function createDataSourceOptions(config: DatabaseConfig = {}): DataSourceOptions {
|
|
31
|
-
const { type = 'sqlite', database = './data/evogram.db', host, port, username, password, synchronize = false, logging = false } = config
|
|
32
|
-
|
|
33
|
-
const baseOptions: DataSourceOptions = {
|
|
34
|
-
type: type as any,
|
|
35
|
-
entities: [Session, SessionEventLog],
|
|
36
|
-
synchronize,
|
|
37
|
-
logging,
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (type === 'sqlite') {
|
|
41
|
-
// Для SQLite используем специальную конфигурацию
|
|
42
|
-
const sqliteOptions: any = {
|
|
43
|
-
...baseOptions,
|
|
44
|
-
type: 'better-sqlite3',
|
|
45
|
-
database,
|
|
46
|
-
}
|
|
47
|
-
return sqliteOptions as DataSourceOptions
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (type === 'postgres') {
|
|
51
|
-
return {
|
|
52
|
-
...baseOptions,
|
|
53
|
-
type: 'postgres',
|
|
54
|
-
host: host || 'localhost',
|
|
55
|
-
port: port || 5432,
|
|
56
|
-
username,
|
|
57
|
-
password,
|
|
58
|
-
database: database || 'evogram',
|
|
59
|
-
} as DataSourceOptions
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (type === 'mysql' || type === 'mariadb') {
|
|
63
|
-
return {
|
|
64
|
-
...baseOptions,
|
|
65
|
-
type: type === 'mariadb' ? 'mariadb' : 'mysql',
|
|
66
|
-
host: host || 'localhost',
|
|
67
|
-
port: port || 3306,
|
|
68
|
-
username,
|
|
69
|
-
password,
|
|
70
|
-
database: database || 'evogram',
|
|
71
|
-
} as DataSourceOptions
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return baseOptions
|
|
75
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { Column, CreateDateColumn, Entity, OneToMany, PrimaryColumn } from 'typeorm'
|
|
2
|
-
import { SessionEventLog } from './SessionEventLog.entity'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Сущность сессии Telegram в базе данных
|
|
6
|
-
*/
|
|
7
|
-
@Entity('sessions')
|
|
8
|
-
export class Session {
|
|
9
|
-
/** Уникальный идентификатор сессии */
|
|
10
|
-
@PrimaryColumn({ type: 'varchar', length: 255 })
|
|
11
|
-
sessionId!: string
|
|
12
|
-
|
|
13
|
-
/** API ID из Telegram */
|
|
14
|
-
@Column({ type: 'integer', nullable: true })
|
|
15
|
-
apiId?: number
|
|
16
|
-
|
|
17
|
-
/** API Hash из Telegram */
|
|
18
|
-
@Column({ type: 'varchar', length: 255, nullable: true })
|
|
19
|
-
apiHash?: string
|
|
20
|
-
|
|
21
|
-
@Column({ type: 'bigint' })
|
|
22
|
-
userId!: number
|
|
23
|
-
|
|
24
|
-
@Column({ type: 'varchar', length: 255, nullable: true })
|
|
25
|
-
username?: string
|
|
26
|
-
|
|
27
|
-
@Column({ type: 'varchar', length: 255, nullable: true })
|
|
28
|
-
firstName?: string
|
|
29
|
-
|
|
30
|
-
@Column({ type: 'varchar', length: 255, nullable: true })
|
|
31
|
-
lastName?: string
|
|
32
|
-
|
|
33
|
-
@Column({ type: 'varchar', length: 255, nullable: true })
|
|
34
|
-
phoneNumber?: string
|
|
35
|
-
|
|
36
|
-
@Column({ type: 'text', nullable: true })
|
|
37
|
-
error?: string
|
|
38
|
-
|
|
39
|
-
/** Строка сессии (зашифрованная) */
|
|
40
|
-
@Column({ type: 'text', nullable: true })
|
|
41
|
-
sessionString?: string
|
|
42
|
-
|
|
43
|
-
/** Дополнительные опции клиента (JSON) */
|
|
44
|
-
@Column({ type: 'text', nullable: true })
|
|
45
|
-
clientOptions?: string
|
|
46
|
-
|
|
47
|
-
/** URL аватарки пользователя */
|
|
48
|
-
@Column({ type: 'varchar', length: 500, nullable: true })
|
|
49
|
-
avatarUrl?: string
|
|
50
|
-
|
|
51
|
-
/** Связанные события сессии */
|
|
52
|
-
@OneToMany(() => SessionEventLog, (eventLog) => eventLog.session, { cascade: true })
|
|
53
|
-
eventLogs!: SessionEventLog[]
|
|
54
|
-
|
|
55
|
-
/** Время создания сессии */
|
|
56
|
-
@CreateDateColumn()
|
|
57
|
-
createdAt!: Date
|
|
58
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'
|
|
2
|
-
import { Session } from './Session.entity'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Сущность для логирования событий сессии
|
|
6
|
-
*/
|
|
7
|
-
@Entity('session_event_logs')
|
|
8
|
-
export class SessionEventLog {
|
|
9
|
-
/** Уникальный идентификатор записи */
|
|
10
|
-
@PrimaryGeneratedColumn()
|
|
11
|
-
id!: number
|
|
12
|
-
|
|
13
|
-
/** Идентификатор сессии */
|
|
14
|
-
@Column({ type: 'varchar', length: 255 })
|
|
15
|
-
sessionId!: string
|
|
16
|
-
|
|
17
|
-
/** Тип события */
|
|
18
|
-
@Column({ type: 'varchar', length: 100 })
|
|
19
|
-
eventType!: string
|
|
20
|
-
|
|
21
|
-
/** Уровень логирования */
|
|
22
|
-
@Column({ type: 'varchar', length: 20, default: 'INFO' })
|
|
23
|
-
level!: string
|
|
24
|
-
|
|
25
|
-
/** Сообщение события */
|
|
26
|
-
@Column({ type: 'text' })
|
|
27
|
-
message!: string
|
|
28
|
-
|
|
29
|
-
/** Дополнительные данные события (JSON) */
|
|
30
|
-
@Column({ type: 'text', nullable: true })
|
|
31
|
-
data?: string
|
|
32
|
-
|
|
33
|
-
/** Время создания события */
|
|
34
|
-
@CreateDateColumn()
|
|
35
|
-
createdAt!: Date
|
|
36
|
-
|
|
37
|
-
/** Связь с сессией */
|
|
38
|
-
@ManyToOne(() => Session, (session) => session.eventLogs, { onDelete: 'CASCADE' })
|
|
39
|
-
@JoinColumn({ name: 'sessionId' })
|
|
40
|
-
session!: Session
|
|
41
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export * from './EvogramGramJS'
|
|
2
|
-
export * from './config/database.config'
|
|
3
|
-
export * from './entities/Session.entity'
|
|
4
|
-
export * from './entities/SessionEventLog.entity'
|
|
5
|
-
export * from './services/DatabaseService'
|
|
6
|
-
export * from './types/auth.types'
|
|
7
|
-
export * from './types/session.types'
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { DataSource, Repository } from 'typeorm'
|
|
2
|
-
import { DatabaseConfig, createDataSourceOptions } from '../config/database.config'
|
|
3
|
-
import { Session as SessionEntity } from '../entities/Session.entity'
|
|
4
|
-
import { SessionEventLog } from '../entities/SessionEventLog.entity'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Сервис для работы с базой данных
|
|
8
|
-
* Управляет сохранением и загрузкой сессий и их событий
|
|
9
|
-
*/
|
|
10
|
-
export class DatabaseService {
|
|
11
|
-
private dataSource!: DataSource
|
|
12
|
-
private sessionRepository!: Repository<SessionEntity>
|
|
13
|
-
private eventLogRepository!: Repository<SessionEventLog>
|
|
14
|
-
private isInitialized: boolean = false
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Инициализирует подключение к базе данных
|
|
18
|
-
*
|
|
19
|
-
* @param config Конфигурация базы данных
|
|
20
|
-
*/
|
|
21
|
-
async initialize(config: DatabaseConfig = {}): Promise<void> {
|
|
22
|
-
if (this.isInitialized) return
|
|
23
|
-
|
|
24
|
-
const options = createDataSourceOptions(config)
|
|
25
|
-
this.dataSource = new DataSource(options)
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
await this.dataSource.initialize()
|
|
29
|
-
this.sessionRepository = this.dataSource.getRepository(SessionEntity)
|
|
30
|
-
this.eventLogRepository = this.dataSource.getRepository(SessionEventLog)
|
|
31
|
-
this.isInitialized = true
|
|
32
|
-
} catch (error) {
|
|
33
|
-
console.error('Ошибка инициализации базы данных:', error)
|
|
34
|
-
throw error
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async saveSession(session: Partial<SessionEntity>) {
|
|
39
|
-
if (!this.isReady()) throw new Error('База данных не инициализирована')
|
|
40
|
-
|
|
41
|
-
const existingSession = await this.sessionRepository.findOne({ where: { sessionId: session.sessionId } })
|
|
42
|
-
|
|
43
|
-
if (existingSession) await this.sessionRepository.update({ sessionId: existingSession.sessionId }, session)
|
|
44
|
-
else await this.sessionRepository.save(session)
|
|
45
|
-
|
|
46
|
-
return this.getSession(session.sessionId!)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async updateSession(sessionId: string, session: Partial<SessionEntity>) {
|
|
50
|
-
if (!this.isReady()) throw new Error('База данных не инициализирована')
|
|
51
|
-
await this.sessionRepository.update({ sessionId }, session)
|
|
52
|
-
|
|
53
|
-
return this.getSession(sessionId)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async getSession(sessionId: string) {
|
|
57
|
-
if (!this.isReady()) throw new Error('База данных не инициализирована')
|
|
58
|
-
return await this.sessionRepository.findOne({ where: { sessionId } })
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async getSessions() {
|
|
62
|
-
if (!this.isReady()) throw new Error('База данных не инициализирована')
|
|
63
|
-
return await this.sessionRepository.find({ order: { createdAt: 'DESC' } })
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Закрывает подключение к базе данных
|
|
68
|
-
*/
|
|
69
|
-
async close(): Promise<void> {
|
|
70
|
-
if (this.dataSource && this.dataSource.isInitialized) {
|
|
71
|
-
await this.dataSource.destroy()
|
|
72
|
-
this.isInitialized = false
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Проверяет, инициализирована ли база данных
|
|
78
|
-
*/
|
|
79
|
-
isReady(): boolean {
|
|
80
|
-
return this.isInitialized && this.dataSource?.isInitialized
|
|
81
|
-
}
|
|
82
|
-
}
|