chz-telegram-bot 0.0.16 → 0.0.17
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.js +3 -3
- package/dist/entities/context/chatContext.d.ts +6 -4
- package/dist/entities/context/chatContext.d.ts.map +1 -1
- package/dist/entities/context/chatContext.js +12 -7
- package/dist/entities/context/messageContext.d.ts +4 -4
- package/dist/entities/context/messageContext.d.ts.map +1 -1
- package/dist/entities/context/messageContext.js +9 -9
- package/dist/entities/responses/imageMessage.d.ts +5 -2
- package/dist/entities/responses/imageMessage.d.ts.map +1 -1
- package/dist/entities/responses/imageMessage.js +5 -1
- package/dist/entities/responses/reaction.d.ts +5 -2
- package/dist/entities/responses/reaction.d.ts.map +1 -1
- package/dist/entities/responses/reaction.js +4 -1
- package/dist/entities/responses/textMessage.d.ts +5 -2
- package/dist/entities/responses/textMessage.d.ts.map +1 -1
- package/dist/entities/responses/textMessage.js +5 -1
- package/dist/entities/responses/unpin.d.ts +10 -0
- package/dist/entities/responses/unpin.d.ts.map +1 -0
- package/dist/entities/responses/unpin.js +14 -0
- package/dist/entities/responses/videoMessage.d.ts +5 -2
- package/dist/entities/responses/videoMessage.d.ts.map +1 -1
- package/dist/entities/responses/videoMessage.js +5 -1
- package/dist/entities/states/actionStateBase.d.ts +1 -0
- package/dist/entities/states/actionStateBase.d.ts.map +1 -1
- package/dist/entities/states/actionStateBase.js +1 -0
- package/dist/services/jsonFileStorage.d.ts +1 -0
- package/dist/services/jsonFileStorage.d.ts.map +1 -1
- package/dist/services/jsonFileStorage.js +8 -0
- package/dist/services/telegramApi.d.ts +15 -10
- package/dist/services/telegramApi.d.ts.map +1 -1
- package/dist/services/telegramApi.js +42 -33
- package/dist/types/actionState.d.ts +1 -0
- package/dist/types/actionState.d.ts.map +1 -1
- package/dist/types/response.d.ts +26 -0
- package/dist/types/response.d.ts.map +1 -0
- package/dist/types/response.js +10 -0
- package/dist/types/storage.d.ts +1 -0
- package/dist/types/storage.d.ts.map +1 -1
- package/entities/botInstance.ts +3 -3
- package/entities/context/chatContext.ts +31 -6
- package/entities/context/messageContext.ts +29 -8
- package/entities/responses/imageMessage.ts +10 -2
- package/entities/responses/reaction.ts +8 -2
- package/entities/responses/textMessage.ts +10 -2
- package/entities/responses/unpin.ts +22 -0
- package/entities/responses/videoMessage.ts +10 -2
- package/entities/states/actionStateBase.ts +1 -0
- package/package.json +1 -1
- package/services/jsonFileStorage.ts +15 -0
- package/services/telegramApi.ts +84 -48
- package/types/actionState.ts +1 -0
- package/types/response.ts +34 -0
- package/types/storage.ts +5 -0
- package/types/replyMessage.ts +0 -7
package/services/telegramApi.ts
CHANGED
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { InputFile } from 'telegraf/types';
|
|
1
|
+
import { InputFile, Message } from 'telegraf/types';
|
|
3
2
|
import { ChatContext } from '../entities/context/chatContext';
|
|
4
3
|
import { MessageContext } from '../entities/context/messageContext';
|
|
5
|
-
import { ImageMessage } from '../entities/responses/imageMessage';
|
|
6
|
-
import { TextMessage } from '../entities/responses/textMessage';
|
|
7
|
-
import { VideoMessage } from '../entities/responses/videoMessage';
|
|
8
4
|
import { reverseMap } from '../helpers/reverseMap';
|
|
9
|
-
import { IReplyMessage } from '../types/replyMessage';
|
|
10
5
|
import { IStorageClient } from '../types/storage';
|
|
11
6
|
import { Milliseconds } from '../types/timeValues';
|
|
12
7
|
import { Scheduler } from './taskScheduler';
|
|
13
8
|
import { Logger } from './logger';
|
|
14
9
|
import { Reaction } from '../entities/responses/reaction';
|
|
15
10
|
import { IncomingMessage } from '../entities/incomingMessage';
|
|
11
|
+
import { BotResponse, IReplyMessage } from '../types/response';
|
|
12
|
+
import { UnpinResponse } from '../entities/responses/unpin';
|
|
13
|
+
import { TextMessage } from '../entities/responses/textMessage';
|
|
14
|
+
import { VideoMessage } from '../entities/responses/videoMessage';
|
|
15
|
+
import { ImageMessage } from '../entities/responses/imageMessage';
|
|
16
|
+
import { Telegram } from 'telegraf/typings/telegram';
|
|
16
17
|
|
|
17
18
|
export class TelegramApiService {
|
|
18
19
|
botName: string;
|
|
19
|
-
|
|
20
|
+
telegram: Telegram;
|
|
20
21
|
chats: Map<number, string>;
|
|
21
|
-
messageQueue: Array<
|
|
22
|
+
messageQueue: Array<BotResponse> = [];
|
|
22
23
|
storage: IStorageClient;
|
|
23
24
|
|
|
24
25
|
constructor(
|
|
25
26
|
botName: string,
|
|
26
|
-
|
|
27
|
+
telegram: Telegram,
|
|
27
28
|
storage: IStorageClient,
|
|
28
29
|
chats: Map<string, number>
|
|
29
30
|
) {
|
|
30
|
-
this.
|
|
31
|
+
this.telegram = telegram;
|
|
31
32
|
this.botName = botName;
|
|
32
33
|
this.chats = reverseMap(chats);
|
|
33
34
|
this.storage = storage;
|
|
@@ -61,28 +62,33 @@ export class TelegramApiService {
|
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
private async
|
|
65
|
-
response: IReplyMessage<
|
|
65
|
+
private async pinIfShould<T>(
|
|
66
|
+
response: IReplyMessage<T>,
|
|
67
|
+
sentMessage: Message
|
|
66
68
|
) {
|
|
67
|
-
if (
|
|
68
|
-
this.
|
|
69
|
+
if (response.shouldPin) {
|
|
70
|
+
await this.telegram.pinChatMessage(
|
|
69
71
|
response.chatId,
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
{
|
|
73
|
-
type: 'emoji',
|
|
74
|
-
emoji: response.emoji
|
|
75
|
-
}
|
|
76
|
-
],
|
|
77
|
-
true
|
|
72
|
+
sentMessage.message_id,
|
|
73
|
+
{ disable_notification: true }
|
|
78
74
|
);
|
|
79
75
|
|
|
80
|
-
|
|
76
|
+
await this.storage.updateStateFor(
|
|
77
|
+
response.sourceActionKey,
|
|
78
|
+
response.chatId,
|
|
79
|
+
async (state) => {
|
|
80
|
+
state.pinnedMessages.push(sentMessage.message_id);
|
|
81
|
+
}
|
|
82
|
+
);
|
|
81
83
|
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private async processResponse(response: BotResponse) {
|
|
87
|
+
let sentMessage: Message;
|
|
82
88
|
|
|
83
|
-
switch (response.
|
|
84
|
-
case
|
|
85
|
-
await this.
|
|
89
|
+
switch (response.kind) {
|
|
90
|
+
case 'text':
|
|
91
|
+
sentMessage = await this.telegram.sendMessage(
|
|
86
92
|
response.chatId,
|
|
87
93
|
response.content as string,
|
|
88
94
|
{
|
|
@@ -92,9 +98,11 @@ export class TelegramApiService {
|
|
|
92
98
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
93
99
|
} as any
|
|
94
100
|
);
|
|
101
|
+
|
|
102
|
+
await this.pinIfShould(response, sentMessage);
|
|
95
103
|
break;
|
|
96
|
-
case
|
|
97
|
-
await this.
|
|
104
|
+
case 'image':
|
|
105
|
+
sentMessage = await this.telegram.sendPhoto(
|
|
98
106
|
response.chatId,
|
|
99
107
|
response.content as InputFile,
|
|
100
108
|
response.replyId
|
|
@@ -102,9 +110,11 @@ export class TelegramApiService {
|
|
|
102
110
|
({ reply_to_message_id: response.replyId } as any)
|
|
103
111
|
: undefined
|
|
104
112
|
);
|
|
113
|
+
|
|
114
|
+
await this.pinIfShould(response, sentMessage);
|
|
105
115
|
break;
|
|
106
|
-
case
|
|
107
|
-
await this.
|
|
116
|
+
case 'video':
|
|
117
|
+
sentMessage = await this.telegram.sendVideo(
|
|
108
118
|
response.chatId,
|
|
109
119
|
response.content as InputFile,
|
|
110
120
|
response.replyId
|
|
@@ -112,35 +122,58 @@ export class TelegramApiService {
|
|
|
112
122
|
({ reply_to_message_id: response.replyId } as any)
|
|
113
123
|
: undefined
|
|
114
124
|
);
|
|
125
|
+
|
|
126
|
+
await this.pinIfShould(response, sentMessage);
|
|
115
127
|
break;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
response.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
128
|
+
case 'react':
|
|
129
|
+
await this.telegram.setMessageReaction(
|
|
130
|
+
response.chatId,
|
|
131
|
+
response.messageId,
|
|
132
|
+
[
|
|
133
|
+
{
|
|
134
|
+
type: 'emoji',
|
|
135
|
+
emoji: response.emoji
|
|
136
|
+
}
|
|
137
|
+
],
|
|
138
|
+
true
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
return;
|
|
142
|
+
case 'unpin':
|
|
143
|
+
await this.telegram.unpinChatMessage(
|
|
144
|
+
response.chatId,
|
|
145
|
+
response.messageId
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
await this.storage.updateStateFor(
|
|
149
|
+
response.sourceActionKey,
|
|
150
|
+
response.chatId,
|
|
151
|
+
async (state) => {
|
|
152
|
+
state.pinnedMessages = state.pinnedMessages.filter(
|
|
153
|
+
(x) => x != response.messageId
|
|
154
|
+
);
|
|
155
|
+
}
|
|
123
156
|
);
|
|
124
157
|
break;
|
|
125
158
|
}
|
|
126
159
|
}
|
|
127
160
|
|
|
128
|
-
private
|
|
129
|
-
this.messageQueue.push(response);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
private enqueueReaction(reaction: Reaction) {
|
|
161
|
+
private enqueue(reaction: BotResponse) {
|
|
133
162
|
this.messageQueue.push(reaction);
|
|
134
163
|
}
|
|
135
164
|
|
|
136
165
|
private getInteractions() {
|
|
137
166
|
return {
|
|
138
|
-
react: (reaction) => this.
|
|
139
|
-
respond: (response) => this.
|
|
167
|
+
react: (reaction) => this.enqueue(reaction),
|
|
168
|
+
respond: (response) => this.enqueue(response),
|
|
169
|
+
unpin: (unpinMessage) => this.enqueue(unpinMessage)
|
|
140
170
|
} as IBotApiInteractions;
|
|
141
171
|
}
|
|
142
172
|
|
|
143
|
-
createContextForMessage(
|
|
173
|
+
createContextForMessage(
|
|
174
|
+
incomingMessage: IncomingMessage,
|
|
175
|
+
commandKey: string
|
|
176
|
+
) {
|
|
144
177
|
const firstName = incomingMessage.from?.first_name ?? 'Unknown user';
|
|
145
178
|
const lastName = incomingMessage.from?.last_name
|
|
146
179
|
? ` ${incomingMessage.from?.last_name}`
|
|
@@ -148,6 +181,7 @@ export class TelegramApiService {
|
|
|
148
181
|
|
|
149
182
|
return new MessageContext(
|
|
150
183
|
this.botName,
|
|
184
|
+
commandKey,
|
|
151
185
|
this.getInteractions(),
|
|
152
186
|
incomingMessage.chat.id,
|
|
153
187
|
incomingMessage.chatName,
|
|
@@ -160,19 +194,21 @@ export class TelegramApiService {
|
|
|
160
194
|
);
|
|
161
195
|
}
|
|
162
196
|
|
|
163
|
-
createContextForChat(chatId: number,
|
|
197
|
+
createContextForChat(chatId: number, scheduledKey: string) {
|
|
164
198
|
return new ChatContext(
|
|
165
199
|
this.botName,
|
|
200
|
+
scheduledKey,
|
|
166
201
|
this.getInteractions(),
|
|
167
202
|
chatId,
|
|
168
203
|
this.chats.get(chatId)!,
|
|
169
|
-
`Scheduled:${
|
|
204
|
+
`Scheduled:${scheduledKey}:${chatId}`,
|
|
170
205
|
this.storage
|
|
171
206
|
);
|
|
172
207
|
}
|
|
173
208
|
}
|
|
174
209
|
|
|
175
210
|
export interface IBotApiInteractions {
|
|
176
|
-
respond:
|
|
211
|
+
respond: (response: TextMessage | VideoMessage | ImageMessage) => void;
|
|
177
212
|
react: (reaction: Reaction) => void;
|
|
213
|
+
unpin: (unpinMessage: UnpinResponse) => void;
|
|
178
214
|
}
|
package/types/actionState.ts
CHANGED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ImageMessage } from '../entities/responses/imageMessage';
|
|
2
|
+
import { Reaction } from '../entities/responses/reaction';
|
|
3
|
+
import { TextMessage } from '../entities/responses/textMessage';
|
|
4
|
+
import { UnpinResponse } from '../entities/responses/unpin';
|
|
5
|
+
import { VideoMessage } from '../entities/responses/videoMessage';
|
|
6
|
+
|
|
7
|
+
export const BotResponseTypes = {
|
|
8
|
+
unpin: 'unpin',
|
|
9
|
+
text: 'text',
|
|
10
|
+
image: 'image',
|
|
11
|
+
video: 'video',
|
|
12
|
+
react: 'react'
|
|
13
|
+
} as const;
|
|
14
|
+
|
|
15
|
+
export type BotResponse =
|
|
16
|
+
| UnpinResponse
|
|
17
|
+
| Reaction
|
|
18
|
+
| TextMessage
|
|
19
|
+
| VideoMessage
|
|
20
|
+
| ImageMessage;
|
|
21
|
+
|
|
22
|
+
export interface IChatResponse {
|
|
23
|
+
kind: keyof typeof BotResponseTypes;
|
|
24
|
+
chatId: number;
|
|
25
|
+
traceId: number | string;
|
|
26
|
+
sourceActionKey: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface IReplyMessage<TType> extends IChatResponse {
|
|
30
|
+
content: TType;
|
|
31
|
+
replyId: number | undefined;
|
|
32
|
+
disableWebPreview: boolean;
|
|
33
|
+
shouldPin: boolean;
|
|
34
|
+
}
|
package/types/storage.ts
CHANGED
|
@@ -3,6 +3,11 @@ import { IActionState } from './actionState';
|
|
|
3
3
|
import { IActionWithState } from './actionWithState';
|
|
4
4
|
|
|
5
5
|
export interface IStorageClient {
|
|
6
|
+
updateStateFor<TActionState extends IActionState>(
|
|
7
|
+
sourceActionKey: string,
|
|
8
|
+
chatId: number,
|
|
9
|
+
update: (state: TActionState) => Promise<void>
|
|
10
|
+
): Promise<void>;
|
|
6
11
|
close(): Promise<void>;
|
|
7
12
|
load<TActionState extends IActionState>(
|
|
8
13
|
key: string
|