@xbibzlibrary/telebibz 0.4.5 → 3.1.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/CHANGELOG.md +53 -138
- package/LICENSE +1 -1
- package/NOTICE.md +9 -4
- package/README.id.md +542 -206
- package/README.md +539 -213
- package/examples/01-quickstart.js +13 -0
- package/examples/02-menu-tombol.js +22 -0
- package/examples/03-wizard.js +58 -0
- package/examples/04-broadcast.js +25 -0
- package/examples/05-kirim-file.js +19 -0
- package/examples/06-menu.js +35 -0
- package/examples/07-inline-query.js +18 -0
- package/index.d.ts +106 -0
- package/index.js +44 -0
- package/lib/api.js +154 -0
- package/lib/broadcast.js +35 -0
- package/lib/composer.js +174 -0
- package/lib/context.js +190 -0
- package/lib/errors.js +35 -0
- package/lib/file.js +41 -0
- package/lib/inline-query.js +28 -0
- package/lib/keyboard.js +83 -0
- package/lib/logger.js +38 -0
- package/lib/menus.js +90 -0
- package/lib/net.js +115 -0
- package/lib/ratelimit.js +61 -0
- package/lib/runner.js +45 -0
- package/lib/session.js +36 -0
- package/lib/telebibz.js +193 -0
- package/lib/wizard.js +247 -0
- package/package.json +35 -97
- package/test/all.test.js +439 -0
- package/CODE_OF_CONDUCT.md +0 -37
- package/CONTRIBUTING.md +0 -59
- package/CONTRIBUTION_RULES.md +0 -41
- package/GOVERNANCE.md +0 -47
- package/README.zh-CN.md +0 -306
- package/RELEASE_AUTOMATION.md +0 -78
- package/RELEASE_POLICY.md +0 -32
- package/SECURITY.md +0 -47
- package/SHOWCASE.md +0 -29
- package/SUPPORT.md +0 -30
- package/assets/readme-preview.html +0 -75
- package/assets/telebibz-logo.png +0 -0
- package/assets/telebibz-readme-preview.png +0 -0
- package/bin/telebibz.mjs +0 -3
- package/dist/generated/api.d.ts +0 -13
- package/dist/generated/api.d.ts.map +0 -1
- package/dist/generated/api.js +0 -192
- package/dist/generated/api.js.map +0 -1
- package/dist/src/api/client.d.ts +0 -62
- package/dist/src/api/client.d.ts.map +0 -1
- package/dist/src/api/client.js +0 -104
- package/dist/src/api/client.js.map +0 -1
- package/dist/src/api/errors.d.ts +0 -45
- package/dist/src/api/errors.d.ts.map +0 -1
- package/dist/src/api/errors.js +0 -65
- package/dist/src/api/errors.js.map +0 -1
- package/dist/src/api/index.d.ts +0 -6
- package/dist/src/api/index.d.ts.map +0 -1
- package/dist/src/api/index.js +0 -6
- package/dist/src/api/index.js.map +0 -1
- package/dist/src/api/telegram-types/LICENSE +0 -21
- package/dist/src/api/telegram-types/api.d.ts +0 -22
- package/dist/src/api/telegram-types/checklist.d.ts +0 -72
- package/dist/src/api/telegram-types/inline.d.ts +0 -692
- package/dist/src/api/telegram-types/langs.d.ts +0 -193
- package/dist/src/api/telegram-types/manage.d.ts +0 -1144
- package/dist/src/api/telegram-types/markup.d.ts +0 -268
- package/dist/src/api/telegram-types/message.d.ts +0 -1537
- package/dist/src/api/telegram-types/methods.d.ts +0 -2870
- package/dist/src/api/telegram-types/mod.d.ts +0 -14
- package/dist/src/api/telegram-types/passport.d.ts +0 -163
- package/dist/src/api/telegram-types/payment.d.ts +0 -570
- package/dist/src/api/telegram-types/rich.d.ts +0 -1010
- package/dist/src/api/telegram-types/settings.d.ts +0 -120
- package/dist/src/api/telegram-types/story.d.ts +0 -89
- package/dist/src/api/telegram-types/update.d.ts +0 -84
- package/dist/src/api/telegram.d.ts +0 -7
- package/dist/src/api/telegram.d.ts.map +0 -1
- package/dist/src/api/telegram.js +0 -2
- package/dist/src/api/telegram.js.map +0 -1
- package/dist/src/api/transport.d.ts +0 -68
- package/dist/src/api/transport.d.ts.map +0 -1
- package/dist/src/api/transport.js +0 -264
- package/dist/src/api/transport.js.map +0 -1
- package/dist/src/api/types.d.ts +0 -466
- package/dist/src/api/types.d.ts.map +0 -1
- package/dist/src/api/types.js +0 -2
- package/dist/src/api/types.js.map +0 -1
- package/dist/src/branding/terminal.d.ts +0 -77
- package/dist/src/branding/terminal.d.ts.map +0 -1
- package/dist/src/branding/terminal.js +0 -328
- package/dist/src/branding/terminal.js.map +0 -1
- package/dist/src/broadcast/broadcast.d.ts +0 -50
- package/dist/src/broadcast/broadcast.d.ts.map +0 -1
- package/dist/src/broadcast/broadcast.js +0 -56
- package/dist/src/broadcast/broadcast.js.map +0 -1
- package/dist/src/cache/cache.d.ts +0 -34
- package/dist/src/cache/cache.d.ts.map +0 -1
- package/dist/src/cache/cache.js +0 -41
- package/dist/src/cache/cache.js.map +0 -1
- package/dist/src/cli.d.ts +0 -2
- package/dist/src/cli.d.ts.map +0 -1
- package/dist/src/cli.js +0 -84
- package/dist/src/cli.js.map +0 -1
- package/dist/src/context/context.d.ts +0 -124
- package/dist/src/context/context.d.ts.map +0 -1
- package/dist/src/context/context.js +0 -302
- package/dist/src/context/context.js.map +0 -1
- package/dist/src/core/bot.d.ts +0 -204
- package/dist/src/core/bot.d.ts.map +0 -1
- package/dist/src/core/bot.js +0 -506
- package/dist/src/core/bot.js.map +0 -1
- package/dist/src/core/events.d.ts +0 -75
- package/dist/src/core/events.d.ts.map +0 -1
- package/dist/src/core/events.js +0 -35
- package/dist/src/core/events.js.map +0 -1
- package/dist/src/core/webhook-reply.d.ts +0 -34
- package/dist/src/core/webhook-reply.d.ts.map +0 -1
- package/dist/src/core/webhook-reply.js +0 -37
- package/dist/src/core/webhook-reply.js.map +0 -1
- package/dist/src/index.d.ts +0 -24
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -24
- package/dist/src/index.js.map +0 -1
- package/dist/src/keyboard/index.d.ts +0 -46
- package/dist/src/keyboard/index.d.ts.map +0 -1
- package/dist/src/keyboard/index.js +0 -55
- package/dist/src/keyboard/index.js.map +0 -1
- package/dist/src/middleware/compose.d.ts +0 -5
- package/dist/src/middleware/compose.d.ts.map +0 -1
- package/dist/src/middleware/compose.js +0 -17
- package/dist/src/middleware/compose.js.map +0 -1
- package/dist/src/observability/logger.d.ts +0 -78
- package/dist/src/observability/logger.d.ts.map +0 -1
- package/dist/src/observability/logger.js +0 -285
- package/dist/src/observability/logger.js.map +0 -1
- package/dist/src/plugins/plugin.d.ts +0 -38
- package/dist/src/plugins/plugin.d.ts.map +0 -1
- package/dist/src/plugins/plugin.js +0 -59
- package/dist/src/plugins/plugin.js.map +0 -1
- package/dist/src/queue/queue.d.ts +0 -77
- package/dist/src/queue/queue.d.ts.map +0 -1
- package/dist/src/queue/queue.js +0 -213
- package/dist/src/queue/queue.js.map +0 -1
- package/dist/src/router/router.d.ts +0 -61
- package/dist/src/router/router.d.ts.map +0 -1
- package/dist/src/router/router.js +0 -183
- package/dist/src/router/router.js.map +0 -1
- package/dist/src/state/conversation.d.ts +0 -56
- package/dist/src/state/conversation.d.ts.map +0 -1
- package/dist/src/state/conversation.js +0 -133
- package/dist/src/state/conversation.js.map +0 -1
- package/dist/src/state/forms.d.ts +0 -34
- package/dist/src/state/forms.d.ts.map +0 -1
- package/dist/src/state/forms.js +0 -44
- package/dist/src/state/forms.js.map +0 -1
- package/dist/src/state/menu.d.ts +0 -78
- package/dist/src/state/menu.d.ts.map +0 -1
- package/dist/src/state/menu.js +0 -127
- package/dist/src/state/menu.js.map +0 -1
- package/dist/src/storage/storage.d.ts +0 -146
- package/dist/src/storage/storage.d.ts.map +0 -1
- package/dist/src/storage/storage.js +0 -195
- package/dist/src/storage/storage.js.map +0 -1
- package/dist/src/telegram-features.d.ts +0 -33
- package/dist/src/telegram-features.d.ts.map +0 -1
- package/dist/src/telegram-features.js +0 -71
- package/dist/src/telegram-features.js.map +0 -1
- package/dist/src/testing.d.ts +0 -24
- package/dist/src/testing.d.ts.map +0 -1
- package/dist/src/testing.js +0 -38
- package/dist/src/testing.js.map +0 -1
- package/dist/src/utils/concurrency.d.ts +0 -25
- package/dist/src/utils/concurrency.d.ts.map +0 -1
- package/dist/src/utils/concurrency.js +0 -52
- package/dist/src/utils/concurrency.js.map +0 -1
- package/dist/src/utils/files.d.ts +0 -45
- package/dist/src/utils/files.d.ts.map +0 -1
- package/dist/src/utils/files.js +0 -53
- package/dist/src/utils/files.js.map +0 -1
- package/dist/src/utils/text.d.ts +0 -39
- package/dist/src/utils/text.d.ts.map +0 -1
- package/dist/src/utils/text.js +0 -56
- package/dist/src/utils/text.js.map +0 -1
- package/dist/src/webhook/handler.d.ts +0 -19
- package/dist/src/webhook/handler.d.ts.map +0 -1
- package/dist/src/webhook/handler.js +0 -141
- package/dist/src/webhook/handler.js.map +0 -1
- package/dist-cjs/generated/api.js +0 -194
- package/dist-cjs/package.json +0 -3
- package/dist-cjs/src/api/client.js +0 -107
- package/dist-cjs/src/api/errors.js +0 -74
- package/dist-cjs/src/api/index.js +0 -21
- package/dist-cjs/src/api/telegram-types/LICENSE +0 -21
- package/dist-cjs/src/api/telegram-types/api.d.ts +0 -22
- package/dist-cjs/src/api/telegram-types/checklist.d.ts +0 -72
- package/dist-cjs/src/api/telegram-types/inline.d.ts +0 -692
- package/dist-cjs/src/api/telegram-types/langs.d.ts +0 -193
- package/dist-cjs/src/api/telegram-types/manage.d.ts +0 -1144
- package/dist-cjs/src/api/telegram-types/markup.d.ts +0 -268
- package/dist-cjs/src/api/telegram-types/message.d.ts +0 -1537
- package/dist-cjs/src/api/telegram-types/methods.d.ts +0 -2870
- package/dist-cjs/src/api/telegram-types/mod.d.ts +0 -14
- package/dist-cjs/src/api/telegram-types/passport.d.ts +0 -163
- package/dist-cjs/src/api/telegram-types/payment.d.ts +0 -570
- package/dist-cjs/src/api/telegram-types/rich.d.ts +0 -1010
- package/dist-cjs/src/api/telegram-types/settings.d.ts +0 -120
- package/dist-cjs/src/api/telegram-types/story.d.ts +0 -89
- package/dist-cjs/src/api/telegram-types/update.d.ts +0 -84
- package/dist-cjs/src/api/telegram.js +0 -2
- package/dist-cjs/src/api/transport.js +0 -267
- package/dist-cjs/src/api/types.js +0 -2
- package/dist-cjs/src/branding/terminal.js +0 -338
- package/dist-cjs/src/broadcast/broadcast.js +0 -58
- package/dist-cjs/src/cache/cache.js +0 -45
- package/dist-cjs/src/cli.js +0 -86
- package/dist-cjs/src/context/context.js +0 -305
- package/dist-cjs/src/core/bot.js +0 -510
- package/dist-cjs/src/core/events.js +0 -38
- package/dist-cjs/src/core/webhook-reply.js +0 -42
- package/dist-cjs/src/index.js +0 -47
- package/dist-cjs/src/keyboard/index.js +0 -61
- package/dist-cjs/src/middleware/compose.js +0 -20
- package/dist-cjs/src/observability/logger.js +0 -293
- package/dist-cjs/src/plugins/plugin.js +0 -63
- package/dist-cjs/src/queue/queue.js +0 -219
- package/dist-cjs/src/router/router.js +0 -186
- package/dist-cjs/src/state/conversation.js +0 -139
- package/dist-cjs/src/state/forms.js +0 -47
- package/dist-cjs/src/state/menu.js +0 -133
- package/dist-cjs/src/storage/storage.js +0 -202
- package/dist-cjs/src/telegram-features.js +0 -76
- package/dist-cjs/src/testing.js +0 -45
- package/dist-cjs/src/utils/concurrency.js +0 -57
- package/dist-cjs/src/utils/files.js +0 -58
- package/dist-cjs/src/utils/text.js +0 -63
- package/dist-cjs/src/webhook/handler.js +0 -144
- package/docs/API.id.md +0 -1935
- package/docs/API.md +0 -1969
- package/docs/API.zh-CN.md +0 -1929
- package/docs/COOKBOOK.id.md +0 -321
- package/docs/COOKBOOK.md +0 -321
- package/docs/COOKBOOK.zh-CN.md +0 -321
- package/docs/ERRORS.id.md +0 -194
- package/docs/ERRORS.md +0 -194
- package/docs/ERRORS.zh-CN.md +0 -194
- package/docs/FILES.id.md +0 -243
- package/docs/FILES.md +0 -243
- package/docs/FILES.zh-CN.md +0 -243
- package/docs/GETTING_STARTED.id.md +0 -89
- package/docs/GETTING_STARTED.md +0 -89
- package/docs/GETTING_STARTED.zh-CN.md +0 -89
- package/docs/GITHUB_PACKAGES.id.md +0 -82
- package/docs/GITHUB_PACKAGES.md +0 -82
- package/docs/GITHUB_PACKAGES.zh-CN.md +0 -82
- package/docs/MIGRATION_TELEGRAF.id.md +0 -147
- package/docs/MIGRATION_TELEGRAF.md +0 -154
- package/docs/MIGRATION_TELEGRAF.zh-CN.md +0 -147
- package/docs/README.md +0 -67
- package/docs/STORAGE.id.md +0 -105
- package/docs/STORAGE.md +0 -105
- package/docs/STORAGE.zh-CN.md +0 -105
- package/docs/TESTING.id.md +0 -203
- package/docs/TESTING.md +0 -203
- package/docs/TESTING.zh-CN.md +0 -203
- package/docs/WEBHOOK.id.md +0 -212
- package/docs/WEBHOOK.md +0 -215
- package/docs/WEBHOOK.zh-CN.md +0 -212
- package/examples/README.md +0 -37
- package/examples/files.ts +0 -35
- package/examples/minimal.ts +0 -12
- package/examples/tsconfig.json +0 -9
- package/examples/webhook.ts +0 -42
- package/examples/wizard-registration.ts +0 -42
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// examples/01-quickstart.js — bot jalan dalam 6 baris kode.
|
|
2
|
+
// BOT_TOKEN=123:abc node examples/01-quickstart.js
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
const { TeleBibz } = require('..');
|
|
6
|
+
|
|
7
|
+
const bot = new TeleBibz(process.env.BOT_TOKEN);
|
|
8
|
+
|
|
9
|
+
bot.cmd('start', (ctx) => ctx.reply(`Halo ${ctx.from.first_name}! Aku hidup 🎉`));
|
|
10
|
+
bot.hears(/halo|hai/i, (ctx) => ctx.reply('Halo juga! 👋'));
|
|
11
|
+
bot.hears('ping', (ctx) => ctx.reply('pong 🏓'));
|
|
12
|
+
|
|
13
|
+
bot.launch();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// examples/02-menu-tombol.js — inline keyboard berwarna + ikon animated.
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { TeleBibz, btn, url, kb } = require('..');
|
|
5
|
+
|
|
6
|
+
const bot = new TeleBibz(process.env.BOT_TOKEN);
|
|
7
|
+
|
|
8
|
+
bot.cmd('menu', (ctx) =>
|
|
9
|
+
ctx.reply('Pilih menu:', kb([
|
|
10
|
+
[btn('💎 Premium', 'premium', 'primary'), btn('📞 Bantuan', 'bantuan')],
|
|
11
|
+
[url('🌐 Website', 'https://example.com', 'success')],
|
|
12
|
+
[btn('❌ Tutup', 'tutup', 'danger')],
|
|
13
|
+
])));
|
|
14
|
+
|
|
15
|
+
bot.action('premium', async (ctx) => {
|
|
16
|
+
await ctx.answerCallbackQuery('Menuju halaman premium…');
|
|
17
|
+
await ctx.reply('💎 Daftar paket premium…');
|
|
18
|
+
});
|
|
19
|
+
bot.action('bantuan', (ctx) => ctx.answerCallbackQuery({ text: 'Hubungi @admin ya!', show_alert: true }));
|
|
20
|
+
bot.action('tutup', (ctx) => ctx.deleteMessage().catch(() => {}));
|
|
21
|
+
|
|
22
|
+
bot.launch();
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// examples/03-wizard.js — form pendaftaran tanya-jawab + TOMBOL + mode edit/delete.
|
|
2
|
+
// BOT_TOKEN=123:abc node examples/03-wizard.js
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
const { TeleBibz } = require('..');
|
|
6
|
+
|
|
7
|
+
const bot = new TeleBibz(process.env.BOT_TOKEN);
|
|
8
|
+
|
|
9
|
+
bot.wizard('daftar', {
|
|
10
|
+
// mode tampilan pertanyaan:
|
|
11
|
+
// 'send' → tiap pertanyaan jadi pesan baru (default)
|
|
12
|
+
// 'edit' → SATU pesan diedit terus dari awal sampai akhir
|
|
13
|
+
// 'delete' → pesan lama dihapus dulu, baru tanya berikutnya
|
|
14
|
+
mode: 'edit',
|
|
15
|
+
|
|
16
|
+
steps: [
|
|
17
|
+
{ key: 'nama', ask: '1️⃣ Siapa nama lengkapmu?' },
|
|
18
|
+
|
|
19
|
+
{
|
|
20
|
+
// TOMBOL reply keyboard — user tinggal ketuk, tak perlu mengetik
|
|
21
|
+
key: 'jk',
|
|
22
|
+
ask: '2️⃣ Jenis kelamin?',
|
|
23
|
+
buttons: ['👨 Laki-laki', '👩 Perempuan'],
|
|
24
|
+
onlyButtons: true, // tolak ketikan bebas
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
{
|
|
28
|
+
// TOMBOL inline (callback) — nilai bisa beda dari label,
|
|
29
|
+
// dan pesan langsung diedit ke langkah berikutnya
|
|
30
|
+
key: 'domisili',
|
|
31
|
+
ask: '3️⃣ Domisili pulau mana?',
|
|
32
|
+
inline: true,
|
|
33
|
+
onlyButtons: true,
|
|
34
|
+
buttons: [
|
|
35
|
+
[{ text: '🌋 Jawa', value: 'jawa' }, { text: '🌴 Sumatera', value: 'sumatera' }],
|
|
36
|
+
[{ text: '🏝️ Lainnya', value: 'lainnya' }],
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
key: 'umur',
|
|
42
|
+
ask: '4️⃣ Umur berapa? (ketik "batal" untuk berhenti)',
|
|
43
|
+
parse: (t) => parseInt(t, 10),
|
|
44
|
+
validate: (n) => (Number.isFinite(n) && n > 0 && n < 120 ? null : 'Umur tidak valid — ketik angka saja ya:'),
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
|
|
48
|
+
// cleanup bawaan: pesan tanya terakhir otomatis dibereskan,
|
|
49
|
+
// reply keyboard otomatis disingkirkan (nonaktif: removeKeyboard: false)
|
|
50
|
+
done: async (ans, ctx) => {
|
|
51
|
+
await ctx.reply(
|
|
52
|
+
`✅ Terdaftar!\nNama : ${ans.nama}\nJK : ${ans.jk}\nDomisili : ${ans.domisili}\nUmur : ${ans.umur}`,
|
|
53
|
+
);
|
|
54
|
+
},
|
|
55
|
+
onCancel: (ctx) => ctx.reply('👋 Pendaftaran dibatalkan.'),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
bot.launch();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// examples/04-broadcast.js — blast pesan ke banyak chat tanpa kena limit.
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { TeleBibz, kb, url } = require('..');
|
|
5
|
+
|
|
6
|
+
const bot = new TeleBibz(process.env.BOT_TOKEN);
|
|
7
|
+
const subscribers = new Set(); // produksi: simpan di DB
|
|
8
|
+
|
|
9
|
+
bot.cmd('start', (ctx) => {
|
|
10
|
+
subscribers.add(ctx.chat.id);
|
|
11
|
+
ctx.reply('Kamu terdaftar! Admin bisa /blast untuk info ke semua.');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
bot.cmd('blast', async (ctx) => {
|
|
15
|
+
if (String(ctx.from.id) !== process.env.ADMIN_ID) return ctx.reply('Khusus admin.');
|
|
16
|
+
const teks = ctx.message.text.replace(/^\/blast\s*/i, '').trim();
|
|
17
|
+
if (!teks) return ctx.reply('Pakai: /blast isi pesannya');
|
|
18
|
+
|
|
19
|
+
const proses = await ctx.reply(`Mengirim ke ${subscribers.size} chat…`);
|
|
20
|
+
const hasil = await bot.broadcast([...subscribers], { text: teks, ...kb([[url('Info', 'https://example.com')]]) });
|
|
21
|
+
await ctx.reply(`Selesai ✅ terkirim ${hasil.terkirim}, gagal ${hasil.gagal}`);
|
|
22
|
+
await ctx.api.deleteMessage(ctx.chat.id, proses.message_id).catch(() => {});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
bot.launch();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// examples/05-kirim-file.js — kirim foto dari URL & dokumen dari Buffer.
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { TeleBibz, InputFile } = require('..');
|
|
5
|
+
|
|
6
|
+
const bot = new TeleBibz(process.env.BOT_TOKEN);
|
|
7
|
+
|
|
8
|
+
bot.cmd('kucing', async (ctx) => {
|
|
9
|
+
const r = await fetch('https://cataas.com/cat');
|
|
10
|
+
const buf = Buffer.from(await r.arrayBuffer());
|
|
11
|
+
await ctx.replyWithPhoto(new InputFile(buf, 'kucing.jpg'), { caption: 'Meong 🐱' });
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
bot.cmd('laporan', async (ctx) => {
|
|
15
|
+
const data = Buffer.from(`Laporan ${new Date().toISOString()}\nHalo dunia!`);
|
|
16
|
+
await ctx.replyWithDocument(new InputFile(data, 'laporan.txt'));
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
bot.launch();
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// examples/06-menu.js — Menu inline ala @grammyjs/menu dengan submenu.
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { TeleBibz, MenuContainer } = require('..');
|
|
5
|
+
|
|
6
|
+
const bot = new TeleBibz(process.env.BOT_TOKEN);
|
|
7
|
+
const mc = new MenuContainer();
|
|
8
|
+
|
|
9
|
+
const utama = mc.create('utama');
|
|
10
|
+
const setelan = mc.create('setelan');
|
|
11
|
+
|
|
12
|
+
const state = { notif: true };
|
|
13
|
+
|
|
14
|
+
utama
|
|
15
|
+
.text('⚙️ Setelan', async (ctx) => {
|
|
16
|
+
await ctx.editMessageReplyMarkup({ reply_markup: await setelan.render(ctx) });
|
|
17
|
+
await ctx.answerCallbackQuery();
|
|
18
|
+
})
|
|
19
|
+
.row()
|
|
20
|
+
.url('📚 Dokumentasi', 'https://github.com/XbibzOfficial777/telebibz');
|
|
21
|
+
|
|
22
|
+
setelan
|
|
23
|
+
.text('🔔 Toggle Notif', async (ctx) => {
|
|
24
|
+
state.notif = !state.notif;
|
|
25
|
+
await ctx.answerCallbackQuery({ text: `Notif ${state.notif ? 'ON ✅' : 'OFF ❌'}` });
|
|
26
|
+
})
|
|
27
|
+
.back('◀️ Kembali', 'utama');
|
|
28
|
+
|
|
29
|
+
bot.use(mc);
|
|
30
|
+
|
|
31
|
+
bot.cmd('menu', async (ctx) => {
|
|
32
|
+
await ctx.reply('Pilih menu:', { reply_markup: await utama.render(ctx) });
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
bot.launch();
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// examples/07-inline-query.js — mode inline: ketik @botkamu apa saja di chat apa pun.
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { TeleBibz, iq } = require('..');
|
|
5
|
+
|
|
6
|
+
const bot = new TeleBibz(process.env.BOT_TOKEN);
|
|
7
|
+
|
|
8
|
+
bot.inlineQuery('*', async (ctx) => {
|
|
9
|
+
const q = (ctx.inline_query.query || '').trim();
|
|
10
|
+
const hasil = [
|
|
11
|
+
iq.article('echo', `Echo: ${q || '…'}`, { message_text: q || 'ketik sesuatu setelah @botkamu' }),
|
|
12
|
+
iq.article('caps', 'HURUF BESAR', { message_text: (q || 'HALO').toUpperCase() }),
|
|
13
|
+
iq.article('terbalik', 'Balik teks', { message_text: [...(q || 'halo')].reverse().join('') }),
|
|
14
|
+
];
|
|
15
|
+
await ctx.answerInlineQuery(hasil, { cache_time: 0, is_personal: true });
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
bot.launch();
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// index.d.ts — tipe ringkas untuk autocompletion editor (autocorrect).
|
|
2
|
+
// v3: tipe longgar (JS-first) — parity grammY.
|
|
3
|
+
type Context = any; type Bot = any;
|
|
4
|
+
|
|
5
|
+
declare module '@xbibzlibrary/telebibz' {
|
|
6
|
+
type Color = 'danger' | 'success' | 'primary';
|
|
7
|
+
type Handler = (ctx: Context) => unknown;
|
|
8
|
+
|
|
9
|
+
type WizardMode = 'send' | 'edit' | 'delete';
|
|
10
|
+
type WizardButton = string | { text: string; value?: unknown };
|
|
11
|
+
interface WizardStep {
|
|
12
|
+
key: string;
|
|
13
|
+
ask: string | ((ctx: Context) => string | Promise<string>);
|
|
14
|
+
parse?: (text: string, ctx: Context) => unknown | Promise<unknown>;
|
|
15
|
+
validate?: (value: unknown, ctx: Context) => string | null | Promise<string | null>;
|
|
16
|
+
opts?: Record<string, unknown>;
|
|
17
|
+
/** Tombol pilihan: ['A','B'] | [{text,value}] | baris eksplisit [['A'],['B','C']]. */
|
|
18
|
+
buttons?: Array<WizardButton | WizardButton[]>;
|
|
19
|
+
/** true → tombol inline (callback), default reply keyboard. */
|
|
20
|
+
inline?: boolean;
|
|
21
|
+
/** true/string → tolak ketikan bebas, wajib pilih tombol. */
|
|
22
|
+
onlyButtons?: boolean | string;
|
|
23
|
+
/** Override mode tampilan per langkah. */
|
|
24
|
+
mode?: WizardMode;
|
|
25
|
+
/** Reply keyboard sekali pakai. */
|
|
26
|
+
oneTime?: boolean;
|
|
27
|
+
}
|
|
28
|
+
interface WizardDef {
|
|
29
|
+
steps: WizardStep[];
|
|
30
|
+
done: (answers: Record<string, unknown>, ctx: Context) => unknown;
|
|
31
|
+
cancelWords?: string[];
|
|
32
|
+
onCancel?: (ctx: Context) => unknown;
|
|
33
|
+
/** 'send' (default) | 'edit' satu pesan | 'delete' tanya-hapus per langkah. */
|
|
34
|
+
mode?: WizardMode;
|
|
35
|
+
/** Hapus pesan tanya terakhir saat wizard selesai (default: true bila mode 'delete'). */
|
|
36
|
+
cleanup?: boolean;
|
|
37
|
+
/** Singkirkan reply keyboard saat selesai (default: true bila tombol reply pernah dipakai). */
|
|
38
|
+
removeKeyboard?: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface TeleBibzOpts {
|
|
42
|
+
allowedUpdates?: string[];
|
|
43
|
+
onError?: (err: unknown, ctx?: Context) => unknown;
|
|
44
|
+
silent?: boolean;
|
|
45
|
+
dropPending?: boolean;
|
|
46
|
+
session?: { initial?: () => unknown; getKey?: (ctx: Context) => string | undefined; storage?: unknown };
|
|
47
|
+
transport?: (method: string, payload?: object) => Promise<unknown>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
class TeleBibz {
|
|
51
|
+
constructor(token: string, opts?: TeleBibzOpts);
|
|
52
|
+
api: any;
|
|
53
|
+
botInfo: any;
|
|
54
|
+
use(...mw: any[]): this;
|
|
55
|
+
cmd(names: string | string[], ...mw: Handler[]): this;
|
|
56
|
+
hears(match: string | RegExp, ...mw: Handler[]): this;
|
|
57
|
+
action(trigs: string | RegExp | string[], ...mw: Handler[]): this;
|
|
58
|
+
on(filter: string | string[], ...mw: Handler[]): this;
|
|
59
|
+
start(replies: string | Handler): this;
|
|
60
|
+
wizard(id: string, def: WizardDef, bindCommand?: boolean): this;
|
|
61
|
+
wizardStart(ctx: Context, id: string): Promise<unknown>;
|
|
62
|
+
wizardActive(ctx: Context): boolean;
|
|
63
|
+
wizardCancel(ctx: Context): Promise<boolean>;
|
|
64
|
+
wizardEdit(ctx: Context, text: string, extra?: object): Promise<unknown>;
|
|
65
|
+
wizardDelete(ctx: Context): Promise<boolean>;
|
|
66
|
+
broadcast(ids: Array<number | string>, pesan: any, opts?: { delay?: number }): Promise<{ terkirim: number; gagal: number; errors: Array<{ chatId: any; pesan: string }> }>;
|
|
67
|
+
launch(opts?: Record<string, unknown>): Promise<this>;
|
|
68
|
+
handleUpdate(update: any): Promise<void>;
|
|
69
|
+
webhook(...args: any[]): any;
|
|
70
|
+
stop(): Promise<void>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function btn(text: string, callbackData: string | number, style?: Color, iconId?: string): any;
|
|
74
|
+
function url(text: string, link: string, style?: Color, iconId?: string): any;
|
|
75
|
+
function webApp(text: string, link: string, iconId?: string): any;
|
|
76
|
+
function copy(text: string, value: string, iconId?: string): any;
|
|
77
|
+
function kb(rows: any[][]): { reply_markup: { inline_keyboard: any[][] } };
|
|
78
|
+
namespace kb {
|
|
79
|
+
function markup(rows: any[][]): { inline_keyboard: any[][] };
|
|
80
|
+
function confirm(yesData: string, noData: string, labelYes?: string, labelNo?: string): any;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const wizard: {
|
|
84
|
+
define: (id: string, def: WizardDef) => string;
|
|
85
|
+
start: (ctx: Context, id: string) => Promise<unknown>;
|
|
86
|
+
active: (ctx: Context) => boolean;
|
|
87
|
+
cancel: (ctx: Context) => Promise<boolean>;
|
|
88
|
+
editAsk: (ctx: Context, text: string, extra?: object) => Promise<unknown>;
|
|
89
|
+
deleteAsk: (ctx: Context) => Promise<boolean>;
|
|
90
|
+
KEY: string;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
function humanize(err: unknown): { pesan: string; saran: string | null; method?: string; code?: number };
|
|
94
|
+
const log: { info: Function; ok: Function; warn: Function; error: Function; banner: Function };
|
|
95
|
+
const say: { html: (text: string, extra?: object) => object };
|
|
96
|
+
|
|
97
|
+
class File { constructor(src: any, filename?: string, type?: string); src: any; filename: string; data(): Promise<Buffer>; }
|
|
98
|
+
const InputFile: typeof File;
|
|
99
|
+
const InlineKeyboard: any;
|
|
100
|
+
const Keyboard: any;
|
|
101
|
+
class ApiError extends Error { description: string; error_code?: number; method?: string; payload?: any; }
|
|
102
|
+
const Composer: any; const BotError: any; const session: any; const Api: any;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
import { Menu as _M } from './lib/menus';
|
|
106
|
+
export {};
|
package/index.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// index.js — pintu masuk @xbibzlibrary/telebibz.
|
|
2
|
+
// v3: set fitur production-grade setara grammY (lihat README -> FEATURE MATRIX).
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
const { TeleBibz } = require('./lib/telebibz');
|
|
6
|
+
const { ApiError, createTransport } = require('./lib/net');
|
|
7
|
+
const { File, InputFile, InputMediaBuilder } = require('./lib/file');
|
|
8
|
+
const { btn, url, webApp, copy, kb, InlineKeyboard, Keyboard } = require('./lib/keyboard');
|
|
9
|
+
const wizard = require('./lib/wizard');
|
|
10
|
+
const { humanize } = require('./lib/errors');
|
|
11
|
+
const log = require('./lib/logger');
|
|
12
|
+
const { session } = require('./lib/session');
|
|
13
|
+
const { Composer, BotError } = require('./lib/composer');
|
|
14
|
+
const { makeApi } = require('./lib/api');
|
|
15
|
+
const { Context } = require('./lib/context');
|
|
16
|
+
const { broadcast } = require('./lib/broadcast');
|
|
17
|
+
const { autoRetry, throttler, limiter } = require('./lib/ratelimit');
|
|
18
|
+
const { matchInlineQuery, iq } = require('./lib/inline-query');
|
|
19
|
+
const { Menu, MenuContainer } = require('./lib/menus');
|
|
20
|
+
|
|
21
|
+
const say = {
|
|
22
|
+
html: (text, extra = {}) => ({ ...extra, text, parse_mode: 'HTML' }),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
// kelas utama
|
|
27
|
+
TeleBibz, Context, Composer, BotError, session,
|
|
28
|
+
// wizard (form percakapan + tombol + edit/delete)
|
|
29
|
+
wizard,
|
|
30
|
+
// keyboard & menu
|
|
31
|
+
btn, url, webApp, copy, kb, InlineKeyboard, Keyboard, Menu, MenuContainer,
|
|
32
|
+
// percakapan
|
|
33
|
+
wizard,
|
|
34
|
+
// file & media
|
|
35
|
+
File, InputFile, InputMediaBuilder,
|
|
36
|
+
// api & transport
|
|
37
|
+
makeApi, createTransport, ApiError,
|
|
38
|
+
// anti-spam & keandalan
|
|
39
|
+
autoRetry, throttler, limiter, broadcast,
|
|
40
|
+
// inline mode
|
|
41
|
+
matchInlineQuery, iq,
|
|
42
|
+
// util
|
|
43
|
+
humanize, log, say,
|
|
44
|
+
};
|
package/lib/api.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// lib/api.js — akses penuh Bot API: ~60 shortcut + PROXY untuk SEGALA metode +
|
|
2
|
+
// transformer pipeline (api.config.use) gaya grammY + download file.
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
const { createTransport } = require('./net');
|
|
6
|
+
|
|
7
|
+
class ApiConfig {
|
|
8
|
+
constructor() { this.transformers = []; }
|
|
9
|
+
/** Sisipkan transformer: (prev, method, payload) => result */
|
|
10
|
+
use(t) { this.transformers.push(t); return this; }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class ApiBase {
|
|
14
|
+
constructor(token, transport) {
|
|
15
|
+
this.token = token;
|
|
16
|
+
this.config = new ApiConfig();
|
|
17
|
+
this._base = transport || createTransport(token, {});
|
|
18
|
+
this.raw = (method, payload = {}) => this.callApi(method, payload);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async callApi(method, payload = {}) {
|
|
22
|
+
let fn = this._base;
|
|
23
|
+
for (const t of this.config.transformers) {
|
|
24
|
+
const prev = fn;
|
|
25
|
+
fn = (m, p) => t(prev, m, p);
|
|
26
|
+
}
|
|
27
|
+
return fn(method, payload);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* =============== metode umum =============== */
|
|
31
|
+
getMe() { return this.callApi('getMe'); }
|
|
32
|
+
logOut() { return this.callApi('logOut'); }
|
|
33
|
+
close() { return this.callApi('close'); }
|
|
34
|
+
|
|
35
|
+
/* ---- pesan ---- */
|
|
36
|
+
sendMessage(chat_id, text, extra = {}) { return this.callApi('sendMessage', { chat_id, text, ...extra }); }
|
|
37
|
+
forwardMessage(chat_id, from_chat_id, message_id, extra = {}) { return this.callApi('forwardMessage', { chat_id, from_chat_id, message_id, ...extra }); }
|
|
38
|
+
forwardMessages(chat_id, from_chat_id, message_ids, extra = {}) { return this.callApi('forwardMessages', { chat_id, from_chat_id, message_ids, ...extra }); }
|
|
39
|
+
copyMessage(chat_id, from_chat_id, message_id, extra = {}) { return this.callApi('copyMessage', { chat_id, from_chat_id, message_id, ...extra }); }
|
|
40
|
+
copyMessages(chat_id, from_chat_id, message_ids, extra = {}) { return this.callApi('copyMessages', { chat_id, from_chat_id, message_ids, ...extra }); }
|
|
41
|
+
editMessageText(chat_id, message_id, text, extra = {}) { return this.callApi('editMessageText', { chat_id, message_id, text, ...extra }); }
|
|
42
|
+
editMessageCaption(chat_id, message_id, extra = {}) { return this.callApi('editMessageCaption', { chat_id, message_id, ...extra }); }
|
|
43
|
+
editMessageMedia(chat_id, message_id, media, extra = {}) { return this.callApi('editMessageMedia', { chat_id, message_id, media, ...extra }); }
|
|
44
|
+
editMessageReplyMarkup(chat_id, message_id, extra = {}) { return this.callApi('editMessageReplyMarkup', { chat_id, message_id, ...extra }); }
|
|
45
|
+
deleteMessage(chat_id, message_id) { return this.callApi('deleteMessage', { chat_id, message_id }); }
|
|
46
|
+
deleteMessages(chat_id, message_ids) { return this.callApi('deleteMessages', { chat_id, message_ids }); }
|
|
47
|
+
setMessageReaction(chat_id, message_id, reaction, extra = {}) { return this.callApi('setMessageReaction', { chat_id, message_id, reaction, ...extra }); }
|
|
48
|
+
sendChatAction(chat_id, action, extra = {}) { return this.callApi('sendChatAction', { chat_id, action, ...extra }); }
|
|
49
|
+
|
|
50
|
+
/* ---- media ---- */
|
|
51
|
+
sendPhoto(c, photo, e = {}) { return this.callApi('sendPhoto', { chat_id: c, photo, ...e }); }
|
|
52
|
+
sendVideo(c, video, e = {}) { return this.callApi('sendVideo', { chat_id: c, video, ...e }); }
|
|
53
|
+
sendAudio(c, audio, e = {}) { return this.callApi('sendAudio', { chat_id: c, audio, ...e }); }
|
|
54
|
+
sendDocument(c, document, e = {}) { return this.callApi('sendDocument', { chat_id: c, document, ...e }); }
|
|
55
|
+
sendAnimation(c, animation, e = {}) { return this.callApi('sendAnimation', { chat_id: c, animation, ...e }); }
|
|
56
|
+
sendVoice(c, voice, e = {}) { return this.callApi('sendVoice', { chat_id: c, voice, ...e }); }
|
|
57
|
+
sendVideoNote(c, vn, e = {}) { return this.callApi('sendVideoNote', { chat_id: c, video_note: vn, ...e }); }
|
|
58
|
+
sendSticker(c, sticker, e = {}) { return this.callApi('sendSticker', { chat_id: c, sticker, ...e }); }
|
|
59
|
+
sendMediaGroup(c, media, e = {}) { return this.callApi('sendMediaGroup', { chat_id: c, media, ...e }); }
|
|
60
|
+
sendLocation(c, lat, lon, e = {}) { return this.callApi('sendLocation', { chat_id: c, latitude: lat, longitude: lon, ...e }); }
|
|
61
|
+
sendVenue(c, lat, lon, title, address, e = {}) { return this.callApi('sendVenue', { chat_id: c, latitude: lat, longitude: lon, title, address, ...e }); }
|
|
62
|
+
sendContact(c, phone, first, e = {}) { return this.callApi('sendContact', { chat_id: c, phone_number: phone, first_name: first, ...e }); }
|
|
63
|
+
sendPoll(c, question, options, e = {}) { return this.callApi('sendPoll', { chat_id: c, question, options, ...e }); }
|
|
64
|
+
sendDice(c, emoji, e = {}) { return this.callApi('sendDice', { chat_id: c, ...(emoji ? { emoji } : {}), ...e }); }
|
|
65
|
+
stopPoll(c, message_id, e = {}) { return this.callApi('stopPoll', { chat_id: c, message_id, ...e }); }
|
|
66
|
+
|
|
67
|
+
/* ---- file ---- */
|
|
68
|
+
getFile(file_id) { return this.callApi('getFile', { file_id }); }
|
|
69
|
+
/** Unduh file_id ke disk; return path tujuan. */
|
|
70
|
+
async downloadFile(file_id, dest, axiosOpts = {}) {
|
|
71
|
+
const f = await this.getFile(file_id);
|
|
72
|
+
const axios = require('axios');
|
|
73
|
+
const fs = require('fs');
|
|
74
|
+
const url = `https://api.telegram.org/file/bot${this.token}/${f.file_path}`;
|
|
75
|
+
const res = await axios.get(url, { responseType: 'stream', ...axiosOpts });
|
|
76
|
+
const out = fs.createWriteStream(dest);
|
|
77
|
+
await new Promise((ok, no) => { res.data.pipe(out); out.on('finish', ok); out.on('error', no); res.data.on('error', no); });
|
|
78
|
+
return dest;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* ---- callback & inline ---- */
|
|
82
|
+
answerCallbackQuery(id, e = {}) { return this.callApi('answerCallbackQuery', { callback_query_id: id, ...e }); }
|
|
83
|
+
answerInlineQuery(id, results, e = {}) { return this.callApi('answerInlineQuery', { inline_query_id: id, results, ...e }); }
|
|
84
|
+
|
|
85
|
+
/* ---- grup & admin ---- */
|
|
86
|
+
banChatMember(c, u, e = {}) { return this.callApi('banChatMember', { chat_id: c, user_id: u, ...e }); }
|
|
87
|
+
unbanChatMember(c, u, e = {}) { return this.callApi('unbanChatMember', { chat_id: c, user_id: u, ...e }); }
|
|
88
|
+
restrictChatMember(c, u, permissions, e = {}) { return this.callApi('restrictChatMember', { chat_id: c, user_id: u, permissions, ...e }); }
|
|
89
|
+
promoteChatMember(c, u, e = {}) { return this.callApi('promoteChatMember', { chat_id: c, user_id: u, ...e }); }
|
|
90
|
+
setChatAdministratorCustomTitle(c, u, t) { return this.callApi('setChatAdministratorCustomTitle', { chat_id: c, user_id: u, custom_title: t }); }
|
|
91
|
+
approveChatJoinRequest(c, u) { return this.callApi('approveChatJoinRequest', { chat_id: c, user_id: u }); }
|
|
92
|
+
declineChatJoinRequest(c, u) { return this.callApi('declineChatJoinRequest', { chat_id: c, user_id: u }); }
|
|
93
|
+
getChat(c) { return this.callApi('getChat', { chat_id: c }); }
|
|
94
|
+
getChatAdministrators(c) { return this.callApi('getChatAdministrators', { chat_id: c }); }
|
|
95
|
+
getChatMemberCount(c) { return this.callApi('getChatMemberCount', { chat_id: c }); }
|
|
96
|
+
getChatMember(c, u) { return this.callApi('getChatMember', { chat_id: c, user_id: u }); }
|
|
97
|
+
leaveChat(c) { return this.callApi('leaveChat', { chat_id: c }); }
|
|
98
|
+
setChatTitle(c, title) { return this.callApi('setChatTitle', { chat_id: c, title }); }
|
|
99
|
+
setChatDescription(c, description) { return this.callApi('setChatDescription', { chat_id: c, description }); }
|
|
100
|
+
setChatPhoto(c, photo) { return this.callApi('setChatPhoto', { chat_id: c, photo }); }
|
|
101
|
+
setChatPermissions(c, permissions, e = {}) { return this.callApi('setChatPermissions', { chat_id: c, permissions, ...e }); }
|
|
102
|
+
pinChatMessage(c, m, e = {}) { return this.callApi('pinChatMessage', { chat_id: c, message_id: m, ...e }); }
|
|
103
|
+
unpinChatMessage(c, e = {}) { return this.callApi('unpinChatMessage', { chat_id: c, ...e }); }
|
|
104
|
+
unpinAllChatMessages(c) { return this.callApi('unpinAllChatMessages', { chat_id: c }); }
|
|
105
|
+
exportChatInviteLink(c) { return this.callApi('exportChatInviteLink', { chat_id: c }); }
|
|
106
|
+
|
|
107
|
+
/* ---- konfigurasi bot ---- */
|
|
108
|
+
setMyCommands(commands, e = {}) { return this.callApi('setMyCommands', { commands, ...e }); }
|
|
109
|
+
getMyCommands(e = {}) { return this.callApi('getMyCommands', e); }
|
|
110
|
+
deleteMyCommands(e = {}) { return this.callApi('deleteMyCommands', e); }
|
|
111
|
+
setMyName(e = {}) { return this.callApi('setMyName', e); }
|
|
112
|
+
getMyName(e = {}) { return this.callApi('getMyName', e); }
|
|
113
|
+
setMyDescription(e = {}) { return this.callApi('setMyDescription', e); }
|
|
114
|
+
getMyDescription(e = {}) { return this.callApi('getMyDescription', e); }
|
|
115
|
+
setMyShortDescription(e = {}) { return this.callApi('setMyShortDescription', e); }
|
|
116
|
+
setChatMenuButton(e = {}) { return this.callApi('setChatMenuButton', e); }
|
|
117
|
+
|
|
118
|
+
/* ---- webhook ---- */
|
|
119
|
+
setWebhook(url, e = {}) { return this.callApi('setWebhook', { url, ...e }); }
|
|
120
|
+
deleteWebhook(e = {}) { return this.callApi('deleteWebhook', e); }
|
|
121
|
+
getWebhookInfo() { return this.callApi('getWebhookInfo'); }
|
|
122
|
+
|
|
123
|
+
/* ---- forum topic ---- */
|
|
124
|
+
createForumTopic(c, name, e = {}) { return this.callApi('createForumTopic', { chat_id: c, name, ...e }); }
|
|
125
|
+
closeForumTopic(c, tid) { return this.callApi('closeForumTopic', { chat_id: c, message_thread_id: tid }); }
|
|
126
|
+
|
|
127
|
+
/* ---- pembayaran & stars ---- */
|
|
128
|
+
sendInvoice(c, title, description, payload, currency, prices, e = {}) { return this.callApi('sendInvoice', { chat_id: c, title, description, payload, currency, prices, ...e }); }
|
|
129
|
+
refundStarPayment(user_id, telegram_payment_charge_id) { return this.callApi('refundStarPayment', { user_id, telegram_payment_charge_id }); }
|
|
130
|
+
getStarTransactions(e = {}) { return this.callApi('getStarTransactions', e); }
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Api = ApiBase + Proxy: metode APA PUN di Bot API bisa dipanggil
|
|
135
|
+
* api.setWebhookCustom({ url }) → callApi('setWebhookCustom', {...})
|
|
136
|
+
* Implementasi: kalau nama ada di ApiBase, pakai definisi resminya; kalau
|
|
137
|
+
* tidak, fallback jadi satu-argumen-payload.
|
|
138
|
+
*/
|
|
139
|
+
function makeApi(token, transport) {
|
|
140
|
+
const base = new ApiBase(token, transport);
|
|
141
|
+
return new Proxy(base, {
|
|
142
|
+
get(target, prop, recv) {
|
|
143
|
+
const v = Reflect.get(target, prop, recv);
|
|
144
|
+
if (v !== undefined) return typeof v === 'function' ? v.bind(target) : v;
|
|
145
|
+
if (typeof prop === 'string' && /^[a-z][a-zA-Z0-9]*$/.test(prop)) {
|
|
146
|
+
return (payload = {}) => target.callApi(prop, payload);
|
|
147
|
+
}
|
|
148
|
+
return undefined;
|
|
149
|
+
},
|
|
150
|
+
set(target, prop, value) { Reflect.set(target, prop, value); return true; },
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
module.exports = { makeApi, ApiBase };
|
package/lib/broadcast.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// lib/broadcast.js — kirim ke banyak chat dengan pacing aman rate-limit.
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* bot.broadcast(ids, pesan, opts)
|
|
8
|
+
* ids : array chat id
|
|
9
|
+
* pesan : string → { text: string }
|
|
10
|
+
* object → payload sendMessage/salinan
|
|
11
|
+
* fungsi → (chatId) => payload (personal per penerima)
|
|
12
|
+
* opts : { delay = 35 } ms antar kirim (≈28 pesan/detik, di bawah limit Telegram)
|
|
13
|
+
*
|
|
14
|
+
* Return: { terkirim, gagal, errors: [{ chatId, pesan }] }
|
|
15
|
+
*/
|
|
16
|
+
async function broadcast(api, ids, pesan, opts = {}) {
|
|
17
|
+
const delay = Number.isFinite(opts.delay) ? opts.delay : 35;
|
|
18
|
+
const failures = [];
|
|
19
|
+
let terkirim = 0;
|
|
20
|
+
|
|
21
|
+
for (const chatId of ids) {
|
|
22
|
+
let p = typeof pesan === 'function' ? await pesan(chatId) : pesan;
|
|
23
|
+
if (typeof p === 'string') p = { text: p };
|
|
24
|
+
try {
|
|
25
|
+
await api.callApi('sendMessage', { chat_id: chatId, ...p });
|
|
26
|
+
terkirim += 1;
|
|
27
|
+
} catch (err) {
|
|
28
|
+
failures.push({ chatId, pesan: (err && (err.description || err.message)) || String(err) });
|
|
29
|
+
}
|
|
30
|
+
if (delay > 0) await sleep(delay);
|
|
31
|
+
}
|
|
32
|
+
return { terkirim, gagal: failures.length, errors: failures };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = { broadcast };
|