Týdenní poznámky #34: Εὕρηκα! Členství vyřešeno

Utekl další týden (18.1. — 22.1.) a tak stejně jako minule sepisuji, co jsem dělal a co zajímavého jsem se naučil. Především se snažím rozvíjet junior.guru. Nemám šéfa, kterému bych reportoval každý svůj krok, ale mám podporovatele, a ty by mohlo zajímat, jestli se neflákám. Taky je to způsob, jak se sám doma nezbláznit a nepropadat pocitu, že je zase pátek a já jsem přitom nestihl nic udělat.

Poznámky
Fotka od Honzy Kahánka

Εὕρηκα je takové to Archimedovo zvolání. Nechtěl jsem to tu mít latinkou, aby si lidi nemysleli, že mám něco společného s vyhledávačem zboží. Už tak jsem dostal za uši, když jsem měl v nadpisu HN a nebyly to HackerNews, ale Hospodářky. Musel jsem se kvůli tomu pak stát slavným nejen na Hospodářkách, ale i HackerNews.

Tento týden se nesl v duchu rozklíčování technického a procesního řešení nákupu členství. Paralelně se mnou mi daňař odpovídal na dotazy ohledně daní a právnička pracovala na mých obchodních podmínkách.

Členství#

V minulých poznámkách jsem skončil tím, že jsem v pasti a neumím vyřešit propojení Stripe a Discord. Nový týden jsem nastartoval s tím, že si musím dát nějaké konkrétní kroky, přes které se doberu výsledku:

  • Poptat se na všech možných místech, zda to už někdo neřešil nebo neví, jak to řešit.
  • Ještě jednou projít hotová řešení a spočítat pricing. Co kdyby to nakonec vycházelo nějak přijatelně?

Výsledkem prvního bodu byly dotazy na supportu Discordu, na Stack Overflow, na Twitteru. Také jsem intenzivně hledal a přece jenom jsem nakonec něco našel. Pokud bych se nakonec rozhodl pro vlastní řešení, zřejmě by mě k němu dovedl tento článek na Mediu a tato odpověď na SO. Jak ale vyplývá z formulace předchozí věty, rozhodl jsem se nakonec vybrat hotové řešení. Zvažoval jsem následující:

  • Memberful - Koupil je Patreon, skvělý support, spousta funkcí.
  • LaunchPass - Malá firma, dobrý support, málo funkcí.
  • Upgrade.Chat - Platící bot, možná trochu něco jiného, než chci. Jakýsi strašně zmatený support přes Discord. Nejmenší marže, ale vyloučil jsem je vlastně celkem brzo.

Dále jsem se díval na:

  • Circle jako na možnou alternativu Discordu a all-in-one řešení. Líbil se mi design, nelíbil se mi ceník a funkce.
  • Auth0 jako na možný stavební blok pro přihlašování,
  • MemberStack jako alternativu Memberful,
  • MemberSpace jako další alternativu Memberful.

Outsourcovat nebo ne?#

Stále jsem všechno zvažoval a rozvažoval. Hlavně jsem si nebyl jistý, zda mám opravdu něco takhle outsourcovat. Nakonec mě přesvědčily následující věci:

  • Udělal jsem si detailní tabulku pro výpočet předplatných, všech marží atd. Náhled níže. To mě přesvědčilo, že marže hotového řešení se tam vleze a že to pořád dává smysl.
  • Všechna hotová řešení jedou přes Stripe, který je industry standard a sám má skvělé API, takže to není úplný vendor lock-in.
  • Když jsem si četl o nejrůznějších funkcích jednotlivých řešení, pochopil jsem, že tohle si fakt sám programovat nechci. Možná bych dokázal vyrobit jednoduchý skript pro ten základ a něco bych ze začátku ušetřil, ale když jsem viděl, co všechno hlídají, jaké maily posílají, co vše jde nastavit, apod., najednou to nebylo jen "propojení Stripe a Discord", byla to hromada práce, kterou nebudu muset řešit. Daně. Kupóny.
  • Přemýšlel jsem nad tím, jestli chci programovat řešení pro online členství nebo chci budovat komunitu, psát příručku a vylepšovat JG. Jasně mi z toho vyšlo, že tohle prostě není můj core business a můj život bude mnohem šťastnější, když použiju hotovou věc a zaplatím za ni.

