@ebowwa/glm-daemon 0.4.5 → 0.4.6
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/dist/bin/discord-cli.js +79 -0
- package/dist/bin/telegram-cli.js +79 -0
- package/dist/index.js +79 -0
- package/package.json +1 -1
- package/src/channels/telegram.ts +105 -0
package/dist/bin/discord-cli.js
CHANGED
|
@@ -98838,6 +98838,50 @@ function registerAllCommands(bot, memory, tools) {
|
|
|
98838
98838
|
registerInnerthoughtsCommand(bot, memory, tools);
|
|
98839
98839
|
register(bot, tools);
|
|
98840
98840
|
}
|
|
98841
|
+
// ../channel-telegram/dist/utils/normalize.js
|
|
98842
|
+
function normalizeTelegramMessagingTarget(raw) {
|
|
98843
|
+
const trimmed = raw.trim();
|
|
98844
|
+
if (!trimmed)
|
|
98845
|
+
return;
|
|
98846
|
+
let normalized = trimmed;
|
|
98847
|
+
if (normalized.startsWith("telegram:")) {
|
|
98848
|
+
normalized = normalized.slice("telegram:".length).trim();
|
|
98849
|
+
} else if (normalized.startsWith("tg:")) {
|
|
98850
|
+
normalized = normalized.slice("tg:".length).trim();
|
|
98851
|
+
}
|
|
98852
|
+
if (!normalized)
|
|
98853
|
+
return;
|
|
98854
|
+
const tmeMatch = /^https?:\/\/t\.me\/([A-Za-z0-9_]+)$/i.exec(normalized) ?? /^t\.me\/([A-Za-z0-9_]+)$/i.exec(normalized);
|
|
98855
|
+
if (tmeMatch?.[1]) {
|
|
98856
|
+
normalized = `@${tmeMatch[1]}`;
|
|
98857
|
+
}
|
|
98858
|
+
if (!normalized)
|
|
98859
|
+
return;
|
|
98860
|
+
return `telegram:${normalized}`.toLowerCase();
|
|
98861
|
+
}
|
|
98862
|
+
function looksLikeTelegramTargetId(raw) {
|
|
98863
|
+
const trimmed = raw.trim();
|
|
98864
|
+
if (!trimmed)
|
|
98865
|
+
return false;
|
|
98866
|
+
if (/^(telegram|tg):/i.test(trimmed))
|
|
98867
|
+
return true;
|
|
98868
|
+
if (trimmed.startsWith("@"))
|
|
98869
|
+
return true;
|
|
98870
|
+
return /^-?\d{6,}$/.test(trimmed);
|
|
98871
|
+
}
|
|
98872
|
+
function extractRawTarget(normalized) {
|
|
98873
|
+
const trimmed = normalized.trim();
|
|
98874
|
+
if (!trimmed.startsWith("telegram:"))
|
|
98875
|
+
return;
|
|
98876
|
+
const raw = trimmed.slice("telegram:".length);
|
|
98877
|
+
return raw || undefined;
|
|
98878
|
+
}
|
|
98879
|
+
function isNumericIdTarget(normalized) {
|
|
98880
|
+
const raw = extractRawTarget(normalized);
|
|
98881
|
+
if (!raw)
|
|
98882
|
+
return false;
|
|
98883
|
+
return /^-?\d+$/.test(raw);
|
|
98884
|
+
}
|
|
98841
98885
|
// ../channel-telegram/dist/index.js
|
|
98842
98886
|
class TelegramChannel {
|
|
98843
98887
|
id;
|
|
@@ -99202,6 +99246,41 @@ class GLMTelegramChannel extends BaseChannel {
|
|
|
99202
99246
|
isAllowed(userId, chatId) {
|
|
99203
99247
|
return this.protocolAdapter.isAllowed(userId, chatId);
|
|
99204
99248
|
}
|
|
99249
|
+
normalizeTarget(raw) {
|
|
99250
|
+
return normalizeTelegramMessagingTarget(raw);
|
|
99251
|
+
}
|
|
99252
|
+
isValidTarget(raw) {
|
|
99253
|
+
return looksLikeTelegramTargetId(raw);
|
|
99254
|
+
}
|
|
99255
|
+
parseTargetFromInput(input) {
|
|
99256
|
+
const words = input.split(/\s+/);
|
|
99257
|
+
for (const word of words) {
|
|
99258
|
+
if (looksLikeTelegramTargetId(word)) {
|
|
99259
|
+
const normalized = normalizeTelegramMessagingTarget(word);
|
|
99260
|
+
if (normalized) {
|
|
99261
|
+
return extractRawTarget(normalized);
|
|
99262
|
+
}
|
|
99263
|
+
}
|
|
99264
|
+
}
|
|
99265
|
+
return;
|
|
99266
|
+
}
|
|
99267
|
+
async sendToTarget(target, text) {
|
|
99268
|
+
const normalized = normalizeTelegramMessagingTarget(target);
|
|
99269
|
+
if (!normalized) {
|
|
99270
|
+
throw new Error(`Invalid Telegram target: ${target}`);
|
|
99271
|
+
}
|
|
99272
|
+
const rawTarget = extractRawTarget(normalized);
|
|
99273
|
+
if (!rawTarget) {
|
|
99274
|
+
throw new Error(`Failed to extract target from: ${normalized}`);
|
|
99275
|
+
}
|
|
99276
|
+
let chatId;
|
|
99277
|
+
if (isNumericIdTarget(normalized)) {
|
|
99278
|
+
chatId = parseInt(rawTarget, 10);
|
|
99279
|
+
} else {
|
|
99280
|
+
throw new Error(`Username targets require resolution. Use numeric chat ID instead, or implement username resolution. Target: ${rawTarget}`);
|
|
99281
|
+
}
|
|
99282
|
+
await this.sendMessage(chatId, text);
|
|
99283
|
+
}
|
|
99205
99284
|
}
|
|
99206
99285
|
// src/channels/discord.ts
|
|
99207
99286
|
var import_discord = __toESM(require_src2(), 1);
|
package/dist/bin/telegram-cli.js
CHANGED
|
@@ -98838,6 +98838,50 @@ function registerAllCommands(bot, memory, tools) {
|
|
|
98838
98838
|
registerInnerthoughtsCommand(bot, memory, tools);
|
|
98839
98839
|
register(bot, tools);
|
|
98840
98840
|
}
|
|
98841
|
+
// ../channel-telegram/dist/utils/normalize.js
|
|
98842
|
+
function normalizeTelegramMessagingTarget(raw) {
|
|
98843
|
+
const trimmed = raw.trim();
|
|
98844
|
+
if (!trimmed)
|
|
98845
|
+
return;
|
|
98846
|
+
let normalized = trimmed;
|
|
98847
|
+
if (normalized.startsWith("telegram:")) {
|
|
98848
|
+
normalized = normalized.slice("telegram:".length).trim();
|
|
98849
|
+
} else if (normalized.startsWith("tg:")) {
|
|
98850
|
+
normalized = normalized.slice("tg:".length).trim();
|
|
98851
|
+
}
|
|
98852
|
+
if (!normalized)
|
|
98853
|
+
return;
|
|
98854
|
+
const tmeMatch = /^https?:\/\/t\.me\/([A-Za-z0-9_]+)$/i.exec(normalized) ?? /^t\.me\/([A-Za-z0-9_]+)$/i.exec(normalized);
|
|
98855
|
+
if (tmeMatch?.[1]) {
|
|
98856
|
+
normalized = `@${tmeMatch[1]}`;
|
|
98857
|
+
}
|
|
98858
|
+
if (!normalized)
|
|
98859
|
+
return;
|
|
98860
|
+
return `telegram:${normalized}`.toLowerCase();
|
|
98861
|
+
}
|
|
98862
|
+
function looksLikeTelegramTargetId(raw) {
|
|
98863
|
+
const trimmed = raw.trim();
|
|
98864
|
+
if (!trimmed)
|
|
98865
|
+
return false;
|
|
98866
|
+
if (/^(telegram|tg):/i.test(trimmed))
|
|
98867
|
+
return true;
|
|
98868
|
+
if (trimmed.startsWith("@"))
|
|
98869
|
+
return true;
|
|
98870
|
+
return /^-?\d{6,}$/.test(trimmed);
|
|
98871
|
+
}
|
|
98872
|
+
function extractRawTarget(normalized) {
|
|
98873
|
+
const trimmed = normalized.trim();
|
|
98874
|
+
if (!trimmed.startsWith("telegram:"))
|
|
98875
|
+
return;
|
|
98876
|
+
const raw = trimmed.slice("telegram:".length);
|
|
98877
|
+
return raw || undefined;
|
|
98878
|
+
}
|
|
98879
|
+
function isNumericIdTarget(normalized) {
|
|
98880
|
+
const raw = extractRawTarget(normalized);
|
|
98881
|
+
if (!raw)
|
|
98882
|
+
return false;
|
|
98883
|
+
return /^-?\d+$/.test(raw);
|
|
98884
|
+
}
|
|
98841
98885
|
// ../channel-telegram/dist/index.js
|
|
98842
98886
|
class TelegramChannel {
|
|
98843
98887
|
id;
|
|
@@ -99202,6 +99246,41 @@ class GLMTelegramChannel extends BaseChannel {
|
|
|
99202
99246
|
isAllowed(userId, chatId) {
|
|
99203
99247
|
return this.protocolAdapter.isAllowed(userId, chatId);
|
|
99204
99248
|
}
|
|
99249
|
+
normalizeTarget(raw) {
|
|
99250
|
+
return normalizeTelegramMessagingTarget(raw);
|
|
99251
|
+
}
|
|
99252
|
+
isValidTarget(raw) {
|
|
99253
|
+
return looksLikeTelegramTargetId(raw);
|
|
99254
|
+
}
|
|
99255
|
+
parseTargetFromInput(input) {
|
|
99256
|
+
const words = input.split(/\s+/);
|
|
99257
|
+
for (const word of words) {
|
|
99258
|
+
if (looksLikeTelegramTargetId(word)) {
|
|
99259
|
+
const normalized = normalizeTelegramMessagingTarget(word);
|
|
99260
|
+
if (normalized) {
|
|
99261
|
+
return extractRawTarget(normalized);
|
|
99262
|
+
}
|
|
99263
|
+
}
|
|
99264
|
+
}
|
|
99265
|
+
return;
|
|
99266
|
+
}
|
|
99267
|
+
async sendToTarget(target, text) {
|
|
99268
|
+
const normalized = normalizeTelegramMessagingTarget(target);
|
|
99269
|
+
if (!normalized) {
|
|
99270
|
+
throw new Error(`Invalid Telegram target: ${target}`);
|
|
99271
|
+
}
|
|
99272
|
+
const rawTarget = extractRawTarget(normalized);
|
|
99273
|
+
if (!rawTarget) {
|
|
99274
|
+
throw new Error(`Failed to extract target from: ${normalized}`);
|
|
99275
|
+
}
|
|
99276
|
+
let chatId;
|
|
99277
|
+
if (isNumericIdTarget(normalized)) {
|
|
99278
|
+
chatId = parseInt(rawTarget, 10);
|
|
99279
|
+
} else {
|
|
99280
|
+
throw new Error(`Username targets require resolution. Use numeric chat ID instead, or implement username resolution. Target: ${rawTarget}`);
|
|
99281
|
+
}
|
|
99282
|
+
await this.sendMessage(chatId, text);
|
|
99283
|
+
}
|
|
99205
99284
|
}
|
|
99206
99285
|
// src/channels/discord.ts
|
|
99207
99286
|
var import_discord = __toESM(require_src2(), 1);
|
package/dist/index.js
CHANGED
|
@@ -99032,6 +99032,50 @@ function registerAllCommands(bot, memory, tools) {
|
|
|
99032
99032
|
registerInnerthoughtsCommand(bot, memory, tools);
|
|
99033
99033
|
register(bot, tools);
|
|
99034
99034
|
}
|
|
99035
|
+
// ../channel-telegram/dist/utils/normalize.js
|
|
99036
|
+
function normalizeTelegramMessagingTarget(raw) {
|
|
99037
|
+
const trimmed = raw.trim();
|
|
99038
|
+
if (!trimmed)
|
|
99039
|
+
return;
|
|
99040
|
+
let normalized = trimmed;
|
|
99041
|
+
if (normalized.startsWith("telegram:")) {
|
|
99042
|
+
normalized = normalized.slice("telegram:".length).trim();
|
|
99043
|
+
} else if (normalized.startsWith("tg:")) {
|
|
99044
|
+
normalized = normalized.slice("tg:".length).trim();
|
|
99045
|
+
}
|
|
99046
|
+
if (!normalized)
|
|
99047
|
+
return;
|
|
99048
|
+
const tmeMatch = /^https?:\/\/t\.me\/([A-Za-z0-9_]+)$/i.exec(normalized) ?? /^t\.me\/([A-Za-z0-9_]+)$/i.exec(normalized);
|
|
99049
|
+
if (tmeMatch?.[1]) {
|
|
99050
|
+
normalized = `@${tmeMatch[1]}`;
|
|
99051
|
+
}
|
|
99052
|
+
if (!normalized)
|
|
99053
|
+
return;
|
|
99054
|
+
return `telegram:${normalized}`.toLowerCase();
|
|
99055
|
+
}
|
|
99056
|
+
function looksLikeTelegramTargetId(raw) {
|
|
99057
|
+
const trimmed = raw.trim();
|
|
99058
|
+
if (!trimmed)
|
|
99059
|
+
return false;
|
|
99060
|
+
if (/^(telegram|tg):/i.test(trimmed))
|
|
99061
|
+
return true;
|
|
99062
|
+
if (trimmed.startsWith("@"))
|
|
99063
|
+
return true;
|
|
99064
|
+
return /^-?\d{6,}$/.test(trimmed);
|
|
99065
|
+
}
|
|
99066
|
+
function extractRawTarget(normalized) {
|
|
99067
|
+
const trimmed = normalized.trim();
|
|
99068
|
+
if (!trimmed.startsWith("telegram:"))
|
|
99069
|
+
return;
|
|
99070
|
+
const raw = trimmed.slice("telegram:".length);
|
|
99071
|
+
return raw || undefined;
|
|
99072
|
+
}
|
|
99073
|
+
function isNumericIdTarget(normalized) {
|
|
99074
|
+
const raw = extractRawTarget(normalized);
|
|
99075
|
+
if (!raw)
|
|
99076
|
+
return false;
|
|
99077
|
+
return /^-?\d+$/.test(raw);
|
|
99078
|
+
}
|
|
99035
99079
|
// ../channel-telegram/dist/index.js
|
|
99036
99080
|
class TelegramChannel {
|
|
99037
99081
|
id;
|
|
@@ -99396,6 +99440,41 @@ class GLMTelegramChannel extends BaseChannel {
|
|
|
99396
99440
|
isAllowed(userId, chatId) {
|
|
99397
99441
|
return this.protocolAdapter.isAllowed(userId, chatId);
|
|
99398
99442
|
}
|
|
99443
|
+
normalizeTarget(raw) {
|
|
99444
|
+
return normalizeTelegramMessagingTarget(raw);
|
|
99445
|
+
}
|
|
99446
|
+
isValidTarget(raw) {
|
|
99447
|
+
return looksLikeTelegramTargetId(raw);
|
|
99448
|
+
}
|
|
99449
|
+
parseTargetFromInput(input) {
|
|
99450
|
+
const words = input.split(/\s+/);
|
|
99451
|
+
for (const word of words) {
|
|
99452
|
+
if (looksLikeTelegramTargetId(word)) {
|
|
99453
|
+
const normalized = normalizeTelegramMessagingTarget(word);
|
|
99454
|
+
if (normalized) {
|
|
99455
|
+
return extractRawTarget(normalized);
|
|
99456
|
+
}
|
|
99457
|
+
}
|
|
99458
|
+
}
|
|
99459
|
+
return;
|
|
99460
|
+
}
|
|
99461
|
+
async sendToTarget(target, text) {
|
|
99462
|
+
const normalized = normalizeTelegramMessagingTarget(target);
|
|
99463
|
+
if (!normalized) {
|
|
99464
|
+
throw new Error(`Invalid Telegram target: ${target}`);
|
|
99465
|
+
}
|
|
99466
|
+
const rawTarget = extractRawTarget(normalized);
|
|
99467
|
+
if (!rawTarget) {
|
|
99468
|
+
throw new Error(`Failed to extract target from: ${normalized}`);
|
|
99469
|
+
}
|
|
99470
|
+
let chatId;
|
|
99471
|
+
if (isNumericIdTarget(normalized)) {
|
|
99472
|
+
chatId = parseInt(rawTarget, 10);
|
|
99473
|
+
} else {
|
|
99474
|
+
throw new Error(`Username targets require resolution. Use numeric chat ID instead, or implement username resolution. Target: ${rawTarget}`);
|
|
99475
|
+
}
|
|
99476
|
+
await this.sendMessage(chatId, text);
|
|
99477
|
+
}
|
|
99399
99478
|
}
|
|
99400
99479
|
// src/channels/discord.ts
|
|
99401
99480
|
var import_discord = __toESM(require_src2(), 1);
|
package/package.json
CHANGED
package/src/channels/telegram.ts
CHANGED
|
@@ -12,12 +12,27 @@ import {
|
|
|
12
12
|
import {
|
|
13
13
|
TelegramChannel as TelegramProtocolAdapter,
|
|
14
14
|
type TelegramConfig as ProtocolConfig,
|
|
15
|
+
// Telegram target normalization utilities
|
|
16
|
+
normalizeTelegramMessagingTarget,
|
|
17
|
+
looksLikeTelegramTargetId,
|
|
18
|
+
extractRawTarget,
|
|
19
|
+
isUsernameTarget,
|
|
20
|
+
isNumericIdTarget,
|
|
15
21
|
} from "@ebowwa/channel-telegram";
|
|
16
22
|
import {
|
|
17
23
|
BaseChannel,
|
|
18
24
|
type GLMChannelConfig,
|
|
19
25
|
} from "./base.js";
|
|
20
26
|
|
|
27
|
+
// Re-export normalization utilities for consumers
|
|
28
|
+
export {
|
|
29
|
+
normalizeTelegramMessagingTarget,
|
|
30
|
+
looksLikeTelegramTargetId,
|
|
31
|
+
extractRawTarget,
|
|
32
|
+
isUsernameTarget,
|
|
33
|
+
isNumericIdTarget,
|
|
34
|
+
};
|
|
35
|
+
|
|
21
36
|
// ============================================================
|
|
22
37
|
// TELEGRAM CHANNEL CONFIG
|
|
23
38
|
// ============================================================
|
|
@@ -163,6 +178,96 @@ export class GLMTelegramChannel extends BaseChannel {
|
|
|
163
178
|
isAllowed(userId?: number, chatId?: number): boolean {
|
|
164
179
|
return this.protocolAdapter.isAllowed(userId, chatId);
|
|
165
180
|
}
|
|
181
|
+
|
|
182
|
+
// ============================================================
|
|
183
|
+
// Target Normalization Helpers
|
|
184
|
+
// ============================================================
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Normalize a Telegram target (username, URL, or ID) to standard format.
|
|
188
|
+
*
|
|
189
|
+
* @param raw - Raw input (@username, t.me/user, 123456, etc.)
|
|
190
|
+
* @returns Normalized target or undefined if invalid
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* channel.normalizeTarget("@durov") // "telegram:@durov"
|
|
194
|
+
* channel.normalizeTarget("t.me/durov") // "telegram:@durov"
|
|
195
|
+
* channel.normalizeTarget("123456") // "telegram:123456"
|
|
196
|
+
*/
|
|
197
|
+
normalizeTarget(raw: string): string | undefined {
|
|
198
|
+
return normalizeTelegramMessagingTarget(raw);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Check if a string looks like a Telegram target.
|
|
203
|
+
*
|
|
204
|
+
* @param raw - Raw input string
|
|
205
|
+
* @returns true if it looks like a Telegram target
|
|
206
|
+
*/
|
|
207
|
+
isValidTarget(raw: string): boolean {
|
|
208
|
+
return looksLikeTelegramTargetId(raw);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Parse a target from user input and extract the usable form.
|
|
213
|
+
*
|
|
214
|
+
* @param input - User input like "send to @user" or "dm t.me/user"
|
|
215
|
+
* @returns Extracted raw target (@username or numeric ID) or undefined
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* channel.parseTargetFromInput("send to @durov") // "@durov"
|
|
219
|
+
* channel.parseTargetFromInput("dm 123456") // "123456"
|
|
220
|
+
*/
|
|
221
|
+
parseTargetFromInput(input: string): string | undefined {
|
|
222
|
+
const words = input.split(/\s+/);
|
|
223
|
+
for (const word of words) {
|
|
224
|
+
if (looksLikeTelegramTargetId(word)) {
|
|
225
|
+
const normalized = normalizeTelegramMessagingTarget(word);
|
|
226
|
+
if (normalized) {
|
|
227
|
+
return extractRawTarget(normalized);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return undefined;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Send a message to a target (username or chat ID).
|
|
236
|
+
*
|
|
237
|
+
* @param target - Telegram target (@username, numeric ID, or normalized format)
|
|
238
|
+
* @param text - Message text
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* await channel.sendToTarget("@durov", "Hello!")
|
|
242
|
+
* await channel.sendToTarget("123456", "Hello!")
|
|
243
|
+
*/
|
|
244
|
+
async sendToTarget(target: string, text: string): Promise<void> {
|
|
245
|
+
const normalized = normalizeTelegramMessagingTarget(target);
|
|
246
|
+
if (!normalized) {
|
|
247
|
+
throw new Error(`Invalid Telegram target: ${target}`);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const rawTarget = extractRawTarget(normalized);
|
|
251
|
+
if (!rawTarget) {
|
|
252
|
+
throw new Error(`Failed to extract target from: ${normalized}`);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Parse chat ID (numeric or resolve username)
|
|
256
|
+
let chatId: number;
|
|
257
|
+
|
|
258
|
+
if (isNumericIdTarget(normalized)) {
|
|
259
|
+
chatId = parseInt(rawTarget, 10);
|
|
260
|
+
} else {
|
|
261
|
+
// Username target - need to resolve via bot API
|
|
262
|
+
// Note: This requires the bot to have seen the user/channel before
|
|
263
|
+
// For now, we'll try direct message with username (may fail if not cached)
|
|
264
|
+
throw new Error(
|
|
265
|
+
`Username targets require resolution. Use numeric chat ID instead, or implement username resolution. Target: ${rawTarget}`
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
await this.sendMessage(chatId, text);
|
|
270
|
+
}
|
|
166
271
|
}
|
|
167
272
|
|
|
168
273
|
// ============================================================
|