Salt la conținutul principal
Un webhook e o adresă de pe serverul tău la care Housera trimite un POST de fiecare dată când se întâmplă ceva cu un anunț al tău: e publicat, respins, editat în portal. Nu mai trebuie să întrebi periodic. Webhook-urile urmează specificația deschisă Standard Webhooks, deci orice bibliotecă compatibilă îți verifică semnătura.

Configurarea

Din contul tău, la Setări → API, secțiunea Webhook-uri:
1

Adaugă adresa

O adresă https:// publică, de exemplu https://crm.exemplu.ro/hooks/housera. Alegi evenimentele pe care vrei să le primești.
2

Păstrează secretul

La creare primești secretul webhook-ului, de forma whsec_…. Se arată o singură dată. Îl folosești ca să verifici semnătura fiecărei livrări.
3

Trimite un test

Butonul „Trimite un test” livrează un eveniment webhook.test, semnat ca oricare altul, doar către acel webhook.
Un cont are cel mult 5 webhook-uri. Fiecare se poate opri și porni din aceeași pagină. Tot acolo vezi ultimele livrări, cu statusul primit de la serverul tău, și le poți retrimite manual. Dacă secretul a ajuns unde nu trebuia, îl rotești: primești unul nou (arătat tot o singură dată), iar cel vechi nu mai semnează nimic, imediat.

Evenimentele

Schimbările de stare produc evenimente indiferent de unde au pornit: prin API, din portal sau de la moderare. Evenimentele unui anunț ajung la contul care deține anunțul, doar dacă acel cont are cel puțin o cheie API.

Forma unui eveniment

Corpul fiecărei livrări e un obiect JSON:
string
Id-ul unic al evenimentului. E același cu antetul webhook-id. Îl folosești ca să nu procesezi de două ori același eveniment.
string
Tipul evenimentului, din tabelul de mai sus.
string
Momentul evenimentului, ISO 8601.
object
Pentru evenimentele de anunț: code, external_ref (sau null), status (starea anunțului în momentul evenimentului), url, plus câmpurile specifice tipului.
La ștergerea anunțului de către tine, by e owner și apare "deleted": true.
Copia ta e acum în urmă. Citește anunțul cu GET /account/listings/{code} și decide ce păstrezi. Vezi Pentru CRM-uri.
Motivele posibile sunt în Pozele.

Livrarea

Fiecare livrare e un POST cu corpul JSON și antetele:
  • Răspunde cu un status 2xx în cel mult 10 secunde. Orice alt status, o redirecționare sau o depășire de timp e o livrare eșuată.
  • Răspunde repede, procesează apoi. Pune evenimentul într-o coadă proprie și confirmă imediat; nu face toată sincronizarea în timp ce Housera așteaptă.
  • Redirecționările nu sunt urmate. Configurează adresa finală.

Reîncercările

O livrare eșuată se reîncearcă automat de încă 6 ori, după 30 de secunde, 2 minute, 10 minute, 30 de minute, 2 ore și 6 ore. În total, Housera încearcă aproximativ 9 ore. Evenimentele webhook.test nu se reîncearcă. Pentru că o livrare poate ajunge de mai multe ori (de exemplu, ai procesat-o, dar răspunsul tău s-a pierdut) și pentru că ordinea nu e garantată:
  • ține minte id-urile procesate (webhook-id) și ignoră un eveniment deja văzut;
  • nu te baza pe ordinea sosirii: pentru starea curentă a unui anunț, sursa de adevăr rămâne GET /account/listings/{code}.

Verificarea semnăturii

Orice server poate trimite un POST la adresa ta. Semnătura dovedește că livrarea vine de la Housera și nu a fost modificată. Semnătura e un HMAC-SHA256 în base64, calculat peste șirul {webhook-id}.{webhook-timestamp}.{corp}, unde {corp} sunt octeții exacți ai corpului primit. Cheia HMAC e partea de după whsec_ din secret, decodată din base64. Pașii:
  1. Citește corpul brut, înainte de orice parsare JSON. Un corp re-serializat nu mai dă aceeași semnătură.
  2. Verifică webhook-timestamp: respinge livrările mai vechi sau mai noi de 5 minute față de ora ta. Așa, o livrare interceptată nu poate fi retrimisă mai târziu.
  3. Calculează semnătura așteptată și compar-o în timp constant cu fiecare semnătură din webhook-signature (antetul poate conține mai multe, separate prin spațiu, fiecare cu prefixul v1,).
Nu compara semnăturile cu ==. O comparație obișnuită se oprește la primul caracter diferit, iar diferența de timp poate fi folosită ca să ghicești semnătura. Folosește mereu funcția de comparare în timp constant a limbajului tău.

Recuperarea evenimentelor

Un webhook pe care serverul tău nu l-a primit (a fost căzut mai mult de 9 ore, sau webhook-ul era oprit) nu e pierdut. Fiecare eveniment se păstrează 35 de zile și îl citești cu GET /events (dreptul listings:read):
  • Evenimentele vin în ordine, de la cel mai vechi la cel mai nou, în aceeași formă ca la webhook.
  • after e id-ul ultimului eveniment pe care l-ai procesat. Fără after, pornești de la cel mai vechi eveniment păstrat.
  • limit merge de la 1 la 500 (implicit 100).
  • Cât timp meta.next nu e null, mai sunt evenimente: ceri pagina următoare cu after egal cu meta.next.
  • Când meta.next e null, ai ajuns la capăt. Păstrează id-ul ultimului eveniment din data și pornește de la el data viitoare.
Un tipar robust: procesezi webhook-urile pe măsură ce vin și, la fiecare câteva minute (sau la repornirea serverului), rulezi GET /events?after=<ultimul id> ca să prinzi orice a scăpat. Id-urile îți spun ce ai procesat deja.