@ebowwa/glm-daemon-telegram 1.0.0 → 1.0.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.
@@ -0,0 +1,22 @@
1
+ /**
2
+ * GLM Daemon Telegram Bot
3
+ *
4
+ * Full-featured Telegram bot with GLM-4.7 AI, git status, Doppler integration
5
+ *
6
+ * Features:
7
+ * - GLM-4.7 AI responses via Z.AI API
8
+ * - 429 rate limit handling with exponential backoff
9
+ * - /git command for git status + GitHub auth
10
+ * - /doppler command for Doppler secrets status
11
+ * - Rolling API key support
12
+ */
13
+ declare class TelegramGLMBot {
14
+ private bot;
15
+ constructor(token: string);
16
+ start(): Promise<void>;
17
+ getGLMResponse(userMessage: string, userName: string): Promise<string>;
18
+ sendTestMessage(chatId: number): Promise<void>;
19
+ stop(): Promise<void>;
20
+ }
21
+ export { TelegramGLMBot };
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAqEH,cAAM,cAAc;IAClB,OAAO,CAAC,GAAG,CAAc;gBAEb,KAAK,EAAE,MAAM;IAInB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA8MtB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiDtE,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB9C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAI5B;AA8BD,OAAO,EAAE,cAAc,EAAE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,344 @@
1
+ /**
2
+ * GLM Daemon Telegram Bot
3
+ *
4
+ * Full-featured Telegram bot with GLM-4.7 AI, git status, Doppler integration
5
+ *
6
+ * Features:
7
+ * - GLM-4.7 AI responses via Z.AI API
8
+ * - 429 rate limit handling with exponential backoff
9
+ * - /git command for git status + GitHub auth
10
+ * - /doppler command for Doppler secrets status
11
+ * - Rolling API key support
12
+ */
13
+ import TelegramBot from 'node-telegram-bot-api';
14
+ import { execSync } from 'child_process';
15
+ const TELEGRAM_BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN || '';
16
+ const TELEGRAM_TEST_CHAT_ID = process.env.TELEGRAM_TEST_CHAT_ID || '';
17
+ // API Key Resolution - supports rolling keys
18
+ const getZAIKey = () => {
19
+ const keyValue = process.env.Z_AI_API_KEY || process.env.ANTHROPIC_API_KEYS;
20
+ if (!keyValue)
21
+ return null;
22
+ try {
23
+ const keysArray = JSON.parse(keyValue);
24
+ if (Array.isArray(keysArray) && keysArray.length > 0) {
25
+ return keysArray[0];
26
+ }
27
+ }
28
+ catch {
29
+ return keyValue;
30
+ }
31
+ return keyValue;
32
+ };
33
+ const ZAI_API_ENDPOINT = 'https://api.z.ai/api/coding/paas/v4/chat/completions';
34
+ // Retry helper with exponential backoff for 429 handling
35
+ const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
36
+ async function fetchWithRetry(url, options, maxRetries = 3, baseDelay = 1000) {
37
+ let lastError = null;
38
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
39
+ try {
40
+ const response = await fetch(url, options);
41
+ if (response.status === 429) {
42
+ const retryAfter = response.headers.get('Retry-After');
43
+ const delay = retryAfter
44
+ ? parseInt(retryAfter) * 1000
45
+ : baseDelay * Math.pow(2, attempt);
46
+ console.log(`[429] Rate limited, retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})`);
47
+ await sleep(delay);
48
+ continue;
49
+ }
50
+ if (!response.ok) {
51
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
52
+ }
53
+ return response;
54
+ }
55
+ catch (error) {
56
+ lastError = error;
57
+ if (attempt < maxRetries - 1) {
58
+ const delay = baseDelay * Math.pow(2, attempt);
59
+ console.log(`[Retry] Attempt ${attempt + 1} failed: ${lastError.message}, retrying in ${delay}ms`);
60
+ await sleep(delay);
61
+ }
62
+ }
63
+ }
64
+ throw lastError;
65
+ }
66
+ class TelegramGLMBot {
67
+ bot;
68
+ constructor(token) {
69
+ this.bot = new TelegramBot(token, { polling: true });
70
+ }
71
+ async start() {
72
+ console.log('🤖 GLM Daemon Telegram Bot starting with GLM-4.7...');
73
+ // /start command
74
+ this.bot.onText(/\/start/, async (msg) => {
75
+ const chatId = msg.chat.id;
76
+ await this.bot.sendMessage(chatId, '👋 Hello! I\'m GLM Daemon Telegram Bot.\n\n' +
77
+ '🧠 Powered by GLM-4.7 via Z.AI API\n\n' +
78
+ 'Commands:\n' +
79
+ '/start - Show this message\n' +
80
+ '/status - Check API status\n' +
81
+ '/git - Check git status & GitHub auth\n' +
82
+ '/doppler - Check Doppler config\n' +
83
+ '/help - Show help\n\n' +
84
+ 'Or just send any message for AI assistance!');
85
+ });
86
+ // /status command
87
+ this.bot.onText(/\/status/, async (msg) => {
88
+ const chatId = msg.chat.id;
89
+ const apiKey = getZAIKey();
90
+ const status = {
91
+ api: !!apiKey,
92
+ key: apiKey ? `${apiKey.slice(0, 10)}...` : 'None',
93
+ endpoint: ZAI_API_ENDPOINT
94
+ };
95
+ await this.bot.sendMessage(chatId, `📊 Bot Status:\n\n` +
96
+ `✅ API: ${status.api ? 'Connected' : 'Disconnected'}\n` +
97
+ `🔑 Key: ${status.key ? 'Configured' : 'Missing'}\n` +
98
+ `📍 Endpoint: ${status.endpoint}`);
99
+ });
100
+ // /help command
101
+ this.bot.onText(/\/help/, async (msg) => {
102
+ const chatId = msg.chat.id;
103
+ await this.bot.sendMessage(chatId, '📚 *GLM Daemon Bot Help*\n\n' +
104
+ '🧠 Powered by GLM-4.7 via Z.AI API\n\n' +
105
+ '*Commands:*\n' +
106
+ '/start - Show welcome message\n' +
107
+ '/status - Check API status\n' +
108
+ '/git - Check git status & GitHub auth\n' +
109
+ '/git auth - Start GitHub auth flow\n' +
110
+ '/doppler - Check Doppler config\n' +
111
+ '/doppler secrets - List secret names\n' +
112
+ '/help - Show this help\n\n' +
113
+ '*Usage:*\n' +
114
+ 'Just send any message and I\\\'ll respond with AI assistance!', { parse_mode: 'Markdown' });
115
+ });
116
+ // /git command
117
+ this.bot.onText(/\/git(?:\s+(.+))?/, async (msg, match) => {
118
+ const chatId = msg.chat.id;
119
+ const subCommand = match?.[1]?.trim();
120
+ try {
121
+ if (subCommand === 'auth') {
122
+ let statusMsg = 'GitHub Auth\n\n';
123
+ try {
124
+ const deviceResp = execSync('gh auth login --web --git-protocol https 2>&1 | head -20', {
125
+ encoding: 'utf-8',
126
+ timeout: 8000,
127
+ cwd: '/root'
128
+ });
129
+ const codeMatch = deviceResp.match(/verification code:\s*([A-Z0-9-]+)/i);
130
+ const urlMatch = deviceResp.match(/https:\/\/github\.com\/login\/device[^\s]*/);
131
+ if (codeMatch && urlMatch) {
132
+ statusMsg += `Code: ${codeMatch[1]}\n`;
133
+ statusMsg += `URL: ${urlMatch[0]}\n\n`;
134
+ statusMsg += `Open URL and enter code to authenticate.`;
135
+ }
136
+ else {
137
+ statusMsg += deviceResp.slice(0, 500);
138
+ }
139
+ }
140
+ catch (e) {
141
+ statusMsg += `Error: ${e.message}`;
142
+ }
143
+ await this.bot.sendMessage(chatId, statusMsg);
144
+ }
145
+ else {
146
+ let statusMsg = 'Git Status\n\n';
147
+ try {
148
+ const authStatus = execSync('gh auth status 2>&1', { encoding: 'utf-8', cwd: '/root' });
149
+ const loggedIn = authStatus.includes('Logged in');
150
+ const accountMatch = authStatus.match(/account\s+(\w+)/i);
151
+ statusMsg += `GitHub: ${loggedIn ? 'Connected' : 'Not logged in'}\n`;
152
+ if (accountMatch)
153
+ statusMsg += `Account: ${accountMatch[1]}\n`;
154
+ if (!loggedIn)
155
+ statusMsg += `\nUse /git auth to authenticate`;
156
+ }
157
+ catch {
158
+ statusMsg += `GitHub: Not authenticated\n`;
159
+ statusMsg += `Use /git auth to login\n`;
160
+ }
161
+ try {
162
+ const branch = execSync('git rev-parse --abbrev-ref HEAD 2>/dev/null', { encoding: 'utf-8', cwd: '/root' }).trim();
163
+ const ahead = execSync('git rev-list --count @{upstream}..HEAD 2>/dev/null || echo 0', { encoding: 'utf-8', cwd: '/root' }).trim();
164
+ const dirty = execSync('git status --porcelain 2>/dev/null | wc -l', { encoding: 'utf-8', cwd: '/root' }).trim();
165
+ statusMsg += `\nRepo:\n`;
166
+ statusMsg += `Branch: ${branch}\n`;
167
+ statusMsg += `Ahead: ${ahead} commits\n`;
168
+ statusMsg += `Modified: ${dirty} files`;
169
+ }
170
+ catch {
171
+ statusMsg += `\nRepo: Not a git repo or error`;
172
+ }
173
+ await this.bot.sendMessage(chatId, statusMsg);
174
+ }
175
+ }
176
+ catch (error) {
177
+ await this.bot.sendMessage(chatId, `Error: ${error.message}`);
178
+ }
179
+ });
180
+ // /doppler command
181
+ this.bot.onText(/\/doppler(?:\s+(.+))?/, async (msg, match) => {
182
+ const chatId = msg.chat.id;
183
+ const subCommand = match?.[1]?.trim();
184
+ try {
185
+ if (subCommand === 'secrets') {
186
+ let statusMsg = 'Doppler Secrets\n\n';
187
+ try {
188
+ const secrets = execSync('doppler secrets --plain 2>&1 | cut -d\'\\t\' -f1', {
189
+ encoding: 'utf-8',
190
+ cwd: '/root'
191
+ });
192
+ const secretList = secrets.trim().split('\n').filter(s => s.length > 0);
193
+ statusMsg += `Found ${secretList.length} secrets:\n\n`;
194
+ statusMsg += secretList.slice(0, 20).join('\n');
195
+ if (secretList.length > 20) {
196
+ statusMsg += `\n... and ${secretList.length - 20} more`;
197
+ }
198
+ }
199
+ catch (e) {
200
+ statusMsg += `Error: ${e.message}`;
201
+ }
202
+ await this.bot.sendMessage(chatId, statusMsg);
203
+ }
204
+ else {
205
+ let statusMsg = 'Doppler Status\n\n';
206
+ try {
207
+ const project = execSync('doppler configure get project 2>/dev/null', { encoding: 'utf-8', cwd: '/root' }).trim();
208
+ const config = execSync('doppler configure get config 2>/dev/null', { encoding: 'utf-8', cwd: '/root' }).trim();
209
+ statusMsg += `Project: ${project || 'Not set'}\n`;
210
+ statusMsg += `Config: ${config || 'Not set'}\n`;
211
+ const tokenCheck = execSync('doppler me 2>&1 | head -5', { encoding: 'utf-8', cwd: '/root' });
212
+ if (tokenCheck.includes('email') || tokenCheck.includes('name')) {
213
+ statusMsg += `Token: Valid\n`;
214
+ }
215
+ else {
216
+ statusMsg += `Token: Not configured\n`;
217
+ }
218
+ statusMsg += `\nCommands:\n`;
219
+ statusMsg += `/doppler secrets - List secret names`;
220
+ }
221
+ catch {
222
+ statusMsg += `Not configured\n\n`;
223
+ statusMsg += `Run: doppler setup`;
224
+ }
225
+ await this.bot.sendMessage(chatId, statusMsg);
226
+ }
227
+ }
228
+ catch (error) {
229
+ await this.bot.sendMessage(chatId, `Error: ${error.message}`);
230
+ }
231
+ });
232
+ // Handle all text messages with GLM-4.7
233
+ this.bot.on('message', async (msg) => {
234
+ if (!msg.text)
235
+ return;
236
+ if (msg.text.startsWith('/'))
237
+ return;
238
+ const chatId = msg.chat.id;
239
+ const userName = msg.from?.first_name || msg.from?.username || 'User';
240
+ console.log(`[Telegram] ${userName}: ${msg.text}`);
241
+ await this.bot.sendChatAction(chatId, 'typing');
242
+ const response = await this.getGLMResponse(msg.text, userName);
243
+ await this.bot.sendMessage(chatId, response);
244
+ });
245
+ // Polling errors
246
+ this.bot.on('polling_error', (error) => {
247
+ console.error('[Telegram] Polling error:', error.message);
248
+ });
249
+ console.log('✅ Telegram bot is running with GLM-4.7!');
250
+ if (TELEGRAM_TEST_CHAT_ID) {
251
+ await this.sendTestMessage(Number(TELEGRAM_TEST_CHAT_ID));
252
+ }
253
+ else {
254
+ console.log('\n💡 Tip: Get your chat ID from @userinfobot and set TELEGRAM_TEST_CHAT_ID');
255
+ }
256
+ }
257
+ async getGLMResponse(userMessage, userName) {
258
+ const apiKey = getZAIKey();
259
+ if (!apiKey) {
260
+ return '⚠️ Z_AI_API_KEY not configured in Doppler secrets.\n\nPlease set Z_AI_API_KEY to use GLM-4.7.';
261
+ }
262
+ try {
263
+ console.log(`🔄 Calling GLM-4.7 API for: ${userMessage}`);
264
+ const response = await fetchWithRetry(ZAI_API_ENDPOINT, {
265
+ method: 'POST',
266
+ headers: {
267
+ 'Content-Type': 'application/json',
268
+ 'Authorization': `Bearer ${apiKey}`
269
+ },
270
+ body: JSON.stringify({
271
+ model: 'glm-4.7',
272
+ messages: [
273
+ {
274
+ role: 'system',
275
+ content: 'You are GLM Daemon, an autonomous AI assistant that helps with coding tasks, questions, and feature development. You are running as part of a distributed system with Telegram and Discord channels. Be helpful, concise, and technical.'
276
+ },
277
+ { role: 'user', content: userMessage }
278
+ ],
279
+ temperature: 0.7,
280
+ max_tokens: 2048
281
+ })
282
+ }, 3, 1000);
283
+ const data = await response.json();
284
+ if (data.choices?.[0]?.message?.content) {
285
+ const aiResponse = data.choices[0].message.content;
286
+ console.log(`✅ GLM-4.7 response: ${aiResponse.slice(0, 100)}...`);
287
+ return aiResponse;
288
+ }
289
+ else {
290
+ console.error('❌ Unexpected API response format:', data);
291
+ return '❌ Unexpected response from AI API.';
292
+ }
293
+ }
294
+ catch (error) {
295
+ console.error('❌ Error calling GLM-4.7:', error.message);
296
+ if (error.message.includes('429')) {
297
+ return '⚠️ Rate limited by API. Please try again in a moment.';
298
+ }
299
+ return `❌ Error: ${error.message}`;
300
+ }
301
+ }
302
+ async sendTestMessage(chatId) {
303
+ const apiKey = getZAIKey();
304
+ await this.bot.sendMessage(chatId, '✅ GLM Daemon Telegram Bot is NOW ONLINE!\n\n' +
305
+ '🎉 Connected from seed-node-prod!\n\n' +
306
+ `🧠 AI: ${apiKey ? 'GLM-4.7 via Z.AI' : 'Not configured'}\n\n` +
307
+ 'Commands:\n' +
308
+ '/start - Show welcome message\n' +
309
+ '/status - Check API status\n' +
310
+ '/git - Git & GitHub status\n' +
311
+ '/doppler - Doppler config\n' +
312
+ '/help - Show all commands\n' +
313
+ 'Any message - Chat with GLM-4.7 AI');
314
+ console.log(`✅ Test message sent to chat ${chatId}`);
315
+ }
316
+ async stop() {
317
+ console.log('🛑 Stopping Telegram bot...');
318
+ this.bot.stopPolling();
319
+ }
320
+ }
321
+ // Main entry point
322
+ async function main() {
323
+ if (!TELEGRAM_BOT_TOKEN) {
324
+ console.error('❌ TELEGRAM_BOT_TOKEN not found in Doppler secrets');
325
+ console.error('Make sure to set in your seed/prd Doppler project');
326
+ process.exit(1);
327
+ }
328
+ console.log(`📱 Bot token loaded: ${TELEGRAM_BOT_TOKEN.substring(0, 10)}...`);
329
+ console.log(`🤖 Bot name: @SimulationapiBot`);
330
+ const bot = new TelegramGLMBot(TELEGRAM_BOT_TOKEN);
331
+ await bot.start();
332
+ process.on('SIGINT', async () => {
333
+ await bot.stop();
334
+ process.exit(0);
335
+ });
336
+ process.on('SIGTERM', async () => {
337
+ await bot.stop();
338
+ process.exit(0);
339
+ });
340
+ }
341
+ main().catch(console.error);
342
+ // Export for use as module
343
+ export { TelegramGLMBot };
344
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,15 @@
1
1
  {
2
2
  "name": "@ebowwa/glm-daemon-telegram",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Telegram adapter for GLM Daemon with ButlerAgent personality",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "src",
11
+ "README.md"
12
+ ],
8
13
  "exports": {
9
14
  ".": {
10
15
  "types": "./dist/index.d.ts",
package/src/index.js ADDED
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ /**
3
+ * GLM Daemon Telegram Bot
4
+ *
5
+ * Simple Telegram adapter - sends test message and echoes messages
6
+ */
7
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
8
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
9
+ return new (P || (P = Promise))(function (resolve, reject) {
10
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
11
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
12
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
13
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
14
+ });
15
+ };
16
+ var __generator = (this && this.__generator) || function (thisArg, body) {
17
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
18
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
19
+ function verb(n) { return function (v) { return step([n, v]); }; }
20
+ function step(op) {
21
+ if (f) throw new TypeError("Generator is already executing.");
22
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
23
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
24
+ if (y = 0, t) op = [op[0] & 2, t.value];
25
+ switch (op[0]) {
26
+ case 0: case 1: t = op; break;
27
+ case 4: _.label++; return { value: op[1], done: false };
28
+ case 5: _.label++; y = op[1]; op = [0]; continue;
29
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
30
+ default:
31
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
32
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
33
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
34
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
35
+ if (t[2]) _.ops.pop();
36
+ _.trys.pop(); continue;
37
+ }
38
+ op = body.call(thisArg, _);
39
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
40
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
41
+ }
42
+ };
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ var node_telegram_bot_api_1 = require("node-telegram-bot-api");
45
+ var TELEGRAM_BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN || '';
46
+ var TELEGRAM_TEST_CHAT_ID = process.env.TELEGRAM_TEST_CHAT_ID || '';
47
+ var TelegramGLMBot = /** @class */ (function () {
48
+ function TelegramGLMBot(token) {
49
+ this.bot = new node_telegram_bot_api_1.TelegramBot(token, { polling: true });
50
+ }
51
+ /**
52
+ * Start the bot and register handlers
53
+ */
54
+ TelegramGLMBot.prototype.start = function () {
55
+ return __awaiter(this, void 0, void 0, function () {
56
+ var _this = this;
57
+ return __generator(this, function (_a) {
58
+ console.log('🤖 GLM Daemon Telegram Bot starting...');
59
+ // Handle /start command
60
+ this.bot.onText(/\/start/, function (msg) { return __awaiter(_this, void 0, void 0, function () {
61
+ var chatId;
62
+ return __generator(this, function (_a) {
63
+ switch (_a.label) {
64
+ case 0:
65
+ chatId = msg.chat.id;
66
+ return [4 /*yield*/, this.bot.sendMessage(chatId, '👋 Hello! I\'m the GLM Daemon Telegram Bot.\n\n' +
67
+ 'I\'m currently in simple echo mode.\n' +
68
+ 'Just send me a message and I\'ll echo it back!\n\n' +
69
+ 'Full Butler AI personality coming soon!')];
70
+ case 1:
71
+ _a.sent();
72
+ return [2 /*return*/];
73
+ }
74
+ });
75
+ }); });
76
+ // Handle all text messages
77
+ this.bot.on('message', function (msg) { return __awaiter(_this, void 0, void 0, function () {
78
+ var chatId, userName, response;
79
+ var _a, _b;
80
+ return __generator(this, function (_c) {
81
+ switch (_c.label) {
82
+ case 0:
83
+ // Ignore non-text messages
84
+ if (!msg.text)
85
+ return [2 /*return*/];
86
+ // Ignore commands
87
+ if (msg.text.startsWith('/'))
88
+ return [2 /*return*/];
89
+ chatId = msg.chat.id;
90
+ userName = ((_a = msg.from) === null || _a === void 0 ? void 0 : _a.first_name) || ((_b = msg.from) === null || _b === void 0 ? void 0 : _b.username) || 'User';
91
+ console.log("[Telegram] ".concat(userName, ": ").concat(msg.text));
92
+ response = "\uD83D\uDCE2 You said: \"".concat(msg.text, "\"\n\n\u2705 Bot is working! Full AI responses coming soon.");
93
+ return [4 /*yield*/, this.bot.sendMessage(chatId, response)];
94
+ case 1:
95
+ _c.sent();
96
+ return [2 /*return*/];
97
+ }
98
+ });
99
+ }); });
100
+ // Handle polling errors
101
+ this.bot.on('polling_error', function (error) {
102
+ console.error('[Telegram] Polling error:', error);
103
+ });
104
+ console.log('✅ Telegram bot is running!');
105
+ return [2 /*return*/];
106
+ });
107
+ });
108
+ };
109
+ /**
110
+ * Send a test message to verify bot is working
111
+ */
112
+ TelegramGLMBot.prototype.sendTestMessage = function (chatId) {
113
+ return __awaiter(this, void 0, void 0, function () {
114
+ return __generator(this, function (_a) {
115
+ switch (_a.label) {
116
+ case 0: return [4 /*yield*/, this.bot.sendMessage(chatId, '✅ GLM Daemon Telegram Bot is NOW ONLINE!\n\n' +
117
+ '🎉 The bot is working correctly!\n\n' +
118
+ 'Commands:\n' +
119
+ '/start - Show welcome message\n' +
120
+ 'Any message - Echo test\n\n' +
121
+ 'Full AI personality integration coming soon!')];
122
+ case 1:
123
+ _a.sent();
124
+ console.log("\u2705 Test message sent to chat ".concat(chatId));
125
+ return [2 /*return*/];
126
+ }
127
+ });
128
+ });
129
+ };
130
+ /**
131
+ * Stop the bot
132
+ */
133
+ TelegramGLMBot.prototype.stop = function () {
134
+ return __awaiter(this, void 0, void 0, function () {
135
+ return __generator(this, function (_a) {
136
+ console.log('🛑 Stopping Telegram bot...');
137
+ this.bot.stopPolling();
138
+ return [2 /*return*/];
139
+ });
140
+ });
141
+ };
142
+ return TelegramGLMBot;
143
+ }());
144
+ /**
145
+ * Main entry point
146
+ */
147
+ function main() {
148
+ return __awaiter(this, void 0, void 0, function () {
149
+ var bot;
150
+ var _this = this;
151
+ return __generator(this, function (_a) {
152
+ switch (_a.label) {
153
+ case 0:
154
+ if (!TELEGRAM_BOT_TOKEN) {
155
+ console.error('❌ TELEGRAM_BOT_TOKEN not set');
156
+ console.error('Get your token from @BotFather on Telegram');
157
+ process.exit(1);
158
+ }
159
+ console.log("\uD83D\uDCF1 Bot token loaded: ".concat(TELEGRAM_BOT_TOKEN.substring(0, 10), "..."));
160
+ bot = new TelegramGLMBot(TELEGRAM_BOT_TOKEN);
161
+ return [4 /*yield*/, bot.start()];
162
+ case 1:
163
+ _a.sent();
164
+ if (!TELEGRAM_TEST_CHAT_ID) return [3 /*break*/, 3];
165
+ return [4 /*yield*/, bot.sendTestMessage(Number(TELEGRAM_TEST_CHAT_ID))];
166
+ case 2:
167
+ _a.sent();
168
+ return [3 /*break*/, 4];
169
+ case 3:
170
+ console.log('');
171
+ console.log('⚠️ No TELEGRAM_TEST_CHAT_ID set.');
172
+ console.log(' Send /start to your bot to test it!');
173
+ console.log(' Or get your chat ID from @userinfobot');
174
+ console.log('');
175
+ _a.label = 4;
176
+ case 4:
177
+ // Handle graceful shutdown
178
+ process.on('SIGINT', function () { return __awaiter(_this, void 0, void 0, function () {
179
+ return __generator(this, function (_a) {
180
+ switch (_a.label) {
181
+ case 0: return [4 /*yield*/, bot.stop()];
182
+ case 1:
183
+ _a.sent();
184
+ process.exit(0);
185
+ return [2 /*return*/];
186
+ }
187
+ });
188
+ }); });
189
+ process.on('SIGTERM', function () { return __awaiter(_this, void 0, void 0, function () {
190
+ return __generator(this, function (_a) {
191
+ switch (_a.label) {
192
+ case 0: return [4 /*yield*/, bot.stop()];
193
+ case 1:
194
+ _a.sent();
195
+ process.exit(0);
196
+ return [2 /*return*/];
197
+ }
198
+ });
199
+ }); });
200
+ return [2 /*return*/];
201
+ }
202
+ });
203
+ });
204
+ }
205
+ main().catch(console.error);
package/src/index.ts CHANGED
@@ -1,14 +1,83 @@
1
1
  /**
2
2
  * GLM Daemon Telegram Bot
3
3
  *
4
- * Simple Telegram adapter - sends test message and echoes messages
4
+ * Full-featured Telegram bot with GLM-4.7 AI, git status, Doppler integration
5
+ *
6
+ * Features:
7
+ * - GLM-4.7 AI responses via Z.AI API
8
+ * - 429 rate limit handling with exponential backoff
9
+ * - /git command for git status + GitHub auth
10
+ * - /doppler command for Doppler secrets status
11
+ * - Rolling API key support
5
12
  */
6
13
 
7
14
  import TelegramBot from 'node-telegram-bot-api';
15
+ import { execSync } from 'child_process';
8
16
 
9
17
  const TELEGRAM_BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN || '';
10
18
  const TELEGRAM_TEST_CHAT_ID = process.env.TELEGRAM_TEST_CHAT_ID || '';
11
19
 
20
+ // API Key Resolution - supports rolling keys
21
+ const getZAIKey = (): string | null => {
22
+ const keyValue = process.env.Z_AI_API_KEY || process.env.ANTHROPIC_API_KEYS;
23
+ if (!keyValue) return null;
24
+ try {
25
+ const keysArray = JSON.parse(keyValue);
26
+ if (Array.isArray(keysArray) && keysArray.length > 0) {
27
+ return keysArray[0];
28
+ }
29
+ } catch {
30
+ return keyValue;
31
+ }
32
+ return keyValue;
33
+ };
34
+
35
+ const ZAI_API_ENDPOINT = 'https://api.z.ai/api/coding/paas/v4/chat/completions';
36
+
37
+ // Retry helper with exponential backoff for 429 handling
38
+ const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
39
+
40
+ async function fetchWithRetry(
41
+ url: string,
42
+ options: RequestInit,
43
+ maxRetries = 3,
44
+ baseDelay = 1000
45
+ ): Promise<Response> {
46
+ let lastError: Error | null = null;
47
+
48
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
49
+ try {
50
+ const response = await fetch(url, options);
51
+
52
+ if (response.status === 429) {
53
+ const retryAfter = response.headers.get('Retry-After');
54
+ const delay = retryAfter
55
+ ? parseInt(retryAfter) * 1000
56
+ : baseDelay * Math.pow(2, attempt);
57
+
58
+ console.log(`[429] Rate limited, retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})`);
59
+ await sleep(delay);
60
+ continue;
61
+ }
62
+
63
+ if (!response.ok) {
64
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
65
+ }
66
+
67
+ return response;
68
+ } catch (error) {
69
+ lastError = error as Error;
70
+ if (attempt < maxRetries - 1) {
71
+ const delay = baseDelay * Math.pow(2, attempt);
72
+ console.log(`[Retry] Attempt ${attempt + 1} failed: ${lastError.message}, retrying in ${delay}ms`);
73
+ await sleep(delay);
74
+ }
75
+ }
76
+ }
77
+
78
+ throw lastError;
79
+ }
80
+
12
81
  class TelegramGLMBot {
13
82
  private bot: TelegramBot;
14
83
 
@@ -16,104 +85,299 @@ class TelegramGLMBot {
16
85
  this.bot = new TelegramBot(token, { polling: true });
17
86
  }
18
87
 
19
- /**
20
- * Start the bot and register handlers
21
- */
22
88
  async start(): Promise<void> {
23
- console.log('🤖 GLM Daemon Telegram Bot starting...');
89
+ console.log('🤖 GLM Daemon Telegram Bot starting with GLM-4.7...');
24
90
 
25
- // Handle /start command
91
+ // /start command
26
92
  this.bot.onText(/\/start/, async (msg: TelegramBot.Message) => {
27
93
  const chatId = msg.chat.id;
28
94
  await this.bot.sendMessage(
29
95
  chatId,
30
- '👋 Hello! I\'m the GLM Daemon Telegram Bot.\n\n' +
31
- 'I\'m currently in simple echo mode.\n' +
32
- 'Just send me a message and I\'ll echo it back!\n\n' +
33
- 'Full Butler AI personality coming soon!'
96
+ '👋 Hello! I\'m GLM Daemon Telegram Bot.\n\n' +
97
+ '🧠 Powered by GLM-4.7 via Z.AI API\n\n' +
98
+ 'Commands:\n' +
99
+ '/start - Show this message\n' +
100
+ '/status - Check API status\n' +
101
+ '/git - Check git status & GitHub auth\n' +
102
+ '/doppler - Check Doppler config\n' +
103
+ '/help - Show help\n\n' +
104
+ 'Or just send any message for AI assistance!'
105
+ );
106
+ });
107
+
108
+ // /status command
109
+ this.bot.onText(/\/status/, async (msg: TelegramBot.Message) => {
110
+ const chatId = msg.chat.id;
111
+ const apiKey = getZAIKey();
112
+ const status = {
113
+ api: !!apiKey,
114
+ key: apiKey ? `${apiKey.slice(0, 10)}...` : 'None',
115
+ endpoint: ZAI_API_ENDPOINT
116
+ };
117
+ await this.bot.sendMessage(
118
+ chatId,
119
+ `📊 Bot Status:\n\n` +
120
+ `✅ API: ${status.api ? 'Connected' : 'Disconnected'}\n` +
121
+ `🔑 Key: ${status.key ? 'Configured' : 'Missing'}\n` +
122
+ `📍 Endpoint: ${status.endpoint}`
34
123
  );
35
124
  });
36
125
 
37
- // Handle all text messages
126
+ // /help command
127
+ this.bot.onText(/\/help/, async (msg: TelegramBot.Message) => {
128
+ const chatId = msg.chat.id;
129
+ await this.bot.sendMessage(
130
+ chatId,
131
+ '📚 *GLM Daemon Bot Help*\n\n' +
132
+ '🧠 Powered by GLM-4.7 via Z.AI API\n\n' +
133
+ '*Commands:*\n' +
134
+ '/start - Show welcome message\n' +
135
+ '/status - Check API status\n' +
136
+ '/git - Check git status & GitHub auth\n' +
137
+ '/git auth - Start GitHub auth flow\n' +
138
+ '/doppler - Check Doppler config\n' +
139
+ '/doppler secrets - List secret names\n' +
140
+ '/help - Show this help\n\n' +
141
+ '*Usage:*\n' +
142
+ 'Just send any message and I\\\'ll respond with AI assistance!',
143
+ { parse_mode: 'Markdown' }
144
+ );
145
+ });
146
+
147
+ // /git command
148
+ this.bot.onText(/\/git(?:\s+(.+))?/, async (msg: TelegramBot.Message, match: RegExpExecArray | null) => {
149
+ const chatId = msg.chat.id;
150
+ const subCommand = match?.[1]?.trim();
151
+
152
+ try {
153
+ if (subCommand === 'auth') {
154
+ let statusMsg = 'GitHub Auth\n\n';
155
+ try {
156
+ const deviceResp = execSync('gh auth login --web --git-protocol https 2>&1 | head -20', {
157
+ encoding: 'utf-8',
158
+ timeout: 8000,
159
+ cwd: '/root'
160
+ });
161
+ const codeMatch = deviceResp.match(/verification code:\s*([A-Z0-9-]+)/i);
162
+ const urlMatch = deviceResp.match(/https:\/\/github\.com\/login\/device[^\s]*/);
163
+
164
+ if (codeMatch && urlMatch) {
165
+ statusMsg += `Code: ${codeMatch[1]}\n`;
166
+ statusMsg += `URL: ${urlMatch[0]}\n\n`;
167
+ statusMsg += `Open URL and enter code to authenticate.`;
168
+ } else {
169
+ statusMsg += deviceResp.slice(0, 500);
170
+ }
171
+ } catch (e) {
172
+ statusMsg += `Error: ${(e as Error).message}`;
173
+ }
174
+ await this.bot.sendMessage(chatId, statusMsg);
175
+ } else {
176
+ let statusMsg = 'Git Status\n\n';
177
+
178
+ try {
179
+ const authStatus = execSync('gh auth status 2>&1', { encoding: 'utf-8', cwd: '/root' });
180
+ const loggedIn = authStatus.includes('Logged in');
181
+ const accountMatch = authStatus.match(/account\s+(\w+)/i);
182
+
183
+ statusMsg += `GitHub: ${loggedIn ? 'Connected' : 'Not logged in'}\n`;
184
+ if (accountMatch) statusMsg += `Account: ${accountMatch[1]}\n`;
185
+ if (!loggedIn) statusMsg += `\nUse /git auth to authenticate`;
186
+ } catch {
187
+ statusMsg += `GitHub: Not authenticated\n`;
188
+ statusMsg += `Use /git auth to login\n`;
189
+ }
190
+
191
+ try {
192
+ const branch = execSync('git rev-parse --abbrev-ref HEAD 2>/dev/null', { encoding: 'utf-8', cwd: '/root' }).trim();
193
+ const ahead = execSync('git rev-list --count @{upstream}..HEAD 2>/dev/null || echo 0', { encoding: 'utf-8', cwd: '/root' }).trim();
194
+ const dirty = execSync('git status --porcelain 2>/dev/null | wc -l', { encoding: 'utf-8', cwd: '/root' }).trim();
195
+
196
+ statusMsg += `\nRepo:\n`;
197
+ statusMsg += `Branch: ${branch}\n`;
198
+ statusMsg += `Ahead: ${ahead} commits\n`;
199
+ statusMsg += `Modified: ${dirty} files`;
200
+ } catch {
201
+ statusMsg += `\nRepo: Not a git repo or error`;
202
+ }
203
+
204
+ await this.bot.sendMessage(chatId, statusMsg);
205
+ }
206
+ } catch (error) {
207
+ await this.bot.sendMessage(chatId, `Error: ${(error as Error).message}`);
208
+ }
209
+ });
210
+
211
+ // /doppler command
212
+ this.bot.onText(/\/doppler(?:\s+(.+))?/, async (msg: TelegramBot.Message, match: RegExpExecArray | null) => {
213
+ const chatId = msg.chat.id;
214
+ const subCommand = match?.[1]?.trim();
215
+
216
+ try {
217
+ if (subCommand === 'secrets') {
218
+ let statusMsg = 'Doppler Secrets\n\n';
219
+ try {
220
+ const secrets = execSync('doppler secrets --plain 2>&1 | cut -d\'\\t\' -f1', {
221
+ encoding: 'utf-8',
222
+ cwd: '/root'
223
+ });
224
+ const secretList = secrets.trim().split('\n').filter(s => s.length > 0);
225
+ statusMsg += `Found ${secretList.length} secrets:\n\n`;
226
+ statusMsg += secretList.slice(0, 20).join('\n');
227
+ if (secretList.length > 20) {
228
+ statusMsg += `\n... and ${secretList.length - 20} more`;
229
+ }
230
+ } catch (e) {
231
+ statusMsg += `Error: ${(e as Error).message}`;
232
+ }
233
+ await this.bot.sendMessage(chatId, statusMsg);
234
+ } else {
235
+ let statusMsg = 'Doppler Status\n\n';
236
+
237
+ try {
238
+ const project = execSync('doppler configure get project 2>/dev/null', { encoding: 'utf-8', cwd: '/root' }).trim();
239
+ const config = execSync('doppler configure get config 2>/dev/null', { encoding: 'utf-8', cwd: '/root' }).trim();
240
+
241
+ statusMsg += `Project: ${project || 'Not set'}\n`;
242
+ statusMsg += `Config: ${config || 'Not set'}\n`;
243
+
244
+ const tokenCheck = execSync('doppler me 2>&1 | head -5', { encoding: 'utf-8', cwd: '/root' });
245
+ if (tokenCheck.includes('email') || tokenCheck.includes('name')) {
246
+ statusMsg += `Token: Valid\n`;
247
+ } else {
248
+ statusMsg += `Token: Not configured\n`;
249
+ }
250
+
251
+ statusMsg += `\nCommands:\n`;
252
+ statusMsg += `/doppler secrets - List secret names`;
253
+ } catch {
254
+ statusMsg += `Not configured\n\n`;
255
+ statusMsg += `Run: doppler setup`;
256
+ }
257
+
258
+ await this.bot.sendMessage(chatId, statusMsg);
259
+ }
260
+ } catch (error) {
261
+ await this.bot.sendMessage(chatId, `Error: ${(error as Error).message}`);
262
+ }
263
+ });
264
+
265
+ // Handle all text messages with GLM-4.7
38
266
  this.bot.on('message', async (msg: TelegramBot.Message) => {
39
- // Ignore non-text messages
40
267
  if (!msg.text) return;
41
-
42
- // Ignore commands
43
268
  if (msg.text.startsWith('/')) return;
44
269
 
45
270
  const chatId = msg.chat.id;
46
271
  const userName = msg.from?.first_name || msg.from?.username || 'User';
47
272
 
48
273
  console.log(`[Telegram] ${userName}: ${msg.text}`);
274
+ await this.bot.sendChatAction(chatId, 'typing');
49
275
 
50
- // Echo back with a friendly response
51
- const response = `📢 You said: "${msg.text}"\n\n✅ Bot is working! Full AI responses coming soon.`;
52
-
276
+ const response = await this.getGLMResponse(msg.text, userName);
53
277
  await this.bot.sendMessage(chatId, response);
54
278
  });
55
279
 
56
- // Handle polling errors
280
+ // Polling errors
57
281
  this.bot.on('polling_error', (error: Error) => {
58
- console.error('[Telegram] Polling error:', error);
282
+ console.error('[Telegram] Polling error:', error.message);
59
283
  });
60
284
 
61
- console.log('✅ Telegram bot is running!');
285
+ console.log('✅ Telegram bot is running with GLM-4.7!');
286
+
287
+ if (TELEGRAM_TEST_CHAT_ID) {
288
+ await this.sendTestMessage(Number(TELEGRAM_TEST_CHAT_ID));
289
+ } else {
290
+ console.log('\n💡 Tip: Get your chat ID from @userinfobot and set TELEGRAM_TEST_CHAT_ID');
291
+ }
292
+ }
293
+
294
+ async getGLMResponse(userMessage: string, userName: string): Promise<string> {
295
+ const apiKey = getZAIKey();
296
+ if (!apiKey) {
297
+ return '⚠️ Z_AI_API_KEY not configured in Doppler secrets.\n\nPlease set Z_AI_API_KEY to use GLM-4.7.';
298
+ }
299
+
300
+ try {
301
+ console.log(`🔄 Calling GLM-4.7 API for: ${userMessage}`);
302
+
303
+ const response = await fetchWithRetry(ZAI_API_ENDPOINT, {
304
+ method: 'POST',
305
+ headers: {
306
+ 'Content-Type': 'application/json',
307
+ 'Authorization': `Bearer ${apiKey}`
308
+ },
309
+ body: JSON.stringify({
310
+ model: 'glm-4.7',
311
+ messages: [
312
+ {
313
+ role: 'system',
314
+ content: 'You are GLM Daemon, an autonomous AI assistant that helps with coding tasks, questions, and feature development. You are running as part of a distributed system with Telegram and Discord channels. Be helpful, concise, and technical.'
315
+ },
316
+ { role: 'user', content: userMessage }
317
+ ],
318
+ temperature: 0.7,
319
+ max_tokens: 2048
320
+ })
321
+ }, 3, 1000);
322
+
323
+ const data = await response.json() as { choices?: Array<{ message?: { content?: string } }> };
324
+
325
+ if (data.choices?.[0]?.message?.content) {
326
+ const aiResponse = data.choices[0].message.content;
327
+ console.log(`✅ GLM-4.7 response: ${aiResponse.slice(0, 100)}...`);
328
+ return aiResponse;
329
+ } else {
330
+ console.error('❌ Unexpected API response format:', data);
331
+ return '❌ Unexpected response from AI API.';
332
+ }
333
+ } catch (error) {
334
+ console.error('❌ Error calling GLM-4.7:', (error as Error).message);
335
+
336
+ if ((error as Error).message.includes('429')) {
337
+ return '⚠️ Rate limited by API. Please try again in a moment.';
338
+ }
339
+ return `❌ Error: ${(error as Error).message}`;
340
+ }
62
341
  }
63
342
 
64
- /**
65
- * Send a test message to verify bot is working
66
- */
67
343
  async sendTestMessage(chatId: number): Promise<void> {
344
+ const apiKey = getZAIKey();
68
345
  await this.bot.sendMessage(
69
346
  chatId,
70
347
  '✅ GLM Daemon Telegram Bot is NOW ONLINE!\n\n' +
71
- '🎉 The bot is working correctly!\n\n' +
348
+ '🎉 Connected from seed-node-prod!\n\n' +
349
+ `🧠 AI: ${apiKey ? 'GLM-4.7 via Z.AI' : 'Not configured'}\n\n` +
72
350
  'Commands:\n' +
73
351
  '/start - Show welcome message\n' +
74
- 'Any message - Echo test\n\n' +
75
- 'Full AI personality integration coming soon!'
352
+ '/status - Check API status\n' +
353
+ '/git - Git & GitHub status\n' +
354
+ '/doppler - Doppler config\n' +
355
+ '/help - Show all commands\n' +
356
+ 'Any message - Chat with GLM-4.7 AI'
76
357
  );
77
358
  console.log(`✅ Test message sent to chat ${chatId}`);
78
359
  }
79
360
 
80
- /**
81
- * Stop the bot
82
- */
83
361
  async stop(): Promise<void> {
84
362
  console.log('🛑 Stopping Telegram bot...');
85
363
  this.bot.stopPolling();
86
364
  }
87
365
  }
