utilitas 1995.3.11 → 1995.3.13
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/utilitas.lite.mjs +1 -1
- package/dist/utilitas.lite.mjs.map +1 -1
- package/lib/bot.mjs +88 -81
- package/lib/manifest.mjs +1 -1
- package/package.json +1 -1
package/lib/bot.mjs
CHANGED
|
@@ -230,14 +230,18 @@ const newCommand = (command, description) => ({
|
|
|
230
230
|
const reply = async (ctx, md, text, extra) => {
|
|
231
231
|
try {
|
|
232
232
|
if (md) {
|
|
233
|
-
return await
|
|
233
|
+
return await (extra?.reply_to_message_id
|
|
234
|
+
? ctx.replyWithMarkdown(text, { ...extra, parse_mode: 'Markdown' })
|
|
235
|
+
: ctx.sendMessage(text, { ...extra, parse_mode: 'Markdown' }));
|
|
234
236
|
}
|
|
235
237
|
} catch (err) {
|
|
236
238
|
assert(isMarkdownError(err), err, 500);
|
|
237
239
|
await ctx.timeout();
|
|
238
240
|
}
|
|
239
241
|
return await ignoreErrFunc(
|
|
240
|
-
async () => await
|
|
242
|
+
async () => await (extra?.reply_to_message_id
|
|
243
|
+
? ctx.reply(text, extra) : ctx.sendMessage(text, extra)
|
|
244
|
+
), logOptions
|
|
241
245
|
);
|
|
242
246
|
};
|
|
243
247
|
|
|
@@ -262,7 +266,7 @@ const editMessageText = async (ctx, md, lastMsgId, text, extra) => {
|
|
|
262
266
|
const memorize = async (ctx) => {
|
|
263
267
|
if (ctx._skipMemorize) { return; }
|
|
264
268
|
const received = ctx.update;
|
|
265
|
-
const received_text = ctx.
|
|
269
|
+
const received_text = ctx.txt;
|
|
266
270
|
const id = received.update_id;
|
|
267
271
|
const response = lastItem(ctx.done.filter(x => x.text)) || {};
|
|
268
272
|
const response_text = response?.text || '';
|
|
@@ -309,7 +313,7 @@ const subconscious = [{
|
|
|
309
313
|
};
|
|
310
314
|
ctx.collect = (content, type) => type ? ctx.collected.push(
|
|
311
315
|
{ type, content }
|
|
312
|
-
) : (ctx.
|
|
316
|
+
) : (ctx.txt = content);
|
|
313
317
|
ctx.skipMemorize = () => ctx._skipMemorize = true;
|
|
314
318
|
ctx.ok = async (message, options) => {
|
|
315
319
|
let pages = paging(message);
|
|
@@ -384,30 +388,33 @@ const subconscious = [{
|
|
|
384
388
|
}, {
|
|
385
389
|
run: true, priority: -8950, name: 'subconscious', func: async (ctx, next) => {
|
|
386
390
|
for (let t of KNOWN_UPDATE_TYPES) {
|
|
387
|
-
if (ctx.update[t]) {
|
|
391
|
+
if (ctx.update[t]) {
|
|
392
|
+
ctx.m = ctx.update[ctx.type = t];
|
|
393
|
+
break;
|
|
394
|
+
}
|
|
388
395
|
}
|
|
389
|
-
if (ctx.type === 'callback_query') { ctx.
|
|
396
|
+
if (ctx.type === 'callback_query') { ctx.m = ctx.msg.message; }
|
|
390
397
|
else if (ctx.type === 'my_chat_member') {
|
|
391
398
|
log(
|
|
392
399
|
'Group member status changed: '
|
|
393
|
-
+ ctx.
|
|
394
|
-
+ ctx.
|
|
400
|
+
+ ctx.m.new_chat_member.user.id + ' => '
|
|
401
|
+
+ ctx.m.new_chat_member.status
|
|
395
402
|
);
|
|
396
|
-
if (ctx.
|
|
397
|
-
|| ctx.
|
|
403
|
+
if (ctx.m.new_chat_member.user.id !== ctx.botInfo.id
|
|
404
|
+
|| ctx.m.new_chat_member.status === 'left') { return }
|
|
398
405
|
else { ctx.hello(); }
|
|
399
406
|
} else if (!ctx.type) { return log(`Unsupported update type.`); }
|
|
400
407
|
ctx._ = bot._;
|
|
401
|
-
ctx.chatId = ctx.
|
|
402
|
-
ctx.chatType = ctx.
|
|
403
|
-
ctx.messageId = ctx.
|
|
404
|
-
ctx.
|
|
408
|
+
ctx.chatId = ctx.m.chat.id;
|
|
409
|
+
ctx.chatType = ctx.m.chat.type;
|
|
410
|
+
ctx.messageId = ctx.m.message_id;
|
|
411
|
+
ctx.m.text && ctx.collect(ctx.m.text);
|
|
405
412
|
ctx.session = await sessionGet(ctx.chatId);
|
|
406
413
|
ctx.limit = ctx.chatType === PRIVATE ? PRIVATE_LIMIT : GROUP_LIMIT;
|
|
407
414
|
ctx.entities = [
|
|
408
|
-
...(ctx.
|
|
409
|
-
...(ctx.
|
|
410
|
-
...(ctx.
|
|
415
|
+
...(ctx.m.entities || []).map(e => ({ ...e, text: ctx.m.text })),
|
|
416
|
+
...(ctx.m.caption_entities || []).map(e => ({ ...e, text: ctx.m.caption })),
|
|
417
|
+
...(ctx.m.reply_to_message?.entities || []).map(e => ({ ...e, text: ctx.m.reply_to_message.text })),
|
|
411
418
|
].map(e => ({
|
|
412
419
|
...e, matched: e.text.substring(e.offset, e.offset + e.length),
|
|
413
420
|
...e.type === 'text_link' ? { type: 'url', matched: e.url } : {},
|
|
@@ -419,16 +426,39 @@ const subconscious = [{
|
|
|
419
426
|
case bot_command: target = e.matched.split('@')[1]; break;
|
|
420
427
|
}
|
|
421
428
|
return target === ctx.botInfo.username;
|
|
422
|
-
}) || ctx.
|
|
429
|
+
}) || ctx.m.reply_to_message?.from?.username === ctx.botInfo.username)
|
|
423
430
|
&& (ctx.chatType = MENTION);
|
|
424
|
-
if ((ctx.
|
|
425
|
-
|| ctx.
|
|
431
|
+
if ((ctx.txt || ctx.m.voice || ctx.m.poll || ctx.m.data
|
|
432
|
+
|| ctx.m.document || ctx.m.photo) && ctx.messageId) {
|
|
426
433
|
await next();
|
|
427
434
|
}
|
|
428
435
|
await sessionSet(ctx.chatId);
|
|
429
436
|
},
|
|
430
437
|
}, {
|
|
431
|
-
run: true, priority: -8940, name: '
|
|
438
|
+
run: true, priority: -8940, name: 'commands', func: async (ctx, next) => {
|
|
439
|
+
for (let e of ctx.entities) {
|
|
440
|
+
if (e.type !== bot_command) { continue; }
|
|
441
|
+
if (!COMMAND_REGEXP.test(e.matched)) { continue; }
|
|
442
|
+
const cmd = trim(e.matched.replace(
|
|
443
|
+
COMMAND_REGEXP, '$1'
|
|
444
|
+
), { case: 'LOW' });
|
|
445
|
+
ctx.cmd = { cmd, args: e.text.substring(e.offset + e.length + 1) };
|
|
446
|
+
break;
|
|
447
|
+
}
|
|
448
|
+
for (let str of [ctx.txt || '', ctx.m.caption || ''].map(trim)) {
|
|
449
|
+
if (!ctx.cmd && COMMAND_REGEXP.test(str)) {
|
|
450
|
+
ctx.cmd = { // this will faild if command includes urls
|
|
451
|
+
cmd: str.replace(COMMAND_REGEXP, '$1').toLowerCase(),
|
|
452
|
+
args: str.replace(COMMAND_REGEXP, '$4'),
|
|
453
|
+
};
|
|
454
|
+
break;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
ctx.cmd && log(`Command: ${JSON.stringify(ctx.cmd)}`);
|
|
458
|
+
await next();
|
|
459
|
+
},
|
|
460
|
+
}, {
|
|
461
|
+
run: true, priority: -8930, name: 'echo', hidden: true, func: async (ctx, next) => {
|
|
432
462
|
let resp, md = false;
|
|
433
463
|
switch (ctx.cmd.cmd) {
|
|
434
464
|
case 'echo':
|
|
@@ -488,10 +518,10 @@ const subconscious = [{
|
|
|
488
518
|
lorem: '[Lorem ipsum](https://en.wikipedia.org/wiki/Lorem_ipsum)',
|
|
489
519
|
},
|
|
490
520
|
}, {
|
|
491
|
-
run: true, priority: -
|
|
521
|
+
run: true, priority: -8920, name: 'authenticate', func: async (ctx, next) => {
|
|
492
522
|
if (!await ctx.shouldReply()) { return; } // if chatType is not in whitelist, exit.
|
|
493
523
|
if (!ctx._.private) { return await next(); } // if not private, go next.
|
|
494
|
-
if (ctx._.magicWord && insensitiveHas(ctx._.magicWord, ctx.
|
|
524
|
+
if (ctx._.magicWord && insensitiveHas(ctx._.magicWord, ctx.txt)) { // auth by magicWord
|
|
495
525
|
ctx._.private.add(String(ctx.chatId));
|
|
496
526
|
await ctx.ok('😸 You are now allowed to talk to me.');
|
|
497
527
|
ctx.hello();
|
|
@@ -515,11 +545,11 @@ const subconscious = [{
|
|
|
515
545
|
await ctx.ok('😿 Sorry, I am not allowed to talk to strangers.');
|
|
516
546
|
},
|
|
517
547
|
}, {
|
|
518
|
-
run: true, priority: -
|
|
519
|
-
if (ctx._.speech?.stt && ctx.
|
|
548
|
+
run: true, priority: -8910, name: 'speech-to-text', func: async (ctx, next) => {
|
|
549
|
+
if (ctx._.speech?.stt && ctx.m.voice?.mime_type === 'audio/ogg') {
|
|
520
550
|
await ctx.ok(EMOJI_SPEECH);
|
|
521
551
|
try {
|
|
522
|
-
const file = await getFile(ctx.
|
|
552
|
+
const file = await getFile(ctx.m.voice.file_id, BUFFER_ENCODE);
|
|
523
553
|
const resp = await ignoreErrFunc(
|
|
524
554
|
async () => await ctx._.speech?.stt(file), logOptions
|
|
525
555
|
) || ' ';
|
|
@@ -530,7 +560,7 @@ const subconscious = [{
|
|
|
530
560
|
await next();
|
|
531
561
|
},
|
|
532
562
|
}, {
|
|
533
|
-
run: true, priority: -
|
|
563
|
+
run: true, priority: -8900, name: 'callback', func: async (ctx, next) => {
|
|
534
564
|
if (ctx.type === 'callback_query') {
|
|
535
565
|
const data = parseJson(ctx.update[ctx.type].data);
|
|
536
566
|
const cb = ctx.session.callback.filter(x => x.id == data?.callback)[0];
|
|
@@ -539,29 +569,29 @@ const subconscious = [{
|
|
|
539
569
|
ctx.collect(cb.text);
|
|
540
570
|
} else {
|
|
541
571
|
return await ctx.er(
|
|
542
|
-
`Command is invalid or expired: ${ctx.
|
|
572
|
+
`Command is invalid or expired: ${ctx.m.data}`
|
|
543
573
|
);
|
|
544
574
|
}
|
|
545
575
|
}
|
|
546
576
|
await next();
|
|
547
577
|
},
|
|
548
578
|
}, {
|
|
549
|
-
run: true, priority: -
|
|
550
|
-
ctx.
|
|
551
|
-
'Question:', ctx.
|
|
552
|
-
'Options:', oList(ctx.
|
|
579
|
+
run: true, priority: -8890, name: 'poll', func: async (ctx, next) => {
|
|
580
|
+
ctx.m.poll && ctx.collect(lines([
|
|
581
|
+
'Question:', ctx.m.poll.question, '',
|
|
582
|
+
'Options:', oList(ctx.m.poll.options.map(x => x.text)),
|
|
553
583
|
]));
|
|
554
584
|
await next();
|
|
555
585
|
},
|
|
556
586
|
}, {
|
|
557
|
-
run: true, priority: -
|
|
558
|
-
ctx.
|
|
559
|
-
ctx.
|
|
587
|
+
run: true, priority: -8880, name: 'contaxt', func: async (ctx, next) => {
|
|
588
|
+
ctx.m.reply_to_message?.text && ctx.collect(
|
|
589
|
+
ctx.m.reply_to_message.text, 'CONTAXT'
|
|
560
590
|
);
|
|
561
591
|
await next();
|
|
562
592
|
},
|
|
563
593
|
}, {
|
|
564
|
-
run: true, priority: -
|
|
594
|
+
run: true, priority: -8870, name: 'web', func: async (ctx, next) => {
|
|
565
595
|
if (ctx.entities.some(e => e.type === 'url')) {
|
|
566
596
|
await ctx.ok(EMOJI_LOOK);
|
|
567
597
|
for (let e of ctx.entities) {
|
|
@@ -575,37 +605,37 @@ const subconscious = [{
|
|
|
575
605
|
await next();
|
|
576
606
|
},
|
|
577
607
|
}, {
|
|
578
|
-
run: true, priority: -
|
|
608
|
+
run: true, priority: -8860, name: 'vision', func: async (ctx, next) => {
|
|
579
609
|
let fileId, type, file_name, mime_type, ocrFunc, asPrompt = false;
|
|
580
|
-
if ('application/pdf' === ctx.
|
|
610
|
+
if ('application/pdf' === ctx.m.document?.mime_type) {
|
|
581
611
|
ocrFunc = ctx._.vision?.read;
|
|
582
|
-
fileId = ctx.
|
|
583
|
-
file_name = ctx.
|
|
584
|
-
mime_type = ctx.
|
|
612
|
+
fileId = ctx.m.document.file_id;
|
|
613
|
+
file_name = ctx.m.document.file_name;
|
|
614
|
+
mime_type = ctx.m.document.mime_type;
|
|
585
615
|
type = 'DOCUMENT';
|
|
586
|
-
} else if (/^image\/.*$/ig.test(ctx.
|
|
587
|
-
asPrompt = bot._.supportedMimeTypes.has(ctx.
|
|
616
|
+
} else if (/^image\/.*$/ig.test(ctx.m.document?.mime_type)) {
|
|
617
|
+
asPrompt = bot._.supportedMimeTypes.has(ctx.m.document.mime_type);
|
|
588
618
|
ocrFunc = ctx._.vision?.see;
|
|
589
|
-
fileId = ctx.
|
|
590
|
-
file_name = ctx.
|
|
591
|
-
mime_type = ctx.
|
|
619
|
+
fileId = ctx.m.document.file_id;
|
|
620
|
+
file_name = ctx.m.document.file_name;
|
|
621
|
+
mime_type = ctx.m.document.mime_type;
|
|
592
622
|
type = 'IMAGE';
|
|
593
|
-
} else if (/^.*\.(docx|xlsx|pptx)$/.test(ctx.
|
|
623
|
+
} else if (/^.*\.(docx|xlsx|pptx)$/.test(ctx.m.document?.file_name)) {
|
|
594
624
|
ocrFunc = officeParser;
|
|
595
|
-
fileId = ctx.
|
|
596
|
-
file_name = ctx.
|
|
597
|
-
mime_type = ctx.
|
|
625
|
+
fileId = ctx.m.document.file_id;
|
|
626
|
+
file_name = ctx.m.document.file_name;
|
|
627
|
+
mime_type = ctx.m.document.mime_type;
|
|
598
628
|
type = 'DOCUMENT';
|
|
599
|
-
} else if (ctx.
|
|
629
|
+
} else if (ctx.m.document) {
|
|
600
630
|
ocrFunc = async file => (await isTextFile(file)) && file.toString();
|
|
601
|
-
fileId = ctx.
|
|
602
|
-
file_name = ctx.
|
|
603
|
-
mime_type = ctx.
|
|
631
|
+
fileId = ctx.m.document.file_id;
|
|
632
|
+
file_name = ctx.m.document.file_name;
|
|
633
|
+
mime_type = ctx.m.document.mime_type;
|
|
604
634
|
type = 'FILE';
|
|
605
|
-
} else if (ctx.
|
|
635
|
+
} else if (ctx.m.photo) {
|
|
606
636
|
asPrompt = true;
|
|
607
637
|
ocrFunc = ctx._.vision?.see;
|
|
608
|
-
fileId = ctx.
|
|
638
|
+
fileId = ctx.m.photo[ctx.m.photo.length - 1]?.file_id;
|
|
609
639
|
mime_type = 'image';
|
|
610
640
|
type = 'PHOTO';
|
|
611
641
|
}
|
|
@@ -615,7 +645,7 @@ const subconscious = [{
|
|
|
615
645
|
const image_url = await getFileUrl(fileId);
|
|
616
646
|
const file = (await get(image_url, BUFFER_ENCODE)).content;
|
|
617
647
|
if (asPrompt) {
|
|
618
|
-
ctx.collect(ctx.
|
|
648
|
+
ctx.collect(ctx.m.caption || '');
|
|
619
649
|
ctx.collect({
|
|
620
650
|
mime_type: mime_type === 'image' ? 'image/jpeg' : mime_type,
|
|
621
651
|
image_url, data: base64Encode(file, true),
|
|
@@ -628,7 +658,7 @@ const subconscious = [{
|
|
|
628
658
|
), logOptions)
|
|
629
659
|
).filter(x => x).join('\n'));
|
|
630
660
|
if (content) {
|
|
631
|
-
ctx.collect(ctx.
|
|
661
|
+
ctx.collect(ctx.m.caption || '');
|
|
632
662
|
ctx.collect(lines([
|
|
633
663
|
'---', ...file_name ? [`file_name: ${file_name}`] : [],
|
|
634
664
|
`mime_type: ${mime_type}`, `type: ${type}`, '---',
|
|
@@ -640,29 +670,6 @@ const subconscious = [{
|
|
|
640
670
|
}
|
|
641
671
|
await next();
|
|
642
672
|
},
|
|
643
|
-
}, {
|
|
644
|
-
run: true, priority: -8860, name: 'commands', func: async (ctx, next) => {
|
|
645
|
-
for (let e of ctx.entities) {
|
|
646
|
-
if (e.type !== bot_command) { continue; }
|
|
647
|
-
if (!COMMAND_REGEXP.test(e.matched)) { continue; }
|
|
648
|
-
const cmd = trim(e.matched.replace(
|
|
649
|
-
COMMAND_REGEXP, '$1'
|
|
650
|
-
), { case: 'LOW' });
|
|
651
|
-
ctx.cmd = { cmd, args: e.text.substring(e.offset + e.length + 1) };
|
|
652
|
-
break;
|
|
653
|
-
}
|
|
654
|
-
for (let str of [ctx.text || '', ctx.msg.caption || ''].map(trim)) {
|
|
655
|
-
if (!ctx.cmd && COMMAND_REGEXP.test(str)) {
|
|
656
|
-
ctx.cmd = { // this will faild if command includes urls
|
|
657
|
-
cmd: str.replace(COMMAND_REGEXP, '$1').toLowerCase(),
|
|
658
|
-
args: str.replace(COMMAND_REGEXP, '$4'),
|
|
659
|
-
};
|
|
660
|
-
break;
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
ctx.cmd && log(`Command: ${JSON.stringify(ctx.cmd)}`);
|
|
664
|
-
await next();
|
|
665
|
-
},
|
|
666
673
|
}, {
|
|
667
674
|
run: true, priority: -8850, name: 'help', func: async (ctx, next) => {
|
|
668
675
|
const help = ctx._.info ? [ctx._.info] : [];
|
package/lib/manifest.mjs
CHANGED