DocsAlmaniyaBilik bazasının beynəlxalq versiyasını göstər

Vebhuklar

Son yeniləmə: 2026-11-066 dəq oxu

Vebhuk - nəsə baş verdikdə GREM-in sizin URL-ə göndərdiyi POST sorğusudur: tapşırıq tamamlanır, elan və ya lid dəyişir. Abunəliklərin idarə edilməsi üçün webhooks scope-u lazımdır və ödənişsizdir. Agentliyin vebhukları agentlik səviyyəli açarla idarə olunur; agent səviyyəli açar 403 alır.

Abunə olmaq

curl -X POST https://developers.grem.capital/api/v1/webhooks \
  -H "Authorization: Bearer gsk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/grem-hook","events":["content.completed","content.failed","lead.created"]}'
{ "id": "...", "url": "https://example.com/grem-hook", "events": [...], "status": "active",
  "failureCount": 0, "lastDeliveryAt": null, "secret": "whsec_..." }
  • url - standart portda (443) ictimai https:// ünvanı, daxilində user:password olmadan. Başqa portlar, ünvanda giriş məlumatları, şəxsi, lokal və daxili ünvanlar rədd edilir (400). Port qaydası ünvanı təyin edərkən tətbiq olunur: əvvəllər başqa portda saxlanmış endpoint-lər çatdırılmaları almağa davam edir.
  • events - aşağıdakı siyahıdan ən azı bir hadisə; naməlum adlar atılır.
  • secret - imza sirri. O, yalnız bir dəfə qaytarılır - onu saxlayın.
  • Hesab başına 10 ünvana qədər, ayrıca isə test açarları ilə yaradılmış 10 sandbox ünvanına qədər; 11-ci ünvan 422 business_rule ilə rədd edilir.
  • Test açarı ilə yaradılmış endpoint-lər sandbox endpoint-ləridir: onlar yalnız sandbox tapşırıqlarının hadisələrini alır (Sandbox).

Abunəlikləri kabinetdə də idarə etmək olar: API → Vebhuklar. İmza sirrini orada dəyişmək mümkündür.

İdarəetmə

SorğuNə edir
GET /webhooksabunəlikləriniz (sirlər olmadan)
PATCH /webhooks/{id}url, events və ya status (active / disabled) dəyişmək
DELETE /webhooks/{id}abunəliyi silmək
POST /webhooks/{id}/testnümunə hadisə göndərmək; {"eventType": "content.completed"} gövdəsi nümunənin formasını təyin edir
GET /webhooks/{id}/deliveriesson 50 çatdırılma: status, cavab kodu, gecikmə, cavabın başlanğıcı
POST /webhooks/{id}/deliveries/{deliveryId}/resendçatdırılmanı yenidən göndərmək; deliveryId jurnaldakı sətrin _id dəyəridir

events daxilində heç bir etibarlı hadisə olmayan və ya status dəyəri active / disabled olmayan PATCH 400 ilə rədd edilir. Naməlum abunəliyin DELETE sorğusu 404 cavabı verir. Çatdırılma jurnalında payload hadisənin data sahəsidir.

Hadisələr

Tamamlanmış tapşırıqlar

HadisəNə vaxt
valuation.completed, valuation.failedtam qiymətləndirmə hesabatı
express.completed, express.failedPrefer: respond-async ilə başladılmış ekspres qiymətləndirmə
rent.completed, rent.failedPrefer: respond-async ilə başladılmış icarə qiymətləndirməsi
draft.completed, draft.failedPrefer: respond-async ilə işə salınmış elan qaralaması
site.completed, site.failedPrefer: respond-async ilə işə salınmış obyekt saytı
review.completed, review.failedhesabatın yoxlanması
review.action_requiredhesabatın yoxlanması sənədi oxuyub və confirm gözləyir
content.completed, content.partial, content.failedkontent paketi (partial - bəzi fayllar alınmadı)
text.completed, text.failedmətnlər
video.completed, video.failedvideo
avatar.completed, avatar.failedavatar video
photo.completed, photo.failedfoto yaxşılaşdırma
floorplan.completed, floorplan.failedmərtəbə planı
pdf.completed, pdf.failedPDF təqdimat

data: { "jobId", "status", "state" }. status alətin böyük hərflərlə yazılmış xam statusudur (məsələn, COMPLETED) - məntiqi state üzrə qurun. Tapşırıq 30 dəqiqə ərzində tamamlanmayıbsa - "reason": "timeout" ilə .failed. Tapşırıq yalnız o yaradılarkən onun hadisəsinə abunəlik mövcud olduqda izlənilir (Tapşırıqlar və nəticələr). express.* və rent.* hadisələrində status DONE və ya FAILED olur. Prefer: respond-async ilə başladılmış mərtəbə planı və ya hesabat yoxlaması üçün hadisə sorğu tapşırığının id-sini (areq_…) daşıyır; belə tapşırığın review.completed hadisəsi sənədin oxunduğunu və confirm tələb etdiyini bildirir - yoxlamanın özü isə, həmişəki kimi, təsdiqdən sonra öz hadisəsini göndərir.

