Yapay zeka ile Telegram botu yapmak için bir kodlama ajanına (Claude Code, Codex ya da benzeri) python-telegram-bot ile çalışan bir bot yazdırman, token’ı .env dosyasına koyman ve botu önce kendi bilgisayarında polling ile çalıştırman yeterli. Sonrası adım adım: komutlar, durum saklama, bir LLM ile akıllı yanıtlar ve botu sunucuda 7/24 çalıştırmak.
Bu yazıda Telegram üzerinden ilerliyorum, sonda da aynı botu Discord’a nasıl uyarlayacağını anlatıyorum. Her adımda ajana verebileceğin hazır istemler var.
Ne yapacağız?
Örnek bot şunları yapacak:
/startve/helpkomutlarına cevap verir./not <metin>ile not kaydeder,/notlarile listeler (durum saklama).- Düz mesajlara bir LLM ile yanıt verir; kullanıcı başına günlük sınırı vardır.
- Yalnızca izin verdiğin kullanıcılarla konuşabilir (isteğe bağlı).
- Bir sunucuda systemd ya da Docker ile sürekli çalışır.
Bu, vibe coding ile başlamak için iyi bir proje: küçük, sonucu hemen telefonunda görüyorsun ve gerçek bir işe yarıyor.
Yığın seçimi: Python mu, TypeScript mi?
İki iyi seçenek var:
- Python + python-telegram-bot: Olgun, belgeleri bol, async yapıda. Yapay zeka, veri ya da otomasyon tarafın Python’daysa doğal seçim.
- TypeScript + grammY: Modern, tipli ve hafif. Webhook ile sunucusuz platformlarda da rahat çalışır. Zaten Node.js kullanıyorsan buradan git.
Bu yazıda Python’la ilerliyorum; istemlerdeki kütüphane adını değiştirirsen aynı adımlar grammY için de geçerli.
Kurulum:
mkdir telegram-bot && cd telegram-bot
git init
python3 -m venv .venv && source .venv/bin/activate
pip install python-telegram-bot python-dotenv anthropic
printf ".env\n.venv/\n*.db\n" >> .gitignore
LLM için Anthropic SDK’sını örnek aldım; başka bir sağlayıcı kullanacaksan paketi onunla değiştir, mantık aynı.
Adım 1: token al ve .env’e koy
Telegram’ın resmi bot oluşturma akışından token al: Telegram içinde yeni bir bot oluşturursun, bir görünen ad ve “bot” ile biten benzersiz bir kullanıcı adı seçersin, sonunda sana uzun bir token verilir. Bu token botun parolasıdır; ona sahip olan herkes botun adına mesaj gönderebilir.
.env dosyası:
TELEGRAM_TOKEN=buraya-token
LLM_API_KEY=buraya-api-anahtari
LLM_MODEL=kullanacagin-model-adi
ALLOWED_USER_IDS=123456789
DAILY_LLM_LIMIT=30
Token’ı ve API anahtarını ajanla konuşurken sohbete yapıştırma. Ajanın bu değerleri bilmesine gerek yok; .env’den okunacaklarını bilmesi yeterli. Token yanlışlıkla bir yere sızarsa aynı resmi akıştan iptal edip yenisini al.
Adım 2: ajana ilk istemi ver
Proje klasöründe ajanı aç ve önce en basit çalışan botu iste:
python-telegram-bot (async, ApplicationBuilder) ile basit bir Telegram botu kur.
- Token'ı .env'den python-dotenv ile oku. .env dosyasını açma, içeriğini yazdırma.
- Yapı: bot.py (başlatma ve handler kaydı), handlers.py (komutlar),
storage.py (ileride SQLite), config.py.
- /start ve /help komutları olsun, /help tüm komutları listelesin.
- Bilinmeyen komutlara kibar bir yanıt ver.
- Polling ile çalışsın. Python logging kullan; token'ı asla loglama.
- Hata işleyici ekle: hatayı logla, kullanıcıya kısa bir özür mesajı gönder.
Bitirince nasıl çalıştıracağımı yaz.
Çalıştır:
python bot.py
Telegram’da botunu bul, /start yaz. Cevap geliyorsa ilk döngü tamam. Gelmiyorsa terminaldeki hatayı aynen ajana ver; çoğu zaman sorun yanlış okunan bir ortam değişkenidir.
Adım 3: komutlar ve durum saklama
Botların çoğu bir şeyler hatırlamak zorunda: kullanıcı ayarları, notlar, kullanım sayaçları. Bellekte tutulan veri bot yeniden başlayınca kaybolur. Küçük bir bot için SQLite yeterli; ayrı bir veritabanı sunucusu gerekmez.
storage.py'ye SQLite ekle (data/bot.db).
- notes tablosu: id, user_id, text, created_at.
- usage tablosu: user_id, date, llm_count.
- /not <metin> notu kaydetsin, /notlar kullanıcının son 10 notunu listelesin,
/sil <id> yalnızca kullanıcının kendi notunu silsin.
- Tüm SQL'ler parametreli olsun (string birleştirme yok).
- pytest ile storage fonksiyonlarına testler yaz ve çalıştır.
“Yalnızca kendi notunu silsin” cümlesi önemli. Ajanlar bu tür yetki kontrollerini sık atlıyor; /sil 5 yazan herkes başkasının notunu silebilir hale geliyor.
python-telegram-bot’un kendi PicklePersistence gibi kalıcılık seçenekleri de var; konuşma durumu (çok adımlı formlar gibi) için işe yarar. Ama kullanıcı verisi için SQLite’ı daha şeffaf buluyorum.
Adım 4: LLM ile akıllı yanıtlar
Şimdi botu “yapay zekalı” yapan kısım: düz mesajları bir LLM’e gönderip yanıtı geri yazmak.
# llm.py
import os
from anthropic import AsyncAnthropic
client = AsyncAnthropic(api_key=os.getenv("LLM_API_KEY"))
async def reply(history: list[dict]) -> str:
resp = await client.messages.create(
model=os.getenv("LLM_MODEL"),
max_tokens=500,
system="Kısa ve net cevap veren yardımsever bir Telegram asistanısın.",
messages=history[-10:], # yalnızca son 10 mesaj
)
return resp.content[0].text
Ajana verebileceğin istem:
Düz metin mesajlarını llm.py'deki reply fonksiyonuna gönder.
- Her kullanıcı için son 10 mesajı bellekte tut (user/assistant sırasıyla).
- /sifirla konuşma geçmişini temizlesin.
- Kullanıcı başına günlük DAILY_LLM_LIMIT sınırı uygula (usage tablosu);
sınır dolunca açıklayıcı bir mesaj gönder.
- ALLOWED_USER_IDS boş değilse yalnızca o kullanıcılara yanıt ver.
- LLM çağrısı sürerken "yazıyor..." eylemini gönder.
- Telegram mesaj uzunluk sınırını aşan yanıtları parçalara böl.
- API hatasında kullanıcıya kısa bir mesaj ver, hatayı logla.
Neden sınırlar? Herkese açık bir LLM botu, biri onu keşfedip binlerce mesaj attığında faturanı şişirir. Günlük sınır, izinli kullanıcı listesi ve kısa geçmiş, maliyeti kontrol altında tutmanın en basit üç yolu. Geçmiş ne kadar uzunsa her istekte o kadar çok token gönderirsin.
Nasıl test edip yinelersin?
Her özellikten sonra aynı döngüyü uygula: ajana tek bir değişiklik yaptır, botu yeniden başlat, Telegram’da dene, sorun varsa terminaldeki hatayı ve botun verdiği yanıtı aynen ajana geri ver. Birkaç el testi her seferinde tekrarla:
- Yetkisiz bir hesaptan (ya da bir arkadaşının telefonundan) mesaj at; bot yanıt vermemeli.
- Günlük sınırı test etmek için
DAILY_LLM_LIMIT=2yapıp üç mesaj gönder. - Botu mesajlaşmanın ortasında durdurup başlat; notlar yerinde durmalı.
Çalışan her adımı küçük bir commit ile kaydet. Ajan bir sonraki adımda bir şeyi bozarsa git diff ile neyin değiştiğini görür, gerekirse geri dönersin.
Adım 5: polling mi webhook mu?
Bot Telegram’dan mesajları iki yolla alabilir:
- Polling (long polling): Bot düzenli olarak Telegram’a “yeni mesaj var mı?” diye sorar. Kurulumu sıfır: HTTPS adresi, alan adı ya da açık port gerekmez. Geliştirme için ve tek sunucuda çalışan küçük-orta botlar için ideal.
- Webhook: Telegram her yeni mesajı senin verdiğin HTTPS adresine gönderir. Boşta beklemez, sunucusuz platformlarda (istek başına çalışan fonksiyonlar) tek seçenek budur. Karşılığında geçerli sertifikalı bir HTTPS adresi ve gizli bir yol ya da secret token ile isteklerin gerçekten Telegram’dan geldiğini doğrulaman gerekir.
Benim kuralım: polling ile başla, gerçekten ihtiyaç duyduğunda webhook’a geç. Aynı token için ikisini aynı anda çalıştıramazsın; webhook ayarlıyken polling çalışmaz.
Adım 6: sunucuda 7/24 çalıştırmak
Bilgisayarın kapanınca bot da susar. Küçük bir Linux VPS yeter; polling kullandığın için alan adı bile gerekmez.
systemd
# /etc/systemd/system/telegram-bot.service
[Unit]
Description=Telegram bot
After=network-online.target
[Service]
User=bot
WorkingDirectory=/home/bot/telegram-bot
EnvironmentFile=/home/bot/telegram-bot/.env
ExecStart=/home/bot/telegram-bot/.venv/bin/python bot.py
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now telegram-bot
journalctl -u telegram-bot -f
Docker
Ajana bir Dockerfile ve docker-compose.yml yazdır: restart: unless-stopped, env_file: .env ve data/ klasörü için bir volume. Volume’u unutursan konteyner her yenilendiğinde SQLite veritabanı da silinir.
Aynı botu iki yerde (örneğin hem bilgisayarında hem sunucuda) polling ile çalıştırma; Telegram bunu çakışma hatasıyla reddeder. Geliştirme için ayrı bir test botu ve ayrı bir token kullan.
Adım 7: Discord’a uyarlamak
Discord botları kavram olarak benzer, ama birkaç önemli fark var:
- Token ve uygulama: Discord’un geliştirici portalında bir uygulama oluşturur, ona bot eklersin ve token’ı oradan alırsın. Botu sunucuna bir davet bağlantısıyla, ihtiyacı olan en az izinle eklersin.
- Intent’ler: Mesaj içeriğini okumak için “message content” intent’ini hem portalda hem kodda açman gerekir. Bot mesajları görmüyorsa sorun neredeyse her zaman budur.
- Bağlantı modeli: Discord botları bir gateway’e sürekli WebSocket bağlantısı kurar. Bu yüzden bot uzun süre çalışan bir süreç olmalı; sunucusuz bir fonksiyonda çalışmaz.
- Komutlar: Modern yol eğik çizgi (slash) komutları. Bunları Discord’a kaydetmen gerekir.
- Kütüphaneler: Python için discord.py, Node.js için discord.js.
En temiz yol, bot mantığını platformdan ayırmak. İstem:
Bot mantığını platformdan ayır:
- core/ altında platformdan bağımsız fonksiyonlar: handle_note, list_notes,
ask_llm. Bunlar user_id ve metin alır, metin döndürür.
- telegram_bot.py mevcut handler'ları core/'u çağıracak şekilde yeniden yazsın.
- discord_bot.py: discord.py ile /not, /notlar ve /sor slash komutları;
hepsi core/'u çağırsın. DISCORD_TOKEN .env'den gelsin.
- Discord user_id'lerini Telegram'dakilerle karıştırmamak için storage'da
platform sütunu ekle.
- Mevcut testler bozulmasın; core için testleri genişlet.
Böylece iki bot aynı veritabanını ve aynı LLM mantığını paylaşır, her biri yalnızca kendi platformunun ayrıntılarıyla uğraşır.
Yaygın hatalar: yapay zekanın sık yanlış yaptığı şeyler
- Eski API’ye göre kod yazmak. python-telegram-bot sürüm 20 ile async yapıya geçti; ajanlar bazen eski senkron örnekleri karıştırır. Hata alırsan ajana kurulu sürümü kontrol ettir (
pip show python-telegram-bot) ve o sürümün belgelerine göre düzelttir. - Token’ı koda gömmek. Ajan “hızlıca denemek için” token’ı
bot.py’ye yazmak isteyebilir. Kabul etme. - Yetki kontrolünü unutmak. Yönetici komutları herkese açık kalır, kullanıcılar birbirinin verisine erişir.
- Engelleyen kod. Async bir handler içinde
time.sleepya da senkron bir HTTP isteği tüm botu dondurur. - Hataları yutmak. Hata işleyici yoksa bot sessizce cevap vermeyi bırakır.
- Durumu bellekte tutmak. Yeniden başlatmada her şey sıfırlanır.
- Uzun mesajları bölmemek. LLM uzun bir yanıt verdiğinde Telegram mesajı reddeder.
Güvenlik
- Token’lar ve API anahtarları yalnızca
.env’de;.env.gitignore’da. - Anahtarları sohbete, ekran görüntüsüne ya da hata raporuna yapıştırma.
- Ajanın çalıştırmak istediği komutları onaylamadan önce oku;
.env’i okuyan ya da dışarıya veri gönderen komutlara özellikle dikkat et. - Botun kullanıcılardan aldığı metni LLM’e gönderirken, bu metnin sistem talimatlarını değiştirmeye çalışabileceğini (prompt injection) hesaba kat. Bota tehlikeli yetkiler (komut çalıştırma, dosya silme) verme.
- Kullanıcı verisini sakladığını ve LLM sağlayıcısına gönderdiğini kullanıcılarına söyle.
- Sunucuda botu root olarak çalıştırma;
.enviçinchmod 600.
Bunu AgentVera ile yapmak
Bu projede iki işi paralel yürütmek doğal: bir ajan Telegram tarafını, diğeri Discord tarafını yazar. AgentVera’da Claude Code’u bir worktree’de, Codex’i başka bir worktree’de aynı ızgarada çalıştırabilirsin. Her tur sonunda otomatik kod incelemesi yetki kontrolü gibi kaçırılması kolay yerlere ikinci bir model gözüyle bakar. Değişiklikleri birleştirmeden önce Git paneli’nde incelersin, LLM özelliğini geliştirirken ajanların token kullanımını da görürsün. Sunucuya geçerken SSH ve SFTP ile dosyaları taşıyabilir, yerelde Docker yöneticisi ile konteynerin loglarını izleyebilirsin.
Hiçbiri şart değil; bir terminal ve git ile de bu botu bitirirsin. Botuna yapacak iş arıyorsan yapay zeka ile kripto botu yapmak yazısındaki Telegram uyarıları iyi bir örnek.
Sonuç
Yapay zeka ile Telegram botu yapmak, vibe coding’e başlamak için en keyifli projelerden biri. Token’ı resmi akıştan al ve .env’e koy, ajana önce en basit botu yazdır, sonra katman katman komut, SQLite ile durum ve LLM yanıtı ekle. Polling ile başla, sunucuda systemd ya da Docker ile çalıştır, mantığı platformdan ayırırsan Discord’a geçiş de kolaylaşır. Ajanın yazdığı yetki kontrollerini ve çalıştırdığı komutları kendin oku; gerisini ajan halleder.