chz-telegram-bot 0.3.6 → 0.3.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.
Files changed (42) hide show
  1. package/dist/dtos/incomingMessage.d.ts.map +1 -1
  2. package/dist/dtos/incomingMessage.js +6 -1
  3. package/dist/entities/context/baseContext.d.ts +35 -0
  4. package/dist/entities/context/baseContext.d.ts.map +1 -0
  5. package/dist/entities/context/baseContext.js +32 -0
  6. package/dist/entities/context/chatContext.d.ts +4 -27
  7. package/dist/entities/context/chatContext.d.ts.map +1 -1
  8. package/dist/entities/context/chatContext.js +3 -19
  9. package/dist/entities/context/inlineQueryContext.d.ts +2 -15
  10. package/dist/entities/context/inlineQueryContext.d.ts.map +1 -1
  11. package/dist/entities/context/inlineQueryContext.js +3 -4
  12. package/dist/entities/context/messageContext.d.ts +2 -1
  13. package/dist/entities/context/messageContext.d.ts.map +1 -1
  14. package/dist/entities/context/replyContext.d.ts +2 -20
  15. package/dist/entities/context/replyContext.d.ts.map +1 -1
  16. package/dist/entities/context/replyContext.js +3 -5
  17. package/dist/services/actionProcessors/baseProcessor.d.ts +20 -0
  18. package/dist/services/actionProcessors/baseProcessor.d.ts.map +1 -0
  19. package/dist/services/actionProcessors/baseProcessor.js +29 -0
  20. package/dist/services/actionProcessors/commandActionProcessor.d.ts +2 -7
  21. package/dist/services/actionProcessors/commandActionProcessor.d.ts.map +1 -1
  22. package/dist/services/actionProcessors/commandActionProcessor.js +16 -27
  23. package/dist/services/actionProcessors/inlineQueryActionProcessor.d.ts +2 -7
  24. package/dist/services/actionProcessors/inlineQueryActionProcessor.d.ts.map +1 -1
  25. package/dist/services/actionProcessors/inlineQueryActionProcessor.js +6 -15
  26. package/dist/services/actionProcessors/scheduledActionProcessor.d.ts +2 -6
  27. package/dist/services/actionProcessors/scheduledActionProcessor.d.ts.map +1 -1
  28. package/dist/services/actionProcessors/scheduledActionProcessor.js +5 -14
  29. package/dist/types/action.d.ts +3 -0
  30. package/dist/types/action.d.ts.map +1 -1
  31. package/dtos/incomingMessage.ts +6 -1
  32. package/entities/context/baseContext.ts +58 -0
  33. package/entities/context/chatContext.ts +8 -45
  34. package/entities/context/inlineQueryContext.ts +3 -20
  35. package/entities/context/messageContext.ts +2 -1
  36. package/entities/context/replyContext.ts +5 -25
  37. package/package.json +1 -1
  38. package/services/actionProcessors/baseProcessor.ts +60 -0
  39. package/services/actionProcessors/commandActionProcessor.ts +24 -42
  40. package/services/actionProcessors/inlineQueryActionProcessor.ts +16 -32
  41. package/services/actionProcessors/scheduledActionProcessor.ts +7 -23
  42. package/types/action.ts +3 -0
@@ -9,16 +9,14 @@ const chatInfo_1 = require("../../dtos/chatInfo");
9
9
  const chatContext_1 = require("../../entities/context/chatContext");
10
10
  const timeConvertions_1 = require("../../helpers/timeConvertions");
11
11
  const traceFactory_1 = require("../../helpers/traceFactory");
