gramio 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +412 -182
- package/dist/index.d.cts +519 -1117
- package/dist/index.d.ts +519 -1117
- package/dist/index.js +410 -185
- package/dist/{utils-C46rnh-r.cjs → utils-DCXj-tb5.cjs} +10 -10
- package/dist/{utils-En0iVLWH.js → utils-DqK73ALI.js} +10 -10
- package/dist/utils.cjs +1 -1
- package/dist/utils.js +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -9,177 +9,181 @@ export * from '@gramio/keyboards';
|
|
|
9
9
|
import fs from 'node:fs/promises';
|
|
10
10
|
import { Readable } from 'node:stream';
|
|
11
11
|
import debug from 'debug';
|
|
12
|
-
import { E as ErrorKind, w as withRetries, T as TelegramError, s as sleep, d as debug$updates, I as IS_BUN, a as simplifyObject, t as timeoutWebhook } from './utils-
|
|
13
|
-
import {
|
|
14
|
-
export { EventQueue, compose, noopNext, skip, stop } from '@gramio/composer';
|
|
12
|
+
import { E as ErrorKind, w as withRetries, T as TelegramError, s as sleep, d as debug$updates, I as IS_BUN, a as simplifyObject, t as timeoutWebhook } from './utils-DqK73ALI.js';
|
|
13
|
+
import { defineComposerMethods, buildFromOptions, noopNext, createComposer, eventTypes, EventQueue } from '@gramio/composer';
|
|
14
|
+
export { EventQueue, buildFromOptions, compose, noopNext, skip, stop } from '@gramio/composer';
|
|
15
15
|
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
for (const
|
|
25
|
-
if (
|
|
26
|
-
const foundIndex = context.oldReactions.findIndex(
|
|
27
|
-
(oldReaction) => oldReaction.type === "emoji" && oldReaction.emoji === reaction.emoji
|
|
28
|
-
);
|
|
29
|
-
if (foundIndex === -1) {
|
|
30
|
-
newReactions.push(reaction);
|
|
31
|
-
} else {
|
|
32
|
-
context.oldReactions.splice(foundIndex, 1);
|
|
33
|
-
}
|
|
16
|
+
const methods = defineComposerMethods({
|
|
17
|
+
reaction(trigger, handler, macroOptions) {
|
|
18
|
+
const reactions = Array.isArray(trigger) ? trigger : [trigger];
|
|
19
|
+
const macroHandler = macroOptions ? buildFromOptions(this["~"].macros, macroOptions, handler) : null;
|
|
20
|
+
return this.on(
|
|
21
|
+
"message_reaction",
|
|
22
|
+
(context, next) => {
|
|
23
|
+
const oldEmojis = /* @__PURE__ */ new Set();
|
|
24
|
+
for (const r of context.oldReactions) {
|
|
25
|
+
if (r.type === "emoji") oldEmojis.add(r.emoji);
|
|
34
26
|
}
|
|
35
|
-
|
|
36
|
-
(
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
return handler(context);
|
|
40
|
-
});
|
|
41
|
-
},
|
|
42
|
-
callbackQuery(trigger, handler) {
|
|
43
|
-
if (typeof trigger === "string") {
|
|
44
|
-
return this.on("callback_query", (context, next) => {
|
|
45
|
-
if (context.data !== trigger) return next();
|
|
46
|
-
return handler(context);
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
if (trigger instanceof RegExp) {
|
|
50
|
-
return this.on("callback_query", (context, next) => {
|
|
51
|
-
if (!context.data || !trigger.test(context.data)) return next();
|
|
52
|
-
context.queryData = context.data.match(trigger);
|
|
53
|
-
return handler(context);
|
|
54
|
-
});
|
|
27
|
+
const hasNewMatchingReaction = context.newReactions.some(
|
|
28
|
+
(reaction) => reaction.type === "emoji" && !oldEmojis.has(reaction.emoji) && reactions.includes(reaction.emoji)
|
|
29
|
+
);
|
|
30
|
+
if (!hasNewMatchingReaction) return next();
|
|
31
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
55
32
|
}
|
|
56
|
-
|
|
33
|
+
);
|
|
34
|
+
},
|
|
35
|
+
callbackQuery(trigger, handler, macroOptions) {
|
|
36
|
+
const macroHandler = macroOptions ? buildFromOptions(this["~"].macros, macroOptions, handler) : null;
|
|
37
|
+
if (typeof trigger === "string") {
|
|
57
38
|
return this.on("callback_query", (context, next) => {
|
|
58
|
-
if (
|
|
59
|
-
context
|
|
60
|
-
return handler(context);
|
|
39
|
+
if (context.data !== trigger) return next();
|
|
40
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
61
41
|
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (trigger
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
42
|
+
}
|
|
43
|
+
if (trigger instanceof RegExp) {
|
|
44
|
+
return this.on("callback_query", (context, next) => {
|
|
45
|
+
if (!context.data || !trigger.test(context.data)) return next();
|
|
46
|
+
context.queryData = context.data.match(trigger);
|
|
47
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return this.on("callback_query", (context, next) => {
|
|
51
|
+
if (!context.data || !trigger.filter(context.data)) return next();
|
|
52
|
+
context.queryData = trigger.unpack(context.data);
|
|
53
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
chosenInlineResult(trigger, handler, macroOptions) {
|
|
57
|
+
const macroHandler = macroOptions ? buildFromOptions(this["~"].macros, macroOptions, handler) : null;
|
|
58
|
+
if (typeof trigger === "string") {
|
|
78
59
|
return this.on("chosen_inline_result", (context, next) => {
|
|
79
|
-
if (
|
|
60
|
+
if (context.query !== trigger) return next();
|
|
80
61
|
context.args = null;
|
|
81
|
-
return handler(context);
|
|
62
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
82
63
|
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
64
|
+
}
|
|
65
|
+
if (trigger instanceof RegExp) {
|
|
66
|
+
return this.on("chosen_inline_result", (context, next) => {
|
|
67
|
+
if (!trigger.test(context.query)) return next();
|
|
68
|
+
context.args = context.query?.match(trigger);
|
|
69
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return this.on("chosen_inline_result", (context, next) => {
|
|
73
|
+
if (!trigger(context)) return next();
|
|
74
|
+
context.args = null;
|
|
75
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
inlineQuery(trigger, handler, options = {}) {
|
|
79
|
+
if (options.onResult) this.chosenInlineResult(trigger, options.onResult);
|
|
80
|
+
const { onResult: _, ...macroOptions } = options;
|
|
81
|
+
const hasMacros = Object.keys(macroOptions).length > 0;
|
|
82
|
+
const macroHandler = hasMacros ? buildFromOptions(this["~"].macros, macroOptions, handler) : null;
|
|
83
|
+
if (typeof trigger === "string") {
|
|
101
84
|
return this.on("inline_query", (context, next) => {
|
|
102
|
-
if (
|
|
85
|
+
if (context.query !== trigger) return next();
|
|
103
86
|
context.args = null;
|
|
104
|
-
return handler(context);
|
|
87
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
105
88
|
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (trigger instanceof RegExp) {
|
|
124
|
-
return this.on("message", (context, next) => {
|
|
125
|
-
const text = context.text ?? context.caption;
|
|
126
|
-
if (!text || !trigger.test(text)) return next();
|
|
127
|
-
context.args = text.match(trigger);
|
|
128
|
-
return handler(context);
|
|
129
|
-
});
|
|
130
|
-
}
|
|
89
|
+
}
|
|
90
|
+
if (trigger instanceof RegExp) {
|
|
91
|
+
return this.on("inline_query", (context, next) => {
|
|
92
|
+
if (!trigger.test(context.query)) return next();
|
|
93
|
+
context.args = context.query?.match(trigger);
|
|
94
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
return this.on("inline_query", (context, next) => {
|
|
98
|
+
if (!trigger(context)) return next();
|
|
99
|
+
context.args = null;
|
|
100
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
hears(trigger, handler, macroOptions) {
|
|
104
|
+
const macroHandler = macroOptions ? buildFromOptions(this["~"].macros, macroOptions, handler) : null;
|
|
105
|
+
if (typeof trigger === "string") {
|
|
131
106
|
return this.on("message", (context, next) => {
|
|
132
|
-
if (
|
|
107
|
+
if ((context.text ?? context.caption) !== trigger) return next();
|
|
133
108
|
context.args = null;
|
|
134
|
-
return handler(context);
|
|
109
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
135
110
|
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
return this.on(["message", "business_message"], (context, next) => {
|
|
144
|
-
if (context.entities?.some((entity) => {
|
|
145
|
-
if (entity.type !== "bot_command" || entity.offset > 0)
|
|
146
|
-
return false;
|
|
147
|
-
const botInfo = context.bot.info;
|
|
148
|
-
const cmd = context.text?.slice(1, entity.length)?.replace(
|
|
149
|
-
botInfo?.username ? `@${botInfo.username}` : /@[a-zA-Z0-9_]+/,
|
|
150
|
-
""
|
|
151
|
-
);
|
|
152
|
-
context.args = context.text?.slice(entity.length).trim() || null;
|
|
153
|
-
return normalizedCommands.some(
|
|
154
|
-
(normalizedCommand) => cmd === normalizedCommand
|
|
155
|
-
);
|
|
156
|
-
}))
|
|
157
|
-
return handler(context);
|
|
158
|
-
return next();
|
|
111
|
+
}
|
|
112
|
+
if (Array.isArray(trigger)) {
|
|
113
|
+
return this.on("message", (context, next) => {
|
|
114
|
+
const text = context.text ?? context.caption;
|
|
115
|
+
if (!text || !trigger.includes(text)) return next();
|
|
116
|
+
context.args = null;
|
|
117
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
159
118
|
});
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
119
|
+
}
|
|
120
|
+
if (trigger instanceof RegExp) {
|
|
121
|
+
return this.on("message", (context, next) => {
|
|
122
|
+
const text = context.text ?? context.caption;
|
|
123
|
+
if (!text || !trigger.test(text)) return next();
|
|
124
|
+
context.args = text.match(trigger);
|
|
125
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
return this.on("message", (context, next) => {
|
|
129
|
+
if (typeof trigger !== "function" || !trigger(context)) return next();
|
|
130
|
+
context.args = null;
|
|
131
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
132
|
+
});
|
|
133
|
+
},
|
|
134
|
+
command(command, handler, macroOptions) {
|
|
135
|
+
const normalizedCommands = typeof command === "string" ? [command] : Array.from(command);
|
|
136
|
+
for (const cmd of normalizedCommands) {
|
|
137
|
+
if (cmd.startsWith("/"))
|
|
138
|
+
throw new Error(`Do not use / in command name (${cmd})`);
|
|
139
|
+
}
|
|
140
|
+
const macroHandler = macroOptions ? buildFromOptions(this["~"].macros, macroOptions, handler) : null;
|
|
141
|
+
return this.on(["message", "business_message"], (context, next) => {
|
|
142
|
+
const entity = context.entities?.find((entity2) => {
|
|
143
|
+
if (entity2.type !== "bot_command" || entity2.offset > 0) return false;
|
|
144
|
+
const botInfo = context.bot.info;
|
|
145
|
+
const cmd = context.text?.slice(1, entity2.length)?.replace(
|
|
146
|
+
botInfo?.username ? `@${botInfo.username}` : /@[a-zA-Z0-9_]+/,
|
|
147
|
+
""
|
|
148
|
+
);
|
|
149
|
+
return normalizedCommands.some(
|
|
150
|
+
(normalizedCommand) => cmd === normalizedCommand
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
|
+
if (entity) {
|
|
154
|
+
context.args = context.text?.slice(entity.length).trim() || null;
|
|
155
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context);
|
|
175
156
|
}
|
|
157
|
+
return next();
|
|
158
|
+
});
|
|
159
|
+
},
|
|
160
|
+
startParameter(parameter, handler, macroOptions) {
|
|
161
|
+
const macroHandler = macroOptions ? buildFromOptions(this["~"].macros, macroOptions, handler) : null;
|
|
162
|
+
if (parameter instanceof RegExp) {
|
|
163
|
+
return this.on("message", (context, next) => {
|
|
164
|
+
if (!context.rawStartPayload || !parameter.test(context.rawStartPayload))
|
|
165
|
+
return next();
|
|
166
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context, noopNext);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
if (Array.isArray(parameter)) {
|
|
176
170
|
return this.on("message", (context, next) => {
|
|
177
|
-
if (context.rawStartPayload
|
|
178
|
-
|
|
171
|
+
if (!context.rawStartPayload || !parameter.includes(context.rawStartPayload))
|
|
172
|
+
return next();
|
|
173
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context, noopNext);
|
|
179
174
|
});
|
|
180
175
|
}
|
|
176
|
+
return this.on("message", (context, next) => {
|
|
177
|
+
if (!context.rawStartPayload || context.rawStartPayload !== parameter) return next();
|
|
178
|
+
return macroHandler ? macroHandler(context, noopNext) : handler(context, noopNext);
|
|
179
|
+
});
|
|
181
180
|
}
|
|
182
181
|
});
|
|
182
|
+
const { Composer } = createComposer({
|
|
183
|
+
discriminator: (ctx) => ctx.updateType,
|
|
184
|
+
types: eventTypes(),
|
|
185
|
+
methods
|
|
186
|
+
});
|
|
183
187
|
|
|
184
188
|
class Plugin {
|
|
185
189
|
/**
|
|
@@ -197,6 +201,8 @@ class Plugin {
|
|
|
197
201
|
Errors: {},
|
|
198
202
|
/** remap generic type. {} in runtime */
|
|
199
203
|
Derives: {},
|
|
204
|
+
/** remap generic type. {} in runtime */
|
|
205
|
+
Macros: {},
|
|
200
206
|
/** Composer */
|
|
201
207
|
composer: new Composer(),
|
|
202
208
|
/** Store plugin preRequests hooks */
|
|
@@ -273,9 +279,27 @@ class Plugin {
|
|
|
273
279
|
}
|
|
274
280
|
return this;
|
|
275
281
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
this
|
|
282
|
+
macro(nameOrDefs, definition) {
|
|
283
|
+
this._.composer.macro(nameOrDefs, definition);
|
|
284
|
+
return this;
|
|
285
|
+
}
|
|
286
|
+
on(updateNameOrFilter, filterOrHandler, handler) {
|
|
287
|
+
if (typeof updateNameOrFilter === "function") {
|
|
288
|
+
this._.composer.on(updateNameOrFilter, filterOrHandler);
|
|
289
|
+
return this;
|
|
290
|
+
}
|
|
291
|
+
if (handler) {
|
|
292
|
+
this._.composer.on(
|
|
293
|
+
updateNameOrFilter,
|
|
294
|
+
filterOrHandler,
|
|
295
|
+
handler
|
|
296
|
+
);
|
|
297
|
+
} else {
|
|
298
|
+
this._.composer.on(
|
|
299
|
+
updateNameOrFilter,
|
|
300
|
+
filterOrHandler
|
|
301
|
+
);
|
|
302
|
+
}
|
|
279
303
|
return this;
|
|
280
304
|
}
|
|
281
305
|
/** Register handler to any Updates */
|
|
@@ -765,6 +789,10 @@ class Bot {
|
|
|
765
789
|
);
|
|
766
790
|
return this;
|
|
767
791
|
}
|
|
792
|
+
macro(nameOrDefs, definition) {
|
|
793
|
+
this.updates.composer.macro(nameOrDefs, definition);
|
|
794
|
+
return this;
|
|
795
|
+
}
|
|
768
796
|
/**
|
|
769
797
|
* This hook called when the bot is `started`.
|
|
770
798
|
*
|
|
@@ -859,22 +887,26 @@ class Bot {
|
|
|
859
887
|
}
|
|
860
888
|
return this;
|
|
861
889
|
}
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
890
|
+
on(updateNameOrFilter, filterOrHandler, handler) {
|
|
891
|
+
if (typeof updateNameOrFilter === "function") {
|
|
892
|
+
this.updates.composer.on(
|
|
893
|
+
updateNameOrFilter,
|
|
894
|
+
filterOrHandler
|
|
895
|
+
);
|
|
896
|
+
return this;
|
|
897
|
+
}
|
|
898
|
+
if (handler) {
|
|
899
|
+
this.updates.composer.on(
|
|
900
|
+
updateNameOrFilter,
|
|
901
|
+
filterOrHandler,
|
|
902
|
+
handler
|
|
903
|
+
);
|
|
904
|
+
} else {
|
|
905
|
+
this.updates.composer.on(
|
|
906
|
+
updateNameOrFilter,
|
|
907
|
+
filterOrHandler
|
|
908
|
+
);
|
|
909
|
+
}
|
|
878
910
|
return this;
|
|
879
911
|
}
|
|
880
912
|
/** Register handler to any Updates */
|
|
@@ -899,6 +931,11 @@ class Bot {
|
|
|
899
931
|
if (plugin._.composer["~"].middlewares.length) {
|
|
900
932
|
plugin._.composer.as("scoped");
|
|
901
933
|
this.updates.composer.extend(plugin._.composer);
|
|
934
|
+
} else if (Object.keys(plugin._.composer["~"].macros).length) {
|
|
935
|
+
Object.assign(
|
|
936
|
+
this.updates.composer["~"].macros,
|
|
937
|
+
plugin._.composer["~"].macros
|
|
938
|
+
);
|
|
902
939
|
}
|
|
903
940
|
this.decorate(plugin._.decorators);
|
|
904
941
|
for (const [key, value] of Object.entries(plugin._.errorsDefinitions)) {
|
|
@@ -949,8 +986,8 @@ class Bot {
|
|
|
949
986
|
* });
|
|
950
987
|
* ```
|
|
951
988
|
* */
|
|
952
|
-
reaction(trigger, handler) {
|
|
953
|
-
this.updates.composer.reaction(trigger, handler);
|
|
989
|
+
reaction(trigger, handler, options) {
|
|
990
|
+
this.updates.composer.reaction(trigger, handler, options);
|
|
954
991
|
return this;
|
|
955
992
|
}
|
|
956
993
|
/**
|
|
@@ -976,13 +1013,21 @@ class Bot {
|
|
|
976
1013
|
* });
|
|
977
1014
|
* ```
|
|
978
1015
|
*/
|
|
979
|
-
callbackQuery(trigger, handler) {
|
|
980
|
-
this.updates.composer.callbackQuery(
|
|
1016
|
+
callbackQuery(trigger, handler, options) {
|
|
1017
|
+
this.updates.composer.callbackQuery(
|
|
1018
|
+
trigger,
|
|
1019
|
+
handler,
|
|
1020
|
+
options
|
|
1021
|
+
);
|
|
981
1022
|
return this;
|
|
982
1023
|
}
|
|
983
1024
|
/** Register handler to `chosen_inline_result` update */
|
|
984
|
-
chosenInlineResult(trigger, handler) {
|
|
985
|
-
this.updates.composer.chosenInlineResult(
|
|
1025
|
+
chosenInlineResult(trigger, handler, options) {
|
|
1026
|
+
this.updates.composer.chosenInlineResult(
|
|
1027
|
+
trigger,
|
|
1028
|
+
handler,
|
|
1029
|
+
options
|
|
1030
|
+
);
|
|
986
1031
|
return this;
|
|
987
1032
|
}
|
|
988
1033
|
/**
|
|
@@ -1020,7 +1065,7 @@ class Bot {
|
|
|
1020
1065
|
* );
|
|
1021
1066
|
* ```
|
|
1022
1067
|
* */
|
|
1023
|
-
inlineQuery(trigger, handler, options
|
|
1068
|
+
inlineQuery(trigger, handler, options) {
|
|
1024
1069
|
this.updates.composer.inlineQuery(
|
|
1025
1070
|
trigger,
|
|
1026
1071
|
handler,
|
|
@@ -1038,8 +1083,8 @@ class Bot {
|
|
|
1038
1083
|
* });
|
|
1039
1084
|
* ```
|
|
1040
1085
|
*/
|
|
1041
|
-
hears(trigger, handler) {
|
|
1042
|
-
this.updates.composer.hears(trigger, handler);
|
|
1086
|
+
hears(trigger, handler, options) {
|
|
1087
|
+
this.updates.composer.hears(trigger, handler, options);
|
|
1043
1088
|
return this;
|
|
1044
1089
|
}
|
|
1045
1090
|
/**
|
|
@@ -1052,8 +1097,8 @@ class Bot {
|
|
|
1052
1097
|
* });
|
|
1053
1098
|
* ```
|
|
1054
1099
|
*/
|
|
1055
|
-
command(command, handler) {
|
|
1056
|
-
this.updates.composer.command(command, handler);
|
|
1100
|
+
command(command, handler, options) {
|
|
1101
|
+
this.updates.composer.command(command, handler, options);
|
|
1057
1102
|
return this;
|
|
1058
1103
|
}
|
|
1059
1104
|
/**
|
|
@@ -1066,8 +1111,12 @@ class Bot {
|
|
|
1066
1111
|
* });
|
|
1067
1112
|
* ```
|
|
1068
1113
|
*/
|
|
1069
|
-
startParameter(parameter, handler) {
|
|
1070
|
-
this.updates.composer.startParameter(
|
|
1114
|
+
startParameter(parameter, handler, options) {
|
|
1115
|
+
this.updates.composer.startParameter(
|
|
1116
|
+
parameter,
|
|
1117
|
+
handler,
|
|
1118
|
+
options
|
|
1119
|
+
);
|
|
1071
1120
|
return this;
|
|
1072
1121
|
}
|
|
1073
1122
|
/** Currently not isolated!!! */
|
|
@@ -1178,13 +1227,185 @@ class Bot {
|
|
|
1178
1227
|
}
|
|
1179
1228
|
}
|
|
1180
1229
|
|
|
1230
|
+
const forwardOriginFilter = ((type) => {
|
|
1231
|
+
if (type === void 0) {
|
|
1232
|
+
return ((ctx) => ctx.hasForwardOrigin());
|
|
1233
|
+
}
|
|
1234
|
+
return ((ctx) => ctx.hasForwardOrigin() && ctx.forwardOrigin?.type === type);
|
|
1235
|
+
});
|
|
1236
|
+
const senderChatFilter = ((type) => {
|
|
1237
|
+
if (type === void 0) {
|
|
1238
|
+
return ((ctx) => ctx.hasSenderChat());
|
|
1239
|
+
}
|
|
1240
|
+
return ((ctx) => ctx.hasSenderChat() && ctx.senderChat?.type === type);
|
|
1241
|
+
});
|
|
1242
|
+
function createAttachmentFilter(type) {
|
|
1243
|
+
return ((ctx) => ctx.hasAttachmentType(type));
|
|
1244
|
+
}
|
|
1245
|
+
const filters = {
|
|
1246
|
+
// ── Attachment filters ──────────────────────────────────────────────
|
|
1247
|
+
photo: createAttachmentFilter("photo"),
|
|
1248
|
+
video: createAttachmentFilter("video"),
|
|
1249
|
+
document: createAttachmentFilter("document"),
|
|
1250
|
+
audio: createAttachmentFilter("audio"),
|
|
1251
|
+
sticker: createAttachmentFilter("sticker"),
|
|
1252
|
+
voice: createAttachmentFilter("voice"),
|
|
1253
|
+
videoNote: createAttachmentFilter("video_note"),
|
|
1254
|
+
animation: createAttachmentFilter("animation"),
|
|
1255
|
+
contact: createAttachmentFilter("contact"),
|
|
1256
|
+
location: createAttachmentFilter("location"),
|
|
1257
|
+
poll: createAttachmentFilter("poll"),
|
|
1258
|
+
/** Matches any message that has an attachment */
|
|
1259
|
+
media: ((ctx) => ctx.hasAttachment()),
|
|
1260
|
+
// ── Text & caption ──────────────────────────────────────────────────
|
|
1261
|
+
/** Matches messages that have text */
|
|
1262
|
+
text: ((ctx) => ctx.hasText()),
|
|
1263
|
+
/** Matches messages that have a caption */
|
|
1264
|
+
caption: ((ctx) => ctx.hasCaption()),
|
|
1265
|
+
// ── Message content & structure ─────────────────────────────────────
|
|
1266
|
+
/** Matches messages that contain a dice */
|
|
1267
|
+
dice: ((ctx) => ctx.hasDice()),
|
|
1268
|
+
/** Matches forwarded messages. Call without args for any origin, or pass a type to narrow precisely. */
|
|
1269
|
+
forwardOrigin: forwardOriginFilter,
|
|
1270
|
+
/** Matches messages that are replies */
|
|
1271
|
+
reply: ((ctx) => ctx.hasReplyMessage()),
|
|
1272
|
+
/** Matches messages that have text entities */
|
|
1273
|
+
entities: ((ctx) => ctx.hasEntities()),
|
|
1274
|
+
/** Matches messages that have caption entities */
|
|
1275
|
+
captionEntities: ((ctx) => ctx.hasCaptionEntities()),
|
|
1276
|
+
/** Matches messages that have a quote */
|
|
1277
|
+
quote: ((ctx) => ctx.hasQuote()),
|
|
1278
|
+
/** Matches messages sent via a bot */
|
|
1279
|
+
viaBot: ((ctx) => ctx.hasViaBot()),
|
|
1280
|
+
/** Matches messages that have link preview options */
|
|
1281
|
+
linkPreview: ((ctx) => ctx.hasLinkPreviewOptions()),
|
|
1282
|
+
/** Matches messages with a /start payload */
|
|
1283
|
+
startPayload: ((ctx) => ctx.hasStartPayload()),
|
|
1284
|
+
/** Matches messages with a raw /start payload string */
|
|
1285
|
+
rawStartPayload: ((ctx) => ctx.rawStartPayload !== void 0),
|
|
1286
|
+
/** Matches messages with an author signature */
|
|
1287
|
+
authorSignature: ((ctx) => ctx.hasAuthorSignature()),
|
|
1288
|
+
/** Matches messages with external reply info */
|
|
1289
|
+
replyInfo: ((ctx) => ctx.hasReplyInfo()),
|
|
1290
|
+
/** Matches contexts that have a sender (from user) */
|
|
1291
|
+
hasFrom: ((ctx) => ctx.hasFrom()),
|
|
1292
|
+
/** Matches messages sent on behalf of a chat. Pass a type to also narrow `senderChat.type`. */
|
|
1293
|
+
senderChat: senderChatFilter,
|
|
1294
|
+
/** Matches giveaway messages */
|
|
1295
|
+
giveaway: ((ctx) => ctx.isGiveaway()),
|
|
1296
|
+
/** Matches messages with paid media */
|
|
1297
|
+
paidMedia: ((ctx) => ctx.paidMedia !== void 0),
|
|
1298
|
+
// ── Raw property narrowing ──────────────────────────────────────────
|
|
1299
|
+
/** Matches messages with a game */
|
|
1300
|
+
game: ((ctx) => ctx.game !== void 0),
|
|
1301
|
+
/** Matches messages with a story */
|
|
1302
|
+
story: ((ctx) => ctx.story !== void 0),
|
|
1303
|
+
/** Matches messages with an effect ID */
|
|
1304
|
+
effectId: ((ctx) => ctx.effectId !== void 0),
|
|
1305
|
+
/** Matches messages that belong to a media group */
|
|
1306
|
+
mediaGroup: ((ctx) => ctx.mediaGroupId !== void 0),
|
|
1307
|
+
/** Matches messages with a venue */
|
|
1308
|
+
venue: ((ctx) => ctx.venue !== void 0),
|
|
1309
|
+
// ── Sender/chat property filters (boolean, no narrowing) ────────────
|
|
1310
|
+
/** Matches messages from bot accounts */
|
|
1311
|
+
isBot: (ctx) => ctx.from?.isBot() === true,
|
|
1312
|
+
/** Matches messages from premium users */
|
|
1313
|
+
isPremium: (ctx) => ctx.from?.isPremium() === true,
|
|
1314
|
+
/** Matches messages in forum (topic) chats */
|
|
1315
|
+
isForum: (ctx) => ctx.isForum === true,
|
|
1316
|
+
// ── Message state filters ───────────────────────────────────────────
|
|
1317
|
+
/** Matches service messages */
|
|
1318
|
+
service: (ctx) => ctx.isServiceMessage?.() ?? false,
|
|
1319
|
+
/** Matches messages in topics */
|
|
1320
|
+
topicMessage: (ctx) => ctx.isTopicMessage?.() ?? false,
|
|
1321
|
+
/** Matches media with spoiler. Narrows `attachment` to confirm media is present. */
|
|
1322
|
+
mediaSpoiler: ((ctx) => ctx.hasAttachment() && ctx.hasMediaSpoiler?.() === true),
|
|
1323
|
+
/** Matches messages with protected content. No type narrowing. */
|
|
1324
|
+
protectedContent: (ctx) => ctx.hasProtectedContent?.() === true,
|
|
1325
|
+
/** Matches messages sent while user was offline. No type narrowing. */
|
|
1326
|
+
fromOffline: (ctx) => ctx.isFromOffline?.() === true,
|
|
1327
|
+
// ── Callback query specific filters ─────────────────────────────────
|
|
1328
|
+
/** Matches callback queries that have an associated message */
|
|
1329
|
+
hasMessage: ((ctx) => ctx.hasMessage?.()),
|
|
1330
|
+
/** Matches callback queries that have data */
|
|
1331
|
+
hasData: ((ctx) => ctx.hasData?.()),
|
|
1332
|
+
/** Matches callback queries with an inline message ID */
|
|
1333
|
+
hasInlineMessageId: ((ctx) => ctx.hasInlineMessageId?.()),
|
|
1334
|
+
/** Matches callback queries with a game short name */
|
|
1335
|
+
hasGameShortName: ((ctx) => ctx.hasGameShortName?.()),
|
|
1336
|
+
// ── Parameterized entity filters ────────────────────────────────────
|
|
1337
|
+
/** Matches messages with a specific text entity type */
|
|
1338
|
+
entity(type) {
|
|
1339
|
+
return ((ctx) => ctx.hasEntities(type));
|
|
1340
|
+
},
|
|
1341
|
+
/** Matches messages with a specific caption entity type */
|
|
1342
|
+
captionEntity(type) {
|
|
1343
|
+
return ((ctx) => ctx.hasCaptionEntities(type));
|
|
1344
|
+
},
|
|
1345
|
+
// ── Chat type shortcuts ─────────────────────────────────────────────
|
|
1346
|
+
/** Matches messages from a specific chat type. Narrows both `chatType` and `chat.type`. */
|
|
1347
|
+
chat(type) {
|
|
1348
|
+
return ((ctx) => ctx.chatType === type);
|
|
1349
|
+
},
|
|
1350
|
+
/** Matches private (DM) chats. Narrows both `chatType` and `chat.type`. */
|
|
1351
|
+
pm: ((ctx) => ctx.chatType === "private"),
|
|
1352
|
+
/** Matches group chats. Narrows both `chatType` and `chat.type`. */
|
|
1353
|
+
group: ((ctx) => ctx.chatType === "group"),
|
|
1354
|
+
/** Matches supergroup chats. Narrows both `chatType` and `chat.type`. */
|
|
1355
|
+
supergroup: ((ctx) => ctx.chatType === "supergroup"),
|
|
1356
|
+
/** Matches channel chats. Narrows both `chatType` and `chat.type`. */
|
|
1357
|
+
channel: ((ctx) => ctx.chatType === "channel"),
|
|
1358
|
+
// ── Parameterized filters ───────────────────────────────────────────
|
|
1359
|
+
/** Matches messages from specific user(s). No type narrowing. */
|
|
1360
|
+
from(userId) {
|
|
1361
|
+
const ids = Array.isArray(userId) ? userId : [userId];
|
|
1362
|
+
return (ctx) => ctx.senderId !== void 0 && ids.includes(ctx.senderId);
|
|
1363
|
+
},
|
|
1364
|
+
/** Matches messages in specific chat(s). No type narrowing. */
|
|
1365
|
+
chatId(chatId) {
|
|
1366
|
+
const ids = Array.isArray(chatId) ? chatId : [chatId];
|
|
1367
|
+
return (ctx) => ids.includes(ctx.chatId);
|
|
1368
|
+
},
|
|
1369
|
+
/** Matches messages whose text/caption matches the regex, sets `ctx.match` */
|
|
1370
|
+
regex(pattern) {
|
|
1371
|
+
return ((ctx) => {
|
|
1372
|
+
const value = ctx.text ?? ctx.caption;
|
|
1373
|
+
if (!value) return false;
|
|
1374
|
+
const result = value.match(pattern);
|
|
1375
|
+
if (!result) return false;
|
|
1376
|
+
ctx.match = result;
|
|
1377
|
+
return true;
|
|
1378
|
+
});
|
|
1379
|
+
},
|
|
1380
|
+
// ── Composition ─────────────────────────────────────────────────────
|
|
1381
|
+
/** Intersection: both filters must match */
|
|
1382
|
+
and(f1, f2) {
|
|
1383
|
+
return ((ctx) => f1(ctx) && f2(ctx));
|
|
1384
|
+
},
|
|
1385
|
+
/** Union: either filter must match */
|
|
1386
|
+
or(f1, f2) {
|
|
1387
|
+
return ((ctx) => f1(ctx) || f2(ctx));
|
|
1388
|
+
},
|
|
1389
|
+
/** Negation: inverts the filter (no type narrowing) */
|
|
1390
|
+
not(f) {
|
|
1391
|
+
return (ctx) => !f(ctx);
|
|
1392
|
+
},
|
|
1393
|
+
/** Variadic intersection: all filters must match */
|
|
1394
|
+
every(...filters2) {
|
|
1395
|
+
return ((ctx) => filters2.every((f) => f(ctx)));
|
|
1396
|
+
},
|
|
1397
|
+
/** Variadic union: any filter must match */
|
|
1398
|
+
some(...filters2) {
|
|
1399
|
+
return ((ctx) => filters2.some((f) => f(ctx)));
|
|
1400
|
+
}
|
|
1401
|
+
};
|
|
1402
|
+
|
|
1181
1403
|
const SECRET_TOKEN_HEADER = "X-Telegram-Bot-Api-Secret-Token";
|
|
1182
1404
|
const WRONG_TOKEN_ERROR = "secret token is invalid";
|
|
1183
1405
|
const RESPONSE_OK = "ok!";
|
|
1184
1406
|
const responseOK = () => new Response(RESPONSE_OK);
|
|
1185
1407
|
const responseUnauthorized = () => new Response(WRONG_TOKEN_ERROR, {
|
|
1186
1408
|
status: 401
|
|
1187
|
-
// @ts-ignore
|
|
1188
1409
|
});
|
|
1189
1410
|
const frameworks = {
|
|
1190
1411
|
elysia: ({ body, headers }) => ({
|
|
@@ -1278,7 +1499,11 @@ function webhookHandler(bot, framework, secretTokenOrOptions) {
|
|
|
1278
1499
|
const timeoutOptions = typeof shouldWaitOptions === "object" ? shouldWaitOptions : void 0;
|
|
1279
1500
|
const timeout = timeoutOptions?.timeout ?? 3e4;
|
|
1280
1501
|
const onTimeout = timeoutOptions?.onTimeout ?? "throw";
|
|
1281
|
-
await timeoutWebhook(
|
|
1502
|
+
await timeoutWebhook(
|
|
1503
|
+
bot.updates.handleUpdate(await update),
|
|
1504
|
+
timeout,
|
|
1505
|
+
onTimeout
|
|
1506
|
+
);
|
|
1282
1507
|
if (response) return response();
|
|
1283
1508
|
}
|
|
1284
1509
|
});
|
|
@@ -1286,4 +1511,4 @@ function webhookHandler(bot, framework, secretTokenOrOptions) {
|
|
|
1286
1511
|
|
|
1287
1512
|
Symbol.metadata ??= Symbol("Symbol.metadata");
|
|
1288
1513
|
|
|
1289
|
-
export { Bot, Composer, ErrorKind, Plugin, TelegramError, Updates, webhookHandler };
|
|
1514
|
+
export { Bot, Composer, ErrorKind, Plugin, TelegramError, Updates, filters, webhookHandler };
|