Telegram'da Etkileşimli Arayüz Oluşturma

Kerem Aydın·10 Temmuz 2026·⏱4 dk

Telegram mesajına veya bota buton eklemek için, mesaj gönderirken reply_markup parametresini kullanmanız gerekir. İki ana klavye türü vardır: Inline (navigasyon ve eylemler için mesajın altındaki butonlar) ve Reply (veri girişi için kullanıcının standart klavyesinin yerine geçen). Seçim göreve bağlıdır: Inline menüler ve geçişler için uygundur, Reply ise hızlı yanıt girişi içindir.

Temel fark: Inline butonlar metni sohbete göndermez, bunun yerine verileri bota "sessizce" (callback) iletir; oysa Reply butonları metni normal bir mesaj gibi giriş alanına yerleştirir.

Klavye türleri ve kullanım senaryoları

Buton türleri arasındaki farkları anlamak, iyi bir kullanıcı deneyimi (UX) oluşturmak için kritiktir.

Inline Keyboard (Satır İçi Klavye)

Butonlar bot mesajının hemen altında görüntülenir. Kullanıcının metin giriş alanında yer kaplamazlar.

  • Amaç: Menüde gezinme, seçenek seçme, bağlantılara geçiş, eylemleri onaylama.
  • Özellik: Tıklandığında bot callback_data alır, ancak kullanıcıdan sohbete herhangi bir mesaj gitmez (aksi programlanmadıkça).
  • Nerede kullanılır: Ana menü, ayarlar, ödeme, web sitesi bağlantıları.

Reply Keyboard (Yanıt Klavyesi)

Kullanıcının akıllı telefonunun veya bilgisayarının standart klavyesinin yerine geçen geçici veya kalıcı bir panel.

  • Amaç: Metin girişini kolaylaştırma, önceden tanımlanmış seçeneklerden seçim yapma, hızlı komutlar.
  • Özellik: Tıklandığında buton metni, kullanıcıdan gelen normal bir mesaj olarak sohbete gönderilir.
  • Nerede kullanılır: Şehir seçimi, ürün kategorisi girişi, destekte hızlı yanıtlar ("Evet", "Hayır", "Operatöre bağlan").

Python ile Uygulama (aiogram 3.x kütüphanesi)

aiogram kütüphanesi, Python'da bot geliştirmek için standarttır. Aşağıda 3.x sürümü için güncel örnekler verilmiştir.

Inline butonları oluşturma

InlineKeyboardMarkup ve InlineKeyboardButton kullanıyoruz.

from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder

def get_main_keyboard():
    builder = InlineKeyboardBuilder()
    
    # Bağlantılı buton
    builder.button(text="🌐 Web sitemiz", url="https://example.com")
    
    # Geri çağrı (callback) içeren buton
    builder.button(text="💰 Fiyatı öğren", callback_data="get_price")
    
    # Izgara ayarı: satır başına 1 buton
    builder.adjust(1)
    
    return builder.as_markup()

# İşleyicide kullanım
# await message.answer("Bir eylem seçin:", reply_markup=get_main_keyboard())

Reply klavyesi oluşturma

ReplyKeyboardMarkup kullanıyoruz. Klavyenin ekranın yarısını kaplamaması için resize_keyboard=True parametresini ayarlamak önemlidir.

from aiogram.types import ReplyKeyboardMarkup, KeyboardButton
from aiogram.utils.keyboard import ReplyKeyboardBuilder

def get_contact_keyboard():
    builder = ReplyKeyboardBuilder()
    
    builder.button(text="📍 Konumum", request_location=True)
    builder.button(text="📞 Kişiyi paylaş", request_contact=True)
    builder.button(text="❌ İptal")
    
    # Ayar: ilk satırda 2 buton, ikincisinde 1
    builder.adjust(2, 1)
    
    return builder.as_markup(resize_keyboard=True, one_time_keyboard=True)

one_time_keyboard=True parametresi, klavyeyi ilk tıklamadan hemen sonra gizler. Bu, arayüzü kalabalıklaştırmamak için tek seferlik seçimlerde (örneğin dil seçimi) kullanışlıdır.

Node.js ile Uygulama (Telegraf kütüphanesi)

JavaScript/TypeScript geliştiricileri için telegraf kütüphanesi kullanışlı bir sözdizimi sağlar.

Inline klavye örneği

const { Markup } = require('telegraf');

bot.start((ctx) => {
  ctx.reply('Hoş geldiniz! Bir seçenek seçin:', 
    Markup.inlineKeyboard([
      Markup.button.url('🔗 Web Sitesi', 'https://example.com'),
      Markup.button.callback('⚙️ Ayarlar', 'btn_settings')
    ]).extra()
  );
});

