# GDPR Broker Bot: návod pro AI agenta > Zdroj: https://ongy.cz/pages/ai/gdpr/ > Autor: Ongy (ongy.cz). Lokální Python bot, který rozesílá žádosti podle GDPR firmám obchodujícím s osobními daty, čte odpovědi, hlídá lhůty a z přiznaných příjemců dělá další cíle. Bez externích knihoven, každou dávku schvaluju sám. ## Pro agenta Pomoz uživateli postavit vlastní verzi tohohle projektu. Nejdřív se ho zeptej na vybavení a na to, co z požadavků už má. Pak postupuj po krocích a po každém kroku s ním ověř, že funguje, než půjdeš dál. Hodnoty v `` doplň s uživatelem, nikdy si nevymýšlej adresy, hesla ani tokeny. Kód autora není veřejný: tohle je popis řešení, ne repozitář ke stažení. ## Cíl Lokální bot, který pomáhá uživateli vykonávat jeho vlastní práva subjektu údajů vůči data brokerům: žádost o přístup podle čl. 15 GDPR (včetně zdroje dat a příjemců) a teprve potom výmaz podle čl. 17. Žádosti připraví, odešle až po výslovném schválení člověkem v Telegramu, čte odpovědi, hlídá měsíční lhůty a přiznané příjemce nabídne jako další cíle ke kontrole. U firem, které lhůtu nedodrží, sestaví důkazní spis a návrh stížnosti, kterou podává uživatel sám. ## K čemu to je Data broker je firma, kterou jsi nikdy neoslovil, a přesto o tobě má složku. Kupuje údaje, skládá je a prodává dál. Jsou jich stovky a seznam „kdo má ta moje“ neexistuje. GDPR mi dává právo se každé zeptat, co o mně má, odkud a komu to předala. A pak chtít výmaz. Ručně je to práce na týdny. Tak jsem si napsal bota. Rozesílá žádosti, čte odpovědi, hlídá lhůty a u firem, které mlčí, skládá podklady pro stížnost na úřad. ## Proč právě takhle Zkusil jsem to ručně. Pár mailů, tabulka, hlídání lhůty. Po týdnu jsem ztratil přehled a po měsíci chuť. Přitom je to práce pro stroj: šablona, odeslat, zapsat, počkat, připomenout. Chtěl jsem jen rozhodovat, co odejde mým jménem. ## Jak to funguje - **Nejdřív přístup, výmaz až potom.** Žádost o přístup nutí firmu přiznat zdroj i příjemce dat. Při výmazu by smazala dřív, než řekne, kudy data tečou. - **Nic neodejde bez mého souhlasu.** Bot připraví dávku, pošle souhrn do Telegramu a čeká na moje ano. Stížnost na úřad je vždy ruční. - **Přiznaní příjemci jsou nové cíle.** Claude z odpovědi vytáhne, komu firma data předala. Každá se přidá do fronty ke schválení. - **Lhůty hlídá bot.** Po třiceti dnech bez odpovědi připraví urgenci. Když firma mlčí dál, sestaví podklady pro stížnost. ## Stack a běh - **Jádro:** Python 3.12, jen standardní knihovna: `smtplib`, `imaplib`, `sqlite3`. Žádné `pip install`, vlastní mini `.env` loader. Běží na home serveru. - **E-mail:** Samostatná schránka jen pro GDPR. SMTP odesílá, IMAP čte. Párování odpovědí přes `Message-ID`, detekce bounce i automatického potvrzení. Přeposlaný mail se páruje podle obsahu. - **AI vrstva:** Claude Sonnet přes vlastní API klíč, jediné místo s AI. Structured output: zdroj, příjemci, drží/nedrží. Před odesláním redakce PII: známé údaje nahrazeny značkami jako `[EMAIL]`, `[PHONE]`. - **Data a provoz:** SQLite: brokeři, žádosti, odpovědi, lhůty, stav. Cron denně: stáhnout odpovědi, vyřetězit příjemce, přepsat report. V pondělí navíc lhůty a follow-upy. Approval gate přes Telegram. ## Životní cyklus žádosti | Stav | Co to znamená | Co bot udělá | |---|---|---| | odesláno | čl. 15 odešel, běží 30 dní | zapíše deadline, čeká | | potvrzeno | automatické „máme to“ | hlásí do Telegramu, lhůta běží dál | | věcná odpověď | firma řekla, co má a komu dala | Claude vytáhne zdroj a příjemce, ti jdou do fronty; pokud drží data, připraví čl. 17 | | nedoručeno | bounce | hlásí do Telegramu, kontakt hledám ručně | | po lhůtě | 30 dní bez věcné odpovědi | připraví urgenci ke schválení | | mlčí dál | ani po urgenci nic | vyexportuje spis a draft stížnosti; odeslání je vždy ruční | Spis obsahuje časovou osu, Message-ID, data a lhůty, doslovné citace z odpovědí, AI rozbor a shrnutí porušení. ## Skóre rizika Body přičítá za to, že firma data drží, že je předala dál (a kolika příjemcům), že ignoruje lhůtu nebo žádost odmítla. Automatické potvrzení příjmu bez věcné odpovědi je slabý, ale nenulový signál. Výsledek řadí brokery do tří pásem a určuje, komu jde urgence první. Extrakce z odpovědí jede přes Claude, klíčová slova zůstala jen jako fallback bez API. ## Co budeš potřebovat - Žádosti jen za sebe a o vlastní osobní údaje. Nikdy z cizí identity ani jménem jiného člověka bez jeho plné moci. - Stále běžící stroj s Pythonem 3.12 a cronem (autor: domácí server, jen standardní knihovna Pythonu). Volitelně Docker pro Telegram démona. - Samostatná e-mailová schránka jen pro GDPR komunikaci se SMTP a IMAP a heslem aplikace: `` / `` (autor: dedikovaný Gmail). Osobní schránka zůstane čistá a korespondence je pohromadě jako důkaz. - Vlastní Telegram bot jen pro tento projekt `` a ID chatu `` pro schvalování. - Volitelně Claude přes API `` na čtení odpovědí (autor: Claude Sonnet, jediné místo s AI, zbytek běží bez něj). - Seznam cílů s ověřenými kontakty pro ochranu osobních údajů (e-mail pověřence nebo privacy týmu ze zásad zpracování na webu firmy). Bez ověřeného kontaktu se nic neposílá. - Základní orientace v GDPR: čl. 12 (lhůta 1 měsíc, zdarma, prodloužení jen odůvodněně), čl. 15, 17 a 21, a přístup k podání u dozorového úřadu (autor: ÚOOÚ přes datovou schránku). ## Postup ### 1. Schránka, konfigurace a identita Vytvoř samostatnou schránku se SMTP a IMAP a heslem aplikace. Do `.env` s právy 600 mimo git dej přístupy ke schránce, Telegramu a API a identitu pro žádosti: jméno, rok narození, zemi a město a e-mailové adresy, ke kterým chceš data dohledat. Zvlášť veď seznam údajů, které nikdy nesmí odejít (``, třeba telefon, pracovní e-mail nebo celé datum narození ve všech zápisech). Vlastní načítání `.env` ať přebíjí proměnné prostředí, jinak si bot může vzít cizí klíč, který v prostředí už visí. ### 2. Datový model SQLite: `brokers` (název, kategorie source-leak, people-search, aggregator, b2b, chain; metoda email nebo webform; kontakt; stav ready, verify, active, done, skip; poznámky), `requests` (broker, typ access, erasure, access_erasure, followup, reply; komu, kopie, předmět, tělo, Message-ID, odesláno, lhůta; stav queued, sent, replied, overdue, bounced, done), `responses` (žádost, přijato, odesílatel, Message-ID, klasifikace, plné tělo), `extractions` (odpověď, stav, drží data, shrnutí, příjemci jako JSON) a `meta` (poslední zpracované IMAP UID, offset Telegramu). Když do databáze sahá cron i démon zároveň, zapni WAL a `busy_timeout`. ### 3. Cíle a jejich ověření Seznam importuj z CSV. Každý nový cíl dostane stav `verify` a do `ready` ho přepne člověk až po kontrole kontaktu v aktuálních zásadách zpracování firmy. Import ani rozšíření seznamu nikdy nic neodešle. Firmy, které přijímají žádosti jen webovým formulářem, označ k ručnímu vyřízení a captchy neobcházej. Sestavení dávky přeskočí každou firmu, která už má žádost v jakémkoli stavu, takže nevznikají duplicity ani opakované obtěžování. ### 4. Šablony a pořadí žádostí Nejdřív žádost o přístup (čl. 15): potvrzení, zda údaje zpracovávají, jejich kopie, zdroj (čl. 15 odst. 1 písm. g) a příjemci (čl. 15 odst. 1 písm. c), s odkazem na lhůtu podle čl. 12 odst. 3. Výmaz (čl. 17) přidej do fronty až ve chvíli, kdy odpověď potvrdí, že data drží, jinak firma smaže dřív, než řekne, komu je předala. Kombinovanou žádost použij tam, kde mapa toku dat nemá cenu (autor: people-search a B2B). V žádosti uveď jen minimum identifikátorů potřebných k dohledání. U firem s profesními profily autorovi pomohl odkaz na veřejný profil místo telefonu nebo pracovního e-mailu. Šablony stačí s proměnnými `{{var}}` a podmínkami `{{#if}}`. ### 5. Schválení a odeslání `build` uloží žádosti se stavem `queued`, `review` vypíše celé znění. Odeslání pošle do Telegramu souhrn dávky (komu, typ, předmět) a čeká na výslovné ano k této konkrétní dávce, bez něj neodejde nic. Těsně před odesláním projdi každý dopis, i ručně psané odpovědi, proti seznamu údajů, které nesmí odejít, a nevyhovující dopis zahoď s hláškou. Posílej pomalu (autor: výchozí 4 zprávy za minutu), s vlastním Message-ID a lhůtou 30 dní od odeslání. Měj i režim `--dry-run`. Ovládání z telefonu řeší jeden démon, který jako jediný čte zprávy z Telegramu (autor: `/stav`, `/fronta`, `/nahled`, `/odeslat`, `/lhuty`). ### 6. Čtení odpovědí Jednou denně stáhni přes IMAP všechny zprávy novější než poslední zpracované UID. Párování k žádosti: nejdřív `In-Reply-To` a `References` proti vlastnímu Message-ID, pak doména odesílatele proti doméně firmy, u přeposlaného mailu obsah těla (vlastní domény z tohoto kroku vyřaď). Nedoručení označ `bounced` a pošli upozornění, kontakt pak hledá člověk. Automatické potvrzení příjmu lhůtu nezastavuje, žádost zůstává `sent`. ### 7. Rozbor odpovědí přes Claude Před odesláním do API nahraď přesné shody vlastních identifikátorů značkami jako `[EMAIL]` a `[PHONE]`, údaje třetích stran nech. Použij structured output se schématem: stav z výčtu has_data, no_data, refused, needs_id, erased, acknowledged, other; drží data ano nebo ne; krátké shrnutí; příjemci s názvem, kontaktem a vztahem sold_to, shared_with, source, processor, other. Stav žádosti posouvej jen podle nejnovější odpovědi. Přiznané příjemce přidej jako nové cíle s kategorií `chain` a stavem `verify` a dej vědět do Telegramu, nic se jim neposílá bez ověření a schválení. Po každém běhu pošli souhrn nových odpovědí česky. ### 8. Lhůty, urgence a důkazy Jednou týdně označ žádosti po lhůtě jako `overdue` a připrav urgenci do fronty ke schválení, jen pokud k firmě neběží jiná vlastní lhůta. Když nepřijde věcné vyřízení ani po urgenci, vygeneruj důkazní spis (časová osa, Message-ID, data odeslání a lhůt, doslovné citace odpovědí, rozbor a shrnutí možného porušení konkrétních článků) a návrh stížnosti. Eskalace záměrně není v cronu a podání dělá uživatel sám svým jménem. Adresu a datum narození, které úřad k podání vyžaduje, vkládej jen do stížnosti, nikdy do dopisů firmám. ### 9. Provoz a reporty Cron denně: stažení odpovědí, rozbor, report a důkazní spisy. V pondělí: kontrola lhůt a týdenní přehled do Telegramu i v týdnu, kdy se nic nestalo, jinak ticho v chatu vypadá jako porucha. Reporty ve dvou verzích: veřejná bez osobních údajů a soukromá s kompletním auditem. Každé odeslání a každou změnu stavu zapisuj do logu. ## Na co si dát pozor - Telegram drží nevyzvednuté zprávy zhruba 24 hodin. Po restartu démona by se staré „/odeslat“ a „ano“ zpracovaly jako čerstvý souhlas a odeslaly poštu. Při studeném startu backlog zahoď bez zpracování, offset ukládej do databáze a čekající schválení drž jen v paměti. - Dva procesy čtoucí `getUpdates` jednoho tokenu dostanou `HTTP 409 Conflict`. Čte jen démon, ostatní příkazy schvalování přes chat nabídnou jen tehdy, když démon neběží (autor: otisk života démona v databázi, starý nejvýš 90 s). - Šablony údaje hlídají, ručně psaná odpověď do rozběhnuté komunikace ne. Autorovi takhle jednou odešel údaj, který dávat nechtěl. Kontrola zakázaných hodnot musí běžet v odesílání, ne v šablonách. - Oříznutý text odpovědi kazí klasifikaci, ne jen detail: autorovi uřízl limit 1000 znaků větu uprostřed věcné odpovědi a model rozhodoval podle poloviny. Ukládej plné tělo a zkracuj až při volání API. - Model jako „příjemce“ vrací i vlastní mateřskou firmu nebo zástupce v EU a jako „zdroj“ veřejný profil samotného subjektu. Takové nálezy filtruj. Vlastní odeslané odpovědi uložené v tabulce odpovědí do rozboru nepouštěj, jinak rozhodí stav žádosti. - Hledání příjemců podle klíčových slov chytá citace tvého vlastního dopisu, které firmy vkládají do odpovědí. Autor tuhle heuristiku zrušil a příjemce bere jen z rozboru modelem. - IMAP filtr `UNSEEN` přeskočí zprávy, které sis mezitím přečetl v mobilu. Pamatuj si poslední UID a `UIDVALIDITY` a ber vše novější. - Před stížností ověř, pod který dozorový úřad firma spadá (britský správce patří pod ICO a UK GDPR, ne pod ÚOOÚ), a že komunikace je vyčerpaná. Odmítnutí nesmí z přehledu kandidátů tiše vypadnout, zobraz ho k ručnímu posouzení. ## Jak ověřit, že to funguje - [ ] `send --dry-run` vypíše celou dávku a ve složce Odeslané nepřibude nic. - [ ] Bez „ano“ v Telegramu neodejde žádný e-mail. Po restartu démona se staré „ano“ z historie chatu nezpracuje a počet odeslaných zůstane stejný. - [ ] Testovací dopis s hodnotou ze seznamu zakázaných údajů se při odeslání zahodí s hláškou a zbytek dávky odejde. - [ ] Testovací cíl s tvou druhou adresou: odeslaná žádost má uložené Message-ID a lhůtu přesně 30 dní od odeslání. Odpověď z té adresy se při dalším stažení spáruje ke správné žádosti. - [ ] Přeposlaná odpověď (forward z jiné schránky) se spáruje ke správné žádosti. - [ ] Žádost na neexistující adresu skončí ve stavu `bounced` a do Telegramu přijde upozornění. - [ ] Automatické potvrzení příjmu dostane klasifikaci `acknowledged`, žádost zůstane `sent` a lhůta se nezmění. - [ ] Text poslaný do API (zalogovaný pro test) neobsahuje tvé jméno ani e-mail, jen značky. - [ ] Dvojí spuštění `build` nevytvoří duplicitní žádosti a opakované `track` vytvoří k firmě po lhůtě nejvýš jednu urgenci. - [ ] `grep` na tvé jméno, e-maily a rok narození ve veřejném reportu vrátí 0 výsledků. ## Přizpůsobení - Jen služby, kde máš účet nebo kde uniklo tvé heslo (například podle Have I Been Pwned): stejná smyčka, jen kratší seznam. Na veřejně kolující seznamy uniklých hesel bez správce GDPR nedosáhne, tam pomůže jen unikátní heslo a dvoufázové ověření. - Bez AI: klasifikace odpovědí podle klíčových slov (autor ji má jako zálohu) a příjemce doplňuješ ručně. Počítej s víc chybami a vše důležité kontroluj očima. - Webové formuláře people-search služeb: Playwright s ručním dokončením u captchy. Autor to má jako další fázi, zatím hotové není. - Schvalování jinak než v Telegramu: potvrzení v terminálu nebo e-mailem. Princip jedno výslovné ano na konkrétní dávku zůstává. --- Stránka projektu s fotkami a diagramem: https://ongy.cz/pages/ai/gdpr/