Z možných řešení jsem nakonec vybral Memberful. Líbilo se mi, že za nimi stojí společnost, která asi jen tak nezanikne, že dělají přesně to co chci a přesně způsobem, jakým chci. Mají dokumentaci a z jejich webu je vše zřejmé - hlavní výhoda oproti LaunchPass. Mají API, mají funkční a úžasný support (prohodil jsem s nimi asi 10 mailů, než jsem si vše ujasnil). Dokonce mají i drahou variantu s možností prodávat skupinové členství. Zprvu jsem myslel, že ji budu potřebovat, ale nakonec jsem to vymyslel jinak. Vědomí, že mi bude stačit levnější varianta, mě už definitivně přesvědčila.

Velké počítání#

Velké počítání
Rozpočítávání cen, marží, nákladů. Mohu měnit čísla v modrých řádcích a vše se přepočítává. Mohu měnit i základní cenu nebo čísla kolem navržených nabídek pro firmy. Ty jsou ve velmi ranném stádiu uvažování.

Když jsem si dělal tabulku, ve které se vše propočítávalo, zkoušel jsem si už rozvrhnout i nabídku pro firmy. Nejdřív jsem myslel, že by byla jedna za zhruba 10 000 Kč, kde by firma mohla pozvat třeba 10 nebo aspoň 8 členů, ale nevycházelo mi to jako moc výhodné. Částky 10 000 Kč ročně se chci ale držet, protože si myslím, že je to psychologická hranice, u které spousta firem mávne rukou a zaplatí ji klidně i jen proto, aby mě podpořili v tom, co dělám. Nakonec jsem zkusil načrtnout spíš dvě nabídky, jednu pro firmy s menším počtem lidí a druhou pro větší. Samozřejmě bude i třetí, pro všechny ostatní, ale ti mi napíšou e-mail a domluvíme se individuálně. Intuitivně jsem to rozdělil tak, že levnější varianta zaplatí za 6 vstupů a dražší za 18, ale pro jistotu jsem nadhodil ankety na FB a Twitter, ať to není úplně vycucané z prstu. Prakticky potvrdily mou úvahu.

No ale stejně to je celé zatím jen pro mou tabulku s čísly, takže o nic nejde. V nejbližší době nepočítám s tím, že se budu dělat s ceníkem na webu, prostě mi firmy napíšou na mail a dohodneme se. Taky to může skončit u toho, že bude nějaká fixní sazba za logo mezi členy klubu a pak dynamické "šoupátko", které výslednou cenu prostě vypočítá násobením počtu členů, které chtějí zaplatit. Třeba žádné "přednastavené" balíčky ani nebudou.

Memberful#

Memberful má pohodlné propojení s Discord, umí CZK a celkově mi přišel nejlépe připravený pro to, co já potřebuji. Dá se vyzkoušet naživo bez toho, aby za to člověk platil - dokud se nerozhodnu, že to chci překlopit do ostré verze, jede to v testovacím režimu a můžu zkoušet i funkce, které jsou pro placené účty. To jsem dělal snad jeden celý den a vytvořil jsem si kvůli tomu i další testovací Discord server. Administraci a možnosti Memberful jsem dlouho poctivě proklikával. Díky tomu jsem pak i rozklíčoval dilema jak technicky řešit hromadné předplatné pro firmy, které chci dělat na fakturu. Zkoušel jsem různé nápady, např. že by každá firma měla svůj vlastní plan, který jinak nepůjde koupit, a jenž bude určovat podmínky předplatného… ale pak jsem na to přišel.