review.action_required hesabatın yoxlanması sənədi oxuyub confirm gözlədikdə bir dəfə gəlir: jobId yoxlamanın özünün id-sidir (Prefer: respond-async ilə işə salındıqda da), status - NEED_CONFIRM, state - action_required.

Elanlar

HadisəNə vaxt
object.createdsiz elan yaratdınız
object.updatedelan dəyişdi, o cümlədən moderator tərəfindən
object.publishedelan ictimai oldu
object.deletedqaralama silindi və ya dərc edilmiş elan arxivə köçürüldü

data: { "objectId", "kind", "status", "occurredAt" }; object.deleted hadisəsində status əvəzinə mode (deleted və ya archived) olur. Tam məlumat - GET /objects/{kind}/{id}.

Lidlər

HadisəNə vaxt
lead.createdsizə ünvanlanmış yeni lid
lead.updatedstatus və ya məsul şəxs dəyişdi

data: { "leadId", "status", "type", "source", "objectId", "occurredAt" }. Hadisədə müştərinin şəxsi məlumatları yoxdur - tam lidi GET /leads/{id} ilə oxuyun.

Swipe Match

HadisəNə vaxt
match.lead.offeredlid sizə (və ya agentliyinizin agentinə) təklif edildi
match.lead.offer_closedtəklif sizsiz bağlandı (vaxt bitdi)
match.lead.matchedlid sizə təyin edildi
match.lead.updatedlid yeni mərhələyə keçdi
match.lead.unassignedlid sizdən götürüldü

data: { "leadId", "eventId", "eventCode", "occurredAt", "source", "stage", "active", "leadKind", "clientType", "country", "brokerId", "agencyId" }. Müştərinin adı, telefonu və e-poçtu heç vaxt hadisələrdə olmur (Swipe Match).

Çatdırılma formatı

POST https://example.com/grem-hook
Content-Type: application/json
x-grem-event: content.completed
x-grem-signature: t=1759400000,v1=3b78a03b78058d229023db2a0b4ee072...

{ "id": "...", "type": "content.completed", "createdAt": "2026-10-02T10:00:00.000Z", "data": { ... } }
  • id bir çatdırılmanın bütün təkrar cəhdlərində eynidir - hadisəni iki dəfə emal etməmək üçün ondan istifadə edin.
  • t və createdAt konkret cəhdin vaxtıdır.
  • Siyahıdakı eventType ilə test çatdırılması (POST /webhooks/{id}/test) data daxilində test: true daşıyır; onsuz hadisənin tipi webhook.test olur. Siyahıda olmayan eventType - 400. webhook.test özü qəbul edilir.

İmzanın yoxlanması

İmza abunəliyin sirri ilə "<t>.<raw body>" sətrindən hesablanmış HMAC-SHA256-dır, v1 daxilində hex formatında kodlanır. İmzanı istənilən emaldan əvvəl yoxlayın və köhnəlmiş t dəyərlərini rədd edin (təkrar göndərmədən qorunma).

İmzanı JSON-u təhlil etməzdən əvvəl, sorğunun xam gövdəsi üzərində, tam alındığı kimi hesablayın. Yenidən seriyalaşdırma baytları dəyişir və imza uyğun gəlməyəcək.

const crypto = require('crypto');

function verifyGremSignature(secret, header, rawBody, toleranceSec = 300) {
  const parts = Object.fromEntries(String(header || '').split(',').map((kv) => kv.split('=')));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
  const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
  const a = Buffer.from(expected);
  const b = Buffer.from(parts.v1 || '');
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

app.post('/grem-hook', express.raw({ type: 'application/json' }), (req, res) => {
  const raw = req.body.toString('utf8');
  if (!verifyGremSignature(process.env.GREM_WEBHOOK_SECRET, req.get('x-grem-signature'), raw)) {
    return res.status(400).send('invalid signature');
  }
  const event = JSON.parse(raw);
  // event.id, event.type, event.data
  res.sendStatus(200);
});

SDK-da verifyWebhookSignature() eyni işi görür.

Təkrar cəhdlər və söndürmə

  • Serveriniz 10 saniyə ərzində 2xx cavabı verdikdə çatdırılma uğurlu sayılır. Tez cavab verin, ağır işləri isə arxa planda görün.
  • Uğursuz çatdırılma 5 dəqiqə, 30 dəqiqə, 2 saat və 6 saat sonra təkrarlanır - cəmi 5 cəhdə qədər.
  • Ardıcıl 5 çatdırılma tamamilə uğursuz olduqdan sonra abunəlik söndürülür (status: disabled). Onu PATCH /webhooks/{id} və {"status":"active"} ilə və ya kabinetdə yenidən aktivləşdirin.
  • Çatdırılma jurnalı (GET /webhooks/{id}/deliveries) serverinizin cavab kodunu və cavab gövdəsinin başlanğıcını göstərir - çatdırılmanın niyə alınmadığını orada görürsünüz.

Əlaqəli

Bu məqalə faydalı oldu?