Skip to content

Keyboard & Markup

VibeGram menyediakan builder keyboard yang komprehensif melalui kelas Markup untuk membuat keyboard inline dan reply keyboard.

Inline Keyboard

Keyboard yang muncul di bawah pesan (bukan di keyboard native):

typescript
import { Markup } from 'vibegram';

await ctx.reply('Pilih opsi:', {
    reply_markup: Markup.inlineKeyboard([
        [
            Markup.button.callback('✅ Setuju', 'setuju'),
            Markup.button.callback('❌ Tolak', 'tolak'),
        ],
        [Markup.button.url('🌐 Website', 'https://alfandi09.github.io/vibegram/')],
    ]),
});

Markup.grid() — Grid Otomatis

Buat grid keyboard dari array flat — tidak perlu menyusun baris manual:

typescript
const hari = ['Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab', 'Min'];

await ctx.reply('Pilih hari:', {
    reply_markup: Markup.grid(
        hari.map(d => Markup.button.callback(d, `hari_${d.toLowerCase()}`)),
        3 // 3 tombol per baris
    ),
});

// Menghasilkan:
// [Sen] [Sel] [Rab]
// [Kam] [Jum] [Sab]
// [Min]

Tipe Tombol Inline

FactoryDeskripsi
Markup.button.callback(text, data)Tombol callback — memicu bot.action()
Markup.button.url(text, url)Tautan URL eksternal
Markup.button.webApp(text, url)Buka Telegram Mini App
Markup.button.pay(text)Tombol pembayaran Telegram Stars
Markup.button.switchInlineQuery(text, query)Buka inline mode
Markup.button.switchInlineQueryCurrentChat(text, query)Inline mode di chat saat ini
Markup.button.login(text, loginUrl)Tombol Login Telegram (OAuth)
Markup.button.copy(text, textToCopy)Salin teks ke clipboard (API 9.6)

Contoh: Login Button

typescript
await ctx.reply('Login ke aplikasi kami:', {
    reply_markup: Markup.inlineKeyboard([
        [
            Markup.button.login('🔑 Login dengan Telegram', {
                url: 'https://auth.contoh.com/telegram',
                request_write_access: true,
            }),
        ],
    ]),
});

Contoh: Copy Button

typescript
await ctx.reply('Kode referral Anda:', {
    reply_markup: Markup.inlineKeyboard([[Markup.button.copy('📋 Salin Kode', 'REF-ABCD1234')]]),
});

Paginasi

Buat keyboard yang bisa di-navigate halaman demi halaman:

typescript
const produk = Array.from({ length: 50 }, (_, i) => ({
    text: `Produk ${i + 1}`,
    callback_data: `produk_${i + 1}`,
}));

await ctx.reply('Daftar produk:', {
    reply_markup: Markup.pagination(produk, {
        currentPage: 1,
        itemsPerPage: 6,
        actionNext: 'hal_berikut',
        actionPrev: 'hal_sebelum',
        columns: 2,
        pageIndicatorPattern: 'Hal {current}/{total}',
    })
});

// Handler navigasi
bot.action('hal_berikut', async ctx => {
    const halaman = getCurrentPage(ctx) + 1;
    await ctx.editMessageReplyMarkup(
        Markup.pagination(produk, { currentPage: halaman, ... })
    );
});

Reply Keyboard

Keyboard yang menggantikan keyboard native di bawah layar:

typescript
await ctx.reply('Pilih menu:', {
    reply_markup: Markup.keyboard(
        [
            [Markup.replyButton.text('📦 Produk'), Markup.replyButton.text('🛒 Keranjang')],
            [Markup.replyButton.text('👤 Profil'), Markup.replyButton.text('📞 Bantuan')],
        ],
        {
            resize_keyboard: true,
            input_field_placeholder: 'Pilih menu...',
        }
    ),
});

Tombol Reply Khusus

typescript
// Minta nomor telepon
Markup.replyButton.requestContact('📱 Bagikan Kontak');

// Minta lokasi GPS
Markup.replyButton.requestLocation('📍 Bagikan Lokasi');

// Minta buat polling
Markup.replyButton.requestPoll('📊 Buat Poll', 'regular');

Hapus Keyboard

typescript
await ctx.reply('Keyboard dihapus.', {
    reply_markup: Markup.removeKeyboard(),
});

Force Reply

Paksa pengguna untuk membalas pesan bot:

typescript
await ctx.reply('Masukkan nama Anda:', {
    reply_markup: Markup.forceReply({
        input_field_placeholder: 'Ketik nama...',
    }),
});

Released under the ISC License.