💬Mesajlaşma Kanalları Entegrasyonu — WhatsApp, Telegram, SMS
- M.1 Onaylı Mesajlaşma Connector Kataloğu
- M.2 WhatsApp Business — Meta Cloud API ile Ajan
- M.3 WhatsApp — Twilio Sandbox ile Hızlı PoC
- M.4 Telegram Bot Entegrasyonu
- M.5 SMS Kanalı (Twilio / Netgsm / Iletimerkezi)
- M.6 KVKK Uyumu — Açık Rıza & DPIA Şablonu
- M.7 Webhook Güvenliği & Lakera Guard
- M.8 Mesaj Geçmişi & Long-term Memory (Qdrant)
- M.9 Maliyet Tahmini & Kota Yönetimi
Komtaş AI ajanlarını kurumsal mesajlaşma kanallarıyla (WhatsApp Business, Telegram, SMS) entegre etmek isteyen geliştiriciler için uçtan uca rehber. Bu sayfa, ajan tasarım desenleri (s2), MCP protokolü (s3) ve n8n otomasyon (s9) bölümlerini, kullanıcıyla doğrudan iletişim kuran kanallarla birleştirir.
M.1 Onaylı Mesajlaşma Connector Kataloğu
| Kanal | Sağlayıcı | KVKK Durumu | Lisans / Maliyet | Kurumsal Sahibi | Onay Statüsü |
|---|---|---|---|---|---|
| WhatsApp Business | Meta Cloud API | DPIA + Açık Rıza zorunlu | İlk 1.000 konuşma/ay ücretsiz; sonra TR template ücreti | İletişim Müdürlüğü | ✅ Onaylı (DPIA ile) |
| WhatsApp Business | Twilio | DPA + DPIA gerekli (US-EU SCC) | Mesaj başına ücret + Twilio aylık ücret | İletişim Müdürlüğü | ⚠️ Yalnızca PoC |
| Telegram Bot | Telegram Bot API | Açık rıza zorunlu; Telegram veri saklama Avrupa dışı | Ücretsiz | — | ⚠️ İç kullanım pilot |
| SMS | Twilio | DPA imzalı; SCC kapsamında | Mesaj başına ücret (TR yüksek) | İletişim Müdürlüğü | ✅ Onaylı |
| SMS | Netgsm / İletimerkezi | Yerel sağlayıcı; KVKK kapsamı net | Mesaj başına ücret (TR düşük) | İletişim Müdürlüğü | ✅ Onaylı (Tercih edilen) |
| Microsoft Teams | Graph API + Bot Framework | M365 kiracısı içinde; KVKK kapsamı M365 DPA ile | M365 lisansı içinde | BT Müdürlüğü | ✅ Onaylı |
| Slack | Slack Web API + Events API | Salesforce DPA + SCC | Slack iş paketi | BT Müdürlüğü | ✅ Onaylı (sınırlı kanal) |
| Discord | Discord Bot API | — | — | — | ❌ Yasak (kurumsal kanal değil) |
- Müşteri ile dış iletişim, yüksek hacim → WhatsApp Business + Meta Cloud API
- Müşteri PoC, hızlı doğrulama → WhatsApp Business + Twilio Sandbox
- İç ekip otomasyonu → Microsoft Teams (M365 DPA içinde)
- OTP / kritik bildirim → SMS (Netgsm)
- Topluluk / iç pilot → Telegram (yalnızca dahili veri sınıfı)
M.2 WhatsApp Business — Meta Cloud API ile Ajan
Önkoşullar: Meta Business Manager hesabı, WhatsApp Business Account (WABA), doğrulanmış telefon numarası, onaylı message template'leri.
Mimari Akış
FastAPI Webhook Receiver
import os, hmac, hashlib, httpx
from fastapi import FastAPI, Request, Header, HTTPException
from anthropic import AsyncAnthropic
app = FastAPI()
META_VERIFY_TOKEN = os.environ["META_VERIFY_TOKEN"]
META_APP_SECRET = os.environ["META_APP_SECRET"]
WHATSAPP_TOKEN = os.environ["WHATSAPP_ACCESS_TOKEN"]
PHONE_NUMBER_ID = os.environ["WHATSAPP_PHONE_NUMBER_ID"]
LAKERA_API_KEY = os.environ["LAKERA_API_KEY"]
claude = AsyncAnthropic()
# 1) Webhook doğrulama (Meta GET handshake)
@app.get("/webhooks/whatsapp")
async def verify(hub_mode: str, hub_challenge: str, hub_verify_token: str):
if hub_verify_token == META_VERIFY_TOKEN:
return int(hub_challenge)
raise HTTPException(403)
# 2) Mesaj alıcı (POST)
@app.post("/webhooks/whatsapp")
async def receive(request: Request, x_hub_signature_256: str = Header(None)):
body = await request.body()
# HMAC SHA-256 doğrulama (kritik güvenlik)
expected = "sha256=" + hmac.new(
META_APP_SECRET.encode(), body, hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected, x_hub_signature_256 or ""):
raise HTTPException(401, "Geçersiz imza")
payload = await request.json()
for entry in payload.get("entry", []):
for change in entry.get("changes", []):
for msg in change.get("value", {}).get("messages", []):
sender = msg["from"]
text = msg.get("text", {}).get("body", "")
await handle_message(sender, text)
return {"status": "ok"}
async def handle_message(sender: str, text: str):
# 1. Açık rıza kontrolü (Veritabanından)
if not await consent_check(sender):
await send_template(sender, "consent_request")
return
# 2. Lakera Guard (prompt injection / PII)
async with httpx.AsyncClient() as h:
guard = await h.post(
"https://api.lakera.ai/v2/guard",
headers={"Authorization": f"Bearer {LAKERA_API_KEY}"},
json={"messages": [{"role": "user", "content": text}]},
)
if guard.json().get("flagged"):
await send_text(sender, "Mesajınız politika gereği işlenemedi.")
return
# 3. Claude'a gönder (tool-use destekli)
response = await claude.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system="Sen Komtaş müşteri destek ajanısın. KVKK kapsamı dışında veri isteme.",
messages=[{"role": "user", "content": text}],
)
reply = response.content[0].text
await send_text(sender, reply)
# 3) WhatsApp'a cevap gönder
async def send_text(to: str, body: str):
async with httpx.AsyncClient() as h:
await h.post(
f"https://graph.facebook.com/v20.0/{PHONE_NUMBER_ID}/messages",
headers={"Authorization": f"Bearer {WHATSAPP_TOKEN}"},
json={"messaging_product": "whatsapp", "to": to,
"type": "text", "text": {"body": body}},
)
M.3 WhatsApp — Twilio Sandbox ile Hızlı PoC
Üretim öncesi PoC için Twilio Sandbox 1-2 günde çalışan bir prototip kurmanızı sağlar. Kullanıcılar bir kez "join <keyword>" mesajı atarak sandbox'a katılır.
# Twilio + Claude — minimal sandbox örneği
from twilio.rest import Client
from twilio.twiml.messaging_response import MessagingResponse
from fastapi import FastAPI, Form
from anthropic import Anthropic
twilio = Client(os.environ["TWILIO_SID"], os.environ["TWILIO_TOKEN"])
claude = Anthropic()
app = FastAPI()
@app.post("/whatsapp/twilio")
async def webhook(From: str = Form(...), Body: str = Form(...)):
response = claude.messages.create(
model="claude-haiku-4-5-20251001", # PoC için hızlı + ucuz
max_tokens=512,
system="Komtaş PoC asistanı. Maksimum 3 cümle cevap ver.",
messages=[{"role": "user", "content": Body}],
)
reply = response.content[0].text
twiml = MessagingResponse()
twiml.message(reply)
return Response(content=str(twiml), media_type="application/xml")
M.4 Telegram Bot Entegrasyonu
Telegram, dahili pilot ve dev/test senaryoları için en hızlı kanaldır. Müşteri verisi Telegram üzerinden işlenmemelidir (sağlayıcı veri saklama bölgesi belirsiz).
# python-telegram-bot v21+ (async)
from telegram import Update
from telegram.ext import Application, MessageHandler, filters, ContextTypes
from anthropic import AsyncAnthropic
claude = AsyncAnthropic()
app = Application.builder().token(os.environ["TELEGRAM_BOT_TOKEN"]).build()
async def on_message(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
text = update.message.text
user_id = update.effective_user.id
response = await claude.messages.create(
model="claude-sonnet-4-6",
max_tokens=800,
system="Komtaş dahili Telegram asistanı.",
messages=[{"role": "user", "content": text}],
)
await update.message.reply_text(response.content[0].text)
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, on_message))
app.run_polling()
M.5 SMS Kanalı (Twilio / Netgsm)
SMS, OTP ve kritik bildirimler için kullanılır. Sohbet için uygun değildir (uzun bekleme süreleri, yanıt akışı zor).
# Netgsm REST API ile tek yönlü SMS gönderimi
import httpx
async def send_sms_netgsm(to: str, body: str, header: str = "KOMTAS"):
payload = {
"usercode": os.environ["NETGSM_USER"],
"password": os.environ["NETGSM_PASS"],
"msgheader": header,
"gsmno": to,
"message": body,
"filter": "0",
}
async with httpx.AsyncClient() as h:
r = await h.post("https://api.netgsm.com.tr/sms/send/get", params=payload)
return r.text # "00 jobID" başarı, diğer kodlar hata
M.6 KVKK Uyumu — Açık Rıza & DPIA Şablonu
DPIA Mini-Şablon (Ajan başına doldurulur)
| # | Soru | Örnek Cevap |
|---|---|---|
| 1 | Hangi kişisel veri işlenecek? | Telefon, mesaj içeriği, ad-soyad (kullanıcı verirse) |
| 2 | Veri toplama yöntemi? | WhatsApp inbound mesaj |
| 3 | Hukuki dayanak? | Açık rıza (m.5/1) + Sözleşme ifası (m.5/2-c) |
| 4 | Yurt dışı aktarım var mı? | Evet — Meta (US/IE), Anthropic (US) |
| 5 | Saklama süresi? | Konuşma sonrası 30 gün; özet 1 yıl |
| 6 | İlgili kişi hakları nasıl kullanılır? | kvkk@komtas.com.tr; otomatik silme komutu "/sil" |
| 7 | Veri minimizasyonu uygulanıyor mu? | PII otomatik maskeleme aktif (presidio) |
| 8 | Açık rıza akışı? | İlk mesajda template ile rıza talep edilir, "EVET" yanıtı saklanır |
Açık Rıza Mesaj Şablonu (WhatsApp Template)
Merhaba, Komtaş AI asistanına hoş geldiniz. Mesajlarınız müşteri
hizmetinizi geliştirmek için işlenecek ve 30 gün saklanacaktır.
Devam etmek için "EVET" yazın.
Ayrıntılı bilgi: komtas.com.tr/kvkk
Onayı geri çekmek için: "SIL" yazın
Veri sorumlusu: Komtaş Bilgi Sistemleri A.Ş. — kvkk@komtas.com.tr
M.7 Webhook Güvenliği & Lakera Guard
| Risk | Önlem | Implementasyon |
|---|---|---|
| Sahte webhook çağrısı | HMAC SHA-256 imza doğrulama | X-Hub-Signature-256 header (Meta), X-Twilio-Signature (Twilio) |
| Replay attack | Timestamp + nonce | 5 dakika tolerans; nonce Redis'te saklanır |
| Prompt injection | Lakera Guard öncesi | Mesaj LLM'ye gitmeden önce filtre |
| Rate limit / DoS | Per-sender token bucket | Redis: dakikada max 10 mesaj/sender |
| PII sızıntısı | Presidio masking | TC kimlik, IBAN, kart no maskele → modele giderken |
| Yetkisiz tool kullanımı | Per-user scope | Tool çağrısı öncesi kullanıcı yetkisi kontrol |
M.8 Mesaj Geçmişi & Long-term Memory (Qdrant)
WhatsApp/Telegram gibi süreğen konuşmalar için son N mesaj kısa süreli bellekte (Redis), uzun vadeli kullanıcı tercihleri ve önceki konu özetleri Qdrant içinde tutulur.
from qdrant_client import QdrantClient, models
from anthropic import Anthropic
q = QdrantClient(url=os.environ["QDRANT_URL"])
claude = Anthropic()
COLLECTION = "user_memories"
# Konuşma sonunda özet üret ve embed et
def store_memory(user_id: str, summary: str):
embedding = claude.embeddings.create(
model="voyage-3", input=summary
).data[0].embedding
q.upsert(
collection_name=COLLECTION,
points=[models.PointStruct(
id=hash(f"{user_id}-{time.time()}"),
vector=embedding,
payload={"user_id": user_id, "text": summary,
"created": time.time()},
)],
)
# Yeni mesajda alakalı geçmişi getir
def recall(user_id: str, query: str, k: int = 3):
qv = claude.embeddings.create(model="voyage-3", input=query).data[0].embedding
results = q.search(
collection_name=COLLECTION,
query_vector=qv,
query_filter=models.Filter(must=[
models.FieldCondition(key="user_id",
match=models.MatchValue(value=user_id))
]),
limit=k,
)
return [r.payload["text"] for r in results]
M.9 Maliyet Tahmini & Kota Yönetimi
Aylık Maliyet Kalkülatörü (Tahmini)
| Kalem | Birim Maliyet | 10K msg/ay | 100K msg/ay |
|---|---|---|---|
| WhatsApp Meta — Müşteri başlatmalı (utility) | ~0.0035 USD/konuşma | $35 | $350 |
| WhatsApp Meta — Marka başlatmalı (marketing) | ~0.0670 USD/konuşma (TR) | $670 | $6.700 |
| Claude Sonnet — input (1.5K token/msg ortalama) | $3 / M token | $45 | $450 |
| Claude Sonnet — output (300 token/msg) | $15 / M token | $45 | $450 |
| Lakera Guard | Plan bazlı | $50 | $200 |
| Qdrant Cloud (Starter) | — | $25 | $140 |
| Toplam (utility) | — | ~$200 | ~$1.600 |
Kota & Devre Kesici Mantığı
# Kullanıcı başına saatlik / günlük token bütçesi
async def check_quota(user_id: str, est_tokens: int):
key = f"quota:{user_id}:{date.today()}"
used = int(await redis.get(key) or 0)
if used + est_tokens > DAILY_TOKEN_LIMIT:
raise QuotaExceeded("Günlük kota aşıldı")
await redis.incrby(key, est_tokens)
await redis.expire(key, 86400)