neogram 9.3.1 → 9.3.2

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 CHANGED
@@ -2,12 +2,35 @@
2
2
 
3
3
  **Neogram** is a lightweight JavaScript module for working with the Telegram Bot API and AI. This is a port of the original Python library by SiriLV. It combines simple Telegram workflows with powerful features like text and image generation, translation, and more.
4
4
 
5
- ## Installation
5
+ ## ✨ Features
6
+
7
+ - **Full Telegram Bot API Coverage** - All 281+ Telegram API types and methods
8
+ - **AI Integration** - Built-in support for OnlySQ, ChatGPT, and Deef AI services
9
+ - **TypeScript Ready** - Complete type definitions for all Telegram objects
10
+ - **ES Modules** - Native ES module support (modern JavaScript)
11
+ - **Lightweight** - Minimal dependencies (axios, cheerio, form-data)
12
+ - **Flexible** - Support for both polling and webhook modes
13
+ - **File Uploads** - Easy handling of photos, documents, videos, and other media
14
+ - **Error Handling** - Comprehensive error handling with Telegram API error codes
15
+ - **Customizable** - Configurable API keys and endpoints for AI services
16
+
17
+ ## 📦 Installation
6
18
 
7
19
  ```bash
8
20
  npm install neogram
9
21
  ```
10
22
 