Udělám to přes kupóny! Objev kupónů a myšlenka, že se s nimi dá řešit skupinové předplatné byl hlavní εὕρηκα moment tohoto týdne a udělal mi velkou radost. Do té doby jsem si připadal na dobré cestě, ale stále zaseknutý. S kupóny najednou vše začalo zase dávat smysl. Firma prostě nakoupí třeba 5 kupónů se 100 % slevou na rok a je to. Ať už je dá svým lidem nebo je někomu podaruje, vše bude fungovat. Akorát si napíšu Python skript, který mi udělá nějaký přehled v Google Sheets tabulce. Mohl by mi třeba i poslat mail, když se bude blížit vypršení doby předplacené fakturou, klidně sám kontaktuji firmu a dořešíme distribuci nové sady kupónů. Pokud firma za někoho platit už dál nebude chtít, tak ten nemusí odejít, může za sebe dál platit individuálně. Právě onen individuální aspekt kupónů a existence individuálních účtů, které firma jen předplatí, se mi na tom hodně líbí. Navíc mohu vytvářet kupóny i s menší než 100% slevou, že, a rozdávat je třeba do nějakých spřízněných komunit :) Ou jé.

Abych nedopadl jak s propojením Stripe/Discord, rozhodl jsem se ještě opravdu vyzkoušet, že API od Memberful je použitelné a mohu přes něj udělat, co potřebuji. V testovacím režimu to naštěstí šlo. Mají GraphQL API, což jsou pro mě pořád ještě trochu vody, ve kterých tápu, ale s pomocí gql jsem docela rychle splácal něco, co mi vyhodilo přesně ta data, která bych při integraci s mými Google Sheets potřeboval. A to už byl pátek, takže dál jsem už nic nedělal a mohu jít dnes spát s tím, že velké dilema je vyřešeno.

Tedy jsem se rozhodl vykopnout se z Patreonu dveřmi (časem chci zrušit svůj Patreon a nahradit jej právě členstvím v klubu) a přijít k němu oknem :D No, hlavně jsem rád, že jsem si to všechno mohl osahat a vyzkoušel jsem si i to API, takže za to mohu s klidným svědomím zaplatit, prohlásit přijímání členů a placení za vyřešené a posunout se na lepší věci. Na Stripe/Discord jsem se naučil, že je asi vždy lepší nejdřív si ověřit, zda předpoklady sedí i v realitě. Nestačí jen fakt, že existuje API, tak vše určitě nějak půjde :)) A taky jsem pochopil, že to není práce pro jeden skript. Že nejde jen o propojení Stripe/Discord, ale že kdybych se do toho pustil sám, programoval bych to a opravoval na tom chyby tak zhruba do konce života.

Jinak další super věc na Memberful je ta, že se tam moji členové mohou přihlásit a je tam celý billing portal, kde mohou změnit předplatné, zrušit, změnit kartu, atd. To by uměl i Stripe sám o sobě, ale jak jsem psal minule, tam bych musel já implementovat to přihlašování. A navíc, pokud bych v budoucnu chtěl vyrobit něco jako knížku nebo video pouze pro členy, mohu to nahrát do Memberful a po přihlášení do svého účtu na to budou mít všichni členové odkaz ke stažení apod. Teď to neplánuji, ale do budoucna se to hodit může a já k tomu budu mít už infrastrukturu bez práce.

MailChimp#

Všiml jsem si, že Memberful má i pěknou integraci s MailChimpem, ale po pár dotazech na jejich support jsem se rozhodl, že ji zatím využívat nebudu. Můj newsletter vznikl už dříve a pro jiný účel. Spojovat bych to teď nechtěl, navíc si nejsem jistý, jak moc legálně to mají uděláno vzhledem k českým pravidlům - např. by se mi líbilo, kdyby tam bylo při registraci nezaškrtnuté zaškrtávátko, kde by si člověk mohl zvolit, že ode mě chce dostávat e-maily, ale to oni tak úplně neumí. Je to až moc automatické :) Nechávám na jindy nebo na nikdy.

