chz-telegram-bot 0.0.25 → 0.0.27
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/entities/actions/commandAction.d.ts +3 -3
- package/dist/entities/actions/commandAction.d.ts.map +1 -1
- package/dist/entities/actions/commandAction.js +12 -7
- package/dist/entities/actions/scheduledAction.d.ts +2 -2
- package/dist/entities/actions/scheduledAction.d.ts.map +1 -1
- package/dist/entities/botInstance.d.ts.map +1 -1
- package/dist/entities/botInstance.js +3 -2
- package/dist/entities/context/chatContext.d.ts +3 -2
- package/dist/entities/context/chatContext.d.ts.map +1 -1
- package/dist/entities/context/chatContext.js +6 -6
- package/dist/entities/context/messageContext.d.ts +3 -1
- package/dist/entities/context/messageContext.d.ts.map +1 -1
- package/dist/entities/context/messageContext.js +19 -11
- package/dist/entities/responses/imageMessage.d.ts +3 -2
- package/dist/entities/responses/imageMessage.d.ts.map +1 -1
- package/dist/entities/responses/imageMessage.js +2 -2
- package/dist/entities/responses/reaction.d.ts +3 -2
- package/dist/entities/responses/reaction.d.ts.map +1 -1
- package/dist/entities/responses/reaction.js +2 -2
- package/dist/entities/responses/textMessage.d.ts +3 -2
- package/dist/entities/responses/textMessage.d.ts.map +1 -1
- package/dist/entities/responses/textMessage.js +2 -2
- package/dist/entities/responses/unpin.d.ts +3 -2
- package/dist/entities/responses/unpin.d.ts.map +1 -1
- package/dist/entities/responses/unpin.js +2 -2
- package/dist/entities/responses/videoMessage.d.ts +3 -2
- package/dist/entities/responses/videoMessage.d.ts.map +1 -1
- package/dist/entities/responses/videoMessage.js +2 -2
- package/dist/helpers/builders/commandActionBuilder.d.ts +3 -3
- package/dist/helpers/builders/commandActionBuilder.d.ts.map +1 -1
- package/dist/services/jsonFileStorage.d.ts +6 -7
- package/dist/services/jsonFileStorage.d.ts.map +1 -1
- package/dist/services/jsonFileStorage.js +29 -23
- package/dist/services/logger.d.ts.map +1 -1
- package/dist/services/logger.js +2 -8
- package/dist/services/taskScheduler.d.ts.map +1 -1
- package/dist/services/taskScheduler.js +0 -1
- package/dist/services/telegramApi.d.ts +1 -1
- package/dist/services/telegramApi.d.ts.map +1 -1
- package/dist/services/telegramApi.js +6 -9
- package/dist/types/actionWithState.d.ts +4 -1
- package/dist/types/actionWithState.d.ts.map +1 -1
- package/dist/types/response.d.ts +2 -1
- package/dist/types/response.d.ts.map +1 -1
- package/dist/types/storage.d.ts +4 -4
- package/dist/types/storage.d.ts.map +1 -1
- package/entities/actions/commandAction.ts +20 -12
- package/entities/actions/scheduledAction.ts +3 -3
- package/entities/botInstance.ts +4 -5
- package/entities/context/chatContext.ts +9 -15
- package/entities/context/messageContext.ts +30 -27
- package/entities/responses/imageMessage.ts +4 -3
- package/entities/responses/reaction.ts +4 -3
- package/entities/responses/textMessage.ts +4 -3
- package/entities/responses/unpin.ts +4 -3
- package/entities/responses/videoMessage.ts +4 -3
- package/helpers/builders/commandActionBuilder.ts +3 -3
- package/package.json +1 -1
- package/services/jsonFileStorage.ts +41 -27
- package/services/logger.ts +6 -8
- package/services/taskScheduler.ts +0 -1
- package/services/telegramApi.ts +9 -18
- package/types/actionWithState.ts +3 -1
- package/types/response.ts +3 -1
- package/types/storage.ts +4 -4
|
@@ -5,10 +5,9 @@ const fs_1 = require("fs");
|
|
|
5
5
|
const path_1 = require("path");
|
|
6
6
|
const promises_1 = require("fs/promises");
|
|
7
7
|
const async_sema_1 = require("async-sema");
|
|
8
|
-
const actionStateBase_1 = require("../entities/states/actionStateBase");
|
|
9
8
|
class JsonFileStorage {
|
|
10
|
-
constructor(botName, path) {
|
|
11
|
-
this.
|
|
9
|
+
constructor(botName, actions, path) {
|
|
10
|
+
this.locks = new Map();
|
|
12
11
|
this.cache = new Map();
|
|
13
12
|
this.botName = botName;
|
|
14
13
|
this.storagePath = path ?? 'storage';
|
|
@@ -17,14 +16,21 @@ class JsonFileStorage {
|
|
|
17
16
|
recursive: true
|
|
18
17
|
});
|
|
19
18
|
}
|
|
19
|
+
for (const action of actions) {
|
|
20
|
+
this.locks.set(action.key, new async_sema_1.Sema(1));
|
|
21
|
+
}
|
|
20
22
|
}
|
|
21
|
-
async lock(action) {
|
|
22
|
-
|
|
23
|
+
async lock(key, action) {
|
|
24
|
+
const lock = this.locks.get(key);
|
|
25
|
+
if (!lock) {
|
|
26
|
+
throw new Error(`Lock for action ${key} not found`);
|
|
27
|
+
}
|
|
28
|
+
await lock.acquire();
|
|
23
29
|
try {
|
|
24
30
|
return await action();
|
|
25
31
|
}
|
|
26
32
|
finally {
|
|
27
|
-
|
|
33
|
+
lock.release();
|
|
28
34
|
}
|
|
29
35
|
}
|
|
30
36
|
async loadInternal(key) {
|
|
@@ -54,26 +60,24 @@ class JsonFileStorage {
|
|
|
54
60
|
return `${this.storagePath}/${this.botName}/${key.replaceAll(':', '/')}.json`;
|
|
55
61
|
}
|
|
56
62
|
async load(key) {
|
|
57
|
-
return await this.lock(async () => {
|
|
63
|
+
return await this.lock(key, async () => {
|
|
58
64
|
return this.loadInternal(key);
|
|
59
65
|
});
|
|
60
66
|
}
|
|
61
67
|
async saveMetadata(actions, botName) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
flag: 'w+'
|
|
66
|
-
});
|
|
68
|
+
const targetPath = this.buidPathFromKey(`Metadata-${botName}`);
|
|
69
|
+
await (0, promises_1.writeFile)(targetPath, JSON.stringify(actions), {
|
|
70
|
+
flag: 'w+'
|
|
67
71
|
});
|
|
68
72
|
}
|
|
69
|
-
async getActionState(
|
|
70
|
-
return await this.lock(async () => {
|
|
71
|
-
const data = await this.loadInternal(
|
|
72
|
-
return Object.assign(
|
|
73
|
+
async getActionState(action, chatId) {
|
|
74
|
+
return await this.lock(action.key, async () => {
|
|
75
|
+
const data = await this.loadInternal(action.key);
|
|
76
|
+
return Object.assign(action.stateConstructor(), data[chatId]);
|
|
73
77
|
});
|
|
74
78
|
}
|
|
75
79
|
async saveActionExecutionResult(action, chatId, transactionResult) {
|
|
76
|
-
await this.lock(async () => {
|
|
80
|
+
await this.lock(action.key, async () => {
|
|
77
81
|
const data = await this.loadInternal(action.key);
|
|
78
82
|
if (transactionResult.shouldUpdate) {
|
|
79
83
|
data[chatId] = transactionResult.data;
|
|
@@ -82,14 +86,16 @@ class JsonFileStorage {
|
|
|
82
86
|
});
|
|
83
87
|
}
|
|
84
88
|
async close() {
|
|
85
|
-
|
|
89
|
+
for (const lock of this.locks.values()) {
|
|
90
|
+
await lock.acquire();
|
|
91
|
+
}
|
|
86
92
|
}
|
|
87
|
-
async updateStateFor(
|
|
88
|
-
await this.lock(async () => {
|
|
89
|
-
const data = await this.loadInternal(
|
|
90
|
-
const state = Object.assign(
|
|
93
|
+
async updateStateFor(action, chatId, update) {
|
|
94
|
+
await this.lock(action.key, async () => {
|
|
95
|
+
const data = await this.loadInternal(action.key);
|
|
96
|
+
const state = Object.assign(action.stateConstructor(), data[chatId]);
|
|
91
97
|
await update(state);
|
|
92
|
-
await this.save(data,
|
|
98
|
+
await this.save(data, action.key);
|
|
93
99
|
});
|
|
94
100
|
}
|
|
95
101
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../services/logger.ts"],"names":[],"mappings":"AAAA,cAAM,UAAU;IAEZ,OAAO,CAAC,cAAc;IAQtB,cAAc,CACV,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../services/logger.ts"],"names":[],"mappings":"AAAA,cAAM,UAAU;IAEZ,OAAO,CAAC,cAAc;IAQtB,cAAc,CACV,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM;IAOhB,gBAAgB,CAAC,KAAK,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,OAAO,EACjB,SAAS,CAAC,EAAE,KAAK,GAAG,SAAS;CAQpC;AAED,eAAO,MAAM,MAAM,YAAmB,CAAC"}
|
package/dist/services/logger.js
CHANGED
|
@@ -11,16 +11,10 @@ class JsonLogger {
|
|
|
11
11
|
return JSON.stringify(plainObject);
|
|
12
12
|
}
|
|
13
13
|
logWithTraceId(botName, traceId, chatName, text) {
|
|
14
|
-
console.log(
|
|
14
|
+
console.log(`{"botName":"${botName}","traceId":"${traceId}","chatName":"${chatName}","text":"${text}"}`);
|
|
15
15
|
}
|
|
16
16
|
errorWithTraceId(botName, traceId, chatName, errorObj, extraData) {
|
|
17
|
-
console.error(JSON.stringify(
|
|
18
|
-
botName,
|
|
19
|
-
traceId,
|
|
20
|
-
chatName,
|
|
21
|
-
error: this.serializeError(errorObj),
|
|
22
|
-
extraData
|
|
23
|
-
}));
|
|
17
|
+
console.error(`{"botName":"${botName}","traceId":"${traceId}","chatName":"${chatName}","error":${this.serializeError(errorObj)}${extraData ? `,"extraData":${JSON.stringify(extraData)}` : ''}}`);
|
|
24
18
|
}
|
|
25
19
|
}
|
|
26
20
|
exports.Logger = new JsonLogger();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"taskScheduler.d.ts","sourceRoot":"","sources":["../../services/taskScheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,cAAM,aAAa;IACf,WAAW,EAAE,UAAU,EAAE,CAAM;IAE/B,OAAO;IAMP,UAAU,CACN,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,IAAI,EAClB,QAAQ,EAAE,YAAY,EACtB,gBAAgB,EAAE,OAAO,EACzB,SAAS,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"taskScheduler.d.ts","sourceRoot":"","sources":["../../services/taskScheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,cAAM,aAAa;IACf,WAAW,EAAE,UAAU,EAAE,CAAM;IAE/B,OAAO;IAMP,UAAU,CACN,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,IAAI,EAClB,QAAQ,EAAE,YAAY,EACtB,gBAAgB,EAAE,OAAO,EACzB,SAAS,EAAE,MAAM;IAmBrB,iBAAiB,CACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,IAAI,EAClB,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM;CAoBxB;AAED,eAAO,MAAM,SAAS,eAAsB,CAAC"}
|
|
@@ -13,7 +13,6 @@ class TaskScheduler {
|
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
15
|
createTask(name, action, interval, executeRightAway, ownerName) {
|
|
16
|
-
executeRightAway = executeRightAway ?? false;
|
|
17
16
|
const taskId = setInterval(action, interval);
|
|
18
17
|
const task = new taskRecord_1.TaskRecord(name, taskId, interval);
|
|
19
18
|
if (executeRightAway) {
|
|
@@ -14,7 +14,7 @@ import { IActionState } from '../types/actionState';
|
|
|
14
14
|
import { CommandAction } from '../entities/actions/commandAction';
|
|
15
15
|
export declare class TelegramApiService {
|
|
16
16
|
isFlushing: boolean;
|
|
17
|
-
messageQueue:
|
|
17
|
+
messageQueue: BotResponse[];
|
|
18
18
|
botName: string;
|
|
19
19
|
telegram: Telegram;
|
|
20
20
|
chats: Record<number, string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telegramApi.d.ts","sourceRoot":"","sources":["../../services/telegramApi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAiB,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"telegramApi.d.ts","sourceRoot":"","sources":["../../services/telegramApi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAiB,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAIlE,qBAAa,kBAAkB;IAC3B,UAAU,UAAS;IACnB,YAAY,EAAE,WAAW,EAAE,CAAM;IAEjC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,OAAO,EAAE,cAAc,CAAC;gBAGpB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAQ3B,cAAc;YA2BN,WAAW;YAqBX,eAAe;IA2E7B,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,eAAe;IAQvB,uBAAuB,CAAC,YAAY,SAAS,YAAY,EACrD,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC;IAWxC,oBAAoB,CAAC,YAAY,SAAS,YAAY,EAClD,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,eAAe,CAAC,YAAY,CAAC;CAYrD;AAED,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,CAAC,QAAQ,EAAE,WAAW,GAAG,YAAY,GAAG,YAAY,KAAK,IAAI,CAAC;IACvE,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,KAAK,EAAE,CAAC,YAAY,EAAE,aAAa,KAAK,IAAI,CAAC;CAChD"}
|
|
@@ -6,6 +6,7 @@ const messageContext_1 = require("../entities/context/messageContext");
|
|
|
6
6
|
const reverseRecord_1 = require("../helpers/reverseRecord");
|
|
7
7
|
const logger_1 = require("./logger");
|
|
8
8
|
const promises_1 = require("timers/promises");
|
|
9
|
+
const TELEGRAM_RATELIMIT_DELAY = 35;
|
|
9
10
|
class TelegramApiService {
|
|
10
11
|
constructor(botName, telegram, storage, chats) {
|
|
11
12
|
this.isFlushing = false;
|
|
@@ -25,7 +26,7 @@ class TelegramApiService {
|
|
|
25
26
|
break;
|
|
26
27
|
try {
|
|
27
28
|
await this.processResponse(message);
|
|
28
|
-
await (0, promises_1.setTimeout)(
|
|
29
|
+
await (0, promises_1.setTimeout)(TELEGRAM_RATELIMIT_DELAY);
|
|
29
30
|
}
|
|
30
31
|
catch (error) {
|
|
31
32
|
logger_1.Logger.errorWithTraceId(this.botName, message.traceId, this.chats[message.chatId], error, message);
|
|
@@ -36,7 +37,7 @@ class TelegramApiService {
|
|
|
36
37
|
async pinIfShould(response, sentMessage) {
|
|
37
38
|
if (response.shouldPin) {
|
|
38
39
|
await this.telegram.pinChatMessage(response.chatId, sentMessage.message_id, { disable_notification: true });
|
|
39
|
-
await this.storage.updateStateFor(response.
|
|
40
|
+
await this.storage.updateStateFor(response.action, response.chatId, async (state) => {
|
|
40
41
|
state.pinnedMessages.push(sentMessage.message_id);
|
|
41
42
|
});
|
|
42
43
|
}
|
|
@@ -77,7 +78,7 @@ class TelegramApiService {
|
|
|
77
78
|
return;
|
|
78
79
|
case 'unpin':
|
|
79
80
|
await this.telegram.unpinChatMessage(response.chatId, response.messageId);
|
|
80
|
-
await this.storage.updateStateFor(response.
|
|
81
|
+
await this.storage.updateStateFor(response.action, response.chatId, async (state) => {
|
|
81
82
|
state.pinnedMessages = state.pinnedMessages.filter((x) => x != response.messageId);
|
|
82
83
|
});
|
|
83
84
|
break;
|
|
@@ -94,14 +95,10 @@ class TelegramApiService {
|
|
|
94
95
|
};
|
|
95
96
|
}
|
|
96
97
|
createContextForMessage(incomingMessage, command) {
|
|
97
|
-
|
|
98
|
-
const lastName = incomingMessage.from?.last_name
|
|
99
|
-
? ` ${incomingMessage.from?.last_name}`
|
|
100
|
-
: '';
|
|
101
|
-
return new messageContext_1.MessageContext(this.botName, command.key, this.getInteractions(), incomingMessage.chat.id, incomingMessage.chatName, incomingMessage.message_id, incomingMessage.text, incomingMessage.from?.id, incomingMessage.traceId, firstName + lastName, this.storage);
|
|
98
|
+
return new messageContext_1.MessageContext(this.botName, command, this.getInteractions(), incomingMessage, this.storage);
|
|
102
99
|
}
|
|
103
100
|
createContextForChat(chatId, scheduledAction) {
|
|
104
|
-
return new chatContext_1.ChatContext(this.botName, scheduledAction
|
|
101
|
+
return new chatContext_1.ChatContext(this.botName, scheduledAction, this.getInteractions(), chatId, this.chats[chatId], `Scheduled:${scheduledAction.key}:${chatId}`, this.storage);
|
|
105
102
|
}
|
|
106
103
|
}
|
|
107
104
|
exports.TelegramApiService = TelegramApiService;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { IActionState } from './actionState';
|
|
2
|
+
export type ActionKey = string & {
|
|
3
|
+
__brand: 'actionKey';
|
|
4
|
+
};
|
|
2
5
|
export interface IActionWithState {
|
|
3
|
-
key:
|
|
6
|
+
key: ActionKey;
|
|
4
7
|
stateConstructor: () => IActionState;
|
|
5
8
|
}
|
|
6
9
|
//# sourceMappingURL=actionWithState.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actionWithState.d.ts","sourceRoot":"","sources":["../../types/actionWithState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,WAAW,gBAAgB;IAC7B,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"actionWithState.d.ts","sourceRoot":"","sources":["../../types/actionWithState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AAE1D,MAAM,WAAW,gBAAgB;IAC7B,GAAG,EAAE,SAAS,CAAC;IACf,gBAAgB,EAAE,MAAM,YAAY,CAAC;CACxC"}
|
package/dist/types/response.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Reaction } from '../entities/responses/reaction';
|
|
|
3
3
|
import { TextMessage } from '../entities/responses/textMessage';
|
|
4
4
|
import { UnpinResponse } from '../entities/responses/unpin';
|
|
5
5
|
import { VideoMessage } from '../entities/responses/videoMessage';
|
|
6
|
+
import { IActionWithState } from './actionWithState';
|
|
6
7
|
export declare const BotResponseTypes: {
|
|
7
8
|
readonly unpin: "unpin";
|
|
8
9
|
readonly text: "text";
|
|
@@ -15,7 +16,7 @@ export interface IChatResponse {
|
|
|
15
16
|
kind: keyof typeof BotResponseTypes;
|
|
16
17
|
chatId: number;
|
|
17
18
|
traceId: number | string;
|
|
18
|
-
|
|
19
|
+
action: IActionWithState;
|
|
19
20
|
}
|
|
20
21
|
export interface IReplyMessage<TType> extends IChatResponse {
|
|
21
22
|
content: TType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../types/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../types/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,gBAAgB;;;;;;CAMnB,CAAC;AAEX,MAAM,MAAM,WAAW,GACjB,aAAa,GACb,QAAQ,GACR,WAAW,GACX,YAAY,GACZ,YAAY,CAAC;AAEnB,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,OAAO,gBAAgB,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzB,MAAM,EAAE,gBAAgB,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa,CAAC,KAAK,CAAE,SAAQ,aAAa;IACvD,OAAO,EAAE,KAAK,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;CACtB"}
|
package/dist/types/storage.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { ActionExecutionResult } from '../entities/actionExecutionResult';
|
|
2
2
|
import { IActionState } from './actionState';
|
|
3
|
-
import { IActionWithState } from './actionWithState';
|
|
3
|
+
import { ActionKey, IActionWithState } from './actionWithState';
|
|
4
4
|
export interface IStorageClient {
|
|
5
|
-
updateStateFor<TActionState extends IActionState>(
|
|
5
|
+
updateStateFor<TActionState extends IActionState>(action: IActionWithState, chatId: number, update: (state: TActionState) => Promise<void>): Promise<void>;
|
|
6
6
|
close(): Promise<void>;
|
|
7
|
-
load<TActionState extends IActionState>(key:
|
|
7
|
+
load<TActionState extends IActionState>(key: ActionKey): Promise<Record<number, TActionState>>;
|
|
8
8
|
saveMetadata(actions: IActionWithState[], botName: string): Promise<void>;
|
|
9
|
-
getActionState<TActionState extends IActionState>(
|
|
9
|
+
getActionState<TActionState extends IActionState>(action: IActionWithState, chatId: number): Promise<TActionState>;
|
|
10
10
|
saveActionExecutionResult(action: IActionWithState, chatId: number, transactionResult: ActionExecutionResult): Promise<void>;
|
|
11
11
|
}
|
|
12
12
|
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../types/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../types/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEhE,MAAM,WAAW,cAAc;IAC3B,cAAc,CAAC,YAAY,SAAS,YAAY,EAC5C,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,GAC/C,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,CAAC,YAAY,SAAS,YAAY,EAClC,GAAG,EAAE,SAAS,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IACzC,YAAY,CAAC,OAAO,EAAE,gBAAgB,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,cAAc,CAAC,YAAY,SAAS,YAAY,EAC5C,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CAAC;IACzB,yBAAyB,CACrB,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,qBAAqB,GACzC,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB"}
|
|
@@ -5,7 +5,7 @@ import { Seconds } from '../../types/timeValues';
|
|
|
5
5
|
import { secondsToMilliseconds } from '../../helpers/timeConvertions';
|
|
6
6
|
import { toArray } from '../../helpers/toArray';
|
|
7
7
|
import { IActionState } from '../../types/actionState';
|
|
8
|
-
import { IActionWithState } from '../../types/actionWithState';
|
|
8
|
+
import { IActionWithState, ActionKey } from '../../types/actionWithState';
|
|
9
9
|
import { CommandTriggerCheckResult } from '../commandTriggerCheckResult';
|
|
10
10
|
import { MessageContext } from '../context/messageContext';
|
|
11
11
|
import { Logger } from '../../services/logger';
|
|
@@ -23,16 +23,16 @@ export class CommandAction<TActionState extends IActionState>
|
|
|
23
23
|
allowedUsers: number[];
|
|
24
24
|
condition: CommandCondition<TActionState>;
|
|
25
25
|
stateConstructor: () => TActionState;
|
|
26
|
-
key:
|
|
26
|
+
key: ActionKey;
|
|
27
27
|
|
|
28
28
|
constructor(
|
|
29
|
-
trigger: string | RegExp |
|
|
29
|
+
trigger: string | RegExp | string[] | RegExp[],
|
|
30
30
|
handler: CommandHandler<TActionState>,
|
|
31
31
|
name: string,
|
|
32
32
|
active: boolean,
|
|
33
33
|
cooldown: Seconds,
|
|
34
|
-
chatsBlacklist:
|
|
35
|
-
allowedUsers:
|
|
34
|
+
chatsBlacklist: number[],
|
|
35
|
+
allowedUsers: number[],
|
|
36
36
|
condition: CommandCondition<TActionState>,
|
|
37
37
|
stateConstructor: () => TActionState
|
|
38
38
|
) {
|
|
@@ -46,7 +46,7 @@ export class CommandAction<TActionState extends IActionState>
|
|
|
46
46
|
this.condition = condition;
|
|
47
47
|
this.stateConstructor = stateConstructor;
|
|
48
48
|
|
|
49
|
-
this.key = `command:${this.name.replace('.', '-')}
|
|
49
|
+
this.key = `command:${this.name.replace('.', '-')}` as ActionKey;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
async exec(ctx: MessageContext<TActionState>) {
|
|
@@ -122,14 +122,22 @@ export class CommandAction<TActionState extends IActionState>
|
|
|
122
122
|
if (typeof trigger == 'string') {
|
|
123
123
|
shouldTrigger = ctx.messageText.toLowerCase() == trigger;
|
|
124
124
|
} else {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
125
|
+
trigger.lastIndex = 0;
|
|
126
|
+
|
|
127
|
+
const execResult = trigger.exec(ctx.messageText);
|
|
128
|
+
if (execResult != null) {
|
|
129
|
+
matchResults.push(execResult);
|
|
130
|
+
|
|
131
|
+
if (trigger.global) {
|
|
132
|
+
while (true) {
|
|
133
|
+
const nextResult = trigger.exec(ctx.messageText);
|
|
134
|
+
if (nextResult == null) break;
|
|
135
|
+
matchResults.push(nextResult);
|
|
136
|
+
}
|
|
130
137
|
}
|
|
131
|
-
shouldTrigger = true;
|
|
132
138
|
}
|
|
139
|
+
|
|
140
|
+
shouldTrigger = matchResults.length > 0;
|
|
133
141
|
}
|
|
134
142
|
}
|
|
135
143
|
|
|
@@ -4,7 +4,7 @@ import { ScheduledHandler } from '../../types/handlers';
|
|
|
4
4
|
import { hoursToMilliseconds } from '../../helpers/timeConvertions';
|
|
5
5
|
import { HoursOfDay } from '../../types/timeValues';
|
|
6
6
|
import { IActionState } from '../../types/actionState';
|
|
7
|
-
import { IActionWithState } from '../../types/actionWithState';
|
|
7
|
+
import { IActionWithState, ActionKey } from '../../types/actionWithState';
|
|
8
8
|
import { CachedStateFactory } from '../cachedStateFactory';
|
|
9
9
|
import { ChatContext } from '../context/chatContext';
|
|
10
10
|
import { ActionExecutionResult } from '../actionExecutionResult';
|
|
@@ -20,7 +20,7 @@ export class ScheduledAction<TActionState extends IActionState>
|
|
|
20
20
|
timeinHours: HoursOfDay;
|
|
21
21
|
active: boolean;
|
|
22
22
|
chatsWhitelist: number[];
|
|
23
|
-
key:
|
|
23
|
+
key: ActionKey;
|
|
24
24
|
|
|
25
25
|
cachedState = new Map<string, unknown>();
|
|
26
26
|
stateConstructor: () => TActionState;
|
|
@@ -42,7 +42,7 @@ export class ScheduledAction<TActionState extends IActionState>
|
|
|
42
42
|
this.active = active;
|
|
43
43
|
this.chatsWhitelist = whitelist;
|
|
44
44
|
this.cachedStateFactories = cachedStateFactories;
|
|
45
|
-
this.key = `scheduled:${this.name.replace('.', '-')}
|
|
45
|
+
this.key = `scheduled:${this.name.replace('.', '-')}` as ActionKey;
|
|
46
46
|
this.stateConstructor = stateConstructor;
|
|
47
47
|
}
|
|
48
48
|
|
package/entities/botInstance.ts
CHANGED
|
@@ -35,6 +35,8 @@ export class BotInstance {
|
|
|
35
35
|
this.scheduled = options.scheduled;
|
|
36
36
|
this.chats = options.chats;
|
|
37
37
|
|
|
38
|
+
const actions = [...this.commands, ...this.scheduled];
|
|
39
|
+
|
|
38
40
|
Logger.logWithTraceId(
|
|
39
41
|
this.name,
|
|
40
42
|
`System:Bot-${this.name}-Start`,
|
|
@@ -44,7 +46,7 @@ export class BotInstance {
|
|
|
44
46
|
this.telegraf = new Telegraf(options.token);
|
|
45
47
|
this.storage =
|
|
46
48
|
options.storageClient ??
|
|
47
|
-
new JsonFileStorage(options.name, options.storagePath);
|
|
49
|
+
new JsonFileStorage(options.name, actions, options.storagePath);
|
|
48
50
|
this.api = new TelegramApiService(
|
|
49
51
|
this.name,
|
|
50
52
|
this.telegraf.telegram,
|
|
@@ -55,10 +57,7 @@ export class BotInstance {
|
|
|
55
57
|
this.initializeMessageProcessing();
|
|
56
58
|
this.initializeScheduledProcessing();
|
|
57
59
|
|
|
58
|
-
this.storage.saveMetadata(
|
|
59
|
-
[...this.commands, ...this.scheduled],
|
|
60
|
-
this.name
|
|
61
|
-
);
|
|
60
|
+
this.storage.saveMetadata(actions, this.name);
|
|
62
61
|
|
|
63
62
|
this.telegraf.launch();
|
|
64
63
|
}
|
|
@@ -9,12 +9,13 @@ import {
|
|
|
9
9
|
MessageSendingOptions,
|
|
10
10
|
TextMessageSendingOptions
|
|
11
11
|
} from '../../types/messageSendingOptions';
|
|
12
|
+
import { IActionWithState } from '../../types/actionWithState';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Context of action executed in chat.
|
|
15
16
|
*/
|
|
16
17
|
export class ChatContext<TActionState> {
|
|
17
|
-
protected
|
|
18
|
+
protected action: IActionWithState;
|
|
18
19
|
protected interactions: IBotApiInteractions;
|
|
19
20
|
updateActions: Array<(state: TActionState) => void> = [];
|
|
20
21
|
/** Trace id of a action execution. */
|
|
@@ -30,7 +31,7 @@ export class ChatContext<TActionState> {
|
|
|
30
31
|
|
|
31
32
|
constructor(
|
|
32
33
|
botName: string,
|
|
33
|
-
|
|
34
|
+
action: IActionWithState,
|
|
34
35
|
interactions: IBotApiInteractions,
|
|
35
36
|
chatId: number,
|
|
36
37
|
chatName: string,
|
|
@@ -38,7 +39,7 @@ export class ChatContext<TActionState> {
|
|
|
38
39
|
storage: IStorageClient
|
|
39
40
|
) {
|
|
40
41
|
this.botName = botName;
|
|
41
|
-
this.
|
|
42
|
+
this.action = action;
|
|
42
43
|
this.interactions = interactions;
|
|
43
44
|
this.chatId = chatId;
|
|
44
45
|
this.chatName = chatName;
|
|
@@ -51,9 +52,7 @@ export class ChatContext<TActionState> {
|
|
|
51
52
|
* @param stateUpdateAction Function that will modify state.
|
|
52
53
|
*/
|
|
53
54
|
updateState(stateUpdateAction: (state: TActionState) => void) {
|
|
54
|
-
this.updateActions.push(
|
|
55
|
-
stateUpdateAction as (state: TActionState) => void
|
|
56
|
-
);
|
|
55
|
+
this.updateActions.push(stateUpdateAction);
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
/**
|
|
@@ -68,7 +67,7 @@ export class ChatContext<TActionState> {
|
|
|
68
67
|
this.chatId,
|
|
69
68
|
undefined,
|
|
70
69
|
this.traceId,
|
|
71
|
-
this.
|
|
70
|
+
this.action,
|
|
72
71
|
options
|
|
73
72
|
)
|
|
74
73
|
);
|
|
@@ -87,7 +86,7 @@ export class ChatContext<TActionState> {
|
|
|
87
86
|
this.chatId,
|
|
88
87
|
undefined,
|
|
89
88
|
this.traceId,
|
|
90
|
-
this.
|
|
89
|
+
this.action,
|
|
91
90
|
options
|
|
92
91
|
)
|
|
93
92
|
);
|
|
@@ -106,7 +105,7 @@ export class ChatContext<TActionState> {
|
|
|
106
105
|
this.chatId,
|
|
107
106
|
undefined,
|
|
108
107
|
this.traceId,
|
|
109
|
-
this.
|
|
108
|
+
this.action,
|
|
110
109
|
options
|
|
111
110
|
)
|
|
112
111
|
);
|
|
@@ -118,12 +117,7 @@ export class ChatContext<TActionState> {
|
|
|
118
117
|
*/
|
|
119
118
|
unpinMessage(messageId: number) {
|
|
120
119
|
this.interactions.unpin(
|
|
121
|
-
new UnpinResponse(
|
|
122
|
-
messageId,
|
|
123
|
-
this.chatId,
|
|
124
|
-
this.traceId,
|
|
125
|
-
this.actionKey
|
|
126
|
-
)
|
|
120
|
+
new UnpinResponse(messageId, this.chatId, this.traceId, this.action)
|
|
127
121
|
);
|
|
128
122
|
}
|
|
129
123
|
}
|
|
@@ -9,10 +9,12 @@ import { TextMessage } from '../responses/textMessage';
|
|
|
9
9
|
import { VideoMessage } from '../responses/videoMessage';
|
|
10
10
|
import { ActionStateBase } from '../states/actionStateBase';
|
|
11
11
|
import { ChatContext } from './chatContext';
|
|
12
|
+
import { IncomingMessage } from '../incomingMessage';
|
|
12
13
|
import {
|
|
13
14
|
MessageSendingOptions,
|
|
14
15
|
TextMessageSendingOptions
|
|
15
16
|
} from '../../types/messageSendingOptions';
|
|
17
|
+
import { IActionWithState, ActionKey } from '../../types/actionWithState';
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
20
|
* Context of action executed in chat, in response to a message
|
|
@@ -35,31 +37,27 @@ export class MessageContext<
|
|
|
35
37
|
|
|
36
38
|
constructor(
|
|
37
39
|
botName: string,
|
|
38
|
-
|
|
40
|
+
action: IActionWithState,
|
|
39
41
|
interactions: IBotApiInteractions,
|
|
40
|
-
|
|
41
|
-
chatName: string,
|
|
42
|
-
messageId: number,
|
|
43
|
-
messageText: string,
|
|
44
|
-
fromUserId: number | undefined,
|
|
45
|
-
traceId: number | string,
|
|
46
|
-
fromUserName: string,
|
|
42
|
+
message: IncomingMessage,
|
|
47
43
|
storage: IStorageClient
|
|
48
44
|
) {
|
|
49
45
|
super(
|
|
50
46
|
botName,
|
|
51
|
-
|
|
47
|
+
action,
|
|
52
48
|
interactions,
|
|
53
|
-
|
|
54
|
-
chatName,
|
|
55
|
-
traceId,
|
|
49
|
+
message.chat.id,
|
|
50
|
+
message.chatName,
|
|
51
|
+
message.traceId,
|
|
56
52
|
storage
|
|
57
53
|
);
|
|
58
54
|
|
|
59
|
-
this.messageId =
|
|
60
|
-
this.messageText =
|
|
61
|
-
this.fromUserId =
|
|
62
|
-
this.fromUserName =
|
|
55
|
+
this.messageId = message.message_id;
|
|
56
|
+
this.messageText = message.text ?? '';
|
|
57
|
+
this.fromUserId = message.from?.id;
|
|
58
|
+
this.fromUserName =
|
|
59
|
+
(message.from?.first_name ?? 'Unknown user') +
|
|
60
|
+
(message.from?.last_name ? ` ${message.from.last_name}` : '');
|
|
63
61
|
}
|
|
64
62
|
|
|
65
63
|
/**
|
|
@@ -70,13 +68,18 @@ export class MessageContext<
|
|
|
70
68
|
async loadStateOf<TAnotherActionState extends IActionState>(
|
|
71
69
|
commandName: string
|
|
72
70
|
): Promise<TAnotherActionState> {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
71
|
+
const storageKey = `command:${commandName.replace(
|
|
72
|
+
'.',
|
|
73
|
+
'-'
|
|
74
|
+
)}` as ActionKey;
|
|
75
|
+
const allStates = await this.storage.load(storageKey);
|
|
76
|
+
const stateForChat = allStates[this.chatId];
|
|
77
|
+
|
|
78
|
+
if (!stateForChat) {
|
|
79
|
+
return new ActionStateBase() as TAnotherActionState;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return stateForChat as TAnotherActionState;
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
/**
|
|
@@ -91,7 +94,7 @@ export class MessageContext<
|
|
|
91
94
|
this.chatId,
|
|
92
95
|
this.messageId,
|
|
93
96
|
this.traceId,
|
|
94
|
-
this.
|
|
97
|
+
this.action,
|
|
95
98
|
options
|
|
96
99
|
)
|
|
97
100
|
);
|
|
@@ -110,7 +113,7 @@ export class MessageContext<
|
|
|
110
113
|
this.chatId,
|
|
111
114
|
this.messageId,
|
|
112
115
|
this.traceId,
|
|
113
|
-
this.
|
|
116
|
+
this.action,
|
|
114
117
|
options
|
|
115
118
|
)
|
|
116
119
|
);
|
|
@@ -129,7 +132,7 @@ export class MessageContext<
|
|
|
129
132
|
this.chatId,
|
|
130
133
|
this.messageId,
|
|
131
134
|
this.traceId,
|
|
132
|
-
this.
|
|
135
|
+
this.action,
|
|
133
136
|
options
|
|
134
137
|
)
|
|
135
138
|
);
|
|
@@ -146,7 +149,7 @@ export class MessageContext<
|
|
|
146
149
|
this.chatId,
|
|
147
150
|
this.messageId,
|
|
148
151
|
emoji,
|
|
149
|
-
this.
|
|
152
|
+
this.action
|
|
150
153
|
)
|
|
151
154
|
);
|
|
152
155
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { InputFile } from 'telegraf/types';
|
|
2
2
|
import { BotResponseTypes, IReplyMessage } from '../../types/response';
|
|
3
3
|
import { MessageSendingOptions } from '../../types/messageSendingOptions';
|
|
4
|
+
import { IActionWithState } from '../../types/actionWithState';
|
|
4
5
|
|
|
5
6
|
export class ImageMessage implements IReplyMessage<InputFile> {
|
|
6
7
|
kind = BotResponseTypes.image;
|
|
@@ -11,14 +12,14 @@ export class ImageMessage implements IReplyMessage<InputFile> {
|
|
|
11
12
|
traceId: string | number;
|
|
12
13
|
disableWebPreview = false;
|
|
13
14
|
shouldPin: boolean;
|
|
14
|
-
|
|
15
|
+
action: IActionWithState;
|
|
15
16
|
|
|
16
17
|
constructor(
|
|
17
18
|
image: InputFile,
|
|
18
19
|
chatId: number,
|
|
19
20
|
replyId: number | undefined,
|
|
20
21
|
traceId: number | string,
|
|
21
|
-
|
|
22
|
+
action: IActionWithState,
|
|
22
23
|
options?: MessageSendingOptions
|
|
23
24
|
) {
|
|
24
25
|
this.content = image;
|
|
@@ -26,6 +27,6 @@ export class ImageMessage implements IReplyMessage<InputFile> {
|
|
|
26
27
|
this.replyId = replyId;
|
|
27
28
|
this.traceId = traceId;
|
|
28
29
|
this.shouldPin = options?.pin ?? false;
|
|
29
|
-
this.
|
|
30
|
+
this.action = action;
|
|
30
31
|
}
|
|
31
32
|
}
|