88
366
 
89
- /**
90
- * Main entry point
91
- */
367
+ // Main entry point
92
368
  async function main() {
93
369
  if (!TELEGRAM_BOT_TOKEN) {
94
- console.error('❌ TELEGRAM_BOT_TOKEN not set');
95
- console.error('Get your token from @BotFather on Telegram');
370
+ console.error('❌ TELEGRAM_BOT_TOKEN not found in Doppler secrets');
371
+ console.error('Make sure to set in your seed/prd Doppler project');
96
372
  process.exit(1);
97
373
  }
98
374
 
99
375
  console.log(`📱 Bot token loaded: ${TELEGRAM_BOT_TOKEN.substring(0, 10)}...`);
376
+ console.log(`🤖 Bot name: @SimulationapiBot`);
100
377
 
101
- // Create and start bot
102
378
  const bot = new TelegramGLMBot(TELEGRAM_BOT_TOKEN);
103
379
  await bot.start();
104
380
 
105
- // Send test message if chat ID is provided
106
- if (TELEGRAM_TEST_CHAT_ID) {
107
- await bot.sendTestMessage(Number(TELEGRAM_TEST_CHAT_ID));
108
- } else {
109
- console.log('');
110
- console.log('⚠️ No TELEGRAM_TEST_CHAT_ID set.');
111
- console.log(' Send /start to your bot to test it!');
112
- console.log(' Or get your chat ID from @userinfobot');
113
- console.log('');
114
- }
115
-
116
- // Handle graceful shutdown
117
381
  process.on('SIGINT', async () => {
118
382
  await bot.stop();
119
383
  process.exit(0);
@@ -126,3 +390,6 @@ async function main() {
126
390
  }
127
391
 
128
392
  main().catch(console.error);
393
+
394
+ // Export for use as module
395
+ export { TelegramGLMBot };
package/CLAUDE.md DELETED
@@ -1,106 +0,0 @@
1
-
2
- Default to using Bun instead of Node.js.
3
-
4
- - Use `bun <file>` instead of `node <file>` or `ts-node <file>`
5
- - Use `bun test` instead of `jest` or `vitest`
6
- - Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`
7
- - Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
8
- - Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`
9
- - Use `bunx <package> <command>` instead of `npx <package> <command>`
10
- - Bun automatically loads .env, so don't use dotenv.
11
-
12
- ## APIs
13
-
14
- - `Bun.serve()` supports WebSockets, HTTPS, and routes. Don't use `express`.
15
- - `bun:sqlite` for SQLite. Don't use `better-sqlite3`.
16
- - `Bun.redis` for Redis. Don't use `ioredis`.
17
- - `Bun.sql` for Postgres. Don't use `pg` or `postgres.js`.
18
- - `WebSocket` is built-in. Don't use `ws`.
19
- - Prefer `Bun.file` over `node:fs`'s readFile/writeFile
20
- - Bun.$`ls` instead of execa.
21
-
22
- ## Testing
23
-
24
- Use `bun test` to run tests.
25
-
26
- ```ts#index.test.ts
27
- import { test, expect } from "bun:test";
28
-
29
- test("hello world", () => {
30
- expect(1).toBe(1);
31
- });
32
- ```
33
-
34
- ## Frontend
35
-
36
- Use HTML imports with `Bun.serve()`. Don't use `vite`. HTML imports fully support React, CSS, Tailwind.
37
-
38
- Server:
39
-
40
- ```ts#index.ts
41
- import index from "./index.html"
42
-
43
- Bun.serve({
44
- routes: {
45
- "/": index,
46
- "/api/users/:id": {
47
- GET: (req) => {
48
- return new Response(JSON.stringify({ id: req.params.id }));
49
- },
50
- },
51
- },
52
- // optional websocket support
53
- websocket: {
54
- open: (ws) => {
55
- ws.send("Hello, world!");
56
- },
57
- message: (ws, message) => {
58
- ws.send(message);
59
- },
60
- close: (ws) => {
61
- // handle close
62
- }
63
- },
64
- development: {
65
- hmr: true,
66
- console: true,
67
- }
68
- })
69
- ```
70
-
71
- HTML files can import .tsx, .jsx or .js files directly and Bun's bundler will transpile & bundle automatically. `<link>` tags can point to stylesheets and Bun's CSS bundler will bundle.
72
-
73
- ```html#index.html
74
- <html>
75
- <body>
76
- <h1>Hello, world!</h1>
77
- <script type="module" src="./frontend.tsx"></script>
78
- </body>
79
- </html>
80
- ```
81
-
82
- With the following `frontend.tsx`:
83
-
84
- ```tsx#frontend.tsx
85
- import React from "react";
86
- import { createRoot } from "react-dom/client";
87
-
88
- // import .css files directly and it works
89
- import './index.css';
90
-
91
- const root = createRoot(document.body);
92
-
93
- export default function Frontend() {
94
- return <h1>Hello, world!</h1>;
95
- }
96
-
97
- root.render(<Frontend />);
98
- ```
99
-
100
- Then, run index.ts
101
-
102
- ```sh
103
- bun --hot ./index.ts
104
- ```
105
-
106
- For more information, read the Bun API docs in `node_modules/bun-types/docs/**.mdx`.
package/TICKET.md DELETED
@@ -1,55 +0,0 @@
1
- # Deployment Ticket: GLM Daemon Telegram Bot
2
-
3
- ## Summary
4
- Deploy the GLM Daemon Telegram bot to Hetzner VPS
5
-
6
- ## VPS Details
7
- - **IP**: 46.225.83.174
8
- - **Name**: workflow-daemon
9
- - **Specs**: cax11 (2 vCPU, 4GB RAM)
10
- - **Location**: nbg1
11
- - **Status**: Running
12
-
13
- ## Requirements
14
- 1. Install dependencies (bun install)
15
- 2. Build TypeScript (bun run build)
16
- 3. Configure Doppler secrets (TELEGRAM_BOT_TOKEN, GLM_API_KEY)
17
- 4. Start the bot (bun run start)
18
- 5. Set up systemd service for persistent operation
19
-
20
- ## Known Issues
21
- - **Terminal MCP has recursive loop** - Cannot use mcp__terminal__exec_ssh
22
- - Use direct SSH or alternative deployment method
23
- - Package structure is ready at `/packages/src/glm-daemon-telegram/`
24
-
25
- ## Files Created
26
- - `package.json` - Dependencies (node-telegram-bot-api, doppler)
27
- - `src/index.ts` - Telegram bot with ButlerAgent
28
- - `deploy.sh` - Deployment script
29
- - `run.sh` - Quick run script
30
- - `tsconfig.json` - TypeScript config
31
- - `README.md` - Setup documentation
32
-
33
- ## Doppler Secrets Required
34
- - `TELEGRAM_BOT_TOKEN` - Telegram bot token from @BotFather
35
- - `TELEGRAM_TEST_CHAT_ID` - Your Telegram chat ID (optional)
36
- - `GLM_API_KEY` - GLM 4.7 API key (or ANTHROPIC_API_KEY)
37
- - `DOPPLER_TOKEN` - Doppler access token
38
-
39
- ## Success Criteria
40
- - Bot connects to Telegram
41
- - Sends test message on startup
42
- - Responds to messages with Butler personality
43
- - Persistent operation via systemd
44
-
45
- ## First Steps
46
- 1. Build locally: `bun run build`
47
- 2. Test locally: `doppler run -- bun run start`
48
- 3. Should see test message in Telegram
49
- 4. Then deploy to VPS
50
-
51
- ## Created
52
- 2026-02-06 - Initial package structure
53
-
54
- ## Priority
55
- HIGH - Ready for deployment once Terminal MCP is fixed
package/deploy.sh DELETED
@@ -1,26 +0,0 @@
1
- #!/bin/bash
2
- set -e
3
-
4
- echo "🚀 Deploying GLM Daemon Telegram Bot to Hetzner..."
5
-
6
- # Load secrets from Doppler
7
- echo "📦 Loading secrets from Doppler..."
8
- eval "$(doppler run --print-envs --token=$DOPPLER_TOKEN | grep -E '^(TELEGRAM_BOT_TOKEN|TELEGRAM_TEST_CHAT_ID|GLM_API_KEY|DOPPLER_TOKEN)=')"
9
-
10
- # Check required secrets
11
- if [[ -z "$TELEGRAM_BOT_TOKEN" ]]; then
12
- echo "❌ TELEGRAM_BOT_TOKEN not set"
13
- exit 1
14
- fi
15
-
16
- # Install dependencies
17
- echo "📥 Installing dependencies..."
18
- bun install
19
-
20
- # Build TypeScript
21
- echo "🔨 Building..."
22
- bun run build
23
-
24
- # Start bot
25
- echo "🤖 Starting Telegram bot..."
26
- bun run start
package/run.sh DELETED
@@ -1,3 +0,0 @@
1
- #!/bin/bash
2
- # Quick run script (uses existing Doppler CLI setup)
3
- doppler run -- bun run start
package/tsconfig.json DELETED
@@ -1,18 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "lib": ["ES2022"],
6
- "moduleResolution": "bundler",
7
- "outDir": "./dist",
8
- "rootDir": "./src",
9
- "declaration": true,
10
- "declarationMap": true,
11
- "sourceMap": true,
12
- "esModuleInterop": true,
13
- "skipLibCheck": true,
14
- "strict": true
15
- },
16
- "include": ["src/**/*"],
17
- "exclude": ["node_modules", "dist"]
18
- }