MCP: slevy, kampaně a feedy
Nástroje MCP pro slevové kódy, vyskakovací okna, koncepty kampaní, segmenty zákazníků a nastavení feedů: oprávnění, potvrzení, důsledky zápisu a parametry.
Slevové kódy i s cílením na produkty a kategorie, feedy do srovnávačů zboží, kampaně i s výsledky rozeslání, vyskakovací okna a segmenty zákazníků. Rozeslání kampaně ani vygenerování feedu mezi nástroji není, obojí zůstává v administraci.
Nástroje volá klient přes server MCP na doméně obchodu, například https://muj-eshop.cz/api/mcp, a v odpovědi na tools/list dostane jen ty, na jejichž oprávnění klíč dosáhne. Jak server mluví, kdy se ptá člověka a jak se změny vracejí, popisuje článek MCP server.
U každého nástroje stojí oprávnění, které chce, jestli se server před provedením zeptá člověka a kudy, jestli volání strhne kredity obchodu nebo peníze z karty, co vrací pro deník změn a jakou větu o důsledku člověk v potvrzení uvidí. Všechno z toho se vyhodnocuje z téhož kódu, podle kterého se server rozhoduje. Popisy parametrů jsou převzaté ze schématu, které server posílá v tools/list; kde se v něm text obrací přímo k modelu, je tady převedený do vykání. Povinnost parametru platí uvnitř objektu, ve kterém parametr leží.
Před zápisem, který přepisuje nebo maže, před útratou kreditů nebo platbou kartou a před hledáním mimo obchod se server ptá člověka a do té doby neprovede nic. Nejdřív použije schválení, které pro totéž volání se stejnými hodnotami už v administraci leží schválené. Jinak se zeptá formulářem, když ho klient deklaruje a politika akce ho dovoluje; formulář potvrzuje ten, kdo drží klíč, takže před ukradeným klíčem takové potvrzení nechrání. Otázka ve formuláři nese pod nadpisem „Co se změní“ tytéž řádky jako stránka schválení. Klient s elicitací URL dostane odkaz na stránku schválení v administraci a klient bez elicitace odmítnutí approval_required s odkazem v _meta; po schválení volání zopakuje se stejnými hodnotami. Na stránce schválení rozhoduje jen přihlášený člověk, kterého u každé akce jmenuje odrážka Potvrzení přes MCP, a účet podpory SHOPZI nikdy. Když politika nedovoluje nic, co klient umí, přijde odmítnutí confirmation_required a neprovede se nic. Výsledek potvrzeného volání nese v _meta["cz.shopzi/confirmation"] údaj, že akci potvrdil člověk a kde (form nebo approval), a v obsahu českou větu pro model, u placené akce i s cenou a zůstatkem kreditů z dotazu. Na otázku formulářem je 15 minut, schválení na stránce platí 60 minut, pokud u akce není uvedeno jinak.
Zápisové nástroje vracejí v poli change_id ID záznamu v deníku změn; co pole u kterého nástroje nese, říká jeho odrážka Deník změn. Změnu z deníku vrací shopzi_undo_change podle jejího druhu: obnoví předchozí hodnoty, u skladu zapíše vyrovnávací pohyb, u běžné ceny zapíše návrat do 30denní historie cen (nic z ní nemaže) a změnu, která už opustila obchod nebo stála peníze (odeslaný e-mail, stržené kredity, platbu kartou), odmítne s vysvětlením.
shopzi_list_marketing
Vrátí podle resource slevové kódy i s počtem uplatnění a cílením na produkty a kategorie, stav feedů do srovnávačů zboží, kampaně i s výsledky rozeslání (s entityId jednu kampaň i s tělem e-mailu), vyskakovací okna, nebo segmenty zákazníků.
- Oprávnění:
marketing:read, u klíče „Marketing: slevy, feedy, kampaně, segmenty (čtení)“. - Druh: čtení (
readOnlyHint). - Potvrzení přes MCP: ne.
- Kredity a platba kartou: ne.
shopzi_list_marketing: oblasti
discountsfeedscampaignspopupssegments
shopzi_list_marketing: parametry
resource(jedna z hodnotdiscounts,feeds,campaigns,popupsasegments; povinný)status(jedna z hodnotdraft,scheduled,active,paused,expired,archived,sending,sentacanceled; nepovinný): Filtr stavu.discounts: draft | scheduled | active | paused | expired | archived.campaigns: draft | scheduled | sending | sent | paused | canceled.search(text; nepovinný): Hledá v kódu a názvu (discounts), v názvu a předmětu (campaigns) nebo v nadpisu (popups).discountKind(jedna z hodnotpercent,fixedafree_shipping; nepovinný): Jendiscounts:percent= procentní sleva,fixed= pevná částka,free_shipping= doprava zdarma.entityId(UUID; nepovinný): Jencampaigns: jedna kampaň i sbody_html.limit(celé číslo od 1 do 100, výchozí25; nepovinný): Počet položek na stránku, 1 až 100. Velká stránka se do jedné odpovědi nemusí vejít a nástroj ji pak odmítne, což stojí krok navíc: berte jen tolik položek, kolik na odpověď opravdu potřebujete.offset(celé číslo od 0 do 100000, výchozí0; nepovinný): Kolik položek přeskočit. 0 = první stránka.
shopzi_save_discount_code
Založí nebo upraví slevový kód včetně cílení na vybrané produkty a kategorie (seznam se nahrazuje celý), smaže kód, který nikdo neuplatnil, nebo přepne stav více vyjmenovaným kódům naráz. Nový kód vzniká jako koncept; u uplatněného kódu jde měnit jen název, veřejný popisek, stav a konec platnosti.
-
Oprávnění:
marketing:write, u klíče „Marketing: slevové kódy, vyskakovací okna, koncepty kampaní, segmenty, feedy (zápis)“. -
Druh: zápis, který umí přepsat nebo smazat existující data (
destructiveHint). -
Potvrzení přes MCP: ano: formulář v klientu, který potvrdí ten, kdo drží klíč; jinak odkaz na stránku schválení přes elicitaci URL; jinak odkaz na stránku schválení v odmítnutí
approval_required. Na stránce schválení rozhoduje vlastník nebo manažer obchodu. -
Kredity a platba kartou: ne.
-
Deník změn: výsledek nese
change_id. ID záznamu v deníku. Předejte ho doshopzi_undo_change. -
Věta o důsledku, kterou člověk uvidí v potvrzení:
Aktivace kódu ho pustí do košíků zákazníků, pozastavení a archivace ho z nich vezmou. Hromadná změna se provede na VŠECH kódech vypsaných níž, naráz a přesně na nich; vrátit to jde jedním krokem, celou dávku najednou. Smazat lze jen kód, který nikdo neuplatnil.
shopzi_save_discount_code: operace
save(uložit)delete(smazat)bulk_status(hromadně přepnout stav)
shopzi_save_discount_code: parametry
operation(jedna z hodnotsave,deleteabulk_status; nepovinný):save(výchozí) = založit nebo upravit,delete= smazat jeden neuplatněný kód,bulk_status= přepnout stav víc kódům najednou.discountId(text; nepovinný): ID promo akce (promotion_id) existujícího kódu. Vynechte pro založení nového. Povinné udelete.discountIds(pole, položka: text, nejvýš 100 položek; nepovinný): Jenbulk_status: VÝSLOVNÝ seznam ID kódů zeshopzi_list_marketing(resource: discounts), nejvýš sto. Filtr se poslat nedá schválně: schvalovací karta ukazuje počet, který v ní stojí, a provede se přesně tolik kódů.fields(objekt; nepovinný): Pole ke změně. Vynechané pole zůstane beze změny. Udeletese nepoužívá, ubulk_statusse z něj čte jenstatus.fields.code(text; nepovinný): Kód, který zákazník zadá v košíku. Jen A-Z, 0-9 a . _ - (2 až 40 znaků). Povinný při zakládání.fields.name(text; nepovinný): Interní název akce. Vidí ho jen obchodník.fields.publicTitle(text nebonull; nepovinný): Popisek slevy v košíku, který uvidí zákazník.fields.status(jedna z hodnotdraft,active,pausedaarchived; nepovinný): draft = koncept, active = platí, paused = pozastaveno, archived = archiv. Ubulk_statusjsou povolené jen active, paused, archived.fields.kind(jedna z hodnotpercent,fixedafree_shipping; nepovinný): percent = procenta, fixed = pevná částka, free_shipping = doprava zdarma.fields.percentBp(celé číslo od 1 do 10000 nebonull; nepovinný): Sleva v setinách procenta: 1000 = 10 %, 10000 = 100 %.fields.amountMinor(celé číslo aspoň 1 nebonull; nepovinný): Pevná sleva v haléřích: 20000 = 200 Kč.fields.maxDiscountMinor(celé číslo aspoň 0 nebonull; nepovinný): Strop procentuální slevy v haléřích. null = bez stropu.fields.minSubtotalMinor(celé číslo aspoň 0 nebonull; nepovinný): Minimální hodnota košíku v haléřích. null = bez limitu.fields.startsAt(text nebonull; nepovinný): Začátek platnosti v ISO tvaru. null = ihned.fields.endsAt(text nebonull; nepovinný): Konec platnosti v ISO tvaru. null = bez konce.fields.totalUsageLimit(celé číslo aspoň 1 nebonull; nepovinný): Maximální počet uplatnění celkem. null = bez limitu.fields.perCustomerLimit(celé číslo aspoň 1 nebonull; nepovinný): Maximální počet uplatnění na zákazníka.fields.usageLimit(celé číslo aspoň 1 nebonull; nepovinný): Maximální počet uplatnění tohoto konkrétního kódu.fields.singleUse(truenebofalse; nepovinný): true = kód lze uplatnit jen jednou.fields.firstOrderOnly(truenebofalse; nepovinný): true = jen pro první objednávku zákazníka.fields.excludeDiscountedItems(truenebofalse; nepovinný): true = neplatí na zboží, které už je zlevněné.fields.targets(pole objektů, nejvýš 200 položek; nepovinný): PLNÁ NÁHRADA cílení: celý výsledný seznam,[]= celý košík. Na uplatněném kódu nejde měnit.fields.targets[].targetType(jedna z hodnotproductacategory; povinný)fields.targets[].targetId(UUID; povinný): ID produktu nebo kategorie zeshopzi_list_catalog.fields.targets[].mode(jedna z hodnotincludeaexclude; povinný): include = jen na tyto, exclude = na tyto ne.idempotencyKey(text, 1 až 200 znaků; nepovinný): Klíč idempotence. Stejný klíč = stejný zápis: opakované volání vrátí původní výsledek a NEZAPÍŠE podruhé. Použijte vlastní náhodný řetězec pro každou zamýšlenou změnu; při opakování po chybě sítě pošlete tentýž.
shopzi_save_marketing_entity
Založí, upraví nebo smaže vyskakovací okno, koncept kampaně, segment zákazníků a nastavení feedů do srovnávačů. Vyskakovací okno vzniká zhasnuté a rozsvítit ho jde, jen když žádné jiné nesvítí. Rozeslat kampaň tudy nejde a změna feedu se do srovnávače propíše až při jeho nejbližším vygenerování.
-
Oprávnění:
marketing:write, u klíče „Marketing: slevové kódy, vyskakovací okna, koncepty kampaní, segmenty, feedy (zápis)“. -
Druh: zápis, který umí přepsat nebo smazat existující data (
destructiveHint). -
Potvrzení přes MCP: ano: formulář v klientu, který potvrdí ten, kdo drží klíč; jinak odkaz na stránku schválení přes elicitaci URL; jinak odkaz na stránku schválení v odmítnutí
approval_required. Na stránce schválení rozhoduje vlastník nebo manažer obchodu. -
Kredity a platba kartou: ne.
-
Deník změn: výsledek nese
change_id. ID záznamu v deníku. Předejte ho doshopzi_undo_change. -
Věta o důsledku, kterou člověk uvidí v potvrzení:
Smazat lze jen KONCEPT kampaně, zhasnuté okno a segment, který nemá navázanou žádnou kampaň; všechno tři se dá vrátit i s obsahem. Nic z toho nikomu nic neodesílá: rozeslat kampaň umí jen člověk v administraci. ZAPNUTÍ FEEDU zveřejní adresu s katalogem obchodu, ze které si ho srovnávač (Heureka, Zboží.cz, Google a další) stahuje; vypnutím se zase zavře. Zařazení kategorií a výjimky u položek se do srovnávače propíšou až při nejbližším vygenerování feedu, tedy při ranní automatické aktualizaci, nebo když v sekci Feedy kliknete na Generovat u kanálu či na Generovat vše. Vygenerovat a zveřejnit feed sám agent neumí.
shopzi_save_marketing_entity: oblasti
popup(Vyskakovací okno)campaign(Kampaň)segment(Segment zákazníků)feed_channel(Kanál feedu)feed_category(Zařazení kategorie ve feedu)feed_item(Výjimka položky ve feedu)
shopzi_save_marketing_entity: operace
save(uložit)delete(smazat)
shopzi_save_marketing_entity: parametry
resource(jedna z hodnotpopup,campaign,segment,feed_channel,feed_categoryafeed_item; povinný): Která položka. Pole musí patřit k ní.operation(jedna z hodnotsaveadelete; nepovinný):save(výchozí) = založit nebo upravit,delete= smazat. Mazání chceentityIda žádnáfields. Ufeed_categoryafeed_itemznamenádeletezrušení zařazení nebo výjimky;feed_channelse nemaže, jen vypíná (enabled: false).channel(jedna z hodnotheureka,zbozi,google_merchant,glami,favi,biano,meta_catalogamicrosoft_merchant; nepovinný): Jen feedy: který srovnávač. Povinné ufeed_channel,feed_categoryifeed_item.entityId(UUID; nepovinný): ID existující položky (UUID) zeshopzi_list_marketing. Vynechte pro založení nové. Ufeed_itemje to ID VARIANTY produktu (zeshopzi_get_product).fields(objekt; nepovinný): Pole ke změně. Vynechané pole zůstane beze změny. Uoperation: deletese nepoužívá.fields.title(text; nepovinný): Jenpopup: nadpis okna, nejvýše 60 znaků. Povinný při zakládání.fields.content(text nebonull; nepovinný): Jenpopup: text okna (HTML), nejvýše 1000 znaků prostého textu.fields.template(jedna z hodnotannouncement,promo,welcome,newsletteradiscount_code; nepovinný): Jenpopup: vzhled okna.discount_codenavíc vyžadujediscountCodeId.fields.ctaText(text nebonull; nepovinný): Jenpopup: text tlačítka, nejvýše 50 znaků.fields.imageUrl(text nebonull; nepovinný): Jenpopup: adresa obrázku v okně.fields.delaySeconds(celé číslo od 0 do 120; nepovinný): Jenpopup: za kolik sekund se okno ukáže (0 až 120).fields.isDismissible(truenebofalse; nepovinný): Jenpopup: lze okno zavřít křížkem.fields.showFrequency(jedna z hodnotonce_session,once_everaevery_visit; nepovinný): Jenpopup: once_session = jednou za návštěvu, once_ever = jednou navždy, every_visit = pokaždé.fields.discountCodeId(UUID nebonull; nepovinný): Jenpopup: ID slevového kódu (UUID), který okno nabízí. Povinné u šablonydiscount_code.fields.isActive(truenebofalse; nepovinný): Jenpopup:falsezhasne,truerozsvítí existující okno, jen když žádné jiné nesvítí.fields.subject(text nebonull; nepovinný): Jencampaign: předmět e-mailu.fields.preheader(text nebonull; nepovinný): Jencampaign: úvodní řádek, který se ukáže v seznamu zpráv vedle předmětu.fields.bodyHtml(text nebonull; nepovinný): Jencampaign: tělo e-mailu (HTML).fields.ctaLabel(text nebonull; nepovinný): Jencampaign: text tlačítka v e-mailu.fields.couponCode(text nebonull; nepovinný): Jencampaign: slevový kód uvedený v e-mailu. Kód se tím nezakládá, jen se do zprávy vypíše.fields.segmentId(UUID nebonull; nepovinný): Jencampaign: ID segmentu (UUID), kterému je kampaň určená. Neodesílá, jen vybírá publikum.fields.description(text nebonull; nepovinný): Jensegment: k čemu segment je. Vidí ho jen obchodník.fields.criteria(objekt nebonull; nepovinný): Jensegment: pravidlo výběru.all= všechny podmínky zároveň,any= aspoň jedna. Segment bez podmínek nevybere NIKOHO (prázdné pravidlo se schválně nepřekládá na „všichni“).total_spent_minorje v haléřích,within_days/older_than_daysberou počet dní.fields.criteria.all(pole objektů, nejvýš 20 položek; nepovinný)fields.criteria.all[].field(jedna z hodnotnewsletter_subscribed,sms_marketing_consent,auth_provider,customer_group_id,marketing_tags,orders_count,total_spent_minor,last_order_at,first_order_at,created_at,locale,is_businessab2b_status; povinný)fields.criteria.all[].op(jedna z hodnoteq,neq,gt,gte,lt,lte,contains,has_tag,within_days,older_than_days,is_setais_not_set; povinný)fields.criteria.all[].value(text nebo číslo nebotruenebofalsenebonull; nepovinný)fields.criteria.any(pole objektů, nejvýš 20 položek; nepovinný)fields.criteria.any[].field(jedna z hodnotnewsletter_subscribed,sms_marketing_consent,auth_provider,customer_group_id,marketing_tags,orders_count,total_spent_minor,last_order_at,first_order_at,created_at,locale,is_businessab2b_status; povinný)fields.criteria.any[].op(jedna z hodnoteq,neq,gt,gte,lt,lte,contains,has_tag,within_days,older_than_days,is_setais_not_set; povinný)fields.criteria.any[].value(text nebo číslo nebotruenebofalsenebonull; nepovinný)fields.name(text; nepovinný):campaignasegment: název. Vidí ho jen obchodník. Povinný při zakládání.fields.ctaUrl(text nebonull; nepovinný):popupacampaign: adresa tlačítka. U okna buď cesta v obchodě (např. /produkty), nebo odkaz na https://.fields.enabled(truenebofalse; nepovinný): Jenfeed_channel: zapnout kanál.trueZVEŘEJNÍ adresu s katalogem, ze které si ho srovnávač stahuje;falseji zase zavře a nastavení zůstane zachované.fields.defaultCpcMinor(celé číslo aspoň 0 nebonull; nepovinný): Jenfeed_channel: výchozí cena za proklik v HALÉŘÍCH (2 Kč = 200). Čtou ji Heureka a Zboží.cz.nullji zruší.fields.includeOutOfStock(truenebofalse; nepovinný): Jenfeed_channel: posílat i zboží, které není skladem.falseho z feedu vynechá.fields.categories(pole objektů; nepovinný): Jenfeed_category: kategorie k zařazení (i víc najednou). Uoperation: deletestačí u každécategoryId.fields.categories[].categoryId(UUID; povinný): ID kategorie obchodu zeshopzi_list_catalog(resourcecategories).fields.categories[].externalCategoryId(text nebonull; nepovinný): Číslo kategorie ve stromu srovnávače. Čte ho Google, Meta a Microsoft; neexistující číslo nástroj odmítne.fields.categories[].externalCategoryPath(text nebonull; nepovinný): Cesta ve stromu srovnávače, například „Heureka.cz | Dům a zahrada | Nábytek“. Čte ji Heureka, Zboží.cz, Glami, Favi i Biano.fields.exclude(truenebofalse; nepovinný): Jenfeed_item:truepoložku z feedu vyřadí,falseji tam vrátí.fields.availability(jedna z hodnotin_stockaout_of_stock, nebonull; nepovinný): Jenfeed_item: přebije dostupnost hlášenou srovnávači.nullvrátí rozhodování skladu.idempotencyKey(text, 1 až 200 znaků; nepovinný): Klíč idempotence. Stejný klíč = stejný zápis: opakované volání vrátí původní výsledek a NEZAPÍŠE podruhé. Použijte vlastní náhodný řetězec pro každou zamýšlenou změnu; při opakování po chybě sítě pošlete tentýž.