qwen-api-proxy 1.0.10

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.
@@ -0,0 +1,255 @@
1
+ import { ProxyAgent } from 'proxy-agent';
2
+ import { TELEGRAM_PROXY, QWEN_PROXY, FILE_DOWNLOAD_PROXY } from '../config.js';
3
+ import { logInfo, logWarn, logDebug } from '../logger/index.js';
4
+
5
+ // Кэш прокси агентов (создаются один раз)
6
+ let telegramProxyAgent = null;
7
+ let qwenProxyAgent = null;
8
+ let fileDownloadProxyAgent = null;
9
+ let telegramProxyInitialized = false;
10
+ let qwenProxyInitialized = false;
11
+ let fileDownloadProxyInitialized = false;
12
+
13
+ /**
14
+ * Получить ProxyAgent для Telegram
15
+ * Агент кэшируется для повторного использования
16
+ * @returns {ProxyAgent|null} - ProxyAgent или null если прокси не настроен
17
+ */
18
+ function getTelegramProxyAgent() {
19
+ if (telegramProxyInitialized) {
20
+ return telegramProxyAgent;
21
+ }
22
+
23
+ if (!TELEGRAM_PROXY) {
24
+ telegramProxyInitialized = true;
25
+ telegramProxyAgent = null;
26
+ return null;
27
+ }
28
+
29
+ try {
30
+ logInfo(`📱 Инициализация прокси для Telegram: ${maskProxyUrl(TELEGRAM_PROXY)}`);
31
+ telegramProxyAgent = new ProxyAgent(TELEGRAM_PROXY);
32
+ telegramProxyInitialized = true;
33
+ logInfo('✅ Прокси для Telegram успешно инициализирован');
34
+ return telegramProxyAgent;
35
+ } catch (error) {
36
+ logWarn(`❌ Ошибка инициализации прокси для Telegram: ${error.message}`);
37
+ telegramProxyInitialized = true;
38
+ telegramProxyAgent = null;
39
+ return null;
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Получить ProxyAgent для Qwen LLM
45
+ * Агент кэшируется для повторного использования
46
+ * @returns {ProxyAgent|null} - ProxyAgent или null если прокси не настроен
47
+ */
48
+ function getQwenProxyAgent() {
49
+ if (qwenProxyInitialized) {
50
+ return qwenProxyAgent;
51
+ }
52
+
53
+ if (!QWEN_PROXY) {
54
+ qwenProxyInitialized = true;
55
+ qwenProxyAgent = null;
56
+ return null;
57
+ }
58
+
59
+ try {
60
+ logInfo(`🧠 Инициализация прокси для Qwen LLM: ${maskProxyUrl(QWEN_PROXY)}`);
61
+ qwenProxyAgent = new ProxyAgent(QWEN_PROXY);
62
+ qwenProxyInitialized = true;
63
+ logInfo('✅ Прокси для Qwen LLM успешно инициализирован');
64
+ return qwenProxyAgent;
65
+ } catch (error) {
66
+ logWarn(`❌ Ошибка инициализации прокси для Qwen LLM: ${error.message}`);
67
+ qwenProxyInitialized = true;
68
+ qwenProxyAgent = null;
69
+ return null;
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Получить ProxyAgent для скачивания файлов
75
+ * Агент кэшируется для повторного использования
76
+ * @returns {ProxyAgent|null} - ProxyAgent или null если прокси не настроен
77
+ */
78
+ export function getFileDownloadProxyAgent() {
79
+ if (fileDownloadProxyInitialized) {
80
+ logDebug(`📥 getFileDownloadProxyAgent: возвращаем кэшированный агент (${fileDownloadProxyAgent ? 'есть' : 'null'})`);
81
+ return fileDownloadProxyAgent;
82
+ }
83
+
84
+ if (!FILE_DOWNLOAD_PROXY) {
85
+ logWarn('⚠️ FILE_DOWNLOAD_PROXY не настроен в .env');
86
+ fileDownloadProxyInitialized = true;
87
+ fileDownloadProxyAgent = null;
88
+ return null;
89
+ }
90
+
91
+ try {
92
+ logInfo(`📥 Инициализация прокси для скачивания файлов: ${maskProxyUrl(FILE_DOWNLOAD_PROXY)}`);
93
+ fileDownloadProxyAgent = new ProxyAgent(FILE_DOWNLOAD_PROXY);
94
+ fileDownloadProxyInitialized = true;
95
+ logInfo('✅ Прокси для скачивания файлов успешно инициализирован');
96
+ return fileDownloadProxyAgent;
97
+ } catch (error) {
98
+ logError(`❌ Ошибка инициализации прокси для скачивания файлов`, error);
99
+ fileDownloadProxyInitialized = true;
100
+ fileDownloadProxyAgent = null;
101
+ return null;
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Замаскировать URL прокси для логирования (скрыть credentials)
107
+ * @param {string} url - URL прокси
108
+ * @returns {string} - Замаскированный URL
109
+ */
110
+ function maskProxyUrl(url) {
111
+ if (!url) return 'none';
112
+ try {
113
+ const parsed = new URL(url);
114
+ if (parsed.username || parsed.password) {
115
+ return `${parsed.protocol}//***:***@${parsed.hostname}:${parsed.port}`;
116
+ }
117
+ return url;
118
+ } catch {
119
+ return 'invalid-url';
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Выполнить fetch запрос к Telegram через прокси (если настроен)
125
+ * @param {string} url - URL для запроса
126
+ * @param {Object} options - Опции fetch
127
+ * @returns {Promise<Response>} - Response от fetch
128
+ */
129
+ export async function fetchWithTelegramProxy(url, options = {}) {
130
+ const proxyAgent = getTelegramProxyAgent();
131
+
132
+ // Если прокси не настроен, используем обычный fetch
133
+ if (!proxyAgent) {
134
+ return fetch(url, options);
135
+ }
136
+
137
+ // Используем node-fetch с agent опцией
138
+ const { default: nodeFetch } = await import('node-fetch');
139
+
140
+ logDebug(`📱 Запрос к Telegram через прокси: ${url}`);
141
+
142
+ return nodeFetch(url, {
143
+ ...options,
144
+ agent: proxyAgent
145
+ });
146
+ }
147
+
148
+ /**
149
+ * Выполнить fetch запрос к Qwen LLM через прокси (если настроен)
150
+ * @param {string} url - URL для запроса
151
+ * @param {Object} options - Опции fetch
152
+ * @returns {Promise<Response>} - Response от fetch
153
+ */
154
+ export async function fetchWithQwenProxy(url, options = {}) {
155
+ const proxyAgent = getQwenProxyAgent();
156
+
157
+ // Если прокси не настроен, используем обычный fetch
158
+ if (!proxyAgent) {
159
+ return fetch(url, options);
160
+ }
161
+
162
+ // Используем node-fetch с agent опцией
163
+ const { default: nodeFetch } = await import('node-fetch');
164
+
165
+ logDebug(`🧠 Запрос к Qwen LLM через прокси: ${url}`);
166
+
167
+ return nodeFetch(url, {
168
+ ...options,
169
+ agent: proxyAgent
170
+ });
171
+ }
172
+
173
+ /**
174
+ * Проверить доступен ли прокси для Telegram
175
+ * @returns {Promise<boolean>} - true если прокси доступен
176
+ */
177
+ export async function checkTelegramProxyAvailability() {
178
+ if (!TELEGRAM_PROXY) {
179
+ return false;
180
+ }
181
+
182
+ try {
183
+ const proxyAgent = getTelegramProxyAgent();
184
+ if (!proxyAgent) {
185
+ return false;
186
+ }
187
+
188
+ const { default: nodeFetch } = await import('node-fetch');
189
+
190
+ // Тестовый запрос к Telegram API
191
+ const response = await nodeFetch('https://api.telegram.org/bot', {
192
+ agent: proxyAgent,
193
+ timeout: 5000
194
+ });
195
+
196
+ return response.ok || response.status === 404; // 404 ok for this endpoint
197
+ } catch (error) {
198
+ logWarn(`⚠️ Прокси для Telegram недоступен: ${error.message}`);
199
+ return false;
200
+ }
201
+ }
202
+
203
+ /**
204
+ * Проверить доступен ли прокси для Qwen LLM
205
+ * @returns {Promise<boolean>} - true если прокси доступен
206
+ */
207
+ export async function checkQwenProxyAvailability() {
208
+ if (!QWEN_PROXY) {
209
+ return false;
210
+ }
211
+
212
+ try {
213
+ const proxyAgent = getQwenProxyAgent();
214
+ if (!proxyAgent) {
215
+ return false;
216
+ }
217
+
218
+ const { default: nodeFetch } = await import('node-fetch');
219
+
220
+ // Тестовый запрос к Qwen API
221
+ const response = await nodeFetch('https://chat.qwen.ai', {
222
+ agent: proxyAgent,
223
+ timeout: 5000
224
+ });
225
+
226
+ return response.ok || response.status === 302; // 302 is ok for redirect
227
+ } catch (error) {
228
+ logWarn(`⚠️ Прокси для Qwen LLM недоступен: ${error.message}`);
229
+ return false;
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Получить информацию о текущей конфигурации прокси
235
+ * @returns {Object} - Информация о прокси
236
+ */
237
+ export function getProxyInfo() {
238
+ return {
239
+ telegram: {
240
+ configured: !!TELEGRAM_PROXY,
241
+ url: maskProxyUrl(TELEGRAM_PROXY),
242
+ active: telegramProxyInitialized && telegramProxyAgent !== null
243
+ },
244
+ qwen: {
245
+ configured: !!QWEN_PROXY,
246
+ url: maskProxyUrl(QWEN_PROXY),
247
+ active: qwenProxyInitialized && qwenProxyAgent !== null
248
+ },
249
+ fileDownload: {
250
+ configured: !!FILE_DOWNLOAD_PROXY,
251
+ url: maskProxyUrl(FILE_DOWNLOAD_PROXY),
252
+ active: fileDownloadProxyInitialized && fileDownloadProxyAgent !== null
253
+ }
254
+ };
255
+ }