12
- class ScheduledActionProcessor {
12
+ const baseProcessor_1 = require("./baseProcessor");
13
+ class ScheduledActionProcessor extends baseProcessor_1.BaseActionProcessor {
13
14
  constructor(botName, chats, storage, scheduler, logger) {
14
- this.storage = storage;
15
- this.scheduler = scheduler;
16
- this.logger = logger;
17
- this.botName = botName;
15
+ super(botName, storage, scheduler, logger);
18
16
  this.chats = chats;
19
17
  }
20
18
  initialize(api, scheduled, period) {
21
- this.api = api;
19
+ this.initializeDependencies(api, null);
22
20
  this.scheduled = scheduled;
23
21
  if (this.scheduled.length > 0) {
24
22
  const now = (0, moment_1.default)();
@@ -45,14 +43,7 @@ class ScheduledActionProcessor {
45
43
  for (const [chatName, chatId] of Object.entries(this.chats)) {
46
44
  for (const scheduledAction of this.scheduled) {
47
45
  this.initializeChatContext(ctx, scheduledAction, new chatInfo_1.ChatInfo(chatId, chatName), (0, traceFactory_1.createTrace)(scheduledAction, this.botName, `${scheduledAction.key}-${chatId}`));
48
- try {
49
- const responses = await scheduledAction.exec(ctx);
50
- this.api.enqueueBatchedResponses(responses);
51
- ctx.isInitialized = false;
52
- }
53
- catch (error) {
54
- ctx.logger.errorWithTraceId(error, ctx);
55
- }
46
+ this.executeAction(scheduledAction, ctx);
56
47
  }
57
48
  }
58
49
  this.api.flushResponses();
@@ -1,4 +1,6 @@
1
+ import { BaseContext } from '../entities/context/baseContext';
1
2
  import { IActionState } from './actionState';
3
+ import { BotResponse } from './response';
2
4
  export type ActionKey = string & {
3
5
  __brand: 'actionKey';
4
6
  };
@@ -7,5 +9,6 @@ export interface IActionWithState<TActionState extends IActionState> extends IAc
7
9
  }
8
10
  export interface IAction {
9
11
  readonly key: ActionKey;
12
+ exec(ctx: BaseContext<IAction>): Promise<BotResponse[]>;
10
13
  }
11
14
  //# sourceMappingURL=action.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../types/action.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,CAAC,YAAY,SAAS,YAAY,CAC/D,SAAQ,OAAO;IACf,QAAQ,CAAC,gBAAgB,EAAE,MAAM,YAAY,CAAC;CACjD;AAED,MAAM,WAAW,OAAO;IACpB,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;CAC3B"}
1
+ {"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../types/action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AAE1D,MAAM,WAAW,gBAAgB,CAAC,YAAY,SAAS,YAAY,CAC/D,SAAQ,OAAO;IACf,QAAQ,CAAC,gBAAgB,EAAE,MAAM,YAAY,CAAC;CACjD;AAED,MAAM,WAAW,OAAO;IACpB,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACxB,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;CAC3D"}
@@ -52,7 +52,12 @@ export class IncomingMessage {
52
52
  ? ctxMessage.reply_to_message?.message_id
53
53
  : undefined;
54
54
  this.from = ctxMessage.from;
55
- this.text = 'text' in ctxMessage ? ctxMessage.text : '';
55
+ this.text =
56
+ 'text' in ctxMessage
57
+ ? ctxMessage.text
58
+ : 'caption' in ctxMessage
59
+ ? ctxMessage.caption ?? ''
60
+ : '';
56
61
  this.chatInfo = new ChatInfo(
57
62
  ctxMessage.chat.id,
58
63
  'title' in ctxMessage.chat
@@ -0,0 +1,58 @@
1
+ import { ChatInfo } from '../../dtos/chatInfo';
2
+ import { IAction, IActionWithState } from '../../types/action';
3
+ import { IActionState } from '../../types/actionState';
4
+ import { IScopedLogger } from '../../types/logger';
5
+ import { BotResponse } from '../../types/response';
6
+ import { IScheduler } from '../../types/scheduler';
7
+ import { IStorageClient } from '../../types/storage';
8
+ import { TraceId } from '../../types/trace';
9
+
10
+ export abstract class BaseContext<TAction extends IAction> {
11
+ isInitialized = false;
12
+ private _responses: BotResponse[] = [];
13
+
14
+ action!: TAction;
15
+
16
+ /** Storage client instance for the bot executing this action. */
17
+ readonly storage: IStorageClient;
18
+ /** Scheduler instance for the bot executing this action */
19
+ readonly scheduler: IScheduler;
20
+ logger!: IScopedLogger;
21
+ /** Trace id of a action execution. */
22
+ traceId!: TraceId;
23
+ /** Name of a bot that executes this action. */
24
+ botName!: string;
25
+ /** Chat information. */
26
+ chatInfo!: ChatInfo;
27
+
28
+ /** Ordered collection of responses to be processed */
29
+ public get responses(): BotResponse[] {
30
+ return this._responses;
31
+ }
32
+ public set responses(value: BotResponse[]) {
33
+ this._responses = value;
34
+ }
35
+
36
+ constructor(storage: IStorageClient, scheduler: IScheduler) {
37
+ this.storage = storage;
38
+ this.scheduler = scheduler;
39
+ }
40
+
41
+ /**
42
+ * Loads state of another action for current chat.
43
+ * @param action Action to load state of.
44
+ * @template TAnotherActionState - Type of a state that is used by another action.
45
+ */
46
+ async loadStateOf<TAnotherActionState extends IActionState>(
47
+ action: IActionWithState<TAnotherActionState>
48
+ ) {
49
+ const allStates = await this.storage.load(action.key);
50
+ const stateForChat = allStates[this.chatInfo.id];
51
+
52
+ if (!stateForChat) {
53
+ return Object.freeze(action.stateConstructor());
54
+ }
55
+
56
+ return Object.freeze(stateForChat as TAnotherActionState);
57
+ }
58
+ }
@@ -10,44 +10,25 @@ import {
10
10
  } from '../../types/messageSendingOptions';
11
11
  import { IActionWithState } from '../../types/action';
12
12
  import { IActionState } from '../../types/actionState';
13
- import { BotResponse, IReplyResponse } from '../../types/response';
13
+ import { IReplyResponse } from '../../types/response';
14
14
  import { Milliseconds } from '../../types/timeValues';
15
15
  import { DelayResponse } from '../../dtos/responses/delay';
16
- import { ChatInfo } from '../../dtos/chatInfo';
17
- import { IScopedLogger } from '../../types/logger';
18
16
  import { IScheduler } from '../../types/scheduler';
19
- import { TraceId } from '../../types/trace';
20
17
  import { ICaptureController } from '../../types/capture';
21
18
  import { CommandTrigger } from '../../types/commandTrigger';
22
19
  import { ReplyContext } from './replyContext';
20
+ import { BaseContext } from './baseContext';
21
+ import { ScheduledAction } from '../actions/scheduledAction';
23
22
 
24
23
  /**
25
24
  * Context of action executed in chat.
26
25
  */
27
- export class ChatContext<TActionState extends IActionState> {
28
- action!: IActionWithState<TActionState>;
29
-
30
- /** Storage client instance for the bot executing this action. */
31
- readonly storage: IStorageClient;
32
- /** Logger instance for the bot executing this action */
33
- /** Scheduler instance for the bot executing this action */
34
- readonly scheduler: IScheduler;
35
-
36
- logger!: IScopedLogger;
37
- /** Trace id of a action execution. */
38
- traceId!: TraceId;
39
- /** Name of a bot that executes this action. */
40
- botName!: string;
41
- /** Chat information. */
42
- chatInfo!: ChatInfo;
43
- /** Ordered collection of responses to be processed */
44
- responses: BotResponse[] = [];
45
-
46
- isInitialized = false;
47
-
26
+ export class ChatContext<
27
+ TActionState extends IActionState,
28
+ TAction extends IActionWithState<TActionState> = ScheduledAction<TActionState>
29
+ > extends BaseContext<TAction> {
48
30
  constructor(storage: IStorageClient, scheduler: IScheduler) {
49
- this.storage = storage;
50
- this.scheduler = scheduler;
31
+ super(storage, scheduler);
51
32
  }
52
33
 
53
34
  protected createCaptureController(
@@ -71,24 +52,6 @@ export class ChatContext<TActionState extends IActionState> {
71
52
  };
72
53
  }
73
54
 
74
- /**
75
- * Loads state of another action for current chat.
76
- * @param action Action to load state of.
77
- * @template TAnotherActionState - Type of a state that is used by another action.
78
- */
79
- async loadStateOf<TAnotherActionState extends IActionState>(
80
- action: IActionWithState<TAnotherActionState>
81
- ) {
82
- const allStates = await this.storage.load(action.key);
83
- const stateForChat = allStates[this.chatInfo.id];
84
-
85
- if (!stateForChat) {
86
- return Object.freeze(action.stateConstructor());
87
- }
88
-
89
- return Object.freeze(stateForChat as TAnotherActionState);
90
- }
91
-
92
55
  /**
93
56
  * Collection of actions that send something to chat as a standalone message.
94
57
  */
@@ -1,27 +1,13 @@
1
1
  import { InlineQueryResult } from 'telegraf/types';
2
- import { IScopedLogger } from '../../types/logger';
3
2
  import { BotResponse } from '../../types/response';
4
3
  import { IScheduler } from '../../types/scheduler';
5
4
  import { IStorageClient } from '../../types/storage';
6
- import { TraceId } from '../../types/trace';
7
5
  import { InlineQueryAction } from '../actions/inlineQueryAction';
8
6
  import { InlineQueryResponse } from '../../dtos/responses/inlineQueryResponse';
7
+ import { BaseContext } from './baseContext';
9
8
 
10
- export class InlineQueryContext {
11
- action!: InlineQueryAction;
9
+ export class InlineQueryContext extends BaseContext<InlineQueryAction> {
12
10
  queryResults: InlineQueryResult[] = [];
13
-
14
- /** Storage client instance for the bot executing this action. */
15
- readonly storage: IStorageClient;
16
- /** Scheduler instance for the bot executing this action */
17
- readonly scheduler: IScheduler;
18
-
19
- /** Logger instance for the bot executing this action */
20
- logger!: IScopedLogger;
21
- /** Trace id of a action execution. */
22
- traceId!: TraceId;
23
- /** Name of a bot that executes this action. */
24
- botName!: string;
25
11
  /**
26
12
  * Abort signal to be utilized in query handler.
27
13
  * Signal will be aborted if new query comes from the same user.
@@ -46,11 +32,8 @@ export class InlineQueryContext {
46
32
  /** Collection of Regexp match results on a message that triggered this action. Will be empty if trigger is not a Regexp. */
47
33
  matchResults: RegExpMatchArray[] = [];
48
34
 
49
- isInitialized = false;
50
-
51
35
  constructor(storage: IStorageClient, scheduler: IScheduler) {
52
- this.storage = storage;
53
- this.scheduler = scheduler;
36
+ super(storage, scheduler);
54
37
  }
55
38
 
56
39
  /**
@@ -17,13 +17,14 @@ import {
17
17
  } from '../../types/messageTypes';
18
18
  import { IScheduler } from '../../types/scheduler';
19
19
  import { ReplyInfo } from '../../dtos/replyInfo';
20
+ import { CommandAction } from '../actions/commandAction';
20
21
 
21
22
  /**
22
23
  * Context of action executed in chat, in response to a message
23
24
  */
24
25
  export class MessageContext<
25
26
  TActionState extends IActionState
26
- > extends ChatContext<TActionState> {
27
+ > extends ChatContext<TActionState, CommandAction<TActionState>> {
27
28
  /** Id of a message that triggered this action. */
28
29
  messageId!: number;
29
30
  /** Text of a message that triggered this action. */
@@ -1,12 +1,10 @@
1
1
  import { TelegramEmoji } from 'telegraf/types';
2
- import { ChatInfo } from '../../dtos/chatInfo';
3
2
  import { ReplyInfo } from '../../dtos/replyInfo';
4
3
  import { ImageMessage } from '../../dtos/responses/imageMessage';
5
4
  import { Reaction } from '../../dtos/responses/reaction';
6
5
  import { TextMessage } from '../../dtos/responses/textMessage';
7
6
  import { VideoMessage } from '../../dtos/responses/videoMessage';
8
7
  import { IActionState } from '../../types/actionState';
9
- import { IScopedLogger } from '../../types/logger';
10
8
  import {
11
9
  TextMessageSendingOptions,
12
10
  MessageSendingOptions
@@ -15,32 +13,15 @@ import {
15
13
  MessageTypeValue,
16
14
  TelegrafContextMessage
17
15
  } from '../../types/messageTypes';
18
- import { BotResponse } from '../../types/response';
19
16
  import { IScheduler } from '../../types/scheduler';
20
17
  import { IStorageClient } from '../../types/storage';
21
- import { TraceId } from '../../types/trace';
22
18
  import { ReplyCaptureAction } from '../actions/replyCaptureAction';
23
19
  import { resolve } from 'path';
20
+ import { BaseContext } from './baseContext';
24
21
 
25
- export class ReplyContext<TParentActionState extends IActionState> {
26
- action!: ReplyCaptureAction<TParentActionState>;
27
-
28
- /** Storage client instance for the bot executing this action. */
29
- readonly storage: IStorageClient;
30
- /** Scheduler instance for the bot executing this action */
31
- readonly scheduler: IScheduler;
32
-
33
- /** Trace id of a action execution. */
34
- traceId!: TraceId;
35
- /** Name of a bot that executes this action. */
36
- botName!: string;
37
- /** Logger instance for the bot executing this action */
38
- logger!: IScopedLogger;
39
-
40
- /** Ordered collection of responses to be processed */
41
- responses: BotResponse[] = [];
42
- /** Chat information. */
43
- chatInfo!: ChatInfo;
22
+ export class ReplyContext<
23
+ TParentActionState extends IActionState
24
+ > extends BaseContext<ReplyCaptureAction<TParentActionState>> {
44
25
  /** Collection of Regexp match results on a message that triggered this action. Will be empty if trigger is not a Regexp. */
45
26
  matchResults!: RegExpExecArray[];
46
27
  /** Id of a message that triggered this action. */
@@ -61,8 +42,7 @@ export class ReplyContext<TParentActionState extends IActionState> {
61
42
  isInitialized = false;
62
43
 
63
44
  constructor(storage: IStorageClient, scheduler: IScheduler) {
64
- this.storage = storage;
65
- this.scheduler = scheduler;
45
+ super(storage, scheduler);
66
46
  }
67
47
 
68
48
  private getQuotePart(quote: boolean | string) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chz-telegram-bot",
3
- "version": "0.3.6",
3
+ "version": "0.3.8",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "async-sema": "^3.1.1",
@@ -0,0 +1,60 @@
1
+ import { Telegraf } from 'telegraf';
2
+ import { ILogger } from '../../types/logger';
3
+ import { IScheduler } from '../../types/scheduler';
4
+ import { IStorageClient } from '../../types/storage';
5
+ import { TelegramApiService } from '../telegramApi';
6
+ import { IAction } from '../../types/action';
7
+ import { BaseContext } from '../../entities/context/baseContext';
8
+
9
+ export abstract class BaseActionProcessor {
10
+ protected readonly storage: IStorageClient;
11
+ protected readonly scheduler: IScheduler;
12
+ protected readonly logger: ILogger;
13
+
14
+ protected readonly botName: string;
15
+
16
+ protected api!: TelegramApiService;
17
+ protected telegraf!: Telegraf;
18
+
19
+ constructor(
20
+ botName: string,
21
+ storage: IStorageClient,
22
+ scheduler: IScheduler,
23
+ logger: ILogger
24
+ ) {
25
+ this.storage = storage;
26
+ this.scheduler = scheduler;
27
+ this.logger = logger;
28
+
29
+ this.botName = botName;
30
+ }
31
+
32
+ private defaultErrorHandler<
33
+ TAction extends IAction,
34
+ TActionContext extends BaseContext<TAction>
35
+ >(error: Error, ctx: TActionContext) {
36
+ ctx.logger.errorWithTraceId(error, ctx);
37
+ }
38
+
39
+ initializeDependencies(api: TelegramApiService, telegraf: Telegraf) {
40
+ this.api = api;
41
+ this.telegraf = telegraf;
42
+ }
43
+
44
+ async executeAction<
45
+ TAction extends IAction,
46
+ TActionContext extends BaseContext<TAction>
47
+ >(
48
+ action: TAction,
49
+ ctx: TActionContext,
50
+ errorHandler?: (error: Error, ctx: TActionContext) => void
51
+ ) {
52
+ try {
53
+ const responses = await action.exec(ctx);
54
+ this.api.enqueueBatchedResponses(responses);
55
+ ctx.isInitialized = false;
56
+ } catch (error) {
57
+ (errorHandler ?? this.defaultErrorHandler)(error as Error, ctx);
58
+ }
59
+ }
60
+ }
@@ -4,7 +4,6 @@ import { CommandAction } from '../../entities/actions/commandAction';
4
4
  import { ReplyCaptureAction } from '../../entities/actions/replyCaptureAction';
5
5
  import { MessageContext } from '../../entities/context/messageContext';
6
6
  import { ReplyContext } from '../../entities/context/replyContext';
7
- import { IActionWithState } from '../../types/action';
8
7
  import { IActionState } from '../../types/actionState';
9
8
  import { ILogger } from '../../types/logger';
10
9
  import { IScheduler } from '../../types/scheduler';
@@ -18,17 +17,11 @@ import {
18
17
  MessageType
19
18
  } from '../../types/messageTypes';
20
19
  import { typeSafeObjectFromEntries } from '../../helpers/objectFromEntries';
20
+ import { BaseActionProcessor } from './baseProcessor';
21
21
 
22
- export class CommandActionProcessor {
23
- private readonly storage: IStorageClient;
24
- private readonly scheduler: IScheduler;
25
- private readonly logger: ILogger;
22
+ export class CommandActionProcessor extends BaseActionProcessor {
23
+ private readonly replyCaptures: ReplyCaptureAction<IActionState>[] = [];
26
24
 
27
- private readonly botName: string;
28
- private readonly replyCaptures: ReplyCaptureAction<IActionState>[];
29
-
30
- private api!: TelegramApiService;
31
- private telegraf!: Telegraf;
32
25
  private commands = typeSafeObjectFromEntries(
33
26
  Object.values(MessageType).map((x) => [
34
27
  x,
@@ -42,12 +35,7 @@ export class CommandActionProcessor {
42
35
  scheduler: IScheduler,
43
36
  logger: ILogger
44
37
  ) {
45
- this.storage = storage;
46
- this.scheduler = scheduler;
47
- this.logger = logger;
48
-
49
- this.botName = botName;
50
- this.replyCaptures = [];
38
+ super(botName, storage, scheduler, logger);
51
39
  }
52
40
 
53
41
  initialize(
@@ -56,8 +44,7 @@ export class CommandActionProcessor {
56
44
  commands: CommandAction<IActionState>[],
57
45
  verboseLoggingForIncomingMessage: boolean
58
46
  ) {
59
- this.api = api;
60
- this.telegraf = telegraf;
47
+ this.initializeDependencies(api, telegraf);
61
48
 
62
49
  for (const msgType of Object.values(MessageType)) {
63
50
  if (msgType == MessageType.Text) {
@@ -153,32 +140,27 @@ export class CommandActionProcessor {
153
140
  this.scheduler
154
141
  );
155
142
 
156
- for (const commandAction of this.commands[msg.type]) {
157
- this.initializeMessageContext(ctx, commandAction, msg);
158
-
159
- try {
160
- const responses = await commandAction.exec(ctx);
161
- this.api.enqueueBatchedResponses(responses);
162
- ctx.isInitialized = false;
163
- } catch (error) {
164
- ctx.logger.errorWithTraceId(error, ctx);
165
- }
143
+ const commandsToCheck = new Set(this.commands[msg.type]);
144
+ if (msg.type != MessageType.Text && msg.text != '') {
145
+ this.commands[MessageType.Text].forEach((x) =>
146
+ commandsToCheck.add(x)
147
+ );
166
148
  }
167
149
 
168
- const replyCtx = new ReplyContext<IActionState>(
169
- this.storage,
170
- this.scheduler
171
- );
150
+ for (const commandAction of commandsToCheck) {
151
+ this.initializeMessageContext(ctx, commandAction, msg);
152
+ this.executeAction(commandAction, ctx);
153
+ }
172
154
 
173
- for (const replyAction of this.replyCaptures) {
174
- this.initializeReplyCaptureContext(replyCtx, replyAction, msg);
155
+ if (this.replyCaptures.length != 0) {
156
+ const replyCtx = new ReplyContext<IActionState>(
157
+ this.storage,
158
+ this.scheduler
159
+ );
175
160
 
176
- try {
177
- const responses = await replyAction.exec(replyCtx);
178
- this.api.enqueueBatchedResponses(responses);
179
- replyCtx.isInitialized = false;
180
- } catch (error) {
181
- replyCtx.logger.errorWithTraceId(error, replyCtx);
161
+ for (const replyAction of this.replyCaptures) {
162
+ this.initializeReplyCaptureContext(replyCtx, replyAction, msg);
163
+ this.executeAction(replyAction, replyCtx);
182
164
  }
183
165
  }
184
166
 
@@ -214,9 +196,9 @@ export class CommandActionProcessor {
214
196
  );
215
197
  }
216
198
 
217
- private initializeMessageContext<TActionState extends IActionState>(
199
+ private initializeMessageContext(
218
200
  ctx: MessageContext<IActionState>,
219
- action: IActionWithState<TActionState>,
201
+ action: CommandAction<IActionState>,
220
202
  message: IncomingMessage
221
203
  ) {
222
204
  ctx.messageId = message.messageId;
@@ -9,16 +9,9 @@ import { IStorageClient } from '../../types/storage';
9
9
  import { Milliseconds } from '../../types/timeValues';
10
10
  import { TraceId } from '../../types/trace';
11
11
  import { TelegramApiService } from '../telegramApi';
12
+ import { BaseActionProcessor } from './baseProcessor';
12
13
 
13
- export class InlineQueryActionProcessor {
14
- private readonly storage: IStorageClient;
15
- private readonly scheduler: IScheduler;
16
- private readonly logger: ILogger;
17
-
18
- private readonly botName: string;
19
-
20
- private api!: TelegramApiService;
21
- private telegraf!: Telegraf;
14
+ export class InlineQueryActionProcessor extends BaseActionProcessor {
22
15
  private inlineQueries!: InlineQueryAction[];
23
16
 
24
17
  constructor(
@@ -27,11 +20,7 @@ export class InlineQueryActionProcessor {
27
20
  scheduler: IScheduler,
28
21
  logger: ILogger
29
22
  ) {
30
- this.storage = storage;
31
- this.scheduler = scheduler;
32
- this.logger = logger;
33
-
34
- this.botName = botName;
23
+ super(botName, storage, scheduler, logger);
35
24
  }
36
25
 
37
26
  initialize(
@@ -40,8 +29,7 @@ export class InlineQueryActionProcessor {
40
29
  inlineQueries: InlineQueryAction[],
41
30
  period: Milliseconds
42
31
  ) {
43
- this.api = api;
44
- this.telegraf = telegraf;
32
+ this.initializeDependencies(api, telegraf);
45
33
  this.inlineQueries = inlineQueries;
46
34
 
47
35
  let pendingInlineQueries: IncomingInlineQuery[] = [];
@@ -113,23 +101,19 @@ export class InlineQueryActionProcessor {
113
101
  inlineQuery.traceId
114
102
  );
115
103
 
116
- try {
117
- const responses = await inlineQueryAction.exec(
118
- ctx
119
- );
120
- this.api.enqueueBatchedResponses(responses);
121
- ctx.isInitialized = false;
122
- } catch (err) {
123
- const error = err as Error;
124
-
125
- if (error.name == 'AbortError') {
126
- ctx.logger.logWithTraceId(
127
- `Aborting query ${inlineQuery.queryId} (${inlineQuery.query}) successful.`
128
- );
129
- } else {
130
- ctx.logger.errorWithTraceId(error, ctx);
104
+ this.executeAction(
105
+ inlineQueryAction,
106
+ ctx,
107
+ (error, ctx) => {
108
+ if (error.name == 'AbortError') {
109
+ ctx.logger.logWithTraceId(
110
+ `Aborting query ${inlineQuery.queryId} (${inlineQuery.query}) successful.`
111
+ );
112
+ } else {
113
+ ctx.logger.errorWithTraceId(error, ctx);
114
+ }
131
115
  }
132
- }
116
+ );
133
117
  }
134
118
 
135
119
  queriesInProcessing.delete(inlineQuery.userId);
@@ -4,7 +4,6 @@ import { ScheduledAction } from '../../entities/actions/scheduledAction';
4
4
  import { ChatContext } from '../../entities/context/chatContext';
5
5
  import { secondsToMilliseconds } from '../../helpers/timeConvertions';
6
6
  import { createTrace } from '../../helpers/traceFactory';
7
- import { IActionWithState } from '../../types/action';
8
7
  import { IActionState } from '../../types/actionState';
9
8
  import { ILogger } from '../../types/logger';
10
9
  import { IScheduler } from '../../types/scheduler';
@@ -12,16 +11,11 @@ import { IStorageClient } from '../../types/storage';
12
11
  import { Seconds, Milliseconds } from '../../types/timeValues';
13
12
  import { TraceId } from '../../types/trace';
14
13
  import { TelegramApiService } from '../telegramApi';
14
+ import { BaseActionProcessor } from './baseProcessor';
15
15
 
16
- export class ScheduledActionProcessor {
17
- private readonly storage: IStorageClient;
18
- private readonly scheduler: IScheduler;
19
- private readonly logger: ILogger;
20
-
21
- private readonly botName: string;
16
+ export class ScheduledActionProcessor extends BaseActionProcessor {
22
17
  private readonly chats: Record<string, number>;
23
18
 
24
- private api!: TelegramApiService;
25
19
  private scheduled!: ScheduledAction<IActionState>[];
26
20
 
27
21
  constructor(
@@ -31,11 +25,7 @@ export class ScheduledActionProcessor {
31
25
  scheduler: IScheduler,
32
26
  logger: ILogger
33
27
  ) {
34
- this.storage = storage;
35
- this.scheduler = scheduler;
36
- this.logger = logger;
37
-
38
- this.botName = botName;
28
+ super(botName, storage, scheduler, logger);
39
29
  this.chats = chats;
40
30
  }
41
31
 
@@ -44,7 +34,7 @@ export class ScheduledActionProcessor {
44
34
  scheduled: ScheduledAction<IActionState>[],
45
35
  period: Seconds
46
36
  ) {
47
- this.api = api;
37
+ this.initializeDependencies(api, null!);
48
38
  this.scheduled = scheduled;
49
39
 
50
40
  if (this.scheduled.length > 0) {
@@ -106,22 +96,16 @@ export class ScheduledActionProcessor {
106
96
  )
107
97
  );
108
98
 
109
- try {
110
- const responses = await scheduledAction.exec(ctx);
111
- this.api.enqueueBatchedResponses(responses);
112
- ctx.isInitialized = false;
113
- } catch (error) {
114
- ctx.logger.errorWithTraceId(error, ctx);
115
- }
99
+ this.executeAction(scheduledAction, ctx);
116
100
  }
117
101
  }
118
102
 
119
103
  this.api.flushResponses();
120
104
  }
121
105
 
122
- private initializeChatContext<TActionState extends IActionState>(
106
+ private initializeChatContext(
123
107
  ctx: ChatContext<IActionState>,
124
- action: IActionWithState<TActionState>,
108
+ action: ScheduledAction<IActionState>,
125
109
  chatInfo: ChatInfo,
126
110
  traceId: TraceId
127
111
  ) {