Bir CAPTCHA çözüm hattının bozulduğunu fark etmenin en pahalı yolu, ertesi sabah boş bir veri tablosuna bakmaktır. Doğru sıra şudur: hata kodunu üreten kod, o hatayı 30 saniye içinde Slack kanalınıza düşürmelidir. Bu rehber tam olarak bunu kuruyor — tek bir webhook URL'si, üç uyarı tipi (çözüm hatası, düşük bakiye, yükselen hata oranı) ve günü kapatan bir özet mesajı.
Kod hem Python hem Node.js olarak veriliyor; ikisi de aynı Slack yük yapısını kullanır, dolayısıyla hangi dilde çalışıyorsanız oradan devam edebilirsiniz. Slack uygulamasını oluşturma dahil toplam kurulum süresi yaklaşık 10 dakikadır.
Neden Slack, neden log dosyası değil?
Otomasyon ekiplerinin çoğunda CAPTCHA çözümü, gece çalışan bir işin ortasında duran sessiz bir adımdır. Log dosyası her şeyi yazar ama kimse okumaz. Slack'in kazandığı yer tam burası: uyarı, zaten açık olan bir pencerede belirir ve tek bir kişiye değil kanaldaki herkese ulaşır.
Türkiye'deki tipik senaryo şu: bir e-ticaret entegrasyonunun ödeme adımını gece boyunca test eden QA iş akışı, Europe/Istanbul saatiyle 03:00'te reCAPTCHA v2 tarafında hata kodu almaya başlıyor. Bakiye eşiğe takılmış olabilir, hedef sayfa yeni bir sitekey yayınlamış olabilir ya da geçici bir zaman aşımı yaşanıyordur. Uyarı yoksa durum 09:00'da fark edilir ve gecenin altı saati çöpe gider. Uyarı varsa nöbetçi geliştirici bakiyeyi yükleyip işi yeniden başlatır — kayıp on dakikadır.
Serbest çalışan bir otomasyon geliştiricisiyseniz bunun bir de müşteri tarafı var: "iş akışı dün gece durmuş" cümlesini müşteriden duymak ile aynı cümleyi kendiniz kurmak arasında ciddi bir güven farkı vardır.
Adım 1: Slack webhook'unu oluşturun
Slack tarafında yapılacak tek iş, bir gelen webhook URL'si üretmek. Bu URL bir sırdır: elinde tutan herkes o kanala mesaj atabilir, bu yüzden ortam değişkeninde saklayın, repoya yazmayın.
- api.slack.com/apps adresine gidin → Create New App
- Incoming Webhooks bölümünü açın → anahtarı Activate konumuna getirin
- Add New Webhook to Workspace'e tıklayın → uyarıların düşeceği kanalı seçin
- Üretilen webhook URL'sini kopyalayın
Kanal seçiminde pratik bir kural: çözüm hataları ile bakiye uyarılarını aynı kanalda toplayın, günlük özeti ayrı bir kanala gönderin. Aksi halde özet mesajları gerçek uyarıların arasına karışır.
Adım 2: Ortak bildirim fonksiyonunu yazın
Her uyarı tipi için ayrı gönderim kodu yazmak yerine tek bir yardımcı fonksiyon kurun. Renk kodu uyarının ciddiyetini taşır: kırmızı hata, turuncu eşik uyarısı, yeşil özet. fields sözlüğü Slack mesajında iki sütunlu bir tabloya dönüşür; hata kodunu, görev kimliğini ve saati tek bakışta okunur hale getirir.
import requests
import json
from datetime import datetime
SLACK_WEBHOOK_URL = "https://hooks.slack.com/services/T00/B00/xxx"
def send_slack_alert(title, message, color="#ff0000", fields=None):
"""Send a formatted Slack alert."""
attachment = {
"color": color,
"title": title,
"text": message,
"ts": int(datetime.now().timestamp()),
}
if fields:
attachment["fields"] = [
{"title": k, "value": str(v), "short": True}
for k, v in fields.items()
]
payload = {"attachments": [attachment]}
resp = requests.post(SLACK_WEBHOOK_URL, json=payload, timeout=10)
return resp.status_code == 200
timeout=10 satırını atlamayın. Slack yanıt vermediğinde bildirim kodunun asıl iş akışınızı bloklamasını istemezsiniz.
Adım 3: Çözüm hatası uyarısını bağlayın
İlk uyarı en doğrudan olanı. Bir görev hata kodu ile döndüğünde kodu, CAPTCHA türünü ve hedef sayfayı Slack'e taşıyın. Hata kodunu mesajın gövdesine koymak önemli: sıfır bakiye hatası ile geçici bir zaman aşımı tamamen farklı iki müdahale gerektirir ve kanaldaki kişi bunu mesajı açmadan görmelidir.
def notify_solve_failure(task_id, captcha_type, error_code, site_url):
send_slack_alert(
title="CAPTCHA Solve Failed",
message=f"Task `{task_id}` failed with `{error_code}`",
color="#ff0000",
fields={
"Type": captcha_type,
"Error": error_code,
"Site": site_url,
"Time": datetime.now().strftime("%H:%M:%S"),
},
)
# Use after a failed solve
result = poll_for_result(task_id)
if result.get("error"):
notify_solve_failure(task_id, "recaptcha_v2", result["error"], "https://example.com")
Bu uyarıyı her başarısız görevde tetiklemeyin. Tek tek hatalar için bildirim göndermek, beşinci adımda kuracağımız hata oranı eşiğinin işini yapar ve kanalı gürültüye boğar. Pratikte iyi çalışan yaklaşım şu: tekil uyarıyı yalnızca insan müdahalesi gerektiren hata kodları için açık tutun, gerisini orana bırakın.
Adım 4: Düşük bakiye uyarısını kurun
Otomasyonun sessizce durmasının en sık nedeni bakiyedir. res.php uç noktası action=getbalance ile güncel bakiyeyi döndürür; bunu beş dakikada bir sorgulayıp eşiğin altına inildiğinde uyarı üretmek yeterli.
def check_balance_alert(api_key, threshold=5.0):
"""Alert when balance drops below threshold."""
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": api_key, "action": "getbalance", "json": "1"
}).json()
balance = float(resp.get("request", 0))
if balance < threshold:
send_slack_alert(
title="Low CaptchaAI Balance",
message=f"Balance is ${balance:.2f} (threshold: ${threshold:.2f})",
color="#ff9900",
fields={
"Current Balance": f"${balance:.2f}",
"Threshold": f"${threshold:.2f}",
},
)
return balance
# Run periodically
import threading
def balance_monitor(api_key, interval=300):
"""Check balance every 5 minutes."""
check_balance_alert(api_key)
timer = threading.Timer(interval, balance_monitor, args=[api_key, interval])
timer.daemon = True
timer.start()
balance_monitor("YOUR_API_KEY")
Eşiği plan büyüklüğünüze göre seçin. CaptchaAI thread tabanlı çalışır — BASIC ($15/ay, 5 thread) ile STANDARD ($30/ay, 15 thread) arasındaki fark eşzamanlı görev sayısıdır, thread başına çözüm sınırsızdır. Yoğun bir gecede günlük harcamanızın kaç dolar olduğunu bir kez ölçün ve eşiği bunun iki katına ayarlayın; böylece uyarı geldiğinde bakiye yüklemek için en az bir tam gününüz olur. Fiyatlar USD üzerindendir; kur dalgalanması nedeniyle aylık USD maliyetin öngörülebilir olması bu planların en pratik tarafıdır.
Adım 5: Hata oranı eşiğini tanımlayın
Asıl değerli uyarı budur. Tekil hatalar normaldir; sorun, son elli görevin üçte birinin başarısız olmasıdır. Kayan pencere (deque) ile oranı takip edin, eşik aşıldığında bir kez uyarın ve bekleme süresi dolmadan tekrar uyarmayın.
from collections import deque
class ErrorRateNotifier:
def __init__(self, window=50, threshold=0.3, cooldown=300):
self.results = deque(maxlen=window)
self.threshold = threshold
self.cooldown = cooldown
self.last_alert = 0
def record(self, success):
self.results.append(success)
if len(self.results) < 20:
return
error_rate = 1 - sum(self.results) / len(self.results)
import time
now = time.time()
if error_rate > self.threshold and (now - self.last_alert) > self.cooldown:
self.last_alert = now
send_slack_alert(
title="High CAPTCHA Error Rate",
message=f"Error rate: {error_rate:.0%} over last {len(self.results)} tasks",
color="#ff0000",
fields={
"Error Rate": f"{error_rate:.1%}",
"Window": f"{len(self.results)} tasks",
"Threshold": f"{self.threshold:.0%}",
},
)
notifier = ErrorRateNotifier()
# After each solve attempt
notifier.record(success=True) # solved
notifier.record(success=False) # failed
Buradaki üç sayı, uyarının işe yarayıp yaramayacağını belirler. Pencere 50 görev: daha küçük bir pencere istatistiksel gürültüyle yanıltır. En az 20 kayıt şartı: iş akışının ilk dakikalarında iki hata yüzünden alarm çalmasını engeller. 300 saniyelik bekleme süresi: aynı arıza için beş dakikada yalnızca bir mesaj demektir.
Aynı hattı Node.js ile kurmak
Node.js tarafında yapı birebir aynı: bir sendSlackAlert yardımcısı, üstüne hata ve bakiye uyarıları. Axios ile webhook'a POST atmak yeterli.
const axios = require('axios');
const SLACK_WEBHOOK = 'https://hooks.slack.com/services/T00/B00/xxx';
async function sendSlackAlert(title, message, color = '#ff0000', fields = {}) {
const attachment = {
color,
title,
text: message,
ts: Math.floor(Date.now() / 1000),
fields: Object.entries(fields).map(([k, v]) => ({
title: k, value: String(v), short: true,
})),
};
await axios.post(SLACK_WEBHOOK, { attachments: [attachment] });
}
// Failure alert
async function notifySolveFailure(taskId, type, error) {
await sendSlackAlert(
'CAPTCHA Solve Failed',
`Task \`${taskId}\` failed: \`${error}\``,
'#ff0000',
{ Type: type, Error: error }
);
}
// Balance alert
async function checkBalance(apiKey, threshold = 5.0) {
const resp = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: apiKey, action: 'getbalance', json: 1 },
});
const balance = parseFloat(resp.data.request);
if (balance < threshold) {
await sendSlackAlert(
'Low CaptchaAI Balance',
`Balance: $${balance.toFixed(2)}`,
'#ff9900',
{ Balance: `$${balance.toFixed(2)}`, Threshold: `$${threshold.toFixed(2)}` }
);
}
return balance;
}
// Periodic check
setInterval(() => checkBalance('YOUR_API_KEY'), 5 * 60 * 1000);
setInterval basit bir çözüm; iş akışınız zaten bir kuyruk veya zamanlayıcı kullanıyorsa bakiye kontrolünü oraya taşımak daha temiz olur.
Günlük özet mesajı
Uyarılar sorunu bildirir, özet ise eğilimi gösterir. Günde bir kez gönderilen toplam görev sayısı, başarı oranı ve ortalama çözüm süresi, bir hafta sonra bakıldığında bozulmanın tam olarak ne zaman başladığını söyler.
def send_daily_summary(stats):
"""Send a daily digest to Slack."""
send_slack_alert(
title="Daily CAPTCHA Summary",
message=f"{stats['total']} tasks processed",
color="#36a64f",
fields={
"Solved": stats["solved"],
"Failed": stats["failed"],
"Avg Solve Time": f"{stats['avg_time_ms']}ms",
"Total Cost": f"${stats['total_cost']:.2f}",
"Success Rate": f"{stats['success_rate']:.1%}",
},
)
Özeti sabah mesai başlangıcına zamanlayın; gece yarısı gönderilen bir özeti kimse okumaz.
Sorun giderme
| Sorun | Sebep | Çözüm |
|---|---|---|
| Webhook 403 döndürüyor | Webhook URL'si geçersiz veya iptal edilmiş | Slack'te webhook'u yeniden oluşturun, ortam değişkenini güncelleyin |
| Kanal uyarıya boğuluyor | Bekleme süresi tanımlı değil | Uyarılar arasına cooldown ekleyin, tekil hataları orana bırakın |
| Uyarılar geç geliyor | Webhook isteği zaman aşımına giriyor | İsteklere timeout=10 verin ve gönderimi ana akıştan ayırın |
| Mesaj hiç görünmüyor | Webhook yanlış kanala bağlı | Slack uygulamasında webhook'un kanal yapılandırmasını kontrol edin |
| Bakiye uyarısı hiç çalışmıyor | getbalance yanıtı beklenen alanı döndürmüyor |
Yanıtı ham haliyle loglayın, json=1 parametresini doğrulayın |
Sık sorulan sorular
Webhook URL'sini nerede saklamalıyım?
Ortam değişkeninde. Webhook URL'si ayrıca kimlik doğrulaması istemez; URL'yi ele geçiren herkes o kanala mesaj gönderebilir. Repoya yazılmış bir webhook sızarsa Slack tarafında iptal edip yenisini üretin.
Uyarı yorgunluğunu nasıl önlerim?
Üç kural yeter: en az beş dakikalık bekleme süresi, tekil hatalar yerine oran eşiği, ve gürültülü olayların günlük özete taşınması. Kanal okunmaz hale geldiği anda uyarı sistemi işlevini kaybeder.
Slack yerine Discord veya Microsoft Teams kullanabilir miyim?
Evet. Discord webhook'ları benzer bir JSON yapısı kabul eder — attachments yerine embeds alanını kullanın. Teams tarafında yük "MessageCard" biçimine dönüşür; yardımcı fonksiyonun yalnızca gövde oluşturan kısmını değiştirmeniz yeterli.
Bu uyarılar CaptchaAI bakiyemden düşer mi?
Hayır. Slack'e giden istekler CaptchaAI API'sinden bağımsızdır. getbalance sorgusu da ücretlendirilmez; ücretlendirme çözüm görevleri ve thread kullanımı üzerinden işler.
Hangi hata kodları için tekil uyarı açmalıyım?
Bakiye ve API anahtarı ile ilgili kodlar için — bunlar insan müdahalesi gerektirir ve kendiliğinden düzelmez. Geçici zaman aşımları ve tekil çözüm hataları yeniden deneme mantığına ve hata oranı eşiğine bırakılmalıdır.
Uyarı hattınızı bugün kurun
API anahtarınızı captchaai.com üzerinden alın, webhook URL'sini ortam değişkenine yazın ve ilk test mesajını gönderin.
İlgili rehberler
- Uyarıların altındaki veri katmanı için: CAPTCHA operasyonlarında yapılandırılmış log kaydı
- Bakiye uyarısını otomatik yüklemeye bağlamak için: bakiye kontrolü ve otomatik yükleme rehberi
- Uzun vadeli eğilimleri izlemek için: CaptchaAI kullanım panosu kurulumu