Kendi Meta Uygulamanı Bağlama (Gelişmiş)
Standart bağlama akışı (“Bağla” butonu) kullanıcıların çoğu için yeterli. Ama kendi Meta uygulamanı getiriyorsan — ajans olarak white-label çalışıyorsan, kendi App Review sürecini yönetiyorsan ya da self-host bir kurulumdaysan — dört ayarı kendin yapmalısın: izinler, redirect URI, webhook callback URL + verify token ve HMAC imza doğrulaması. Doğru kurulunca lead’ler saniyeler içinde düşer. Yanlış kurulunca Meta webhook’ları sessizce 401/403 ile reddeder ve tek bir lead bile gelmez — bu sayfa o dört ayarın tam olarak nasıl eşleşmesi gerektiğini gösterir.
Bu sayfa altyapı-seviyesi bir rehberdir ve Purvisor’ın ortam değişkenlerine (env) erişim gerektirir. Sadece lead reklamlarını bağlamak istiyorsan Meta Lead Ads Entegrasyonu sayfasındaki normal akışı izle; kendi uygulamanı kurmana gerek yok.
Ne zaman kendi uygulaman gerekir?
- Ajans / white-label — lead’lerin senin Meta uygulaman üzerinden aksın, App Review kendi işletme adına geçsin.
- Kendi App Review’ın —
leads_retrievalgibi izinler için onayı kendi uygulamanla almak istiyorsun. - Self-host / izole kurulum — Purvisor backend’ini kendi alan adında çalıştırıyorsun, dolayısıyla webhook ve redirect URL’leri sana ait.
Bunların hiçbiri geçerli değilse, standart akış daha az bakım ister. Kendi uygulaman = kendi App Review’ın + kendi token yenilemen (uzun ömürlü token 60 gün geçerlidir) demektir.
Mimari
İki ayrı kanal var: kullanıcının hesabını bağladığı OAuth akışı ve lead bildirimlerinin düştüğü webhook akışı. İkisi farklı ayar setleri ister.
OAuth (bir kere, kullanıcı bağlarken)
Panel → /api/integrations/meta/authorize
→ facebook.com/v21.0/dialog/oauth (izinler + redirect_uri)
→ kullanıcı onaylar
→ /api/integrations/meta/callback (code → token, redirect_uri TEKRAR kontrol edilir)
Webhook (her lead için, sürekli)
Facebook leadgen event
→ POST /api/integrations/meta/webhook
→ x-hub-signature-256 HMAC doğrulaması (META_APP_SECRET)
→ lead Graph API'den çekilir → kontak + otomatik aramaRedirect URI OAuth tarafını, verify token + HMAC ise webhook tarafını korur. Birini kurup diğerini atlarsan yarısı çalışır: bağlanırsın ama lead gelmez (ya da tam tersi).
Gereken ortam değişkenleri
Purvisor bu değerleri env üzerinden okur. Hepsi kendi Meta uygulamandan gelir:
| Değişken | Ne işe yarar |
|---|---|
META_APP_ID | Uygulamanın App ID’si — OAuth client_id olarak kullanılır. |
META_APP_SECRET | App Secret — hem token değişiminde hem HMAC imza doğrulamasında kullanılır. Gizli tut. |
META_REDIRECT_URI | OAuth callback URL’i — Meta panelindeki “Valid OAuth Redirect URIs” ile birebir aynı olmalı. |
META_WEBHOOK_VERIFY_TOKEN | Webhook doğrulamasında Meta’ya gireceğin token. Ayarlanmazsa varsayılan purvisor_meta_webhook_2026 kullanılır. |
META_APP_SECRET, HMAC anahtarının ta kendisidir — sızarsa biri sahte lead webhook’u imzalayabilir. Bir parola gibi düşün: rotasyona girerse hem env’i hem Meta panelini aynı anda güncelle.
1. Gereken izinler (scope)
Purvisor en az yetki ilkesiyle çalışır: sadece lead formu verisini okur, reklam yönetmez. OAuth ekranında istenen üç izin şudur:
| İzin (scope) | Ne için |
|---|---|
pages_show_list | Kullanıcının yönettiği Facebook Sayfalarını listelemek (hangi sayfanın lead’lerini takip edeceğini seçmek için). |
leads_retrieval | Lead formu gönderimlerini (ad, telefon, e-posta) çekmek. |
pages_read_engagement | Lead’i işlemek için gereken form meta verisini (alan adları) okumak. |
Purvisor bilinçli olarak ads_read, ads_management, pages_manage_ads, business_management ve pages_manage_metadata izinlerini istemez. Webhook aboneliği uygulama seviyesindedir (sayfa seviyesi değil), bu yüzden pages_manage_metadata gerekmez. Uygulaman App Review’a bu üç izinle gitmeli — fazlası onay sürecini uzatır ve reddedilme riskini artırır.
OAuth diyaloğu v21.0 Graph API sürümüyle açılır ve CSRF koruması için bir state token (32 baytlık rastgele hex) taşır; bu token 10 dakika ömürlü meta_oauth_state çerezinde saklanır.
2. Redirect URI eşleşmesi
En sık takılınan yer burası. redirect_uri iki kez kullanılır — önce OAuth diyaloğunda, sonra code → token değişiminde — ve Meta ikisinin de kayıtlı URI ile karakter karakter aynı olmasını ister.
Üç yerin aynı olması gerekir:
- Meta App paneli → Facebook Login → Settings → Valid OAuth Redirect URIs
- Purvisor’daki
META_REDIRECT_URIortam değişkeni - Purvisor callback yolu:
/api/integrations/meta/callback
Yani META_REDIRECT_URI şuna benzemeli:
https://<senin-purvisor-alan-adin>/api/integrations/meta/callbackSondaki
/,httpyerinehttps,wwwvar/yok, port farkı — hepsi “eşleşmedi” sayılır. Kopyala-yapıştır yap, elle yazma.
Callback bir sorun tespit ederse kullanıcıyı hata koduyla panele geri yollar. Karşılaştığın kodu buradan çöz:
| Yönlendirme | Anlamı / çözüm |
|---|---|
?error=meta_denied | Kullanıcı izin ekranında reddetti. |
?error=missing_params | code veya state gelmedi — genelde redirect URI yanlış eşleşmesinden. |
?error=invalid_state | state çerezle uyuşmadı (CSRF koruması) — çerez süresi doldu (10 dk) ya da farklı alan adı. |
?error=user_mismatch | Oturumdaki kullanıcı ile state’teki kullanıcı farklı — güvenlik reddi (IDOR koruması). |
?error=token_failed | code → token değişimi başarısız — META_APP_ID/META_APP_SECRET/redirect URI kombinasyonunu kontrol et. |
?error=callback_failed | Beklenmeyen hata — sunucu loglarına bak. |
Başarılıysa yönlendirme ?meta_connected=true&integration_id=... şeklinde döner ve panelde sayfa seçim adımına geçersin.
3. Webhook callback URL + verify token
Lead bildirimleri Meta’dan Purvisor’a bir webhook ile gelir. Meta App panelinde:
- Webhooks → Page nesnesine abone ol
- Yalnızca
leadgenalanına abone ol (Purvisor sadece bunu işler; diğer alanlar sessizce yok sayılır) - Callback URL olarak şunu gir:
https://<senin-purvisor-alan-adin>/api/integrations/meta/webhook- Verify Token olarak
META_WEBHOOK_VERIFY_TOKENdeğerini gir (varsayılan:purvisor_meta_webhook_2026)
Meta “Verify and Save” dediğinde bu URL’e bir GET doğrulama isteği atar. Purvisor hub.verify_token değerini env’deki token ile karşılaştırır; tutarsa hub.challenge değerini aynen geri döner:
GET /api/integrations/meta/webhook?hub.mode=subscribe&hub.verify_token=purvisor_meta_webhook_2026&hub.challenge=1158201444
→ 200 OK
1158201444Token yanlışsa:
→ 403 Forbidden
{ "error": "Forbidden" }403 alıyorsan panelde girdiğin verify token ile
META_WEBHOOK_VERIFY_TOKENenv değeri farklıdır. Bir “gizli parola karşılaştırması” gibi: iki taraf da aynı kelimeyi bilmezse Meta aboneliği kaydetmez.
📸 [Ekran görüntüsü: Meta App paneli — Webhooks, Page nesnesi, leadgen alanı, Callback URL + Verify Token]
4. x-hub-signature-256 (HMAC) doğrulaması
Doğrulama tamamlandıktan sonra Meta her lead’i POST ile gönderir ve her isteği X-Hub-Signature-256 başlığıyla imzalar. Purvisor bu imzayı fail-closed (varsayılan reddet) mantığıyla doğrular: imza geçerli değilse istek hiç işlenmez. Bu, birinin sahte lead’ler enjekte etmesini engeller.
İmza, ham gövdenin META_APP_SECRET ile HMAC-SHA256’sıdır ve sha256= önekiyle gelir. Purvisor aynısını hesaplar ve zamanlama-güvenli (timingSafeEqual) karşılaştırır:
X-Hub-Signature-256: sha256=<hex>
beklenen = "sha256=" + HMAC_SHA256(META_APP_SECRET, ham_gövde)Kendin kontrol etmek istersen (loglardaki bir imzayı doğrulamak için):
# RAW_BODY: webhook'un ham JSON gövdesi (değiştirilmemiş, byte-byte)
printf '%s' "$RAW_BODY" | \
openssl dgst -sha256 -hmac "$META_APP_SECRET" -hex
# çıktı, gelen imzadaki sha256='den sonraki hex ile aynı olmalıPOST doğrulamasının olası sonuçları:
| Durum | HTTP | Gövde |
|---|---|---|
META_APP_SECRET env’de yok | 503 | { "error": "Webhook verification not configured" } |
X-Hub-Signature-256 başlığı yok | 401 | { "error": "Missing signature" } |
| İmza uyuşmuyor | 401 | { "error": "Invalid signature" } |
| İmza geçerli | 200 | { "received": true } |
META_APP_SECRET ayarlanmadan webhook 503 ile tüm istekleri reddeder — bu kasıtlı bir güvenlik önlemidir, hata değil. Önce secret’ı ayarla, sonra Meta’da aboneliği doğrula.
Bir ince nokta: gövde imzayı hesaplamak için ham (raw) okunur. Araya bir proxy/gateway girip JSON’u yeniden serileştirirse (boşluk/sıra değişir) imza tutmaz. Meta ile Purvisor arasındaki gövdeyi hiçbir katman değiştirmemeli.
Uçtan uca kurulum
Meta uygulamasını oluştur
developers.facebook.com’da bir uygulama oluştur, Facebook Login ve Webhooks ürünlerini ekle. App ID ve App Secret’ı not al.
Ortam değişkenlerini gir
Purvisor tarafında META_APP_ID, META_APP_SECRET, META_REDIRECT_URI ve (istersen özel) META_WEBHOOK_VERIFY_TOKEN değerlerini ayarla.
Redirect URI’yi kaydet
Meta panelinde Valid OAuth Redirect URIs alanına https://<alan-adin>/api/integrations/meta/callback gir — META_REDIRECT_URI ile birebir aynı.
Webhook’u bağla ve doğrula
Webhooks → Page altında callback URL https://<alan-adin>/api/integrations/meta/webhook, verify token’ı gir, leadgen alanına abone ol. Meta’nın GET doğrulaması 200 + challenge dönmeli.
İzinlerle bağlan
Panelden Meta / Facebook → Bağla ile OAuth akışını çalıştır; ekran pages_show_list, leads_retrieval, pages_read_engagement isteyecek. Onayla, sayfa/form eşleştirmesini Meta Lead Ads sayfasındaki gibi yap.
Test lead’i gönder
Meta’nın Lead Ads Testing Tool’u ile sahte bir lead gönder; birkaç saniye içinde Kontaklar altında yeni kayıt görünmeli.
KVKK notu
Lead formundaki ad, telefon ve e-posta kişisel veridir ve bu webhook üzerinden Purvisor’a aktarılır. Kendi Meta uygulamanı kullanıyorsan, veri işleyen zincirinde senin uygulaman da yer alır: formda alınan açık rızanın otomatik arama kapsamını da içerdiğinden emin ol ve asistanın açılışta kim olduğunu, neden aradığını net söylesin. Detay: KVKK ve Veri Yönetimi.
Sorun giderme
| Belirti | Olası neden / çözüm |
|---|---|
| Meta “Verify and Save” 403 veriyor | Panel verify token’ı ≠ META_WEBHOOK_VERIFY_TOKEN. İkisini eşitle. |
| Webhook tüm isteklere 503 dönüyor | META_APP_SECRET env’de tanımlı değil (fail-closed). Secret’ı ayarla. |
| Webhook 401 “Invalid signature” | App Secret yanlış/rotasyona uğramış ya da araya giren bir katman gövdeyi değiştiriyor. Secret’ı ve ham gövdenin korunduğunu doğrula. |
OAuth ?error=missing_params / token_failed | Redirect URI üç yerde birebir aynı değil. Kopyala-yapıştır ile eşitle. |
?error=invalid_state | state çerezi süresi doldu (10 dk) veya callback farklı alan adına düştü. Aynı alan adında tekrar dene. |
| Bağlandı ama lead gelmiyor | Webhook leadgen alanına abone değil; ya da uygulaman leads_retrieval için App Review’dan onaysız (development modunda sadece uygulama rolündeki hesaplar test edebilir). |
| Lead geldi ama arama yok | Otomatik arama kapalı, bağlı SIP numarası yok/pasif ya da mesai dışı — Meta Lead Ads sorun gidermeye bak. |