balebaazoo 1.2.3 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +275 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +68 -8
- package/dist/index.d.ts +68 -8
- package/dist/index.js +270 -23
- package/dist/index.js.map +1 -1
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ SDK مدرن و type-safe برای توسعهٔ بازو (Bot) در پیام
|
|
|
6
6
|
|
|
7
7
|
بر پایهٔ [مستندات رسمی API بازوی بله](https://docs.bale.ai/) ساخته شده است.
|
|
8
8
|
|
|
9
|
-
**English:** [README.en.md](README.en.md) · **مستندات فارسی:** [docs/fa/usage.md](docs/fa/usage.md)
|
|
9
|
+
**English:** [README.en.md](README.en.md) · **مستندات فارسی:** [docs/fa/usage.md](docs/fa/usage.md) · **سایت مستندات:** https://hadimardanian.github.io/baleBaazooSDK/fa/usage.html
|
|
10
10
|
|
|
11
11
|
## نصب
|
|
12
12
|
|
package/dist/index.cjs
CHANGED
|
@@ -416,7 +416,13 @@ var Api = class {
|
|
|
416
416
|
return this.call("answerPreCheckoutQuery", asParams(params));
|
|
417
417
|
}
|
|
418
418
|
inquireTransaction(params) {
|
|
419
|
-
|
|
419
|
+
const transactionId = params.transaction_id || params.provider_payment_charge_id;
|
|
420
|
+
if (!transactionId) {
|
|
421
|
+
throw new Error("transaction_id is required for inquireTransaction");
|
|
422
|
+
}
|
|
423
|
+
return this.call("inquireTransaction", {
|
|
424
|
+
transaction_id: transactionId
|
|
425
|
+
});
|
|
420
426
|
}
|
|
421
427
|
};
|
|
422
428
|
function asParams(params) {
|
|
@@ -473,6 +479,13 @@ function matchUpdate(update) {
|
|
|
473
479
|
const matches = [];
|
|
474
480
|
if (update.message) {
|
|
475
481
|
matches.push("message");
|
|
482
|
+
if (update.message.animation) matches.push("message:animation");
|
|
483
|
+
if (update.message.new_chat_members?.length) {
|
|
484
|
+
matches.push("message:new_chat_members");
|
|
485
|
+
}
|
|
486
|
+
if (update.message.left_chat_member) {
|
|
487
|
+
matches.push("message:left_chat_member");
|
|
488
|
+
}
|
|
476
489
|
if (update.message.text !== void 0) matches.push("message:text");
|
|
477
490
|
if (update.message.photo) matches.push("message:photo");
|
|
478
491
|
if (update.message.document) matches.push("message:document");
|
|
@@ -532,20 +545,32 @@ function matchesChatType(ctx, chatType) {
|
|
|
532
545
|
|
|
533
546
|
// src/composer.ts
|
|
534
547
|
var Composer = class _Composer {
|
|
535
|
-
handler;
|
|
536
548
|
registered = [];
|
|
549
|
+
dirty = true;
|
|
550
|
+
snapshot = [];
|
|
551
|
+
cachedHandler;
|
|
537
552
|
constructor(...middleware) {
|
|
538
553
|
this.registered.push(...middleware.map(normalizeMiddleware));
|
|
539
|
-
this.
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
554
|
+
this.markDirty();
|
|
555
|
+
}
|
|
556
|
+
markDirty() {
|
|
557
|
+
this.dirty = true;
|
|
558
|
+
this.cachedHandler = void 0;
|
|
543
559
|
}
|
|
544
560
|
middleware() {
|
|
545
|
-
|
|
561
|
+
if (!this.cachedHandler || this.dirty) {
|
|
562
|
+
this.snapshot = [...this.registered];
|
|
563
|
+
this.cachedHandler = async (ctx, next) => {
|
|
564
|
+
await runMiddleware(this.snapshot, ctx);
|
|
565
|
+
await next();
|
|
566
|
+
};
|
|
567
|
+
this.dirty = false;
|
|
568
|
+
}
|
|
569
|
+
return this.cachedHandler;
|
|
546
570
|
}
|
|
547
571
|
use(...middleware) {
|
|
548
572
|
this.registered.push(...middleware.map(normalizeMiddleware));
|
|
573
|
+
this.markDirty();
|
|
549
574
|
return this;
|
|
550
575
|
}
|
|
551
576
|
on(filter, ...middleware) {
|
|
@@ -569,6 +594,7 @@ var Composer = class _Composer {
|
|
|
569
594
|
);
|
|
570
595
|
});
|
|
571
596
|
composer.registered.push(...middleware);
|
|
597
|
+
this.markDirty();
|
|
572
598
|
return this;
|
|
573
599
|
}
|
|
574
600
|
command(command, ...middleware) {
|
|
@@ -623,6 +649,17 @@ var Composer = class _Composer {
|
|
|
623
649
|
...middleware
|
|
624
650
|
);
|
|
625
651
|
}
|
|
652
|
+
static compose(...composers) {
|
|
653
|
+
const result = new _Composer();
|
|
654
|
+
for (const item of composers) {
|
|
655
|
+
if (item instanceof _Composer) {
|
|
656
|
+
result.use(item);
|
|
657
|
+
} else {
|
|
658
|
+
result.use(item);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
return result;
|
|
662
|
+
}
|
|
626
663
|
};
|
|
627
664
|
function escapeRegex(value) {
|
|
628
665
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -635,6 +672,8 @@ var Context = class {
|
|
|
635
672
|
botInfo;
|
|
636
673
|
callbackQueryAnswered = false;
|
|
637
674
|
_updateTypes;
|
|
675
|
+
session = {};
|
|
676
|
+
state = {};
|
|
638
677
|
constructor(options) {
|
|
639
678
|
this.api = options.api;
|
|
640
679
|
this.update = options.update;
|
|
@@ -733,6 +772,54 @@ var Context = class {
|
|
|
733
772
|
const chatId = this.requireChatId();
|
|
734
773
|
return this.api.sendInvoice({ chat_id: chatId, ...params });
|
|
735
774
|
}
|
|
775
|
+
targetMessage() {
|
|
776
|
+
return this.callbackQuery?.message ?? this.message;
|
|
777
|
+
}
|
|
778
|
+
async editMessageText(text, extra) {
|
|
779
|
+
const message = this.targetMessage();
|
|
780
|
+
if (!message) {
|
|
781
|
+
throw new Error("No message to edit in context");
|
|
782
|
+
}
|
|
783
|
+
return this.api.editMessageText({
|
|
784
|
+
chat_id: message.chat.id,
|
|
785
|
+
message_id: message.message_id,
|
|
786
|
+
text,
|
|
787
|
+
...extra
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
async deleteMessage(params) {
|
|
791
|
+
const message = this.targetMessage();
|
|
792
|
+
const chatId = params?.chat_id ?? message?.chat.id ?? this.chatId;
|
|
793
|
+
const messageId = params?.message_id ?? message?.message_id;
|
|
794
|
+
if (chatId === void 0 || messageId === void 0) {
|
|
795
|
+
throw new Error("No message to delete in context");
|
|
796
|
+
}
|
|
797
|
+
return this.api.deleteMessage({ chat_id: chatId, message_id: messageId });
|
|
798
|
+
}
|
|
799
|
+
async forwardMessage(toChatId, params) {
|
|
800
|
+
const message = this.targetMessage();
|
|
801
|
+
if (!message && !params?.from_chat_id) {
|
|
802
|
+
throw new Error("No source message in context");
|
|
803
|
+
}
|
|
804
|
+
return this.api.forwardMessage({
|
|
805
|
+
chat_id: toChatId,
|
|
806
|
+
from_chat_id: params?.from_chat_id ?? message.chat.id,
|
|
807
|
+
message_id: params?.message_id ?? message.message_id,
|
|
808
|
+
...params
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
async copyMessage(toChatId, params) {
|
|
812
|
+
const message = this.targetMessage();
|
|
813
|
+
if (!message && !params?.from_chat_id) {
|
|
814
|
+
throw new Error("No source message in context");
|
|
815
|
+
}
|
|
816
|
+
return this.api.copyMessage({
|
|
817
|
+
chat_id: toChatId,
|
|
818
|
+
from_chat_id: params?.from_chat_id ?? message.chat.id,
|
|
819
|
+
message_id: params?.message_id ?? message.message_id,
|
|
820
|
+
...params
|
|
821
|
+
});
|
|
822
|
+
}
|
|
736
823
|
async sendChatAction(action) {
|
|
737
824
|
const chatId = this.requireChatId();
|
|
738
825
|
return this.api.sendChatAction({ chat_id: chatId, action });
|
|
@@ -842,14 +929,7 @@ var PollingRunner = class {
|
|
|
842
929
|
{ signal }
|
|
843
930
|
);
|
|
844
931
|
this.backoffAttempt = 0;
|
|
845
|
-
|
|
846
|
-
this.offset = update.update_id + 1;
|
|
847
|
-
try {
|
|
848
|
-
await bot.handleUpdate(update);
|
|
849
|
-
} catch (error) {
|
|
850
|
-
onError(error);
|
|
851
|
-
}
|
|
852
|
-
}
|
|
932
|
+
await this.processUpdates(bot, updates, options, onError);
|
|
853
933
|
if (updates.length === 0 && signal.aborted) {
|
|
854
934
|
break;
|
|
855
935
|
}
|
|
@@ -868,6 +948,34 @@ var PollingRunner = class {
|
|
|
868
948
|
}
|
|
869
949
|
}
|
|
870
950
|
}
|
|
951
|
+
async processUpdates(bot, updates, options, onError) {
|
|
952
|
+
const concurrency = Math.max(1, options.concurrency ?? 1);
|
|
953
|
+
if (concurrency === 1) {
|
|
954
|
+
for (const update of updates) {
|
|
955
|
+
this.offset = update.update_id + 1;
|
|
956
|
+
try {
|
|
957
|
+
await bot.handleUpdate(update);
|
|
958
|
+
} catch (error) {
|
|
959
|
+
onError(error);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
let index = 0;
|
|
965
|
+
const workers = Array.from({ length: Math.min(concurrency, updates.length) }, async () => {
|
|
966
|
+
while (index < updates.length) {
|
|
967
|
+
const current = index++;
|
|
968
|
+
const update = updates[current];
|
|
969
|
+
this.offset = update.update_id + 1;
|
|
970
|
+
try {
|
|
971
|
+
await bot.handleUpdate(update);
|
|
972
|
+
} catch (error) {
|
|
973
|
+
onError(error);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
await Promise.all(workers);
|
|
978
|
+
}
|
|
871
979
|
setOffset(offset) {
|
|
872
980
|
this.offset = offset;
|
|
873
981
|
}
|
|
@@ -935,7 +1043,7 @@ async function webhookFromJson(bot) {
|
|
|
935
1043
|
// src/bot.ts
|
|
936
1044
|
var Bot = class extends Composer {
|
|
937
1045
|
api;
|
|
938
|
-
|
|
1046
|
+
_botInfo;
|
|
939
1047
|
polling = new PollingRunner();
|
|
940
1048
|
autoAnswer;
|
|
941
1049
|
catchHandler;
|
|
@@ -943,17 +1051,23 @@ var Bot = class extends Composer {
|
|
|
943
1051
|
const api = new Api({ token, ...options });
|
|
944
1052
|
super();
|
|
945
1053
|
this.api = api;
|
|
946
|
-
this.
|
|
1054
|
+
this._botInfo = options.botInfo;
|
|
947
1055
|
this.autoAnswer = options.autoAnswerCallback ?? true;
|
|
948
1056
|
if (this.autoAnswer) {
|
|
949
1057
|
this.use(autoAnswerCallback());
|
|
950
1058
|
}
|
|
951
1059
|
}
|
|
1060
|
+
get telegram() {
|
|
1061
|
+
return this.api;
|
|
1062
|
+
}
|
|
1063
|
+
get botInfo() {
|
|
1064
|
+
return this._botInfo;
|
|
1065
|
+
}
|
|
952
1066
|
async init() {
|
|
953
|
-
if (!this.
|
|
954
|
-
this.
|
|
1067
|
+
if (!this._botInfo) {
|
|
1068
|
+
this._botInfo = await this.api.getMe();
|
|
955
1069
|
}
|
|
956
|
-
return this.
|
|
1070
|
+
return this._botInfo;
|
|
957
1071
|
}
|
|
958
1072
|
catch(handler) {
|
|
959
1073
|
this.catchHandler = handler;
|
|
@@ -976,7 +1090,7 @@ var Bot = class extends Composer {
|
|
|
976
1090
|
return new Context({
|
|
977
1091
|
api: this.api,
|
|
978
1092
|
update,
|
|
979
|
-
botInfo: this.
|
|
1093
|
+
botInfo: this._botInfo
|
|
980
1094
|
});
|
|
981
1095
|
}
|
|
982
1096
|
async start(options = {}) {
|
|
@@ -1007,7 +1121,7 @@ var Bot = class extends Composer {
|
|
|
1007
1121
|
}
|
|
1008
1122
|
if (options.onStart) {
|
|
1009
1123
|
try {
|
|
1010
|
-
await options.onStart(this.
|
|
1124
|
+
await options.onStart(this._botInfo);
|
|
1011
1125
|
} catch (error) {
|
|
1012
1126
|
onError(error);
|
|
1013
1127
|
return;
|
|
@@ -1018,6 +1132,13 @@ var Bot = class extends Composer {
|
|
|
1018
1132
|
launch(options) {
|
|
1019
1133
|
return this.start(options);
|
|
1020
1134
|
}
|
|
1135
|
+
async switchToPolling(options = {}) {
|
|
1136
|
+
await this.api.deleteWebhook();
|
|
1137
|
+
await this.start({
|
|
1138
|
+
...options,
|
|
1139
|
+
dropPendingUpdates: options.dropPendingUpdates ?? true
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1021
1142
|
async stop() {
|
|
1022
1143
|
await this.polling.stop();
|
|
1023
1144
|
}
|
|
@@ -1138,6 +1259,132 @@ function setupGracefulShutdown(bot, options = {}) {
|
|
|
1138
1259
|
}
|
|
1139
1260
|
}
|
|
1140
1261
|
|
|
1262
|
+
// src/scenes/index.ts
|
|
1263
|
+
var Scene = class extends Composer {
|
|
1264
|
+
id;
|
|
1265
|
+
enterMiddleware = [];
|
|
1266
|
+
leaveMiddleware = [];
|
|
1267
|
+
constructor(id, ...middleware) {
|
|
1268
|
+
super(...middleware);
|
|
1269
|
+
this.id = id;
|
|
1270
|
+
}
|
|
1271
|
+
enter(...middleware) {
|
|
1272
|
+
this.enterMiddleware.push(...middleware);
|
|
1273
|
+
return this;
|
|
1274
|
+
}
|
|
1275
|
+
leave(...middleware) {
|
|
1276
|
+
this.leaveMiddleware.push(...middleware);
|
|
1277
|
+
return this;
|
|
1278
|
+
}
|
|
1279
|
+
async runEnter(ctx) {
|
|
1280
|
+
await runMiddleware(this.enterMiddleware, ctx);
|
|
1281
|
+
}
|
|
1282
|
+
async runLeave(ctx) {
|
|
1283
|
+
await runMiddleware(this.leaveMiddleware, ctx);
|
|
1284
|
+
}
|
|
1285
|
+
};
|
|
1286
|
+
var Stage = class extends Composer {
|
|
1287
|
+
scenes = /* @__PURE__ */ new Map();
|
|
1288
|
+
register(...scenes) {
|
|
1289
|
+
for (const scene of scenes) {
|
|
1290
|
+
this.scenes.set(scene.id, scene);
|
|
1291
|
+
}
|
|
1292
|
+
return this;
|
|
1293
|
+
}
|
|
1294
|
+
getScene(id) {
|
|
1295
|
+
return this.scenes.get(id);
|
|
1296
|
+
}
|
|
1297
|
+
async enter(ctx, sceneId, state = {}) {
|
|
1298
|
+
const scene = this.scenes.get(sceneId);
|
|
1299
|
+
if (!scene) {
|
|
1300
|
+
throw new Error(`Scene "${sceneId}" is not registered`);
|
|
1301
|
+
}
|
|
1302
|
+
const session2 = ctx.session;
|
|
1303
|
+
const currentId = session2.__scene?.id;
|
|
1304
|
+
if (currentId && currentId !== sceneId) {
|
|
1305
|
+
const current = this.scenes.get(currentId);
|
|
1306
|
+
if (current) {
|
|
1307
|
+
await leaveScene(ctx, current);
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
await enterScene(ctx, sceneId, scene, state);
|
|
1311
|
+
}
|
|
1312
|
+
async leave(ctx) {
|
|
1313
|
+
const session2 = ctx.session;
|
|
1314
|
+
const sceneId = session2.__scene?.id;
|
|
1315
|
+
if (!sceneId) return;
|
|
1316
|
+
const scene = this.scenes.get(sceneId);
|
|
1317
|
+
if (scene) {
|
|
1318
|
+
await leaveScene(ctx, scene);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
middleware() {
|
|
1322
|
+
const sceneMiddleware = super.middleware();
|
|
1323
|
+
return async (ctx, next) => {
|
|
1324
|
+
const session2 = ctx.session;
|
|
1325
|
+
const sceneId = session2.__scene?.id;
|
|
1326
|
+
if (!sceneId) {
|
|
1327
|
+
await sceneMiddleware(ctx, next);
|
|
1328
|
+
return;
|
|
1329
|
+
}
|
|
1330
|
+
const scene = this.scenes.get(sceneId);
|
|
1331
|
+
if (!scene) {
|
|
1332
|
+
delete session2.__scene;
|
|
1333
|
+
await sceneMiddleware(ctx, next);
|
|
1334
|
+
return;
|
|
1335
|
+
}
|
|
1336
|
+
await scene.middleware()(ctx, next);
|
|
1337
|
+
};
|
|
1338
|
+
}
|
|
1339
|
+
};
|
|
1340
|
+
async function enterScene(ctx, sceneId, scene, initialState = {}) {
|
|
1341
|
+
const session2 = ctx.session;
|
|
1342
|
+
session2.__scene = { ...initialState, id: sceneId };
|
|
1343
|
+
await scene.runEnter(ctx);
|
|
1344
|
+
}
|
|
1345
|
+
async function leaveScene(ctx, scene) {
|
|
1346
|
+
const session2 = ctx.session;
|
|
1347
|
+
await scene.runLeave(ctx);
|
|
1348
|
+
delete session2.__scene;
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
// src/session/memory.ts
|
|
1352
|
+
function memorySessionStore() {
|
|
1353
|
+
const data = /* @__PURE__ */ new Map();
|
|
1354
|
+
return {
|
|
1355
|
+
get: (key) => data.get(key),
|
|
1356
|
+
set: (key, value) => {
|
|
1357
|
+
data.set(key, value);
|
|
1358
|
+
},
|
|
1359
|
+
delete: (key) => {
|
|
1360
|
+
data.delete(key);
|
|
1361
|
+
}
|
|
1362
|
+
};
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
// src/session/index.ts
|
|
1366
|
+
function session(options) {
|
|
1367
|
+
const store = options.store ?? memorySessionStore();
|
|
1368
|
+
return async (ctx, next) => {
|
|
1369
|
+
const key = options.getSessionKey(ctx);
|
|
1370
|
+
if (!key) {
|
|
1371
|
+
await next();
|
|
1372
|
+
return;
|
|
1373
|
+
}
|
|
1374
|
+
let current = store.get(key) ?? options.defaultSession(ctx);
|
|
1375
|
+
Object.defineProperty(ctx, "session", {
|
|
1376
|
+
configurable: true,
|
|
1377
|
+
enumerable: true,
|
|
1378
|
+
get: () => current,
|
|
1379
|
+
set: (value) => {
|
|
1380
|
+
current = value;
|
|
1381
|
+
}
|
|
1382
|
+
});
|
|
1383
|
+
await next();
|
|
1384
|
+
store.set(key, current);
|
|
1385
|
+
};
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1141
1388
|
exports.Api = Api;
|
|
1142
1389
|
exports.BaleAPIError = BaleAPIError;
|
|
1143
1390
|
exports.BaleError = BaleError;
|
|
@@ -1150,23 +1397,29 @@ exports.InlineKeyboard = InlineKeyboard;
|
|
|
1150
1397
|
exports.InputFile = InputFile;
|
|
1151
1398
|
exports.PollingRunner = PollingRunner;
|
|
1152
1399
|
exports.ReplyKeyboard = ReplyKeyboard;
|
|
1400
|
+
exports.Scene = Scene;
|
|
1401
|
+
exports.Stage = Stage;
|
|
1153
1402
|
exports.autoAnswerCallback = autoAnswerCallback;
|
|
1154
1403
|
exports.bold = bold;
|
|
1155
1404
|
exports.createWebhookHandler = createWebhookHandler;
|
|
1405
|
+
exports.enterScene = enterScene;
|
|
1156
1406
|
exports.errorHandler = errorHandler;
|
|
1157
1407
|
exports.extractCommand = extractCommand;
|
|
1158
1408
|
exports.isFilePath = isFilePath;
|
|
1159
1409
|
exports.isMiddlewareObject = isMiddlewareObject;
|
|
1160
1410
|
exports.italic = italic;
|
|
1411
|
+
exports.leaveScene = leaveScene;
|
|
1161
1412
|
exports.link = link;
|
|
1162
1413
|
exports.matchUpdate = matchUpdate;
|
|
1163
1414
|
exports.matchesAnyFilter = matchesAnyFilter;
|
|
1164
1415
|
exports.matchesChatType = matchesChatType;
|
|
1165
1416
|
exports.matchesFilter = matchesFilter;
|
|
1166
1417
|
exports.md = md;
|
|
1418
|
+
exports.memorySessionStore = memorySessionStore;
|
|
1167
1419
|
exports.normalizeMiddleware = normalizeMiddleware;
|
|
1168
1420
|
exports.removeKeyboard = removeKeyboard;
|
|
1169
1421
|
exports.runMiddleware = runMiddleware;
|
|
1422
|
+
exports.session = session;
|
|
1170
1423
|
exports.setupGracefulShutdown = setupGracefulShutdown;
|
|
1171
1424
|
exports.spoiler = spoiler;
|
|
1172
1425
|
exports.webhookFromJson = webhookFromJson;
|