23
+ ### Getting a Bot Token
24
+
25
+ 1. Open Telegram and search for [@BotFather](https://t.me/botfather)
26
+ 2. Send `/newbot` and follow the instructions
27
+ 3. Copy the token provided by BotFather
28
+ 4. Set it as environment variable or use directly in your code:
29
+
30
+ ```bash
31
+ export BOT_TOKEN="your_token_here"
32
+ ```
33
+
11
34
  ## Dependencies
12
35
 
13
36
  - `axios` (^1.7.7) - HTTP client for API requests
@@ -38,6 +61,51 @@ const me = await bot.getMe();
38
61
  console.log(`Bot username: @${me.username}`);
39
62
  ```
40
63
 
64
+ ## Quick Start
65
+
66
+ Here's a complete example of a bot that responds to messages and uses AI:
67
+
68
+ ```javascript
69
+ import { Bot, OnlySQ } from 'neogram';
70
+
71
+ const bot = new Bot('YOUR_BOT_TOKEN');
72
+ const ai = new OnlySQ(); // Uses default 'openai' key
73
+
74
+ // Simple polling loop
75
+ let offset = 0;
76
+ while (true) {
77
+ const updates = await bot.getUpdates({ offset, timeout: 30 });
78
+
79
+ for (const update of updates) {
80
+ offset = update.update_id + 1;
81
+
82
+ if (update.message?.text) {
83
+ const { chat, text } = update.message;
84
+
85
+ // Echo with AI enhancement
86
+ if (text.startsWith('/ask ')) {
87
+ const question = text.substring(5);
88
+ const answer = await ai.generateAnswer('gpt-5.2-chat', [
89
+ { role: 'user', content: question }
90
+ ]);
91
+
92
+ await bot.sendMessage({
93
+ chat_id: chat.id,
94
+ text: `🤖 AI says: ${answer}`
95
+ });
96
+ } else {
97
+ await bot.sendMessage({
98
+ chat_id: chat.id,
99
+ text: `You said: ${text}`
100
+ });
101
+ }
102
+ }
103
+ }
104
+ }
105
+ ```
106
+
107
+ For more examples, see the `examples/` directory.
108
+
41
109
  ## Core API Methods
42
110
 
43
111
  The `Bot` class provides comprehensive access to the Telegram Bot API. Here are the main categories of methods:
@@ -104,10 +172,7 @@ The `Bot` class provides comprehensive access to the Telegram Bot API. Here are
104
172
 
105
173
  ### Updates and Polling
106
174
 
107
- - `getUpdates(options)` - Get bot updates
108
- - `setWebhook(options)` - Set webhook
109
- - `deleteWebhook(options)` - Delete webhook
110
- - `getWebhookInfo()` - Get webhook info
175
+ - `getUpdates(options)` - Get bot updates (polling mode)
111
176
 
112
177
  ### User and File Management
113
178
 
@@ -238,11 +303,15 @@ const translation = await chatgpt.generateTranslation(file, 'whisper-1');
238
303
 
239
304
  ### OnlySQ Class
240
305
 
241
- Provides access to OnlySQ AI services:
306
+ Provides access to OnlySQ AI services with customizable API key support:
242
307
 
243
308
  ```javascript
309
+ // Default constructor uses 'openai' key (backward compatible)
244
310
  const onlysq = new OnlySQ();
245
311
 
312
+ // Or provide your own API key
313
+ const onlysqWithKey = new OnlySQ({ apiKey: 'your-onlysq-api-key' });
314
+
246
315
  // Get available models
247
316
  const models = await onlysq.getModels({
248
317
  modality: 'text', // Filter by modality
@@ -263,6 +332,7 @@ await onlysq.generateImage('flux', 'A futuristic city', '16:9', 'output.png');
263
332
  ```
264
333
 
265
334
  **Methods:**
335
+ - `constructor(options?)` - Create instance with optional `{ apiKey }` (defaults to 'openai')
266
336
  - `getModels(options)` - Get filtered list of available models
267
337
  - `generateAnswer(model, messages)` - Generate text responses
268
338
  - `generateImage(model, prompt, ratio, filename)` - Generate and save images
@@ -319,13 +389,77 @@ import {
319
389
  } from 'neogram';
320
390
  ```
321
391
 
392
+ ### TelegramObject Base Class
393
+
394
+ All Telegram API types extend the `TelegramObject` base class, which provides:
395
+
396
+ - **Automatic field mapping**: `from` ↔ `from_user`, `type` ↔ `type_val`, `filter` ↔ `filter_val`
397
+ - **Serialization**: `toJSON()` method for converting to plain objects
398
+ - **Deserialization**: Static `fromJSON(data)` method for creating instances
399
+ - **Constructor**: Accepts plain objects and automatically maps properties
400
+
401
+ Example:
402
+ ```javascript
403
+ import { User } from 'neogram';
404
+
405
+ // Create User instance from Telegram API response
406
+ const userData = { id: 123, is_bot: false, first_name: 'John' };
407
+ const user = new User(userData);
408
+
409
+ // Convert back to plain object
410
+ const json = user.toJSON();
411
+ ```
412
+
322
413
  ## Examples
323
414
 
324
- See the `examples/` directory for complete usage examples:
415
+ See the `examples/` directory for complete, runnable examples:
416
+
417
+ | File | Description | Key Features |
418
+ |------|-------------|--------------|
419
+ | `simple-bot.js` | Minimal bot with polling | `getUpdates`, `sendMessage`, error handling |
420
+ | `test-bot.js` | Feature-rich test bot | Commands, photos, polls, dice, locations, keyboards |
421
+ | `test-bot-full.js` | Complete bot with inline buttons | Callback query handling, answerCallbackQuery |
422
+ | `test-bot-debug.js` | Debug and connectivity test | Error inspection, token validation |
423
+ | `ai-bot.js` | AI-powered bot with OnlySQ | GPT-4o-mini integration, conversation history |
325
424
 
326
- - `simple-bot.js` - Basic bot setup
327
- - `test-bot.js` - Comprehensive bot testing
328
- - `ai-bot.js` - AI-integrated bot example
425
+ Run any example:
426
+ ```bash
427
+ BOT_TOKEN="your_token_here" node examples/simple-bot.js
428
+ ```
429
+
430
+ ### Webhook Example
431
+
432
+ ```javascript
433
+ import { Bot } from 'neogram';
434
+ import express from 'express';
435
+
436
+ const bot = new Bot('YOUR_BOT_TOKEN');
437
+ const app = express();
438
+
439
+ app.use(express.json());
440
+
441
+ // Set webhook (run once)
442
+ await bot.setWebhook({
443
+ url: 'https://yourdomain.com/webhook',
444
+ secret_token: 'your_secret_token'
445
+ });
446
+
447
+ // Handle incoming updates
448
+ app.post('/webhook', async (req, res) => {
449
+ const update = req.body;
450
+
451
+ if (update.message?.text === '/start') {
452
+ await bot.sendMessage({
453
+ chat_id: update.message.chat.id,
454
+ text: 'Hello from webhook!'
455
+ });
456
+ }
457
+
458
+ res.sendStatus(200);
459
+ });
460
+
461
+ app.listen(3000, () => console.log('Webhook server running on port 3000'));
462
+ ```
329
463
 
330
464
  ### Function Examples
331
465
 
@@ -713,7 +847,9 @@ src/
713
847
 
714
848
  ## Contributing
715
849
 
716
- Contributions are welcome! Please see the [GitHub repository](https://github.com/AndrewImm-OP/neogram) for issues and pull requests.
850
+ Join our Telegram channel: https://t.me/neogram_js
851
+
852
+
717
853
 
718
854
  ## License
719
855
 
@@ -721,5 +857,5 @@ MIT License - see LICENSE file for details.
721
857
 
722
858
  ## Credits
723
859
 
724
- - Original Python library by [SiriLV](https://github.com/SiriLV)
725
- - JavaScript port by [AndrewImm-OP](https://github.com/AndrewImm-OP)
860
+ - Original Python library by SiriLV
861
+ - JavaScript port by AndrewImm-OP
@@ -0,0 +1,47 @@
1
+ # Примеры использования neogram-js
2
+
3
+ ## Запуск тестового бота
4
+
5
+ 1. Создай бота через [@BotFather](https://t.me/botfather)
6
+ 2. Получи токен
7
+ 3. Экспортируй токен:
8
+
9
+ \`\`\`bash
10
+ export BOT_TOKEN="your_bot_token_here"
11
+ \`\`\`
12
+
13
+ 4. Запусти бота:
14
+
15
+ \`\`\`bash
16
+ node examples/test-bot.js
17
+ \`\`\`
18
+
19
+ ## Простой эхо-бот
20
+
21
+ \`\`\`bash
22
+ export BOT_TOKEN="your_token"
23
+ node examples/simple-bot.js
24
+ \`\`\`
25
+
26
+ ## Доступные команды в test-bot
27
+
28
+ - \`/start\` - Приветствие и список команд
29
+ - \`/test\` - Тест основных функций
30
+ - \`/photo\` - Отправка фото
31
+ - \`/poll\` - Создание опроса
32
+ - \`/dice\` - Бросить кубик
33
+ - \`/location\` - Отправить локацию
34
+ - \`/keyboard\` - Показать клавиатуру
35
+ - \`/inline\` - Inline кнопки
36
+ - \`/help\` - Помощь
37
+
38
+ ## Что тестируется
39
+
40
+ - ✅ Long polling (getUpdates)
41
+ - ✅ Отправка сообщений
42
+ - ✅ Отправка медиа (фото)
43
+ - ✅ Опросы
44
+ - ✅ Действия (typing, dice)
45
+ - ✅ Локации
46
+ - ✅ Клавиатуры (reply & inline)
47
+ - ✅ Обработка команд
@@ -0,0 +1,155 @@
1
+ import { Bot } from '../src/Bot.js';
2
+ import axios from 'axios';
3
+
4
+ const BOT_TOKEN = process.env.BOT_TOKEN;
5
+ const ONLYSQ_API_KEY = process.env.ONLYSQ_API_KEY || 'openai';
6
+ const ONLYSQ_API_URL = 'https://api.onlysq.ru/ai/openai/chat/completions';
7
+
8
+ if (!BOT_TOKEN) {
9
+ console.error('❌ Установи BOT_TOKEN');
10
+ process.exit(1);
11
+ }
12
+
13
+ const bot = new Bot(BOT_TOKEN);
14
+ const conversations = new Map();
15
+
16
+ console.log('🤖 AI Бот запускается...');
17
+
18
+ async function callOnlySQ(messages) {
19
+ try {
20
+ const response = await axios.post(ONLYSQ_API_URL, {
21
+ model: 'gpt-4o-mini',
22
+ messages: messages,
23
+ temperature: 0.7,
24
+ max_tokens: 1000
25
+ }, {
26
+ headers: {
27
+ 'Authorization': `Bearer ${ONLYSQ_API_KEY}`,
28
+ 'Content-Type': 'application/json'
29
+ },
30
+ proxy: false
31
+ });
32
+
33
+ return response.data.choices[0].message.content;
34
+ } catch (error) {
35
+ console.error('❌ Ошибка OnlySQ:', error.message);
36
+ throw error;
37
+ }
38
+ }
39
+
40
+ async function start() {
41
+ try {
42
+ const me = await bot.getMe();
43
+ console.log('✅ Бот запущен:', '@' + me.username);
44
+ console.log('🧠 OnlySQ API: GPT-4o-mini');
45
+ console.log('🔄 Ожидаю сообщения...\n');
46
+
47
+ let offset = 0;
48
+
49
+ while (true) {
50
+ try {
51
+ const updates = await bot.getUpdates({ offset, timeout: 30 });
52
+
53
+ for (const update of updates) {
54
+ offset = update.update_id + 1;
55
+
56
+ if (update.message) {
57
+ await handleMessage(update.message);
58
+ }
59
+ }
60
+ } catch (error) {
61
+ console.error('❌ Ошибка получения обновлений:', error.message);
62
+ await new Promise(r => setTimeout(r, 3000));
63
+ }
64
+ }
65
+ } catch (error) {
66
+ console.error('❌ Ошибка запуска:', error.message);
67
+ process.exit(1);
68
+ }
69
+ }
70
+
71
+ async function handleMessage(message) {
72
+ const chatId = message.chat.id;
73
+ const text = message.text;
74
+ const username = message.from.username || message.from.first_name;
75
+
76
+ if (!text) return;
77
+
78
+ console.log(`📨 @${username}: ${text}`);
79
+
80
+ if (text === '/start') {
81
+ await bot.sendMessage({
82
+ chat_id: chatId,
83
+ text: '👋 Привет! Я AI бот на базе OnlySQ!\n\n' +
84
+ '🧠 Модель: GPT-4o-mini\n' +
85
+ '📚 Построен на neogram-js\n\n' +
86
+ 'Просто напиши мне что-нибудь!\n\n' +
87
+ '/clear - очистить историю\n' +
88
+ '/help - помощь'
89
+ });
90
+ return;
91
+ }
92
+
93
+ if (text === '/clear') {
94
+ conversations.delete(chatId);
95
+ await bot.sendMessage({
96
+ chat_id: chatId,
97
+ text: '🗑️ История диалога очищена!'
98
+ });
99
+ return;
100
+ }
101
+
102
+ if (text === '/help') {
103
+ await bot.sendMessage({
104
+ chat_id: chatId,
105
+ text: '📚 AI Бот на neogram-js\n\n' +
106
+ '🧠 Модель: GPT-4o-mini (OnlySQ)\n' +
107
+ '🔥 Framework: neogram-js\n' +
108
+ '💬 Long Polling\n\n' +
109
+ 'Задавай любые вопросы!'
110
+ });
111
+ return;
112
+ }
113
+
114
+ await bot.sendChatAction({ chat_id: chatId, action: 'typing' });
115
+
116
+ try {
117
+ if (!conversations.has(chatId)) {
118
+ conversations.set(chatId, [
119
+ { role: 'system', content: 'Ты полезный AI ассистент. Отвечай кратко и по делу на русском языке.' }
120
+ ]);
121
+ }
122
+
123
+ const history = conversations.get(chatId);
124
+ history.push({ role: 'user', content: text });
125
+
126
+ // Ограничиваем историю (последние 10 пар сообщений)
127
+ if (history.length > 21) {
128
+ history.splice(1, 2);
129
+ }
130
+
131
+ const aiResponse = await callOnlySQ(history);
132
+ history.push({ role: 'assistant', content: aiResponse });
133
+
134
+ console.log(`🤖 AI: ${aiResponse.substring(0, 80)}${aiResponse.length > 80 ? '...' : ''}`);
135
+
136
+ await bot.sendMessage({
137
+ chat_id: chatId,
138
+ text: aiResponse
139
+ });
140
+
141
+ } catch (error) {
142
+ console.error('❌ Ошибка AI:', error.message);
143
+ await bot.sendMessage({
144
+ chat_id: chatId,
145
+ text: '❌ Ошибка при обработке запроса. Попробуй позже или напиши /clear'
146
+ });
147
+ }
148
+ }
149
+
150
+ start().catch(console.error);
151
+
152
+ process.on('SIGINT', () => {
153
+ console.log('\n👋 Бот остановлен');
154
+ process.exit(0);
155
+ });
@@ -0,0 +1,30 @@
1
+ import { Bot } from '../src/Bot.js';
2
+
3
+ const bot = new Bot(process.env.BOT_TOKEN);
4
+
5
+ async function main() {
6
+ const me = await bot.getMe();
7
+ console.log('Бот запущен:', me.username);
8
+
9
+ let offset = 0;
10
+
11
+ while (true) {
12
+ const updates = await bot.getUpdates({ offset, timeout: 30 });
13
+
14
+ for (const update of updates) {
15
+ offset = update.update_id + 1;
16
+
17
+ if (update.message) {
18
+ const { chat, text } = update.message;
19
+ console.log('Получено:', text);
20
+
21
+ await bot.sendMessage({
22
+ chat_id: chat.id,
23
+ text: 'Ты написал: ' + text
24
+ });
25
+ }
26
+ }
27
+ }
28
+ }
29
+
30
+ main().catch(console.error);
@@ -0,0 +1,26 @@
1
+ import { Bot } from '../src/Bot.js';
2
+
3
+ const TOKEN = process.env.BOT_TOKEN;
4
+ const bot = new Bot(TOKEN);
5
+
6
+ console.log('🤖 Тестирую бота...');
7
+ console.log('🔑 Токен:', TOKEN.substring(0, 10) + '...');
8
+ console.log('🌐 Base URL:', bot.http.defaults.baseURL);
9
+
10
+ async function start() {
11
+ try {
12
+ console.log('📡 Отправляю getMe...');
13
+ const me = await bot.getMe();
14
+ console.log('✅ Успех!');
15
+ console.log('👤 @' + me.username);
16
+ console.log('🆔 ID:', me.id);
17
+ console.log('📝 Имя:', me.first_name);
18
+ } catch (error) {
19
+ console.error('❌ Ошибка:', error.message);
20
+ console.error('📊 Код:', error.code);
21
+ console.error('🔧 Config:', error.config?.url);
22
+ console.error('📄 Response:', error.response?.data);
23
+ }
24
+ }
25
+
26
+ start();
@@ -0,0 +1,221 @@
1
+ import { Bot } from '../src/Bot.js';
2
+
3
+ const TOKEN = process.env.BOT_TOKEN;
4
+ if (!TOKEN) {
5
+ console.error('❌ Ошибка: установи переменную BOT_TOKEN');
6
+ process.exit(1);
7
+ }
8
+
9
+ const bot = new Bot(TOKEN);
10
+
11
+ console.log('🤖 Бот запускается...');
12
+
13
+ async function start() {
14
+ try {
15
+ const me = await bot.getMe();
16
+ console.log('✅ Бот успешно запущен!');
17
+ console.log('👤 Username:', '@' + me.username);
18
+ console.log('🆔 Bot ID:', me.id);
19
+ console.log('📝 Name:', me.first_name);
20
+ console.log('');
21
+ console.log('🔄 Ожидаю сообщения...');
22
+
23
+ let offset = 0;
24
+
25
+ while (true) {
26
+ try {
27
+ const updates = await bot.getUpdates({
28
+ offset,
29
+ timeout: 30,
30
+ limit: 100
31
+ });
32
+
33
+ for (const update of updates) {
34
+ offset = update.update_id + 1;
35
+
36
+ // Обрабатываем сообщения
37
+ if (update.message) {
38
+ await handleMessage(update.message);
39
+ }
40
+
41
+ // Обрабатываем нажатия на inline кнопки
42
+ if (update.callback_query) {
43
+ await handleCallback(update.callback_query);
44
+ }
45
+ }
46
+ } catch (error) {
47
+ console.error('❌ Ошибка при получении обновлений:', error.message);
48
+ await new Promise(resolve => setTimeout(resolve, 3000));
49
+ }
50
+ }
51
+ } catch (error) {
52
+ console.error('❌ Ошибка при запуске:', error.message);
53
+ process.exit(1);
54
+ }
55
+ }
56
+
57
+ async function handleMessage(message) {
58
+ const chatId = message.chat.id;
59
+ const text = message.text;
60
+ const username = message.from.username || message.from.first_name;
61
+
62
+ console.log('📨 Сообщение от @' + username + ':', text);
63
+
64
+ if (text === '/start') {
65
+ await bot.sendMessage({
66
+ chat_id: chatId,
67
+ text: '👋 Привет! Я тестовый бот для neogram-js!\n\n' +
68
+ 'Доступные команды:\n' +
69
+ '/test - Тест основных функций\n' +
70
+ '/photo - Отправить фото\n' +
71
+ '/poll - Создать опрос\n' +
72
+ '/dice - Бросить кубик\n' +
73
+ '/location - Отправить локацию\n' +
74
+ '/keyboard - Показать клавиатуру\n' +
75
+ '/inline - Inline кнопки\n' +
76
+ '/help - Помощь'
77
+ });
78
+ }
79
+
80
+ else if (text === '/test') {
81
+ await bot.sendChatAction({ chat_id: chatId, action: 'typing' });
82
+
83
+ await bot.sendMessage({
84
+ chat_id: chatId,
85
+ text: '✅ Тест основных функций:\n\n' +
86
+ '✓ sendMessage работает\n' +
87
+ '✓ getUpdates работает\n' +
88
+ '✓ sendChatAction работает\n\n' +
89
+ '🎉 Всё отлично!'
90
+ });
91
+ }
92
+
93
+ else if (text === '/photo') {
94
+ await bot.sendPhoto({
95
+ chat_id: chatId,
96
+ photo: 'https://picsum.photos/800/600',
97
+ caption: '📸 Случайное фото с picsum.photos'
98
+ });
99
+ }
100
+
101
+ else if (text === '/poll') {
102
+ await bot.sendPoll({
103
+ chat_id: chatId,
104
+ question: 'Как тебе neogram-js?',
105
+ pollOptions: ['🔥 Отлично!', '👍 Хорошо', '👌 Норм', '🤔 Так себе']
106
+ });
107
+ }
108
+
109
+ else if (text === '/dice') {
110
+ await bot.sendDice({ chat_id: chatId, emoji: '🎲' });
111
+ }
112
+
113
+ else if (text === '/location') {
114
+ await bot.sendLocation({
115
+ chat_id: chatId,
116
+ latitude: 55.7558,
117
+ longitude: 37.6173
118
+ });
119
+ await bot.sendMessage({
120
+ chat_id: chatId,
121
+ text: '📍 Красная площадь, Москва'
122
+ });
123
+ }
124
+
125
+ else if (text === '/keyboard') {
126
+ await bot.sendMessage({
127
+ chat_id: chatId,
128
+ text: '⌨️ Клавиатура:',
129
+ reply_markup: {
130
+ keyboard: [
131
+ [{ text: '🔥 Кнопка 1' }, { text: '⚡ Кнопка 2' }],
132
+ [{ text: '💎 Кнопка 3' }],
133
+ [{ text: '❌ Убрать клавиатуру' }]
134
+ ],
135
+ resize_keyboard: true
136
+ }
137
+ });
138
+ }
139
+
140
+ else if (text === '/inline') {
141
+ await bot.sendMessage({
142
+ chat_id: chatId,
143
+ text: '🔘 Inline кнопки (нажми на них!):',
144
+ reply_markup: {
145
+ inline_keyboard: [
146
+ [
147
+ { text: '✅ Кнопка 1', callback_data: 'btn1' },
148
+ { text: '❌ Кнопка 2', callback_data: 'btn2' }
149
+ ],
150
+ [
151
+ { text: '🔥 Кнопка 3', callback_data: 'btn3' }
152
+ ],
153
+ [
154
+ { text: '🌐 Google', url: 'https://google.com' }
155
+ ]
156
+ ]
157
+ }
158
+ });
159
+ }
160
+
161
+ else if (text === '❌ Убрать клавиатуру') {
162
+ await bot.sendMessage({
163
+ chat_id: chatId,
164
+ text: '✅ Клавиатура убрана',
165
+ reply_markup: { remove_keyboard: true }
166
+ });
167
+ }
168
+
169
+ else if (text === '/help') {
170
+ await bot.sendMessage({
171
+ chat_id: chatId,
172
+ text: '📚 Помощь:\n\n' +
173
+ 'Этот бот тестирует функциональность neogram-js\n' +
174
+ 'Используй /start чтобы увидеть все команды'
175
+ });
176
+ }
177
+
178
+ else {
179
+ await bot.sendMessage({
180
+ chat_id: chatId,
181
+ text: '🤔 Неизвестная команда. Используй /help'
182
+ });
183
+ }
184
+ }
185
+
186
+ // Обработка callback_query (нажатия на inline кнопки)
187
+ async function handleCallback(callbackQuery) {
188
+ const chatId = callbackQuery.message.chat.id;
189
+ const messageId = callbackQuery.message.message_id;
190
+ const data = callbackQuery.data;
191
+ const username = callbackQuery.from.username || callbackQuery.from.first_name;
192
+
193
+ console.log('🔘 Callback от @' + username + ':', data);
194
+
195
+ // Отвечаем на callback (убирает "часики" у пользователя)
196
+ await bot.answerCallbackQuery({ callback_query_id: callbackQuery.id });
197
+
198
+ if (data === 'btn1') {
199
+ await bot.sendMessage({
200
+ chat_id: chatId,
201
+ text: '✅ Ты нажал на Кнопку 1!'
202
+ });
203
+ } else if (data === 'btn2') {
204
+ await bot.sendMessage({
205
+ chat_id: chatId,
206
+ text: '❌ Ты нажал на Кнопку 2!'
207
+ });
208
+ } else if (data === 'btn3') {
209
+ await bot.sendMessage({
210
+ chat_id: chatId,
211
+ text: '🔥 Ты нажал на Кнопку 3!'
212
+ });
213
+ }
214
+ }
215
+
216
+ start().catch(console.error);
217
+
218
+ process.on('SIGINT', () => {
219
+ console.log('\n👋 Бот остановлен');
220
+ process.exit(0);
221
+ });
@@ -0,0 +1,196 @@
1
+ import { Bot } from '../src/Bot.js';
2
+
3
+ // Получаем токен из переменной окружения
4
+ const TOKEN = process.env.BOT_TOKEN;
5
+
6
+ if (!TOKEN) {
7
+ console.error('❌ Ошибка: установи переменную BOT_TOKEN');
8
+ console.error('Пример: export BOT_TOKEN="your_token_here"');
9
+ process.exit(1);
10
+ }
11
+
12
+ const bot = new Bot(TOKEN);
13
+
14
+ console.log('🤖 Бот запускается...');
15
+
16
+ // Получаем информацию о боте
17
+ async function start() {
18
+ try {
19
+ const me = await bot.getMe();
20
+ console.log('✅ Бот успешно запущен!');
21
+ console.log('👤 Username:', '@' + me.username);
22
+ console.log('🆔 Bot ID:', me.id);
23
+ console.log('📝 Name:', me.first_name);
24
+ console.log('');
25
+ console.log('🔄 Ожидаю сообщения...');
26
+
27
+ let offset = 0;
28
+
29
+ // Polling loop
30
+ while (true) {
31
+ try {
32
+ const updates = await bot.getUpdates({
33
+ offset,
34
+ timeout: 30,
35
+ limit: 100
36
+ });
37
+
38
+ for (const update of updates) {
39
+ offset = update.update_id + 1;
40
+ await handleUpdate(update);
41
+ }
42
+ } catch (error) {
43
+ console.error('❌ Ошибка при получении обновлений:', error.message);
44
+ await new Promise(resolve => setTimeout(resolve, 3000));
45
+ }
46
+ }
47
+ } catch (error) {
48
+ console.error('❌ Ошибка при запуске:', error.message);
49
+ process.exit(1);
50
+ }
51
+ }
52
+
53
+ // Обработка обновлений
54
+ async function handleUpdate(update) {
55
+ const message = update.message;
56
+ if (!message) return;
57
+
58
+ const chatId = message.chat.id;
59
+ const text = message.text;
60
+ const username = message.from.username || message.from.first_name;
61
+
62
+ console.log('📨 Сообщение от @' + username + ':', text);
63
+
64
+ // Команды
65
+ if (text === '/start') {
66
+ await bot.sendMessage({
67
+ chat_id: chatId,
68
+ text: '👋 Привет! Я тестовый бот для neogram-js!\n\n' +
69
+ 'Доступные команды:\n' +
70
+ '/test - Тест основных функций\n' +
71
+ '/photo - Отправить фото\n' +
72
+ '/poll - Создать опрос\n' +
73
+ '/dice - Бросить кубик\n' +
74
+ '/location - Отправить локацию\n' +
75
+ '/keyboard - Показать клавиатуру\n' +
76
+ '/inline - Inline кнопки\n' +
77
+ '/help - Помощь'
78
+ });
79
+ }
80
+
81
+ else if (text === '/test') {
82
+ await bot.sendChatAction({ chat_id: chatId, action: 'typing' });
83
+
84
+ await bot.sendMessage({
85
+ chat_id: chatId,
86
+ text: '✅ Тест основных функций:\n\n' +
87
+ '✓ sendMessage работает\n' +
88
+ '✓ getUpdates работает\n' +
89
+ '✓ sendChatAction работает\n\n' +
90
+ '🎉 Всё отлично!'
91
+ });
92
+ }
93
+
94
+ else if (text === '/photo') {
95
+ await bot.sendPhoto({
96
+ chat_id: chatId,
97
+ photo: 'https://picsum.photos/800/600',
98
+ caption: '📸 Случайное фото с picsum.photos'
99
+ });
100
+ }
101
+
102
+ else if (text === '/poll') {
103
+ await bot.sendPoll({
104
+ chat_id: chatId,
105
+ question: 'Как тебе neogram-js?',
106
+ pollOptions: ['🔥 Отлично!', '👍 Хорошо', '👌 Норм', '🤔 Так себе']
107
+ });
108
+ }
109
+
110
+ else if (text === '/dice') {
111
+ await bot.sendDice({ chat_id: chatId, emoji: '🎲' });
112
+ }
113
+
114
+ else if (text === '/location') {
115
+ await bot.sendLocation({
116
+ chat_id: chatId,
117
+ latitude: 55.7558,
118
+ longitude: 37.6173
119
+ });
120
+ await bot.sendMessage({
121
+ chat_id: chatId,
122
+ text: '📍 Красная площадь, Москва'
123
+ });
124
+ }
125
+
126
+ else if (text === '/keyboard') {
127
+ await bot.sendMessage({
128
+ chat_id: chatId,
129
+ text: '⌨️ Клавиатура:',
130
+ reply_markup: {
131
+ keyboard: [
132
+ [{ text: '🔥 Кнопка 1' }, { text: '⚡ Кнопка 2' }],
133
+ [{ text: '💎 Кнопка 3' }],
134
+ [{ text: '❌ Убрать клавиатуру' }]
135
+ ],
136
+ resize_keyboard: true
137
+ }
138
+ });
139
+ }
140
+
141
+ else if (text === '/inline') {
142
+ await bot.sendMessage({
143
+ chat_id: chatId,
144
+ text: '🔘 Inline кнопки:',
145
+ reply_markup: {
146
+ inline_keyboard: [
147
+ [
148
+ { text: '✅ Кнопка 1', callback_data: 'btn1' },
149
+ { text: '❌ Кнопка 2', callback_data: 'btn2' }
150
+ ],
151
+ [
152
+ { text: '🌐 Google', url: 'https://google.com' }
153
+ ]
154
+ ]
155
+ }
156
+ });
157
+ }
158
+
159
+ else if (text === '❌ Убрать клавиатуру') {
160
+ await bot.sendMessage({
161
+ chat_id: chatId,
162
+ text: '✅ Клавиатура убрана',
163
+ reply_markup: { remove_keyboard: true }
164
+ });
165
+ }
166
+
167
+ else if (text === '/help') {
168
+ await bot.sendMessage({
169
+ chat_id: chatId,
170
+ text: '📚 Помощь:\n\n' +
171
+ 'Этот бот тестирует функциональность neogram-js\n' +
172
+ 'Используй /start чтобы увидеть все команды'
173
+ });
174
+ }
175
+
176
+ else {
177
+ await bot.sendMessage({
178
+ chat_id: chatId,
179
+ text: '🤔 Неизвестная команда. Используй /help'
180
+ });
181
+ }
182
+ }
183
+
184
+ // Обработка callback запросов (inline кнопки)
185
+ bot.on = (event, handler) => {
186
+ // TODO: implement event system
187
+ };
188
+
189
+ // Запуск
190
+ start().catch(console.error);
191
+
192
+ // Graceful shutdown
193
+ process.on('SIGINT', () => {
194
+ console.log('\n👋 Бот остановлен');
195
+ process.exit(0);
196
+ });
package/package.json CHANGED
@@ -8,15 +8,11 @@
8
8
  "contributors": [
9
9
  {
10
10
  "name": "AndrewImm-OP",
11
- "email": "bessmertnyja89@gmail.com",
12
- "url": "https://github.com/AndrewImm-OP"
11
+ "email": "bessmertnyja89@gmail.com"
13
12
  }
14
13
  ],
15
14
  "license": "MIT",
16
- "repository": {
17
- "type": "git",
18
- "url": "git+https://github.com/AndrewImm-OP/neogram.git"
19
- },
15
+
20
16
  "keywords": [
21
17
  "telegram",
22
18
  "bot",
@@ -30,6 +26,7 @@
30
26
  "files": [
31
27
  "src",
32
28
  "types",
29
+ "examples",
33
30
  "README.md",
34
31
  "LICENSE"
35
32
  ],
@@ -48,9 +45,7 @@
48
45
  "cheerio": "^1.0.0",
49
46
  "form-data": "^4.0.0"
50
47
  },
51
- "version": "9.3.1",
52
- "bugs": {
53
- "url": "https://github.com/AndrewImm-OP/neogram/issues"
54
- },
55
- "homepage": "https://github.com/AndrewImm-OP/neogram#readme"
48
+ "version": "9.3.2"
49
+
50
+
56
51
  }
package/src/ai/OnlySQ.js CHANGED
@@ -2,6 +2,10 @@ import axios from 'axios';
2
2
  import fs from 'fs';
3
3
 
4
4
  export class OnlySQ {
5
+ constructor(options = {}) {
6
+ this.apiKey = options.apiKey || 'openai';
7
+ }
8
+
5
9
  async getModels({
6
10
  modality = null,
7
11
  can_tools = null,
@@ -70,7 +74,7 @@ export class OnlySQ {
70
74
  const { data } = await axios.post('https://api.onlysq.ru/ai/v2', payload, {
71
75
  timeout: 30000,
72
76
  headers: {
73
- 'Authorization': 'Bearer openai',
77
+ 'Authorization': `Bearer ${this.apiKey}`,
74
78
  'Content-Type': 'application/json',
75
79
  'User-Agent': 'Mozilla/5.0 (compatible; OnlySQ/1.0)',
76
80
  },
@@ -103,7 +107,7 @@ export class OnlySQ {
103
107
  {
104
108
  timeout: 60000, // Image generation can take longer
105
109
  headers: {
106
- 'Authorization': 'Bearer openai',
110
+ 'Authorization': `Bearer ${this.apiKey}`,
107
111
  'Content-Type': 'application/json',
108
112
  'User-Agent': 'Mozilla/5.0 (compatible; OnlySQ/1.0)',
109
113
  },
package/types/index.d.ts CHANGED
@@ -764,6 +764,8 @@ export declare class Bot {
764
764
 
765
765
  // AI Classes
766
766
  export declare class OnlySQ {
767
+ constructor(options?: { apiKey?: string });
768
+
767
769
  getModels(options?: {
768
770
  modality?: string | string[];
769
771
  can_tools?: boolean;