// Tıklamayı işleme
bot.action('btn_settings', (ctx) => {
  ctx.editMessageText('Ayarlar açılıyor...');
  ctx.answerCbQuery(); // Sorguyu mutlaka onaylayın
});

Reply klavye örneği

bot.command('menu', (ctx) => {
  ctx.reply('Size nasıl yardımcı olabilirim?', 
    Markup.keyboard([
      ['🍕 Pizza', '🍔 Burgerler'],
      ['🥤 İçecekler'],
      Markup.button.contactRequest('📞 Bizi arayın')
    ])
    .oneTime()
    .resize()
    .extra()
  );
});

Tıklamaları işleme ve çalışma mantığı

Sadece butonları göstermek yeterli değildir; kullanıcının tepkisini işlemek gerekir.

  1. Callback işleme (Inline için): Kullanıcı bir Inline butona tıkladığında, bot callback_query türünde bir güncelleme alır.

    • Önemli: Her zaman geri çağrı yanıtı yöntemini çağırın (aiogram'da answer_callback_query veya telegraf'ta answerCbQuery). Bunu yapmazsanız, kullanıcının ekranında yükleme göstergesi sonsuza kadar döner.
    • Limitler: callback_data alanı 64 bayt ile sınırlıdır. Buraya büyük nesneler veya uzun metinler göndermeyin. Benzersiz ID'ler kullanın ve verileri bu ID'ye göre veritabanından yükleyin.
  2. Metin işleme (Reply için): Reply butonuna tıklamak, kullanıcının metni manuel olarak yazıp mesaj göndermesine eşdeğerdir. Bu tür mesajları normal metin filtreleri veya tam dize eşleşmesi yoluyla işleyin.

Veri güvenliği: Hassas verileri (token'lar, şifreler, kişisel bilgiler) asla callback_data parametresinde göndermeyin. Bu veriler ele geçirilebilir veya ara sunucuların günlüklerinde saklanabilir.

Uygulama yöntemlerinin karşılaştırılması

ÖzellikInline KlavyeReply Klavye
KonumBot mesajının altındaKullanıcının giriş alanında
Mesaj görünürlüğüHayır (sessiz tıklama)Evet (metin sohbete gider)
Bağlantı desteğiEvet (url)Hayır
Kişi/konum isteğiHayırEvet (requestcontact, requestlocation)
En iyi kullanımMenüler, navigasyon, eylemlerVeri girişi, hızlı yanıtlar
KaldırmaMesajı düzenleyerek gizlenebilirKendiliğinden kaybolur veya /start komutuyla

Geliştiricilerin sık yaptığı hatalar

  • "Takılı kalan" yükleyici: Kullanıcı butona tıkladı ancak görsel olarak hiçbir şey olmadı. Sebep: answer_callback_query onayını göndermeyi unuttunuz.
  • Arayüzün aşırı yüklenmesi: Tek bir mesaja 20 buton sığdırma girişimi. Telegram'ın satır başına buton sayısı ve toplam buton sayısı için limitleri vardır. Optimal olanı satır başına 2–4 butondur.
  • Uzun etiketler: Buton üzerindeki metin çok uzunsa kesilir. Düşünceleri kısa ifade edin (1–3 kelimeye kadar).
  • Çıkış yolunun olmaması: Butonlardan oluşan bir menü oluştururken, kullanıcıyı çıkmaza sokacak şekilde "Geri" veya "Ana Menü" butonu eklemeyi unutmak.

SSS

Zaten gönderilmiş bir mesajdaki butonlar dinamik olarak değiştirilebilir mi? Evet. Inline klavyeler için mesaj düzenleme yöntemini (editMessageReplyMarkup) kullanın. Mesaj metnini değiştirmeden buton setini tamamen değiştirebilirsiniz. Reply klavyeler için bu mümkün değildir; yeni bir mesaj göndermeniz gerekir.

Seçim yaptıktan sonra klavye nasıl kaldırılır?

  • Inline: Boş bir işaretlemeye sahip mesaj düzenlemesi gönderin veya sonraki adımlarda onu yok sayın.
  • Reply: Parametresi remove_keyboard=true olan özel bir klavye ile yeni bir mesaj gönderin (aiogram'da: ReplyKeyboardRemove()).

Buton sayısı için bir limit var mı? Evet. Bir satırda en fazla 8 buton olabilir (bazı istemcilerde daha az), klavyede toplamda ise 100 butona kadar çıkılabilir. Ancak kullanıcı kolaylığı için ekranda 5–6 butonu aşmamanız önerilir.