@ebowwa/glm-daemon 0.3.2 → 0.4.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/package.json +5 -5
- package/src/agent.js +166 -0
- package/src/builtin-tools.js +349 -0
- package/src/channels/base.js +509 -0
- package/src/channels/discord.js +374 -0
- package/src/channels/index.js +186 -0
- package/src/channels/telegram.js +395 -0
- package/src/daemon.js +593 -0
- package/src/daemon.ts +188 -1
- package/src/hooks.js +145 -0
- package/src/hooks.ts +3 -0
- package/src/index.js +123 -0
- package/src/memory.js +323 -0
- package/src/state.js +168 -0
- package/src/tools.js +192 -0
- package/src/types.js +21 -0
- package/src/types.ts +62 -0
- package/src/worktree.js +195 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Discord Channel Adapter
|
|
4
|
+
*
|
|
5
|
+
* Implements ChannelConnector from @ebowwa/channel-types.
|
|
6
|
+
* Discord bot using discord.js.
|
|
7
|
+
*/
|
|
8
|
+
var __extends = (this && this.__extends) || (function () {
|
|
9
|
+
var extendStatics = function (d, b) {
|
|
10
|
+
extendStatics = Object.setPrototypeOf ||
|
|
11
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
12
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
13
|
+
return extendStatics(d, b);
|
|
14
|
+
};
|
|
15
|
+
return function (d, b) {
|
|
16
|
+
if (typeof b !== "function" && b !== null)
|
|
17
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
18
|
+
extendStatics(d, b);
|
|
19
|
+
function __() { this.constructor = d; }
|
|
20
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
21
|
+
};
|
|
22
|
+
})();
|
|
23
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
24
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
25
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
26
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
27
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
28
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
29
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
33
|
+
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);
|
|
34
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
35
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
36
|
+
function step(op) {
|
|
37
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
38
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
39
|
+
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;
|
|
40
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
41
|
+
switch (op[0]) {
|
|
42
|
+
case 0: case 1: t = op; break;
|
|
43
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
44
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
45
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
46
|
+
default:
|
|
47
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
48
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
49
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
50
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
51
|
+
if (t[2]) _.ops.pop();
|
|
52
|
+
_.trys.pop(); continue;
|
|
53
|
+
}
|
|
54
|
+
op = body.call(thisArg, _);
|
|
55
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
56
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
60
|
+
exports.DiscordChannel = void 0;
|
|
61
|
+
exports.createDiscordChannel = createDiscordChannel;
|
|
62
|
+
exports.createDiscordConfigFromEnv = createDiscordConfigFromEnv;
|
|
63
|
+
var discord_js_1 = require("discord.js");
|
|
64
|
+
var base_js_1 = require("./base.js");
|
|
65
|
+
// ============================================================
|
|
66
|
+
// DISCORD CHANNEL
|
|
67
|
+
// ============================================================
|
|
68
|
+
var DiscordChannel = /** @class */ (function (_super) {
|
|
69
|
+
__extends(DiscordChannel, _super);
|
|
70
|
+
function DiscordChannel(config) {
|
|
71
|
+
var _this = _super.call(this, config) || this;
|
|
72
|
+
_this.label = "Discord";
|
|
73
|
+
_this.capabilities = {
|
|
74
|
+
supports: {
|
|
75
|
+
text: true,
|
|
76
|
+
media: true,
|
|
77
|
+
replies: true,
|
|
78
|
+
threads: true,
|
|
79
|
+
reactions: true,
|
|
80
|
+
editing: true,
|
|
81
|
+
streaming: false, // Discord doesn't support true streaming
|
|
82
|
+
},
|
|
83
|
+
media: {
|
|
84
|
+
maxFileSize: 25 * 1024 * 1024, // 25MB (nitro is higher)
|
|
85
|
+
supportedMimeTypes: ["image/*", "video/*", "audio/*", "application/*"],
|
|
86
|
+
},
|
|
87
|
+
rateLimits: {
|
|
88
|
+
messagesPerMinute: 50,
|
|
89
|
+
charactersPerMessage: 2000,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
_this.token = config.botToken;
|
|
93
|
+
_this.guildId = config.guildId;
|
|
94
|
+
_this.channelIds = config.channelIds;
|
|
95
|
+
_this.id = _this.createId();
|
|
96
|
+
_this.client = new discord_js_1.Client({
|
|
97
|
+
intents: [
|
|
98
|
+
discord_js_1.GatewayIntentBits.Guilds,
|
|
99
|
+
discord_js_1.GatewayIntentBits.GuildMessages,
|
|
100
|
+
discord_js_1.GatewayIntentBits.MessageContent,
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
return _this;
|
|
104
|
+
}
|
|
105
|
+
// ============================================================
|
|
106
|
+
// ChannelConnector Implementation
|
|
107
|
+
// ============================================================
|
|
108
|
+
/**
|
|
109
|
+
* Send response to Discord
|
|
110
|
+
*/
|
|
111
|
+
DiscordChannel.prototype.send = function (response) {
|
|
112
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
113
|
+
var _a, channelId, messageId, channel, textChannel, message, error_1;
|
|
114
|
+
return __generator(this, function (_b) {
|
|
115
|
+
switch (_b.label) {
|
|
116
|
+
case 0:
|
|
117
|
+
_a = response.replyTo, channelId = _a.channelId, messageId = _a.messageId;
|
|
118
|
+
_b.label = 1;
|
|
119
|
+
case 1:
|
|
120
|
+
_b.trys.push([1, 8, , 9]);
|
|
121
|
+
return [4 /*yield*/, this.client.channels.fetch(channelId.accountId)];
|
|
122
|
+
case 2:
|
|
123
|
+
channel = _b.sent();
|
|
124
|
+
if (!channel || !channel.isTextBased()) {
|
|
125
|
+
console.error("[Discord] Cannot send: channel not found or not text-based");
|
|
126
|
+
return [2 /*return*/];
|
|
127
|
+
}
|
|
128
|
+
textChannel = channel;
|
|
129
|
+
return [4 /*yield*/, textChannel.messages.fetch(messageId)];
|
|
130
|
+
case 3:
|
|
131
|
+
message = _b.sent();
|
|
132
|
+
if (!response.content.replyToOriginal) return [3 /*break*/, 5];
|
|
133
|
+
return [4 /*yield*/, message.reply(response.content.text)];
|
|
134
|
+
case 4:
|
|
135
|
+
_b.sent();
|
|
136
|
+
return [3 /*break*/, 7];
|
|
137
|
+
case 5: return [4 /*yield*/, textChannel.send(response.content.text)];
|
|
138
|
+
case 6:
|
|
139
|
+
_b.sent();
|
|
140
|
+
_b.label = 7;
|
|
141
|
+
case 7: return [3 /*break*/, 9];
|
|
142
|
+
case 8:
|
|
143
|
+
error_1 = _b.sent();
|
|
144
|
+
console.error("[Discord] Error sending response:", error_1);
|
|
145
|
+
return [3 /*break*/, 9];
|
|
146
|
+
case 9: return [2 /*return*/];
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
// ============================================================
|
|
152
|
+
// Platform-Specific Implementation
|
|
153
|
+
// ============================================================
|
|
154
|
+
/**
|
|
155
|
+
* Start Discord bot
|
|
156
|
+
*/
|
|
157
|
+
DiscordChannel.prototype.startPlatform = function () {
|
|
158
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
159
|
+
var _this = this;
|
|
160
|
+
return __generator(this, function (_a) {
|
|
161
|
+
switch (_a.label) {
|
|
162
|
+
case 0:
|
|
163
|
+
console.log("[Discord] Starting bot...");
|
|
164
|
+
this.client.on("ready", function () {
|
|
165
|
+
var _a;
|
|
166
|
+
console.log("[Discord] Logged in as ".concat((_a = _this.client.user) === null || _a === void 0 ? void 0 : _a.tag));
|
|
167
|
+
console.log("[Discord] Ready to handle messages");
|
|
168
|
+
});
|
|
169
|
+
this.client.on("messageCreate", function (message) { return __awaiter(_this, void 0, void 0, function () {
|
|
170
|
+
var channelMessage, response, error_2;
|
|
171
|
+
var _a;
|
|
172
|
+
return __generator(this, function (_b) {
|
|
173
|
+
switch (_b.label) {
|
|
174
|
+
case 0:
|
|
175
|
+
// Ignore bot messages
|
|
176
|
+
if (message.author.bot)
|
|
177
|
+
return [2 /*return*/];
|
|
178
|
+
// Check guild restriction
|
|
179
|
+
if (this.guildId && message.guildId !== this.guildId) {
|
|
180
|
+
return [2 /*return*/];
|
|
181
|
+
}
|
|
182
|
+
// Check channel restriction
|
|
183
|
+
if (((_a = this.channelIds) === null || _a === void 0 ? void 0 : _a.length) && !this.channelIds.includes(message.channelId)) {
|
|
184
|
+
return [2 /*return*/];
|
|
185
|
+
}
|
|
186
|
+
console.log("[Discord] [".concat(message.author.tag, "]: ").concat(message.content));
|
|
187
|
+
if (!("sendTyping" in message.channel && typeof message.channel.sendTyping === "function")) return [3 /*break*/, 2];
|
|
188
|
+
return [4 /*yield*/, message.channel.sendTyping()];
|
|
189
|
+
case 1:
|
|
190
|
+
_b.sent();
|
|
191
|
+
_b.label = 2;
|
|
192
|
+
case 2:
|
|
193
|
+
_b.trys.push([2, 5, , 7]);
|
|
194
|
+
channelMessage = this.createChannelMessage(message);
|
|
195
|
+
return [4 /*yield*/, this.routeChannelMessage(channelMessage)];
|
|
196
|
+
case 3:
|
|
197
|
+
response = _b.sent();
|
|
198
|
+
// Send response
|
|
199
|
+
return [4 /*yield*/, this.send(response)];
|
|
200
|
+
case 4:
|
|
201
|
+
// Send response
|
|
202
|
+
_b.sent();
|
|
203
|
+
return [3 /*break*/, 7];
|
|
204
|
+
case 5:
|
|
205
|
+
error_2 = _b.sent();
|
|
206
|
+
console.error("[Discord] Error handling message:", error_2);
|
|
207
|
+
return [4 /*yield*/, message.reply("Sorry, I encountered an error: ".concat(error_2 instanceof Error ? error_2.message : String(error_2)))];
|
|
208
|
+
case 6:
|
|
209
|
+
_b.sent();
|
|
210
|
+
return [3 /*break*/, 7];
|
|
211
|
+
case 7: return [2 /*return*/];
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}); });
|
|
215
|
+
return [4 /*yield*/, this.client.login(this.token)];
|
|
216
|
+
case 1:
|
|
217
|
+
_a.sent();
|
|
218
|
+
return [2 /*return*/];
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* Stop Discord bot
|
|
225
|
+
*/
|
|
226
|
+
DiscordChannel.prototype.stopPlatform = function () {
|
|
227
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
228
|
+
return __generator(this, function (_a) {
|
|
229
|
+
switch (_a.label) {
|
|
230
|
+
case 0:
|
|
231
|
+
console.log("[Discord] Shutting down...");
|
|
232
|
+
return [4 /*yield*/, this.client.destroy()];
|
|
233
|
+
case 1:
|
|
234
|
+
_a.sent();
|
|
235
|
+
return [2 /*return*/];
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
};
|
|
240
|
+
// ============================================================
|
|
241
|
+
// Discord-Specific Helpers
|
|
242
|
+
// ============================================================
|
|
243
|
+
/**
|
|
244
|
+
* Create normalized ChannelMessage from Discord message
|
|
245
|
+
*/
|
|
246
|
+
DiscordChannel.prototype.createChannelMessage = function (msg) {
|
|
247
|
+
var _a, _b;
|
|
248
|
+
var sender = {
|
|
249
|
+
id: msg.author.id,
|
|
250
|
+
username: msg.author.username,
|
|
251
|
+
displayName: msg.author.displayName || msg.author.username,
|
|
252
|
+
isBot: msg.author.bot,
|
|
253
|
+
};
|
|
254
|
+
var context = {
|
|
255
|
+
isDM: msg.channel.isDMBased(),
|
|
256
|
+
groupName: !msg.channel.isDMBased() ? (_a = msg.guild) === null || _a === void 0 ? void 0 : _a.name : undefined,
|
|
257
|
+
threadId: msg.channel.isThread() ? msg.channelId : undefined,
|
|
258
|
+
metadata: {
|
|
259
|
+
guildId: msg.guildId,
|
|
260
|
+
channelId: msg.channelId,
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
// Extract media attachments
|
|
264
|
+
var media = msg.attachments.size > 0
|
|
265
|
+
? msg.attachments.map(function (att) {
|
|
266
|
+
var _a, _b, _c;
|
|
267
|
+
return ({
|
|
268
|
+
type: ((_a = att.contentType) === null || _a === void 0 ? void 0 : _a.startsWith("image"))
|
|
269
|
+
? "image"
|
|
270
|
+
: ((_b = att.contentType) === null || _b === void 0 ? void 0 : _b.startsWith("video"))
|
|
271
|
+
? "video"
|
|
272
|
+
: ((_c = att.contentType) === null || _c === void 0 ? void 0 : _c.startsWith("audio"))
|
|
273
|
+
? "audio"
|
|
274
|
+
: "file",
|
|
275
|
+
url: att.url,
|
|
276
|
+
mimeType: att.contentType || undefined,
|
|
277
|
+
filename: att.name || undefined,
|
|
278
|
+
});
|
|
279
|
+
})
|
|
280
|
+
: undefined;
|
|
281
|
+
return {
|
|
282
|
+
messageId: msg.id,
|
|
283
|
+
channelId: {
|
|
284
|
+
platform: "discord",
|
|
285
|
+
accountId: msg.channelId,
|
|
286
|
+
},
|
|
287
|
+
timestamp: new Date(msg.createdTimestamp),
|
|
288
|
+
sender: sender,
|
|
289
|
+
text: msg.content,
|
|
290
|
+
media: media,
|
|
291
|
+
context: context,
|
|
292
|
+
replyTo: ((_b = msg.reference) === null || _b === void 0 ? void 0 : _b.messageId)
|
|
293
|
+
? {
|
|
294
|
+
messageId: msg.reference.messageId,
|
|
295
|
+
channelId: {
|
|
296
|
+
platform: "discord",
|
|
297
|
+
accountId: msg.reference.channelId,
|
|
298
|
+
},
|
|
299
|
+
}
|
|
300
|
+
: undefined,
|
|
301
|
+
quotedText: undefined,
|
|
302
|
+
};
|
|
303
|
+
};
|
|
304
|
+
/**
|
|
305
|
+
* Send response, handling chunking for long messages
|
|
306
|
+
*/
|
|
307
|
+
DiscordChannel.prototype.sendResponse = function (message, response) {
|
|
308
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
309
|
+
var maxLength, chunks, _i, chunks_1, chunk;
|
|
310
|
+
return __generator(this, function (_a) {
|
|
311
|
+
switch (_a.label) {
|
|
312
|
+
case 0:
|
|
313
|
+
maxLength = 2000;
|
|
314
|
+
if (!(response.length > maxLength)) return [3 /*break*/, 5];
|
|
315
|
+
chunks = response.match(/[\s\S]{1,2000}/g) || [];
|
|
316
|
+
_i = 0, chunks_1 = chunks;
|
|
317
|
+
_a.label = 1;
|
|
318
|
+
case 1:
|
|
319
|
+
if (!(_i < chunks_1.length)) return [3 /*break*/, 4];
|
|
320
|
+
chunk = chunks_1[_i];
|
|
321
|
+
return [4 /*yield*/, message.reply(chunk)];
|
|
322
|
+
case 2:
|
|
323
|
+
_a.sent();
|
|
324
|
+
_a.label = 3;
|
|
325
|
+
case 3:
|
|
326
|
+
_i++;
|
|
327
|
+
return [3 /*break*/, 1];
|
|
328
|
+
case 4: return [3 /*break*/, 7];
|
|
329
|
+
case 5: return [4 /*yield*/, message.reply(response)];
|
|
330
|
+
case 6:
|
|
331
|
+
_a.sent();
|
|
332
|
+
_a.label = 7;
|
|
333
|
+
case 7: return [2 /*return*/];
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
};
|
|
338
|
+
return DiscordChannel;
|
|
339
|
+
}(base_js_1.BaseChannel));
|
|
340
|
+
exports.DiscordChannel = DiscordChannel;
|
|
341
|
+
// ============================================================
|
|
342
|
+
// FACTORY FUNCTION
|
|
343
|
+
// ============================================================
|
|
344
|
+
/**
|
|
345
|
+
* Create a Discord channel from config
|
|
346
|
+
*/
|
|
347
|
+
function createDiscordChannel(config) {
|
|
348
|
+
return new DiscordChannel(config);
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Create Discord channel config from environment (Doppler)
|
|
352
|
+
*/
|
|
353
|
+
function createDiscordConfigFromEnv() {
|
|
354
|
+
var _a;
|
|
355
|
+
var token = process.env.DISCORD_BOT_TOKEN;
|
|
356
|
+
if (!token)
|
|
357
|
+
return null;
|
|
358
|
+
var channelIds = (_a = process.env.DISCORD_CHANNEL_IDS) === null || _a === void 0 ? void 0 : _a.split(",").map(function (s) { return s.trim(); }).filter(Boolean);
|
|
359
|
+
return {
|
|
360
|
+
platform: "discord",
|
|
361
|
+
accountId: process.env.DISCORD_ACCOUNT_ID || "default",
|
|
362
|
+
instanceId: process.env.DISCORD_INSTANCE_ID,
|
|
363
|
+
botToken: token,
|
|
364
|
+
applicationId: process.env.DISCORD_APPLICATION_ID,
|
|
365
|
+
guildId: process.env.DISCORD_GUILD_ID,
|
|
366
|
+
channelIds: channelIds,
|
|
367
|
+
enableSlashCommands: process.env.DISCORD_ENABLE_SLASH_COMMANDS !== "false",
|
|
368
|
+
daemonWorkdir: process.env.DAEMON_WORKDIR,
|
|
369
|
+
daemonBaseBranch: process.env.DAEMON_BASE_BRANCH,
|
|
370
|
+
enableDaemonAutoPR: process.env.DAEMON_AUTO_PR === "true",
|
|
371
|
+
enableDaemonAutoCommit: process.env.DAEMON_AUTO_COMMIT === "true",
|
|
372
|
+
butlerStorageDir: process.env.BUTLER_STORAGE_DIR,
|
|
373
|
+
};
|
|
374
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* GLM Daemon Channels
|
|
4
|
+
*
|
|
5
|
+
* Communication channel adapters for GLM Daemon.
|
|
6
|
+
* All channels implement ChannelConnector from @ebowwa/channel-types.
|
|
7
|
+
*
|
|
8
|
+
* Supported platforms:
|
|
9
|
+
* - Telegram
|
|
10
|
+
* - Discord
|
|
11
|
+
*/
|
|
12
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
+
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);
|
|
23
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
+
function step(op) {
|
|
26
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
+
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;
|
|
29
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
+
switch (op[0]) {
|
|
31
|
+
case 0: case 1: t = op; break;
|
|
32
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
+
default:
|
|
36
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
+
if (t[2]) _.ops.pop();
|
|
41
|
+
_.trys.pop(); continue;
|
|
42
|
+
}
|
|
43
|
+
op = body.call(thisArg, _);
|
|
44
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.ChannelRegistry = exports.createDiscordConfigFromEnv = exports.createDiscordChannel = exports.DiscordChannel = exports.createTelegramConfigFromEnv = exports.createTelegramChannel = exports.TelegramChannel = exports.BaseChannel = void 0;
|
|
50
|
+
exports.createChannelsFromEnv = createChannelsFromEnv;
|
|
51
|
+
exports.initializeChannelsFromEnv = initializeChannelsFromEnv;
|
|
52
|
+
// Base channel
|
|
53
|
+
var base_js_1 = require("./base.js");
|
|
54
|
+
Object.defineProperty(exports, "BaseChannel", { enumerable: true, get: function () { return base_js_1.BaseChannel; } });
|
|
55
|
+
// Telegram
|
|
56
|
+
var telegram_js_1 = require("./telegram.js");
|
|
57
|
+
Object.defineProperty(exports, "TelegramChannel", { enumerable: true, get: function () { return telegram_js_1.TelegramChannel; } });
|
|
58
|
+
Object.defineProperty(exports, "createTelegramChannel", { enumerable: true, get: function () { return telegram_js_1.createTelegramChannel; } });
|
|
59
|
+
Object.defineProperty(exports, "createTelegramConfigFromEnv", { enumerable: true, get: function () { return telegram_js_1.createTelegramConfigFromEnv; } });
|
|
60
|
+
// Discord
|
|
61
|
+
var discord_js_1 = require("./discord.js");
|
|
62
|
+
Object.defineProperty(exports, "DiscordChannel", { enumerable: true, get: function () { return discord_js_1.DiscordChannel; } });
|
|
63
|
+
Object.defineProperty(exports, "createDiscordChannel", { enumerable: true, get: function () { return discord_js_1.createDiscordChannel; } });
|
|
64
|
+
Object.defineProperty(exports, "createDiscordConfigFromEnv", { enumerable: true, get: function () { return discord_js_1.createDiscordConfigFromEnv; } });
|
|
65
|
+
var telegram_js_2 = require("./telegram.js");
|
|
66
|
+
var discord_js_2 = require("./discord.js");
|
|
67
|
+
/**
|
|
68
|
+
* Channel registry for managing multiple channels
|
|
69
|
+
*/
|
|
70
|
+
var ChannelRegistry = /** @class */ (function () {
|
|
71
|
+
function ChannelRegistry() {
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Register a channel
|
|
75
|
+
*/
|
|
76
|
+
ChannelRegistry.register = function (name, channel) {
|
|
77
|
+
this.channels.set(name, channel);
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Get a registered channel
|
|
81
|
+
*/
|
|
82
|
+
ChannelRegistry.get = function (name) {
|
|
83
|
+
return this.channels.get(name);
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Unregister a channel
|
|
87
|
+
*/
|
|
88
|
+
ChannelRegistry.unregister = function (name) {
|
|
89
|
+
var channel = this.channels.get(name);
|
|
90
|
+
if (channel) {
|
|
91
|
+
channel.stop();
|
|
92
|
+
this.channels.delete(name);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Get all registered channels
|
|
97
|
+
*/
|
|
98
|
+
ChannelRegistry.getAll = function () {
|
|
99
|
+
return new Map(this.channels);
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Stop all channels
|
|
103
|
+
*/
|
|
104
|
+
ChannelRegistry.stopAll = function () {
|
|
105
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
106
|
+
var stopPromises;
|
|
107
|
+
return __generator(this, function (_a) {
|
|
108
|
+
switch (_a.label) {
|
|
109
|
+
case 0:
|
|
110
|
+
stopPromises = Array.from(this.channels.values()).map(function (channel) { return channel.stop(); });
|
|
111
|
+
return [4 /*yield*/, Promise.all(stopPromises)];
|
|
112
|
+
case 1:
|
|
113
|
+
_a.sent();
|
|
114
|
+
this.channels.clear();
|
|
115
|
+
return [2 /*return*/];
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* Start all channels
|
|
122
|
+
*/
|
|
123
|
+
ChannelRegistry.startAll = function () {
|
|
124
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
125
|
+
var startPromises;
|
|
126
|
+
return __generator(this, function (_a) {
|
|
127
|
+
switch (_a.label) {
|
|
128
|
+
case 0:
|
|
129
|
+
startPromises = Array.from(this.channels.values()).map(function (channel) { return channel.start(); });
|
|
130
|
+
return [4 /*yield*/, Promise.all(startPromises)];
|
|
131
|
+
case 1:
|
|
132
|
+
_a.sent();
|
|
133
|
+
return [2 /*return*/];
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
ChannelRegistry.channels = new Map();
|
|
139
|
+
return ChannelRegistry;
|
|
140
|
+
}());
|
|
141
|
+
exports.ChannelRegistry = ChannelRegistry;
|
|
142
|
+
// ============================================================
|
|
143
|
+
// FACTORY FUNCTIONS
|
|
144
|
+
// ============================================================
|
|
145
|
+
/**
|
|
146
|
+
* Create all channels from environment variables (Doppler)
|
|
147
|
+
*/
|
|
148
|
+
function createChannelsFromEnv() {
|
|
149
|
+
var channels = [];
|
|
150
|
+
// Telegram
|
|
151
|
+
var telegramConfig = (0, telegram_js_2.createTelegramConfigFromEnv)();
|
|
152
|
+
if (telegramConfig) {
|
|
153
|
+
channels.push(new telegram_js_2.TelegramChannel(telegramConfig));
|
|
154
|
+
}
|
|
155
|
+
// Discord
|
|
156
|
+
var discordConfig = (0, discord_js_2.createDiscordConfigFromEnv)();
|
|
157
|
+
if (discordConfig) {
|
|
158
|
+
channels.push(new discord_js_2.DiscordChannel(discordConfig));
|
|
159
|
+
}
|
|
160
|
+
return channels;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Initialize channels from environment and register them
|
|
164
|
+
*/
|
|
165
|
+
function initializeChannelsFromEnv() {
|
|
166
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
167
|
+
var channels, _i, channels_1, channel, key;
|
|
168
|
+
return __generator(this, function (_a) {
|
|
169
|
+
switch (_a.label) {
|
|
170
|
+
case 0:
|
|
171
|
+
channels = createChannelsFromEnv();
|
|
172
|
+
for (_i = 0, channels_1 = channels; _i < channels_1.length; _i++) {
|
|
173
|
+
channel = channels_1[_i];
|
|
174
|
+
key = "".concat(channel.id.platform, ":").concat(channel.id.accountId);
|
|
175
|
+
ChannelRegistry.register(key, channel);
|
|
176
|
+
}
|
|
177
|
+
// Start all channels
|
|
178
|
+
return [4 /*yield*/, ChannelRegistry.startAll()];
|
|
179
|
+
case 1:
|
|
180
|
+
// Start all channels
|
|
181
|
+
_a.sent();
|
|
182
|
+
return [2 /*return*/, ChannelRegistry];
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
}
|