Daně#

Svého daňaře jsem se vyptal na spoustu věcí, které mi vrtaly hlavou. V jedné z odpovědí mi napsal následující:

Jde ale o tak specifickou situaci pro někoho kdo není plátce DPH, že jsem se s něčím takovým ještě nesetkal.

Moje první reakce byla: Challenge accepted!

Pokud by někoho zajímalo, jestli musím automaticky vydávat doklady, tak podle zákona o ochraně spotřebitele je povinnost vystavit doklad o poskytnutí služby, pokud o to zákazník požádá. Stejná povinnost je i v živnostenském zákoně.

Pak jsem se ptal, jak to je, když může koncový zákazník samoobslužně nakupovat na mém webu kartou a já nejsem plátce DPH. Pokud přijde někdo ze Slovenska a nakoupí, velmi to neovlivním. Stanu se pak automaticky identifikovanou osobou nebo plátcem DPH? V podstatě jsem rozlišil čtyři situace:

  1. Koncový zákazník z ČR, zaplatí kartou na webu, jednou za měsíc/za rok se mu strhne částka.
  2. Firma/podnikatel z ČR, má IČO, domluvíme se přes e-mail a já pošlu fakturu z Fakturoidu a třeba za rok pošlu další.
  3. Koncový zákazník ze SR nebo odkudkoliv jinud z celého světa. Platební brána bude na webu a kdo zaplatí, dostane členství. Logicky nemohu nijak omezit nebo ověřit odkud člověk je. Protože je má služba česky, mohu se domnívat, že ze zahraničních koncových zákazníků to bude zajímat hlavně Slováky, ale reálně to může být kdokoliv.
  4. Firma/podnikatel mimo ČR. Ti nemohou nakupovat přes platební bránu, museli by se se mnou domluvit, takže jim snadno mohu říct, že službu neposkytuji mimo ČR, pokud se nechci stát ID osobou/plátcem DPH, a z obchodu nic nebude.

Případ 2. dělám odjakživa. Případ 1. je pro mě nový, takže nevím, jaké má náležitosti, ale nebojím se ho. Případ 4. mohu snadno ručně vyloučit, takže se ho taky nebojím. Co mě straší je případ 3., protože je de facto mimo mou kontrolu. Pokud bych jej měl mít pod kontrolou, musel bych nějak v platební bráně zamezit lidem platit, pokud nejsou z ČR, ale to mi moc nedává smysl.

Podle všeho, pokud nebudou prodeje do EU běžným smrtelníkům vyšší než 10 000 EUR/kalendářní rok, tak údajně DPH řešit nemusím. Po překročení bych se nejspíš stal identifikovanou osobou a musel bych se přihlásit do MOSS. Než budu mít vysoké výdělky, nemuselo by mě ani zajímat, odkud ti lidé jsou, ale pro jistotu je lepší si to někde evidovat, abych případně mohl prokázat, zda ty vysoké výdělky ze zahraničí (ne)mám. EU do směrnice k DPH zařadilo i demonstrativní výčet důkazů, které můžu použít k prokázání, ze kterého státu lidi jsou:

  • Fakturační adresu příjemce,
  • adresu internetového protokolu (IP) zařízení používaného příjemcem nebo jakýkoli způsob geolokalizace,
  • bankovní údaje, například místo, kde je veden bankovní účet používaný k placení nebo fakturační adresa příjemce, již má uvedená banka k dispozici,
  • mezinárodní směrový kód země (MCC) mezinárodní identifikace mobilního účastníka (IMSI) uložený na SIM kartě, kterou příjemce používá,
  • místo pevné linky příjemce, jejímž prostřednictvím je mu služba poskytována,
  • jiné informace důležité z obchodního hlediska.

