Логин не нужен. Пошаговая настройка Keitaro — раздел 3 ↓. В кабинете то же: Потоки → «Хвосты и трекинг».
https://madpwa.com/postback?subid={external_id}&status={status}
Хвосты, трекинг и интеграции
Практическая документация для кабинета madpwa.com: хвосты, Keitaro, postback и пиксели.
Коротко: как устроена цепочка
Ссылка «С хвостом» из карточки потока
https://madpwa.com/n/{naming_key}?fbp=…&sub1=…&sub3={{campaign.name}}…
/n/…- сохраняем
click_id+fbp/fbc/fbclid - раскрываем макросы, дописываем хвост (если
append_query= Да) - редирект 302 на Campaign URL трекера
В Campaign URL обязательно:
external_id={clickId}
- открывает
/a/{slug} - браузерный пиксель +
POST /api/pwas/{slug}/event - CAPI (FB / Twitter)
- S2S Postback:
https://madpwa.com/postback?subid={external_id}&status=lead|sale
- счётчики leads/deps + CAPI + Web Push
Три ссылки в карточке потока:
| Ссылка | Что это |
|---|---|
| Поток | Чистый /n/{key} без параметров |
| С хвостом | Тот же URL + шаблон query для рекламы |
| Postback | URL для S2S в трекере |
1. Хвосты
Что такое хвост
Хвост — query-строка на ссылке запуска. В неё кладут параметры рекламной сети и свои sub*, чтобы они доехали до трекера и в макросы оффера.
Пример (как в кабинете):
https://madpwa.com/n/nk_xxxxxxxx?fbp=PIXEL&ttp=TTP&sub1=SUB1&sub2=SUB2&sub3={{campaign.name}}&sub4={{adset.name}}&sub5={{ad.name}}
В Facebook/TikTok макросы {{…}} подставляет сама рекламная сеть. На выходе получается обычная строка ?sub3=MyCampaign&….
Куда попадает хвост
- Реклама ведёт на лендинг PWA:
GET /a/{slug}?…(преленд → стор →/go). Прямой оффер без воронки:/n/{key}или/a/{slug}/go. - На
/go(или/n/…) кабинет создаётclick_id, пишет клик в БД (вместе сfbp/fbc/fbclid, если они были в query). - Выбирается URL оффера по правилам потока (GEO / платформа / вес).
- Макросы
{clickId},{sub1},{campaignName}… раскрываются. - Редирект 302 на трекер.
«Добавлять параметры с потока / ссылки запуска» (append_query)
| Режим | Поведение |
|---|---|
| Да (по умолчанию) | К офферу дописываются параметры потока и весь хвост со ссылки запуска. При конфликте ключей побеждает поток / params правила. |
| Нет | Хвост не дописывается целиком. В трекер уходят только макросы, которые явно прописаны в URL оффера ({sub1}, {clickId}…). |
Всегда добавляются служебные: click_id, nk (ключ потока). Params конкретного URL-правила применяются всегда.
Макросы в URL оффера
Пишутся в фигурных скобках:
| Макрос | Откуда берётся |
|---|---|
{clickId} | Наш id клика (для Keitaro → external_id) |
{campaignName}, {adsetName}, {adName} | Из хвоста / UTM-алиасов |
{campaignId}, {adsetId}, {adId}, {accountId} | То же |
{networkSource}, {networkChannel} | utm_source / utm_medium и синонимы |
{country}, {language} | GEO / язык |
{deviceBrand}, {deviceModel}, {osName}, {osVer} | Из UA или хвоста |
{sn_SUBNAME} | Любой ключ хвоста: {sn_sub1} ← sub1=… |
{fd:af_siteid} | AppsFlyer-style: af_siteid / site_id |
Алиасы хвоста (часть списка): utm_campaign → campaignName, utm_source → networkSource, ad_id → adId и т.д. Полный набор — в namings.py (NAMING_MACROS, _INCOMING_ALIASES).
Правила URL в потоке
- Список URL сверху вниз: первое подходящее правило (страны, exclude, платформы
android|ios|desktop|other, логика AND/OR). - Несколько подряд совпавших правил — выбор по весу.
- Замыкающая ссылка (
closing_url) — если ни одно правило не подошло. - Первая подходящая (
save_first_url) — при нескольких совпадениях брать первую подходящую строку (GEO/платформа всё равно учитываются), без розыгрыша по весу.
Типичный оффер для Keitaro:
https://tracker.example/XXXXX?external_id={clickId}&sub1={sub1}&sub2={sub2}&sub3={sub3}
Без external_id={clickId} постбек не склеит конверсию с кликом.
Код
| Файл | Роль |
|---|---|
namings.py | Схема, макросы, build_redirect, GEO-роутинг |
app.py | GET /n/{key}, GET /a/{slug}/go |
static/cabinet.js | Карточка потока, копирование хвоста / postback |
2. Трекинг
2.1 Клик и атрибуция
| Эндпоинт | Назначение |
|---|---|
GET /n/{key} | Редирект по потоку |
GET /a/{slug}/go | То же через PWA (если привязан поток) |
В таблице clicks сохраняются: click_id, slug, IP, UA, fbp, fbc, fbclid, naming_key.
Этот click_id и есть то, что трекер должен вернуть в постбеке как subid (через external_id в Campaign URL).
2.2 S2S Postback
Формат как у Skak (полный) или минимальный:
GET /postback?subid={external_id}&tid={tid}&status={status}&payout={conversion_revenue:usd}&sale_status=sale,dep,ftd,deposit,approved&lead_status=lead,reg¤cy=usd
GET /postback?subid={external_id}&status={status}&payout=…|sum=…|amount=…
status (или через sale/lead_status) | Что делаем |
|---|---|
lead, reg, registration | +1 lead, событие reg, CAPI reg |
sale, dep, deposit, purchase, ftd, approved | +1 dep, событие dep, CAPI dep |
Дополнительно: Web Push по slug PWA, запись в stats_events, CAPI с сохранёнными fbp/fbc/fbclid клика.
В Keitaro → Source → S2S Postback — та же схема, что Skak, хост madpwa.com. Подробный копипаст: §3.
{external_id} в Keitaro — это наш click_id.
2.3 Пиксели в браузере + клиентские события
На store / preland / white (по настройкам) в <head> попадает HTML из metrics.head_html().
| Канал | Браузер | Сервер (CAPI) |
|---|---|---|
fbevents.js или 1×1 img (pixel_as_img) | Graph /{pixel_id}/events | |
| Twitter/X | uwt.js | Ads API measurement/conversions |
| TikTok | Нет своего Pixel SDK | Только прокидывание ttclid/ttp на оффер при tiktok_source |
Клиентский скрипт (landings.install_script):
ping('install'|'clicks'|'leads')→POST /api/pwas/{slug}/eventfbq('track', …)/twq(…)сeventID- читает cookies
_fbp,_fbc, queryfbclid
Карта событий по умолчанию (настраивается на PWA):
| Этап воронки | FB-событие по умолчанию |
|---|---|
| Install | Lead |
| Reg | CompleteRegistration |
| Dep | Purchase |
Пиксели задаются в карточке PWA: fb_pixels (pixel_id + access token), tw_pixels (Track ID + API key). Без токена — только браузер; с токеном — ещё и CAPI.
2.4 Лог «События Ads»
- Отправка CAPI в фоне (
metrics.fire) - Лог:
data/metrics-capi-log.jsonl(или путь изPWA_METRICS_LOG) - Кабинет: список через
GET /api/ads-events, тест —POST /api/pwas/{id}/metrics/test
2.5 Статистика воронки
stats.py — виды: visit, open, install, reg, dep, push_*. На install списывается CPI (CPI_CENTS, по умолчанию 2 цента = $0.02).
2.6 Клоака
cloak.py: боты / VPN / hosting → white-страница. Страна: заголовок Cloudflare CF-IPCountry или ip-api.com. Настройки PWA: bot_hosting, bot_proxy, tiktok_source, pixel_on_white, white_url и др.
3. Как настроить Keitaro (как у Skak)
Схема та же, что у Skakapp: реклама → наш `/n/…` → Keitaro → оффер → S2S postback → нам. Мы не шлём конверсии в Keitaro — Keitaro шлёт их нам на /postback.
madpwa ≈ Skak: что совпадает
| Skak | madpwa | |
|---|---|---|
| Клик в Ads | их launch / naming | https://madpwa.com/n/{key}?… («С хвостом») |
| В Keitaro External ID | param external_id = {clickId} | то же |
| S2S Postback | https://uclient.skakapp.com/postback?subid={external_id}&… | https://madpwa.com/postback?subid={external_id}&… |
| Склейка | subid ← {external_id} ← наш click_id | то же |
| Lead / Sale | lead_status / sale_status списки | поддерживаем те же списки |
Отличия: другой домен postback; у Skak ещё from=client_ID_SKAK (у нас не нужен). Остальное можно копировать 1-в-1.
Готовые ссылки (копипаст)
1) Keitaro → Edit Source → S2S postback
Как у Skak, только хост наш:
https://madpwa.com/postback?subid={external_id}&tid={tid}&status={status}&payout={conversion_revenue:usd}&sale_status=sale,dep,ftd,deposit,approved&lead_status=lead,reg¤cy=usd
Минимальный вариант:
https://madpwa.com/postback?subid={external_id}&status={status}
Send only statuses: Lead + Sale (как на скрине Skak).
| Query | Кто подставляет | Зачем |
|---|---|---|
subid={external_id} | Keitaro | наш click_id (обязательно) |
status={status} | Keitaro | lead / sale / … |
payout={conversion_revenue:usd} | Keitaro | сумма → FB Purchase CAPI |
tid={tid} | Keitaro | пишется в лог postbacks (опционально) |
sale_status=… | константа | какие status считать депозитом |
lead_status=… | константа | какие status считать регистрацией |
currency=usd | константа | валюта CAPI |
2) Keitaro → Edit Source → Parameters (шаблон как Skak)
В колонке Parameter / Placeholder — то, что Keitaro допишет к Campaign URL. Справа — макросы madpwa (их раскроет наш /n/… при редиректе на трекер).
| Name | Parameter | Placeholder or value |
|---|---|---|
| External ID | external_id | {clickId} |
| Ad Campaign ID | ad_campaign_id | {campaignId} |
| Site | source | {networkSource} |
| Sub 1 | sub1 | {sn_sub1} |
| Sub 2 | sub2 | {sn_sub2} или свой BUYER_ID |
| Sub 3 | sub3 | {sn_sub3} |
| Sub 4 | sub4 | {sn_sub4} |
| Sub 5 | sub5 | {sn_sub5} |
| Campaign name | campaign_name | {campaignName} |
| App number | app_num | {appNum} |
| App bundle | app_bundle | {appBundle} |
| Adset ID | adset_id | {adsetId} |
| Adset name | adset_name | {adsetName} |
| Ad ID | ad_id | {adId} |
| Ad name | ad_name | {adName} |
| Network channel | network_channel | {networkChannel} |
| Organic | is_organic | {isOrganic} |
| GAID | gaid | {gaid} |
| Back Url | isBackUrl | 0 |
| Pixel Facebook | fbp | {sn_fbp} |
| Pixel TikTok | ttp | {sn_ttp} |
| OS name | os_name | {osName} |
| OS ver | os_ver | {osVer} |
| Language | language | {language} |
| Country | country | {country} |
| FB click | fbclid | {sn_fbclid} |
Критично: строка External ID = external_id / {clickId} — без неё postback не склеится.
3) Кабинет → поток → URL оффера
Вставьте Campaign URL из Keitaro (после сохранения Source параметры уже в шаблоне). Должно получиться примерно так:
https://ВАШ-ТРЕКЕР/XXXXX?external_id={clickId}&source={networkSource}&ad_campaign_id={campaignId}&sub1={sn_sub1}&sub2={sn_sub2}&sub3={sn_sub3}&sub4={sn_sub4}&sub5={sn_sub5}&campaign_name={campaignName}&fbp={sn_fbp}&fbclid={sn_fbclid}&country={country}&os_name={osName}
«Добавлять параметры» = Да.
4) Реклама — только «С хвостом»
https://madpwa.com/n/nk_xxxxxxxx?fbp=PIXEL_ID&ttp=TTP&sub1=SUB1&sub2=BUYER&sub3={{campaign.name}}&sub4={{adset.name}}&sub5={{ad.name}}
{{…}} — макросы FB/TikTok. Нельзя кидать в Ads сырой Campaign URL Keitaro.
Что куда (кратко)
| Где | Что |
|---|---|
| Keitaro Source → S2S | postback madpwa (блок выше) |
| Keitaro Source → Parameters | таблица External ID + subs (как Skak) |
| Кабинет → поток → оффер | Campaign URL с external_id={clickId} |
| Ads | «С хвостом» /n/… |
| PWA | привязать поток + Pixel + Access Token |
Шаг за шагом
- Keitaro → Sources → New / Edit
- S2S postback = ссылка madpwa из блока «Готовые ссылки». - Send only: Lead + Sale. - Parameters: External ID → external_id = {clickId} (+ остальные по таблице).
- Кампания Keitaro на этом Source → скопировать Campaign URL.
- Кабинет → Потоки → в оффер вставить Campaign URL; append_query = Да; сохранить.
- PWA → выбрать поток; Метрики → pixel + token.
- В Ads — «С хвостом».
- Прогон теста (ниже).
Как прогнать тест (когда всё добавили)
A. Ручной тест postback (30 секунд)
- Открой ссылку «С хвостом» из карточки потока (или чистый
/n/ключ) в браузере. - DevTools → Network → найди 302 на трекер. В URL скопируй значение
external_id=(это нашclick_id). - В новой вкладке открой (подставь свой id):
https://madpwa.com/postback?subid=СКОПИРОВАННЫЙ_EXTERNAL_ID&status=lead
Должно вернуть {"ok":"1"}.
- Для депозита:
https://madpwa.com/postback?subid=СКОПИРОВАННЫЙ_EXTERNAL_ID&status=sale&payout=10¤cy=usd
- Проверь в кабинете:
- у PWA вырос leads / deps; - раздел События Ads — строка CAPI (если есть Access Token у пикселя).
Без живого клика (external_id из шага 2) postback придёт, но не привяжется к PWA — счётчики не вырастут.
B. Тест из Keitaro
- Сделай тестовый клик по «С хвостом» → клик появится в Keitaro с External ID.
- В Keitaro на этом клике / конверсии отправь тестовый Lead (или Conversion → Lead).
- Keitaro дернет наш S2S URL сам.
- Снова проверь счётчики + «События Ads».
C. Тест пикселя без Keitaro
В карточке PWA → Метрики → кнопка Тест (install / reg / dep) — шлёт CAPI напрямую. Это проверка token/pixel, не склейки с трекером.
Маппинг status → события
status (или из sale/lead_status) | Кабинет | FB по умолчанию |
|---|---|---|
lead, reg, registration | lead / reg | CompleteRegistration |
sale, dep, deposit, purchase, ftd, approved | dep | Purchase |
Если в postback заданы sale_status=… и lead_status=… — кабинет смотрит на эти списки (как Skak).
Частые ошибки
| Ошибка | Симптом |
|---|---|
Нет external_id={clickId} в Parameters / оффере | Postback есть, клик не находится |
В postback subid={subid} вместо {external_id} | Пустой/чужой subid |
| В Ads — Campaign URL Keitaro | Кабинет не создал click_id |
| Пиксель без Access Token | CAPI с postback молчит |
Sub6 с параметром sub5 (дубль как на части скринов Skak) | Затирает sub5 — лучше sub6 / {sn_sub6} |
Короткий чеклист
- Source S2S = madpwa postback (Skak-формат).
- Parameters:
external_id={clickId}. - Поток: Campaign URL + append_query Да.
- Ads: только «С хвостом».
- Тест postback
status=lead.
4. Интеграции
Реклама и атрибуция
| Интеграция | Назначение | Как подключена | Что настроить |
|---|---|---|---|
| Keitaro | Трекер (основной сценарий) | Campaign URL в оффере + S2S /postback | external_id={clickId} в URL; postback с {external_id} → subid |
| Facebook Pixel + CAPI | PageView, install/reg/dep | Браузерный скрипт + Graph API | В PWA: fb_pixels (id + token), события, Domain Verify; env PWA_FB_GRAPH |
| Twitter/X Pixel + CAPI | Браузер + Conversions API | uwt.js + Bearer API | В PWA: tw_pixels; env PWA_TW_CAPI |
| TikTok | Параметры клика + фильтр ботов | ttclid/ttp на оффер; tiktok_source в клоаке | Тогл в настройках PWA. Отдельного TikTok Pixel/CAPI нет |
| UTM / макросы FB | Имена кампаний/адсетов в хвосте | Алиасы в namings.py | Ключи в ссылке запуска |
| AppsFlyer-style | {fd:af_siteid} | Алиас query | af_siteid / site_id в хвосте |
Любой трекер с S2S и external_id работает по той же схеме, что Keitaro. Отдельной интеграции Binom в коде нет.
Пуши и мессенджеры
| Интеграция | Назначение | Как | Настройка |
|---|---|---|---|
| Web Push (VAPID) | Нативные пуши PWA | pywebpush + Service Worker | data/vapid.json, env VAPID_MAILTO |
| OneSignal | Опциональный SDK | CDN в <head> | onesignal_on, onesignal_app |
| Push.express | Опциональный пуш | cdn.push.express/auto.js | push_express_on, push_express_app (+ поле key в настройках) |
| Extendy | Partner push | cdn.extendy.net/partner.js | extendy_on, extendy_id |
| Telegram Login | Вход в кабинет | POST /api/auth/telegram | TELEGRAM_BOT_TOKEN, TELEGRAM_BOT_NAME |
Домены и инфраструктура
| Интеграция | Назначение | Как | Настройка |
|---|---|---|---|
| Cloudflare | Зоны, A-записи, custom hostnames | cloudflare_cf.py | CF_API_TOKEN, CF_ACCOUNT_ID, опционально CF_SAAS_ZONE_ID, PWA_PUBLIC_IPS |
| Namecheap | Проверка/покупка доменов | XML API (registrar.py) | REGISTRAR_PROVIDER=namecheap, NAMECHEAP_* |
| Porkbun | То же | JSON API | REGISTRAR_PROVIDER=porkbun, PORKBUN_* |
| RDAP | Доступность без ключей регистратора | HTTP | — |
| ip-api.com | Страна / proxy / hosting для клоаки | cloak.lookup_ip | Публичный API |
| Bypass URL | Обход клоаки (bypass-ключ) | HMAC _bypassKey | PWA_BYPASS_SECRET, PWA_BYPASS_TTL |
Прочее
| Что | Примечание |
|---|---|
| Шаблоны Google Play / App Store | Только UI лендинга, не API консолей |
custom_js | Произвольный JS на store-странице |
| CRM wteam.app | Отдельный продукт — не делить nginx/БД/CF с PWA |
5. Переменные окружения
| Переменная | Область |
|---|---|
CPI_CENTS, ADMIN_USER, ADMIN_PASSWORD | Биллинг / вход |
CABINET_HOSTS, PWA_PUBLIC_ORIGIN, PWA_PUBLIC_IPS, PWA_SKIP_DNS, PORT | Хостинг |
TELEGRAM_BOT_TOKEN, TELEGRAM_BOT_NAME | Telegram |
VAPID_MAILTO | Web Push |
CF_API_TOKEN, CF_ACCOUNT_ID, CF_SAAS_ZONE_ID | Cloudflare |
REGISTRAR_PROVIDER, NAMECHEAP_*, PORKBUN_* | Домены |
PWA_FB_GRAPH, PWA_TW_CAPI, PWA_METRICS_LOG, PWA_METRICS_SINK | Метрики |
PWA_BYPASS_SECRET, PWA_BYPASS_TTL | Bypass клоаки |
На проде секреты: /etc/pwa-cabinet.env (см. deploy/pwa-cabinet.service). Пиксели, потоки, токены CAPI — в SQLite (pwas, namings), не в env.
6. Словарь RU ↔ код
| В кабинете | В коде |
|---|---|
| хвост / С хвостом | launch tail, query pass-through |
| поток | namings, naming_key, /n/… |
| Добавлять параметры… | append_query |
| Замыкающая ссылка | closing_url |
| оффер / трекер | offer_url / Campaign URL |
| постбек | /postback |
| пиксель / CAPI | pixel / Conversions API |
| События Ads | ads-events log |
| клоака / white | cloak.py / white page |
| метрики | metrics.py |
7. Ключевые файлы
| Файл | Тема |
|---|---|
namings.py | Хвосты, макросы, редирект |
metrics.py | Пиксели, CAPI, лог |
landings.py | Клиентский трекинг, шаблоны |
cloak.py | Фильтры трафика |
stats.py | Воронка |
settings.py | Тоглы PWA (TikTok, пуши, пиксель на white…) |
cloudflare_cf.py | Cloudflare |
registrar.py | Namecheap / Porkbun |
bypass.py | Обход клоаки |
app.py | /n/…, /postback, /event, API |
static/cabinet.js | UI потоков и метрик |
https://madpwa.com/docs/tracking · алиас /docs/keitaro