chz-telegram-bot 0.1.19 → 0.2.0

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 (50) hide show
  1. package/builtin/helpAction.ts +1 -1
  2. package/bun.lock +307 -0
  3. package/dist/builtin/helpAction.js +1 -1
  4. package/dist/dtos/responses/imageMessage.d.ts +5 -4
  5. package/dist/dtos/responses/imageMessage.d.ts.map +1 -1
  6. package/dist/dtos/responses/imageMessage.js +2 -2
  7. package/dist/dtos/responses/textMessage.d.ts +5 -4
  8. package/dist/dtos/responses/textMessage.d.ts.map +1 -1
  9. package/dist/dtos/responses/textMessage.js +2 -2
  10. package/dist/dtos/responses/videoMessage.d.ts +5 -4
  11. package/dist/dtos/responses/videoMessage.d.ts.map +1 -1
  12. package/dist/dtos/responses/videoMessage.js +2 -2
  13. package/dist/entities/botInstance.d.ts +2 -0
  14. package/dist/entities/botInstance.d.ts.map +1 -1
  15. package/dist/entities/botInstance.js +34 -7
  16. package/dist/entities/context/chatContext.d.ts +25 -21
  17. package/dist/entities/context/chatContext.d.ts.map +1 -1
  18. package/dist/entities/context/chatContext.js +32 -38
  19. package/dist/entities/context/messageContext.d.ts +60 -28
  20. package/dist/entities/context/messageContext.d.ts.map +1 -1
  21. package/dist/entities/context/messageContext.js +79 -49
  22. package/dist/services/jsonFileStorage.d.ts.map +1 -1
  23. package/dist/services/jsonFileStorage.js +6 -11
  24. package/dist/services/responseProcessingQueue.d.ts +0 -1
  25. package/dist/services/responseProcessingQueue.d.ts.map +1 -1
  26. package/dist/services/responseProcessingQueue.js +1 -6
  27. package/dist/services/telegramApi.d.ts.map +1 -1
  28. package/dist/services/telegramApi.js +9 -7
  29. package/dist/types/messageTypes.d.ts +1 -0
  30. package/dist/types/messageTypes.d.ts.map +1 -1
  31. package/dist/types/messageTypes.js +15 -14
  32. package/dist/types/replyInfo.d.ts +6 -0
  33. package/dist/types/replyInfo.d.ts.map +1 -0
  34. package/dist/types/replyInfo.js +10 -0
  35. package/dist/types/response.d.ts +3 -2
  36. package/dist/types/response.d.ts.map +1 -1
  37. package/dtos/responses/imageMessage.ts +6 -5
  38. package/dtos/responses/textMessage.ts +6 -5
  39. package/dtos/responses/videoMessage.ts +6 -5
  40. package/entities/botInstance.ts +65 -10
  41. package/entities/context/chatContext.ts +58 -72
  42. package/entities/context/messageContext.ts +133 -88
  43. package/eslint.config.js +0 -1
  44. package/package.json +30 -29
  45. package/services/jsonFileStorage.ts +7 -13
  46. package/services/responseProcessingQueue.ts +2 -8
  47. package/services/telegramApi.ts +11 -9
  48. package/types/messageTypes.ts +15 -13
  49. package/types/replyInfo.ts +9 -0
  50. package/types/response.ts +3 -2