Takže stačí i celkem vágní informace jako IP adresa. Super :) Pro mě je to důležité hlavně proto, že se teď ještě nechci stát plátcem DPH a také proto, že chci, aby formulář pro placení musel obsahovat co nejméně políček. Čím víc políček k vyplnění, tím menší šance, že formulář někdo dokončí a opravdu zaplatí.

Další poznámky#

  • V nativním macOS terminálu, který teď zkouším používat místo iTerm2, mi zatím chyběla jediná věc, a to skákání šipkama po slovech se zmáčknutým altem/option. Zjistil jsem ale, že to jde zapnout jediným zaškrtávátkem.
  • Poděkoval jsem e-mailem někomu, kdo mi už vloni v létě radil něco v tom smyslu, že vydělat by se v mém případě dalo nejlépe asi na nějakém placeném členství apod. věcech. Trvalo mi jen tři čtvrtě roku na to přijít sám.
  • Člověk, který prosazoval sponzorování JG v jedné firmě, měl teď prezentaci o tom, jak se jim ta investice vyplatila. Trochu jsem mu pomáhal s přípravou. Vypadá to, že výsledky dobrý! 40 % kandidátů byly ženy, 2 lidi přijali.
  • Ozvala se korporace, že jsem jejich dodavatel a mám jim ihned poslat spoustu údajů. Údaje jsem dodal.
  • Jako OSVČ jsem od ledna zvýšil pravidelnou zálohu na zdravotní pojištění.
  • Spadl mi scraper na WWR, protože měli v JSONu text, jehož součástí byla i sekvence znaků pro tzv. shrug, tedy krčení ramen, a nebylo to nijak ošetřeno (zpětné lomítko). Opravil jsem to tak, že když se něco takového stane, holt se nabídka práce přeskočí ¯\_(ツ)_/¯
  • Měl jsem hovor s právničkou, kde jsme dolaďovali obchodní podmínky. To, že jsem vybral Memberful, nám zodpovědělo spoustu nevyjasněných otázek, takže další palec nahoru pro hotové řešení.

Pyvec#

  • Upgrade knihoven na různých Pyvec projektech (přes Dependabot).
  • Spadla hlavní větev na webu Pyvce, a to proto, že Twitter už definitivně odebral možnost přes jednoduché URL získat avatar uživatele. Musel jsem to celé odstranit a nyní mohou obrázky členů Pyvce pocházet už jen z Gravataru nebo GitHubu.
  • Měli jsme pravidelnou schůzi výboru Pyvce. Pár věcí jsme vyřešili. Přijali jsme do spolku nového člena.

Redis Collections#

Kdysi dávno jsem napsal knihovnu redis-collections. Byl to můj první balíček na PyPI, napsal jsem k tomu svou první dokumentaci na ReadTheDocs, prostě můj první opravdový Open Source. Koukám se, že to bylo v lednu 2013, tedy před osmi lety. Knihovně jsem se věnoval, ale pak jsem změnil práci a už jsem ji nadále sám nepotřeboval, takže trochu umírala na nezájem. V roce 2016 se ale objevil nějaký Bo Bayles z druhého konce zeměkoule a navrhl, že by se o to dál staral. Postupně jsme si předali žezlo a od té doby na tom zahradničí on.

Nedávno se ozval s tím, že by chtěl vyhodit Travis CI a vyměnit jej za GitHub Actions, ale nemá všechna potřebná oprávnění. Proto jsem se na to tento týden mkrnul:

  • Přidal jsem současného správce jako spoluvlastníka balíčku na PyPI
  • Vytvořil jsem organizaci na GitHubu: github.com/redis-collections
  • Nastavil jsem nás oba jako vlastníky
  • Přesunul jsem repozitář pod novou organizaci

