chz-telegram-bot 0.2.1 → 0.3.1

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 (123) hide show
  1. package/dist/dtos/commandTriggerCheckResult.d.ts +1 -0
  2. package/dist/dtos/commandTriggerCheckResult.d.ts.map +1 -1
  3. package/dist/dtos/commandTriggerCheckResult.js +3 -0
  4. package/dist/dtos/incomingMessage.d.ts +2 -1
  5. package/dist/dtos/incomingMessage.d.ts.map +1 -1
  6. package/dist/dtos/incomingMessage.js +5 -1
  7. package/dist/dtos/incomingQuery.d.ts +1 -0
  8. package/dist/dtos/incomingQuery.d.ts.map +1 -1
  9. package/dist/dtos/incomingQuery.js +1 -0
  10. package/dist/dtos/replyInfo.d.ts.map +1 -0
  11. package/dist/dtos/responses/delay.d.ts +1 -1
  12. package/dist/dtos/responses/delay.d.ts.map +1 -1
  13. package/dist/dtos/responses/imageMessage.d.ts +8 -7
  14. package/dist/dtos/responses/imageMessage.d.ts.map +1 -1
  15. package/dist/dtos/responses/imageMessage.js +1 -0
  16. package/dist/dtos/responses/reaction.d.ts +3 -4
  17. package/dist/dtos/responses/reaction.d.ts.map +1 -1
  18. package/dist/dtos/responses/textMessage.d.ts +8 -7
  19. package/dist/dtos/responses/textMessage.d.ts.map +1 -1
  20. package/dist/dtos/responses/textMessage.js +1 -0
  21. package/dist/dtos/responses/unpin.d.ts +1 -1
  22. package/dist/dtos/responses/unpin.d.ts.map +1 -1
  23. package/dist/dtos/responses/videoMessage.d.ts +8 -7
  24. package/dist/dtos/responses/videoMessage.d.ts.map +1 -1
  25. package/dist/dtos/responses/videoMessage.js +1 -0
  26. package/dist/entities/actions/commandAction.d.ts +1 -1
  27. package/dist/entities/actions/commandAction.d.ts.map +1 -1
  28. package/dist/entities/actions/commandAction.js +7 -12
  29. package/dist/entities/actions/inlineQueryAction.d.ts +2 -3
  30. package/dist/entities/actions/inlineQueryAction.d.ts.map +1 -1
  31. package/dist/entities/actions/replyCaptureAction.d.ts +15 -0
  32. package/dist/entities/actions/replyCaptureAction.d.ts.map +1 -0
  33. package/dist/entities/actions/replyCaptureAction.js +56 -0
  34. package/dist/entities/actions/scheduledAction.d.ts +1 -1
  35. package/dist/entities/actions/scheduledAction.d.ts.map +1 -1
  36. package/dist/entities/botInstance.d.ts +7 -36
  37. package/dist/entities/botInstance.d.ts.map +1 -1
  38. package/dist/entities/botInstance.js +5 -162
  39. package/dist/entities/context/chatContext.d.ts +7 -5
  40. package/dist/entities/context/chatContext.d.ts.map +1 -1
  41. package/dist/entities/context/chatContext.js +21 -3
  42. package/dist/entities/context/inlineQueryContext.d.ts +7 -3
  43. package/dist/entities/context/inlineQueryContext.d.ts.map +1 -1
  44. package/dist/entities/context/inlineQueryContext.js +0 -11
  45. package/dist/entities/context/messageContext.d.ts +6 -6
  46. package/dist/entities/context/messageContext.d.ts.map +1 -1
  47. package/dist/entities/context/messageContext.js +10 -4
  48. package/dist/entities/context/replyContext.d.ts +113 -0
  49. package/dist/entities/context/replyContext.d.ts.map +1 -0
  50. package/dist/entities/context/replyContext.js +108 -0
  51. package/dist/main.d.ts.map +1 -1
  52. package/dist/main.js +5 -9
  53. package/dist/services/actionProcessingService.d.ts +25 -0
  54. package/dist/services/actionProcessingService.d.ts.map +1 -0
  55. package/dist/services/actionProcessingService.js +40 -0
  56. package/dist/services/actionProcessors/commandActionProcessor.d.ts +28 -0
  57. package/dist/services/actionProcessors/commandActionProcessor.d.ts.map +1 -0
  58. package/dist/services/actionProcessors/commandActionProcessor.js +116 -0
  59. package/dist/services/actionProcessors/inlineQueryActionProcessor.d.ts +20 -0
  60. package/dist/services/actionProcessors/inlineQueryActionProcessor.d.ts.map +1 -0
  61. package/dist/services/actionProcessors/inlineQueryActionProcessor.js +74 -0
  62. package/dist/services/actionProcessors/scheduledActionProcessor.d.ts +21 -0
  63. package/dist/services/actionProcessors/scheduledActionProcessor.d.ts.map +1 -0
  64. package/dist/services/actionProcessors/scheduledActionProcessor.js +69 -0
  65. package/dist/services/jsonFileStorage.d.ts +1 -1
  66. package/dist/services/jsonFileStorage.d.ts.map +1 -1
  67. package/dist/services/telegramApi.d.ts +5 -1
  68. package/dist/services/telegramApi.d.ts.map +1 -1
  69. package/dist/services/telegramApi.js +19 -23
  70. package/dist/types/{actionWithState.d.ts → action.d.ts} +5 -3
  71. package/dist/types/action.d.ts.map +1 -0
  72. package/dist/types/capture.d.ts +14 -0
  73. package/dist/types/capture.d.ts.map +1 -0
  74. package/dist/types/commandCondition.d.ts +1 -1
  75. package/dist/types/commandCondition.d.ts.map +1 -1
  76. package/dist/types/response.d.ts +9 -6
  77. package/dist/types/response.d.ts.map +1 -1
  78. package/dist/types/storage.d.ts +1 -1
  79. package/dist/types/storage.d.ts.map +1 -1
  80. package/dtos/commandTriggerCheckResult.ts +3 -0
  81. package/dtos/incomingMessage.ts +7 -2
  82. package/dtos/incomingQuery.ts +2 -0
  83. package/dtos/responses/delay.ts +1 -1
  84. package/dtos/responses/imageMessage.ts +11 -7
  85. package/dtos/responses/reaction.ts +3 -4
  86. package/dtos/responses/textMessage.ts +11 -7
  87. package/dtos/responses/unpin.ts +1 -1
  88. package/dtos/responses/videoMessage.ts +11 -7
  89. package/entities/actions/commandAction.ts +13 -20
  90. package/entities/actions/inlineQueryAction.ts +2 -3
  91. package/entities/actions/replyCaptureAction.ts +104 -0
  92. package/entities/actions/scheduledAction.ts +1 -1
  93. package/entities/botInstance.ts +19 -347
  94. package/entities/context/chatContext.ts +59 -29
  95. package/entities/context/inlineQueryContext.ts +7 -22
  96. package/entities/context/messageContext.ts +36 -29
  97. package/entities/context/replyContext.ts +225 -0
  98. package/main.ts +11 -10
  99. package/package.json +1 -1
  100. package/services/actionProcessingService.ts +123 -0
  101. package/services/actionProcessors/commandActionProcessor.ts +242 -0
  102. package/services/actionProcessors/inlineQueryActionProcessor.ts +176 -0
  103. package/services/actionProcessors/scheduledActionProcessor.ts +145 -0
  104. package/services/jsonFileStorage.ts +1 -1
  105. package/services/telegramApi.ts +45 -31
  106. package/types/{statefulAction.ts → action.ts} +6 -2
  107. package/types/capture.ts +21 -0
  108. package/types/commandCondition.ts +2 -1
  109. package/types/response.ts +10 -6
  110. package/types/storage.ts +1 -1
  111. package/dist/types/actionWithState.d.ts.map +0 -1
  112. package/dist/types/replyInfo.d.ts.map +0 -1
  113. package/dist/types/statefulAction.d.ts +0 -9
  114. package/dist/types/statefulAction.d.ts.map +0 -1
  115. package/dist/types/statelessAction.d.ts +0 -5
  116. package/dist/types/statelessAction.d.ts.map +0 -1
  117. package/dist/types/statelessAction.js +0 -2
  118. package/types/statelessAction.ts +0 -5
  119. /package/dist/{types → dtos}/replyInfo.d.ts +0 -0
  120. /package/dist/{types → dtos}/replyInfo.js +0 -0
  121. /package/dist/types/{actionWithState.js → action.js} +0 -0
  122. /package/dist/types/{statefulAction.js → capture.js} +0 -0
  123. /package/{types → dtos}/replyInfo.ts +0 -0
