Dokumentasyon
Mga outbound webhook: payload at signature
Tumanggap ng mga alerto at ulat ng AutoPSEO bilang signed na JSON sa anumang HTTPS endpoint: ang mga request header, mga field ng body, mga uri ng event, at kung paano i-verify ang signature.
Ang outbound webhook ay nagpapadala ng mga alerto, naka-iskedyul na ulat, test message, at buod ng ulat ng AutoPSEO sa isang endpoint na pinapatakbo mo, bilang isang JSON POST kada mensahe na may lagda ng HMAC-SHA256. Gamitin ito para pakainin ang Zapier, Make, n8n, isang incident tool, o ang sarili mong code; walang kailangang Slack o Teams account. Hinahanap ang webhook na naghahatid ng mga artikulo sa iyong site? Nasa content engine iyon: tingnan ang content delivery.
Magdagdag ng webhook
- Sa seksyong Outbound webhooks, i-click ang New webhook.
- Bigyan ito ng Name at i-paste ang URL ng endpoint. Dapat itong pampublikong HTTPS: tinatanggihan ang plain
http,localhost, mga pangalang nagtatapos sa.localo.internal, mga host na walang tuldok, at mga private o link-local na IP address. - Kopyahin ang signing secret na ipinapakita pagkatapos mong mag-save. Isang beses lang ito ipinapakita.
- I-click ang Send test para mag-post ng
testevent, pagkatapos ay ikabit ang mga naka-iskedyul na ulat o mga alerto sa webhook.
Ano ang hitsura ng isang webhook request
Ang bawat mensahe ay isang POST na may mga sumusunod na header:
| Header | Halaga |
|---|---|
Content-Type | application/json |
User-Agent | AutoPSEO-Webhook/1.0 |
X-AutoPSEO-Event | Ang uri ng event, halimbawa traffic_drop |
X-AutoPSEO-Signature | sha256= na sinusundan ng 64 na lowercase hex na karakter |
Narito ang alerto ng pagbaba ng trapiko para sa isang domain property mula sa 06:00 UTC na takbo noong 12 Oktubre 2026, na naka-format para madaling basahin (sa aktwal na pagpapadala ay compact JSON ito, at gawa-gawa lang ang mga halaga ng id at site_id):
{
"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"
}
Pareho ang mga top-level na field sa lahat ng event:
| Field | Laman |
|---|---|
id | Isang random na 32-karakter na hex string, bago sa bawat request |
event_type | Ang nangyari (tingnan ang susunod na seksyon) |
severity | critical, high, medium o low para sa mga alerto; info para sa mga ulat, buod, at test |
site_id | Ang id ng AutoPSEO para sa property, o null para sa mga test at sa demo property |
site_url | Ang Search Console property, gaya ng sc-domain:example.com o https://www.example.com/, o null para sa mga test |
occurred_at | Kung kailan binuo ang mensahe, bilang ISO 8601 timestamp sa UTC |
title, text | Ang headline at ang pangungusap na buod na ipinapakita ng Slack at Teams |
url | Ang ulat sa AutoPSEO, o null para sa mga test |
payload.fields | Ang mga may-label na halaga na ipinapakita ng Slack bilang mga field at ng Teams bilang mga fact |
payload.table | columns at rows para sa mga ulat at buod, kung hindi ay null |
source | Palaging autopseo |
Mga fraction ang mga ratio: ang change na -0.25 ay pagbaba ng 25%, at ang ctr na 0.034 ay 3.4%.
Mga uri ng event
event_type | Ipinapadala kapag | Mga karagdagang key sa payload |
|---|---|---|
traffic_drop, traffic_spike, position_drop, ctr_drop, new_lost_rankings, anomaly, index_flip, rank_drop, audit_regression | May na-trigger na alert rule, ayon sa iskedyul o sa pamamagitan ng Test rule | detector, window, range (ang mga petsa, o null para sa index_flip, rank_drop at audit_regression), result |
scheduled_report | May lumabas na naka-iskedyul na ulat, ayon sa iskedyul o sa pamamagitan ng Send now | reportType (summary, queries, pages o rankings), range (mga petsa kasama ang label), totals, previous |
report_summary | May gumamit ng Send to Slack sa pahina ng ulat | Wala: nasa fields at table ang mga numero |
test | May nag-click ng Send test sa webhook | sample, palaging true |
Inuulit ng result ang sinukat ng detector: fired, metric, value, baseline, change (null kapag walang mapaghahambingan), severity at summary, kasama ang z, ang modified z-score, para sa anomaly. Taglay ng totals at previous ang clicks, impressions, ctr at position para sa dalawang window ng isang ulat. Inilalarawan sa Alerts kung ano ang sinusukat ng bawat detector.
Paano i-verify ang signature
Ang signature ay HMAC-SHA256 ng eksaktong mga byte na ipinadala ng AutoPSEO, na may susi na signing secret ng webhook at isinulat bilang sha256= kasama ang lowercase hex. Para i-verify ito:
- Basahin ang raw na request body bago ang anumang JSON parsing. Maaaring baguhin ng pag-parse at muling pag-serialize ang mga byte.
- Kalkulahin ang HMAC-SHA256 sa mga byte na iyon, gamit ang secret bilang text: ang 64-karakter na string nang eksakto gaya ng ipinakita, hindi dina-decode mula sa hex.
- Idagdag ang prefix na
sha256=at ihambing ang resulta saX-AutoPSEO-Signatureheader sa constant time. - Tanggihan ang request kapag magkaiba ang dalawa. Kung hindi, tumugon agad ng 2xx na status at gawin na lang ang mabibigat na gawain pagkatapos.
Isang receiver para sa Node.js na walang dependency:
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);
Nauuna ang pagsusuri ng haba dahil nagtatapon ng error ang timingSafeEqual ng Node kapag magkaiba ang haba ng dalawang buffer.
Mga patakaran sa paghahatid
- Isang pagtatangka lang ang bawat mensahe, na may 10-segundong timeout. Ang anumang sagot na hindi 2xx ay ituturing na pagkabigo at itatago sa Delivery history kasama ang status code at ang simula ng response body mo.
- Hindi sinusundan ang mga redirect. Ang 3xx na sagot ay mabibigo na may paalalang gamitin ang pinal na URL.
- Walang nire-retry ayon sa timer. Ang nabigong alerto ay hindi mamarkahang naipadala, kaya susuriin itong muli sa susunod nitong check at magpo-post kung nagti-trigger pa rin: kinabukasan ng umaga para sa karamihan ng detector, sa susunod na oras para sa mga index flip. Ang nabigong naka-iskedyul na ulat ay hindi ipapadala muli sa parehong panahon, kaya gamitin ang Send now matapos ayusin ang endpoint.
- Ginagawa ang
idkada request, kaya kinikilala nito ang isang paghahatid at hindi ang isang event. Para i-de-duplicate ang mga alerto, pagsamahin angevent_type,site_urlat ang petsa ngoccurred_at: nagpo-post ang isang rule nang hindi hihigit sa isang beses kada property kada UTC na araw, maliban kung may magpatakbo ng Test rule.
Ang signing secret
Isang beses lang ipinapakita ng AutoPSEO ang signing secret, kapag sine-save mo ang webhook, at hindi na ito ipinapakita muli ng listahan. Itabi ito agad sa configuration ng iyong receiver, kasama ng endpoint na pinoprotektahan nito.
Naka-encrypt ang mismong URL, at ipinapakita lang ng listahan ang host nito at ang mga huling karakter. Kapag binura ang isang webhook, buburahin din ang bawat rule na nagpo-post dito. Kung gusto mo ng nababasang card sa isang Teams channel sa halip na JSON, gamitin ang Microsoft Teams.