Pak jsem si říkal, že by byla škoda mít na organizaci výchozí náhodný obrázek, že by to chtělo nějaké logo. Takže jsem stáhl SVG logo Redisu, otevřel v Inkscape, dal ungroup, smazal text a různé detaily a přes červené destičky napsal v Arial Black iniciály projektu, RC. Zabralo to 5 minut. Dalších 15 minut zabralo správně nastavit rozměry dokumentu a vše vycentrovat a exportovat správně do PNG. I když jsem mu jasně řekl, že to byl jen pokus a klidně to můžeme zahodit, tak Bo napsal, že logo je nádherné a bude ho používat. Aby mi neleželo jen někde na disku, vytvořil jsem pro něj repo logo.

Ano, asi není úplně správné vzít něčí logo a derivovat z něj svoje. Dnes už třeba vím i to, že není správné ani pojmenovávat věci slovem "Redis", když nemám s Redisem nic společného, protože tím nejspíš porušuji jejich ochrannou známku. U nových projektů bych to už vymyslel jinak, ale tady mi přišlo, že logo vytvořené z loga Redisu bude konzistentní s názvem knihovny, který je vytvořený z názvu Redisu, a že to doteď nikomu nevadilo, tak snad OK. Pokud mi někdo z Redisu napíše, že to není OK, samozřejmě to odstraním nebo knihovnu přejmenujeme. Zatím jsme aspoň přidali tuhle větu do README.

Když už jsem byl u takových detailů, po svém angažmá v Oracle jsem se podíval i na licenci a věci kolem toho.

Vylepšení skriptu na týdenní poznámky#

Ve volné chvilce jsem se podíval na skript weeknotes.py, kterým generuji šablonu pro každé nové týdenní poznámky:

  • Opravil jsem kód, který chybně vytvářel odkaz na minulé poznámky v prvním odstavci.
  • Přidal jsem novou sekci "Co plánuji" (k vidění o kousek níž), která by mi měla pomáhat určovat si trochu priority na další týden a zpětně sledovat, jak se mi tyto plány drží dodržovat. Cílem není vyčerpávající seznam, ale napsat si tři nejdůležitější věci, které bych fakt měl udělat.

Napadlo mě, že by v poznámkách mohla být vždy jedna věta o tom, kolik jsem měl za poslední týden pohybu. Vám by to ukázalo, jak je každá odrážka v poznámkách vykoupená tím, že se nehnu od počítače. Mě by to třeba pomohlo víc se motivovat vyrazit ven na procházky, běhat, projet se na kole. Zjistil jsem ale, že Strava má API přístupné jen přes OAuth2, je tedy nutná interakce uživatele, abych mohl stáhnout data o svých aktivitách. Taková API úplně nenávidím. Jak to nemá API token, nejde to pořádně použít ze skriptu a nebo jde, ale je to hrozná otrava.

Zkusil jsem pak ještě přístup "když to nemá použitelné API, třeba se to dá scrapovat" a na pár řádcích se mi opravdu povedlo napsat Python skript, který se přes mé jméno a heslo přihlásil do Stravy a viděl moje poslední aktivity. Pak bych ale musel nějak přes CSS nebo XPath vysekávat jednotlivé kousky jako kolik km nebo datum a to už jsem si řekl, že se mi kvůli jedné větě v poznámkách dělat momentálně nechce.

Možná jsem si měl jít radši zaběhat?

Co plánuji#

Tři věci, které bych chtěl zvládnout udělat příště:

  1. Propojit Memberful s webem junior.guru
  2. Mít hotové obchodní podmínky
  3. Pověnovat se Visualbooku, který jsem dostal k Vánocům od Jirky

Myslím, že by se mi mohlo povést klub na přelomu ledna a února už spustit pro veřejnost.

A co vy?#

Pokud byste čistě náhodou měli dojem, že jste oproti mě za uplynulý týden vůbec nic nestihli, tak mám pro vás skvělou zprávu! V klidu se na ten dojem můžete vykašlat. Není zač!

Co mě zaujalo#

Když si něco přečtu nebo poslechnu a líbí se mi to, sdílím to na Pocketu. Od posledních poznámek jsem sdílel toto:

Vygenerováno pomocí pocket-recommendations.