@@ -49,7 +49,7 @@ class TelegramApiService {
49
49
  switch (response.kind) {
50
50
  case 'text':
51
51
  sentMessage = await this.telegram.sendMessage(response.chatInfo.id, response.content, {
52
- reply_to_message_id: response.replyId,
52
+ reply_to_message_id: response.replyInfo?.id,
53
53
  parse_mode: 'MarkdownV2',
54
54
  disable_web_page_preview: response.disableWebPreview
55
55
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -57,16 +57,18 @@ class TelegramApiService {
57
57
  await this.pinIfShould(response, sentMessage);
58
58
  break;
59
59
  case 'image':
60
- sentMessage = await this.telegram.sendPhoto(response.chatInfo.id, response.content, response.replyId
61
- ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
62
- { reply_to_message_id: response.replyId }
60
+ sentMessage = await this.telegram.sendPhoto(response.chatInfo.id, response.content, response.replyInfo?.id
61
+ ? {
62
+ reply_to_message_id: response.replyInfo?.id // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
+ }
63
64
  : undefined);
64
65
  await this.pinIfShould(response, sentMessage);
65
66
  break;
66
67
  case 'video':
67
- sentMessage = await this.telegram.sendVideo(response.chatInfo.id, response.content, response.replyId
68
- ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
- { reply_to_message_id: response.replyId }
68
+ sentMessage = await this.telegram.sendVideo(response.chatInfo.id, response.content, response.replyInfo?.id
69
+ ? {
70
+ reply_to_message_id: response.replyInfo?.id // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ }
70
72
  : undefined);
71
73
  await this.pinIfShould(response, sentMessage);
72
74
  break;
@@ -1,4 +1,5 @@
1
1
  import { Message, Update } from 'telegraf/types';
2
+ export declare const INTERNAL_MESSAGE_TYPE_PREFIX = "__msg:";
2
3
  export declare const MessageType: {
3
4
  readonly Text: "__msg:Text";
4
5
  readonly Sticker: "__msg:Sticker";
@@ -1 +1 @@
1
- {"version":3,"file":"messageTypes.d.ts","sourceRoot":"","sources":["../../types/messageTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAEjD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;CAcd,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC;AAE9E,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC"}
1
+ {"version":3,"file":"messageTypes.d.ts","sourceRoot":"","sources":["../../types/messageTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAEjD,eAAO,MAAM,4BAA4B,WAAW,CAAC;AAErD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;CAcd,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC;AAE9E,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC"}
@@ -1,18 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MessageType = void 0;
3
+ exports.MessageType = exports.INTERNAL_MESSAGE_TYPE_PREFIX = void 0;
4
+ exports.INTERNAL_MESSAGE_TYPE_PREFIX = `__msg:`;
4
5
  exports.MessageType = {
5
- Text: '__msg:Text',
6
- Sticker: '__msg:Sticker',
7
- Animation: '__msg:Animation',
8
- Document: '__msg:Document',
9
- Voice: '__msg:Voice',
10
- Audio: '__msg:Audio',
11
- LeftChatMember: '__msg:LeftChatMember',
12
- NewChatMember: '__msg:NewChatMember',
13
- Poll: '__msg:Poll',
14
- Location: '__msg:Location',
15
- Photo: '__msg:Photo',
16
- Forward: '__msg:Forward',
17
- Unknown: '__msg:Unknown'
6
+ Text: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}Text`,
7
+ Sticker: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}Sticker`,
8
+ Animation: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}Animation`,
9
+ Document: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}Document`,
10
+ Voice: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}Voice`,
11
+ Audio: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}Audio`,
12
+ LeftChatMember: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}LeftChatMember`,
13
+ NewChatMember: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}NewChatMember`,
14
+ Poll: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}Poll`,
15
+ Location: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}Location`,
16
+ Photo: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}Photo`,
17
+ Forward: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}Forward`,
18
+ Unknown: `${exports.INTERNAL_MESSAGE_TYPE_PREFIX}Unknown`
18
19
  };
@@ -0,0 +1,6 @@
1
+ export declare class ReplyInfo {
2
+ readonly id: number;
3
+ readonly quote: string | undefined;
4
+ constructor(id: number, quote?: string);
5
+ }
6
+ //# sourceMappingURL=replyInfo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replyInfo.d.ts","sourceRoot":"","sources":["../../types/replyInfo.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAS;IAClB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;gBAEvB,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAIzC"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ReplyInfo = void 0;
4
+ class ReplyInfo {
5
+ constructor(id, quote) {
6
+ this.id = id;
7
+ this.quote = quote;
8
+ }
9
+ }
10
+ exports.ReplyInfo = ReplyInfo;
@@ -7,6 +7,7 @@ import { TextMessage } from '../dtos/responses/textMessage';
7
7
  import { UnpinResponse } from '../dtos/responses/unpin';
8
8
  import { VideoMessage } from '../dtos/responses/videoMessage';
9
9
  import { IActionState } from './actionState';
10
+ import { ReplyInfo } from './replyInfo';
10
11
  import { IActionWithState } from './statefulAction';
11
12
  import { TraceId } from './trace';
12
13
  export declare const BotResponseTypes: {
@@ -26,9 +27,9 @@ export interface IChatResponse {
26
27
  readonly createdAt: number;
27
28
  readonly action: IActionWithState<IActionState>;
28
29
  }
29
- export interface IReplyMessage<TType> extends IChatResponse {
30
+ export interface IReplyResponse<TType> extends IChatResponse {
30
31
  readonly content: TType;
31
- readonly replyId: number | undefined;
32
+ readonly replyInfo: ReplyInfo | undefined;
32
33
  readonly disableWebPreview: boolean;
33
34
  readonly shouldPin: boolean;
34
35
  }
@@ -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,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,aAAa,CAAC,KAAK,CAAE,SAAQ,aAAa;IACvD,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,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,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,18 +1,19 @@
1
1
  import { InputFile } from 'telegraf/types';
2
- import { BotResponseTypes, IReplyMessage } from '../../types/response';
2
+ import { BotResponseTypes, IReplyResponse } from '../../types/response';
3
3
  import { MessageSendingOptions } from '../../types/messageSendingOptions';
4
4
  import { IActionWithState } from '../../types/statefulAction';
5
5
  import { IActionState } from '../../types/actionState';
6
6
  import { ChatInfo } from '../chatInfo';
7
7
  import { TraceId } from '../../types/trace';
8
+ import { ReplyInfo } from '../../types/replyInfo';
8
9
 
9
- export class ImageMessage implements IReplyMessage<InputFile> {
10
+ export class ImageMessage implements IReplyResponse<InputFile> {
10
11
  readonly kind = BotResponseTypes.image;
11
12
  readonly createdAt = Date.now();
12
13
 
13
14
  readonly content: InputFile;
14
15
  readonly chatInfo: ChatInfo;
15
- readonly replyId: number | undefined;
16
+ readonly replyInfo: ReplyInfo | undefined;
16
17
  readonly traceId: TraceId;
17
18
  readonly disableWebPreview = false;
18
19
  readonly shouldPin: boolean;
@@ -21,14 +22,14 @@ export class ImageMessage implements IReplyMessage<InputFile> {
21
22
  constructor(
22
23
  image: InputFile,
23
24
  chatInfo: ChatInfo,
24
- replyId: number | undefined,
25
25
  traceId: TraceId,
26
26
  action: IActionWithState<IActionState>,
27
+ replyInfo: ReplyInfo | undefined,
27
28
  options?: MessageSendingOptions
28
29
  ) {
29
30
  this.content = image;
30
31
  this.chatInfo = chatInfo;
31
- this.replyId = replyId;
32
+ this.replyInfo = replyInfo;
32
33
  this.traceId = traceId;
33
34
  this.shouldPin = options?.pin ?? false;
34
35
  this.action = action;
@@ -1,17 +1,18 @@
1
1
  import { TextMessageSendingOptions } from '../../types/messageSendingOptions';
2
- import { BotResponseTypes, IReplyMessage } from '../../types/response';
2
+ import { BotResponseTypes, IReplyResponse } from '../../types/response';
3
3
  import { IActionWithState } from '../../types/statefulAction';
4
4
  import { IActionState } from '../../types/actionState';
5
5
  import { ChatInfo } from '../chatInfo';
6
6
  import { TraceId } from '../../types/trace';
7
+ import { ReplyInfo } from '../../types/replyInfo';
7
8
 
8
- export class TextMessage implements IReplyMessage<string> {
9
+ export class TextMessage implements IReplyResponse<string> {
9
10
  readonly kind = BotResponseTypes.text;
10
11
  readonly createdAt = Date.now();
11
12
 
12
13
  readonly content: string;
13
14
  readonly chatInfo: ChatInfo;
14
- readonly replyId: number | undefined;
15
+ readonly replyInfo: ReplyInfo | undefined;
15
16
  readonly traceId: TraceId;
16
17
  readonly disableWebPreview: boolean;
17
18
  readonly shouldPin: boolean;
@@ -20,14 +21,14 @@ export class TextMessage implements IReplyMessage<string> {
20
21
  constructor(
21
22
  text: string,
22
23
  chatInfo: ChatInfo,
23
- replyId: number | undefined,
24
24
  traceId: TraceId,
25
25
  action: IActionWithState<IActionState>,
26
+ replyInfo?: ReplyInfo,
26
27
  options?: TextMessageSendingOptions
27
28
  ) {
28
29
  this.content = text;
29
30
  this.chatInfo = chatInfo;
30
- this.replyId = replyId;
31
+ this.replyInfo = replyInfo;
31
32
  this.traceId = traceId;
32
33
  this.disableWebPreview = options?.disableWebPreview ?? false;
33
34
  this.shouldPin = options?.pin ?? false;
@@ -1,18 +1,19 @@
1
1
  import { InputFile } from 'telegraf/types';
2
- import { BotResponseTypes, IReplyMessage } from '../../types/response';
2
+ import { BotResponseTypes, IReplyResponse } from '../../types/response';
3
3
  import { MessageSendingOptions } from '../../types/messageSendingOptions';
4
4
  import { IActionWithState } from '../../types/statefulAction';
5
5
  import { IActionState } from '../../types/actionState';
6
6
  import { ChatInfo } from '../chatInfo';
7
7
  import { TraceId } from '../../types/trace';
8
+ import { ReplyInfo } from '../../types/replyInfo';
8
9
 
9
- export class VideoMessage implements IReplyMessage<InputFile> {
10
+ export class VideoMessage implements IReplyResponse<InputFile> {
10
11
  readonly kind = BotResponseTypes.video;
11
12
  readonly createdAt = Date.now();
12
13
 
13
14
  readonly content: InputFile;
14
15
  readonly chatInfo: ChatInfo;
15
- readonly replyId: number | undefined;
16
+ readonly replyInfo: ReplyInfo | undefined;
16
17
  readonly traceId: TraceId;
17
18
  readonly disableWebPreview = false;
18
19
  readonly shouldPin: boolean;
@@ -21,14 +22,14 @@ export class VideoMessage implements IReplyMessage<InputFile> {
21
22
  constructor(
22
23
  video: InputFile,
23
24
  chatInfo: ChatInfo,
24
- replyId: number | undefined,
25
25
  traceId: TraceId,
26
26
  action: IActionWithState<IActionState>,
27
+ replyInfo: ReplyInfo | undefined,
27
28
  options?: MessageSendingOptions
28
29
  ) {
29
30
  this.content = video;
30
31
  this.chatInfo = chatInfo;
31
- this.replyId = replyId;
32
+ this.replyInfo = replyInfo;
32
33
  this.traceId = traceId;
33
34
  this.shouldPin = options?.pin ?? false;
34
35
  this.action = action;
@@ -25,6 +25,12 @@ import { IncomingInlineQuery } from '../dtos/incomingQuery';
25
25
  import { InlineQueryContext } from './context/inlineQueryContext';
26
26
  import { buildHelpCommand } from '../builtin/helpAction';
27
27
  import { UserFromGetMe } from 'telegraf/types';
28
+ import {
29
+ INTERNAL_MESSAGE_TYPE_PREFIX,
30
+ MessageType
31
+ } from '../types/messageTypes';
32
+ import { IActionWithState } from '../types/statefulAction';
33
+ import { TraceId } from '../types/trace';
28
34
 
29
35
  export class BotInstance {
30
36
  private readonly api: TelegramApiService;
@@ -262,13 +268,20 @@ export class BotInstance {
262
268
  verboseLoggingForIncomingMessage: boolean
263
269
  ) {
264
270
  if (this.commands.length > 0) {
271
+ const triggersToBeProcessed = new Set(
272
+ this.commands
273
+ .flatMap((x) => x.triggers)
274
+ .map((x) =>
275
+ typeof x == 'string'
276
+ ? x.startsWith(INTERNAL_MESSAGE_TYPE_PREFIX)
277
+ ? x
278
+ : MessageType.Text
279
+ : MessageType.Text
280
+ )
281
+ );
282
+
265
283
  this.telegraf.on('message', async (ctx) => {
266
284
  const msg = new IncomingMessage(ctx.update.message, this.name);
267
- const messageContent =
268
- msg.text || `<non-text message: ${msg.type}>`;
269
-
270
- const messageFromName = msg.from?.first_name ?? 'Unknown';
271
- const messageFromId = msg.from?.id ?? 'Unknown';
272
285
 
273
286
  if (verboseLoggingForIncomingMessage) {
274
287
  this.logger.logObjectWithTraceId(
@@ -282,11 +295,14 @@ export class BotInstance {
282
295
  this.name,
283
296
  msg.traceId,
284
297
  msg.chatInfo.name,
285
- `${messageFromName} (${messageFromId}): ${messageContent}`
298
+ `${msg.from?.first_name ?? 'Unknown'} (${
299
+ msg.from?.id ?? 'Unknown'
300
+ }): ${msg.text || `<non-text message: ${msg.type}>`}`
286
301
  );
287
302
  }
288
303
 
289
- await this.processMessage(msg);
304
+ if (triggersToBeProcessed.has(msg.type))
305
+ await this.processMessage(msg);
290
306
  });
291
307
  }
292
308
  }
@@ -304,6 +320,45 @@ export class BotInstance {
304
320
  this.telegraf.stop(code);
305
321
  }
306
322
 
323
+ private initializeMessageContext<TActionState extends IActionState>(
324
+ ctx: MessageContext<IActionState>,
325
+ action: IActionWithState<TActionState>,
326
+ message: IncomingMessage
327
+ ) {
328
+ ctx.messageId = message.message_id;
329
+ ctx.messageText = message.text ?? '';
330
+ ctx.messageType = message.type;
331
+ ctx.fromUserId = message.from?.id;
332
+ ctx.fromUserName =
333
+ (message.from?.first_name ?? 'Unknown user') +
334
+ (message.from?.last_name ? ` ${message.from.last_name}` : '');
335
+ ctx.messageUpdateObject = message.updateObject;
336
+
337
+ ctx.matchResults = [];
338
+ ctx.startCooldown = true;
339
+
340
+ this.initializeChatContext(
341
+ ctx,
342
+ action,
343
+ message.chatInfo,
344
+ message.traceId
345
+ );
346
+ }
347
+
348
+ private initializeChatContext<TActionState extends IActionState>(
349
+ ctx: ChatContext<IActionState>,
350
+ action: IActionWithState<TActionState>,
351
+ chatInfo: ChatInfo,
352
+ traceId: TraceId
353
+ ) {
354
+ ctx.responses = [];
355
+ ctx.isInitialized = true;
356
+ ctx.botName = this.name;
357
+ ctx.action = action;
358
+ ctx.chatInfo = chatInfo;
359
+ ctx.traceId = traceId;
360
+ }
361
+
307
362
  private async runScheduled() {
308
363
  const ctx = new ChatContext<IActionState>(
309
364
  this.storage,
@@ -313,8 +368,8 @@ export class BotInstance {
313
368
 
314
369
  for (const [chatName, chatId] of Object.entries(this.chats)) {
315
370
  for (const scheduledAction of this.scheduled) {
316
- ctx.initializeChatContext(
317
- this.name,
371
+ this.initializeChatContext(
372
+ ctx,
318
373
  scheduledAction,
319
374
  new ChatInfo(chatId, chatName),
320
375
  createTrace(
@@ -351,7 +406,7 @@ export class BotInstance {
351
406
  );
352
407
 
353
408
  for (const commandAction of this.commands) {
354
- ctx.initializeMessageContext(this.name, commandAction, msg);
409
+ this.initializeMessageContext(ctx, commandAction, msg);
355
410
 
356
411
  try {
357
412
  const responses = await commandAction.exec(ctx);
@@ -22,7 +22,7 @@ import { TraceId } from '../../types/trace';
22
22
  * Context of action executed in chat.
23
23
  */
24
24
  export class ChatContext<TActionState extends IActionState> {
25
- protected action!: IActionWithState<TActionState>;
25
+ action!: IActionWithState<TActionState>;
26
26
 
27
27
  /** Storage client instance for the bot executing this action. */
28
28
  readonly storage: IStorageClient;
@@ -52,81 +52,67 @@ export class ChatContext<TActionState extends IActionState> {
52
52
  this.scheduler = scheduler;
53
53
  }
54
54
 
55
- initializeChatContext(
56
- botName: string,
57
- action: IActionWithState<TActionState>,
58
- chatInfo: ChatInfo,
59
- traceId: TraceId
60
- ) {
61
- this.botName = botName;
62
- this.action = action;
63
- this.chatInfo = chatInfo;
64
- this.traceId = traceId;
65
-
66
- this.isInitialized = true;
67
- this.responses = [];
68
-
69
- return this;
70
- }
71
-
72
55
  /**
73
- * Sends text message to chat after action execution is finished.
74
- * If multiple responses are sent, they will be sent in the order they were added, with delay of at least 35ms as per Telegram rate-limit.
75
- * @param text Message contents.
76
- * @param options Message sending option.
56
+ * Collection of actions that send something to chat as a standalone message.
77
57
  */
78
- sendTextToChat(text: string, options?: TextMessageSendingOptions) {
79
- this.responses.push(
80
- new TextMessage(
81
- text,
82
- this.chatInfo,
83
- undefined,
84
- this.traceId,
85
- this.action,
86
- options
87
- )
88
- );
89
- }
58
+ send = {
59
+ /**
60
+ * Sends text message to chat after action execution is finished.
61
+ * If multiple responses are sent, they will be sent in the order they were added, with delay of at least 35ms as per Telegram rate-limit.
62
+ * @param text Message contents.
63
+ * @param options Message sending option.
64
+ */
65
+ text: (text: string, options?: TextMessageSendingOptions) => {
66
+ this.responses.push(
67
+ new TextMessage(
68
+ text,
69
+ this.chatInfo,
70
+ this.traceId,
71
+ this.action,
72
+ undefined,
73
+ options
74
+ )
75
+ );
76
+ },
90
77
 
91
- /**
92
- * Sends image message to chat after action execution is finished.
93
- * If multiple responses are sent, they will be sent in the order they were added, with delay of at least 35ms as per Telegram rate-limit.
94
- * @param name Message contents.
95
- * @param options Message sending option.
96
- */
97
- sendImageToChat(name: string, options?: MessageSendingOptions) {
98
- const filePath = `./content/${name}.png`;
99
- this.responses.push(
100
- new ImageMessage(
101
- { source: resolve(filePath) },
102
- this.chatInfo,
103
- undefined,
104
- this.traceId,
105
- this.action,
106
- options
107
- )
108
- );
109
- }
78
+ /**
79
+ * Sends image message to chat after action execution is finished.
80
+ * If multiple responses are sent, they will be sent in the order they were added, with delay of at least 35ms as per Telegram rate-limit.
81
+ * @param name Message contents.
82
+ * @param options Message sending option.
83
+ */
84
+ image: (name: string, options?: MessageSendingOptions) => {
85
+ this.responses.push(
86
+ new ImageMessage(
87
+ { source: resolve(`./content/${name}.png`) },
88
+ this.chatInfo,
89
+ this.traceId,
90
+ this.action,
91
+ undefined,
92
+ options
93
+ )
94
+ );
95
+ },
110
96
 
111
- /**
112
- * Sends video/gif message to chat after action execution is finished.
113
- * If multiple responses are sent, they will be sent in the order they were added, with delay of at least 35ms as per Telegram rate-limit.
114
- * @param name Message contents.
115
- * @param options Message sending option.
116
- */
117
- sendVideoToChat(name: string, options?: MessageSendingOptions) {
118
- const filePath = `./content/${name}.mp4`;
119
- this.responses.push(
120
- new VideoMessage(
121
- { source: resolve(filePath) },
122
- this.chatInfo,
123
- undefined,
124
- this.traceId,
125
- this.action,
126
- options
127
- )
128
- );
129
- }
97
+ /**
98
+ * Sends video/gif message to chat after action execution is finished.
99
+ * If multiple responses are sent, they will be sent in the order they were added, with delay of at least 35ms as per Telegram rate-limit.
100
+ * @param name Message contents.
101
+ * @param options Message sending option.
102
+ */
103
+ video: (name: string, options?: MessageSendingOptions) => {
104
+ this.responses.push(
105
+ new VideoMessage(
106
+ { source: resolve(`./content/${name}.mp4`) },
107
+ this.chatInfo,
108
+ this.traceId,
109
+ this.action,
110
+ undefined,
111
+ options
112
+ )
113
+ );
114
+ }
115
+ };
130
116
 
131
117
  /**
132
118
  * Unpins message after action execution is finished.