apexbot 1.0.0
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/LICENSE +21 -0
- package/README.md +307 -0
- package/dist/adapters/manifold.js +166 -0
- package/dist/adapters/telegram.js +133 -0
- package/dist/agent/agentManager.js +315 -0
- package/dist/backtest/backtester.js +24 -0
- package/dist/channels/channelManager.js +72 -0
- package/dist/channels/discord.js +136 -0
- package/dist/channels/telegram.js +186 -0
- package/dist/cli/index.js +838 -0
- package/dist/core/eventBus.js +33 -0
- package/dist/decisionEngine.js +69 -0
- package/dist/eventBus.js +21 -0
- package/dist/gateway/dashboard.js +1009 -0
- package/dist/gateway/index.js +303 -0
- package/dist/index.js +195 -0
- package/dist/math/ev.js +25 -0
- package/dist/math/kelly.js +24 -0
- package/dist/rateLimiter.js +42 -0
- package/dist/safety/failsafe.js +32 -0
- package/dist/safety/llmChecker.js +148 -0
- package/dist/sessions/sessionManager.js +120 -0
- package/dist/strategy/arbitrage.js +151 -0
- package/package.json +78 -0
- package/scripts/install.ps1 +114 -0
- package/scripts/install.sh +146 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Telegram Channel - Bot API integration via grammY
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TelegramChannel = void 0;
|
|
7
|
+
const grammy_1 = require("grammy");
|
|
8
|
+
const eventBus_1 = require("../core/eventBus");
|
|
9
|
+
class TelegramChannel {
|
|
10
|
+
name = 'telegram';
|
|
11
|
+
status = 'disconnected';
|
|
12
|
+
bot;
|
|
13
|
+
config;
|
|
14
|
+
botUsername = '';
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.config = {
|
|
17
|
+
allowGroups: true,
|
|
18
|
+
requireMention: true,
|
|
19
|
+
...config,
|
|
20
|
+
};
|
|
21
|
+
this.bot = new grammy_1.Bot(config.botToken);
|
|
22
|
+
this.setupHandlers();
|
|
23
|
+
}
|
|
24
|
+
setupHandlers() {
|
|
25
|
+
// Get bot info on start
|
|
26
|
+
this.bot.api.getMe().then(me => {
|
|
27
|
+
this.botUsername = me.username || '';
|
|
28
|
+
console.log(`[Telegram] Bot username: @${this.botUsername}`);
|
|
29
|
+
});
|
|
30
|
+
// Handle all messages
|
|
31
|
+
this.bot.on('message:text', async (ctx) => {
|
|
32
|
+
const userId = ctx.from?.id;
|
|
33
|
+
const chatId = ctx.chat.id;
|
|
34
|
+
const isGroup = ctx.chat.type === 'group' || ctx.chat.type === 'supergroup';
|
|
35
|
+
const text = ctx.message.text;
|
|
36
|
+
// Check if allowed
|
|
37
|
+
if (this.config.allowedUsers && this.config.allowedUsers.length > 0) {
|
|
38
|
+
if (!this.config.allowedUsers.includes(userId)) {
|
|
39
|
+
// Silent ignore or send access denied
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// In groups, check for mention
|
|
44
|
+
if (isGroup && this.config.requireMention) {
|
|
45
|
+
const mentioned = text.toLowerCase().includes(`@${this.botUsername.toLowerCase()}`) ||
|
|
46
|
+
ctx.message.reply_to_message?.from?.id === ctx.me.id;
|
|
47
|
+
if (!mentioned) {
|
|
48
|
+
return; // Ignore messages without mention
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Clean text (remove bot mention)
|
|
52
|
+
const cleanText = text.replace(new RegExp(`@${this.botUsername}`, 'gi'), '').trim();
|
|
53
|
+
// Emit message event
|
|
54
|
+
(0, eventBus_1.emit)('channel:message', {
|
|
55
|
+
channel: 'telegram',
|
|
56
|
+
from: chatId.toString(),
|
|
57
|
+
text: cleanText,
|
|
58
|
+
id: ctx.message.message_id.toString(),
|
|
59
|
+
isGroup,
|
|
60
|
+
groupId: isGroup ? chatId.toString() : undefined,
|
|
61
|
+
timestamp: ctx.message.date * 1000,
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
// Handle media
|
|
65
|
+
this.bot.on('message:photo', async (ctx) => {
|
|
66
|
+
const photo = ctx.message.photo[ctx.message.photo.length - 1]; // Highest resolution
|
|
67
|
+
const fileId = photo.file_id;
|
|
68
|
+
(0, eventBus_1.emit)('channel:message', {
|
|
69
|
+
channel: 'telegram',
|
|
70
|
+
from: ctx.chat.id.toString(),
|
|
71
|
+
text: ctx.message.caption || '',
|
|
72
|
+
media: [{ type: 'image', url: fileId }],
|
|
73
|
+
id: ctx.message.message_id.toString(),
|
|
74
|
+
isGroup: ctx.chat.type !== 'private',
|
|
75
|
+
timestamp: ctx.message.date * 1000,
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
// Handle voice/audio
|
|
79
|
+
this.bot.on('message:voice', async (ctx) => {
|
|
80
|
+
(0, eventBus_1.emit)('channel:message', {
|
|
81
|
+
channel: 'telegram',
|
|
82
|
+
from: ctx.chat.id.toString(),
|
|
83
|
+
text: '[Voice message]',
|
|
84
|
+
media: [{ type: 'voice', url: ctx.message.voice.file_id }],
|
|
85
|
+
id: ctx.message.message_id.toString(),
|
|
86
|
+
isGroup: ctx.chat.type !== 'private',
|
|
87
|
+
timestamp: ctx.message.date * 1000,
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
// Slash commands
|
|
91
|
+
this.bot.command('start', async (ctx) => {
|
|
92
|
+
await ctx.reply('👋 *Welcome to ApexBot!*\n\n' +
|
|
93
|
+
'I\'m your personal AI assistant. Just send me a message!\n\n' +
|
|
94
|
+
'Commands:\n' +
|
|
95
|
+
'/status - Check bot status\n' +
|
|
96
|
+
'/new - Start fresh conversation\n' +
|
|
97
|
+
'/help - Show help', { parse_mode: 'Markdown' });
|
|
98
|
+
});
|
|
99
|
+
this.bot.command('status', async (ctx) => {
|
|
100
|
+
(0, eventBus_1.emit)('channel:message', {
|
|
101
|
+
channel: 'telegram',
|
|
102
|
+
from: ctx.chat.id.toString(),
|
|
103
|
+
text: '/status',
|
|
104
|
+
id: ctx.message.message_id.toString(),
|
|
105
|
+
isGroup: ctx.chat.type !== 'private',
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
this.bot.command('new', async (ctx) => {
|
|
109
|
+
(0, eventBus_1.emit)('channel:message', {
|
|
110
|
+
channel: 'telegram',
|
|
111
|
+
from: ctx.chat.id.toString(),
|
|
112
|
+
text: '/new',
|
|
113
|
+
id: ctx.message.message_id.toString(),
|
|
114
|
+
isGroup: ctx.chat.type !== 'private',
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
async connect() {
|
|
119
|
+
this.status = 'connecting';
|
|
120
|
+
(0, eventBus_1.emit)('channel:status', { channel: 'telegram', status: 'connecting' });
|
|
121
|
+
try {
|
|
122
|
+
await this.bot.start({
|
|
123
|
+
onStart: () => {
|
|
124
|
+
this.status = 'connected';
|
|
125
|
+
(0, eventBus_1.emit)('channel:status', { channel: 'telegram', status: 'connected' });
|
|
126
|
+
console.log('[Telegram] Connected and polling');
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
catch (e) {
|
|
131
|
+
this.status = 'error';
|
|
132
|
+
(0, eventBus_1.emit)('channel:status', { channel: 'telegram', status: 'error', data: e });
|
|
133
|
+
throw e;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async disconnect() {
|
|
137
|
+
this.bot.stop();
|
|
138
|
+
this.status = 'disconnected';
|
|
139
|
+
(0, eventBus_1.emit)('channel:status', { channel: 'telegram', status: 'disconnected' });
|
|
140
|
+
}
|
|
141
|
+
async send(to, text, replyTo) {
|
|
142
|
+
const chatId = parseInt(to, 10);
|
|
143
|
+
const options = { parse_mode: 'Markdown' };
|
|
144
|
+
if (replyTo) {
|
|
145
|
+
options.reply_to_message_id = parseInt(replyTo, 10);
|
|
146
|
+
}
|
|
147
|
+
// Split long messages
|
|
148
|
+
const maxLength = 4096;
|
|
149
|
+
if (text.length <= maxLength) {
|
|
150
|
+
await this.bot.api.sendMessage(chatId, text, options);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
// Split at paragraph or sentence boundaries
|
|
154
|
+
const chunks = this.splitMessage(text, maxLength);
|
|
155
|
+
for (const chunk of chunks) {
|
|
156
|
+
await this.bot.api.sendMessage(chatId, chunk, options);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
splitMessage(text, maxLength) {
|
|
161
|
+
const chunks = [];
|
|
162
|
+
let remaining = text;
|
|
163
|
+
while (remaining.length > 0) {
|
|
164
|
+
if (remaining.length <= maxLength) {
|
|
165
|
+
chunks.push(remaining);
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
// Find a good split point
|
|
169
|
+
let splitAt = remaining.lastIndexOf('\n\n', maxLength);
|
|
170
|
+
if (splitAt < maxLength / 2) {
|
|
171
|
+
splitAt = remaining.lastIndexOf('\n', maxLength);
|
|
172
|
+
}
|
|
173
|
+
if (splitAt < maxLength / 2) {
|
|
174
|
+
splitAt = remaining.lastIndexOf('. ', maxLength);
|
|
175
|
+
}
|
|
176
|
+
if (splitAt < maxLength / 2) {
|
|
177
|
+
splitAt = maxLength;
|
|
178
|
+
}
|
|
179
|
+
chunks.push(remaining.slice(0, splitAt));
|
|
180
|
+
remaining = remaining.slice(splitAt).trim();
|
|
181
|
+
}
|
|
182
|
+
return chunks;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
exports.TelegramChannel = TelegramChannel;
|
|
186
|
+
exports.default = TelegramChannel;
|