chz-telegram-bot 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builtin/helpAction.js +3 -6
- package/dist/dtos/chatHistoryMessage.js +1 -5
- package/dist/dtos/chatInfo.js +1 -5
- package/dist/dtos/commandTriggerCheckResult.js +1 -5
- package/dist/dtos/cooldownInfo.js +1 -5
- package/dist/dtos/incomingMessage.js +21 -25
- package/dist/dtos/incomingQuery.js +1 -5
- package/dist/dtos/messageInfo.js +1 -5
- package/dist/dtos/propertyProviderSets.js +1 -2
- package/dist/dtos/replyInfo.js +1 -5
- package/dist/dtos/responses/delay.js +3 -7
- package/dist/dtos/responses/imageMessage.js +3 -7
- package/dist/dtos/responses/inlineQueryResponse.js +3 -7
- package/dist/dtos/responses/reaction.js +3 -7
- package/dist/dtos/responses/textMessage.d.ts +2 -0
- package/dist/dtos/responses/textMessage.d.ts.map +1 -1
- package/dist/dtos/responses/textMessage.js +5 -7
- package/dist/dtos/responses/unpin.js +3 -7
- package/dist/dtos/responses/videoMessage.js +3 -7
- package/dist/dtos/userInfo.js +1 -5
- package/dist/entities/actions/commandAction.js +32 -39
- package/dist/entities/actions/inlineQueryAction.js +4 -8
- package/dist/entities/actions/replyCaptureAction.js +10 -14
- package/dist/entities/actions/scheduledAction.js +16 -23
- package/dist/entities/botInstance.js +13 -17
- package/dist/entities/cachedStateFactory.js +1 -5
- package/dist/entities/context/baseContext.d.ts +1 -1
- package/dist/entities/context/baseContext.d.ts.map +1 -1
- package/dist/entities/context/baseContext.js +1 -5
- package/dist/entities/context/chatContext.js +13 -17
- package/dist/entities/context/inlineQueryContext.js +4 -8
- package/dist/entities/context/messageContext.js +15 -19
- package/dist/entities/context/replyContext.js +15 -19
- package/dist/entities/states/actionStateBase.js +1 -5
- package/dist/entities/taskRecord.js +1 -5
- package/dist/eslint.config.d.ts +3 -0
- package/dist/eslint.config.d.ts.map +1 -0
- package/dist/eslint.config.js +51 -0
- package/dist/helpers/builders/commandActionBuilder.js +15 -20
- package/dist/helpers/builders/inlineQueryActionBuilder.js +5 -9
- package/dist/helpers/builders/scheduledActionBuilder.js +10 -15
- package/dist/helpers/mapUtils.js +2 -6
- package/dist/helpers/noop.js +1 -5
- package/dist/helpers/objectFromEntries.js +1 -5
- package/dist/helpers/timeConvertions.js +3 -8
- package/dist/helpers/toArray.js +1 -4
- package/dist/helpers/traceFactory.js +1 -4
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -41
- package/dist/main.js +5 -8
- package/dist/services/actionProcessingService.js +15 -19
- package/dist/services/actionProcessors/baseProcessor.js +1 -5
- package/dist/services/actionProcessors/commandActionProcessor.d.ts.map +1 -1
- package/dist/services/actionProcessors/commandActionProcessor.js +35 -38
- package/dist/services/actionProcessors/inlineQueryActionProcessor.js +7 -11
- package/dist/services/actionProcessors/scheduledActionProcessor.js +12 -19
- package/dist/services/jsonFileStorage.js +15 -19
- package/dist/services/jsonLogger.js +1 -5
- package/dist/services/nodeTimeoutScheduler.js +9 -13
- package/dist/services/responseProcessingQueue.js +3 -7
- package/dist/services/telegramApi.d.ts +1 -0
- package/dist/services/telegramApi.d.ts.map +1 -1
- package/dist/services/telegramApi.js +27 -27
- package/dist/types/action.js +1 -2
- package/dist/types/actionState.js +1 -2
- package/dist/types/cachedValueAccessor.js +1 -2
- package/dist/types/capture.js +1 -2
- package/dist/types/commandCondition.js +1 -2
- package/dist/types/commandTrigger.js +1 -2
- package/dist/types/externalAliases.d.ts +3 -3
- package/dist/types/externalAliases.d.ts.map +1 -1
- package/dist/types/externalAliases.js +1 -2
- package/dist/types/handlers.js +1 -2
- package/dist/types/inputFile.js +1 -2
- package/dist/types/logger.js +1 -2
- package/dist/types/messageSendingOptions.d.ts +2 -0
- package/dist/types/messageSendingOptions.d.ts.map +1 -1
- package/dist/types/messageSendingOptions.js +1 -2
- package/dist/types/messageTypes.js +17 -20
- package/dist/types/propertyProvider.js +1 -2
- package/dist/types/response.js +1 -4
- package/dist/types/scheduler.js +1 -2
- package/dist/types/storage.js +1 -2
- package/dist/types/timeValues.js +1 -2
- package/dist/types/trace.js +1 -2
- package/dtos/responses/textMessage.ts +3 -0
- package/entities/botInstance.ts +1 -1
- package/entities/context/messageContext.ts +3 -3
- package/entities/context/replyContext.ts +3 -3
- package/{eslint.config.js → eslint.config.ts} +9 -5
- package/index.ts +3 -0
- package/package.json +2 -1
- package/services/actionProcessors/commandActionProcessor.ts +5 -6
- package/services/jsonFileStorage.ts +1 -1
- package/services/nodeTimeoutScheduler.ts +2 -2
- package/services/telegramApi.ts +34 -25
- package/tsconfig.json +2 -2
- package/types/externalAliases.ts +5 -4
- package/types/messageSendingOptions.ts +3 -0
- package/bun.lock +0 -301
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const promises_1 = require("fs/promises");
|
|
6
|
-
const async_sema_1 = require("async-sema");
|
|
7
|
-
const mapUtils_1 = require("../helpers/mapUtils");
|
|
1
|
+
import { existsSync, mkdirSync } from 'fs';
|
|
2
|
+
import { readFile, writeFile } from 'fs/promises';
|
|
3
|
+
import { Sema as Semaphore } from 'async-sema';
|
|
4
|
+
import { getOrSetIfNotExists } from '../helpers/mapUtils';
|
|
8
5
|
function buildPath(storagePath, botName, actionKey) {
|
|
9
6
|
return `${storagePath}/${botName}/${actionKey.replaceAll(':', '/')}.json`;
|
|
10
7
|
}
|
|
11
|
-
class JsonFileStorage {
|
|
8
|
+
export class JsonFileStorage {
|
|
12
9
|
filePaths = new Map();
|
|
13
10
|
locks = new Map();
|
|
14
11
|
cache;
|
|
@@ -18,13 +15,13 @@ class JsonFileStorage {
|
|
|
18
15
|
this.cache = new Map();
|
|
19
16
|
this.botName = botName;
|
|
20
17
|
this.storagePath = path ?? 'storage';
|
|
21
|
-
if (!
|
|
22
|
-
|
|
18
|
+
if (!existsSync(`${this.storagePath}/${this.botName}/`)) {
|
|
19
|
+
mkdirSync(`${this.storagePath}/${this.botName}/`, {
|
|
23
20
|
recursive: true
|
|
24
21
|
});
|
|
25
22
|
}
|
|
26
23
|
for (const action of actions) {
|
|
27
|
-
this.locks.set(action.key, new
|
|
24
|
+
this.locks.set(action.key, new Semaphore(1));
|
|
28
25
|
this.filePaths.set(action.key, buildPath(this.storagePath, this.botName, action.key));
|
|
29
26
|
}
|
|
30
27
|
}
|
|
@@ -32,12 +29,12 @@ class JsonFileStorage {
|
|
|
32
29
|
for (const [stringKey, value] of Object.entries(data)) {
|
|
33
30
|
if (value)
|
|
34
31
|
continue;
|
|
35
|
-
data[parseInt(stringKey)] = action.stateConstructor();
|
|
32
|
+
data[Number.parseInt(stringKey)] = action.stateConstructor();
|
|
36
33
|
}
|
|
37
34
|
return true;
|
|
38
35
|
}
|
|
39
36
|
async lock(key, action) {
|
|
40
|
-
const lock =
|
|
37
|
+
const lock = getOrSetIfNotExists(this.locks, key, new Semaphore(1));
|
|
41
38
|
await lock.acquire();
|
|
42
39
|
try {
|
|
43
40
|
return await action();
|
|
@@ -50,8 +47,8 @@ class JsonFileStorage {
|
|
|
50
47
|
return this.cache.get(key);
|
|
51
48
|
}
|
|
52
49
|
async loadFromFile(key) {
|
|
53
|
-
const targetPath =
|
|
54
|
-
const fileContent = await
|
|
50
|
+
const targetPath = getOrSetIfNotExists(this.filePaths, key, buildPath(this.storagePath, this.botName, key));
|
|
51
|
+
const fileContent = await readFile(targetPath, {
|
|
55
52
|
encoding: 'utf-8',
|
|
56
53
|
flag: 'a+'
|
|
57
54
|
});
|
|
@@ -63,8 +60,8 @@ class JsonFileStorage {
|
|
|
63
60
|
}
|
|
64
61
|
async updateCacheAndSaveToFile(data, key) {
|
|
65
62
|
this.cache.set(key, data);
|
|
66
|
-
const targetPath =
|
|
67
|
-
await
|
|
63
|
+
const targetPath = getOrSetIfNotExists(this.filePaths, key, buildPath(this.storagePath, this.botName, key));
|
|
64
|
+
await writeFile(targetPath, JSON.stringify(data), { flag: 'w+' });
|
|
68
65
|
}
|
|
69
66
|
async load(key) {
|
|
70
67
|
return (this.tryGetFromCache(key) ??
|
|
@@ -74,7 +71,7 @@ class JsonFileStorage {
|
|
|
74
71
|
}
|
|
75
72
|
async saveMetadata(actions) {
|
|
76
73
|
const targetPath = `${this.storagePath}/${this.botName}/Metadata-${this.botName}.json`;
|
|
77
|
-
await
|
|
74
|
+
await writeFile(targetPath, JSON.stringify(actions), {
|
|
78
75
|
flag: 'w+'
|
|
79
76
|
});
|
|
80
77
|
}
|
|
@@ -110,4 +107,3 @@ class JsonFileStorage {
|
|
|
110
107
|
});
|
|
111
108
|
}
|
|
112
109
|
}
|
|
113
|
-
exports.JsonFileStorage = JsonFileStorage;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.JsonLogger = void 0;
|
|
4
|
-
class JsonLogger {
|
|
1
|
+
export class JsonLogger {
|
|
5
2
|
serializeError(error) {
|
|
6
3
|
if (error instanceof Error) {
|
|
7
4
|
const plainObject = {
|
|
@@ -67,4 +64,3 @@ class JsonLogger {
|
|
|
67
64
|
console.error(`{"botName":"${botName}","traceId":"${traceId}","chatName":"${chatName}","error":${this.serializeError(errorObj)}${dataString}}`);
|
|
68
65
|
}
|
|
69
66
|
}
|
|
70
|
-
exports.JsonLogger = JsonLogger;
|
|
@@ -1,35 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const taskRecord_1 = require("../entities/taskRecord");
|
|
5
|
-
const traceFactory_1 = require("../helpers/traceFactory");
|
|
6
|
-
class NodeTimeoutScheduler {
|
|
1
|
+
import { TaskRecord } from '../entities/taskRecord';
|
|
2
|
+
import { createTrace } from '../helpers/traceFactory';
|
|
3
|
+
export class NodeTimeoutScheduler {
|
|
7
4
|
logger;
|
|
8
5
|
activeTasks = [];
|
|
9
6
|
constructor(logger) {
|
|
10
7
|
this.logger = logger;
|
|
11
8
|
}
|
|
12
9
|
stopAll() {
|
|
13
|
-
this.activeTasks
|
|
10
|
+
for (const task of this.activeTasks) {
|
|
14
11
|
clearInterval(task.taskId);
|
|
15
|
-
}
|
|
12
|
+
}
|
|
16
13
|
}
|
|
17
14
|
createTask(name, action, interval, executeRightAway, ownerName) {
|
|
18
15
|
const taskId = setInterval(action, interval);
|
|
19
|
-
const task = new
|
|
16
|
+
const task = new TaskRecord(name, taskId, interval);
|
|
20
17
|
if (executeRightAway) {
|
|
21
18
|
setImmediate(action);
|
|
22
19
|
}
|
|
23
|
-
this.logger.logWithTraceId(ownerName,
|
|
20
|
+
this.logger.logWithTraceId(ownerName, createTrace(this, ownerName, name), 'System', `Created task ${name}, that will run every ${interval}ms.`);
|
|
24
21
|
this.activeTasks.push(task);
|
|
25
22
|
}
|
|
26
23
|
createOnetimeTask(name, action, delay, ownerName) {
|
|
27
24
|
const actionWrapper = () => {
|
|
28
|
-
this.logger.logWithTraceId(ownerName,
|
|
25
|
+
this.logger.logWithTraceId(ownerName, createTrace(this, ownerName, name), 'System', `Executing delayed oneshot ${name}`);
|
|
29
26
|
action();
|
|
30
27
|
};
|
|
31
28
|
setTimeout(actionWrapper, delay);
|
|
32
|
-
this.logger.logWithTraceId(ownerName,
|
|
29
|
+
this.logger.logWithTraceId(ownerName, createTrace(this, ownerName, name), 'System', `Created oneshot task ${name}, that will run in ${delay}ms.`);
|
|
33
30
|
}
|
|
34
31
|
}
|
|
35
|
-
exports.NodeTimeoutScheduler = NodeTimeoutScheduler;
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ResponseProcessingQueue = void 0;
|
|
4
|
-
const async_sema_1 = require("async-sema");
|
|
1
|
+
import { RateLimit } from 'async-sema';
|
|
5
2
|
function notEmpty(arr) {
|
|
6
3
|
return arr.length > 0;
|
|
7
4
|
}
|
|
8
5
|
const TELEGRAM_RATELIMIT_DELAY = 35;
|
|
9
|
-
class ResponseProcessingQueue {
|
|
10
|
-
rateLimiter =
|
|
6
|
+
export class ResponseProcessingQueue {
|
|
7
|
+
rateLimiter = RateLimit(1, { timeUnit: TELEGRAM_RATELIMIT_DELAY });
|
|
11
8
|
items = [];
|
|
12
9
|
isFlushing = false;
|
|
13
10
|
enqueue(item) {
|
|
@@ -38,4 +35,3 @@ class ResponseProcessingQueue {
|
|
|
38
35
|
this.isFlushing = false;
|
|
39
36
|
}
|
|
40
37
|
}
|
|
41
|
-
exports.ResponseProcessingQueue = ResponseProcessingQueue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telegramApi.d.ts","sourceRoot":"","sources":["../../services/telegramApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAmB,MAAM,0BAA0B,CAAC;AAE9E,eAAO,MAAM,4BAA4B,uBAAuB,CAAC;AAEjE,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAKlC;IAEV,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAG7B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,OAAO,EACf,2BAA2B,EAAE,CACzB,OAAO,EAAE,aAAa,EACtB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,KACf,IAAI;IASb,uBAAuB,CAAC,SAAS,EAAE,WAAW,EAAE;IAwDhD,cAAc;YAIA,WAAW;YAqBX,eAAe;
|
|
1
|
+
{"version":3,"file":"telegramApi.d.ts","sourceRoot":"","sources":["../../services/telegramApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAmB,MAAM,0BAA0B,CAAC;AAE9E,eAAO,MAAM,4BAA4B,uBAAuB,CAAC;AAEjE,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAKlC;IAEV,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAG7B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,OAAO,EACf,2BAA2B,EAAE,CACzB,OAAO,EAAE,aAAa,EACtB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,KACf,IAAI;IASb,uBAAuB,CAAC,SAAS,EAAE,WAAW,EAAE;IAwDhD,cAAc;YAIA,WAAW;YAqBX,eAAe;YAiBf,cAAc;CA6F/B"}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
exports.TELEGRAM_ERROR_QUOTE_INVALID = 'QUOTE_TEXT_INVALID';
|
|
6
|
-
class TelegramApiService {
|
|
7
|
-
queue = new responseProcessingQueue_1.ResponseProcessingQueue();
|
|
1
|
+
import { ResponseProcessingQueue } from './responseProcessingQueue';
|
|
2
|
+
export const TELEGRAM_ERROR_QUOTE_INVALID = 'QUOTE_TEXT_INVALID';
|
|
3
|
+
export class TelegramApiService {
|
|
4
|
+
queue = new ResponseProcessingQueue();
|
|
8
5
|
telegram;
|
|
9
6
|
storage;
|
|
10
7
|
logger;
|
|
@@ -35,7 +32,7 @@ class TelegramApiService {
|
|
|
35
32
|
catch (error) {
|
|
36
33
|
if ('message' in error) {
|
|
37
34
|
const telegramResponse = error;
|
|
38
|
-
if (telegramResponse.message.includes(
|
|
35
|
+
if (telegramResponse.message.includes(TELEGRAM_ERROR_QUOTE_INVALID)) {
|
|
39
36
|
scopedLogger.logWithTraceId('Quote error recieved, retrying without quote');
|
|
40
37
|
try {
|
|
41
38
|
await this.processResponse(response, true);
|
|
@@ -66,10 +63,18 @@ class TelegramApiService {
|
|
|
66
63
|
}
|
|
67
64
|
}
|
|
68
65
|
async processResponse(response, ignoreQuote = false) {
|
|
69
|
-
|
|
66
|
+
const sentMessage = await this.sendApiRequest(response, ignoreQuote);
|
|
67
|
+
if (sentMessage && 'content' in response) {
|
|
68
|
+
await this.pinIfShould(response, sentMessage);
|
|
69
|
+
for (const capture of response.captures) {
|
|
70
|
+
this.captureRegistrationCallback(capture, sentMessage.message_id, response.chatInfo, response.traceId);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async sendApiRequest(response, ignoreQuote) {
|
|
70
75
|
switch (response.kind) {
|
|
71
76
|
case 'text':
|
|
72
|
-
|
|
77
|
+
return await this.telegram.sendMessage(response.chatInfo.id, response.content, {
|
|
73
78
|
reply_parameters: response.replyInfo
|
|
74
79
|
? {
|
|
75
80
|
message_id: response.replyInfo.id,
|
|
@@ -81,27 +86,29 @@ class TelegramApiService {
|
|
|
81
86
|
parse_mode: 'MarkdownV2',
|
|
82
87
|
link_preview_options: {
|
|
83
88
|
is_disabled: response.disableWebPreview
|
|
84
|
-
}
|
|
89
|
+
},
|
|
90
|
+
reply_markup: response.keyboard
|
|
91
|
+
? {
|
|
92
|
+
inline_keyboard: response.keyboard
|
|
93
|
+
}
|
|
94
|
+
: undefined
|
|
85
95
|
});
|
|
86
|
-
break;
|
|
87
96
|
case 'image':
|
|
88
|
-
|
|
97
|
+
return await this.telegram.sendPhoto(response.chatInfo.id, response.content,
|
|
89
98
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
90
99
|
response.replyInfo?.id
|
|
91
100
|
? {
|
|
92
101
|
reply_to_message_id: response.replyInfo.id // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
93
102
|
}
|
|
94
103
|
: undefined);
|
|
95
|
-
break;
|
|
96
104
|
case 'video':
|
|
97
|
-
|
|
105
|
+
return await this.telegram.sendVideo(response.chatInfo.id, response.content,
|
|
98
106
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
99
107
|
response.replyInfo?.id
|
|
100
108
|
? {
|
|
101
109
|
reply_to_message_id: response.replyInfo.id // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
102
110
|
}
|
|
103
111
|
: undefined);
|
|
104
|
-
break;
|
|
105
112
|
case 'react':
|
|
106
113
|
await this.telegram.setMessageReaction(response.chatInfo.id, response.messageId, [
|
|
107
114
|
{
|
|
@@ -109,25 +116,18 @@ class TelegramApiService {
|
|
|
109
116
|
emoji: response.emoji
|
|
110
117
|
}
|
|
111
118
|
]);
|
|
112
|
-
return;
|
|
119
|
+
return null;
|
|
113
120
|
case 'unpin':
|
|
114
121
|
await this.telegram.unpinChatMessage(response.chatInfo.id, response.messageId);
|
|
115
122
|
await this.storage.updateStateFor(response.action, response.chatInfo.id, (state) => {
|
|
116
123
|
state.pinnedMessages = state.pinnedMessages.filter((x) => x != response.messageId);
|
|
117
124
|
});
|
|
118
|
-
|
|
125
|
+
return null;
|
|
119
126
|
case 'inlineQuery':
|
|
120
127
|
await this.telegram.answerInlineQuery(response.queryId, response.queryResults, { cache_time: 0 });
|
|
121
|
-
|
|
128
|
+
return null;
|
|
122
129
|
case 'delay':
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
if ('content' in response && sentMessage) {
|
|
126
|
-
await this.pinIfShould(response, sentMessage);
|
|
127
|
-
for (const capture of response.captures) {
|
|
128
|
-
this.captureRegistrationCallback(capture, sentMessage.message_id, response.chatInfo, response.traceId);
|
|
129
|
-
}
|
|
130
|
+
return null;
|
|
130
131
|
}
|
|
131
132
|
}
|
|
132
133
|
}
|
|
133
|
-
exports.TelegramApiService = TelegramApiService;
|
package/dist/types/action.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/dist/types/capture.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import Telegram from 'telegraf/typings/telegram';
|
|
1
|
+
import { Telegram, Telegraf } from 'telegraf';
|
|
2
|
+
import { User, Message, InlineQueryResult, UserFromGetMe, TelegramEmoji as Emoji, InlineKeyboardButton } from 'telegraf/types';
|
|
4
3
|
export type TelegramUser = User;
|
|
5
4
|
export type TelegramMessage = Message;
|
|
6
5
|
export type TelegramInlineQueryResult = InlineQueryResult;
|
|
@@ -8,4 +7,5 @@ export type TelegramEmoji = Emoji;
|
|
|
8
7
|
export type TelegramApiClient = Telegram;
|
|
9
8
|
export type BotInfo = UserFromGetMe;
|
|
10
9
|
export type TelegramBot = Telegraf;
|
|
10
|
+
export type TelegramInlineKeyboardButton = InlineKeyboardButton;
|
|
11
11
|
//# sourceMappingURL=externalAliases.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"externalAliases.d.ts","sourceRoot":"","sources":["../../types/externalAliases.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,IAAI,EACJ,OAAO,EACP,iBAAiB,EACjB,aAAa,IAAI,KAAK,EACtB,
|
|
1
|
+
{"version":3,"file":"externalAliases.d.ts","sourceRoot":"","sources":["../../types/externalAliases.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EACH,IAAI,EACJ,OAAO,EACP,iBAAiB,EACjB,aAAa,EACb,aAAa,IAAI,KAAK,EACtB,oBAAoB,EACvB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC;AAChC,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC;AACtC,MAAM,MAAM,yBAAyB,GAAG,iBAAiB,CAAC;AAC1D,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC;AAClC,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;AACzC,MAAM,MAAM,OAAO,GAAG,aAAa,CAAC;AACpC,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;AACnC,MAAM,MAAM,4BAA4B,GAAG,oBAAoB,CAAC"}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/dist/types/handlers.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/dist/types/inputFile.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/dist/types/logger.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { TelegramInlineKeyboardButton } from './externalAliases';
|
|
1
2
|
export interface MessageSendingOptions {
|
|
2
3
|
pin?: boolean;
|
|
3
4
|
}
|
|
4
5
|
export interface TextMessageSendingOptions extends MessageSendingOptions {
|
|
5
6
|
disableWebPreview?: boolean;
|
|
7
|
+
keyboard?: TelegramInlineKeyboardButton[][];
|
|
6
8
|
}
|
|
7
9
|
//# sourceMappingURL=messageSendingOptions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messageSendingOptions.d.ts","sourceRoot":"","sources":["../../types/messageSendingOptions.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IAClC,GAAG,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,yBAA0B,SAAQ,qBAAqB;IACpE,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/
|
|
1
|
+
{"version":3,"file":"messageSendingOptions.d.ts","sourceRoot":"","sources":["../../types/messageSendingOptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAEjE,MAAM,WAAW,qBAAqB;IAClC,GAAG,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,yBAA0B,SAAQ,qBAAqB;IACpE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,4BAA4B,EAAE,EAAE,CAAC;CAC/C"}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
Forward: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}Forward`,
|
|
19
|
-
Video: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}Video`,
|
|
20
|
-
Unknown: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}Unknown`
|
|
1
|
+
export const INTERNAL_MESSAGE_TYPE_PREFIX = `__msg:`;
|
|
2
|
+
export const MessageType = {
|
|
3
|
+
Any: `${INTERNAL_MESSAGE_TYPE_PREFIX}Any`,
|
|
4
|
+
Text: `${INTERNAL_MESSAGE_TYPE_PREFIX}Text`,
|
|
5
|
+
Sticker: `${INTERNAL_MESSAGE_TYPE_PREFIX}Sticker`,
|
|
6
|
+
Animation: `${INTERNAL_MESSAGE_TYPE_PREFIX}Animation`,
|
|
7
|
+
Document: `${INTERNAL_MESSAGE_TYPE_PREFIX}Document`,
|
|
8
|
+
Voice: `${INTERNAL_MESSAGE_TYPE_PREFIX}Voice`,
|
|
9
|
+
Audio: `${INTERNAL_MESSAGE_TYPE_PREFIX}Audio`,
|
|
10
|
+
LeftChatMember: `${INTERNAL_MESSAGE_TYPE_PREFIX}LeftChatMember`,
|
|
11
|
+
NewChatMember: `${INTERNAL_MESSAGE_TYPE_PREFIX}NewChatMember`,
|
|
12
|
+
Poll: `${INTERNAL_MESSAGE_TYPE_PREFIX}Poll`,
|
|
13
|
+
Location: `${INTERNAL_MESSAGE_TYPE_PREFIX}Location`,
|
|
14
|
+
Photo: `${INTERNAL_MESSAGE_TYPE_PREFIX}Photo`,
|
|
15
|
+
Forward: `${INTERNAL_MESSAGE_TYPE_PREFIX}Forward`,
|
|
16
|
+
Video: `${INTERNAL_MESSAGE_TYPE_PREFIX}Video`,
|
|
17
|
+
Unknown: `${INTERNAL_MESSAGE_TYPE_PREFIX}Unknown`
|
|
21
18
|
};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/dist/types/response.js
CHANGED
package/dist/types/scheduler.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/dist/types/storage.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/dist/types/timeValues.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/dist/types/trace.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -8,6 +8,7 @@ import { ChatInfo } from '../chatInfo';
|
|
|
8
8
|
import { TraceId } from '../../types/trace';
|
|
9
9
|
import { ReplyInfo } from '../replyInfo';
|
|
10
10
|
import { IReplyCapture } from '../../types/capture';
|
|
11
|
+
import { TelegramInlineKeyboardButton } from '../../types/externalAliases';
|
|
11
12
|
|
|
12
13
|
export class TextMessage implements IReplyResponseWithContent<string> {
|
|
13
14
|
readonly kind = BotResponseTypes.text;
|
|
@@ -21,6 +22,7 @@ export class TextMessage implements IReplyResponseWithContent<string> {
|
|
|
21
22
|
readonly disableWebPreview: boolean;
|
|
22
23
|
readonly shouldPin: boolean;
|
|
23
24
|
readonly action: IAction;
|
|
25
|
+
readonly keyboard?: TelegramInlineKeyboardButton[][];
|
|
24
26
|
|
|
25
27
|
constructor(
|
|
26
28
|
text: string,
|
|
@@ -37,5 +39,6 @@ export class TextMessage implements IReplyResponseWithContent<string> {
|
|
|
37
39
|
this.disableWebPreview = options?.disableWebPreview ?? false;
|
|
38
40
|
this.shouldPin = options?.pin ?? false;
|
|
39
41
|
this.action = action;
|
|
42
|
+
this.keyboard = options?.keyboard;
|
|
40
43
|
}
|
|
41
44
|
}
|
package/entities/botInstance.ts
CHANGED
|
@@ -43,9 +43,9 @@ export class MessageContextInternal<
|
|
|
43
43
|
private getQuotePart(quote: boolean | string) {
|
|
44
44
|
if (typeof quote != 'boolean') return quote;
|
|
45
45
|
|
|
46
|
-
return this.matchResults.length
|
|
47
|
-
? this.
|
|
48
|
-
: this.
|
|
46
|
+
return this.matchResults.length == 0
|
|
47
|
+
? this.messageInfo.text
|
|
48
|
+
: this.matchResults[0][1];
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
private replyWithText(
|
|
@@ -45,9 +45,9 @@ export class ReplyContextInternal<
|
|
|
45
45
|
private getQuotePart(quote: boolean | string) {
|
|
46
46
|
if (typeof quote != 'boolean') return quote;
|
|
47
47
|
|
|
48
|
-
return this.matchResults.length
|
|
49
|
-
? this.
|
|
50
|
-
: this.
|
|
48
|
+
return this.matchResults.length == 0
|
|
49
|
+
? this.messageInfo.text
|
|
50
|
+
: this.matchResults[0][1];
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
private replyWithText(
|
|
@@ -3,19 +3,24 @@ import tseslint from 'typescript-eslint';
|
|
|
3
3
|
import parser from '@typescript-eslint/parser';
|
|
4
4
|
|
|
5
5
|
export default tseslint.config(
|
|
6
|
+
{
|
|
7
|
+
ignores: ['dist/**']
|
|
8
|
+
},
|
|
6
9
|
eslint.configs.recommended,
|
|
7
10
|
tseslint.configs.strictTypeChecked,
|
|
8
11
|
{
|
|
9
12
|
languageOptions: {
|
|
10
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
11
13
|
parser,
|
|
12
14
|
parserOptions: {
|
|
13
15
|
project: './tsconfig.json',
|
|
14
|
-
tsconfigRootDir:
|
|
15
|
-
sourceType: 'module'
|
|
16
|
+
tsconfigRootDir: __dirname,
|
|
17
|
+
sourceType: 'module',
|
|
18
|
+
projectService: true
|
|
16
19
|
}
|
|
17
20
|
},
|
|
21
|
+
plugins: { '@typescript-eslint': tseslint.plugin },
|
|
18
22
|
rules: {
|
|
23
|
+
'@typescript-eslint/switch-exhaustiveness-check': 'error',
|
|
19
24
|
'@typescript-eslint/no-unused-vars': [
|
|
20
25
|
'error',
|
|
21
26
|
{
|
|
@@ -47,7 +52,6 @@ export default tseslint.config(
|
|
|
47
52
|
ignoreStatic: true
|
|
48
53
|
}
|
|
49
54
|
]
|
|
50
|
-
}
|
|
51
|
-
ignores: ['dist/*']
|
|
55
|
+
}
|
|
52
56
|
}
|
|
53
57
|
);
|
package/index.ts
CHANGED
|
@@ -8,6 +8,9 @@ export * from './types/messageTypes';
|
|
|
8
8
|
export * from './helpers/timeConvertions';
|
|
9
9
|
export * from './types/action';
|
|
10
10
|
export * from './types/externalAliases';
|
|
11
|
+
export * from './types/storage';
|
|
12
|
+
export * from './types/logger';
|
|
13
|
+
export * from './types/scheduler';
|
|
11
14
|
export { CommandAction } from './entities/actions/commandAction';
|
|
12
15
|
export { InlineQueryAction } from './entities/actions/inlineQueryAction';
|
|
13
16
|
export { ReplyCaptureAction } from './entities/actions/replyCaptureAction';
|
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"type": "git",
|
|
15
15
|
"url": "https://github.com/AlexSolari/botFramework.git"
|
|
16
16
|
},
|
|
17
|
-
"version": "0.5.
|
|
17
|
+
"version": "0.5.2",
|
|
18
18
|
"type": "module",
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"async-sema": "^3.1.1",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"@eslint/js": "^9.29.0",
|
|
28
28
|
"@types/node": "^22.5.5",
|
|
29
29
|
"eslint": "^9.29.0",
|
|
30
|
+
"jiti": "^2.6.1",
|
|
30
31
|
"typescript": "^5.9.0-beta",
|
|
31
32
|
"typescript-eslint": "^8.34.1"
|
|
32
33
|
},
|
|
@@ -48,9 +48,8 @@ export class CommandActionProcessor extends BaseActionProcessor {
|
|
|
48
48
|
if (msgType == MessageType.Text) {
|
|
49
49
|
this.commands[msgType] = commands.filter(
|
|
50
50
|
(cmd) =>
|
|
51
|
-
cmd.triggers.
|
|
52
|
-
|
|
53
|
-
cmd.triggers.find(
|
|
51
|
+
cmd.triggers.some((x) => typeof x != 'string') ||
|
|
52
|
+
cmd.triggers.some(
|
|
54
53
|
(x) =>
|
|
55
54
|
typeof x == 'string' &&
|
|
56
55
|
!x.startsWith(INTERNAL_MESSAGE_TYPE_PREFIX)
|
|
@@ -161,9 +160,9 @@ export class CommandActionProcessor extends BaseActionProcessor {
|
|
|
161
160
|
|
|
162
161
|
const commandsToCheck = new Set(this.commands[msg.type]);
|
|
163
162
|
if (msg.type != MessageType.Text && msg.text != '') {
|
|
164
|
-
this.commands[MessageType.Text]
|
|
165
|
-
commandsToCheck.add(
|
|
166
|
-
|
|
163
|
+
for (const command of this.commands[MessageType.Text]) {
|
|
164
|
+
commandsToCheck.add(command);
|
|
165
|
+
}
|
|
167
166
|
}
|
|
168
167
|
|
|
169
168
|
for (const commandAction of commandsToCheck) {
|
|
@@ -48,7 +48,7 @@ export class JsonFileStorage implements IStorageClient {
|
|
|
48
48
|
for (const [stringKey, value] of Object.entries(data)) {
|
|
49
49
|
if (value) continue;
|
|
50
50
|
|
|
51
|
-
data[parseInt(stringKey)] = action.stateConstructor();
|
|
51
|
+
data[Number.parseInt(stringKey)] = action.stateConstructor();
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
return true;
|