Belgeler
Giden webhook'lar: payload ve imza
AutoPSEO uyarılarını ve raporlarını herhangi bir HTTPS uç noktasında imzalı JSON olarak alın: istek başlıkları, gövde alanları, olay türleri ve imzanın nasıl doğrulanacağı.
Giden webhook, AutoPSEO'nun uyarılarını, zamanlanmış raporlarını, test mesajlarını ve rapor özetlerini sizin işlettiğiniz bir uç noktaya iletir. Her mesaj, HMAC-SHA256 ile imzalanmış tek bir JSON POST isteği olarak gönderilir. Zapier, Make, n8n, bir olay yönetimi aracı veya kendi kodunuzu beslemek için kullanabilirsiniz; Slack ya da Teams hesabı gerekmez. Sitenize makale ileten webhook'u mu arıyorsunuz? O webhook içerik motoruna aittir: içerik teslimi sayfasına bakın.
Webhook ekleme
- Outbound webhooks bölümünde New webhook düğmesine tıklayın.
- Bir Name (ad) verin ve uç noktanın URL'sini yapıştırın. URL herkese açık bir HTTPS adresi olmalıdır: düz
http,localhost,.localveya.internalile biten adlar, noktası olmayan ana makine adları ve özel ya da link-local IP adresleri reddedilir. - Kaydettikten sonra gösterilen signing secret değerini kopyalayın. Bu değer yalnızca bir kez gösterilir.
testolayı göndermek için Send test düğmesine tıklayın, ardından zamanlanmış raporları veya uyarıları webhook'a bağlayın.
Webhook isteği neye benzer
Her mesaj, şu başlıklarla bir POST isteği olarak gönderilir:
| Başlık | Değer |
|---|---|
Content-Type | application/json |
User-Agent | AutoPSEO-Webhook/1.0 |
X-AutoPSEO-Event | Olay türü, örneğin traffic_drop |
X-AutoPSEO-Signature | sha256= ve ardından 64 küçük harfli onaltılık karakter |
Aşağıda, 12 Ekim 2026 tarihli 06:00 UTC çalıştırmasından bir alan adı mülkü için trafik düşüşü uyarısı okunabilir biçimde gösterilmiştir (gerçekte kompakt JSON olarak gönderilir; id ve site_id değerleri uydurmadır):
{
"id": "9b2e61f04c3a4d7e8f15a0b6c2d39e47",
"event_type": "traffic_drop",
"severity": "high",
"site_id": "4f0c1e9a2b7d4c58",
"site_url": "sc-domain:example.com",
"occurred_at": "2026-10-12T06:00:04.183Z",
"title": "Traffic drop: example.com",
"text": "Clicks 1,500 vs 2,000 in the previous window (-25.0%).",
"url": "https://app.autopseo.com/property/sc-domain%3Aexample.com",
"payload": {
"fields": [
{ "label": "Metric", "value": "clicks" },
{ "label": "Current", "value": "1,500" },
{ "label": "Baseline", "value": "2,000" },
{ "label": "Window", "value": "7 days (2026-10-05 → 2026-10-11 vs 2026-09-28 → 2026-10-04)" },
{ "label": "Change", "value": "-25.0%" }
],
"table": null,
"detector": "traffic_drop",
"window": 7,
"range": { "start": "2026-10-05", "end": "2026-10-11", "compStart": "2026-09-28", "compEnd": "2026-10-04" },
"result": {
"fired": true,
"metric": "clicks",
"value": 1500,
"baseline": 2000,
"change": -0.25,
"severity": "high",
"summary": "Clicks 1,500 vs 2,000 in the previous window (-25.0%)."
}
},
"source": "autopseo"
}
Üst düzey alanlar tüm olaylarda aynıdır:
| Alan | İçeriği |
|---|---|
id | Rastgele 32 karakterlik onaltılık bir dize; her istekte yenisi üretilir |
event_type | Ne olduğu (bir sonraki bölüme bakın) |
severity | Uyarılar için critical, high, medium veya low; raporlar, özetler ve testler için info |
site_id | AutoPSEO'nun mülk için kullandığı kimlik; testlerde ve demo mülkünde null |
site_url | sc-domain:example.com veya https://www.example.com/ gibi Search Console mülkü; testlerde null |
occurred_at | Mesajın oluşturulduğu an; UTC cinsinden ISO 8601 zaman damgası |
title, text | Slack ve Teams'in gösterdiği başlık ve özet cümlesi |
url | AutoPSEO'daki rapor; testlerde null |
payload.fields | Slack'in alan, Teams'in fact olarak gösterdiği etiketli değerler |
payload.table | Raporlar ve özetler için columns ve rows; diğer durumlarda null |
source | Her zaman autopseo |
Oranlar kesir olarak verilir: -0.25 değerindeki bir change yüzde 25'lik düşüş, 0.034 değerindeki bir ctr ise yüzde 3,4 anlamına gelir.
Olay türleri
event_type | Ne zaman gönderilir | payload içindeki ek anahtarlar |
|---|---|---|
traffic_drop, traffic_spike, position_drop, ctr_drop, new_lost_rankings, anomaly, index_flip, rank_drop, audit_regression | Bir uyarı kuralı tetiklendiğinde; zamanlamaya göre ya da Test rule ile | detector, window, range (tarihler; index_flip, rank_drop ve audit_regression için null), result |
scheduled_report | Zamanlanmış bir rapor gönderildiğinde; zamanlamaya göre ya da Send now ile | reportType (summary, queries, pages veya rankings), range (tarihler ve bir label), totals, previous |
report_summary | Biri bir rapor sayfasında Send to Slack düğmesini kullandığında | Yok: değerler fields ve table içindedir |
test | Biri webhook üzerinde Send test düğmesine tıkladığında | sample, her zaman true |
result, dedektörün ölçtüklerini tekrar eder: fired, metric, value, baseline, change (karşılaştırılacak veri yoksa null), severity ve summary; anomaly için ayrıca değiştirilmiş z-skoru olan z da bulunur. totals ve previous, bir raporun iki dönemi için clicks, impressions, ctr ve position değerlerini içerir. Her dedektörün neyi ölçtüğü Uyarılar sayfasında açıklanmıştır.
İmza nasıl doğrulanır
İmza, AutoPSEO'nun gönderdiği baytların tamamı üzerinden, webhook'un signing secret değeriyle anahtarlanarak hesaplanan bir HMAC-SHA256'dır ve sha256= önekiyle küçük harfli onaltılık biçimde yazılır. Doğrulamak için:
- İstek gövdesini, JSON olarak ayrıştırmadan önce ham haliyle okuyun. Ayrıştırıp yeniden serileştirmek baytları değiştirebilir.
- Bu baytlar üzerinden HMAC-SHA256 hesaplayın; secret değerini metin olarak kullanın: 64 karakterlik dizeyi gösterildiği gibi alın, onaltılıktan çözmeyin.
- Sonucun başına
sha256=ekleyin veX-AutoPSEO-Signaturebaşlığıyla sabit zamanlı (constant-time) bir karşılaştırmayla kıyaslayın. - İkisi farklıysa isteği reddedin. Aksi halde hemen 2xx durum koduyla yanıt verin ve yavaş işleri sonra yapın.
Node.js için bağımlılık gerektirmeyen bir alıcı:
import { createServer } from 'node:http';
import { createHmac, timingSafeEqual } from 'node:crypto';
const secret = process.env.AUTOPSEO_WEBHOOK_SECRET;
createServer((req, res) => {
const chunks = [];
req.on('data', (chunk) => chunks.push(chunk));
req.on('end', () => {
const raw = Buffer.concat(chunks);
const expected = Buffer.from('sha256=' + createHmac('sha256', secret).update(raw).digest('hex'));
const received = Buffer.from(String(req.headers['x-autopseo-signature'] || ''));
if (received.length !== expected.length || !timingSafeEqual(received, expected)) {
res.writeHead(401).end();
return;
}
res.writeHead(204).end();
const event = JSON.parse(raw.toString('utf8'));
console.log(event.event_type, event.severity, event.site_url);
});
}).listen(8080);
Uzunluk kontrolü başta yapılır, çünkü Node'un timingSafeEqual fonksiyonu iki arabelleğin uzunluğu farklıysa hata fırlatır.
Teslimat kuralları
- Her mesaj için tek deneme yapılır ve zaman aşımı 10 saniyedir. 2xx dışındaki her yanıt başarısızlık sayılır ve durum koduyla birlikte yanıt gövdenizin ilk kısmı Delivery history içinde saklanır.
- Yönlendirmeler izlenmez. 3xx yanıtı, nihai URL'yi kullanmanızı belirten bir notla başarısız olur.
- Hiçbir şey zamanlayıcıyla yeniden denenmez. Başarısız olan bir uyarı gönderildi olarak işaretlenmez; bu nedenle bir sonraki kontrolde yeniden değerlendirilir ve hâlâ tetikleniyorsa gönderilir: çoğu dedektör için ertesi sabah, index flip için ertesi saat. Başarısız olan bir zamanlanmış rapor aynı dönem içinde yeniden gönderilmez; uç noktayı düzelttikten sonra Send now kullanın.
idher istek için ayrı üretilir; yani bir olayı değil, bir teslimatı tanımlar. Uyarıları tekrarlardan ayıklamak içinevent_type,site_urlveoccurred_attarihini birlikte kullanın: bir kural, biri Test rule çalıştırmadıkça, mülk başına UTC gününde en fazla bir kez gönderim yapar.
Signing secret
AutoPSEO, signing secret değerini webhook'u kaydettiğinizde yalnızca bir kez gösterir; liste bunu bir daha göstermez. Değeri hemen alıcınızın yapılandırmasında, koruduğu uç noktanın yanında saklayın.
URL'nin kendisi şifreli olarak saklanır ve liste yalnızca ana makine adını ve son karakterlerini gösterir. Bir webhook'u silmek, ona gönderim yapan tüm kuralları da siler. Teams kanalında JSON yerine okunaklı bir kart istiyorsanız Microsoft Teams sayfasına bakın.