chz-telegram-bot 0.3.10 → 0.3.12

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 (127) hide show
  1. package/builtin/helpAction.ts +1 -1
  2. package/dist/builtin/helpAction.js +1 -1
  3. package/dist/dtos/chatInfo.js +4 -0
  4. package/dist/dtos/commandTriggerCheckResult.js +3 -0
  5. package/dist/dtos/incomingMessage.js +9 -1
  6. package/dist/dtos/incomingQuery.js +5 -0
  7. package/dist/dtos/replyInfo.js +2 -0
  8. package/dist/dtos/responses/delay.js +6 -2
  9. package/dist/dtos/responses/imageMessage.js +10 -4
  10. package/dist/dtos/responses/inlineQueryResponse.js +6 -2
  11. package/dist/dtos/responses/reaction.js +7 -2
  12. package/dist/dtos/responses/textMessage.js +10 -3
  13. package/dist/dtos/responses/unpin.js +6 -2
  14. package/dist/dtos/responses/videoMessage.js +10 -4
  15. package/dist/entities/actions/commandAction.d.ts +4 -1
  16. package/dist/entities/actions/commandAction.d.ts.map +1 -1
  17. package/dist/entities/actions/commandAction.js +46 -17
  18. package/dist/entities/actions/inlineQueryAction.d.ts.map +1 -1
  19. package/dist/entities/actions/inlineQueryAction.js +8 -1
  20. package/dist/entities/actions/replyCaptureAction.d.ts.map +1 -1
  21. package/dist/entities/actions/replyCaptureAction.js +8 -1
  22. package/dist/entities/actions/scheduledAction.d.ts.map +1 -1
  23. package/dist/entities/actions/scheduledAction.js +13 -14
  24. package/dist/entities/botInstance.js +6 -1
  25. package/dist/entities/cachedStateFactory.js +2 -0
  26. package/dist/entities/context/baseContext.js +14 -2
  27. package/dist/entities/context/chatContext.d.ts +0 -3
  28. package/dist/entities/context/chatContext.d.ts.map +1 -1
  29. package/dist/entities/context/chatContext.js +38 -41
  30. package/dist/entities/context/inlineQueryContext.d.ts +0 -3
  31. package/dist/entities/context/inlineQueryContext.d.ts.map +1 -1
  32. package/dist/entities/context/inlineQueryContext.js +12 -6
  33. package/dist/entities/context/messageContext.d.ts +0 -3
  34. package/dist/entities/context/messageContext.d.ts.map +1 -1
  35. package/dist/entities/context/messageContext.js +77 -68
  36. package/dist/entities/context/replyContext.d.ts +0 -3
  37. package/dist/entities/context/replyContext.d.ts.map +1 -1
  38. package/dist/entities/context/replyContext.js +90 -65
  39. package/dist/entities/states/actionStateBase.js +2 -4
  40. package/dist/entities/taskRecord.js +3 -0
  41. package/dist/helpers/builders/commandActionBuilder.d.ts +3 -0
  42. package/dist/helpers/builders/commandActionBuilder.d.ts.map +1 -1
  43. package/dist/helpers/builders/commandActionBuilder.js +18 -9
  44. package/dist/helpers/builders/inlineQueryActionBuilder.js +7 -6
  45. package/dist/helpers/builders/scheduledActionBuilder.js +7 -5
  46. package/dist/helpers/mapUtils.d.ts +3 -0
  47. package/dist/helpers/mapUtils.d.ts.map +1 -0
  48. package/dist/helpers/mapUtils.js +17 -0
  49. package/dist/helpers/noop.d.ts +3 -4
  50. package/dist/helpers/noop.d.ts.map +1 -1
  51. package/dist/helpers/noop.js +2 -1
  52. package/dist/helpers/traceFactory.d.ts +1 -1
  53. package/dist/helpers/traceFactory.d.ts.map +1 -1
  54. package/dist/main.js +1 -3
  55. package/dist/services/actionProcessingService.d.ts.map +1 -1
  56. package/dist/services/actionProcessingService.js +15 -3
  57. package/dist/services/actionProcessors/baseProcessor.d.ts +1 -3
  58. package/dist/services/actionProcessors/baseProcessor.d.ts.map +1 -1
  59. package/dist/services/actionProcessors/baseProcessor.js +6 -2
  60. package/dist/services/actionProcessors/commandActionProcessor.d.ts +0 -4
  61. package/dist/services/actionProcessors/commandActionProcessor.d.ts.map +1 -1
  62. package/dist/services/actionProcessors/commandActionProcessor.js +10 -13
  63. package/dist/services/actionProcessors/inlineQueryActionProcessor.d.ts +0 -4
  64. package/dist/services/actionProcessors/inlineQueryActionProcessor.d.ts.map +1 -1
  65. package/dist/services/actionProcessors/inlineQueryActionProcessor.js +4 -6
  66. package/dist/services/actionProcessors/scheduledActionProcessor.js +6 -4
  67. package/dist/services/jsonFileStorage.d.ts +4 -3
  68. package/dist/services/jsonFileStorage.d.ts.map +1 -1
  69. package/dist/services/jsonFileStorage.js +22 -14
  70. package/dist/services/jsonLogger.d.ts +1 -1
  71. package/dist/services/jsonLogger.d.ts.map +1 -1
  72. package/dist/services/jsonLogger.js +9 -3
  73. package/dist/services/nodeTimeoutScheduler.d.ts +2 -2
  74. package/dist/services/nodeTimeoutScheduler.d.ts.map +1 -1
  75. package/dist/services/nodeTimeoutScheduler.js +6 -5
  76. package/dist/services/responseProcessingQueue.d.ts.map +1 -1
  77. package/dist/services/responseProcessingQueue.js +9 -7
  78. package/dist/services/telegramApi.d.ts.map +1 -1
  79. package/dist/services/telegramApi.js +17 -8
  80. package/dist/types/commandTrigger.d.ts +1 -2
  81. package/dist/types/commandTrigger.d.ts.map +1 -1
  82. package/dist/types/handlers.d.ts +1 -1
  83. package/dist/types/handlers.d.ts.map +1 -1
  84. package/dist/types/logger.d.ts +2 -2
  85. package/dist/types/logger.d.ts.map +1 -1
  86. package/dist/types/scheduler.d.ts +2 -2
  87. package/dist/types/scheduler.d.ts.map +1 -1
  88. package/dist/types/storage.d.ts +2 -2
  89. package/dist/types/storage.d.ts.map +1 -1
  90. package/dist/types/timeValues.d.ts +3 -3
  91. package/dist/types/timeValues.d.ts.map +1 -1
  92. package/dist/types/trace.d.ts +1 -1
  93. package/dist/types/trace.d.ts.map +1 -1
  94. package/dtos/incomingMessage.ts +1 -1
  95. package/entities/actions/commandAction.ts +55 -28
  96. package/entities/actions/inlineQueryAction.ts +5 -1
  97. package/entities/actions/replyCaptureAction.ts +5 -1
  98. package/entities/actions/scheduledAction.ts +11 -13
  99. package/entities/botInstance.ts +7 -7
  100. package/entities/context/chatContext.ts +0 -6
  101. package/entities/context/inlineQueryContext.ts +0 -6
  102. package/entities/context/messageContext.ts +0 -6
  103. package/entities/context/replyContext.ts +18 -15
  104. package/eslint.config.js +26 -1
  105. package/helpers/builders/commandActionBuilder.ts +10 -0
  106. package/helpers/mapUtils.ts +15 -0
  107. package/helpers/noop.ts +4 -4
  108. package/helpers/traceFactory.ts +2 -2
  109. package/package.json +1 -1
  110. package/services/actionProcessingService.ts +8 -4
  111. package/services/actionProcessors/baseProcessor.ts +5 -8
  112. package/services/actionProcessors/commandActionProcessor.ts +5 -17
  113. package/services/actionProcessors/inlineQueryActionProcessor.ts +5 -15
  114. package/services/actionProcessors/scheduledActionProcessor.ts +4 -4
  115. package/services/jsonFileStorage.ts +39 -21
  116. package/services/jsonLogger.ts +12 -8
  117. package/services/nodeTimeoutScheduler.ts +6 -6
  118. package/services/responseProcessingQueue.ts +9 -4
  119. package/services/telegramApi.ts +7 -5
  120. package/tsconfig.json +1 -1
  121. package/types/commandTrigger.ts +1 -3
  122. package/types/handlers.ts +1 -1
  123. package/types/logger.ts +3 -6
  124. package/types/scheduler.ts +2 -2
  125. package/types/storage.ts +2 -2
  126. package/types/timeValues.ts +3 -3
  127. package/types/trace.ts +3 -1
