chz-telegram-bot 0.0.20 → 0.0.22

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 (33) hide show
  1. package/dist/entities/botInstance.d.ts +3 -2
  2. package/dist/entities/botInstance.d.ts.map +1 -1
  3. package/dist/entities/botInstance.js +26 -23
  4. package/dist/entities/context/chatContext.d.ts +4 -3
  5. package/dist/entities/context/chatContext.d.ts.map +1 -1
  6. package/dist/entities/context/chatContext.js +6 -6
  7. package/dist/entities/context/messageContext.d.ts +4 -3
  8. package/dist/entities/context/messageContext.d.ts.map +1 -1
  9. package/dist/entities/context/messageContext.js +6 -6
  10. package/dist/entities/responses/imageMessage.d.ts +2 -1
  11. package/dist/entities/responses/imageMessage.d.ts.map +1 -1
  12. package/dist/entities/responses/imageMessage.js +2 -2
  13. package/dist/entities/responses/textMessage.d.ts +2 -1
  14. package/dist/entities/responses/textMessage.d.ts.map +1 -1
  15. package/dist/entities/responses/textMessage.js +3 -3
  16. package/dist/entities/responses/videoMessage.d.ts +2 -1
  17. package/dist/entities/responses/videoMessage.d.ts.map +1 -1
  18. package/dist/entities/responses/videoMessage.js +2 -2
  19. package/dist/services/telegramApi.d.ts +3 -2
  20. package/dist/services/telegramApi.d.ts.map +1 -1
  21. package/dist/services/telegramApi.js +18 -14
  22. package/dist/types/messageSendingOptions.d.ts +7 -0
  23. package/dist/types/messageSendingOptions.d.ts.map +1 -0
  24. package/dist/types/messageSendingOptions.js +2 -0
  25. package/entities/botInstance.ts +44 -50
  26. package/entities/context/chatContext.ts +13 -14
  27. package/entities/context/messageContext.ts +13 -10
  28. package/entities/responses/imageMessage.ts +4 -3
  29. package/entities/responses/textMessage.ts +5 -5
  30. package/entities/responses/videoMessage.ts +4 -3
  31. package/package.json +1 -1
  32. package/services/telegramApi.ts +27 -28
  33. package/types/messageSendingOptions.ts +7 -0
