Komunikační brána MenuBot
SMS běží přes SMSGate Android. Nejnovější požadavek mění směr WhatsAppu: připravit oficiální Meta Cloud API pro vlastní účet s co nejmenším schvalováním. Meta účet, číslo ani token nejsou připojené; aktivní číslo v WhatsApp aplikaci se nesmí převést bez výslovného rozhodnutí. Hovory jsou odložené.
Orientační přímé ceny pro české číslo (+420), stav 29. 10. 2026
- SMSGate Android app/API: zdarma; SMS se řídí tarifem operátora na SIM.
- WhatsApp Business App: zdarma pro ruční práci; nemá serverové Cloud API ani automatický webhook.
- Meta Cloud service odpovědi: prvních 1 000 doručených zpráv měsíčně na jedno firemní číslo zdarma, potom €0,0175 za zprávu.
- Meta Cloud utility a authentication šablony: €0,0175 za doručenou zprávu.
- Meta Cloud marketing šablony: €0,0712 za doručenou zprávu.
- Příchozí zprávy uživatel→firma jsou zdarma. Meta účtuje jen doručené zprávy firmy; sazby se mohou měnit a existují zvláštní bezplatná okna.
Sazby Meta jsou k 1. 10. 2026 pro Rest of Central & Eastern Europe. Bezplatná aplikace WhatsApp Business není automatická alternativa k Cloud API. Neoficiální automatizaci WhatsApp Web nepoužívat.
Další kroky – přesné pořadí při návratu k práci
A. Serverové kroky bez telefonu – nic neposílají
- **Zpřístupnit aktuální dokumentaci.** Nejnovější úpravy `mbsmd.md` a `api-manual.md` jsou zatím v pracovním stromu; po synchronizaci ověřit veřejný index s novým cache-bust parametrem. Před API testem porovnat i nasazení `api.php`, `sdk/php/SmsGatewayClient.php`, `../app/api/API-bridge.php` a `../app/lib/api/API-sms-inbound.php`. Synchronizovat jen soubory, jejichž obsah se liší. Migrace SMS 001/002 i tabulka app inboxu už existují; žádnou z nich znovu nespouštět.
- **Ověřit API bez SMS.** Po synchronizaci spustit PHP lint změněných souborů. Vytvořit jeden testovací API klíč, uložit ho pouze do souboru přístupného rootovi a ověřit autorizované `GET ?op=status` a `GET ?op=inbound&channel=sms`. Tělo odpovědi s čísly/texty ani klíč neposílat do chatu. Tento test nic neodesílá a lze ho udělat před nákupem SIM.
- **Dokončit SMS push receiver.** App inbox tabulka je už potvrzená (`table_count=1`, `column_count=10`); DDL neopakovat. Do chráněné konfigurace doplnit `inbound_webhook_url=https://app.menubot.cz/api/?bridge=sms-inbound` a nový náhodný `inbound_webhook_signing_key`, stejný pro odesílatele i receiver. Ověřit pouze přítomnost hodnot a spustit `webhook-worker.php --check`. GET receiveru má vracet 405; podepsaný POST otestovat až jako jeden jasně označený syntetický event, bez SMS.
B. Až bude připravený Android telefon a SIM – SMS
- **Zkontrolovat číslo a podmínky operátora.** Ověřit, že SIM přijme běžné SMS i hovory a má datové připojení. Tesco Mobile VOP účinné od 1. 7. 2026 uvádějí, že umělé nebo automatické generování zpráv může být zneužitím výhod tarifu. Před jakýmkoli API odesláním vyžádat písemné potvrzení, že konkrétní tarif dovoluje automatické transakční SMS přes SMS bránu; bez potvrzení z této SIM automaticky neposílat. Pro zamýšlené přímé WhatsApp Cloud API nepřihlašovat toto číslo do WhatsApp Messenger ani Business App. Pokud je číslo už ve WhatsApp registrované, nic nemazat ani nemigrovat; zastavit se a použít jiné číslo, nebo zvlášť řešit složitější Coexistence.
- **Připravit Huawei pouze pro laboratorní test.** Huawei P smart 2021 (PPA-LX2) má Android 10/EMUI 10.1.1 a bezpečnostní záplatu z 1. 8. 2022. SMSGate uvádí minimum Android 5; telefon bez Google Play Services musí používat SMSGate Cloud `SSE Only`. Instalovat pouze standardní zabezpečenou APK z oficiálního SMSGate vydání, povolit `SEND_SMS`, `RECEIVE_SMS` a podle výběru SIM `READ_PHONE_STATE`. V EMUI povolit automatické spuštění, sekundární spuštění a běh na pozadí. Kvůli více než čtyři roky staré bezpečnostní záplatě nepoužívat tento telefon pro zákaznický provoz ani na něm neukládat zákaznické SMS; pro produkci nejprve zajistit aktuálně bezpečnostně podporovaný Android. Bez Google Play se aktualizace instalují ručně.
- **Nastavit SMSGate na serveru.** Do `/etc/menubot-sms/config.php` přidat Cloud username/password získané z aplikace, náhodný `smsgate_webhook_token` (64 hex znaků) a základní `smsgate_webhook_url=https://www.menubot.cz/sub/sms/webhook.php`. SMSGate Cloud nepodepisuje webhooky; registrační skript připojí token do query URL. Token může být zaznamenán v přístupových logách, proto je chraň a nikdy ho nevypisuj ani neposílej.
- **Nejdřív jen kontroly.** Po ověření konfigurace spustit `worker.php --check`, `register-webhooks.php --check` a `webhook-worker.php --check`. Zkontrolovat cílovou HTTPS adresu i podpis. Teprve pokud výstup odpovídá očekávání, spustit samostatně `register-webhooks.php --register` a read-only kontrolou ověřit registraci událostí.
- **Přejímka Huawei a SMS test.** Nejprve ověřit SSE spojení, příjem jedné běžné ručně odeslané SMS a opětovné připojení po restartu; telefon nechat se zamčeným displejem online alespoň 24 hodin. API odeslání testovat až po písemném potvrzení Tesco Mobile, že je automatizace na daném tarifu povolená. Pro jediný autorizovaný test je připravená stránka `test.php`, dostupná jen správci WordPressu; má pevné číslo a text, ochranu proti opakování a spouští worker jen pro tuto testovací zprávu. Před odesláním vyžaduje potvrzení oprávnění operátora. PASS pro laboratorní SMSGate test znamená stabilní SSE, příjem SMS, webhook a obnovu po restartu. Ani úspěšný test nepovoluje zákaznický provoz na Huawei se záplatou z roku 2022. Zákaznická čísla, hromadný test ani opakování nejasně dokončeného požadavku nepoužívat.
C. WhatsApp Cloud API – odděleně od WhatsApp aplikace
- **Nejdřív Meta testovací číslo.** V Meta Developer Dashboardu založit vlastní aplikaci „Connect with customers through WhatsApp“, vlastní Business Portfolio/WABA a použít testovací číslo. Aplikaci používat jen pod vlastním účtem/rolí; nezakládat Tech Provider ani Embedded Signup. Pokud Meta zobrazí žádost o dokumenty nebo App Review, zastavit se před odesláním žádosti a ověřit konkrétní požadavek.
- **Až po úspěšném testu produkční číslo.** Použít dedikované číslo, které není registrované ve WhatsApp; ověřit ho SMS nebo hovorem v Meta Dashboardu. Stejná SIM může zůstat v telefonu pro SMSGate, ale WhatsApp zprávy pak obsluhuje Cloud API, nikoli aplikace v telefonu. Existující aktivní WhatsApp číslo nemigrovat.
- **Zabezpečit připojení serveru.** V Meta vytvořit System User token, přiřadit vlastní WABA/aplikaci a potřebná oprávnění. Do chráněného configu přidat `meta_whatsapp_access_token`, `meta_whatsapp_phone_number_id`, aktuální `meta_graph_api_version`, `meta_whatsapp_app_secret` a `meta_whatsapp_verify_token`. Nastavit webhook `https://www.menubot.cz/sub/sms/whatsapp-webhook.php`, ověřit challenge a odběr `messages`. Ověřit jen přítomnost configu a spustit `whatsapp-worker.php --check`; běžný worker zatím nespouštět.
- **Jeden WhatsApp test.** Předem ověřit cenu a souhlas s případnou platební metodou; pro zprávu zahajující konverzaci může být potřeba schválená šablona. Potom poslat jednu testovací zprávu pouze na vlastní číslo, ověřit status/webhook/příchozí odpověď a vypnout testovacího klienta, pokud už není potřeba.
D. Teprve po úspěšných testech – pilot
- Ověřit zálohu/obnovu, idempotenci, deduplikaci, retenční pravidla a způsob zastavení pouze SMS/WhatsApp workeru. Sledovat nízký pilotní provoz alespoň 24 hodin. Timer/cron ani zvýšení limitu nenastavovat, dokud nejsou schválené cena, frekvence, limity a návrat.
Bezpečnostní hranice
- Přiložený plný instalátor je určen pro nový prázdný server; na tomto víceúčelovém VPS se nesmí spouštět.
- Neměnit existující weby, služby, databáze, globální API, firewall ani časovače kvůli SMS.
- Nepouštět aktualizace balíčků, restart ani změnu konfigurace jako součást auditu.
- Přímé HTTP požadavky na worker.php, whatsapp-worker.php i webhook-worker.php jsou odmítnuté; jejich běžné CLI spuštění může odeslat zprávu nebo zavolat webhook. Pouze --check nic neposílá. Výjimkou není veřejné API: `test.php` dovolí pouze přihlášenému správci jediný pevně definovaný test a worker omezí na jeho ID.
- Při další práci přes SSH postupovat po jednom příkazu, počkat na výstup a teprve potom pokračovat. Klíče, hesla, tokeny ani těla zpráv neposílat do chatu.
- WhatsApp worker má pilotní limit nejvýše pěti pokusů za klouzavou hodinu a jedno předání na spuštění; zvýšení limitu vyžaduje samostatné schválení.
- Limit pěti pokusů za hodinu není cenový limit Meta; šablony mohou být placené od prvního doručení a 1 000 bezplatných service odpovědí není neomezené.
- Po nejednoznačném timeoutu se SMS ani WhatsApp neposílá znovu naslepo; stav unknown čeká na webhook/ověření.
- SMSGate Android aplikace je pouze SMS brána; WhatsApp automatizaci přes neoficiální WhatsApp Web/WAHA/Baileys nepoužívat.
- Čísla a texty SMS jsou citlivé údaje; SMSGate uvádí, že zprávy zůstávají viditelné také v systémové SMS aplikaci telefonu. Použít zámek obrazovky a fyzicky chránit zařízení; plán uchování a ochranu záloh vyřešit před ostrým provozem.
Aktuální stav
- Produkční migrace 001 a 002 jsou potvrzené: verze `1,2`, celkem 12 tabulek, pět nových tabulek a čtyři doplněné sloupce.
- Produkční SMS základ je potvrzen uživatelskými výstupy: migrace 001/002, 12 tabulek, PHP spojení pod www-data a runtime práva pouze INSERT, SELECT a UPDATE. Testovací klient ID 1 prošel autorizovaným `GET ?op=status` s HTTP 200; jeho klíč zůstal uložený pouze rootovi.
- App inbox tabulka je už vytvořená a readback potvrdil `table_count=1`, `column_count=10`; SQL DDL znovu nespouštět. Receiver GET vrátil očekávaný 405, ale podepsaný POST, callback konfigurace a skutečné doručení ještě ověřené nejsou.
- Cache-bust readback 30. 10. potvrdil aktuální veřejný index; obsah za značkou `SMS_INDEX:PUBLIC_END` se nezobrazuje. Produkční API manuál byl ověřen v browseru a obsahuje nové zabezpečené testovací rozhraní.
- Dne 29. 10. ve 23:29 uživatel spustil SSH fázi A jako root: všechny uvedené soubory byly přítomné, PHP lint prošel, před migrací 002 bylo 7 tabulek a runtime práva byla INSERT/SELECT/UPDATE; config má root:www-data 640.
- Root preflight ukázal, že SMSGate, app callback i Meta klíče chybí. Push pro příchozí SMS zůstává zvolený; cílová URL je `https://app.menubot.cz/api/?bridge=sms-inbound`. Polling `GET ?op=inbound` zůstává bezpečná alternativa.
- Produkční SMS worker prošel `--check`; autorizovaný `GET ?op=status` testovacího klienta ID 1 vrátil HTTP 200. Produkční chování nového pollingu `GET ?op=inbound`, SDK a podepsaného app receiveru zatím ověřené není.
- Lokálně prošel PHP lint všech SMS souborů, izolované podpisové/konfigurační/SDK testy a vykreslení indexu i manuálu. Produkční DB transakce, Meta/callback připojení a živé zprávy testované nejsou.
- Huawei P smart 2021 (PPA-LX2, Android 10, EMUI 10.1.1, 4 GB RAM, přibližně 100 GB úložiště) technicky splňuje minimální Android požadavky SMSGate. Bez Google Play Services je nutné `SSE Only`. Záplata 1. 8. 2022 je bezpečnostní stopka pro zákaznický provoz: telefon lze použít jen k izolovanému laboratornímu testu; produkce vyžaduje aktuálně podporovaný a záplatovaný Android.
- Uživatel uvádí Tesco Mobile tarif „50 GB / plná 5G rychlost“. Přesný název balíčku a jeho zvláštní podmínky nejsou ověřené. VOP Tesco Mobile platné od 1. 7. 2026 v části o zneužití výhod uvádějí umělé nebo automatické generování hovorů či zpráv jako možné zneužití tarifu. Dokud Tesco Mobile písemně nepotvrdí povolení automatických SMS přes SMS gateway pro konkrétní tarif, SMS API z této SIM nepoužívat.
- SMSGate Cloud autentizace prošla, `worker.php --check` vrátil `SMS_WORKER_CHECK_OK` a všech pět webhooků bylo registrováno a ověřeno. Telefon je nastavený na Cloud `SSE Only` a hlásí `Connected`; uživatel potvrzuje, že jednorázová testovací SMS dorazila. Finální stav `delivered` a navazující webhook je potřeba ověřit v dashboardu.
- `test.php` je dostupná na produkční URL; nepřihlášený browser byl správně přesměrován na WordPress login. Uživatel potvrdil přijetí testovací SMS. Nový read-only dashboard `dashboard.php` používá stávající WordPress správce a časově omezený GET hash, bez dalšího účtu či hesla; přihlášený přehled v tomto browseru ověřený není. SSH přístup dostupným lokálním klíčem selhal.
- Žádný opakovaný worker, timer/cron, PHP-FPM restart, firewall ani nový port nebyl spuštěn/nastaven. Zálohu mimo VPS a obnovu do oddělené DB uživatel potvrdil.
Audit a dosavadní ověření
- Ověřen aktivní víceúčelový server; kapacita při jednom měření nevypadala kriticky, ale měření není garance dlouhodobé rezervy.
- Syntaxe Nginx a PHP-FPM prošla. Read-only MariaDB preflight 2026-10-29 v 14:26 potvrdil bind na loopbacku, port 3306 a volný název schématu i aplikačního účtu.
- Dne 2026-10-29 ve 14:30 uživatel vytvořil nové prázdné SMS schéma; readback potvrdil utf8mb4 a utf8mb4_unicode_ci. Existující schémata ani služby nebyly měněny.
- Konfigurace je uložena mimo webroot a PHP test pod www-data vrátil PHP_DB_CONNECTION_OK. Dne 2026-10-29 v 19:46 uživatel odebral DELETE; read-only kontrola oprávnění potvrdila pouze INSERT, SELECT a UPDATE.
- Hetzner Firewall se zobrazuje jako Fully applied k cílovému serveru. Pravidla nebyla měněna; přesné síťové podrobnosti nejsou součástí veřejného přehledu.
- Byly zjištěny nevyřešené provozní odchylky. V rámci SMS se nemění.
- Uživatel potvrdil, že databázová záloha je mimo VPS a obnova do oddělené DB byla ověřena.
- Read-only kontrola práv po migraci 002 potvrdila pouze `INSERT`, `SELECT` a `UPDATE`.
Hotovo – doložený stav
- Prošel jsem dodaný postup a oddělil SMS MVP od WhatsAppu, hovorů a AI.
- První SSH audit proběhl pouze pro čtení; syntaktické kontroly Nginx a PHP-FPM prošly.
- Firewall je potvrzen jako plně aplikovaný na server z SSH auditu.
- Read-only databázový preflight potvrdil volný název schématu i aplikačního účtu.
- Nové SMS schéma bylo vytvořeno a charset/collation ověřeny.
- Migrace 001 vytvořila všech šest aplikačních tabulek; bezpečný GET bez klíče potvrdil odpověď 401 a žádná SMS nebyla odeslána.
- Samostatný databázový účet a chráněný konfigurační soubor byly vytvořeny; PHP-FPM uživatel má k souboru čtecí přístup, DB spojení prošlo read-only testem a nadbytečné právo DELETE bylo odebráno.
- Cache-bust kontrola 30. 10. potvrdila aktuální veřejný index a jeho hranici veřejných značek. `test.php` i `dashboard.php` v nepřihlášeném browseru správně přesměrovávají na WordPress login. Uživatel potvrzuje doručení jedné testovací SMS; administrátorský dashboard ani stav webhooku v této relaci ověřené nejsou.
- Uživatelův root preflight potvrdil přítomnost a čistý PHP lint všech uvedených souborů. Následně uživatel spustil migraci 002; readback potvrdil verze 1,2, 12 tabulek, pět nových tabulek a čtyři sloupce.
- Produkční webroot obsahuje SMS/WhatsApp API, Meta webhook a workery; původní soubory prošly PHP lintem. Nejnovější polling API/SDK/app receiver změny je nutné před autorizovaným testem porovnat a případně synchronizovat. Normální CLI workery ani živé zprávy nejsou spuštěné.
- Všechny lokální PHP soubory prošly php -l; izolované testy podpisů, callback konfigurace, SDK pojistek, bind parametrů a renderu indexu/manuálu prošly.
- Oficiální SMSGate dokumentace byla ověřena pro JWT scopes, odesílání a webhooky včetně podpisu i počtu částí zprávy.
- Zálohu databáze uživatel hlásí jako provedenou; žádná SMS ani změna produkčních služeb nebyla provedena.
- Migrace 002 již na produkci proběhla; Meta Cloud HTTP klient, WhatsApp API fronta/stavy, source_system a trvalé podepsané webhook doručení jsou publikované. Konfigurace a provozní workery čekají.
- Každý API klient má mít WhatsApp vypnutý jako výchozí stav; povolit pouze konkrétnímu testovanému klientovi. Volný text se řídí 24hodinovým zákaznickým oknem, mimo něj se pro zahájení konverzace používá schválená šablona.
Aktualizováno
Aktualizace: 2. 11. 2026 – migrace SMS 002, post-migrační granty, obnova zálohy a app inbox tabulka jsou potvrzené. App receiver GET vrátil očekávaný 405; callback konfigurace a podepsaný POST zůstávají neověřené. Testovací klient ID 1 prošel `GET ?op=status` s HTTP 200; SMSGate autentizace, worker `--check` a registrace pěti SMS webhooků prošly. Uživatel potvrzuje doručení jediné testovací SMS; přehled jejího finálního stavu je dostupný v novém správci-only dashboardu. Dashboard ani finální webhook stav nebyly v této nepřihlášené browser relaci ověřené. Meta konfigurace čeká.