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.
- package/dist/entities/botInstance.d.ts +3 -2
- package/dist/entities/botInstance.d.ts.map +1 -1
- package/dist/entities/botInstance.js +26 -23
- package/dist/entities/context/chatContext.d.ts +4 -3
- package/dist/entities/context/chatContext.d.ts.map +1 -1
- package/dist/entities/context/chatContext.js +6 -6
- package/dist/entities/context/messageContext.d.ts +4 -3
- package/dist/entities/context/messageContext.d.ts.map +1 -1
- package/dist/entities/context/messageContext.js +6 -6
- package/dist/entities/responses/imageMessage.d.ts +2 -1
- package/dist/entities/responses/imageMessage.d.ts.map +1 -1
- package/dist/entities/responses/imageMessage.js +2 -2
- package/dist/entities/responses/textMessage.d.ts +2 -1
- package/dist/entities/responses/textMessage.d.ts.map +1 -1
- package/dist/entities/responses/textMessage.js +3 -3
- package/dist/entities/responses/videoMessage.d.ts +2 -1
- package/dist/entities/responses/videoMessage.d.ts.map +1 -1
- package/dist/entities/responses/videoMessage.js +2 -2
- package/dist/services/telegramApi.d.ts +3 -2
- package/dist/services/telegramApi.d.ts.map +1 -1
- package/dist/services/telegramApi.js +18 -14
- package/dist/types/messageSendingOptions.d.ts +7 -0
- package/dist/types/messageSendingOptions.d.ts.map +1 -0
- package/dist/types/messageSendingOptions.js +2 -0
- package/entities/botInstance.ts +44 -50
- package/entities/context/chatContext.ts +13 -14
- package/entities/context/messageContext.ts +13 -10
- package/entities/responses/imageMessage.ts +4 -3
- package/entities/responses/textMessage.ts +5 -5
- package/entities/responses/videoMessage.ts +4 -3
- package/package.json +1 -1
- package/services/telegramApi.ts +27 -28
- 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
|
|
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":"
|
|
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.
|
|
25
|
-
|
|
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
|
|
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,
|
|
13
|
-
sendImageToChat(name: string,
|
|
14
|
-
sendVideoToChat(name: string,
|
|
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;
|
|
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,
|
|
20
|
-
this.interactions.respond(new textMessage_1.TextMessage(text, this.chatId, undefined, this.traceId,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
18
|
-
replyWithImage(name: string,
|
|
19
|
-
replyWithVideo(name: string,
|
|
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;
|
|
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,
|
|
29
|
-
this.interactions.respond(new textMessage_1.TextMessage(text, this.chatId, this.messageId, this.traceId,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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;
|
|
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,
|
|
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 =
|
|
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,
|
|
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,
|
|
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,
|
|
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 =
|
|
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,
|
|
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;
|
|
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,
|
|
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 =
|
|
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
|
-
|
|
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;
|
|
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
|
|
21
|
-
|
|
22
|
-
if (!message)
|
|
18
|
+
async flushResponses() {
|
|
19
|
+
if (this.isFlushing)
|
|
23
20
|
return;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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(
|
|
82
|
-
this.messageQueue.push(
|
|
85
|
+
enqueue(response) {
|
|
86
|
+
this.messageQueue.push(response);
|
|
83
87
|
}
|
|
84
88
|
getInteractions() {
|
|
85
89
|
return {
|
|
@@ -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"}
|
package/entities/botInstance.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { Telegraf } from 'telegraf';
|
|
2
|
-
import {
|
|
3
|
-
|
|
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.
|
|
59
|
-
|
|
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
|
-
|
|
72
|
-
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
async () => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
this.actionKey
|
|
47
|
+
this.actionKey,
|
|
48
|
+
options
|
|
50
49
|
)
|
|
51
50
|
);
|
|
52
51
|
}
|
|
53
52
|
|
|
54
|
-
sendImageToChat(name: string,
|
|
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
|
-
|
|
63
|
-
|
|
61
|
+
this.actionKey,
|
|
62
|
+
options
|
|
64
63
|
)
|
|
65
64
|
);
|
|
66
65
|
}
|
|
67
66
|
|
|
68
|
-
sendVideoToChat(name: string,
|
|
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
|
-
|
|
77
|
-
|
|
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,
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
this.actionKey
|
|
82
|
+
this.actionKey,
|
|
83
|
+
options
|
|
81
84
|
)
|
|
82
85
|
);
|
|
83
86
|
}
|
|
84
87
|
|
|
85
|
-
replyWithImage(name: string,
|
|
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
|
-
|
|
94
|
-
|
|
96
|
+
this.actionKey,
|
|
97
|
+
options
|
|
95
98
|
)
|
|
96
99
|
);
|
|
97
100
|
}
|
|
98
101
|
|
|
99
|
-
replyWithVideo(name: string,
|
|
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
|
-
|
|
108
|
-
|
|
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
|
-
|
|
21
|
-
|
|
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 =
|
|
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
|
-
|
|
20
|
-
|
|
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 =
|
|
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
|
-
|
|
21
|
-
|
|
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 =
|
|
28
|
+
this.shouldPin = options?.pin ?? false;
|
|
28
29
|
this.sourceActionKey = sourceActionKey;
|
|
29
30
|
}
|
|
30
31
|
}
|
package/package.json
CHANGED
package/services/telegramApi.ts
CHANGED
|
@@ -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
|
-
|
|
48
|
-
|
|
39
|
+
async flushResponses() {
|
|
40
|
+
if (this.isFlushing) return;
|
|
49
41
|
|
|
50
|
-
|
|
42
|
+
while (this.messageQueue.length) {
|
|
43
|
+
const message = this.messageQueue.pop();
|
|
51
44
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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(
|
|
162
|
-
this.messageQueue.push(
|
|
160
|
+
private enqueue(response: BotResponse) {
|
|
161
|
+
this.messageQueue.push(response);
|
|
163
162
|
}
|
|
164
163
|
|
|
165
164
|
private getInteractions() {
|