chz-telegram-bot 0.5.4 → 0.6.8
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/README.md +41 -31
- package/dist/builtin/helpAction.d.ts +2 -0
- package/dist/builtin/helpAction.d.ts.map +1 -0
- package/dist/builtin/helpAction.js +14 -0
- package/dist/dtos/chatHistoryMessage.d.ts +35 -0
- package/dist/dtos/chatHistoryMessage.d.ts.map +1 -0
- package/dist/dtos/chatHistoryMessage.js +32 -0
- package/dist/dtos/chatInfo.d.ts +17 -0
- package/dist/dtos/chatInfo.d.ts.map +1 -0
- package/dist/dtos/chatInfo.js +16 -0
- package/dist/dtos/commandTriggerCheckResult.d.ts +24 -0
- package/dist/dtos/commandTriggerCheckResult.d.ts.map +1 -0
- package/dist/dtos/commandTriggerCheckResult.js +34 -0
- package/dist/dtos/cooldownInfo.d.ts +13 -0
- package/dist/dtos/cooldownInfo.d.ts.map +1 -0
- package/dist/dtos/cooldownInfo.js +12 -0
- package/dist/dtos/incomingMessage.d.ts +19 -0
- package/dist/dtos/incomingMessage.d.ts.map +1 -0
- package/dist/dtos/incomingMessage.js +63 -0
- package/dist/dtos/incomingQuery.d.ts +10 -0
- package/dist/dtos/incomingQuery.d.ts.map +1 -0
- package/dist/dtos/incomingQuery.js +14 -0
- package/dist/dtos/messageInfo.d.ts +22 -0
- package/dist/dtos/messageInfo.d.ts.map +1 -0
- package/dist/dtos/messageInfo.js +20 -0
- package/dist/dtos/propertyProviderSets.d.ts +16 -0
- package/dist/dtos/propertyProviderSets.d.ts.map +1 -0
- package/dist/dtos/propertyProviderSets.js +1 -0
- package/dist/dtos/replyInfo.d.ts +6 -0
- package/dist/dtos/replyInfo.d.ts.map +1 -0
- package/dist/dtos/replyInfo.js +8 -0
- package/dist/dtos/responses/delay.d.ts +16 -0
- package/dist/dtos/responses/delay.d.ts.map +1 -0
- package/dist/dtos/responses/delay.js +15 -0
- package/dist/dtos/responses/imageMessage.d.ts +22 -0
- package/dist/dtos/responses/imageMessage.d.ts.map +1 -0
- package/dist/dtos/responses/imageMessage.js +21 -0
- package/dist/dtos/responses/inlineQueryResponse.d.ts +13 -0
- package/dist/dtos/responses/inlineQueryResponse.d.ts.map +1 -0
- package/dist/dtos/responses/inlineQueryResponse.js +15 -0
- package/dist/dtos/responses/reaction.d.ts +16 -0
- package/dist/dtos/responses/reaction.d.ts.map +1 -0
- package/dist/dtos/responses/reaction.js +17 -0
- package/dist/dtos/responses/textMessage.d.ts +23 -0
- package/dist/dtos/responses/textMessage.d.ts.map +1 -0
- package/dist/dtos/responses/textMessage.js +24 -0
- package/dist/dtos/responses/unpin.d.ts +15 -0
- package/dist/dtos/responses/unpin.d.ts.map +1 -0
- package/dist/dtos/responses/unpin.js +15 -0
- package/dist/dtos/responses/videoMessage.d.ts +22 -0
- package/dist/dtos/responses/videoMessage.d.ts.map +1 -0
- package/dist/dtos/responses/videoMessage.js +21 -0
- package/dist/dtos/userInfo.d.ts +12 -0
- package/dist/dtos/userInfo.d.ts.map +1 -0
- package/dist/dtos/userInfo.js +12 -0
- package/dist/entities/actions/commandAction.d.ts +31 -0
- package/dist/entities/actions/commandAction.d.ts.map +1 -0
- package/dist/entities/actions/commandAction.js +149 -0
- package/dist/entities/actions/inlineQueryAction.d.ts +14 -0
- package/dist/entities/actions/inlineQueryAction.d.ts.map +1 -0
- package/dist/entities/actions/inlineQueryAction.js +51 -0
- package/dist/entities/actions/replyCaptureAction.d.ts +15 -0
- package/dist/entities/actions/replyCaptureAction.d.ts.map +1 -0
- package/dist/entities/actions/replyCaptureAction.js +66 -0
- package/dist/entities/actions/scheduledAction.d.ts +24 -0
- package/dist/entities/actions/scheduledAction.d.ts.map +1 -0
- package/dist/entities/actions/scheduledAction.js +92 -0
- package/dist/entities/botInstance.d.ts +36 -0
- package/dist/entities/botInstance.d.ts.map +1 -0
- package/dist/entities/botInstance.js +39 -0
- package/dist/entities/cachedStateFactory.d.ts +7 -0
- package/dist/entities/cachedStateFactory.d.ts.map +1 -0
- package/dist/entities/cachedStateFactory.js +8 -0
- package/dist/entities/context/baseContext.d.ts +39 -0
- package/dist/entities/context/baseContext.d.ts.map +1 -0
- package/dist/entities/context/baseContext.js +56 -0
- package/dist/entities/context/chatContext.d.ts +50 -0
- package/dist/entities/context/chatContext.d.ts.map +1 -0
- package/dist/entities/context/chatContext.js +65 -0
- package/dist/entities/context/inlineQueryContext.d.ts +27 -0
- package/dist/entities/context/inlineQueryContext.d.ts.map +1 -0
- package/dist/entities/context/inlineQueryContext.js +29 -0
- package/dist/entities/context/messageContext.d.ts +92 -0
- package/dist/entities/context/messageContext.d.ts.map +1 -0
- package/dist/entities/context/messageContext.js +116 -0
- package/dist/entities/context/replyContext.d.ts +89 -0
- package/dist/entities/context/replyContext.d.ts.map +1 -0
- package/dist/entities/context/replyContext.js +124 -0
- package/dist/entities/states/actionStateBase.d.ts +6 -0
- package/dist/entities/states/actionStateBase.d.ts.map +1 -0
- package/dist/entities/states/actionStateBase.js +4 -0
- package/dist/entities/taskRecord.d.ts +8 -0
- package/dist/entities/taskRecord.d.ts.map +1 -0
- package/dist/entities/taskRecord.js +10 -0
- 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.d.ts +100 -0
- package/dist/helpers/builders/commandActionBuilder.d.ts.map +1 -0
- package/dist/helpers/builders/commandActionBuilder.js +146 -0
- package/dist/helpers/builders/inlineQueryActionBuilder.d.ts +37 -0
- package/dist/helpers/builders/inlineQueryActionBuilder.d.ts.map +1 -0
- package/dist/helpers/builders/inlineQueryActionBuilder.js +50 -0
- package/dist/helpers/builders/scheduledActionBuilder.d.ts +68 -0
- package/dist/helpers/builders/scheduledActionBuilder.d.ts.map +1 -0
- package/dist/helpers/builders/scheduledActionBuilder.js +95 -0
- package/dist/helpers/mapUtils.d.ts +10 -0
- package/dist/helpers/mapUtils.d.ts.map +1 -0
- package/dist/helpers/mapUtils.js +13 -0
- package/dist/helpers/noop.d.ts +9 -0
- package/dist/helpers/noop.d.ts.map +1 -0
- package/dist/helpers/noop.js +17 -0
- package/dist/helpers/objectFromEntries.d.ts +2 -0
- package/dist/helpers/objectFromEntries.d.ts.map +1 -0
- package/dist/helpers/objectFromEntries.js +3 -0
- package/dist/helpers/timeConvertions.d.ts +5 -0
- package/dist/helpers/timeConvertions.d.ts.map +1 -0
- package/dist/helpers/timeConvertions.js +9 -0
- package/dist/helpers/toArray.d.ts +2 -0
- package/dist/helpers/toArray.d.ts.map +1 -0
- package/dist/helpers/toArray.js +3 -0
- package/dist/helpers/traceFactory.d.ts +3 -0
- package/dist/helpers/traceFactory.d.ts.map +1 -0
- package/dist/helpers/traceFactory.js +3 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/main.d.ts +49 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +33 -0
- package/dist/services/actionProcessingService.d.ts +25 -0
- package/dist/services/actionProcessingService.d.ts.map +1 -0
- package/dist/services/actionProcessingService.js +50 -0
- package/dist/services/actionProcessors/baseProcessor.d.ts +18 -0
- package/dist/services/actionProcessors/baseProcessor.d.ts.map +1 -0
- package/dist/services/actionProcessors/baseProcessor.js +33 -0
- package/dist/services/actionProcessors/commandActionProcessor.d.ts +19 -0
- package/dist/services/actionProcessors/commandActionProcessor.d.ts.map +1 -0
- package/dist/services/actionProcessors/commandActionProcessor.js +130 -0
- package/dist/services/actionProcessors/inlineQueryActionProcessor.d.ts +11 -0
- package/dist/services/actionProcessors/inlineQueryActionProcessor.d.ts.map +1 -0
- package/dist/services/actionProcessors/inlineQueryActionProcessor.js +69 -0
- package/dist/services/actionProcessors/scheduledActionProcessor.d.ts +17 -0
- package/dist/services/actionProcessors/scheduledActionProcessor.d.ts.map +1 -0
- package/dist/services/actionProcessors/scheduledActionProcessor.js +55 -0
- package/dist/services/jsonFileStorage.d.ts +25 -0
- package/dist/services/jsonFileStorage.d.ts.map +1 -0
- package/dist/services/jsonFileStorage.js +133 -0
- package/dist/services/nodeTimeoutScheduler.d.ts +13 -0
- package/dist/services/nodeTimeoutScheduler.d.ts.map +1 -0
- package/dist/services/nodeTimeoutScheduler.js +50 -0
- package/dist/services/responseProcessingQueue.d.ts +12 -0
- package/dist/services/responseProcessingQueue.d.ts.map +1 -0
- package/dist/services/responseProcessingQueue.js +37 -0
- package/dist/services/telegramApi.d.ts +23 -0
- package/dist/services/telegramApi.d.ts.map +1 -0
- package/dist/services/telegramApi.js +163 -0
- package/dist/types/action.d.ts +14 -0
- package/dist/types/action.d.ts.map +1 -0
- package/dist/types/action.js +1 -0
- package/dist/types/actionState.d.ts +5 -0
- package/dist/types/actionState.d.ts.map +1 -0
- package/dist/types/actionState.js +1 -0
- package/dist/types/cachedValueAccessor.d.ts +2 -0
- package/dist/types/cachedValueAccessor.d.ts.map +1 -0
- package/dist/types/cachedValueAccessor.js +1 -0
- package/dist/types/capture.d.ts +24 -0
- package/dist/types/capture.d.ts.map +1 -0
- package/dist/types/capture.js +1 -0
- package/dist/types/commandCondition.d.ts +8 -0
- package/dist/types/commandCondition.d.ts.map +1 -0
- package/dist/types/commandCondition.js +1 -0
- package/dist/types/commandTrigger.d.ts +2 -0
- package/dist/types/commandTrigger.d.ts.map +1 -0
- package/dist/types/commandTrigger.js +1 -0
- package/dist/types/events.d.ts +193 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +69 -0
- package/dist/types/externalAliases.d.ts +11 -0
- package/dist/types/externalAliases.d.ts.map +1 -0
- package/dist/types/externalAliases.js +1 -0
- package/dist/types/handlers.d.ts +21 -0
- package/dist/types/handlers.d.ts.map +1 -0
- package/dist/types/handlers.js +1 -0
- package/dist/types/inputFile.d.ts +5 -0
- package/dist/types/inputFile.d.ts.map +1 -0
- package/dist/types/inputFile.js +1 -0
- package/dist/types/logger.d.ts +1 -0
- package/dist/types/logger.d.ts.map +1 -0
- package/dist/types/logger.js +1 -0
- package/dist/types/messageSendingOptions.d.ts +9 -0
- package/dist/types/messageSendingOptions.d.ts.map +1 -0
- package/dist/types/messageSendingOptions.js +1 -0
- package/dist/types/messageTypes.d.ts +20 -0
- package/dist/types/messageTypes.d.ts.map +1 -0
- package/dist/types/messageTypes.js +18 -0
- package/dist/types/propertyProvider.d.ts +8 -0
- package/dist/types/propertyProvider.d.ts.map +1 -0
- package/dist/types/propertyProvider.js +1 -0
- package/dist/types/response.d.ts +39 -0
- package/dist/types/response.d.ts.map +1 -0
- package/dist/types/response.js +9 -0
- package/dist/types/scheduler.d.ts +7 -0
- package/dist/types/scheduler.d.ts.map +1 -0
- package/dist/types/scheduler.js +1 -0
- package/dist/types/storage.d.ts +11 -0
- package/dist/types/storage.d.ts.map +1 -0
- package/dist/types/storage.js +1 -0
- package/dist/types/timeValues.d.ts +15 -0
- package/dist/types/timeValues.d.ts.map +1 -0
- package/dist/types/timeValues.js +1 -0
- package/dist/types/trace.d.ts +6 -0
- package/dist/types/trace.d.ts.map +1 -0
- package/dist/types/trace.js +1 -0
- package/entities/actions/commandAction.ts +11 -3
- package/entities/actions/inlineQueryAction.ts +9 -1
- package/entities/actions/replyCaptureAction.ts +9 -3
- package/entities/actions/scheduledAction.ts +31 -10
- package/entities/botInstance.ts +18 -25
- package/entities/context/baseContext.ts +9 -4
- package/index.ts +1 -1
- package/main.ts +1 -10
- package/package.json +38 -38
- package/services/actionProcessingService.ts +11 -15
- package/services/actionProcessors/baseProcessor.ts +9 -9
- package/services/actionProcessors/commandActionProcessor.ts +35 -46
- package/services/actionProcessors/inlineQueryActionProcessor.ts +24 -20
- package/services/actionProcessors/scheduledActionProcessor.ts +5 -10
- package/services/jsonFileStorage.ts +27 -1
- package/services/nodeTimeoutScheduler.ts +22 -22
- package/services/telegramApi.ts +53 -23
- package/types/events.ts +285 -0
- package/services/jsonLogger.ts +0 -112
- package/types/logger.ts +0 -39
|
@@ -6,7 +6,6 @@ import { ReplyContextInternal } from '../../entities/context/replyContext';
|
|
|
6
6
|
import { IActionState } from '../../types/actionState';
|
|
7
7
|
import { TelegramApiService } from '../telegramApi';
|
|
8
8
|
import { IReplyCapture } from '../../types/capture';
|
|
9
|
-
import { TraceId } from '../../types/trace';
|
|
10
9
|
import { ChatInfo } from '../../dtos/chatInfo';
|
|
11
10
|
import {
|
|
12
11
|
INTERNAL_MESSAGE_TYPE_PREFIX,
|
|
@@ -19,6 +18,7 @@ import { MessageInfo } from '../../dtos/messageInfo';
|
|
|
19
18
|
import { UserInfo } from '../../dtos/userInfo';
|
|
20
19
|
import { ChatHistoryMessage } from '../../dtos/chatHistoryMessage';
|
|
21
20
|
import { BotInfo, TelegramBot } from '../../types/externalAliases';
|
|
21
|
+
import { BotEventType } from '../../types/events';
|
|
22
22
|
|
|
23
23
|
const MESSAGE_HISTORY_LENGTH_LIMIT = 100;
|
|
24
24
|
|
|
@@ -38,7 +38,6 @@ export class CommandActionProcessor extends BaseActionProcessor {
|
|
|
38
38
|
api: TelegramApiService,
|
|
39
39
|
telegram: TelegramBot,
|
|
40
40
|
commands: CommandAction<IActionState>[],
|
|
41
|
-
verboseLoggingForIncomingMessage: boolean,
|
|
42
41
|
botInfo: BotInfo
|
|
43
42
|
) {
|
|
44
43
|
this.botInfo = botInfo;
|
|
@@ -69,30 +68,24 @@ export class CommandActionProcessor extends BaseActionProcessor {
|
|
|
69
68
|
}
|
|
70
69
|
|
|
71
70
|
if (commands.length > 0) {
|
|
72
|
-
telegram.on('message', ({ message }) => {
|
|
71
|
+
telegram.on('message', async ({ message }) => {
|
|
73
72
|
const internalMessage = new IncomingMessage(
|
|
74
73
|
message,
|
|
75
74
|
this.botName,
|
|
76
75
|
getOrSetIfNotExists(this.chatHistory, message.chat.id, [])
|
|
77
76
|
);
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
this.
|
|
81
|
-
internalMessage
|
|
82
|
-
|
|
83
|
-
);
|
|
78
|
+
this.eventEmitter.emit(BotEventType.messageRecieved, {
|
|
79
|
+
botInfo: this.botInfo,
|
|
80
|
+
message: internalMessage
|
|
81
|
+
});
|
|
84
82
|
|
|
85
|
-
|
|
86
|
-
logger.logObjectWithTraceId(message);
|
|
87
|
-
} else {
|
|
88
|
-
logger.logWithTraceId(
|
|
89
|
-
`${internalMessage.from?.first_name ?? 'Unknown'} (${
|
|
90
|
-
internalMessage.from?.id ?? 'Unknown'
|
|
91
|
-
}): ${internalMessage.text || internalMessage.type}`
|
|
92
|
-
);
|
|
93
|
-
}
|
|
83
|
+
await this.processMessage(internalMessage);
|
|
94
84
|
|
|
95
|
-
|
|
85
|
+
this.eventEmitter.emit(BotEventType.messageProcessingFinished, {
|
|
86
|
+
botInfo: this.botInfo,
|
|
87
|
+
message: internalMessage
|
|
88
|
+
});
|
|
96
89
|
});
|
|
97
90
|
}
|
|
98
91
|
}
|
|
@@ -100,8 +93,7 @@ export class CommandActionProcessor extends BaseActionProcessor {
|
|
|
100
93
|
captureRegistrationCallback(
|
|
101
94
|
capture: IReplyCapture,
|
|
102
95
|
parentMessageId: number,
|
|
103
|
-
chatInfo: ChatInfo
|
|
104
|
-
traceId: TraceId
|
|
96
|
+
chatInfo: ChatInfo
|
|
105
97
|
) {
|
|
106
98
|
const replyAction = new ReplyCaptureAction(
|
|
107
99
|
parentMessageId,
|
|
@@ -111,15 +103,10 @@ export class CommandActionProcessor extends BaseActionProcessor {
|
|
|
111
103
|
capture.abortController
|
|
112
104
|
);
|
|
113
105
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
logger.logWithTraceId(
|
|
121
|
-
`Starting capturing replies to message ${parentMessageId} with action ${replyAction.key}`
|
|
122
|
-
);
|
|
106
|
+
this.eventEmitter.emit(BotEventType.commandActionCaptureStarted, {
|
|
107
|
+
parentMessageId,
|
|
108
|
+
chatInfo
|
|
109
|
+
});
|
|
123
110
|
|
|
124
111
|
this.replyCaptures.push(replyAction);
|
|
125
112
|
|
|
@@ -127,13 +114,19 @@ export class CommandActionProcessor extends BaseActionProcessor {
|
|
|
127
114
|
const index = this.replyCaptures.indexOf(replyAction);
|
|
128
115
|
this.replyCaptures.splice(index, 1);
|
|
129
116
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
117
|
+
this.eventEmitter.emit(BotEventType.commandActionCaptureAborted, {
|
|
118
|
+
parentMessageId,
|
|
119
|
+
chatInfo
|
|
120
|
+
});
|
|
133
121
|
});
|
|
134
122
|
}
|
|
135
123
|
|
|
136
124
|
private async processMessage(msg: IncomingMessage) {
|
|
125
|
+
this.eventEmitter.emit(BotEventType.messageProcessingStarted, {
|
|
126
|
+
botInfo: this.botInfo,
|
|
127
|
+
message: msg
|
|
128
|
+
});
|
|
129
|
+
|
|
137
130
|
const chatHistoryArray = getOrSetIfNotExists(
|
|
138
131
|
this.chatHistory,
|
|
139
132
|
msg.chatInfo.id,
|
|
@@ -142,6 +135,7 @@ export class CommandActionProcessor extends BaseActionProcessor {
|
|
|
142
135
|
|
|
143
136
|
while (chatHistoryArray.length > MESSAGE_HISTORY_LENGTH_LIMIT)
|
|
144
137
|
chatHistoryArray.shift();
|
|
138
|
+
|
|
145
139
|
chatHistoryArray.push(
|
|
146
140
|
new ChatHistoryMessage(
|
|
147
141
|
msg.messageId,
|
|
@@ -156,7 +150,8 @@ export class CommandActionProcessor extends BaseActionProcessor {
|
|
|
156
150
|
|
|
157
151
|
const ctx = new MessageContextInternal<IActionState>(
|
|
158
152
|
this.storage,
|
|
159
|
-
this.scheduler
|
|
153
|
+
this.scheduler,
|
|
154
|
+
this.eventEmitter
|
|
160
155
|
);
|
|
161
156
|
|
|
162
157
|
const commandsToCheck = new Set(this.commands[msg.type]);
|
|
@@ -166,6 +161,11 @@ export class CommandActionProcessor extends BaseActionProcessor {
|
|
|
166
161
|
}
|
|
167
162
|
}
|
|
168
163
|
|
|
164
|
+
this.eventEmitter.emit(BotEventType.beforeActionsExecuting, {
|
|
165
|
+
botInfo: this.botInfo,
|
|
166
|
+
message: msg,
|
|
167
|
+
commands: commandsToCheck
|
|
168
|
+
});
|
|
169
169
|
for (const commandAction of commandsToCheck) {
|
|
170
170
|
this.initializeMessageContext(ctx, commandAction, msg);
|
|
171
171
|
await this.executeAction(commandAction, ctx);
|
|
@@ -174,7 +174,8 @@ export class CommandActionProcessor extends BaseActionProcessor {
|
|
|
174
174
|
if (this.replyCaptures.length != 0) {
|
|
175
175
|
const replyCtx = new ReplyContextInternal<IActionState>(
|
|
176
176
|
this.storage,
|
|
177
|
-
this.scheduler
|
|
177
|
+
this.scheduler,
|
|
178
|
+
this.eventEmitter
|
|
178
179
|
);
|
|
179
180
|
|
|
180
181
|
for (const replyAction of this.replyCaptures) {
|
|
@@ -211,12 +212,6 @@ export class CommandActionProcessor extends BaseActionProcessor {
|
|
|
211
212
|
|
|
212
213
|
ctx.isInitialized = true;
|
|
213
214
|
ctx.matchResults = [];
|
|
214
|
-
|
|
215
|
-
ctx.logger = this.logger.createScope(
|
|
216
|
-
this.botName,
|
|
217
|
-
message.traceId,
|
|
218
|
-
message.chatInfo.name
|
|
219
|
-
);
|
|
220
215
|
}
|
|
221
216
|
|
|
222
217
|
private initializeMessageContext(
|
|
@@ -247,11 +242,5 @@ export class CommandActionProcessor extends BaseActionProcessor {
|
|
|
247
242
|
ctx.traceId = message.traceId;
|
|
248
243
|
ctx.botInfo = this.botInfo;
|
|
249
244
|
ctx.customCooldown = undefined;
|
|
250
|
-
|
|
251
|
-
ctx.logger = this.logger.createScope(
|
|
252
|
-
this.botName,
|
|
253
|
-
message.traceId,
|
|
254
|
-
message.chatInfo.name
|
|
255
|
-
);
|
|
256
245
|
}
|
|
257
246
|
}
|
|
@@ -2,6 +2,7 @@ import { IncomingInlineQuery } from '../../dtos/incomingQuery';
|
|
|
2
2
|
import { InlineQueryAction } from '../../entities/actions/inlineQueryAction';
|
|
3
3
|
import { InlineQueryContextInternal } from '../../entities/context/inlineQueryContext';
|
|
4
4
|
import { createTrace } from '../../helpers/traceFactory';
|
|
5
|
+
import { BotEventType } from '../../types/events';
|
|
5
6
|
import { TelegramBot } from '../../types/externalAliases';
|
|
6
7
|
import { Milliseconds } from '../../types/timeValues';
|
|
7
8
|
import { TraceId } from '../../types/trace';
|
|
@@ -33,24 +34,20 @@ export class InlineQueryActionProcessor extends BaseActionProcessor {
|
|
|
33
34
|
createTrace('InlineQuery', this.botName, inlineQuery.id)
|
|
34
35
|
);
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
'Query'
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
logger.logWithTraceId(
|
|
43
|
-
`${inlineQuery.from.username ?? 'Unknown'} (${
|
|
44
|
-
inlineQuery.from.id
|
|
45
|
-
}): Query for ${inlineQuery.query}`
|
|
46
|
-
);
|
|
37
|
+
this.eventEmitter.emit(BotEventType.inlineProcessingStarted, {
|
|
38
|
+
query
|
|
39
|
+
});
|
|
47
40
|
|
|
48
41
|
const queryBeingProcessed = queriesInProcessing.get(
|
|
49
42
|
query.userId
|
|
50
43
|
);
|
|
51
44
|
if (queryBeingProcessed) {
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
this.eventEmitter.emit(
|
|
46
|
+
BotEventType.inlineProcessingAborting,
|
|
47
|
+
{
|
|
48
|
+
newQuery: query,
|
|
49
|
+
abortedQuery: queryBeingProcessed
|
|
50
|
+
}
|
|
54
51
|
);
|
|
55
52
|
|
|
56
53
|
queryBeingProcessed.abortController.abort();
|
|
@@ -69,7 +66,8 @@ export class InlineQueryActionProcessor extends BaseActionProcessor {
|
|
|
69
66
|
async () => {
|
|
70
67
|
const ctx = new InlineQueryContextInternal(
|
|
71
68
|
this.storage,
|
|
72
|
-
this.scheduler
|
|
69
|
+
this.scheduler,
|
|
70
|
+
this.eventEmitter
|
|
73
71
|
);
|
|
74
72
|
|
|
75
73
|
const queriesToProcess = [...pendingInlineQueries];
|
|
@@ -94,13 +92,21 @@ export class InlineQueryActionProcessor extends BaseActionProcessor {
|
|
|
94
92
|
await this.executeAction(
|
|
95
93
|
inlineQueryAction,
|
|
96
94
|
ctx,
|
|
97
|
-
(error,
|
|
95
|
+
(error, _) => {
|
|
98
96
|
if (error.name == 'AbortError') {
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
this.eventEmitter.emit(
|
|
98
|
+
BotEventType.inlineProcessingAborted,
|
|
99
|
+
{
|
|
100
|
+
abortedQuery: inlineQuery
|
|
101
|
+
}
|
|
101
102
|
);
|
|
102
103
|
} else {
|
|
103
|
-
|
|
104
|
+
this.eventEmitter.emit(
|
|
105
|
+
BotEventType.error,
|
|
106
|
+
{
|
|
107
|
+
error
|
|
108
|
+
}
|
|
109
|
+
);
|
|
104
110
|
}
|
|
105
111
|
}
|
|
106
112
|
);
|
|
@@ -136,7 +142,5 @@ export class InlineQueryActionProcessor extends BaseActionProcessor {
|
|
|
136
142
|
ctx.isInitialized = true;
|
|
137
143
|
ctx.queryResults = [];
|
|
138
144
|
ctx.matchResults = [];
|
|
139
|
-
|
|
140
|
-
ctx.logger = this.logger.createScope(this.botName, traceId, 'Unknown');
|
|
141
145
|
}
|
|
142
146
|
}
|
|
@@ -5,13 +5,13 @@ import { ChatContextInternal } from '../../entities/context/chatContext';
|
|
|
5
5
|
import { secondsToMilliseconds } from '../../helpers/timeConvertions';
|
|
6
6
|
import { createTrace } from '../../helpers/traceFactory';
|
|
7
7
|
import { IActionState } from '../../types/actionState';
|
|
8
|
-
import { ILogger } from '../../types/logger';
|
|
9
8
|
import { IScheduler } from '../../types/scheduler';
|
|
10
9
|
import { IStorageClient } from '../../types/storage';
|
|
11
10
|
import { Seconds, Milliseconds } from '../../types/timeValues';
|
|
12
11
|
import { TraceId } from '../../types/trace';
|
|
13
12
|
import { TelegramApiService } from '../telegramApi';
|
|
14
13
|
import { BaseActionProcessor } from './baseProcessor';
|
|
14
|
+
import { TypedEventEmitter } from '../../types/events';
|
|
15
15
|
|
|
16
16
|
export class ScheduledActionProcessor extends BaseActionProcessor {
|
|
17
17
|
private readonly chats: Record<string, number>;
|
|
@@ -23,9 +23,9 @@ export class ScheduledActionProcessor extends BaseActionProcessor {
|
|
|
23
23
|
chats: Record<string, number>,
|
|
24
24
|
storage: IStorageClient,
|
|
25
25
|
scheduler: IScheduler,
|
|
26
|
-
|
|
26
|
+
eventEmitter: TypedEventEmitter
|
|
27
27
|
) {
|
|
28
|
-
super(botName, storage, scheduler,
|
|
28
|
+
super(botName, storage, scheduler, eventEmitter);
|
|
29
29
|
this.chats = chats;
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -83,7 +83,8 @@ export class ScheduledActionProcessor extends BaseActionProcessor {
|
|
|
83
83
|
private async runScheduled() {
|
|
84
84
|
const ctx = new ChatContextInternal<IActionState>(
|
|
85
85
|
this.storage,
|
|
86
|
-
this.scheduler
|
|
86
|
+
this.scheduler,
|
|
87
|
+
this.eventEmitter
|
|
87
88
|
);
|
|
88
89
|
|
|
89
90
|
for (const [chatName, chatId] of Object.entries(this.chats)) {
|
|
@@ -118,11 +119,5 @@ export class ScheduledActionProcessor extends BaseActionProcessor {
|
|
|
118
119
|
ctx.action = action;
|
|
119
120
|
ctx.chatInfo = chatInfo;
|
|
120
121
|
ctx.traceId = traceId;
|
|
121
|
-
|
|
122
|
-
ctx.logger = this.logger.createScope(
|
|
123
|
-
this.botName,
|
|
124
|
-
traceId,
|
|
125
|
-
chatInfo.name
|
|
126
|
-
);
|
|
127
122
|
}
|
|
128
123
|
}
|
|
@@ -5,12 +5,14 @@ import { IStorageClient } from '../types/storage';
|
|
|
5
5
|
import { IActionState } from '../types/actionState';
|
|
6
6
|
import { IActionWithState, ActionKey } from '../types/action';
|
|
7
7
|
import { getOrSetIfNotExists } from '../helpers/mapUtils';
|
|
8
|
+
import { BotEventType, TypedEventEmitter } from '../types/events';
|
|
8
9
|
|
|
9
10
|
function buildPath(storagePath: string, botName: string, actionKey: string) {
|
|
10
11
|
return `${storagePath}/${botName}/${actionKey.replaceAll(':', '/')}.json`;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export class JsonFileStorage implements IStorageClient {
|
|
15
|
+
private readonly eventEmitter: TypedEventEmitter;
|
|
14
16
|
private readonly filePaths = new Map<ActionKey, string>();
|
|
15
17
|
private readonly locks = new Map<ActionKey, Semaphore>();
|
|
16
18
|
private readonly cache: Map<string, Record<number, IActionState>>;
|
|
@@ -20,8 +22,10 @@ export class JsonFileStorage implements IStorageClient {
|
|
|
20
22
|
constructor(
|
|
21
23
|
botName: string,
|
|
22
24
|
actions: IActionWithState<IActionState>[],
|
|
25
|
+
eventEmitter: TypedEventEmitter,
|
|
23
26
|
path?: string
|
|
24
27
|
) {
|
|
28
|
+
this.eventEmitter = eventEmitter;
|
|
25
29
|
this.cache = new Map<string, Record<number, IActionState>>();
|
|
26
30
|
this.botName = botName;
|
|
27
31
|
this.storagePath = path ?? 'storage';
|
|
@@ -57,12 +61,15 @@ export class JsonFileStorage implements IStorageClient {
|
|
|
57
61
|
private async lock<TType>(key: ActionKey, action: () => Promise<TType>) {
|
|
58
62
|
const lock = getOrSetIfNotExists(this.locks, key, new Semaphore(1));
|
|
59
63
|
|
|
64
|
+
this.eventEmitter.emit(BotEventType.storageLockAcquiring, key);
|
|
60
65
|
await lock.acquire();
|
|
66
|
+
this.eventEmitter.emit(BotEventType.storageLockAcquired, key);
|
|
61
67
|
|
|
62
68
|
try {
|
|
63
69
|
return await action();
|
|
64
70
|
} finally {
|
|
65
71
|
lock.release();
|
|
72
|
+
this.eventEmitter.emit(BotEventType.storageLockReleased, key);
|
|
66
73
|
}
|
|
67
74
|
}
|
|
68
75
|
|
|
@@ -103,6 +110,10 @@ export class JsonFileStorage implements IStorageClient {
|
|
|
103
110
|
data: Record<number, TActionState>,
|
|
104
111
|
key: ActionKey
|
|
105
112
|
) {
|
|
113
|
+
this.eventEmitter.emit(BotEventType.storageStateSaving, {
|
|
114
|
+
data,
|
|
115
|
+
key
|
|
116
|
+
});
|
|
106
117
|
this.cache.set(key, data);
|
|
107
118
|
|
|
108
119
|
const targetPath = getOrSetIfNotExists(
|
|
@@ -112,6 +123,10 @@ export class JsonFileStorage implements IStorageClient {
|
|
|
112
123
|
);
|
|
113
124
|
|
|
114
125
|
await writeFile(targetPath, JSON.stringify(data), { flag: 'w+' });
|
|
126
|
+
this.eventEmitter.emit(BotEventType.storageStateSaved, {
|
|
127
|
+
data,
|
|
128
|
+
key
|
|
129
|
+
});
|
|
115
130
|
}
|
|
116
131
|
|
|
117
132
|
async load<TActionState extends IActionState>(key: ActionKey) {
|
|
@@ -135,13 +150,24 @@ export class JsonFileStorage implements IStorageClient {
|
|
|
135
150
|
action: IActionWithState<TActionState>,
|
|
136
151
|
chatId: number
|
|
137
152
|
) {
|
|
153
|
+
this.eventEmitter.emit(BotEventType.storageStateLoading, {
|
|
154
|
+
action,
|
|
155
|
+
chatId
|
|
156
|
+
});
|
|
138
157
|
const value =
|
|
139
158
|
this.tryGetFromCache<TActionState>(action.key) ??
|
|
140
159
|
(await this.lock(action.key, async () => {
|
|
141
160
|
return await this.loadFromFile<TActionState>(action.key);
|
|
142
161
|
}));
|
|
143
162
|
|
|
144
|
-
|
|
163
|
+
const result = Object.assign(action.stateConstructor(), value[chatId]);
|
|
164
|
+
|
|
165
|
+
this.eventEmitter.emit(BotEventType.storageStateLoaded, {
|
|
166
|
+
action,
|
|
167
|
+
chatId,
|
|
168
|
+
state: result
|
|
169
|
+
});
|
|
170
|
+
return result;
|
|
145
171
|
}
|
|
146
172
|
|
|
147
173
|
async saveActionExecutionResult<TActionState extends IActionState>(
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import { TaskRecord } from '../entities/taskRecord';
|
|
2
|
-
import {
|
|
3
|
-
import { ILogger } from '../types/logger';
|
|
2
|
+
import { BotEventType, TypedEventEmitter } from '../types/events';
|
|
4
3
|
import { IScheduler } from '../types/scheduler';
|
|
5
4
|
import { Milliseconds } from '../types/timeValues';
|
|
6
5
|
|
|
7
6
|
export class NodeTimeoutScheduler implements IScheduler {
|
|
8
|
-
private readonly logger!: ILogger;
|
|
9
7
|
readonly activeTasks: TaskRecord[] = [];
|
|
10
8
|
|
|
11
|
-
constructor(
|
|
12
|
-
this.logger = logger;
|
|
13
|
-
}
|
|
9
|
+
constructor(readonly eventEmitter: TypedEventEmitter) {}
|
|
14
10
|
|
|
15
11
|
stopAll() {
|
|
16
12
|
for (const task of this.activeTasks) {
|
|
@@ -25,19 +21,25 @@ export class NodeTimeoutScheduler implements IScheduler {
|
|
|
25
21
|
executeRightAway: boolean,
|
|
26
22
|
ownerName: string
|
|
27
23
|
) {
|
|
28
|
-
const taskId = setInterval(
|
|
24
|
+
const taskId = setInterval(() => {
|
|
25
|
+
action();
|
|
26
|
+
this.eventEmitter.emit(BotEventType.taskRun, {
|
|
27
|
+
name,
|
|
28
|
+
ownerName,
|
|
29
|
+
interval
|
|
30
|
+
});
|
|
31
|
+
}, interval);
|
|
29
32
|
const task = new TaskRecord(name, taskId, interval);
|
|
30
33
|
|
|
31
34
|
if (executeRightAway) {
|
|
32
35
|
setImmediate(action);
|
|
33
36
|
}
|
|
34
37
|
|
|
35
|
-
this.
|
|
38
|
+
this.eventEmitter.emit(BotEventType.taskCreated, {
|
|
39
|
+
name,
|
|
36
40
|
ownerName,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
`Created task ${name}, that will run every ${interval}ms.`
|
|
40
|
-
);
|
|
41
|
+
interval
|
|
42
|
+
});
|
|
41
43
|
|
|
42
44
|
this.activeTasks.push(task);
|
|
43
45
|
}
|
|
@@ -49,21 +51,19 @@ export class NodeTimeoutScheduler implements IScheduler {
|
|
|
49
51
|
ownerName: string
|
|
50
52
|
) {
|
|
51
53
|
const actionWrapper = () => {
|
|
52
|
-
this.
|
|
54
|
+
this.eventEmitter.emit(BotEventType.taskRun, {
|
|
55
|
+
name,
|
|
53
56
|
ownerName,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
`Executing delayed oneshot ${name}`
|
|
57
|
-
);
|
|
57
|
+
delay
|
|
58
|
+
});
|
|
58
59
|
action();
|
|
59
60
|
};
|
|
60
61
|
setTimeout(actionWrapper, delay);
|
|
61
62
|
|
|
62
|
-
this.
|
|
63
|
+
this.eventEmitter.emit(BotEventType.taskCreated, {
|
|
64
|
+
name,
|
|
63
65
|
ownerName,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
`Created oneshot task ${name}, that will run in ${delay}ms.`
|
|
67
|
-
);
|
|
66
|
+
delay
|
|
67
|
+
});
|
|
68
68
|
}
|
|
69
69
|
}
|
package/services/telegramApi.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { IStorageClient } from '../types/storage';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
BotResponse,
|
|
4
|
+
BotResponseTypes,
|
|
5
|
+
IReplyResponse
|
|
6
|
+
} from '../types/response';
|
|
4
7
|
import { QueueItem, ResponseProcessingQueue } from './responseProcessingQueue';
|
|
5
8
|
import { IReplyCapture } from '../types/capture';
|
|
6
9
|
import { IActionWithState } from '../types/action';
|
|
@@ -8,6 +11,7 @@ import { IActionState } from '../types/actionState';
|
|
|
8
11
|
import { TraceId } from '../types/trace';
|
|
9
12
|
import { ChatInfo } from '../dtos/chatInfo';
|
|
10
13
|
import { TelegramApiClient, TelegramMessage } from '../types/externalAliases';
|
|
14
|
+
import { BotEventType, TypedEventEmitter } from '../types/events';
|
|
11
15
|
|
|
12
16
|
export const TELEGRAM_ERROR_QUOTE_INVALID = 'QUOTE_TEXT_INVALID';
|
|
13
17
|
|
|
@@ -15,7 +19,7 @@ export class TelegramApiService {
|
|
|
15
19
|
private readonly queue = new ResponseProcessingQueue();
|
|
16
20
|
private readonly telegram: TelegramApiClient;
|
|
17
21
|
private readonly storage: IStorageClient;
|
|
18
|
-
private readonly
|
|
22
|
+
private readonly eventEmitter: TypedEventEmitter;
|
|
19
23
|
private readonly captureRegistrationCallback: (
|
|
20
24
|
capture: IReplyCapture,
|
|
21
25
|
parentMessageId: number,
|
|
@@ -25,22 +29,35 @@ export class TelegramApiService {
|
|
|
25
29
|
|
|
26
30
|
private readonly botName: string;
|
|
27
31
|
|
|
32
|
+
private readonly methodMap: Record<
|
|
33
|
+
'pin' | keyof typeof BotResponseTypes,
|
|
34
|
+
string | null
|
|
35
|
+
> = {
|
|
36
|
+
inlineQuery: 'answerInlineQuery',
|
|
37
|
+
text: 'sendMessage',
|
|
38
|
+
react: 'setMessageReaction',
|
|
39
|
+
unpin: 'unpinChatMessage',
|
|
40
|
+
pin: 'pinChatMessage',
|
|
41
|
+
image: 'sendPhoto',
|
|
42
|
+
video: 'sendVideo',
|
|
43
|
+
delay: null
|
|
44
|
+
};
|
|
45
|
+
|
|
28
46
|
constructor(
|
|
29
47
|
botName: string,
|
|
30
48
|
telegram: TelegramApiClient,
|
|
31
49
|
storage: IStorageClient,
|
|
32
|
-
|
|
50
|
+
eventEmitter: TypedEventEmitter,
|
|
33
51
|
captureRegistrationCallback: (
|
|
34
52
|
capture: IReplyCapture,
|
|
35
53
|
parentMessageId: number,
|
|
36
|
-
chatInfo: ChatInfo
|
|
37
|
-
traceId: TraceId
|
|
54
|
+
chatInfo: ChatInfo
|
|
38
55
|
) => void
|
|
39
56
|
) {
|
|
40
57
|
this.telegram = telegram;
|
|
41
58
|
this.botName = botName;
|
|
42
59
|
this.storage = storage;
|
|
43
|
-
this.
|
|
60
|
+
this.eventEmitter = eventEmitter;
|
|
44
61
|
this.captureRegistrationCallback = captureRegistrationCallback;
|
|
45
62
|
}
|
|
46
63
|
|
|
@@ -54,14 +71,6 @@ export class TelegramApiService {
|
|
|
54
71
|
|
|
55
72
|
const queueItem: QueueItem = {
|
|
56
73
|
callback: async () => {
|
|
57
|
-
const scopedLogger = this.logger.createScope(
|
|
58
|
-
this.botName,
|
|
59
|
-
response.traceId,
|
|
60
|
-
'chatInfo' in response
|
|
61
|
-
? response.chatInfo.name
|
|
62
|
-
: 'Unknown'
|
|
63
|
-
);
|
|
64
|
-
|
|
65
74
|
try {
|
|
66
75
|
await this.processResponse(response);
|
|
67
76
|
} catch (error) {
|
|
@@ -75,23 +84,27 @@ export class TelegramApiService {
|
|
|
75
84
|
TELEGRAM_ERROR_QUOTE_INVALID
|
|
76
85
|
)
|
|
77
86
|
) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
87
|
+
this.eventEmitter.emit(BotEventType.error, {
|
|
88
|
+
error: new Error(
|
|
89
|
+
'Quote error recieved, retrying without quote'
|
|
90
|
+
)
|
|
91
|
+
});
|
|
92
|
+
|
|
81
93
|
try {
|
|
82
94
|
await this.processResponse(response, true);
|
|
83
95
|
} catch (error) {
|
|
84
|
-
|
|
85
|
-
error
|
|
86
|
-
|
|
87
|
-
);
|
|
96
|
+
this.eventEmitter.emit(BotEventType.error, {
|
|
97
|
+
error: error as Error
|
|
98
|
+
});
|
|
88
99
|
}
|
|
89
100
|
|
|
90
101
|
return;
|
|
91
102
|
}
|
|
92
103
|
}
|
|
93
104
|
|
|
94
|
-
|
|
105
|
+
this.eventEmitter.emit(BotEventType.error, {
|
|
106
|
+
error: error as Error
|
|
107
|
+
});
|
|
95
108
|
}
|
|
96
109
|
},
|
|
97
110
|
priority: response.createdAt + offset
|
|
@@ -109,11 +122,19 @@ export class TelegramApiService {
|
|
|
109
122
|
message: TelegramMessage
|
|
110
123
|
) {
|
|
111
124
|
if (response.shouldPin) {
|
|
125
|
+
this.eventEmitter.emit(BotEventType.apiRequestSending, {
|
|
126
|
+
response: null,
|
|
127
|
+
telegramMethod: this.methodMap['pin']
|
|
128
|
+
});
|
|
112
129
|
await this.telegram.pinChatMessage(
|
|
113
130
|
response.chatInfo.id,
|
|
114
131
|
message.message_id,
|
|
115
132
|
{ disable_notification: true }
|
|
116
133
|
);
|
|
134
|
+
this.eventEmitter.emit(BotEventType.apiRequestSent, {
|
|
135
|
+
response: null,
|
|
136
|
+
telegramMethod: this.methodMap['pin']
|
|
137
|
+
});
|
|
117
138
|
|
|
118
139
|
await this.storage.updateStateFor(
|
|
119
140
|
response.action as IActionWithState<IActionState>,
|
|
@@ -127,6 +148,10 @@ export class TelegramApiService {
|
|
|
127
148
|
|
|
128
149
|
private async processResponse(response: BotResponse, ignoreQuote = false) {
|
|
129
150
|
const sentMessage = await this.sendApiRequest(response, ignoreQuote);
|
|
151
|
+
this.eventEmitter.emit(BotEventType.apiRequestSent, {
|
|
152
|
+
response,
|
|
153
|
+
telegramMethod: this.methodMap[response.kind]
|
|
154
|
+
});
|
|
130
155
|
|
|
131
156
|
if (sentMessage && 'content' in response) {
|
|
132
157
|
await this.pinIfShould(response, sentMessage);
|
|
@@ -146,6 +171,11 @@ export class TelegramApiService {
|
|
|
146
171
|
response: BotResponse,
|
|
147
172
|
ignoreQuote: boolean
|
|
148
173
|
): Promise<TelegramMessage | null> {
|
|
174
|
+
this.eventEmitter.emit(BotEventType.apiRequestSending, {
|
|
175
|
+
response,
|
|
176
|
+
telegramMethod: this.methodMap[response.kind]
|
|
177
|
+
});
|
|
178
|
+
|
|
149
179
|
switch (response.kind) {
|
|
150
180
|
case 'text':
|
|
151
181
|
return await this.telegram.sendMessage(
|