@@ -2,13 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ResponseProcessingQueue = void 0;
4
4
  const async_sema_1 = require("async-sema");
5
+ function notEmpty(arr) {
6
+ return arr.length > 0;
7
+ }
5
8
  const TELEGRAM_RATELIMIT_DELAY = 35;
6
9
  class ResponseProcessingQueue {
7
- constructor() {
8
- this.rateLimiter = (0, async_sema_1.RateLimit)(1, { timeUnit: TELEGRAM_RATELIMIT_DELAY });
9
- this.items = [];
10
- this.isFlushing = false;
11
- }
10
+ rateLimiter = (0, async_sema_1.RateLimit)(1, { timeUnit: TELEGRAM_RATELIMIT_DELAY });
11
+ items = [];
12
+ isFlushing = false;
12
13
  enqueue(item) {
13
14
  if (this.items.length === 0 ||
14
15
  item.priority >= this.items[this.items.length - 1].priority) {
@@ -26,10 +27,11 @@ class ResponseProcessingQueue {
26
27
  if (this.isFlushing)
27
28
  return;
28
29
  this.isFlushing = true;
29
- while (this.items.length) {
30
+ while (notEmpty(this.items)) {
30
31
  if (Date.now() >= this.items[0].priority) {
31
32
  await this.rateLimiter();
32
- const item = this.items.shift();
33
+ const [item] = this.items;
34
+ this.items.shift();
33
35
  await item.callback();
34
36
  }
35
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"telegramApi.d.ts","sourceRoot":"","sources":["../../services/telegramApi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,eAAO,MAAM,4BAA4B,uBAAuB,CAAC;AAEjE,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAKlC;IAEV,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAG7B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,OAAO,EACf,2BAA2B,EAAE,CACzB,OAAO,EAAE,aAAa,EACtB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,KACf,IAAI;IASb,uBAAuB,CAAC,SAAS,EAAE,WAAW,EAAE;IAsDhD,cAAc;YAIA,WAAW;YAkBX,eAAe;CAoGhC"}
1
+ {"version":3,"file":"telegramApi.d.ts","sourceRoot":"","sources":["../../services/telegramApi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,eAAO,MAAM,4BAA4B,uBAAuB,CAAC;AAEjE,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAKlC;IAEV,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAG7B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,OAAO,EACf,2BAA2B,EAAE,CACzB,OAAO,EAAE,aAAa,EACtB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,KACf,IAAI;IASb,uBAAuB,CAAC,SAAS,EAAE,WAAW,EAAE;IAsDhD,cAAc;YAIA,WAAW;YAkBX,eAAe;CAsGhC"}
@@ -4,8 +4,13 @@ exports.TelegramApiService = exports.TELEGRAM_ERROR_QUOTE_INVALID = void 0;
4
4
  const responseProcessingQueue_1 = require("./responseProcessingQueue");
5
5
  exports.TELEGRAM_ERROR_QUOTE_INVALID = 'QUOTE_TEXT_INVALID';
6
6
  class TelegramApiService {
7
+ queue = new responseProcessingQueue_1.ResponseProcessingQueue();
8
+ telegram;
9
+ storage;
10
+ logger;
11
+ captureRegistrationCallback;
12
+ botName;
7
13
  constructor(botName, telegram, storage, logger, captureRegistrationCallback) {
8
- this.queue = new responseProcessingQueue_1.ResponseProcessingQueue();
9
14
  this.telegram = telegram;
10
15
  this.botName = botName;
11
16
  this.storage = storage;
@@ -50,12 +55,12 @@ class TelegramApiService {
50
55
  }
51
56
  }
52
57
  flushResponses() {
53
- this.queue.flushReadyItems();
58
+ void this.queue.flushReadyItems();
54
59
  }
55
60
  async pinIfShould(response, sentMessage) {
56
61
  if (response.shouldPin) {
57
62
  await this.telegram.pinChatMessage(response.chatInfo.id, sentMessage.message_id, { disable_notification: true });
58
- await this.storage.updateStateFor(response.action, response.chatInfo.id, async (state) => {
63
+ await this.storage.updateStateFor(response.action, response.chatInfo.id, (state) => {
59
64
  state.pinnedMessages.push(sentMessage.message_id);
60
65
  });
61
66
  }
@@ -80,16 +85,20 @@ class TelegramApiService {
80
85
  });
81
86
  break;
82
87
  case 'image':
83
- sentMessage = await this.telegram.sendPhoto(response.chatInfo.id, response.content, response.replyInfo?.id
88
+ sentMessage = await this.telegram.sendPhoto(response.chatInfo.id, response.content,
89
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
90
+ response.replyInfo?.id
84
91
  ? {
85
- reply_to_message_id: response.replyInfo?.id // eslint-disable-next-line @typescript-eslint/no-explicit-any
92
+ reply_to_message_id: response.replyInfo.id // eslint-disable-next-line @typescript-eslint/no-explicit-any
86
93
  }
87
94
  : undefined);
88
95
  break;
89
96
  case 'video':
90
- sentMessage = await this.telegram.sendVideo(response.chatInfo.id, response.content, response.replyInfo?.id
97
+ sentMessage = await this.telegram.sendVideo(response.chatInfo.id, response.content,
98
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
99
+ response.replyInfo?.id
91
100
  ? {
92
- reply_to_message_id: response.replyInfo?.id // eslint-disable-next-line @typescript-eslint/no-explicit-any
101
+ reply_to_message_id: response.replyInfo.id // eslint-disable-next-line @typescript-eslint/no-explicit-any
93
102
  }
94
103
  : undefined);
95
104
  break;
@@ -103,7 +112,7 @@ class TelegramApiService {
103
112
  return;
104
113
  case 'unpin':
105
114
  await this.telegram.unpinChatMessage(response.chatInfo.id, response.messageId);
106
- await this.storage.updateStateFor(response.action, response.chatInfo.id, async (state) => {
115
+ await this.storage.updateStateFor(response.action, response.chatInfo.id, (state) => {
107
116
  state.pinnedMessages = state.pinnedMessages.filter((x) => x != response.messageId);
108
117
  });
109
118
  break;
@@ -1,3 +1,2 @@
1
- import { MessageTypeValue } from './messageTypes';
2
- export type CommandTrigger = MessageTypeValue | string | RegExp;
1
+ export type CommandTrigger = string | RegExp;
3
2
  //# sourceMappingURL=commandTrigger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"commandTrigger.d.ts","sourceRoot":"","sources":["../../types/commandTrigger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG,MAAM,GAAG,MAAM,CAAC"}
1
+ {"version":3,"file":"commandTrigger.d.ts","sourceRoot":"","sources":["../../types/commandTrigger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC"}
@@ -10,7 +10,7 @@ export type CommandHandler<TActionState extends IActionState> = (
10
10
  /** Context of action executed in chat, in response to a message. */
11
11
  ctx: MessageContext<TActionState>,
12
12
  /** State of an action being executed. */
13
- state: TActionState) => Promise<void>;
13
+ state: TActionState) => Promise<void> | void;
14
14
  export type ScheduledHandler<TActionState extends IActionState> = (
15
15
  /** Context of action executed in chat. */
16
16
  ctx: ChatContext<TActionState>,
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../types/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,MAAM,kBAAkB,GAAG;AAC7B,0EAA0E;AAC1E,GAAG,EAAE,kBAAkB,KACtB,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,cAAc,CAAC,YAAY,SAAS,YAAY,IAAI;AAC5D,oEAAoE;AACpE,GAAG,EAAE,cAAc,CAAC,YAAY,CAAC;AACjC,yCAAyC;AACzC,KAAK,EAAE,YAAY,KAClB,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,gBAAgB,CAAC,YAAY,SAAS,YAAY,IAAI;AAC9D,0CAA0C;AAC1C,GAAG,EAAE,WAAW,CAAC,YAAY,CAAC;AAC9B,yIAAyI;AACzI,SAAS,EAAE,mBAAmB;AAC9B,yCAAyC;AACzC,KAAK,EAAE,YAAY,KAClB,OAAO,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../types/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,MAAM,kBAAkB,GAAG;AAC7B,0EAA0E;AAC1E,GAAG,EAAE,kBAAkB,KACtB,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,cAAc,CAAC,YAAY,SAAS,YAAY,IAAI;AAC5D,oEAAoE;AACpE,GAAG,EAAE,cAAc,CAAC,YAAY,CAAC;AACjC,yCAAyC;AACzC,KAAK,EAAE,YAAY,KAClB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAE1B,MAAM,MAAM,gBAAgB,CAAC,YAAY,SAAS,YAAY,IAAI;AAC9D,0CAA0C;AAC1C,GAAG,EAAE,WAAW,CAAC,YAAY,CAAC;AAC9B,yIAAyI;AACzI,SAAS,EAAE,mBAAmB;AAC9B,yCAAyC;AACzC,KAAK,EAAE,YAAY,KAClB,OAAO,CAAC,IAAI,CAAC,CAAC"}
@@ -2,12 +2,12 @@ import { TraceId } from './trace';
2
2
  export interface IScopedLogger {
3
3
  logObjectWithTraceId(data: any): void;
4
4
  logWithTraceId(text: string): void;
5
- errorWithTraceId<TData>(errorObj: unknown, extraData?: TData | undefined): void;
5
+ errorWithTraceId(errorObj: unknown, extraData?: unknown): void;
6
6
  }
7
7
  export interface ILogger {
8
8
  createScope(botName: string, traceId: TraceId, chatName: string): IScopedLogger;
9
9
  logObjectWithTraceId(botName: string, traceId: TraceId, chatName: string, data: any): void;
10
10
  logWithTraceId(botName: string, traceId: TraceId, chatName: string, text: string): void;
11
- errorWithTraceId<TData>(botName: string, traceId: TraceId, chatName: string, errorObj: unknown, extraData?: TData | undefined): void;
11
+ errorWithTraceId(botName: string, traceId: TraceId, chatName: string, errorObj: unknown, extraData?: unknown): void;
12
12
  }
13
13
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../types/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,WAAW,aAAa;IAC1B,oBAAoB,CAEhB,IAAI,EAAE,GAAG,GACV,IAAI,CAAC;IAER,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnC,gBAAgB,CAAC,KAAK,EAClB,QAAQ,EAAE,OAAO,EACjB,SAAS,CAAC,EAAE,KAAK,GAAG,SAAS,GAC9B,IAAI,CAAC;CACX;AAED,MAAM,WAAW,OAAO;IACpB,WAAW,CACP,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,GACjB,aAAa,CAAC;IAEjB,oBAAoB,CAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAEhB,IAAI,EAAE,GAAG,GACV,IAAI,CAAC;IAER,cAAc,CACV,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACb,IAAI,CAAC;IAER,gBAAgB,CAAC,KAAK,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,OAAO,EACjB,SAAS,CAAC,EAAE,KAAK,GAAG,SAAS,GAC9B,IAAI,CAAC;CACX"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../types/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,WAAW,aAAa;IAC1B,oBAAoB,CAEhB,IAAI,EAAE,GAAG,GACV,IAAI,CAAC;IAER,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAClE;AAED,MAAM,WAAW,OAAO;IACpB,WAAW,CACP,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,GACjB,aAAa,CAAC;IAEjB,oBAAoB,CAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAEhB,IAAI,EAAE,GAAG,GACV,IAAI,CAAC;IAER,cAAc,CACV,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACb,IAAI,CAAC;IAER,gBAAgB,CACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,OAAO,EACjB,SAAS,CAAC,EAAE,OAAO,GACpB,IAAI,CAAC;CACX"}
@@ -1,7 +1,7 @@
1
1
  import { Milliseconds } from './timeValues';
2
2
  export interface IScheduler {
3
3
  stopAll(): void;
4
- createTask(name: string, action: () => void, interval: Milliseconds, executeRightAway: boolean, ownerName: string): void;
5
- createOnetimeTask(name: string, action: () => void, delay: Milliseconds, ownerName: string): void;
4
+ createTask(name: string, action: () => unknown, interval: Milliseconds, executeRightAway: boolean, ownerName: string): void;
5
+ createOnetimeTask(name: string, action: () => unknown, delay: Milliseconds, ownerName: string): void;
6
6
  }
7
7
  //# sourceMappingURL=scheduler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../types/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,WAAW,UAAU;IACvB,OAAO,IAAI,IAAI,CAAC;IAEhB,UAAU,CACN,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,IAAI,EAClB,QAAQ,EAAE,YAAY,EACtB,gBAAgB,EAAE,OAAO,EACzB,SAAS,EAAE,MAAM,GAClB,IAAI,CAAC;IAER,iBAAiB,CACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,IAAI,EAClB,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,GAClB,IAAI,CAAC;CACX"}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../types/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,WAAW,UAAU;IACvB,OAAO,IAAI,IAAI,CAAC;IAEhB,UAAU,CACN,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,OAAO,EACrB,QAAQ,EAAE,YAAY,EACtB,gBAAgB,EAAE,OAAO,EACzB,SAAS,EAAE,MAAM,GAClB,IAAI,CAAC;IAER,iBAAiB,CACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,OAAO,EACrB,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,GAClB,IAAI,CAAC;CACX"}
@@ -1,9 +1,9 @@
1
1
  import { IActionState } from './actionState';
2
2
  import { ActionKey, IActionWithState } from './action';
3
3
  export interface IStorageClient {
4
- updateStateFor<TActionState extends IActionState>(action: IActionWithState<TActionState>, chatId: number, update: (state: TActionState) => Promise<void>): Promise<void>;
4
+ updateStateFor<TActionState extends IActionState>(action: IActionWithState<TActionState>, chatId: number, update: (state: TActionState) => Promise<void> | void): Promise<void>;
5
5
  close(): Promise<void>;
6
- load<TActionState extends IActionState>(key: ActionKey): Promise<Record<number, TActionState>>;
6
+ load<TActionState extends IActionState>(key: ActionKey): Promise<Record<number, TActionState | undefined>>;
7
7
  saveMetadata<TActionState extends IActionState>(actions: IActionWithState<TActionState>[]): Promise<void>;
8
8
  getActionState<TActionState extends IActionState>(action: IActionWithState<TActionState>, chatId: number): Promise<TActionState>;
9
9
  saveActionExecutionResult<TActionState extends IActionState>(action: IActionWithState<TActionState>, chatId: number, state: TActionState): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../types/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC3B,cAAc,CAAC,YAAY,SAAS,YAAY,EAC5C,MAAM,EAAE,gBAAgB,CAAC,YAAY,CAAC,EACtC,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,YAAY,SAAS,YAAY,EAC1C,OAAO,EAAE,gBAAgB,CAAC,YAAY,CAAC,EAAE,GAC1C,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,cAAc,CAAC,YAAY,SAAS,YAAY,EAC5C,MAAM,EAAE,gBAAgB,CAAC,YAAY,CAAC,EACtC,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CAAC;IACzB,yBAAyB,CAAC,YAAY,SAAS,YAAY,EACvD,MAAM,EAAE,gBAAgB,CAAC,YAAY,CAAC,EACtC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../types/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC3B,cAAc,CAAC,YAAY,SAAS,YAAY,EAC5C,MAAM,EAAE,gBAAgB,CAAC,YAAY,CAAC,EACtC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GACtD,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,GAAG,SAAS,CAAC,CAAC,CAAC;IACrD,YAAY,CAAC,YAAY,SAAS,YAAY,EAC1C,OAAO,EAAE,gBAAgB,CAAC,YAAY,CAAC,EAAE,GAC1C,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,cAAc,CAAC,YAAY,SAAS,YAAY,EAC5C,MAAM,EAAE,gBAAgB,CAAC,YAAY,CAAC,EACtC,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CAAC;IACzB,yBAAyB,CAAC,YAAY,SAAS,YAAY,EACvD,MAAM,EAAE,gBAAgB,CAAC,YAAY,CAAC,EACtC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB"}
@@ -2,13 +2,13 @@ declare const millisecondsSymbol: unique symbol;
2
2
  declare const secondsSymbol: unique symbol;
3
3
  declare const hoursSymbol: unique symbol;
4
4
  export type Milliseconds = number & {
5
- [millisecondsSymbol]: void;
5
+ [millisecondsSymbol]: never;
6
6
  };
7
7
  export type Seconds = number & {
8
- [secondsSymbol]: void;
8
+ [secondsSymbol]: never;
9
9
  };
10
10
  export type Hours = number & {
11
- [hoursSymbol]: void;
11
+ [hoursSymbol]: never;
12
12
  };
13
13
  export type HoursOfDay = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23;
14
14
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"timeValues.d.ts","sourceRoot":"","sources":["../../types/timeValues.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,MAAM,CAAC;AAChD,OAAO,CAAC,MAAM,aAAa,EAAE,OAAO,MAAM,CAAC;AAC3C,OAAO,CAAC,MAAM,WAAW,EAAE,OAAO,MAAM,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG;IAAE,CAAC,kBAAkB,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AACnE,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG;IAAE,CAAC,aAAa,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AACzD,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG;IAAE,CAAC,WAAW,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAErD,MAAM,MAAM,UAAU,GAChB,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,CAAC"}
1
+ {"version":3,"file":"timeValues.d.ts","sourceRoot":"","sources":["../../types/timeValues.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,MAAM,CAAC;AAChD,OAAO,CAAC,MAAM,aAAa,EAAE,OAAO,MAAM,CAAC;AAC3C,OAAO,CAAC,MAAM,WAAW,EAAE,OAAO,MAAM,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG;IAAE,CAAC,kBAAkB,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AACpE,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG;IAAE,CAAC,aAAa,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAC1D,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG;IAAE,CAAC,WAAW,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAEtD,MAAM,MAAM,UAAU,GAChB,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,GACF,EAAE,CAAC"}
@@ -1,6 +1,6 @@
1
1
  declare const traceSymbol: unique symbol;
2
2
  export type TraceId = `${string}:${string}-${string}` & {
3
- [traceSymbol]: void;
3
+ [traceSymbol]: never;
4
4
  };
5
5
  export {};
6
6
  //# sourceMappingURL=trace.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../types/trace.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,WAAW,EAAE,OAAO,MAAM,CAAC;AAEzC,MAAM,MAAM,OAAO,GAAG,GAAG,MAAM,IAAI,MAAM,IAAI,MAAM,EAAE,GAAG;IAAE,CAAC,WAAW,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../types/trace.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,WAAW,EAAE,OAAO,MAAM,CAAC;AAEzC,MAAM,MAAM,OAAO,GAAG,GAAG,MAAM,IAAI,MAAM,IAAI,MAAM,EAAE,GAAG;IACpD,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC;CACxB,CAAC"}
@@ -61,7 +61,7 @@ export class IncomingMessage {
61
61
  this.chatInfo = new ChatInfo(
62
62
  ctxMessage.chat.id,
63
63
  'title' in ctxMessage.chat
64
- ? ctxMessage.chat.title + ' ' + ctxMessage.chat.id
64
+ ? `${ctxMessage.chat.title} ${ctxMessage.chat.id}`
65
65
  : 'DM'
66
66
  );
67
67
  this.type = this.detectMessageType(ctxMessage);
@@ -11,10 +11,14 @@ import { MessageContext } from '../context/messageContext';
11
11
  import { CommandTrigger } from '../../types/commandTrigger';
12
12
  import { Noop } from '../../helpers/noop';
13
13
  import { MessageType } from '../../types/messageTypes';
14
+ import { Sema as Semaphore } from 'async-sema';
15
+ import { getOrSetIfNotExists } from '../../helpers/mapUtils';
14
16
 
15
17
  export class CommandAction<TActionState extends IActionState>
16
18
  implements IActionWithState<TActionState>
17
19
  {
20
+ readonly ratelimitSemaphores = new Map<number, Semaphore>();
21
+
18
22
  readonly triggers: CommandTrigger[];
19
23
  readonly handler: CommandHandler<TActionState>;
20
24
  readonly name: string;
@@ -26,6 +30,7 @@ export class CommandAction<TActionState extends IActionState>
26
30
  readonly stateConstructor: () => TActionState;
27
31
  readonly key: ActionKey;
28
32
  readonly readmeFactory: (botName: string) => string;
33
+ readonly maxAllowedSimultaniousExecutions: number;
29
34
 
30
35
  constructor(
31
36
  trigger: CommandTrigger | CommandTrigger[],
@@ -35,6 +40,7 @@ export class CommandAction<TActionState extends IActionState>
35
40
  cooldown: Seconds,
36
41
  chatsBlacklist: number[],
37
42
  allowedUsers: number[],
43
+ maxAllowedSimultaniousExecutions: number,
38
44
  condition: CommandCondition<TActionState>,
39
45
  stateConstructor: () => TActionState,
40
46
  readmeFactory: (botName: string) => string
@@ -49,6 +55,8 @@ export class CommandAction<TActionState extends IActionState>
49
55
  this.condition = condition;
50
56
  this.stateConstructor = stateConstructor;
51
57
  this.readmeFactory = readmeFactory;
58
+ this.maxAllowedSimultaniousExecutions =
59
+ maxAllowedSimultaniousExecutions;
52
60
 
53
61
  this.key = `command:${this.name.replace('.', '-')}` as ActionKey;
54
62
  }
@@ -62,42 +70,57 @@ export class CommandAction<TActionState extends IActionState>
62
70
  if (!this.active || this.chatsBlacklist.includes(ctx.chatInfo.id))
63
71
  return Noop.NoResponse;
64
72
 
65
- const state = await ctx.storage.getActionState<TActionState>(
66
- this,
67
- ctx.chatInfo.id
68
- );
73
+ let lock: Semaphore | undefined;
74
+ if (this.maxAllowedSimultaniousExecutions != 0) {
75
+ lock = getOrSetIfNotExists(
76
+ this.ratelimitSemaphores,
77
+ ctx.chatInfo.id,
78
+ new Semaphore(this.maxAllowedSimultaniousExecutions)
79
+ );
80
+
81
+ await lock.acquire();
82
+ }
69
83
 
70
- const { shouldExecute, matchResults, skipCooldown } = this.triggers
71
- .map((x) => this.checkIfShouldBeExecuted(ctx, x, state))
72
- .reduce(
73
- (acc, curr) => acc.mergeWith(curr),
74
- CommandTriggerCheckResult.DoNotTrigger
84
+ try {
85
+ const state = await ctx.storage.getActionState<TActionState>(
86
+ this,
87
+ ctx.chatInfo.id
75
88
  );
76
89
 
77
- if (!shouldExecute) return Noop.NoResponse;
90
+ const { shouldExecute, matchResults, skipCooldown } = this.triggers
91
+ .map((x) => this.checkIfShouldBeExecuted(ctx, x, state))
92
+ .reduce(
93
+ (acc, curr) => acc.mergeWith(curr),
94
+ CommandTriggerCheckResult.DoNotTrigger
95
+ );
78
96
 
79
- ctx.logger.logWithTraceId(
80
- ` - Executing [${this.name}] in ${ctx.chatInfo.id}`
81
- );
82
- ctx.matchResults = matchResults;
97
+ if (!shouldExecute) return Noop.NoResponse;
83
98
 
84
- await this.handler(ctx, state);
99
+ ctx.logger.logWithTraceId(
100
+ ` - Executing [${this.name}] in ${ctx.chatInfo.id}`
101
+ );
102
+ ctx.matchResults = matchResults;
85
103
 
86
- if (skipCooldown) {
87
- ctx.startCooldown = false;
88
- }
104
+ await this.handler(ctx, state);
89
105
 
90
- if (ctx.startCooldown) {
91
- state.lastExecutedDate = moment().valueOf();
92
- }
106
+ if (skipCooldown) {
107
+ ctx.startCooldown = false;
108
+ }
93
109
 
94
- await ctx.storage.saveActionExecutionResult(
95
- this,
96
- ctx.chatInfo.id,
97
- state
98
- );
110
+ if (ctx.startCooldown) {
111
+ state.lastExecutedDate = moment().valueOf();
112
+ }
113
+
114
+ await ctx.storage.saveActionExecutionResult(
115
+ this,
116
+ ctx.chatInfo.id,
117
+ state
118
+ );
99
119
 
100
- return ctx.responses;
120
+ return ctx.responses;
121
+ } finally {
122
+ lock?.release();
123
+ }
101
124
  }
102
125
 
103
126
  private checkIfShouldBeExecuted(
@@ -149,13 +172,17 @@ export class CommandAction<TActionState extends IActionState>
149
172
 
150
173
  const execResult = trigger.exec(ctx.messageText);
151
174
  if (execResult != null) {
175
+ let regexMatchLimit = 100;
152
176
  matchResults.push(execResult);
153
177
 
154
178
  if (trigger.global) {
155
- while (true) {
179
+ while (regexMatchLimit > 0) {
156
180
  const nextResult = trigger.exec(ctx.messageText);
181
+
157
182
  if (nextResult == null) break;
183
+
158
184
  matchResults.push(nextResult);
185
+ regexMatchLimit -= 1;
159
186
  }
160
187
  }
161
188
  }
@@ -38,13 +38,17 @@ export class InlineQueryAction implements IAction {
38
38
 
39
39
  const execResult = this.pattern.exec(ctx.queryText);
40
40
  if (execResult != null) {
41
+ let regexMatchLimit = 100;
41
42
  matchResults.push(execResult);
42
43
 
43
44
  if (this.pattern.global) {
44
- while (true) {
45
+ while (regexMatchLimit > 0) {
45
46
  const nextResult = this.pattern.exec(ctx.queryText);
47
+
46
48
  if (nextResult == null) break;
49
+
47
50
  matchResults.push(nextResult);
51
+ regexMatchLimit -= 1;
48
52
  }
49
53
  }
50
54
  }
@@ -81,13 +81,17 @@ export class ReplyCaptureAction<TParentActionState extends IActionState>
81
81
 
82
82
  const execResult = trigger.exec(ctx.messageText);
83
83
  if (execResult != null) {
84
+ let regexMatchLimit = 100;
84
85
  matchResults.push(execResult);
85
86
 
86
87
  if (trigger.global) {
87
- while (true) {
88
+ while (regexMatchLimit > 0) {
88
89
  const nextResult = trigger.exec(ctx.messageText);
90
+
89
91
  if (nextResult == null) break;
92
+
90
93
  matchResults.push(nextResult);
94
+ regexMatchLimit -= 1;
91
95
  }
92
96
  }
93
97
  }
@@ -9,6 +9,7 @@ import { CachedStateFactory } from '../cachedStateFactory';
9
9
  import { ChatContext } from '../context/chatContext';
10
10
  import { Noop } from '../../helpers/noop';
11
11
  import { IScheduler } from '../../types/scheduler';
12
+ import { getOrSetIfNotExists, getOrThrow } from '../../helpers/mapUtils';
12
13
 
13
14
  export class ScheduledAction<TActionState extends IActionState>
14
15
  implements IActionWithState<TActionState>
@@ -89,20 +90,18 @@ export class ScheduledAction<TActionState extends IActionState>
89
90
  botName: string,
90
91
  scheduler: IScheduler
91
92
  ): Promise<TResult> {
92
- if (!this.cachedStateFactories.has(key)) {
93
- throw new Error(
94
- `No shared cache was set up for the key [${key}] in action '${this.name}'`
95
- );
96
- }
93
+ const cachedItemFactory = getOrThrow(
94
+ this.cachedStateFactories,
95
+ key,
96
+ `No shared cache was set up for the key [${key}] in action '${this.name}'`
97
+ );
97
98
 
98
99
  const semaphoreKey = `${this.key}_cached:${key}`;
99
- let semaphore: Semaphore;
100
- if (ScheduledAction.locks.has(semaphoreKey)) {
101
- semaphore = ScheduledAction.locks.get(semaphoreKey)!;
102
- } else {
103
- semaphore = new Semaphore(1);
104
- ScheduledAction.locks.set(semaphoreKey, semaphore);
105
- }
100
+ const semaphore = getOrSetIfNotExists(
101
+ ScheduledAction.locks,
102
+ semaphoreKey,
103
+ new Semaphore(1)
104
+ );
106
105
 
107
106
  await semaphore.acquire();
108
107
 
@@ -111,7 +110,6 @@ export class ScheduledAction<TActionState extends IActionState>
111
110
  return this.cachedState.get(key) as TResult;
112
111
  }
113
112
 
114
- const cachedItemFactory = this.cachedStateFactories.get(key)!;
115
113
  const value = await cachedItemFactory.getValue();
116
114
 
117
115
  this.cachedState.set(key, value);
@@ -68,19 +68,19 @@ export class BotInstance {
68
68
  scheduledPeriod?: Seconds,
69
69
  verboseLoggingForIncomingMessage?: boolean
70
70
  ) {
71
- this.actionProcessingService.initialize(
72
- token,
73
- actions,
74
- scheduledPeriod,
75
- verboseLoggingForIncomingMessage
76
- );
77
-
78
71
  this.logger.logWithTraceId(
79
72
  this.name,
80
73
  createTrace(this, this.name, 'Start'),
81
74
  'System',
82
75
  'Starting bot...'
83
76
  );
77
+
78
+ await this.actionProcessingService.initialize(
79
+ token,
80
+ actions,
81
+ scheduledPeriod,
82
+ verboseLoggingForIncomingMessage
83
+ );
84
84
  }
85
85
 
86
86
  async stop(code: string) {
@@ -1,5 +1,4 @@
1
1
  import { resolve } from 'path';
2
- import { IStorageClient } from '../../types/storage';
3
2
  import { ImageMessage } from '../../dtos/responses/imageMessage';
4
3
  import { TextMessage } from '../../dtos/responses/textMessage';
5
4
  import { VideoMessage } from '../../dtos/responses/videoMessage';
@@ -13,7 +12,6 @@ import { IActionState } from '../../types/actionState';
13
12
  import { IReplyResponse } from '../../types/response';
14
13
  import { Milliseconds } from '../../types/timeValues';
15
14
  import { DelayResponse } from '../../dtos/responses/delay';
16
- import { IScheduler } from '../../types/scheduler';
17
15
  import { ICaptureController } from '../../types/capture';
18
16
  import { CommandTrigger } from '../../types/commandTrigger';
19
17
  import { ReplyContext } from './replyContext';
@@ -27,10 +25,6 @@ export class ChatContext<
27
25
  TActionState extends IActionState,
28
26
  TAction extends IActionWithState<TActionState> = ScheduledAction<TActionState>
29
27
  > extends BaseContext<TAction> {
30
- constructor(storage: IStorageClient, scheduler: IScheduler) {
31
- super(storage, scheduler);
32
- }
33
-
34
28
  protected createCaptureController(
35
29
  response: IReplyResponse
36
30
  ): ICaptureController {
@@ -1,7 +1,5 @@
1
1
  import { InlineQueryResult } from 'telegraf/types';
2
2
  import { BotResponse } from '../../types/response';
3
- import { IScheduler } from '../../types/scheduler';
4
- import { IStorageClient } from '../../types/storage';
5
3
  import { InlineQueryAction } from '../actions/inlineQueryAction';
6
4
  import { InlineQueryResponse } from '../../dtos/responses/inlineQueryResponse';
7
5
  import { BaseContext } from './baseContext';
@@ -32,10 +30,6 @@ export class InlineQueryContext extends BaseContext<InlineQueryAction> {
32
30
  /** Collection of Regexp match results on a message that triggered this action. Will be empty if trigger is not a Regexp. */
33
31
  matchResults: RegExpMatchArray[] = [];
34
32
 
35
- constructor(storage: IStorageClient, scheduler: IScheduler) {
36
- super(storage, scheduler);
37
- }
38
-
39
33
  /**
40
34
  * This result will be shown to user as a response to inline query.
41
35
  * @param queryResult Inline query result to be shown to user.
@@ -1,6 +1,5 @@
1
1
  import { resolve } from 'path';
2
2
  import { TelegramEmoji } from 'telegraf/types';
3
- import { IStorageClient } from '../../types/storage';
4
3
  import { IActionState } from '../../types/actionState';
5
4
  import { ImageMessage } from '../../dtos/responses/imageMessage';
6
5
  import { Reaction } from '../../dtos/responses/reaction';
@@ -15,7 +14,6 @@ import {
15
14
  MessageTypeValue,
16
15
  TelegrafContextMessage
17
16
  } from '../../types/messageTypes';
18
- import { IScheduler } from '../../types/scheduler';
19
17
  import { ReplyInfo } from '../../dtos/replyInfo';
20
18
  import { CommandAction } from '../actions/commandAction';
21
19
 
@@ -42,10 +40,6 @@ export class MessageContext<
42
40
  /** Message object recieved from Telegram */
43
41
  messageUpdateObject!: TelegrafContextMessage;
44
42
 
45
- constructor(storage: IStorageClient, scheduler: IScheduler) {
46
- super(storage, scheduler);
47
- }
48
-
49
43
  private getQuotePart(quote: boolean | string) {
50
44
  return typeof quote == 'boolean'
51
45
  ? this.matchResults.length != 0