@@ -3,12 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TelegramApiService = void 0;
4
4
  const responseProcessingQueue_1 = require("./responseProcessingQueue");
5
5
  class TelegramApiService {
6
- constructor(botName, telegram, storage, logger) {
6
+ constructor(botName, telegram, storage, logger, captureRegistrationCallback) {
7
7
  this.queue = new responseProcessingQueue_1.ResponseProcessingQueue();
8
8
  this.telegram = telegram;
9
9
  this.botName = botName;
10
10
  this.storage = storage;
11
11
  this.logger = logger;
12
+ this.captureRegistrationCallback = captureRegistrationCallback;
12
13
  }
13
14
  enqueueBatchedResponses(responses) {
14
15
  let offset = 0;
@@ -45,7 +46,7 @@ class TelegramApiService {
45
46
  }
46
47
  }
47
48
  async processResponse(response) {
48
- let sentMessage;
49
+ let sentMessage = null;
49
50
  switch (response.kind) {
50
51
  case 'text':
51
52
  sentMessage = await this.telegram.sendMessage(response.chatInfo.id, response.content, {
@@ -60,31 +61,20 @@ class TelegramApiService {
60
61
  is_disabled: response.disableWebPreview
61
62
  }
62
63
  });
63
- await this.pinIfShould(response, sentMessage);
64
64
  break;
65
65
  case 'image':
66
- sentMessage = await this.telegram.sendPhoto(response.chatInfo.id, response.content, {
67
- reply_parameters: response.replyInfo
68
- ? {
69
- message_id: response.replyInfo.id,
70
- quote: response.replyInfo.quote
71
- }
72
- : undefined,
73
- parse_mode: 'MarkdownV2'
74
- });
75
- await this.pinIfShould(response, sentMessage);
66
+ sentMessage = await this.telegram.sendPhoto(response.chatInfo.id, response.content, response.replyInfo?.id
67
+ ? {
68
+ reply_to_message_id: response.replyInfo?.id // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
+ }
70
+ : undefined);
76
71
  break;
77
72
  case 'video':
78
- sentMessage = await this.telegram.sendVideo(response.chatInfo.id, response.content, {
79
- reply_parameters: response.replyInfo
80
- ? {
81
- message_id: response.replyInfo.id,
82
- quote: response.replyInfo.quote
83
- }
84
- : undefined,
85
- parse_mode: 'MarkdownV2'
86
- });
87
- await this.pinIfShould(response, sentMessage);
73
+ sentMessage = await this.telegram.sendVideo(response.chatInfo.id, response.content, response.replyInfo?.id
74
+ ? {
75
+ reply_to_message_id: response.replyInfo?.id // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
+ }
77
+ : undefined);
88
78
  break;
89
79
  case 'react':
90
80
  await this.telegram.setMessageReaction(response.chatInfo.id, response.messageId, [
@@ -106,6 +96,12 @@ class TelegramApiService {
106
96
  case 'delay':
107
97
  break;
108
98
  }
99
+ if ('content' in response && sentMessage) {
100
+ await this.pinIfShould(response, sentMessage);
101
+ for (const capture of response.captures) {
102
+ this.captureRegistrationCallback(capture, sentMessage.message_id, response.chatInfo, response.traceId);
103
+ }
104
+ }
109
105
  }
110
106
  }
111
107
  exports.TelegramApiService = TelegramApiService;
@@ -2,8 +2,10 @@ import { IActionState } from './actionState';
2
2
  export type ActionKey = string & {
3
3
  __brand: 'actionKey';
4
4
  };
5
- export interface IActionWithState<TActionState extends IActionState> {
6
- readonly key: ActionKey;
5
+ export interface IActionWithState<TActionState extends IActionState> extends IAction {
7
6
  readonly stateConstructor: () => TActionState;
8
7
  }
9
- //# sourceMappingURL=actionWithState.d.ts.map
8
+ export interface IAction {
9
+ readonly key: ActionKey;
10
+ }
11
+ //# sourceMappingURL=action.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,14 @@
1
+ import { ReplyContext } from '../entities/context/replyContext';
2
+ import { IActionState } from './actionState';
3
+ import { CommandTrigger } from './commandTrigger';
4
+ import { IActionWithState } from './action';
5
+ export interface ICaptureController {
6
+ captureReplies: <TParentActionState extends IActionState>(trigger: CommandTrigger[], handler: (replyContext: ReplyContext<TParentActionState>) => Promise<void>, abortController: AbortController) => void;
7
+ }
8
+ export interface IReplyCapture {
9
+ trigger: CommandTrigger[];
10
+ handler: (replyContext: ReplyContext<IActionState>) => Promise<void>;
11
+ abortController: AbortController;
12
+ action: IActionWithState<IActionState>;
13
+ }
14
+ //# sourceMappingURL=capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../types/capture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,WAAW,kBAAkB;IAC/B,cAAc,EAAE,CAAC,kBAAkB,SAAS,YAAY,EACpD,OAAO,EAAE,cAAc,EAAE,EACzB,OAAO,EAAE,CACL,YAAY,EAAE,YAAY,CAAC,kBAAkB,CAAC,KAC7C,OAAO,CAAC,IAAI,CAAC,EAClB,eAAe,EAAE,eAAe,KAC/B,IAAI,CAAC;CACb;AAED,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,OAAO,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,YAAY,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,eAAe,EAAE,eAAe,CAAC;IACjC,MAAM,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;CAC1C"}
@@ -1,4 +1,4 @@
1
1
  import { MessageContext } from '../entities/context/messageContext';
2
2
  import { IActionState } from './actionState';
3
- export type CommandCondition<TActionState extends IActionState> = (ctx: MessageContext<TActionState>) => boolean;
3
+ export type CommandCondition<TActionState extends IActionState> = (ctx: MessageContext<TActionState>, state: TActionState) => boolean;
4
4
  //# sourceMappingURL=commandCondition.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"commandCondition.d.ts","sourceRoot":"","sources":["../../types/commandCondition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,MAAM,gBAAgB,CAAC,YAAY,SAAS,YAAY,IAAI,CAC9D,GAAG,EAAE,cAAc,CAAC,YAAY,CAAC,KAChC,OAAO,CAAC"}
1
+ {"version":3,"file":"commandCondition.d.ts","sourceRoot":"","sources":["../../types/commandCondition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,MAAM,gBAAgB,CAAC,YAAY,SAAS,YAAY,IAAI,CAC9D,GAAG,EAAE,cAAc,CAAC,YAAY,CAAC,EACjC,KAAK,EAAE,YAAY,KAClB,OAAO,CAAC"}
@@ -6,10 +6,10 @@ import { Reaction } from '../dtos/responses/reaction';
6
6
  import { TextMessage } from '../dtos/responses/textMessage';
7
7
  import { UnpinResponse } from '../dtos/responses/unpin';
8
8
  import { VideoMessage } from '../dtos/responses/videoMessage';
9
- import { IActionState } from './actionState';
10
- import { ReplyInfo } from './replyInfo';
11
- import { IActionWithState } from './statefulAction';
9
+ import { IReplyCapture } from './capture';
10
+ import { ReplyInfo } from '../dtos/replyInfo';
12
11
  import { TraceId } from './trace';
12
+ import { IAction } from './action';
13
13
  export declare const BotResponseTypes: {
14
14
  readonly unpin: "unpin";
15
15
  readonly text: "text";
@@ -25,12 +25,15 @@ export interface IChatResponse {
25
25
  readonly chatInfo: ChatInfo;
26
26
  readonly traceId: TraceId;
27
27
  readonly createdAt: number;
28
- readonly action: IActionWithState<IActionState>;
28
+ readonly action: IAction;
29
29
  }
30
- export interface IReplyResponse<TType> extends IChatResponse {
31
- readonly content: TType;
30
+ export interface IReplyResponse extends IChatResponse {
31
+ readonly captures: IReplyCapture[];
32
32
  readonly replyInfo: ReplyInfo | undefined;
33
33
  readonly disableWebPreview: boolean;
34
34
  readonly shouldPin: boolean;
35
35
  }
36
+ export interface IReplyResponseWithContent<TType> extends IReplyResponse {
37
+ readonly content: TType;
38
+ }
36
39
  //# sourceMappingURL=response.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../types/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,eAAO,MAAM,gBAAgB;;;;;;;;CAQnB,CAAC;AAEX,MAAM,MAAM,WAAW,GACjB,aAAa,GACb,QAAQ,GACR,WAAW,GACX,YAAY,GACZ,aAAa,GACb,mBAAmB,GACnB,YAAY,CAAC;AAEnB,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,gBAAgB,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,cAAc,CAAC,KAAK,CAAE,SAAQ,aAAa;IACxD,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC/B"}
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../types/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,eAAO,MAAM,gBAAgB;;;;;;;;CAQnB,CAAC;AAEX,MAAM,MAAM,WAAW,GACjB,aAAa,GACb,QAAQ,GACR,WAAW,GACX,YAAY,GACZ,aAAa,GACb,mBAAmB,GACnB,YAAY,CAAC;AAEnB,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,gBAAgB,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,cAAe,SAAQ,aAAa;IACjD,QAAQ,CAAC,QAAQ,EAAE,aAAa,EAAE,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,yBAAyB,CAAC,KAAK,CAAE,SAAQ,cAAc;IACpE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;CAC3B"}
@@ -1,5 +1,5 @@
1
1
  import { IActionState } from './actionState';
2
- import { ActionKey, IActionWithState } from './statefulAction';
2
+ import { ActionKey, IActionWithState } from './action';
3
3
  export interface IStorageClient {
4
4
  updateStateFor<TActionState extends IActionState>(action: IActionWithState<TActionState>, chatId: number, update: (state: TActionState) => Promise<void>): Promise<void>;
5
5
  close(): 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,kBAAkB,CAAC;AAE/D,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,EACzC,OAAO,EAAE,MAAM,GAChB,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,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,EACzC,OAAO,EAAE,MAAM,GAChB,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"}
@@ -5,6 +5,9 @@ export class CommandTriggerCheckResult {
5
5
  static get DoNotTrigger() {
6
6
  return new CommandTriggerCheckResult(false, [], false);
7
7
  }
8
+ static get Trigger() {
9
+ return new CommandTriggerCheckResult(true, [], false);
10
+ }
8
11
 
9
12
  readonly shouldExecute: boolean;
10
13
  readonly matchResults: RegExpExecArray[];
@@ -10,12 +10,13 @@ import { createTrace } from '../helpers/traceFactory';
10
10
  import { TraceId } from '../types/trace';
11
11
 
12
12
  export class IncomingMessage {
13
- readonly message_id: number;
13
+ readonly messageId: number;
14
14
  readonly chatInfo: ChatInfo;
15
15
  readonly from: User | undefined;
16
16
  readonly text: string;
17
17
  readonly type: MessageTypeValue;
18
18
  readonly traceId: TraceId;
19
+ readonly replyToMessageId: number | undefined;
19
20
 
20
21
  readonly updateObject: TelegrafContextMessage;
21
22
 
@@ -44,7 +45,11 @@ export class IncomingMessage {
44
45
  botName,
45
46
  randomInt(10000, 99999).toString()
46
47
  );
47
- this.message_id = ctxMessage.message_id;
48
+ this.messageId = ctxMessage.message_id;
49
+ this.replyToMessageId =
50
+ 'reply_to_message' in ctxMessage
51
+ ? ctxMessage.reply_to_message?.message_id
52
+ : undefined;
48
53
  this.from = ctxMessage.from;
49
54
  this.text = 'text' in ctxMessage ? ctxMessage.text : '';
50
55
  this.chatInfo = new ChatInfo(
@@ -5,6 +5,7 @@ export class IncomingInlineQuery {
5
5
  readonly query: string;
6
6
  readonly userId: number;
7
7
  readonly traceId: TraceId;
8
+ readonly abortController: AbortController;
8
9
 
9
10
  constructor(
10
11
  queryId: string,
@@ -16,5 +17,6 @@ export class IncomingInlineQuery {
16
17
  this.query = query;
17
18
  this.userId = userId;
18
19
  this.traceId = traceId;
20
+ this.abortController = new AbortController();
19
21
  }
20
22
  }
@@ -1,5 +1,5 @@
1
1
  import { IActionState } from '../../types/actionState';
2
- import { IActionWithState } from '../../types/statefulAction';
2
+ import { IActionWithState } from '../../types/action';
3
3
  import { BotResponseTypes, IChatResponse } from '../../types/response';
4
4
  import { Milliseconds } from '../../types/timeValues';
5
5
  import { TraceId } from '../../types/trace';
@@ -1,15 +1,19 @@
1
1
  import { InputFile } from 'telegraf/types';
2
- import { BotResponseTypes, IReplyResponse } from '../../types/response';
2
+ import {
3
+ BotResponseTypes,
4
+ IReplyResponseWithContent
5
+ } from '../../types/response';
3
6
  import { MessageSendingOptions } from '../../types/messageSendingOptions';
4
- import { IActionWithState } from '../../types/statefulAction';
5
- import { IActionState } from '../../types/actionState';
7
+ import { IAction } from '../../types/action';
6
8
  import { ChatInfo } from '../chatInfo';
7
9
  import { TraceId } from '../../types/trace';
8
- import { ReplyInfo } from '../../types/replyInfo';
10
+ import { ReplyInfo } from '../replyInfo';
11
+ import { IReplyCapture } from '../../types/capture';
9
12
 
10
- export class ImageMessage implements IReplyResponse<InputFile> {
13
+ export class ImageMessage implements IReplyResponseWithContent<InputFile> {
11
14
  readonly kind = BotResponseTypes.image;
12
15
  readonly createdAt = Date.now();
16
+ readonly captures: IReplyCapture[] = [];
13
17
 
14
18
  readonly content: InputFile;
15
19
  readonly chatInfo: ChatInfo;
@@ -17,13 +21,13 @@ export class ImageMessage implements IReplyResponse<InputFile> {
17
21
  readonly traceId: TraceId;
18
22
  readonly disableWebPreview = false;
19
23
  readonly shouldPin: boolean;
20
- readonly action: IActionWithState<IActionState>;
24
+ readonly action: IAction;
21
25
 
22
26
  constructor(
23
27
  image: InputFile,
24
28
  chatInfo: ChatInfo,
25
29
  traceId: TraceId,
26
- action: IActionWithState<IActionState>,
30
+ action: IAction,
27
31
  replyInfo: ReplyInfo | undefined,
28
32
  options?: MessageSendingOptions
29
33
  ) {
@@ -1,7 +1,6 @@
1
1
  import { TelegramEmoji } from 'telegraf/types';
2
2
  import { BotResponseTypes, IChatResponse } from '../../types/response';
3
- import { IActionWithState } from '../../types/statefulAction';
4
- import { IActionState } from '../../types/actionState';
3
+ import { IAction } from '../../types/action';
5
4
  import { ChatInfo } from '../chatInfo';
6
5
  import { TraceId } from '../../types/trace';
7
6
 
@@ -13,14 +12,14 @@ export class Reaction implements IChatResponse {
13
12
  readonly messageId: number;
14
13
  readonly traceId: TraceId;
15
14
  readonly emoji: TelegramEmoji;
16
- readonly action: IActionWithState<IActionState>;
15
+ readonly action: IAction;
17
16
 
18
17
  constructor(
19
18
  traceId: TraceId,
20
19
  chatInfo: ChatInfo,
21
20
  messageId: number,
22
21
  emoji: TelegramEmoji,
23
- action: IActionWithState<IActionState>
22
+ action: IAction
24
23
  ) {
25
24
  this.chatInfo = chatInfo;
26
25
  this.messageId = messageId;
@@ -1,14 +1,18 @@
1
1
  import { TextMessageSendingOptions } from '../../types/messageSendingOptions';
2
- import { BotResponseTypes, IReplyResponse } from '../../types/response';
3
- import { IActionWithState } from '../../types/statefulAction';
4
- import { IActionState } from '../../types/actionState';
2
+ import {
3
+ BotResponseTypes,
4
+ IReplyResponseWithContent
5
+ } from '../../types/response';
6
+ import { IAction } from '../../types/action';
5
7
  import { ChatInfo } from '../chatInfo';
6
8
  import { TraceId } from '../../types/trace';
7
- import { ReplyInfo } from '../../types/replyInfo';
9
+ import { ReplyInfo } from '../replyInfo';
10
+ import { IReplyCapture } from '../../types/capture';
8
11
 
9
- export class TextMessage implements IReplyResponse<string> {
12
+ export class TextMessage implements IReplyResponseWithContent<string> {
10
13
  readonly kind = BotResponseTypes.text;
11
14
  readonly createdAt = Date.now();
15
+ readonly captures: IReplyCapture[] = [];
12
16
 
13
17
  readonly content: string;
14
18
  readonly chatInfo: ChatInfo;
@@ -16,13 +20,13 @@ export class TextMessage implements IReplyResponse<string> {
16
20
  readonly traceId: TraceId;
17
21
  readonly disableWebPreview: boolean;
18
22
  readonly shouldPin: boolean;
19
- readonly action: IActionWithState<IActionState>;
23
+ readonly action: IAction;
20
24
 
21
25
  constructor(
22
26
  text: string,
23
27
  chatInfo: ChatInfo,
24
28
  traceId: TraceId,
25
- action: IActionWithState<IActionState>,
29
+ action: IAction,
26
30
  replyInfo?: ReplyInfo,
27
31
  options?: TextMessageSendingOptions
28
32
  ) {
@@ -1,5 +1,5 @@
1
1
  import { BotResponseTypes, IChatResponse } from '../../types/response';
2
- import { IActionWithState } from '../../types/statefulAction';
2
+ import { IActionWithState } from '../../types/action';
3
3
  import { IActionState } from '../../types/actionState';
4
4
  import { ChatInfo } from '../chatInfo';
5
5
  import { TraceId } from '../../types/trace';
@@ -1,15 +1,19 @@
1
1
  import { InputFile } from 'telegraf/types';
2
- import { BotResponseTypes, IReplyResponse } from '../../types/response';
2
+ import {
3
+ BotResponseTypes,
4
+ IReplyResponseWithContent
5
+ } from '../../types/response';
3
6
  import { MessageSendingOptions } from '../../types/messageSendingOptions';
4
- import { IActionWithState } from '../../types/statefulAction';
5
- import { IActionState } from '../../types/actionState';
7
+ import { IAction } from '../../types/action';
6
8
  import { ChatInfo } from '../chatInfo';
7
9
  import { TraceId } from '../../types/trace';
8
- import { ReplyInfo } from '../../types/replyInfo';
10
+ import { ReplyInfo } from '../replyInfo';
11
+ import { IReplyCapture } from '../../types/capture';
9
12
 
10
- export class VideoMessage implements IReplyResponse<InputFile> {
13
+ export class VideoMessage implements IReplyResponseWithContent<InputFile> {
11
14
  readonly kind = BotResponseTypes.video;
12
15
  readonly createdAt = Date.now();
16
+ readonly captures: IReplyCapture[] = [];
13
17
 
14
18
  readonly content: InputFile;
15
19
  readonly chatInfo: ChatInfo;
@@ -17,13 +21,13 @@ export class VideoMessage implements IReplyResponse<InputFile> {
17
21
  readonly traceId: TraceId;
18
22
  readonly disableWebPreview = false;
19
23
  readonly shouldPin: boolean;
20
- readonly action: IActionWithState<IActionState>;
24
+ readonly action: IAction;
21
25
 
22
26
  constructor(
23
27
  video: InputFile,
24
28
  chatInfo: ChatInfo,
25
29
  traceId: TraceId,
26
- action: IActionWithState<IActionState>,
30
+ action: IAction,
27
31
  replyInfo: ReplyInfo | undefined,
28
32
  options?: MessageSendingOptions
29
33
  ) {
@@ -5,7 +5,7 @@ import { Seconds } from '../../types/timeValues';
5
5
  import { secondsToMilliseconds } from '../../helpers/timeConvertions';
6
6
  import { toArray } from '../../helpers/toArray';
7
7
  import { IActionState } from '../../types/actionState';
8
- import { IActionWithState, ActionKey } from '../../types/statefulAction';
8
+ import { IActionWithState, ActionKey } from '../../types/action';
9
9
  import { CommandTriggerCheckResult } from '../../dtos/commandTriggerCheckResult';
10
10
  import { MessageContext } from '../context/messageContext';
11
11
  import { CommandTrigger } from '../../types/commandTrigger';
@@ -105,7 +105,7 @@ export class CommandAction<TActionState extends IActionState>
105
105
  private checkIfShouldBeExecuted(
106
106
  ctx: MessageContext<TActionState>,
107
107
  trigger: CommandTrigger,
108
- state: IActionState
108
+ state: TActionState
109
109
  ) {
110
110
  if (!ctx.fromUserId)
111
111
  return CommandTriggerCheckResult.DontTriggerAndSkipCooldown;
@@ -126,17 +126,11 @@ export class CommandAction<TActionState extends IActionState>
126
126
 
127
127
  if (onCooldown) return CommandTriggerCheckResult.DoNotTrigger;
128
128
 
129
- const isCustomConditionMet = this.condition(ctx);
129
+ const isCustomConditionMet = this.condition(ctx, state);
130
130
  if (!isCustomConditionMet)
131
131
  return CommandTriggerCheckResult.DontTriggerAndSkipCooldown;
132
132
 
133
- const { shouldTrigger, matchResults } = this.checkTrigger(ctx, trigger);
134
-
135
- return new CommandTriggerCheckResult(
136
- shouldTrigger,
137
- matchResults,
138
- false
139
- );
133
+ return this.checkTrigger(ctx, trigger);
140
134
  }
141
135
 
142
136
  private checkTrigger(
@@ -144,14 +138,12 @@ export class CommandAction<TActionState extends IActionState>
144
138
  trigger: CommandTrigger
145
139
  ) {
146
140
  if (trigger == ctx.messageType)
147
- return { shouldTrigger: true, matchResults: [] };
141
+ return CommandTriggerCheckResult.Trigger;
148
142
 
149
143
  if (typeof trigger == 'string')
150
- return {
151
- shouldTrigger:
152
- ctx.messageText.toLowerCase() == trigger.toLowerCase(),
153
- matchResults: []
154
- };
144
+ return ctx.messageText.toLowerCase() == trigger.toLowerCase()
145
+ ? CommandTriggerCheckResult.Trigger
146
+ : CommandTriggerCheckResult.DoNotTrigger;
155
147
 
156
148
  const matchResults: RegExpExecArray[] = [];
157
149
 
@@ -170,9 +162,10 @@ export class CommandAction<TActionState extends IActionState>
170
162
  }
171
163
  }
172
164
 
173
- return {
174
- shouldTrigger: matchResults.length > 0,
175
- matchResults
176
- };
165
+ return new CommandTriggerCheckResult(
166
+ matchResults.length > 0,
167
+ matchResults,
168
+ false
169
+ );
177
170
  }
178
171
  }
@@ -1,10 +1,9 @@
1
1
  import { Noop } from '../../helpers/noop';
2
- import { ActionKey } from '../../types/statefulAction';
2
+ import { ActionKey, IAction } from '../../types/action';
3
3
  import { InlineQueryContext } from '../context/inlineQueryContext';
4
4
  import { InlineQueryHandler } from '../../types/handlers';
5
- import { IActionWithoutState } from '../../types/statelessAction';
6
5
 
7
- export class InlineQueryAction implements IActionWithoutState {
6
+ export class InlineQueryAction implements IAction {
8
7
  readonly key: ActionKey;
9
8
  readonly active: boolean;
10
9
  readonly handler: InlineQueryHandler;
@@ -0,0 +1,104 @@
1
+ import { CommandTriggerCheckResult } from '../../dtos/commandTriggerCheckResult';
2
+ import { Noop } from '../../helpers/noop';
3
+ import { IActionState } from '../../types/actionState';
4
+ import { CommandTrigger } from '../../types/commandTrigger';
5
+ import { ActionKey, IAction, IActionWithState } from '../../types/action';
6
+ import { ReplyContext } from '../context/replyContext';
7
+
8
+ export class ReplyCaptureAction<TParentActionState extends IActionState>
9
+ implements IAction
10
+ {
11
+ readonly parentMessageId: number;
12
+ readonly key: ActionKey;
13
+ readonly handler: (
14
+ replyContext: ReplyContext<TParentActionState>
15
+ ) => Promise<void>;
16
+ readonly triggers: CommandTrigger[];
17
+ readonly abortController: AbortController;
18
+
19
+ constructor(
20
+ parentMessageId: number,
21
+ parentAction: IActionWithState<TParentActionState>,
22
+ handler: (
23
+ replyContext: ReplyContext<TParentActionState>
24
+ ) => Promise<void>,
25
+ triggers: CommandTrigger[],
26
+ abortController: AbortController
27
+ ) {
28
+ this.parentMessageId = parentMessageId;
29
+ this.handler = handler;
30
+ this.triggers = triggers;
31
+ this.abortController = abortController;
32
+
33
+ this.key = `capture:${parentAction.key}:${Math.random()
34
+ .toString()
35
+ .replace('.', '')}` as ActionKey;
36
+ }
37
+
38
+ async exec(ctx: ReplyContext<TParentActionState>) {
39
+ if (!ctx.isInitialized)
40
+ throw new Error(
41
+ `Context for ${this.key} is not initialized or already consumed`
42
+ );
43
+
44
+ const { shouldExecute, matchResults } = this.triggers
45
+ .map((x) => this.checkIfShouldBeExecuted(ctx, x))
46
+ .reduce(
47
+ (acc, curr) => acc.mergeWith(curr),
48
+ CommandTriggerCheckResult.DoNotTrigger
49
+ );
50
+
51
+ if (!shouldExecute) return Noop.NoResponse;
52
+
53
+ ctx.logger.logWithTraceId(
54
+ ctx.botName,
55
+ ctx.traceId,
56
+ ctx.chatInfo.name,
57
+ ` - Executing [${this.key}] in ${ctx.chatInfo.id}`
58
+ );
59
+ ctx.matchResults = matchResults;
60
+
61
+ await this.handler(ctx);
62
+
63
+ return ctx.responses;
64
+ }
65
+
66
+ private checkIfShouldBeExecuted(
67
+ ctx: ReplyContext<TParentActionState>,
68
+ trigger: CommandTrigger
69
+ ) {
70
+ if (ctx.replyMessageId != this.parentMessageId)
71
+ return CommandTriggerCheckResult.DoNotTrigger;
72
+
73
+ if (trigger == ctx.messageType)
74
+ return CommandTriggerCheckResult.Trigger;
75
+
76
+ if (typeof trigger == 'string')
77
+ if (ctx.messageText.toLowerCase() == trigger.toLowerCase())
78
+ return CommandTriggerCheckResult.Trigger;
79
+ else return CommandTriggerCheckResult.DoNotTrigger;
80
+
81
+ const matchResults: RegExpExecArray[] = [];
82
+
83
+ trigger.lastIndex = 0;
84
+
85
+ const execResult = trigger.exec(ctx.messageText);
86
+ if (execResult != null) {
87
+ matchResults.push(execResult);
88
+
89
+ if (trigger.global) {
90
+ while (true) {
91
+ const nextResult = trigger.exec(ctx.messageText);
92
+ if (nextResult == null) break;
93
+ matchResults.push(nextResult);
94
+ }
95
+ }
96
+ }
97
+
98
+ return new CommandTriggerCheckResult(
99
+ matchResults.length > 0,
100
+ matchResults,
101
+ false
102
+ );
103
+ }
104
+ }
@@ -4,7 +4,7 @@ import { ScheduledHandler } from '../../types/handlers';
4
4
  import { hoursToMilliseconds } from '../../helpers/timeConvertions';
5
5
  import { HoursOfDay } from '../../types/timeValues';
6
6
  import { IActionState } from '../../types/actionState';
7
- import { IActionWithState, ActionKey } from '../../types/statefulAction';
7
+ import { IActionWithState, ActionKey } from '../../types/action';
8
8
  import { CachedStateFactory } from '../cachedStateFactory';
9
9
  import { ChatContext } from '../context/chatContext';
10
10
  import { Noop } from '../../helpers/noop';