@@ -9,7 +9,6 @@ export declare class BotInstance {
9
9
  private commands;
10
10
  private scheduled;
11
11
  private chats;
12
- private messageQueue;
13
12
  storage: IStorageClient;
14
13
  constructor(options: {
15
14
  name: string;
@@ -20,8 +19,10 @@ export declare class BotInstance {
20
19
  storageClient?: IStorageClient;
21
20
  storagePath?: string;
22
21
  });
22
+ private initializeScheduledProcessing;
23
+ private initializeMessageProcessing;
23
24
  stop(code: string): Promise<void>;
24
25
  private runScheduled;
25
- private processMessages;
26
+ private processMessage;
26
27
  }
27
28
  //# sourceMappingURL=botInstance.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"botInstance.d.ts","sourceRoot":"","sources":["../../entities/botInstance.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAK5D,qBAAa,WAAW;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,GAAG,CAAqB;IAChC,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,EAAE,cAAc,CAAC;gBAEZ,OAAO,EAAE;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,aAAa,CAAC,YAAY,CAAC,EAAE,CAAC;QACxC,SAAS,EAAE,eAAe,CAAC,YAAY,CAAC,EAAE,CAAC;QAC3C,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3B,aAAa,CAAC,EAAE,cAAc,CAAC;QAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;KACxB;IAuEK,IAAI,CAAC,IAAI,EAAE,MAAM;YAYT,YAAY;YAqBZ,eAAe;CAmBhC"}
1
+ {"version":3,"file":"botInstance.d.ts","sourceRoot":"","sources":["../../entities/botInstance.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAK5D,qBAAa,WAAW;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,GAAG,CAAqB;IAChC,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,EAAE,cAAc,CAAC;gBAEZ,OAAO,EAAE;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,aAAa,CAAC,YAAY,CAAC,EAAE,CAAC;QACxC,SAAS,EAAE,eAAe,CAAC,YAAY,CAAC,EAAE,CAAC;QAC3C,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3B,aAAa,CAAC,EAAE,cAAc,CAAC;QAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;KACxB;IAkCD,OAAO,CAAC,6BAA6B;IAcrC,OAAO,CAAC,2BAA2B;IAsB7B,IAAI,CAAC,IAAI,EAAE,MAAM;YAYT,YAAY;YAoBZ,cAAc;CAmB/B"}
@@ -10,7 +10,6 @@ const taskScheduler_1 = require("../services/taskScheduler");
10
10
  const incomingMessage_1 = require("./incomingMessage");
11
11
  class BotInstance {
12
12
  constructor(options) {
13
- this.messageQueue = [];
14
13
  this.name = options.name;
15
14
  this.commands = options.commands;
16
15
  this.scheduled = options.scheduled;
@@ -21,26 +20,31 @@ class BotInstance {
21
20
  options.storageClient ??
22
21
  new jsonFileStorage_1.JsonFileStorage(options.name, options.storagePath);
23
22
  this.api = new telegramApi_1.TelegramApiService(this.name, this.telegraf.telegram, this.storage, this.chats);
24
- this.telegraf.on('message', async (ctx) => {
25
- const msg = new incomingMessage_1.IncomingMessage(ctx.update.message);
26
- const messageContent = msg.text || '<non-text message>';
27
- const messageFromName = msg.from?.first_name ?? 'Unknown';
28
- const messageFromId = msg.from?.id ?? 'Unknown';
29
- logger_1.Logger.logWithTraceId(this.name, msg.traceId, msg.chatName, `${messageFromName} (${messageFromId}): ${messageContent}`);
30
- if (msg.text) {
31
- this.messageQueue.push(msg);
32
- }
33
- });
34
- this.telegraf.launch();
35
- taskScheduler_1.Scheduler.createTask('MessageProcessing', async () => {
36
- while (this.messageQueue.length > 0) {
37
- await this.processMessages();
38
- }
39
- }, (0, timeConvertions_1.secondsToMilliseconds)(0.3), false, this.name);
40
- taskScheduler_1.Scheduler.createTask('ScheduledProcessing', async () => {
41
- await this.runScheduled();
42
- }, (0, timeConvertions_1.hoursToMilliseconds)(0.5), true, this.name);
23
+ this.initializeMessageProcessing();
24
+ this.initializeScheduledProcessing();
43
25
  this.storage.saveMetadata([...this.commands, ...this.scheduled], this.name);
26
+ this.telegraf.launch();
27
+ }
28
+ initializeScheduledProcessing() {
29
+ if (this.scheduled.length > 0) {
30
+ taskScheduler_1.Scheduler.createTask('ScheduledProcessing', async () => {
31
+ await this.runScheduled();
32
+ }, (0, timeConvertions_1.hoursToMilliseconds)(0.5), true, this.name);
33
+ }
34
+ }
35
+ initializeMessageProcessing() {
36
+ if (this.commands.length > 0) {
37
+ this.telegraf.on('message', async (ctx) => {
38
+ const msg = new incomingMessage_1.IncomingMessage(ctx.update.message);
39
+ const messageContent = msg.text || '<non-text message>';
40
+ const messageFromName = msg.from?.first_name ?? 'Unknown';
41
+ const messageFromId = msg.from?.id ?? 'Unknown';
42
+ logger_1.Logger.logWithTraceId(this.name, msg.traceId, msg.chatName, `${messageFromName} (${messageFromId}): ${messageContent}`);
43
+ if (msg.text) {
44
+ await this.processMessage(msg);
45
+ }
46
+ });
47
+ }
44
48
  }
45
49
  async stop(code) {
46
50
  logger_1.Logger.logWithTraceId(this.name, `System:Bot-${this.name}-Stop`, 'System', 'Stopping bot...');
@@ -55,14 +59,12 @@ class BotInstance {
55
59
  await trig.exec(ctx);
56
60
  }
57
61
  catch (error) {
58
- console.dir(error);
59
62
  logger_1.Logger.errorWithTraceId(ctx.botName, ctx.traceId, chatName, error, ctx);
60
63
  }
61
64
  }
62
65
  }
63
66
  }
64
- async processMessages() {
65
- const msg = this.messageQueue.pop();
67
+ async processMessage(msg) {
66
68
  for (const cmd of this.commands) {
67
69
  const ctx = this.api.createContextForMessage(msg, cmd.key);
68
70
  try {
@@ -72,6 +74,7 @@ class BotInstance {
72
74
  logger_1.Logger.errorWithTraceId(ctx.botName, ctx.traceId, ctx.chatName, error, ctx);
73
75
  }
74
76
  }
77
+ this.api.flushResponses();
75
78
  }
76
79
  }
77
80
  exports.BotInstance = BotInstance;
@@ -1,5 +1,6 @@
1
1
  import { IBotApiInteractions } from '../../services/telegramApi';
2
2
  import { IStorageClient } from '../../types/storage';
3
+ import { MessageSendingOptions, TextMessageSendingOptions } from '../../types/messageSendingOptions';
3
4
  export declare class ChatContext {
4
5
  botName: string;
5
6
  actionKey: string;
@@ -9,9 +10,9 @@ export declare class ChatContext {
9
10
  traceId: number | string;
10
11
  storage: IStorageClient;
11
12
  constructor(botName: string, actionKey: string, interactions: IBotApiInteractions, chatId: number, chatName: string, traceId: number | string, storage: IStorageClient);
12
- sendTextToChat(text: string, disableWebPreview?: boolean, pinned?: boolean): void;
13
- sendImageToChat(name: string, pinned?: boolean): void;
14
- sendVideoToChat(name: string, pinned?: boolean): void;
13
+ sendTextToChat(text: string, options?: TextMessageSendingOptions): void;
14
+ sendImageToChat(name: string, options?: MessageSendingOptions): void;
15
+ sendVideoToChat(name: string, options?: MessageSendingOptions): void;
15
16
  unpinMessage(messageId: number): void;
16
17
  }
17
18
  //# sourceMappingURL=chatContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chatContext.d.ts","sourceRoot":"","sources":["../../../entities/context/chatContext.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAMrD,qBAAa,WAAW;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,mBAAmB,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,OAAO,EAAE,cAAc,CAAC;gBAGpB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,mBAAmB,EACjC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,OAAO,EAAE,cAAc;IAW3B,cAAc,CACV,IAAI,EAAE,MAAM,EACZ,iBAAiB,CAAC,EAAE,OAAO,EAC3B,MAAM,CAAC,EAAE,OAAO;IAepB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO;IAc9C,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO;IAc9C,YAAY,CAAC,SAAS,EAAE,MAAM;CAUjC"}
1
+ {"version":3,"file":"chatContext.d.ts","sourceRoot":"","sources":["../../../entities/context/chatContext.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAKrD,OAAO,EACH,qBAAqB,EACrB,yBAAyB,EAC5B,MAAM,mCAAmC,CAAC;AAE3C,qBAAa,WAAW;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,mBAAmB,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,OAAO,EAAE,cAAc,CAAC;gBAGpB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,mBAAmB,EACjC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,OAAO,EAAE,cAAc;IAW3B,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,yBAAyB;IAahE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB;IAc7D,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB;IAc7D,YAAY,CAAC,SAAS,EAAE,MAAM;CAUjC"}
@@ -16,16 +16,16 @@ class ChatContext {
16
16
  this.traceId = traceId;
17
17
  this.storage = storage;
18
18
  }
19
- sendTextToChat(text, disableWebPreview, pinned) {
20
- this.interactions.respond(new textMessage_1.TextMessage(text, this.chatId, undefined, this.traceId, disableWebPreview ?? false, pinned ?? false, this.actionKey));
19
+ sendTextToChat(text, options) {
20
+ this.interactions.respond(new textMessage_1.TextMessage(text, this.chatId, undefined, this.traceId, this.actionKey, options));
21
21
  }
22
- sendImageToChat(name, pinned) {
22
+ sendImageToChat(name, options) {
23
23
  const filePath = `./content/${name}.png`;
24
- this.interactions.respond(new imageMessage_1.ImageMessage({ source: (0, path_1.resolve)(filePath) }, this.chatId, undefined, this.traceId, pinned ?? false, this.actionKey));
24
+ this.interactions.respond(new imageMessage_1.ImageMessage({ source: (0, path_1.resolve)(filePath) }, this.chatId, undefined, this.traceId, this.actionKey, options));
25
25
  }
26
- sendVideoToChat(name, pinned) {
26
+ sendVideoToChat(name, options) {
27
27
  const filePath = `./content/${name}.mp4`;
28
- this.interactions.respond(new videoMessage_1.VideoMessage({ source: (0, path_1.resolve)(filePath) }, this.chatId, undefined, this.traceId, pinned ?? false, this.actionKey));
28
+ this.interactions.respond(new videoMessage_1.VideoMessage({ source: (0, path_1.resolve)(filePath) }, this.chatId, undefined, this.traceId, this.actionKey, options));
29
29
  }
30
30
  unpinMessage(messageId) {
31
31
  this.interactions.unpin(new unpin_1.UnpinResponse(messageId, this.chatId, this.traceId, this.actionKey));
@@ -3,6 +3,7 @@ import { TelegramEmoji } from 'telegraf/types';
3
3
  import { IStorageClient } from '../../types/storage';
4
4
  import { IActionState } from '../../types/actionState';
5
5
  import { ChatContext } from './chatContext';
6
+ import { MessageSendingOptions, TextMessageSendingOptions } from '../../types/messageSendingOptions';
6
7
  export declare class MessageContext<TActionState extends IActionState> extends ChatContext {
7
8
  messageId: number;
8
9
  messageText: string;
@@ -14,9 +15,9 @@ export declare class MessageContext<TActionState extends IActionState> extends C
14
15
  constructor(botName: string, scheduledKey: string, interactions: IBotApiInteractions, chatId: number, chatName: string, messageId: number, messageText: string, fromUserId: number | undefined, traceId: number | string, fromUserName: string, storage: IStorageClient);
15
16
  loadStateOf<TAnotherActionState extends IActionState>(commandName: string): Promise<TAnotherActionState>;
16
17
  updateState(stateUpdateAction: (state: TActionState) => void): void;
17
- replyWithText(text: string, disableWebPreview?: boolean, pinned?: boolean): void;
18
- replyWithImage(name: string, pinned?: boolean): void;
19
- replyWithVideo(name: string, pinned?: boolean): void;
18
+ replyWithText(text: string, options?: TextMessageSendingOptions): void;
19
+ replyWithImage(name: string, options?: MessageSendingOptions): void;
20
+ replyWithVideo(name: string, options?: MessageSendingOptions): void;
20
21
  react(emoji: TelegramEmoji): void;
21
22
  }
22
23
  //# sourceMappingURL=messageContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"messageContext.d.ts","sourceRoot":"","sources":["../../../entities/context/messageContext.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAMvD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,qBAAa,cAAc,CACvB,YAAY,SAAS,YAAY,CACnC,SAAQ,WAAW;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,gBAAgB,EAAE,CAAM;IACtC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,aAAa,EAAE,OAAO,CAAQ;IAC9B,aAAa,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC,CAAM;IACzD,YAAY,EAAE,MAAM,CAAC;gBAGjB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,mBAAmB,EACjC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,cAAc;IAkBrB,WAAW,CAAC,mBAAmB,SAAS,YAAY,EACtD,WAAW,EAAE,MAAM,GACpB,OAAO,CAAC,mBAAmB,CAAC;IAU/B,WAAW,CAAC,iBAAiB,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI;IAM5D,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO;IAczE,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO;IAc7C,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO;IAc7C,KAAK,CAAC,KAAK,EAAE,aAAa;CAW7B"}
1
+ {"version":3,"file":"messageContext.d.ts","sourceRoot":"","sources":["../../../entities/context/messageContext.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAMvD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EACH,qBAAqB,EACrB,yBAAyB,EAC5B,MAAM,mCAAmC,CAAC;AAE3C,qBAAa,cAAc,CACvB,YAAY,SAAS,YAAY,CACnC,SAAQ,WAAW;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,gBAAgB,EAAE,CAAM;IACtC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,aAAa,EAAE,OAAO,CAAQ;IAC9B,aAAa,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC,CAAM;IACzD,YAAY,EAAE,MAAM,CAAC;gBAGjB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,mBAAmB,EACjC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,cAAc;IAkBrB,WAAW,CAAC,mBAAmB,SAAS,YAAY,EACtD,WAAW,EAAE,MAAM,GACpB,OAAO,CAAC,mBAAmB,CAAC;IAU/B,WAAW,CAAC,iBAAiB,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI;IAM5D,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,yBAAyB;IAa/D,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB;IAc5D,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB;IAc5D,KAAK,CAAC,KAAK,EAAE,aAAa;CAW7B"}
@@ -25,16 +25,16 @@ class MessageContext extends chatContext_1.ChatContext {
25
25
  updateState(stateUpdateAction) {
26
26
  this.updateActions.push(stateUpdateAction);
27
27
  }
28
- replyWithText(text, disableWebPreview, pinned) {
29
- this.interactions.respond(new textMessage_1.TextMessage(text, this.chatId, this.messageId, this.traceId, disableWebPreview ?? false, pinned ?? false, this.actionKey));
28
+ replyWithText(text, options) {
29
+ this.interactions.respond(new textMessage_1.TextMessage(text, this.chatId, this.messageId, this.traceId, this.actionKey, options));
30
30
  }
31
- replyWithImage(name, pinned) {
31
+ replyWithImage(name, options) {
32
32
  const filePath = `./content/${name}.png`;
33
- this.interactions.respond(new imageMessage_1.ImageMessage({ source: (0, path_1.resolve)(filePath) }, this.chatId, this.messageId, this.traceId, pinned ?? false, this.actionKey));
33
+ this.interactions.respond(new imageMessage_1.ImageMessage({ source: (0, path_1.resolve)(filePath) }, this.chatId, this.messageId, this.traceId, this.actionKey, options));
34
34
  }
35
- replyWithVideo(name, pinned) {
35
+ replyWithVideo(name, options) {
36
36
  const filePath = `./content/${name}.mp4`;
37
- this.interactions.respond(new videoMessage_1.VideoMessage({ source: (0, path_1.resolve)(filePath) }, this.chatId, this.messageId, this.traceId, pinned ?? false, this.actionKey));
37
+ this.interactions.respond(new videoMessage_1.VideoMessage({ source: (0, path_1.resolve)(filePath) }, this.chatId, this.messageId, this.traceId, this.actionKey, options));
38
38
  }
39
39
  react(emoji) {
40
40
  this.interactions.react(new reaction_1.Reaction(this.traceId, this.chatId, this.messageId, emoji, this.actionKey));
@@ -1,5 +1,6 @@
1
1
  import { InputFile } from 'telegraf/types';
2
2
  import { IReplyMessage } from '../../types/response';
3
+ import { MessageSendingOptions } from '../../types/messageSendingOptions';
3
4
  export declare class ImageMessage implements IReplyMessage<InputFile> {
4
5
  kind: "image";
5
6
  content: InputFile;
@@ -9,6 +10,6 @@ export declare class ImageMessage implements IReplyMessage<InputFile> {
9
10
  disableWebPreview: boolean;
10
11
  shouldPin: boolean;
11
12
  sourceActionKey: string;
12
- constructor(image: InputFile, chatId: number, replyId: number | undefined, traceId: number | string, pinned: boolean, sourceActionKey: string);
13
+ constructor(image: InputFile, chatId: number, replyId: number | undefined, traceId: number | string, sourceActionKey: string, options?: MessageSendingOptions);
13
14
  }
14
15
  //# sourceMappingURL=imageMessage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"imageMessage.d.ts","sourceRoot":"","sources":["../../../entities/responses/imageMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAoB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEvE,qBAAa,YAAa,YAAW,aAAa,CAAC,SAAS,CAAC;IACzD,IAAI,UAA0B;IAE9B,OAAO,EAAE,SAAS,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,iBAAiB,UAAS;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;gBAGpB,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,MAAM,EAAE,OAAO,EACf,eAAe,EAAE,MAAM;CAS9B"}
1
+ {"version":3,"file":"imageMessage.d.ts","sourceRoot":"","sources":["../../../entities/responses/imageMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAoB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,qBAAa,YAAa,YAAW,aAAa,CAAC,SAAS,CAAC;IACzD,IAAI,UAA0B;IAE9B,OAAO,EAAE,SAAS,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,iBAAiB,UAAS;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;gBAGpB,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,qBAAqB;CAStC"}
@@ -3,14 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ImageMessage = void 0;
4
4
  const response_1 = require("../../types/response");
5
5
  class ImageMessage {
6
- constructor(image, chatId, replyId, traceId, pinned, sourceActionKey) {
6
+ constructor(image, chatId, replyId, traceId, sourceActionKey, options) {
7
7
  this.kind = response_1.BotResponseTypes.image;
8
8
  this.disableWebPreview = false;
9
9
  this.content = image;
10
10
  this.chatId = chatId;
11
11
  this.replyId = replyId;
12
12
  this.traceId = traceId;
13
- this.shouldPin = pinned;
13
+ this.shouldPin = options?.pin ?? false;
14
14
  this.sourceActionKey = sourceActionKey;
15
15
  }
16
16
  }
@@ -1,3 +1,4 @@
1
+ import { TextMessageSendingOptions } from '../../types/messageSendingOptions';
1
2
  import { IReplyMessage } from '../../types/response';
2
3
  export declare class TextMessage implements IReplyMessage<string> {
3
4
  kind: "text";
@@ -8,6 +9,6 @@ export declare class TextMessage implements IReplyMessage<string> {
8
9
  disableWebPreview: boolean;
9
10
  shouldPin: boolean;
10
11
  sourceActionKey: string;
11
- constructor(text: string, chatId: number, replyId: number | undefined, traceId: string | number, disableWebPreview: boolean, pinned: boolean, sourceActionKey: string);
12
+ constructor(text: string, chatId: number, replyId: number | undefined, traceId: string | number, sourceActionKey: string, options?: TextMessageSendingOptions);
12
13
  }
13
14
  //# sourceMappingURL=textMessage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"textMessage.d.ts","sourceRoot":"","sources":["../../../entities/responses/textMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEvE,qBAAa,WAAY,YAAW,aAAa,CAAC,MAAM,CAAC;IACrD,IAAI,SAAyB;IAE7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;gBAGpB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,iBAAiB,EAAE,OAAO,EAC1B,MAAM,EAAE,OAAO,EACf,eAAe,EAAE,MAAM;CAU9B"}
1
+ {"version":3,"file":"textMessage.d.ts","sourceRoot":"","sources":["../../../entities/responses/textMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAoB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEvE,qBAAa,WAAY,YAAW,aAAa,CAAC,MAAM,CAAC;IACrD,IAAI,SAAyB;IAE7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;gBAGpB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,yBAAyB;CAU1C"}
@@ -3,14 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TextMessage = void 0;
4
4
  const response_1 = require("../../types/response");
5
5
  class TextMessage {
6
- constructor(text, chatId, replyId, traceId, disableWebPreview, pinned, sourceActionKey) {
6
+ constructor(text, chatId, replyId, traceId, sourceActionKey, options) {
7
7
  this.kind = response_1.BotResponseTypes.text;
8
8
  this.content = text;
9
9
  this.chatId = chatId;
10
10
  this.replyId = replyId;
11
11
  this.traceId = traceId;
12
- this.disableWebPreview = disableWebPreview;
13
- this.shouldPin = pinned;
12
+ this.disableWebPreview = options?.disableWebPreview ?? false;
13
+ this.shouldPin = options?.pin ?? false;
14
14
  this.sourceActionKey = sourceActionKey;
15
15
  }
16
16
  }
@@ -1,5 +1,6 @@
1
1
  import { InputFile } from 'telegraf/types';
2
2
  import { IReplyMessage } from '../../types/response';
3
+ import { MessageSendingOptions } from '../../types/messageSendingOptions';
3
4
  export declare class VideoMessage implements IReplyMessage<InputFile> {
4
5
  kind: "video";
5
6
  content: InputFile;
@@ -9,6 +10,6 @@ export declare class VideoMessage implements IReplyMessage<InputFile> {
9
10
  disableWebPreview: boolean;
10
11
  shouldPin: boolean;
11
12
  sourceActionKey: string;
12
- constructor(video: InputFile, chatId: number, replyId: number | undefined, traceId: number | string, pinned: boolean, sourceActionKey: string);
13
+ constructor(video: InputFile, chatId: number, replyId: number | undefined, traceId: number | string, sourceActionKey: string, options?: MessageSendingOptions);
13
14
  }
14
15
  //# sourceMappingURL=videoMessage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"videoMessage.d.ts","sourceRoot":"","sources":["../../../entities/responses/videoMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAoB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEvE,qBAAa,YAAa,YAAW,aAAa,CAAC,SAAS,CAAC;IACzD,IAAI,UAA0B;IAE9B,OAAO,EAAE,SAAS,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,iBAAiB,UAAS;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;gBAGpB,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,MAAM,EAAE,OAAO,EACf,eAAe,EAAE,MAAM;CAS9B"}
1
+ {"version":3,"file":"videoMessage.d.ts","sourceRoot":"","sources":["../../../entities/responses/videoMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAoB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,qBAAa,YAAa,YAAW,aAAa,CAAC,SAAS,CAAC;IACzD,IAAI,UAA0B;IAE9B,OAAO,EAAE,SAAS,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,iBAAiB,UAAS;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;gBAGpB,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,qBAAqB;CAStC"}
@@ -3,14 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VideoMessage = void 0;
4
4
  const response_1 = require("../../types/response");
5
5
  class VideoMessage {
6
- constructor(video, chatId, replyId, traceId, pinned, sourceActionKey) {
6
+ constructor(video, chatId, replyId, traceId, sourceActionKey, options) {
7
7
  this.kind = response_1.BotResponseTypes.video;
8
8
  this.disableWebPreview = false;
9
9
  this.content = video;
10
10
  this.chatId = chatId;
11
11
  this.replyId = replyId;
12
12
  this.traceId = traceId;
13
- this.shouldPin = pinned;
13
+ this.shouldPin = options?.pin ?? false;
14
14
  this.sourceActionKey = sourceActionKey;
15
15
  }
16
16
  }
@@ -10,13 +10,14 @@ import { VideoMessage } from '../entities/responses/videoMessage';
10
10
  import { ImageMessage } from '../entities/responses/imageMessage';
11
11
  import { Telegram } from 'telegraf/typings/telegram';
12
12
  export declare class TelegramApiService {
13
+ isFlushing: boolean;
14
+ messageQueue: Array<BotResponse>;
13
15
  botName: string;
14
16
  telegram: Telegram;
15
17
  chats: Map<number, string>;
16
- messageQueue: Array<BotResponse>;
17
18
  storage: IStorageClient;
18
19
  constructor(botName: string, telegram: Telegram, storage: IStorageClient, chats: Map<string, number>);
19
- private dequeueResponse;
20
+ flushResponses(): Promise<void>;
20
21
  private pinIfShould;
21
22
  private processResponse;
22
23
  private enqueue;
@@ -1 +1 @@
1
- {"version":3,"file":"telegramApi.d.ts","sourceRoot":"","sources":["../../services/telegramApi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAIlD,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAiB,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD,qBAAa,kBAAkB;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,CAAM;IACtC,OAAO,EAAE,cAAc,CAAC;gBAGpB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;YAkBhB,eAAe;YAkBf,WAAW;YAqBX,eAAe;IA2E7B,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,eAAe;IAQvB,uBAAuB,CACnB,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,MAAM;IAsBtB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAW5D;AAED,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,CAAC,QAAQ,EAAE,WAAW,GAAG,YAAY,GAAG,YAAY,KAAK,IAAI,CAAC;IACvE,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,KAAK,EAAE,CAAC,YAAY,EAAE,aAAa,KAAK,IAAI,CAAC;CAChD"}
1
+ {"version":3,"file":"telegramApi.d.ts","sourceRoot":"","sources":["../../services/telegramApi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAiB,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAIrD,qBAAa,kBAAkB;IAC3B,UAAU,UAAS;IACnB,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,CAAM;IAEtC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,OAAO,EAAE,cAAc,CAAC;gBAGpB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAQxB,cAAc;YAyBN,WAAW;YAqBX,eAAe;IA2E7B,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,eAAe;IAQvB,uBAAuB,CACnB,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,MAAM;IAsBtB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAW5D;AAED,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,CAAC,QAAQ,EAAE,WAAW,GAAG,YAAY,GAAG,YAAY,KAAK,IAAI,CAAC;IACvE,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,KAAK,EAAE,CAAC,YAAY,EAAE,aAAa,KAAK,IAAI,CAAC;CAChD"}
@@ -4,29 +4,33 @@ exports.TelegramApiService = void 0;
4
4
  const chatContext_1 = require("../entities/context/chatContext");
5
5
  const messageContext_1 = require("../entities/context/messageContext");
6
6
  const reverseMap_1 = require("../helpers/reverseMap");
7
- const taskScheduler_1 = require("./taskScheduler");
8
7
  const logger_1 = require("./logger");
8
+ const promises_1 = require("timers/promises");
9
9
  class TelegramApiService {
10
10
  constructor(botName, telegram, storage, chats) {
11
+ this.isFlushing = false;
11
12
  this.messageQueue = [];
12
13
  this.telegram = telegram;
13
14
  this.botName = botName;
14
15
  this.chats = (0, reverseMap_1.reverseMap)(chats);
15
16
  this.storage = storage;
16
- taskScheduler_1.Scheduler.createTask('MessageSending', () => {
17
- this.dequeueResponse();
18
- }, 100, false, this.botName);
19
17
  }
20
- async dequeueResponse() {
21
- const message = this.messageQueue.pop();
22
- if (!message)
18
+ async flushResponses() {
19
+ if (this.isFlushing)
23
20
  return;
24
- try {
25
- await this.processResponse(message);
26
- }
27
- catch (error) {
28
- logger_1.Logger.errorWithTraceId(this.botName, message.traceId, this.chats.get(message.chatId), error, message);
21
+ while (this.messageQueue.length) {
22
+ const message = this.messageQueue.pop();
23
+ if (!message)
24
+ break;
25
+ try {
26
+ await this.processResponse(message);
27
+ await (0, promises_1.setTimeout)(100);
28
+ }
29
+ catch (error) {
30
+ logger_1.Logger.errorWithTraceId(this.botName, message.traceId, this.chats.get(message.chatId), error, message);
31
+ }
29
32
  }
33
+ this.isFlushing = false;
30
34
  }
31
35
  async pinIfShould(response, sentMessage) {
32
36
  if (response.shouldPin) {
@@ -78,8 +82,8 @@ class TelegramApiService {
78
82
  break;
79
83
  }
80
84
  }
81
- enqueue(reaction) {
82
- this.messageQueue.push(reaction);
85
+ enqueue(response) {
86
+ this.messageQueue.push(response);
83
87
  }
84
88
  getInteractions() {
85
89
  return {
@@ -0,0 +1,7 @@
1
+ export interface MessageSendingOptions {
2
+ pin?: boolean;
3
+ }
4
+ export interface TextMessageSendingOptions extends MessageSendingOptions {
5
+ disableWebPreview?: boolean;
6
+ }
7
+ //# sourceMappingURL=messageSendingOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messageSendingOptions.d.ts","sourceRoot":"","sources":["../../types/messageSendingOptions.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IAClC,GAAG,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,yBAA0B,SAAQ,qBAAqB;IACpE,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,9 +1,6 @@
1
1
  import { Telegraf } from 'telegraf';
2
- import {
3
- hoursToMilliseconds,
4
- secondsToMilliseconds
5
- } from '../helpers/timeConvertions';
6
- import { Hours, Seconds } from '../types/timeValues';
2
+ import { hoursToMilliseconds } from '../helpers/timeConvertions';
3
+ import { Hours } from '../types/timeValues';
7
4
  import { IStorageClient } from '../types/storage';
8
5
  import { JsonFileStorage } from '../services/jsonFileStorage';
9
6
  import { TelegramApiService } from '../services/telegramApi';
@@ -21,7 +18,6 @@ export class BotInstance {
21
18
  private commands: CommandAction<IActionState>[];
22
19
  private scheduled: ScheduledAction<IActionState>[];
23
20
  private chats: Map<string, number>;
24
- private messageQueue: IncomingMessage[] = [];
25
21
  storage: IStorageClient;
26
22
 
27
23
  constructor(options: {
@@ -55,52 +51,51 @@ export class BotInstance {
55
51
  this.chats
56
52
  );
57
53
 
58
- this.telegraf.on('message', async (ctx) => {
59
- const msg = new IncomingMessage(ctx.update.message);
60
- const messageContent = msg.text || '<non-text message>';
61
-
62
- const messageFromName = msg.from?.first_name ?? 'Unknown';
63
- const messageFromId = msg.from?.id ?? 'Unknown';
64
- Logger.logWithTraceId(
65
- this.name,
66
- msg.traceId,
67
- msg.chatName,
68
- `${messageFromName} (${messageFromId}): ${messageContent}`
69
- );
54
+ this.initializeMessageProcessing();
55
+ this.initializeScheduledProcessing();
70
56
 
71
- if (msg.text) {
72
- this.messageQueue.push(msg);
73
- }
74
- });
57
+ this.storage.saveMetadata(
58
+ [...this.commands, ...this.scheduled],
59
+ this.name
60
+ );
75
61
 
76
62
  this.telegraf.launch();
63
+ }
77
64
 
78
- Scheduler.createTask(
79
- 'MessageProcessing',
80
- async () => {
81
- while (this.messageQueue.length > 0) {
82
- await this.processMessages();
83
- }
84
- },
85
- secondsToMilliseconds(0.3 as Seconds),
86
- false,
87
- this.name
88
- );
65
+ private initializeScheduledProcessing() {
66
+ if (this.scheduled.length > 0) {
67
+ Scheduler.createTask(
68
+ 'ScheduledProcessing',
69
+ async () => {
70
+ await this.runScheduled();
71
+ },
72
+ hoursToMilliseconds(0.5 as Hours),
73
+ true,
74
+ this.name
75
+ );
76
+ }
77
+ }
89
78
 
90
- Scheduler.createTask(
91
- 'ScheduledProcessing',
92
- async () => {
93
- await this.runScheduled();
94
- },
95
- hoursToMilliseconds(0.5 as Hours),
96
- true,
97
- this.name
98
- );
79
+ private initializeMessageProcessing() {
80
+ if (this.commands.length > 0) {
81
+ this.telegraf.on('message', async (ctx) => {
82
+ const msg = new IncomingMessage(ctx.update.message);
83
+ const messageContent = msg.text || '<non-text message>';
84
+
85
+ const messageFromName = msg.from?.first_name ?? 'Unknown';
86
+ const messageFromId = msg.from?.id ?? 'Unknown';
87
+ Logger.logWithTraceId(
88
+ this.name,
89
+ msg.traceId,
90
+ msg.chatName,
91
+ `${messageFromName} (${messageFromId}): ${messageContent}`
92
+ );
99
93
 
100
- this.storage.saveMetadata(
101
- [...this.commands, ...this.scheduled],
102
- this.name
103
- );
94
+ if (msg.text) {
95
+ await this.processMessage(msg);
96
+ }
97
+ });
98
+ }
104
99
  }
105
100
 
106
101
  async stop(code: string) {
@@ -123,7 +118,6 @@ export class BotInstance {
123
118
  try {
124
119
  await trig.exec(ctx);
125
120
  } catch (error) {
126
- console.dir(error);
127
121
  Logger.errorWithTraceId(
128
122
  ctx.botName,
129
123
  ctx.traceId,
@@ -136,9 +130,7 @@ export class BotInstance {
136
130
  }
137
131
  }
138
132
 
139
- private async processMessages() {
140
- const msg = this.messageQueue.pop()!;
141
-
133
+ private async processMessage(msg: IncomingMessage) {
142
134
  for (const cmd of this.commands) {
143
135
  const ctx = this.api.createContextForMessage(msg, cmd.key);
144
136
 
@@ -154,5 +146,7 @@ export class BotInstance {
154
146
  );
155
147
  }
156
148
  }
149
+
150
+ this.api.flushResponses();
157
151
  }
158
152
  }
@@ -5,6 +5,10 @@ import { ImageMessage } from '../responses/imageMessage';
5
5
  import { TextMessage } from '../responses/textMessage';
6
6
  import { VideoMessage } from '../responses/videoMessage';
7
7
  import { UnpinResponse } from '../responses/unpin';
8
+ import {
9
+ MessageSendingOptions,
10
+ TextMessageSendingOptions
11
+ } from '../../types/messageSendingOptions';
8
12
 
9
13
  export class ChatContext {
10
14
  botName: string;
@@ -33,25 +37,20 @@ export class ChatContext {
33
37
  this.storage = storage;
34
38
  }
35
39
 
36
- sendTextToChat(
37
- text: string,
38
- disableWebPreview?: boolean,
39
- pinned?: boolean
40
- ) {
40
+ sendTextToChat(text: string, options?: TextMessageSendingOptions) {
41
41
  this.interactions.respond(
42
42
  new TextMessage(
43
43
  text,
44
44
  this.chatId,
45
45
  undefined,
46
46
  this.traceId,
47
- disableWebPreview ?? false,
48
- pinned ?? false,
49
- this.actionKey
47
+ this.actionKey,
48
+ options
50
49
  )
51
50
  );
52
51
  }
53
52
 
54
- sendImageToChat(name: string, pinned?: boolean) {
53
+ sendImageToChat(name: string, options?: MessageSendingOptions) {
55
54
  const filePath = `./content/${name}.png`;
56
55
  this.interactions.respond(
57
56
  new ImageMessage(
@@ -59,13 +58,13 @@ export class ChatContext {
59
58
  this.chatId,
60
59
  undefined,
61
60
  this.traceId,
62
- pinned ?? false,
63
- this.actionKey
61
+ this.actionKey,
62
+ options
64
63
  )
65
64
  );
66
65
  }
67
66
 
68
- sendVideoToChat(name: string, pinned?: boolean) {
67
+ sendVideoToChat(name: string, options?: MessageSendingOptions) {
69
68
  const filePath = `./content/${name}.mp4`;
70
69
  this.interactions.respond(
71
70
  new VideoMessage(
@@ -73,8 +72,8 @@ export class ChatContext {
73
72
  this.chatId,
74
73
  undefined,
75
74
  this.traceId,
76
- pinned ?? false,
77
- this.actionKey
75
+ this.actionKey,
76
+ options
78
77
  )
79
78
  );
80
79
  }
@@ -9,6 +9,10 @@ import { TextMessage } from '../responses/textMessage';
9
9
  import { VideoMessage } from '../responses/videoMessage';
10
10
  import { ActionStateBase } from '../states/actionStateBase';
11
11
  import { ChatContext } from './chatContext';
12
+ import {
13
+ MessageSendingOptions,
14
+ TextMessageSendingOptions
15
+ } from '../../types/messageSendingOptions';
12
16
 
13
17
  export class MessageContext<
14
18
  TActionState extends IActionState
@@ -68,21 +72,20 @@ export class MessageContext<
68
72
  );
69
73
  }
70
74
 
71
- replyWithText(text: string, disableWebPreview?: boolean, pinned?: boolean) {
75
+ replyWithText(text: string, options?: TextMessageSendingOptions) {
72
76
  this.interactions.respond(
73
77
  new TextMessage(
74
78
  text,
75
79
  this.chatId,
76
80
  this.messageId,
77
81
  this.traceId,
78
- disableWebPreview ?? false,
79
- pinned ?? false,
80
- this.actionKey
82
+ this.actionKey,
83
+ options
81
84
  )
82
85
  );
83
86
  }
84
87
 
85
- replyWithImage(name: string, pinned?: boolean) {
88
+ replyWithImage(name: string, options?: MessageSendingOptions) {
86
89
  const filePath = `./content/${name}.png`;
87
90
  this.interactions.respond(
88
91
  new ImageMessage(
@@ -90,13 +93,13 @@ export class MessageContext<
90
93
  this.chatId,
91
94
  this.messageId,
92
95
  this.traceId,
93
- pinned ?? false,
94
- this.actionKey
96
+ this.actionKey,
97
+ options
95
98
  )
96
99
  );
97
100
  }
98
101
 
99
- replyWithVideo(name: string, pinned?: boolean) {
102
+ replyWithVideo(name: string, options?: MessageSendingOptions) {
100
103
  const filePath = `./content/${name}.mp4`;
101
104
  this.interactions.respond(
102
105
  new VideoMessage(
@@ -104,8 +107,8 @@ export class MessageContext<
104
107
  this.chatId,
105
108
  this.messageId,
106
109
  this.traceId,
107
- pinned ?? false,
108
- this.actionKey
110
+ this.actionKey,
111
+ options
109
112
  )
110
113
  );
111
114
  }
@@ -1,5 +1,6 @@
1
1
  import { InputFile } from 'telegraf/types';
2
2
  import { BotResponseTypes, IReplyMessage } from '../../types/response';
3
+ import { MessageSendingOptions } from '../../types/messageSendingOptions';
3
4
 
4
5
  export class ImageMessage implements IReplyMessage<InputFile> {
5
6
  kind = BotResponseTypes.image;
@@ -17,14 +18,14 @@ export class ImageMessage implements IReplyMessage<InputFile> {
17
18
  chatId: number,
18
19
  replyId: number | undefined,
19
20
  traceId: number | string,
20
- pinned: boolean,
21
- sourceActionKey: string
21
+ sourceActionKey: string,
22
+ options?: MessageSendingOptions
22
23
  ) {
23
24
  this.content = image;
24
25
  this.chatId = chatId;
25
26
  this.replyId = replyId;
26
27
  this.traceId = traceId;
27
- this.shouldPin = pinned;
28
+ this.shouldPin = options?.pin ?? false;
28
29
  this.sourceActionKey = sourceActionKey;
29
30
  }
30
31
  }
@@ -1,3 +1,4 @@
1
+ import { TextMessageSendingOptions } from '../../types/messageSendingOptions';
1
2
  import { BotResponseTypes, IReplyMessage } from '../../types/response';
2
3
 
3
4
  export class TextMessage implements IReplyMessage<string> {
@@ -16,16 +17,15 @@ export class TextMessage implements IReplyMessage<string> {
16
17
  chatId: number,
17
18
  replyId: number | undefined,
18
19
  traceId: string | number,
19
- disableWebPreview: boolean,
20
- pinned: boolean,
21
- sourceActionKey: string
20
+ sourceActionKey: string,
21
+ options?: TextMessageSendingOptions
22
22
  ) {
23
23
  this.content = text;
24
24
  this.chatId = chatId;
25
25
  this.replyId = replyId;
26
26
  this.traceId = traceId;
27
- this.disableWebPreview = disableWebPreview;
28
- this.shouldPin = pinned;
27
+ this.disableWebPreview = options?.disableWebPreview ?? false;
28
+ this.shouldPin = options?.pin ?? false;
29
29
  this.sourceActionKey = sourceActionKey;
30
30
  }
31
31
  }
@@ -1,5 +1,6 @@
1
1
  import { InputFile } from 'telegraf/types';
2
2
  import { BotResponseTypes, IReplyMessage } from '../../types/response';
3
+ import { MessageSendingOptions } from '../../types/messageSendingOptions';
3
4
 
4
5
  export class VideoMessage implements IReplyMessage<InputFile> {
5
6
  kind = BotResponseTypes.video;
@@ -17,14 +18,14 @@ export class VideoMessage implements IReplyMessage<InputFile> {
17
18
  chatId: number,
18
19
  replyId: number | undefined,
19
20
  traceId: number | string,
20
- pinned: boolean,
21
- sourceActionKey: string
21
+ sourceActionKey: string,
22
+ options?: MessageSendingOptions
22
23
  ) {
23
24
  this.content = video;
24
25
  this.chatId = chatId;
25
26
  this.replyId = replyId;
26
27
  this.traceId = traceId;
27
- this.shouldPin = pinned;
28
+ this.shouldPin = options?.pin ?? false;
28
29
  this.sourceActionKey = sourceActionKey;
29
30
  }
30
31
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chz-telegram-bot",
3
- "version": "0.0.20",
3
+ "version": "0.0.22",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "async-sema": "^3.1.1",
@@ -3,8 +3,6 @@ import { ChatContext } from '../entities/context/chatContext';
3
3
  import { MessageContext } from '../entities/context/messageContext';
4
4
  import { reverseMap } from '../helpers/reverseMap';
5
5
  import { IStorageClient } from '../types/storage';
6
- import { Milliseconds } from '../types/timeValues';
7
- import { Scheduler } from './taskScheduler';
8
6
  import { Logger } from './logger';
9
7
  import { Reaction } from '../entities/responses/reaction';
10
8
  import { IncomingMessage } from '../entities/incomingMessage';
@@ -14,12 +12,16 @@ import { TextMessage } from '../entities/responses/textMessage';
14
12
  import { VideoMessage } from '../entities/responses/videoMessage';
15
13
  import { ImageMessage } from '../entities/responses/imageMessage';
16
14
  import { Telegram } from 'telegraf/typings/telegram';
15
+ import { setTimeout } from 'timers/promises';
16
+ import { Milliseconds } from '../types/timeValues';
17
17
 
18
18
  export class TelegramApiService {
19
+ isFlushing = false;
20
+ messageQueue: Array<BotResponse> = [];
21
+
19
22
  botName: string;
20
23
  telegram: Telegram;
21
24
  chats: Map<number, string>;
22
- messageQueue: Array<BotResponse> = [];
23
25
  storage: IStorageClient;
24
26
 
25
27
  constructor(
@@ -32,34 +34,31 @@ export class TelegramApiService {
32
34
  this.botName = botName;
33
35
  this.chats = reverseMap(chats);
34
36
  this.storage = storage;
35
-
36
- Scheduler.createTask(
37
- 'MessageSending',
38
- () => {
39
- this.dequeueResponse();
40
- },
41
- 100 as Milliseconds,
42
- false,
43
- this.botName
44
- );
45
37
  }
46
38
 
47
- private async dequeueResponse() {
48
- const message = this.messageQueue.pop();
39
+ async flushResponses() {
40
+ if (this.isFlushing) return;
49
41
 
50
- if (!message) return;
42
+ while (this.messageQueue.length) {
43
+ const message = this.messageQueue.pop();
51
44
 
52
- try {
53
- await this.processResponse(message);
54
- } catch (error) {
55
- Logger.errorWithTraceId(
56
- this.botName,
57
- message.traceId,
58
- this.chats.get(message.chatId)!,
59
- error,
60
- message
61
- );
45
+ if (!message) break;
46
+
47
+ try {
48
+ await this.processResponse(message);
49
+ await setTimeout(100 as Milliseconds);
50
+ } catch (error) {
51
+ Logger.errorWithTraceId(
52
+ this.botName,
53
+ message.traceId,
54
+ this.chats.get(message.chatId)!,
55
+ error,
56
+ message
57
+ );
58
+ }
62
59
  }
60
+
61
+ this.isFlushing = false;
63
62
  }
64
63
 
65
64
  private async pinIfShould<T>(
@@ -158,8 +157,8 @@ export class TelegramApiService {
158
157
  }
159
158
  }
160
159
 
161
- private enqueue(reaction: BotResponse) {
162
- this.messageQueue.push(reaction);
160
+ private enqueue(response: BotResponse) {
161
+ this.messageQueue.push(response);
163
162
  }
164
163
 
165
164
  private getInteractions() {
@@ -0,0 +1,7 @@
1
+ export interface MessageSendingOptions {
2
+ pin?: boolean;
3
+ }
4
+
5
+ export interface TextMessageSendingOptions extends MessageSendingOptions {
6
+ disableWebPreview?: boolean;
7
+ }