@koda-sl/baker-cli 0.489.0 → 0.490.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +169 -7
- package/dist/{account-Z65CPOWE.js → account-3H6BZO5H.js} +2 -2
- package/dist/account-IKFDY52P.js +138 -0
- package/dist/account-IKFDY52P.js.map +1 -0
- package/dist/account-assets-LKZVWZAR.js +289 -0
- package/dist/account-assets-LKZVWZAR.js.map +1 -0
- package/dist/account-level-UJOZDVXY.js +608 -0
- package/dist/account-level-UJOZDVXY.js.map +1 -0
- package/dist/{account-writes-4N2MA2ZR.js → account-writes-AE5IJGGW.js} +2 -2
- package/dist/{accounts-UA2ZWRN4.js → accounts-K4INATCW.js} +2 -2
- package/dist/{activities-IQPJPP4B.js → activities-T253KK4Q.js} +4 -4
- package/dist/{ad-group-writes-EUTMPBMK.js → ad-group-writes-VRSBI2Z2.js} +2 -2
- package/dist/{ad-groups-OVPAI5RM.js → ad-groups-IEBVEAMS.js} +6 -6
- package/dist/{ad-writes-DACTYFEO.js → ad-writes-ALV4KFPZ.js} +2 -2
- package/dist/{ads-L65JIKCD.js → ads-CQZHD7FC.js} +7 -7
- package/dist/{ads-G6AS5L7G.js → ads-QIKZ6O2N.js} +5 -5
- package/dist/{ads-HXX2IAFF.js → ads-ZEY72UBN.js} +14 -13
- package/dist/ads-ZEY72UBN.js.map +1 -0
- package/dist/{adsets-LPN6WFGF.js → adsets-5H3MOT3D.js} +15 -14
- package/dist/{adsets-LPN6WFGF.js.map → adsets-5H3MOT3D.js.map} +1 -1
- package/dist/{analytics-QKP3A5F3.js → analytics-ALOZ7ZZ4.js} +1 -1
- package/dist/asset-writes-L5TMKIZC.js +47 -0
- package/dist/audience-writes-X52VG35Y.js +324 -0
- package/dist/audience-writes-X52VG35Y.js.map +1 -0
- package/dist/{audiences-RPLVMO4H.js → audiences-AAZH56WD.js} +2 -2
- package/dist/{audiences-XEZHACKH.js → audiences-X3RLGOVM.js} +12 -6
- package/dist/audiences-X3RLGOVM.js.map +1 -0
- package/dist/{avatars-MXTI74VC.js → avatars-YSFFRHDK.js} +1 -1
- package/dist/{brief-BN4UGUXF.js → brief-7S6XCJIA.js} +15 -15
- package/dist/{businesses-PRRYPR7H.js → businesses-H3HIDQX6.js} +2 -2
- package/dist/{campaign-writes-BAFB5E7A.js → campaign-writes-7ZF57KLH.js} +3 -3
- package/dist/campaign-writes-7ZF57KLH.js.map +1 -0
- package/dist/{campaign-writes-U5LTDTYK.js → campaign-writes-U5PUVSMT.js} +2 -2
- package/dist/{campaigns-4SOLY7OR.js → campaigns-AV6G3AUU.js} +32 -15
- package/dist/campaigns-AV6G3AUU.js.map +1 -0
- package/dist/{campaigns-TFEQTSO3.js → campaigns-JEIKY2M4.js} +6 -6
- package/dist/{campaigns-NR6TNQFN.js → campaigns-VTRMKSAT.js} +5 -5
- package/dist/{canvas-GJAQAVS6.js → canvas-SVJEQO4V.js} +13 -13
- package/dist/{catalog-USZL4SGX.js → catalog-S32MX453.js} +5 -5
- package/dist/{catalogs-A7XMEEEP.js → catalogs-OCVXZLIF.js} +2 -2
- package/dist/catalogs-RXJTZTVX.js +778 -0
- package/dist/catalogs-RXJTZTVX.js.map +1 -0
- package/dist/{chatgpt-4PEWDJKP.js → chatgpt-QVF2FD3E.js} +12 -12
- package/dist/{chats-INN2OHSH.js → chats-QG72JB6Y.js} +22 -8
- package/dist/chats-QG72JB6Y.js.map +1 -0
- package/dist/{check-MMJGFFZS.js → check-SLNHVYGS.js} +4 -4
- package/dist/{chunk-7RBJ2Z7Z.js → chunk-2C7AHPM4.js} +25 -6
- package/dist/chunk-2C7AHPM4.js.map +1 -0
- package/dist/{chunk-KPYDTIAI.js → chunk-2WZI36D3.js} +2 -2
- package/dist/{chunk-FUKDI2UK.js → chunk-3W6G6ARX.js} +2 -2
- package/dist/{chunk-JWSEPW7F.js → chunk-46GWHUKN.js} +2 -2
- package/dist/{chunk-3TZVZXM6.js → chunk-4KJMLYCD.js} +6 -6
- package/dist/{chunk-6JWEGFM5.js → chunk-5C35OW7L.js} +38 -7
- package/dist/chunk-5C35OW7L.js.map +1 -0
- package/dist/chunk-5GQCN2QZ.js +391 -0
- package/dist/chunk-5GQCN2QZ.js.map +1 -0
- package/dist/{chunk-KIGGMKAE.js → chunk-65Y3RCWP.js} +4 -2
- package/dist/chunk-65Y3RCWP.js.map +1 -0
- package/dist/{chunk-R3EKM2P2.js → chunk-6NCJGU6I.js} +5 -5
- package/dist/chunk-A4MVVPJ2.js +4204 -0
- package/dist/chunk-A4MVVPJ2.js.map +1 -0
- package/dist/{chunk-LPXSM2DI.js → chunk-AO45BX6Q.js} +3 -3
- package/dist/{chunk-3UXMQ3K2.js → chunk-AQM4JH62.js} +2 -2
- package/dist/chunk-AQM4JH62.js.map +1 -0
- package/dist/{chunk-NPMAATZG.js → chunk-C7NWUCLQ.js} +2 -2
- package/dist/chunk-CP4P6YKM.js +287 -0
- package/dist/chunk-CP4P6YKM.js.map +1 -0
- package/dist/{chunk-OWA7ZLC4.js → chunk-D4CKCNGW.js} +4 -4
- package/dist/{chunk-H5HDZ7IC.js → chunk-DCBZ5CHZ.js} +4 -4
- package/dist/{chunk-C6EYCD5J.js → chunk-FVHJCERJ.js} +5 -5
- package/dist/{chunk-BITS62MF.js → chunk-G6XKD7QE.js} +2 -2
- package/dist/{chunk-QE3JEJXF.js → chunk-GSZZLW5Q.js} +4 -4
- package/dist/chunk-HLVRHBKL.js +1078 -0
- package/dist/chunk-HLVRHBKL.js.map +1 -0
- package/dist/{chunk-TPANP5A2.js → chunk-JKJQWRLO.js} +2 -2
- package/dist/{chunk-62JQQUAU.js → chunk-JQH5VG6F.js} +2 -2
- package/dist/{chunk-6WXV5GTA.js → chunk-JVH5A3XC.js} +2 -2
- package/dist/{chunk-AVNSH2JE.js → chunk-KOXDXSKN.js} +7 -7
- package/dist/{chunk-2XRMPSEV.js → chunk-LXQB4ZGE.js} +2 -2
- package/dist/{chunk-ZL23HA4N.js → chunk-M6PN3VH6.js} +2 -2
- package/dist/{chunk-TZEVD4Q6.js → chunk-P5FRWPG7.js} +2 -2
- package/dist/{chunk-CSZFZKVX.js → chunk-PQJXIY64.js} +5 -5
- package/dist/{chunk-OP7DNHD2.js → chunk-QTOZ32SU.js} +27 -1
- package/dist/chunk-QTOZ32SU.js.map +1 -0
- package/dist/chunk-SVAB6KV5.js +219 -0
- package/dist/chunk-SVAB6KV5.js.map +1 -0
- package/dist/{chunk-LBO2YAZY.js → chunk-UNX6BS4U.js} +15 -15
- package/dist/{chunk-UWXDNVS5.js → chunk-ZJSGGJ5R.js} +2 -2
- package/dist/cli.js +20 -20
- package/dist/{connect-WBGCBBFJ.js → connect-S54TJ6OV.js} +3 -3
- package/dist/{conversion-writes-JU7Q2MUO.js → conversion-writes-ECZBVY7D.js} +2 -2
- package/dist/{conversions-3ISBR3TS.js → conversions-5QCSCRLI.js} +3 -3
- package/dist/copy-writes-D2RTHAL6.js +167 -0
- package/dist/copy-writes-D2RTHAL6.js.map +1 -0
- package/dist/{creatives-VQO2TKE3.js → creatives-5I3G5YP3.js} +2 -2
- package/dist/{creatives-YJ3CXZQC.js → creatives-MZ6ICNSY.js} +5 -4
- package/dist/{creatives-YJ3CXZQC.js.map → creatives-MZ6ICNSY.js.map} +1 -1
- package/dist/{creatives-S5QUWUL6.js → creatives-PCAGWPW3.js} +10 -10
- package/dist/{critique-5LCG5TYF.js → critique-NRHUPIWF.js} +7 -7
- package/dist/{custom-conversions-YRYE65PU.js → custom-conversions-FIP6ZS34.js} +5 -3
- package/dist/{custom-conversions-YRYE65PU.js.map → custom-conversions-FIP6ZS34.js.map} +1 -1
- package/dist/{draft-Y2QJE2NM.js → draft-34CGWUVA.js} +2 -2
- package/dist/{draft-GPN3HOAG.js → draft-4P3YO67N.js} +9 -5
- package/dist/draft-4P3YO67N.js.map +1 -0
- package/dist/{draft-EWDOIXSH.js → draft-L45PGCYZ.js} +7 -3
- package/dist/draft-L45PGCYZ.js.map +1 -0
- package/dist/engine/index.js +4 -4
- package/dist/{experiment-G3FQVAJU.js → experiment-7N4QFRWV.js} +4 -4
- package/dist/{feedback-CAOZPGTT.js → feedback-O3H42V4I.js} +10 -10
- package/dist/{feedback-record-EXV5H6OS.js → feedback-record-FAPN2GBS.js} +12 -12
- package/dist/{find-EVY4XEIQ.js → find-FSQAEGGF.js} +4 -4
- package/dist/{flows-Z7355RMD.js → flows-T22B77J3.js} +3 -3
- package/dist/{funnel-2B3JXJPX.js → funnel-7OA33VRP.js} +5 -5
- package/dist/{ga4-2BL5YAYN.js → ga4-LPDIBNYP.js} +1 -1
- package/dist/{google-7STODZQR.js → google-5ESVO76E.js} +5 -5
- package/dist/{gsc-UU3T2C6B.js → gsc-FIZTQX3N.js} +1 -1
- package/dist/{history-IQ33J5PB.js → history-QKDYBSYM.js} +2 -2
- package/dist/{icon-GB7UH5RF.js → icon-CSVAZ7NE.js} +4 -4
- package/dist/{ideas-F6CIGTVU.js → ideas-JQT422P7.js} +4 -4
- package/dist/{images-WCKTD6Z2.js → images-WBNWK2ZH.js} +6 -6
- package/dist/{insights-4HT2NAYP.js → insights-YWVJMATY.js} +4 -3
- package/dist/{insights-4HT2NAYP.js.map → insights-YWVJMATY.js.map} +1 -1
- package/dist/{inspiration-XQYHBJY2.js → inspiration-IX5N724J.js} +1 -1
- package/dist/instant-experiences-NQ2GWIWL.js +257 -0
- package/dist/instant-experiences-NQ2GWIWL.js.map +1 -0
- package/dist/{landing-WUILAWDS.js → landing-Y6QCTXCZ.js} +2 -2
- package/dist/leads-THI37ZMD.js +537 -0
- package/dist/leads-THI37ZMD.js.map +1 -0
- package/dist/{learn-CC6Q5IK2.js → learn-3BDZUWDT.js} +5 -5
- package/dist/{linkedin-XKVPSCLV.js → linkedin-UGMAFSGO.js} +2 -2
- package/dist/{locations-YA7NZY44.js → locations-HM56X2MK.js} +2 -2
- package/dist/locations-HM56X2MK.js.map +1 -0
- package/dist/{logo-YSNUUT33.js → logo-VHXH4J6A.js} +3 -3
- package/dist/{make-ED7HBLH3.js → make-W2PYZXYF.js} +39 -39
- package/dist/media-H6B7VDON.js +18 -0
- package/dist/media-H6B7VDON.js.map +1 -0
- package/dist/{media-sources-PEHUMH7C.js → media-sources-EZKAJNVD.js} +1 -1
- package/dist/meta-YHDTGJQ6.js +122 -0
- package/dist/meta-YHDTGJQ6.js.map +1 -0
- package/dist/{options-6FCNFWUF.js → options-NSCZSQ5P.js} +3 -3
- package/dist/page-photos-CXRG4AXV.js +115 -0
- package/dist/page-photos-CXRG4AXV.js.map +1 -0
- package/dist/{pages-FTI44OSH.js → pages-PTWRXAZT.js} +2 -2
- package/dist/{pixels-6IUB3Y3H.js → pixels-MYT3TCHZ.js} +2 -2
- package/dist/{pixels-MBKR4XPX.js → pixels-ZZCQUS3J.js} +2 -2
- package/dist/{preview-V4YBD45S.js → preview-XOXAAPMQ.js} +73 -27
- package/dist/preview-XOXAAPMQ.js.map +1 -0
- package/dist/{rerun-A2XHGFZS.js → rerun-5THJLQQJ.js} +18 -18
- package/dist/{research-BLDY5UWH.js → research-JHDWWFL7.js} +1 -1
- package/dist/rule-writes-6ZCAJDYZ.js +522 -0
- package/dist/rule-writes-6ZCAJDYZ.js.map +1 -0
- package/dist/rules-BMYOY2BM.js +216 -0
- package/dist/rules-BMYOY2BM.js.map +1 -0
- package/dist/{rules-SK5DFFPY.js → rules-YLLFDZEM.js} +3 -3
- package/dist/{rules-add-YQNYSME7.js → rules-add-U2GU4AGP.js} +4 -4
- package/dist/{run-KBN5K7LE.js → run-V5YQB6TH.js} +18 -18
- package/dist/{scaffold-ad-6BN5LWQH.js → scaffold-ad-H4GJOKAW.js} +12 -12
- package/dist/{scaffold-static-ad-VVZRAWBR.js → scaffold-static-ad-2YIFHCTL.js} +25 -25
- package/dist/{scaffold-video-LFIYI4GP.js → scaffold-video-3EJLKR2O.js} +14 -14
- package/dist/{select-QBU6ED4K.js → select-I22NPSIW.js} +9 -9
- package/dist/{set-prompt-TL64CRBQ.js → set-prompt-S75OMQ7L.js} +8 -8
- package/dist/{shared-NDRFKAH7.js → shared-3IBNDEFL.js} +2 -2
- package/dist/{sources-RMNFV4CA.js → sources-VA23PDND.js} +1 -1
- package/dist/{stale-ITFCPOER.js → stale-MHTU2NQJ.js} +8 -8
- package/dist/{stats-RCLQE4HJ.js → stats-ZAGJH4AD.js} +1 -1
- package/dist/{stock-ECRBD7RP.js → stock-6SHHLSKG.js} +5 -5
- package/dist/studies-4NIV4D5Y.js +249 -0
- package/dist/studies-4NIV4D5Y.js.map +1 -0
- package/dist/{studio-MARZ22J2.js → studio-ZLCGXFAN.js} +1 -1
- package/dist/study-writes-L2AA2PGL.js +467 -0
- package/dist/study-writes-L2AA2PGL.js.map +1 -0
- package/dist/{sync-definition-C6ROLKJ4.js → sync-definition-2EBSQA6A.js} +11 -11
- package/dist/{tag-manager-G3LBQZUL.js → tag-manager-3CJ66GKJ.js} +1 -1
- package/dist/targeting-LNDQV4EK.js +759 -0
- package/dist/targeting-LNDQV4EK.js.map +1 -0
- package/dist/{testimonials-YMMA5YWL.js → testimonials-GR6TIS5S.js} +2 -2
- package/dist/{translate-OXVIMYHE.js → translate-GEFUP6KQ.js} +18 -18
- package/dist/{validate-ZS2M5Q3V.js → validate-NOWIOAHE.js} +11 -11
- package/dist/{videos-I6YXFBFT.js → videos-XMTDEHEJ.js} +1 -1
- package/dist/{viewer-check-7ZG7KHEN.js → viewer-check-U4XZMMS7.js} +6 -6
- package/dist/viewer-check-U4XZMMS7.js.map +1 -0
- package/dist/{winning-ads-ABN5OULS.js → winning-ads-QOAYIR5U.js} +1 -1
- package/dist/{write-commands-HCQI4Y27.js → write-commands-PEJBTME6.js} +485 -57
- package/dist/write-commands-PEJBTME6.js.map +1 -0
- package/dist/{x-WK2VQDPF.js → x-VCSMV7T5.js} +4 -4
- package/package.json +1 -1
- package/dist/account-7LUQWY6Q.js +0 -49
- package/dist/account-7LUQWY6Q.js.map +0 -1
- package/dist/ads-HXX2IAFF.js.map +0 -1
- package/dist/audiences-XEZHACKH.js.map +0 -1
- package/dist/campaign-writes-BAFB5E7A.js.map +0 -1
- package/dist/campaigns-4SOLY7OR.js.map +0 -1
- package/dist/chats-INN2OHSH.js.map +0 -1
- package/dist/chunk-3UXMQ3K2.js.map +0 -1
- package/dist/chunk-6JWEGFM5.js.map +0 -1
- package/dist/chunk-7RBJ2Z7Z.js.map +0 -1
- package/dist/chunk-GOJXKIFQ.js +0 -1605
- package/dist/chunk-GOJXKIFQ.js.map +0 -1
- package/dist/chunk-KIGGMKAE.js.map +0 -1
- package/dist/chunk-OP7DNHD2.js.map +0 -1
- package/dist/draft-EWDOIXSH.js.map +0 -1
- package/dist/draft-GPN3HOAG.js.map +0 -1
- package/dist/leads-2XOSAYP4.js +0 -293
- package/dist/leads-2XOSAYP4.js.map +0 -1
- package/dist/locations-YA7NZY44.js.map +0 -1
- package/dist/media-ES2UBGYW.js +0 -15
- package/dist/media-ES2UBGYW.js.map +0 -1
- package/dist/meta-AOIPEDV5.js +0 -69
- package/dist/meta-AOIPEDV5.js.map +0 -1
- package/dist/preview-V4YBD45S.js.map +0 -1
- package/dist/write-commands-HCQI4Y27.js.map +0 -1
- /package/dist/{account-Z65CPOWE.js.map → account-3H6BZO5H.js.map} +0 -0
- /package/dist/{account-writes-4N2MA2ZR.js.map → account-writes-AE5IJGGW.js.map} +0 -0
- /package/dist/{accounts-UA2ZWRN4.js.map → accounts-K4INATCW.js.map} +0 -0
- /package/dist/{activities-IQPJPP4B.js.map → activities-T253KK4Q.js.map} +0 -0
- /package/dist/{ad-group-writes-EUTMPBMK.js.map → ad-group-writes-VRSBI2Z2.js.map} +0 -0
- /package/dist/{ad-groups-OVPAI5RM.js.map → ad-groups-IEBVEAMS.js.map} +0 -0
- /package/dist/{ad-writes-DACTYFEO.js.map → ad-writes-ALV4KFPZ.js.map} +0 -0
- /package/dist/{ads-L65JIKCD.js.map → ads-CQZHD7FC.js.map} +0 -0
- /package/dist/{ads-G6AS5L7G.js.map → ads-QIKZ6O2N.js.map} +0 -0
- /package/dist/{analytics-QKP3A5F3.js.map → analytics-ALOZ7ZZ4.js.map} +0 -0
- /package/dist/{connect-WBGCBBFJ.js.map → asset-writes-L5TMKIZC.js.map} +0 -0
- /package/dist/{audiences-RPLVMO4H.js.map → audiences-AAZH56WD.js.map} +0 -0
- /package/dist/{avatars-MXTI74VC.js.map → avatars-YSFFRHDK.js.map} +0 -0
- /package/dist/{brief-BN4UGUXF.js.map → brief-7S6XCJIA.js.map} +0 -0
- /package/dist/{businesses-PRRYPR7H.js.map → businesses-H3HIDQX6.js.map} +0 -0
- /package/dist/{campaign-writes-U5LTDTYK.js.map → campaign-writes-U5PUVSMT.js.map} +0 -0
- /package/dist/{campaigns-TFEQTSO3.js.map → campaigns-JEIKY2M4.js.map} +0 -0
- /package/dist/{campaigns-NR6TNQFN.js.map → campaigns-VTRMKSAT.js.map} +0 -0
- /package/dist/{canvas-GJAQAVS6.js.map → canvas-SVJEQO4V.js.map} +0 -0
- /package/dist/{catalog-USZL4SGX.js.map → catalog-S32MX453.js.map} +0 -0
- /package/dist/{catalogs-A7XMEEEP.js.map → catalogs-OCVXZLIF.js.map} +0 -0
- /package/dist/{chatgpt-4PEWDJKP.js.map → chatgpt-QVF2FD3E.js.map} +0 -0
- /package/dist/{check-MMJGFFZS.js.map → check-SLNHVYGS.js.map} +0 -0
- /package/dist/{chunk-KPYDTIAI.js.map → chunk-2WZI36D3.js.map} +0 -0
- /package/dist/{chunk-FUKDI2UK.js.map → chunk-3W6G6ARX.js.map} +0 -0
- /package/dist/{chunk-JWSEPW7F.js.map → chunk-46GWHUKN.js.map} +0 -0
- /package/dist/{chunk-3TZVZXM6.js.map → chunk-4KJMLYCD.js.map} +0 -0
- /package/dist/{chunk-R3EKM2P2.js.map → chunk-6NCJGU6I.js.map} +0 -0
- /package/dist/{chunk-LPXSM2DI.js.map → chunk-AO45BX6Q.js.map} +0 -0
- /package/dist/{chunk-NPMAATZG.js.map → chunk-C7NWUCLQ.js.map} +0 -0
- /package/dist/{chunk-OWA7ZLC4.js.map → chunk-D4CKCNGW.js.map} +0 -0
- /package/dist/{chunk-H5HDZ7IC.js.map → chunk-DCBZ5CHZ.js.map} +0 -0
- /package/dist/{chunk-C6EYCD5J.js.map → chunk-FVHJCERJ.js.map} +0 -0
- /package/dist/{chunk-BITS62MF.js.map → chunk-G6XKD7QE.js.map} +0 -0
- /package/dist/{chunk-QE3JEJXF.js.map → chunk-GSZZLW5Q.js.map} +0 -0
- /package/dist/{chunk-TPANP5A2.js.map → chunk-JKJQWRLO.js.map} +0 -0
- /package/dist/{chunk-62JQQUAU.js.map → chunk-JQH5VG6F.js.map} +0 -0
- /package/dist/{chunk-6WXV5GTA.js.map → chunk-JVH5A3XC.js.map} +0 -0
- /package/dist/{chunk-AVNSH2JE.js.map → chunk-KOXDXSKN.js.map} +0 -0
- /package/dist/{chunk-2XRMPSEV.js.map → chunk-LXQB4ZGE.js.map} +0 -0
- /package/dist/{chunk-ZL23HA4N.js.map → chunk-M6PN3VH6.js.map} +0 -0
- /package/dist/{chunk-TZEVD4Q6.js.map → chunk-P5FRWPG7.js.map} +0 -0
- /package/dist/{chunk-CSZFZKVX.js.map → chunk-PQJXIY64.js.map} +0 -0
- /package/dist/{chunk-LBO2YAZY.js.map → chunk-UNX6BS4U.js.map} +0 -0
- /package/dist/{chunk-UWXDNVS5.js.map → chunk-ZJSGGJ5R.js.map} +0 -0
- /package/dist/{ideas-F6CIGTVU.js.map → connect-S54TJ6OV.js.map} +0 -0
- /package/dist/{conversion-writes-JU7Q2MUO.js.map → conversion-writes-ECZBVY7D.js.map} +0 -0
- /package/dist/{conversions-3ISBR3TS.js.map → conversions-5QCSCRLI.js.map} +0 -0
- /package/dist/{creatives-VQO2TKE3.js.map → creatives-5I3G5YP3.js.map} +0 -0
- /package/dist/{creatives-S5QUWUL6.js.map → creatives-PCAGWPW3.js.map} +0 -0
- /package/dist/{critique-5LCG5TYF.js.map → critique-NRHUPIWF.js.map} +0 -0
- /package/dist/{draft-Y2QJE2NM.js.map → draft-34CGWUVA.js.map} +0 -0
- /package/dist/{experiment-G3FQVAJU.js.map → experiment-7N4QFRWV.js.map} +0 -0
- /package/dist/{feedback-CAOZPGTT.js.map → feedback-O3H42V4I.js.map} +0 -0
- /package/dist/{feedback-record-EXV5H6OS.js.map → feedback-record-FAPN2GBS.js.map} +0 -0
- /package/dist/{find-EVY4XEIQ.js.map → find-FSQAEGGF.js.map} +0 -0
- /package/dist/{flows-Z7355RMD.js.map → flows-T22B77J3.js.map} +0 -0
- /package/dist/{funnel-2B3JXJPX.js.map → funnel-7OA33VRP.js.map} +0 -0
- /package/dist/{ga4-2BL5YAYN.js.map → ga4-LPDIBNYP.js.map} +0 -0
- /package/dist/{google-7STODZQR.js.map → google-5ESVO76E.js.map} +0 -0
- /package/dist/{gsc-UU3T2C6B.js.map → gsc-FIZTQX3N.js.map} +0 -0
- /package/dist/{history-IQ33J5PB.js.map → history-QKDYBSYM.js.map} +0 -0
- /package/dist/{icon-GB7UH5RF.js.map → icon-CSVAZ7NE.js.map} +0 -0
- /package/dist/{logo-YSNUUT33.js.map → ideas-JQT422P7.js.map} +0 -0
- /package/dist/{images-WCKTD6Z2.js.map → images-WBNWK2ZH.js.map} +0 -0
- /package/dist/{inspiration-XQYHBJY2.js.map → inspiration-IX5N724J.js.map} +0 -0
- /package/dist/{landing-WUILAWDS.js.map → landing-Y6QCTXCZ.js.map} +0 -0
- /package/dist/{learn-CC6Q5IK2.js.map → learn-3BDZUWDT.js.map} +0 -0
- /package/dist/{linkedin-XKVPSCLV.js.map → linkedin-UGMAFSGO.js.map} +0 -0
- /package/dist/{run-KBN5K7LE.js.map → logo-VHXH4J6A.js.map} +0 -0
- /package/dist/{make-ED7HBLH3.js.map → make-W2PYZXYF.js.map} +0 -0
- /package/dist/{media-sources-PEHUMH7C.js.map → media-sources-EZKAJNVD.js.map} +0 -0
- /package/dist/{options-6FCNFWUF.js.map → options-NSCZSQ5P.js.map} +0 -0
- /package/dist/{pages-FTI44OSH.js.map → pages-PTWRXAZT.js.map} +0 -0
- /package/dist/{pixels-6IUB3Y3H.js.map → pixels-MYT3TCHZ.js.map} +0 -0
- /package/dist/{pixels-MBKR4XPX.js.map → pixels-ZZCQUS3J.js.map} +0 -0
- /package/dist/{rerun-A2XHGFZS.js.map → rerun-5THJLQQJ.js.map} +0 -0
- /package/dist/{research-BLDY5UWH.js.map → research-JHDWWFL7.js.map} +0 -0
- /package/dist/{rules-SK5DFFPY.js.map → rules-YLLFDZEM.js.map} +0 -0
- /package/dist/{rules-add-YQNYSME7.js.map → rules-add-U2GU4AGP.js.map} +0 -0
- /package/dist/{shared-NDRFKAH7.js.map → run-V5YQB6TH.js.map} +0 -0
- /package/dist/{scaffold-ad-6BN5LWQH.js.map → scaffold-ad-H4GJOKAW.js.map} +0 -0
- /package/dist/{scaffold-static-ad-VVZRAWBR.js.map → scaffold-static-ad-2YIFHCTL.js.map} +0 -0
- /package/dist/{scaffold-video-LFIYI4GP.js.map → scaffold-video-3EJLKR2O.js.map} +0 -0
- /package/dist/{select-QBU6ED4K.js.map → select-I22NPSIW.js.map} +0 -0
- /package/dist/{set-prompt-TL64CRBQ.js.map → set-prompt-S75OMQ7L.js.map} +0 -0
- /package/dist/{sync-definition-C6ROLKJ4.js.map → shared-3IBNDEFL.js.map} +0 -0
- /package/dist/{sources-RMNFV4CA.js.map → sources-VA23PDND.js.map} +0 -0
- /package/dist/{stale-ITFCPOER.js.map → stale-MHTU2NQJ.js.map} +0 -0
- /package/dist/{stats-RCLQE4HJ.js.map → stats-ZAGJH4AD.js.map} +0 -0
- /package/dist/{stock-ECRBD7RP.js.map → stock-6SHHLSKG.js.map} +0 -0
- /package/dist/{studio-MARZ22J2.js.map → studio-ZLCGXFAN.js.map} +0 -0
- /package/dist/{viewer-check-7ZG7KHEN.js.map → sync-definition-2EBSQA6A.js.map} +0 -0
- /package/dist/{tag-manager-G3LBQZUL.js.map → tag-manager-3CJ66GKJ.js.map} +0 -0
- /package/dist/{testimonials-YMMA5YWL.js.map → testimonials-GR6TIS5S.js.map} +0 -0
- /package/dist/{translate-OXVIMYHE.js.map → translate-GEFUP6KQ.js.map} +0 -0
- /package/dist/{validate-ZS2M5Q3V.js.map → validate-NOWIOAHE.js.map} +0 -0
- /package/dist/{videos-I6YXFBFT.js.map → videos-XMTDEHEJ.js.map} +0 -0
- /package/dist/{winning-ads-ABN5OULS.js.map → winning-ads-QOAYIR5U.js.map} +0 -0
- /package/dist/{x-WK2VQDPF.js.map → x-VCSMV7T5.js.map} +0 -0
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
adSetDeliveryArgs,
|
|
3
|
+
adSetDeliveryFromFlags,
|
|
4
|
+
boostEditArgs,
|
|
5
|
+
boostEditsFromFlags,
|
|
6
|
+
budgetBoostArg,
|
|
7
|
+
budgetBoostsFromFlags,
|
|
8
|
+
clearArg,
|
|
9
|
+
clearFromFlags
|
|
10
|
+
} from "./chunk-CP4P6YKM.js";
|
|
1
11
|
import {
|
|
2
12
|
bareAccountId,
|
|
3
13
|
failWriteValidation,
|
|
@@ -8,15 +18,22 @@ import {
|
|
|
8
18
|
parseDateFlag,
|
|
9
19
|
parseMoneyFlag,
|
|
10
20
|
refuseDeleteByUpdate,
|
|
21
|
+
repeatedListFlag,
|
|
11
22
|
requireTarget,
|
|
12
23
|
stageOp,
|
|
13
24
|
stageStatusChange,
|
|
14
25
|
upper
|
|
15
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-5C35OW7L.js";
|
|
16
27
|
import {
|
|
17
28
|
buildCustomConversionRule
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import
|
|
29
|
+
} from "./chunk-A4MVVPJ2.js";
|
|
30
|
+
import {
|
|
31
|
+
VISUAL_ENHANCEMENT_FEATURES
|
|
32
|
+
} from "./chunk-HLVRHBKL.js";
|
|
33
|
+
import "./chunk-QTOZ32SU.js";
|
|
34
|
+
import {
|
|
35
|
+
repeatedValues
|
|
36
|
+
} from "./chunk-ERSX3MKH.js";
|
|
20
37
|
import "./chunk-SFJW2KED.js";
|
|
21
38
|
import "./chunk-4NZ47VXO.js";
|
|
22
39
|
import "./chunk-D5FY4FAK.js";
|
|
@@ -37,6 +54,72 @@ import "./chunk-YQSBHWOI.js";
|
|
|
37
54
|
|
|
38
55
|
// src/commands/ads/meta/write-commands.ts
|
|
39
56
|
import { defineCommand } from "citty";
|
|
57
|
+
|
|
58
|
+
// src/commands/ads/meta/creative-flags.ts
|
|
59
|
+
function parseEnroll(value) {
|
|
60
|
+
const raw = String(value).toLowerCase();
|
|
61
|
+
if (raw === "on" || raw === "true" || raw === "opt_in") return "OPT_IN";
|
|
62
|
+
if (raw === "off" || raw === "false" || raw === "opt_out") return "OPT_OUT";
|
|
63
|
+
failWriteValidation("--standard-enhancements must be on|off");
|
|
64
|
+
}
|
|
65
|
+
function creativeEnhancementsFromFlags(args, rawArgs) {
|
|
66
|
+
const visual = repeatedValues(rawArgs, "visual-enhancement", args["visual-enhancement"]);
|
|
67
|
+
const unknown = visual.filter((feature) => !(feature in VISUAL_ENHANCEMENT_FEATURES));
|
|
68
|
+
if (unknown.length > 0) {
|
|
69
|
+
failWriteValidation(
|
|
70
|
+
`--visual-enhancement ${unknown.join(", ")} is not a feature that changes the media \u2014 one of ${Object.keys(VISUAL_ENHANCEMENT_FEATURES).join(", ")}`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
const standard = args["standard-enhancements"] !== void 0 ? parseEnroll(args["standard-enhancements"]) : void 0;
|
|
74
|
+
if (!standard && visual.length === 0) return void 0;
|
|
75
|
+
return {
|
|
76
|
+
...standard ? { standardEnhancements: standard } : {},
|
|
77
|
+
...visual.length > 0 ? { features: Object.fromEntries(visual.map((feature) => [feature, "OPT_IN"])) } : {}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function carouselFlags(args) {
|
|
81
|
+
const order = args["card-order"];
|
|
82
|
+
if (order !== void 0 && order !== "fixed" && order !== "optimized") {
|
|
83
|
+
failWriteValidation("--card-order must be fixed (the order you built) or optimized (Meta reorders)");
|
|
84
|
+
}
|
|
85
|
+
const endCard = args["end-card"];
|
|
86
|
+
return {
|
|
87
|
+
...order !== void 0 ? { card_order: String(order) } : {},
|
|
88
|
+
...endCard !== void 0 ? { end_card: parseEnroll(endCard) === "OPT_IN" } : {}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function welcomeMessageFromFlags(args, rawArgs) {
|
|
92
|
+
const breakers = repeatedValues(rawArgs, "ice-breaker", args["ice-breaker"]).map((entry) => {
|
|
93
|
+
const [question, ...rest] = entry.split("=>");
|
|
94
|
+
const answer = rest.join("=>").trim();
|
|
95
|
+
if (!question?.trim() || !answer) {
|
|
96
|
+
failWriteValidation(`--ice-breaker takes "Question => Answer" \u2014 got "${entry}"`);
|
|
97
|
+
}
|
|
98
|
+
return { question: question.trim(), answer };
|
|
99
|
+
});
|
|
100
|
+
if (args.greeting === void 0 && breakers.length === 0 && args.autofill === void 0) return void 0;
|
|
101
|
+
return {
|
|
102
|
+
...args.greeting !== void 0 ? { greeting: String(args.greeting) } : {},
|
|
103
|
+
...breakers.length > 0 ? { iceBreakers: breakers } : {},
|
|
104
|
+
...args.autofill !== void 0 ? { autofill: String(args.autofill) } : {}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
var BUTTON_OPENS = {
|
|
108
|
+
MESSAGE_PAGE: "MESSENGER",
|
|
109
|
+
WHATSAPP_MESSAGE: "WHATSAPP",
|
|
110
|
+
INSTAGRAM_MESSAGE: "INSTAGRAM_DIRECT"
|
|
111
|
+
};
|
|
112
|
+
function conversationAndAppCta(args) {
|
|
113
|
+
const cta = args.cta === void 0 ? void 0 : String(args.cta).toUpperCase();
|
|
114
|
+
const destination = args["app-destination"] !== void 0 ? String(args["app-destination"]).toUpperCase() : cta ? BUTTON_OPENS[cta] : void 0;
|
|
115
|
+
return {
|
|
116
|
+
...destination ? { app_destination: destination } : {},
|
|
117
|
+
...args["deep-link"] !== void 0 ? { app_link: String(args["deep-link"]) } : {},
|
|
118
|
+
...args["app-id"] !== void 0 ? { application: String(args["app-id"]) } : {}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// src/commands/ads/meta/write-commands.ts
|
|
40
123
|
var STAGED_NOTE = "Staged until publish \u2014 review with `baker ads meta draft`.";
|
|
41
124
|
var accountArgs = {
|
|
42
125
|
"account-id": { type: "string", description: "Numeric account ID or act_N" }
|
|
@@ -55,7 +138,8 @@ function campaignPayloadFromFlags(args) {
|
|
|
55
138
|
spendCap: parseMoneyFlag(args["spend-cap"], args.currency, "--spend-cap"),
|
|
56
139
|
adSetBudgetSharing: args["adset-budget-sharing"] === void 0 ? void 0 : Boolean(args["adset-budget-sharing"]),
|
|
57
140
|
start_time: parseDateFlag(args.start, "--start"),
|
|
58
|
-
stop_time: parseDateFlag(args.stop, "--stop")
|
|
141
|
+
stop_time: parseDateFlag(args.stop, "--stop"),
|
|
142
|
+
promoted_object: args["catalog-id"] ? { product_catalog_id: String(args["catalog-id"]) } : void 0
|
|
59
143
|
};
|
|
60
144
|
}
|
|
61
145
|
var campaignBudgetArgs = {
|
|
@@ -68,13 +152,16 @@ var campaignBudgetArgs = {
|
|
|
68
152
|
description: "LOWEST_COST_WITHOUT_CAP|LOWEST_COST_WITH_BID_CAP|COST_CAP|LOWEST_COST_WITH_MIN_ROAS"
|
|
69
153
|
},
|
|
70
154
|
start: { type: "string", description: "Start time (ISO date or epoch ms)" },
|
|
71
|
-
stop: { type: "string", description: "Stop time" }
|
|
155
|
+
stop: { type: "string", description: "Stop time" },
|
|
156
|
+
...budgetBoostArg
|
|
72
157
|
};
|
|
73
158
|
var campaignsCreateCommand = defineCommand({
|
|
74
159
|
meta: {
|
|
75
160
|
name: "create",
|
|
76
161
|
description: `Stage a new campaign. ${STAGED_NOTE}
|
|
77
|
-
Example: baker ads meta campaigns create --name "Q3 Prospecting" --objective OUTCOME_LEADS --daily-budget 50
|
|
162
|
+
Example: baker ads meta campaigns create --name "Q3 Prospecting" --objective OUTCOME_LEADS --daily-budget 50
|
|
163
|
+
Advantage+ (Meta's own "Advantage+ campaign" state) is not a setting: it follows from a campaign budget here, Advantage+ audience (targeting_automation.advantage_audience 1) and automatic placements (no placement lists) on every ad set. Read it back with \`baker ads meta campaigns --fields id,name,advantage_state_info\`.
|
|
164
|
+
Black Friday boost: baker ads meta campaigns create --name "BF" --objective OUTCOME_SALES --daily-budget 50 --budget-boost 2027-11-27T00:00Z..2027-11-28T00:00Z=+100%`
|
|
78
165
|
},
|
|
79
166
|
args: {
|
|
80
167
|
...accountArgs,
|
|
@@ -92,11 +179,18 @@ Example: baker ads meta campaigns create --name "Q3 Prospecting" --objective OUT
|
|
|
92
179
|
description: "Let ad sets lend up to 20% of their budget to each other (off unless set; ignored with a campaign budget)"
|
|
93
180
|
},
|
|
94
181
|
...campaignBudgetArgs,
|
|
182
|
+
"catalog-id": {
|
|
183
|
+
type: "string",
|
|
184
|
+
description: "Advantage+ catalog ads: the product catalog the campaign sells from (OUTCOME_SALES) \u2014 from `baker ads meta catalogs`. Fixed at creation; each ad set then names one of its product sets with --product-set-id"
|
|
185
|
+
},
|
|
95
186
|
file: { type: "string", description: "JSON file with the full payload; flags override file keys" }
|
|
96
187
|
},
|
|
97
|
-
run: async ({ args }) => {
|
|
188
|
+
run: async ({ args, rawArgs }) => {
|
|
98
189
|
const accountId = bareAccountId(args);
|
|
99
|
-
const payload = mergePayload(loadJsonFileArg(args.file),
|
|
190
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
191
|
+
...campaignPayloadFromFlags(args),
|
|
192
|
+
budgetSchedules: budgetBoostsFromFlags(args, rawArgs)
|
|
193
|
+
});
|
|
100
194
|
await stageOp({ kind: "campaign.create", accountId, payload });
|
|
101
195
|
}
|
|
102
196
|
});
|
|
@@ -104,7 +198,9 @@ var campaignsUpdateCommand = defineCommand({
|
|
|
104
198
|
meta: {
|
|
105
199
|
name: "update",
|
|
106
200
|
description: `Stage changes to a campaign. ${STAGED_NOTE}
|
|
107
|
-
Pass a meta_temp_* ref to amend a campaign staged in this chat. Example: baker ads meta campaigns update 6123 --daily-budget 80
|
|
201
|
+
Pass a meta_temp_* ref to amend a campaign staged in this chat. Example: baker ads meta campaigns update 6123 --daily-budget 80
|
|
202
|
+
Budget boosts on a live campaign need its daily budget restated in the same command (Meta reads it from the request): baker ads meta campaigns update 6123 --daily-budget 50 --budget-boost 2027-11-27T00:00Z..2027-11-28T00:00Z=+25
|
|
203
|
+
A boost is ADDED to the ones the campaign has (Meta keeps them, even overlapping); take them all away with --clear boosts, or one at a time with --remove-boost / --move-boost (ids from \`baker ads meta high-demand-periods --campaign-id 6123\`): baker ads meta campaigns update 6123 --move-boost 1633135568548763=2027-11-27T06:00Z..2027-11-27T12:00Z`
|
|
108
204
|
},
|
|
109
205
|
args: {
|
|
110
206
|
id: { type: "positional", description: "Campaign id or meta_temp_* ref", required: true },
|
|
@@ -112,13 +208,18 @@ Pass a meta_temp_* ref to amend a campaign staged in this chat. Example: baker a
|
|
|
112
208
|
name: { type: "string", description: "New name" },
|
|
113
209
|
status: { type: "string", description: "ACTIVE|PAUSED|ARCHIVED" },
|
|
114
210
|
...campaignBudgetArgs,
|
|
211
|
+
clear: { type: "string", description: "boosts \u2014 take away every budget boost the campaign has now" },
|
|
212
|
+
...boostEditArgs,
|
|
115
213
|
file: { type: "string", description: "JSON file with fields to change" }
|
|
116
214
|
},
|
|
117
|
-
run: async ({ args }) => {
|
|
215
|
+
run: async ({ args, rawArgs }) => {
|
|
118
216
|
const accountId = bareAccountId(args);
|
|
119
217
|
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
120
218
|
name: args.name,
|
|
121
219
|
status: upper(args.status),
|
|
220
|
+
budgetSchedules: budgetBoostsFromFlags(args, rawArgs),
|
|
221
|
+
clear: clearOrFail(rawArgs, "campaign"),
|
|
222
|
+
...boostEditsFromFlags(args, rawArgs),
|
|
122
223
|
bid_strategy: upper(args["bid-strategy"]),
|
|
123
224
|
dailyBudget: parseMoneyFlag(args["daily-budget"], args.currency, "--daily-budget"),
|
|
124
225
|
lifetimeBudget: parseMoneyFlag(args["lifetime-budget"], args.currency, "--lifetime-budget"),
|
|
@@ -135,9 +236,18 @@ Pass a meta_temp_* ref to amend a campaign staged in this chat. Example: baker a
|
|
|
135
236
|
});
|
|
136
237
|
}
|
|
137
238
|
});
|
|
138
|
-
function
|
|
239
|
+
function clearOrFail(rawArgs, entity) {
|
|
240
|
+
try {
|
|
241
|
+
return clearFromFlags(rawArgs, entity);
|
|
242
|
+
} catch (err) {
|
|
243
|
+
failWriteValidation(err instanceof Error ? err.message : String(err));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
function adSetPayloadFromFlags(args, rawArgs, file) {
|
|
139
247
|
const promotedObject = args["promoted-object-file"] ? loadJsonFileArg(args["promoted-object-file"]) : buildPromotedObject(args);
|
|
140
248
|
return {
|
|
249
|
+
...adSetDeliveryFromFlags(args, rawArgs),
|
|
250
|
+
budgetSchedules: budgetBoostsFromFlags(args, rawArgs),
|
|
141
251
|
name: args.name,
|
|
142
252
|
campaign_id: args.campaign,
|
|
143
253
|
status: upper(args.status),
|
|
@@ -150,16 +260,41 @@ function adSetPayloadFromFlags(args) {
|
|
|
150
260
|
bid_strategy: upper(args["bid-strategy"]),
|
|
151
261
|
start_time: parseDateFlag(args.start, "--start"),
|
|
152
262
|
end_time: parseDateFlag(args.end, "--end"),
|
|
153
|
-
targeting: args
|
|
263
|
+
targeting: targetingFromFlags(args, rawArgs, targetingOf(file)),
|
|
264
|
+
rf_prediction_id: args.reservation,
|
|
154
265
|
promoted_object: promotedObject && Object.keys(promotedObject).length > 0 ? promotedObject : void 0
|
|
155
266
|
};
|
|
156
267
|
}
|
|
268
|
+
function targetingOf(file) {
|
|
269
|
+
const targeting = file.targeting;
|
|
270
|
+
return targeting && typeof targeting === "object" && !Array.isArray(targeting) ? targeting : void 0;
|
|
271
|
+
}
|
|
272
|
+
function targetingFromFlags(args, rawArgs, fileTargeting) {
|
|
273
|
+
const file = args["targeting-file"] ? loadJsonFileArg(args["targeting-file"]) : void 0;
|
|
274
|
+
const base = file ?? fileTargeting;
|
|
275
|
+
const lists = repeatedValues(rawArgs, "block-list", args["block-list"]);
|
|
276
|
+
const filters = repeatedValues(rawArgs, "content-filter", args["content-filter"]).map((value) => value.toUpperCase());
|
|
277
|
+
const categories = repeatedValues(rawArgs, "exclude-publisher-category", args["exclude-publisher-category"]).map(
|
|
278
|
+
(value) => value.toLowerCase()
|
|
279
|
+
);
|
|
280
|
+
const safety = {
|
|
281
|
+
...lists.length > 0 ? { excluded_publisher_list_ids: lists } : {},
|
|
282
|
+
...filters.length > 0 ? { brand_safety_content_filter_levels: filters } : {},
|
|
283
|
+
...categories.length > 0 ? { excluded_publisher_categories: categories } : {}
|
|
284
|
+
};
|
|
285
|
+
if (Object.keys(safety).length === 0) return file;
|
|
286
|
+
return { ...base ?? {}, ...safety };
|
|
287
|
+
}
|
|
157
288
|
function buildPromotedObject(args) {
|
|
158
289
|
const out = {};
|
|
159
290
|
if (args["page-id"]) out.page_id = String(args["page-id"]);
|
|
160
291
|
if (args["pixel-id"]) out.pixel_id = String(args["pixel-id"]);
|
|
161
292
|
if (args["custom-event-type"]) out.custom_event_type = upper(args["custom-event-type"]);
|
|
162
293
|
if (args["custom-conversion-id"]) out.custom_conversion_id = String(args["custom-conversion-id"]);
|
|
294
|
+
if (args["product-set-id"]) out.product_set_id = String(args["product-set-id"]);
|
|
295
|
+
if (args["app-id"]) out.application_id = String(args["app-id"]);
|
|
296
|
+
if (args["app-store-url"]) out.object_store_url = String(args["app-store-url"]);
|
|
297
|
+
if (args["whatsapp-number"]) out.whatsapp_phone_number = String(args["whatsapp-number"]);
|
|
163
298
|
return out;
|
|
164
299
|
}
|
|
165
300
|
function customConversionRuleFromFlags(args) {
|
|
@@ -236,12 +371,32 @@ var adSetWriteArgs = {
|
|
|
236
371
|
"bid-amount": { type: "string", description: "Bid amount (required for COST_CAP / bid-cap strategies)" },
|
|
237
372
|
"bid-strategy": {
|
|
238
373
|
type: "string",
|
|
239
|
-
description: "LOWEST_COST_WITHOUT_CAP (auto-bid) | LOWEST_COST_WITH_BID_CAP | COST_CAP \u2014 needs --bid-amount. Omit and Baker sets auto-bid; never leave it to Meta, whose default is a bid cap that then fails without an amount."
|
|
374
|
+
description: "LOWEST_COST_WITHOUT_CAP (auto-bid) | LOWEST_COST_WITH_BID_CAP | COST_CAP \u2014 needs --bid-amount | LOWEST_COST_WITH_MIN_ROAS \u2014 needs --min-roas. Omit and Baker sets auto-bid (or min-ROAS when --min-roas is given); never leave it to Meta, whose default is a bid cap that then fails without an amount."
|
|
240
375
|
},
|
|
376
|
+
...adSetDeliveryArgs,
|
|
241
377
|
currency: { type: "string", description: "3-letter currency (defaults to the account currency)" },
|
|
242
378
|
start: { type: "string", description: "Start time" },
|
|
243
379
|
end: { type: "string", description: "End time" },
|
|
244
|
-
"targeting-file": {
|
|
380
|
+
"targeting-file": {
|
|
381
|
+
type: "string",
|
|
382
|
+
description: "JSON file with the full Meta targeting spec. Ids, never names: look them up with `baker ads meta targeting search|geo|locales` and size it with `targeting estimate`"
|
|
383
|
+
},
|
|
384
|
+
"block-list": {
|
|
385
|
+
type: "string",
|
|
386
|
+
description: "Repeatable. Keep the ad set off a publisher block list \u2014 an id from `baker ads meta block-lists` or a meta_temp_* ref. On update without --targeting-file, the rest of the live targeting is kept"
|
|
387
|
+
},
|
|
388
|
+
"content-filter": {
|
|
389
|
+
type: "string",
|
|
390
|
+
description: "Repeatable, one per family: FEED_|FACEBOOK_|AN_ + RELAXED|STANDARD|STRICT \u2014 how strict Meta's content filter next to the ad is (feeds, in-stream/Reels, Audience Network)"
|
|
391
|
+
},
|
|
392
|
+
"exclude-publisher-category": {
|
|
393
|
+
type: "string",
|
|
394
|
+
description: "Repeatable: dating|gambling (and, for Audience Network / in-stream, debated_social_issues|mature_audiences|tragedy_and_conflict)"
|
|
395
|
+
},
|
|
396
|
+
reservation: {
|
|
397
|
+
type: "string",
|
|
398
|
+
description: "Create only: a reach-and-frequency reservation this ad set is bought on (id or meta_temp_* from `reach-frequency reserve`); its campaign is --buying-type RESERVED and it takes no budget"
|
|
399
|
+
},
|
|
245
400
|
"promoted-object-file": { type: "string", description: "JSON file with the promoted_object" },
|
|
246
401
|
"page-id": {
|
|
247
402
|
type: "string",
|
|
@@ -253,6 +408,22 @@ var adSetWriteArgs = {
|
|
|
253
408
|
type: "string",
|
|
254
409
|
description: "Optimize toward a Custom Conversion \u2014 the id from `baker ads meta custom-conversions`. Use it instead of --pixel-id/--custom-event-type, not alongside: Baker reads the conversion off Meta and fills its pixel, event category and rule."
|
|
255
410
|
},
|
|
411
|
+
"product-set-id": {
|
|
412
|
+
type: "string",
|
|
413
|
+
description: "Advantage+ catalog ads: the product set this ad set shows (promoted_object.product_set_id) \u2014 from `baker ads meta catalogs --catalog-id <id>`. With OFFSITE_CONVERSIONS pass --custom-event-type (PURCHASE, ADD_TO_CART\u2026); no pixel needed"
|
|
414
|
+
},
|
|
415
|
+
"app-id": {
|
|
416
|
+
type: "string",
|
|
417
|
+
description: "App ads: the app to promote (promoted_object.application_id) \u2014 from `baker ads meta apps`; needs --app-store-url"
|
|
418
|
+
},
|
|
419
|
+
"app-store-url": {
|
|
420
|
+
type: "string",
|
|
421
|
+
description: "App ads: the app's App Store / Google Play page (promoted_object.object_store_url)"
|
|
422
|
+
},
|
|
423
|
+
"whatsapp-number": {
|
|
424
|
+
type: "string",
|
|
425
|
+
description: "Click-to-WhatsApp: the WhatsApp Business number connected to the Page (promoted_object.whatsapp_phone_number)"
|
|
426
|
+
},
|
|
256
427
|
file: { type: "string", description: "JSON file with the full payload; flags override" }
|
|
257
428
|
};
|
|
258
429
|
var adSetsCreateCommand = defineCommand({
|
|
@@ -262,12 +433,37 @@ var adSetsCreateCommand = defineCommand({
|
|
|
262
433
|
Chain to a campaign with --campaign (real id or meta_temp_* ref).
|
|
263
434
|
Lead-form goals (LEAD_GENERATION, QUALITY_LEAD) and PAGE_LIKES need --page-id (the Facebook Page the leads/likes belong to).
|
|
264
435
|
Conversion goals take EITHER --pixel-id + --custom-event-type (a standard event) OR --custom-conversion-id (the marketer's own conversion, from 'baker ads meta custom-conversions').
|
|
265
|
-
Example: baker ads meta adsets create --campaign meta_temp_ab12 --name "US 25-54" --optimization-goal LINK_CLICKS --billing-event IMPRESSIONS --daily-budget 50 --targeting-file t.json
|
|
436
|
+
Example: baker ads meta adsets create --campaign meta_temp_ab12 --name "US 25-54" --optimization-goal LINK_CLICKS --billing-event IMPRESSIONS --daily-budget 50 --targeting-file t.json
|
|
437
|
+
Delivery controls: --min-roas (ROAS goal bidding), --frequency-cap 2/7 (REACH/THRUPLAY), --schedule "Mon-Fri 09-18" (dayparting, lifetime budget only), --pacing no_pacing (bid cap only), --daily-spend-cap/--daily-min-spend (an ad set's share of a campaign budget), --budget-boost (high-demand periods), --attribution 7d_click,1d_view, --dynamic-creative (create only).
|
|
438
|
+
Example: baker ads meta adsets create --campaign 6123 --name "Reach ES" --optimization-goal REACH --billing-event IMPRESSIONS --lifetime-budget 300 --end 2027-02-01 --frequency-cap 2/7 --schedule "Mon-Fri 09-18" --targeting-file t.json`
|
|
266
439
|
},
|
|
267
|
-
args: {
|
|
268
|
-
|
|
440
|
+
args: {
|
|
441
|
+
campaign: { type: "string", description: "Parent campaign id or meta_temp_* ref" },
|
|
442
|
+
...adSetWriteArgs,
|
|
443
|
+
"budget-boost": {
|
|
444
|
+
type: "string",
|
|
445
|
+
description: "Raise this ad set's daily budget for a high-demand period, repeatable (on a live ad set, `adsets update --budget-boost` adds one beside those it has): START..END=+AMOUNT or START..END=+PERCENT% (max 800%), at least 3 hours, on quarter hours, all amounts or all percentages. Needs --daily-budget. Example: --budget-boost 2027-11-27T00:00Z..2027-11-28T00:00Z=+50%"
|
|
446
|
+
},
|
|
447
|
+
"dynamic-creative": {
|
|
448
|
+
type: "boolean",
|
|
449
|
+
description: "Make this a Dynamic Creative ad set: its ONE ad runs a creativeType dynamic creative (Meta mixes the images, videos and texts). Create-only \u2014 Meta fixes it for the ad set's life."
|
|
450
|
+
},
|
|
451
|
+
"saved-audience": {
|
|
452
|
+
type: "string",
|
|
453
|
+
description: "Start from a saved audience's targeting (id from `baker ads meta audiences saved`) \u2014 copied into the ad set; instead of --targeting-file, and --block-list / --content-filter / --exclude-publisher-category join it"
|
|
454
|
+
}
|
|
455
|
+
},
|
|
456
|
+
run: async ({ args, rawArgs }) => {
|
|
269
457
|
const accountId = bareAccountId(args);
|
|
270
|
-
const
|
|
458
|
+
const file = loadJsonFileArg(args.file);
|
|
459
|
+
const payload = mergePayload(file, adSetPayloadFromFlags(args, rawArgs, file));
|
|
460
|
+
if (args["saved-audience"]) {
|
|
461
|
+
const { savedAudienceTargeting, targetingFromSavedAudience } = await import("./audience-writes-X52VG35Y.js");
|
|
462
|
+
const saved = await savedAudienceTargeting(accountId, String(args["saved-audience"]));
|
|
463
|
+
const merged = targetingFromSavedAudience(saved, payload.targeting);
|
|
464
|
+
if ("refusal" in merged) failWriteValidation(merged.refusal);
|
|
465
|
+
payload.targeting = merged.targeting;
|
|
466
|
+
}
|
|
271
467
|
await stageOp({ kind: "adSet.create", accountId, payload });
|
|
272
468
|
}
|
|
273
469
|
});
|
|
@@ -276,17 +472,33 @@ var adSetsUpdateCommand = defineCommand({
|
|
|
276
472
|
name: "update",
|
|
277
473
|
description: `Stage changes to an ad set. ${STAGED_NOTE}
|
|
278
474
|
Switching --optimization-goal to a lead-form goal (LEAD_GENERATION, QUALITY_LEAD) or PAGE_LIKES needs --page-id in the same change.
|
|
475
|
+
Take a control away with --clear: baker ads meta adsets update 6123 --clear daily-spend-cap,schedule
|
|
476
|
+
Budget boosts on a live ad set with its own daily budget: add with --budget-boost, take one away with --remove-boost, re-time one with --move-boost (ids from \`baker ads meta high-demand-periods --campaign-id <ad set id>\`).
|
|
279
477
|
Example: baker ads meta adsets update 6123 --daily-budget 80`
|
|
280
478
|
},
|
|
281
|
-
args: {
|
|
282
|
-
|
|
479
|
+
args: {
|
|
480
|
+
id: { type: "positional", description: "Ad set id or meta_temp_* ref", required: true },
|
|
481
|
+
...adSetWriteArgs,
|
|
482
|
+
"budget-boost": {
|
|
483
|
+
type: "string",
|
|
484
|
+
description: "Add a budget boost to this ad set (its own daily budget is raised for a high-demand period), repeatable: START..END=+AMOUNT or START..END=+PERCENT% (max 800%), at least 3 hours, on quarter hours. Sent to Meta's boost list for the ad set, so the budget need not be restated. Example: --budget-boost 2027-11-27T00:00Z..2027-11-28T00:00Z=+50%"
|
|
485
|
+
},
|
|
486
|
+
...boostEditArgs,
|
|
487
|
+
...clearArg
|
|
488
|
+
},
|
|
489
|
+
run: async ({ args, rawArgs }) => {
|
|
283
490
|
const accountId = bareAccountId(args);
|
|
491
|
+
const file = loadJsonFileArg(args.file);
|
|
284
492
|
const {
|
|
285
493
|
campaign_id: _drop,
|
|
286
494
|
billing_event: _be,
|
|
287
495
|
...payload
|
|
288
|
-
} = adSetPayloadFromFlags(args);
|
|
289
|
-
const merged = mergePayload(
|
|
496
|
+
} = adSetPayloadFromFlags(args, rawArgs, file);
|
|
497
|
+
const merged = mergePayload(file, {
|
|
498
|
+
...payload,
|
|
499
|
+
...boostEditsFromFlags(args, rawArgs),
|
|
500
|
+
clear: clearOrFail(rawArgs, "adSet")
|
|
501
|
+
});
|
|
290
502
|
refuseDeleteByUpdate(merged, "adsets");
|
|
291
503
|
await stageOp({
|
|
292
504
|
kind: "adSet.update",
|
|
@@ -296,8 +508,8 @@ Example: baker ads meta adsets update 6123 --daily-budget 80`
|
|
|
296
508
|
});
|
|
297
509
|
}
|
|
298
510
|
});
|
|
299
|
-
function creativePayloadFromFlags(args) {
|
|
300
|
-
const enhancements = args
|
|
511
|
+
function creativePayloadFromFlags(args, rawArgs) {
|
|
512
|
+
const enhancements = creativeEnhancementsFromFlags(args, rawArgs);
|
|
301
513
|
return {
|
|
302
514
|
// Leave undefined when --type is omitted so a --file's creativeType survives
|
|
303
515
|
// mergePayload (any defined flag overrides the file). Defaulted after merge.
|
|
@@ -311,25 +523,62 @@ function creativePayloadFromFlags(args) {
|
|
|
311
523
|
description: args.description,
|
|
312
524
|
caption: args.caption,
|
|
313
525
|
call_to_action: creativeCta(args),
|
|
526
|
+
welcome_message: welcomeMessageFromFlags(args, rawArgs),
|
|
527
|
+
applink_treatment: args["applink-treatment"],
|
|
528
|
+
product_set_id: args["product-set-id"],
|
|
529
|
+
canvas_id: args["canvas-id"],
|
|
530
|
+
format: args.format,
|
|
314
531
|
imageHash: args["image-hash"],
|
|
315
532
|
imageRef: args["image-ref"],
|
|
316
533
|
videoId: args["video-id"],
|
|
317
534
|
videoRef: args["video-ref"],
|
|
318
535
|
thumbnailHash: args["thumbnail-hash"],
|
|
536
|
+
thumbnailRef: args["thumbnail-ref"],
|
|
319
537
|
url_tags: args["url-tags"],
|
|
320
|
-
|
|
538
|
+
shop_destination: args["shop-destination"],
|
|
539
|
+
multi_advertiser: args["multi-advertiser"],
|
|
540
|
+
partner: partnerFromFlags(args),
|
|
541
|
+
object_story_id: args["post-id"],
|
|
542
|
+
source_instagram_media_id: args["instagram-media-id"],
|
|
543
|
+
instagram_ad_code: args["ad-code"],
|
|
544
|
+
collection_thumbnails: collectionThumbnailsFromFlags(rawArgs, args["collection-thumbnail"]),
|
|
545
|
+
enhancements,
|
|
546
|
+
...carouselFlags(args)
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
function collectionThumbnailsFromFlags(rawArgs, parsed) {
|
|
550
|
+
const values = repeatedValues(rawArgs, "collection-thumbnail", parsed);
|
|
551
|
+
if (values.length === 0) return void 0;
|
|
552
|
+
return values.map((value) => {
|
|
553
|
+
const [elementId = "", index] = value.split(":");
|
|
554
|
+
return index === void 0 ? { element_id: elementId } : { element_id: elementId, element_child_index: Number(index) };
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
function partnerFromFlags(args) {
|
|
558
|
+
const partner = {
|
|
559
|
+
facebook_page_id: args["partner-page"],
|
|
560
|
+
instagram_user_id: args["partner-instagram"],
|
|
561
|
+
ad_format: args["partner-format"]
|
|
321
562
|
};
|
|
563
|
+
return Object.values(partner).some((value) => value !== void 0) ? partner : void 0;
|
|
322
564
|
}
|
|
323
565
|
function ctaPatchFromFlags(args) {
|
|
324
566
|
const patch = {
|
|
325
567
|
...args.cta ? { type: String(upper(args.cta)) } : {},
|
|
326
|
-
...args["lead-form"] === void 0 ? {} : { lead_gen_form_id: String(args["lead-form"]) }
|
|
568
|
+
...args["lead-form"] === void 0 ? {} : { lead_gen_form_id: String(args["lead-form"]) },
|
|
569
|
+
...conversationAndAppCta(args)
|
|
327
570
|
};
|
|
328
571
|
return Object.keys(patch).length > 0 ? patch : void 0;
|
|
329
572
|
}
|
|
330
573
|
function creativeCta(args) {
|
|
331
574
|
const patch = ctaPatchFromFlags(args);
|
|
332
|
-
|
|
575
|
+
if (!patch) return void 0;
|
|
576
|
+
const opener = Object.entries({
|
|
577
|
+
MESSENGER: "MESSAGE_PAGE",
|
|
578
|
+
WHATSAPP: "WHATSAPP_MESSAGE",
|
|
579
|
+
INSTAGRAM_DIRECT: "INSTAGRAM_MESSAGE"
|
|
580
|
+
}).find(([app]) => app === patch.app_destination)?.[1];
|
|
581
|
+
return { type: opener ?? (patch.app_link || patch.application ? "INSTALL_MOBILE_APP" : "SIGN_UP"), ...patch };
|
|
333
582
|
}
|
|
334
583
|
function creativeContentPatch(file, args) {
|
|
335
584
|
const cta = ctaPatchFromFlags(args);
|
|
@@ -340,26 +589,70 @@ function creativeContentPatch(file, args) {
|
|
|
340
589
|
const fileCta = fileContent.call_to_action ?? {};
|
|
341
590
|
return { ...fileContent, call_to_action: { ...fileCta, ...cta } };
|
|
342
591
|
}
|
|
343
|
-
function parseEnroll(value) {
|
|
344
|
-
const raw = String(value).toLowerCase();
|
|
345
|
-
if (raw === "on" || raw === "true" || raw === "opt_in") return "OPT_IN";
|
|
346
|
-
if (raw === "off" || raw === "false" || raw === "opt_out") return "OPT_OUT";
|
|
347
|
-
failWriteValidation("--standard-enhancements must be on|off");
|
|
348
|
-
}
|
|
349
592
|
var adCreativesCreateCommand = defineCommand({
|
|
350
593
|
meta: {
|
|
351
594
|
name: "create",
|
|
352
595
|
description: `Stage a new ad creative. ${STAGED_NOTE}
|
|
353
596
|
Single-image/video via flags; carousel/dynamic via --file (creativeType carousel|dynamic).
|
|
597
|
+
Click-to-message: --cta MESSAGE_PAGE|WHATSAPP_MESSAGE|INSTAGRAM_MESSAGE (opens Messenger|WhatsApp|Instagram Direct) + --greeting "Hi!" --ice-breaker "Prices? => From 99 EUR." (ad set: --destination-type MESSENGER --optimization-goal CONVERSATIONS --page-id).
|
|
598
|
+
App ads: --link <App Store / Google Play URL> --cta INSTALL_MOBILE_APP|USE_MOBILE_APP --deep-link myapp://x --app-id <id> --applink-treatment deeplink_with_appstore_fallback.
|
|
599
|
+
Catalog (Advantage+ catalog ads): --type catalog --product-set-id <id> --message "{{product.name}}" --headline "{{product.price}}" --link https://shop.example --format carousel|single|slideshow.
|
|
600
|
+
Instant Experience / collection: --type instant_experience --canvas-id <id or meta_temp_*> --message \u2026 --image-hash \u2026 [--format collection] (build one with \`baker ads meta instant-experiences create\`).
|
|
354
601
|
Reference media by --image-hash (already on Meta) or --image-ref meta_temp_* (a staged media upload).
|
|
355
602
|
Example: baker ads meta creatives create --page 555 --message "Save now" --link https://x.com --headline "Best cover" --image-hash abc123\u2026 --cta SHOP_NOW`
|
|
356
603
|
},
|
|
357
604
|
args: {
|
|
358
605
|
...accountArgs,
|
|
359
|
-
type: {
|
|
606
|
+
type: {
|
|
607
|
+
type: "string",
|
|
608
|
+
description: "single|carousel|dynamic|existing_post|catalog|instant_experience (default single)"
|
|
609
|
+
},
|
|
610
|
+
"product-set-id": {
|
|
611
|
+
type: "string",
|
|
612
|
+
description: "--type catalog: the product set the template shows \u2014 from `baker ads meta catalogs --catalog-id <id>`"
|
|
613
|
+
},
|
|
614
|
+
"canvas-id": {
|
|
615
|
+
type: "string",
|
|
616
|
+
description: "--type instant_experience: the Instant Experience the ad opens \u2014 an id from `baker ads meta instant-experiences --page-id <id>` (published) or the meta_temp_* ref of one this chat creates"
|
|
617
|
+
},
|
|
618
|
+
format: {
|
|
619
|
+
type: "string",
|
|
620
|
+
description: "--type catalog: carousel (default) | single (one product per ad) | slideshow. --type instant_experience: standard (default) | collection (products or photos under the ad)"
|
|
621
|
+
},
|
|
622
|
+
greeting: {
|
|
623
|
+
type: "string",
|
|
624
|
+
description: "Click-to-message: the first message the person reads when the conversation opens (\u2264300 chars)"
|
|
625
|
+
},
|
|
626
|
+
"ice-breaker": {
|
|
627
|
+
type: "string",
|
|
628
|
+
description: 'Click-to-message, repeatable (max 4): a question the person can tap and your answer \u2014 "Question => Answer"'
|
|
629
|
+
},
|
|
630
|
+
autofill: {
|
|
631
|
+
type: "string",
|
|
632
|
+
description: "Click-to-message (instead of ice breakers): a message pre-filled for the person to send"
|
|
633
|
+
},
|
|
634
|
+
"app-destination": {
|
|
635
|
+
type: "string",
|
|
636
|
+
description: "Click-to-message: MESSENGER|WHATSAPP|INSTAGRAM_DIRECT \u2014 implied by --cta MESSAGE_PAGE|WHATSAPP_MESSAGE|INSTAGRAM_MESSAGE"
|
|
637
|
+
},
|
|
638
|
+
"deep-link": {
|
|
639
|
+
type: "string",
|
|
640
|
+
description: "App ads: where the button opens inside the installed app (e.g. myapp://product/12). --link must be the App Store / Google Play page"
|
|
641
|
+
},
|
|
642
|
+
"app-id": {
|
|
643
|
+
type: "string",
|
|
644
|
+
description: "App ads: the app the button installs or opens \u2014 from `baker ads meta apps`"
|
|
645
|
+
},
|
|
646
|
+
"applink-treatment": {
|
|
647
|
+
type: "string",
|
|
648
|
+
description: "App ads: how a deep link opens \u2014 deeplink_with_web_fallback|deeplink_with_appstore_fallback|web_only|automatic"
|
|
649
|
+
},
|
|
360
650
|
name: { type: "string", description: "Creative name" },
|
|
361
651
|
page: { type: "string", description: "Facebook Page id (identity)" },
|
|
362
|
-
"instagram-user": {
|
|
652
|
+
"instagram-user": {
|
|
653
|
+
type: "string",
|
|
654
|
+
description: "Instagram account id for IG placements \u2014 from `baker ads meta instagram-accounts`"
|
|
655
|
+
},
|
|
363
656
|
message: { type: "string", description: "Primary text" },
|
|
364
657
|
link: { type: "string", description: "Destination URL (https)" },
|
|
365
658
|
headline: { type: "string", description: "Headline" },
|
|
@@ -376,15 +669,70 @@ Example: baker ads meta creatives create --page 555 --message "Save now" --link
|
|
|
376
669
|
"video-ref": { type: "string", description: "meta_temp_* ref of a staged video upload" },
|
|
377
670
|
"thumbnail-hash": {
|
|
378
671
|
type: "string",
|
|
379
|
-
description: "Cover
|
|
672
|
+
description: "Cover for a video ad: a picture hash already in the ad account (Meta's own frame is used when no cover is given)"
|
|
673
|
+
},
|
|
674
|
+
"thumbnail-ref": {
|
|
675
|
+
type: "string",
|
|
676
|
+
description: "Cover for a video ad: meta_temp_* ref of a staged `media upload --kind image` \u2014 how a cover picked from the library is used"
|
|
380
677
|
},
|
|
381
678
|
"url-tags": { type: "string", description: "URL tracking params (utm_source=fb&\u2026)" },
|
|
382
|
-
"
|
|
679
|
+
"shop-destination": {
|
|
680
|
+
type: "string",
|
|
681
|
+
description: "website_only keeps a shop advertiser's ad on the website (Meta's v26 default also sends it to the shop); website_and_shop asks for both"
|
|
682
|
+
},
|
|
683
|
+
"standard-enhancements": {
|
|
684
|
+
type: "string",
|
|
685
|
+
description: "Meta's suggestions to the ad's TEXT on|off \u2014 never changes the picture or video"
|
|
686
|
+
},
|
|
687
|
+
"multi-advertiser": {
|
|
688
|
+
type: "string",
|
|
689
|
+
description: "opt_out keeps the ad from being shown beside other advertisers' ads after someone engages (Meta opts every new ad IN by default); opt_in asks for it"
|
|
690
|
+
},
|
|
691
|
+
"partner-page": {
|
|
692
|
+
type: "string",
|
|
693
|
+
description: "Partnership ad: the partner's (creator's or other brand's) Facebook Page id, shown beside yours. Needs --instagram-user on the ad and the partner's approval before it runs"
|
|
694
|
+
},
|
|
695
|
+
"partner-instagram": { type: "string", description: "Partnership ad: the partner's Instagram account id" },
|
|
696
|
+
"partner-format": {
|
|
697
|
+
type: "string",
|
|
698
|
+
description: "Partnership ad: both (default \u2014 both identities) | first_only | auto (Meta picks, Instagram only)"
|
|
699
|
+
},
|
|
700
|
+
"collection-thumbnail": {
|
|
701
|
+
type: "string",
|
|
702
|
+
description: "--format collection over a photo experience, repeat 4 times: an element id of the live experience (`instant-experiences --page-id`), or <product-set element id>:<product index>"
|
|
703
|
+
},
|
|
704
|
+
"post-id": {
|
|
705
|
+
type: "string",
|
|
706
|
+
description: "--type existing_post: the Facebook post to boost, <page_id>_<post_id> \u2014 from `baker ads meta page-posts --page-id <id>`"
|
|
707
|
+
},
|
|
708
|
+
"instagram-media-id": {
|
|
709
|
+
type: "string",
|
|
710
|
+
description: "--type existing_post: the Instagram post to boost (with --page and --instagram-user) \u2014 from `baker ads meta instagram-media`"
|
|
711
|
+
},
|
|
712
|
+
"ad-code": {
|
|
713
|
+
type: "string",
|
|
714
|
+
description: "--type existing_post: a creator's partnership ad code for their Instagram post (with --page)"
|
|
715
|
+
},
|
|
716
|
+
"card-order": {
|
|
717
|
+
type: "string",
|
|
718
|
+
description: "Carousel only: fixed (default \u2014 every card, in the order built) or optimized (Meta reorders by performance and may show only the top 5)"
|
|
719
|
+
},
|
|
720
|
+
"end-card": {
|
|
721
|
+
type: "string",
|
|
722
|
+
description: "Carousel only: on adds Meta's card linking to the Page after the last card (default off)"
|
|
723
|
+
},
|
|
724
|
+
"visual-enhancement": {
|
|
725
|
+
type: "string",
|
|
726
|
+
description: "Repeatable. Let Meta change the media with this feature (e.g. image_uncrop, image_animation, music_generation) \u2014 ONLY when the user asked for it by name; every such feature is off otherwise"
|
|
727
|
+
},
|
|
383
728
|
file: { type: "string", description: "JSON file with the full creative payload (carousel cards / dynamic assets)" }
|
|
384
729
|
},
|
|
385
|
-
run: async ({ args }) => {
|
|
730
|
+
run: async ({ args, rawArgs }) => {
|
|
386
731
|
const accountId = bareAccountId(args);
|
|
387
|
-
const payload = mergePayload(
|
|
732
|
+
const payload = mergePayload(
|
|
733
|
+
loadJsonFileArg(args.file),
|
|
734
|
+
creativePayloadFromFlags(args, rawArgs)
|
|
735
|
+
);
|
|
388
736
|
if (payload.creativeType === void 0) {
|
|
389
737
|
payload.creativeType = "single";
|
|
390
738
|
}
|
|
@@ -424,6 +772,11 @@ Amending a staged (meta_temp_*) creative merges fields into the create. Example:
|
|
|
424
772
|
// staging an ad refuses it for naming no instant form.
|
|
425
773
|
content: creativeContentPatch(file, args)
|
|
426
774
|
});
|
|
775
|
+
if (payload.status === "DELETED") {
|
|
776
|
+
failWriteValidation(
|
|
777
|
+
"update does not delete \u2014 use `baker ads meta creatives delete <id>` if the user asked to delete it"
|
|
778
|
+
);
|
|
779
|
+
}
|
|
427
780
|
await stageOp({
|
|
428
781
|
kind: "adCreative.update",
|
|
429
782
|
accountId,
|
|
@@ -445,6 +798,10 @@ Example: baker ads meta ads create --name "Ad 1" --adset meta_temp_as01 --creati
|
|
|
445
798
|
creative: { type: "string", description: "Creative id or meta_temp_* ref" },
|
|
446
799
|
status: { type: "string", description: "ACTIVE|PAUSED (default PAUSED)" },
|
|
447
800
|
"tracking-file": { type: "string", description: "JSON file with tracking_specs" },
|
|
801
|
+
"conversion-domain": {
|
|
802
|
+
type: "string",
|
|
803
|
+
description: "The website domain conversions are counted on (example.com \u2014 no www., no https://). Meta fills it from the link when left out; set it when the site and the pixel's domain differ"
|
|
804
|
+
},
|
|
448
805
|
file: { type: "string", description: "JSON file with the full payload" }
|
|
449
806
|
},
|
|
450
807
|
run: async ({ args }) => {
|
|
@@ -455,7 +812,8 @@ Example: baker ads meta ads create --name "Ad 1" --adset meta_temp_as01 --creati
|
|
|
455
812
|
adset_id: args.adset,
|
|
456
813
|
creative: args.creative ? { creative_id: String(args.creative) } : void 0,
|
|
457
814
|
status: upper(args.status),
|
|
458
|
-
tracking_specs: tracking
|
|
815
|
+
tracking_specs: tracking,
|
|
816
|
+
conversion_domain: args["conversion-domain"]
|
|
459
817
|
});
|
|
460
818
|
await stageOp({ kind: "ad.create", accountId, payload });
|
|
461
819
|
}
|
|
@@ -505,14 +863,14 @@ Example: baker ads meta ads retag 120252158038400247 --url-tags "utm_source={{si
|
|
|
505
863
|
"url-tags": { type: "string", description: "Replace the WHOLE tracking string" },
|
|
506
864
|
set: {
|
|
507
865
|
type: "string",
|
|
508
|
-
description: 'Rewrite only these keys, keeping the rest: "utm_medium=paid-social&ad_id={{ad.id}}"'
|
|
866
|
+
description: 'Rewrite only these keys, keeping the rest: "utm_medium=paid-social&ad_id={{ad.id}}" (repeatable: --set a=1 --set b=2)'
|
|
509
867
|
}
|
|
510
868
|
},
|
|
511
|
-
run: async ({ args }) => {
|
|
869
|
+
run: async ({ args, rawArgs }) => {
|
|
512
870
|
const { apiPost } = await import("./client-WL2FKW4T.js");
|
|
513
871
|
const { requireChatId } = await import("./env-5MUVYE2L.js");
|
|
514
872
|
const { writeJsonEnvelope } = await import("./output-GWIP6ROX.js");
|
|
515
|
-
const { handleMetaError } = await import("./shared-
|
|
873
|
+
const { handleMetaError } = await import("./shared-3IBNDEFL.js");
|
|
516
874
|
try {
|
|
517
875
|
const accountId = bareAccountId(args);
|
|
518
876
|
const urlTags = typeof args["url-tags"] === "string" ? args["url-tags"] : void 0;
|
|
@@ -525,7 +883,7 @@ Example: baker ads meta ads retag 120252158038400247 --url-tags "utm_source={{si
|
|
|
525
883
|
accountId,
|
|
526
884
|
adId: requireTarget(args, "ad"),
|
|
527
885
|
urlTags,
|
|
528
|
-
set: setRaw === void 0 ? void 0 :
|
|
886
|
+
set: setRaw === void 0 ? void 0 : retagSetPairs(rawArgs, setRaw)
|
|
529
887
|
});
|
|
530
888
|
writeJsonEnvelope(response);
|
|
531
889
|
} catch (err) {
|
|
@@ -533,6 +891,9 @@ Example: baker ads meta ads retag 120252158038400247 --url-tags "utm_source={{si
|
|
|
533
891
|
}
|
|
534
892
|
}
|
|
535
893
|
});
|
|
894
|
+
function retagSetPairs(rawArgs, parsed) {
|
|
895
|
+
return parseSetPairs(repeatedValues(rawArgs, "set", parsed).join("&"));
|
|
896
|
+
}
|
|
536
897
|
function parseSetPairs(raw) {
|
|
537
898
|
const pairs = {};
|
|
538
899
|
for (const part of raw.replace(/^[?&]+/, "").split("&")) {
|
|
@@ -551,10 +912,12 @@ function parseSetPairs(raw) {
|
|
|
551
912
|
var audiencesCreateCommand = defineCommand({
|
|
552
913
|
meta: {
|
|
553
914
|
name: "create",
|
|
554
|
-
description: `Stage a new custom audience
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
915
|
+
description: `Stage a new custom audience. ${STAGED_NOTE}
|
|
916
|
+
Customer list: --subtype CUSTOM --customer-file-source USER_PROVIDED_ONLY, then put people in it with \`audiences members add <ref> --file list.csv\` (hashed on this machine). --value-based for a list where each person carries a value (needs the account's value-based terms).
|
|
917
|
+
Lookalike: --subtype LOOKALIKE --lookalike-of <seed audience> --ratio 0.02 --country ES (or --countries ES,PT; --starting-ratio 0.01 for the 1%\u20132% band). The seed needs 100+ people in those countries. Or seed it from the people who converted in live campaigns: --lookalike-of-conversions <campaign or ad set id,\u2026>.
|
|
918
|
+
WEBSITE/ENGAGEMENT: the rule via --file. A rule carries its own window in retention_seconds, so --retention-days is refused next to one, and one audience covers one kind of event source (a Page and an Instagram profile are two audiences).
|
|
919
|
+
Example: baker ads meta audiences create --name "Site visitors 30d" --subtype WEBSITE --file rule.json
|
|
920
|
+
Example: baker ads meta audiences create --name "Customers" --subtype CUSTOM --customer-file-source USER_PROVIDED_ONLY`
|
|
558
921
|
},
|
|
559
922
|
args: {
|
|
560
923
|
...accountArgs,
|
|
@@ -565,34 +928,94 @@ Example: baker ads meta audiences create --name "Site visitors 30d" --subtype WE
|
|
|
565
928
|
type: "string",
|
|
566
929
|
description: "Retention window in days \u2014 customer-file audiences only; a rule carries its own retention_seconds"
|
|
567
930
|
},
|
|
931
|
+
"customer-file-source": {
|
|
932
|
+
type: "string",
|
|
933
|
+
description: "Customer list: where its people came from \u2014 USER_PROVIDED_ONLY (collected from customers directly) | PARTNER_PROVIDED_ONLY | BOTH_USER_AND_PARTNER_PROVIDED"
|
|
934
|
+
},
|
|
935
|
+
"value-based": {
|
|
936
|
+
type: "boolean",
|
|
937
|
+
description: "Customer list where each person carries a value (LOOKALIKE_VALUE column)"
|
|
938
|
+
},
|
|
939
|
+
"lookalike-of": {
|
|
940
|
+
type: "string",
|
|
941
|
+
description: "Lookalike: the seed audience id (a live audience \u2014 one this chat creates cannot be a seed yet)"
|
|
942
|
+
},
|
|
943
|
+
"lookalike-of-conversions": {
|
|
944
|
+
type: "string",
|
|
945
|
+
description: "Lookalike seeded from the people who converted in live campaigns or ad sets (ids, comma-separated or repeated) instead of an audience. Meta wants 100+ conversions in the lookalike's countries."
|
|
946
|
+
},
|
|
947
|
+
ratio: { type: "string", description: "Lookalike size: 0.01\u20130.20 of the country, in 0.01 steps" },
|
|
948
|
+
"starting-ratio": {
|
|
949
|
+
type: "string",
|
|
950
|
+
description: "Lookalike band start, below --ratio (0.01 with --ratio 0.03 = the 1%\u20133% band)"
|
|
951
|
+
},
|
|
952
|
+
country: { type: "string", description: "Lookalike: one country (ES)" },
|
|
953
|
+
countries: { type: "string", description: "Lookalike: several countries (ES,PT \u2014 comma-separated or repeated)" },
|
|
954
|
+
"allow-international-seeds": {
|
|
955
|
+
type: "boolean",
|
|
956
|
+
description: "Lookalike: let Meta use seed people from other countries when the seed is thin in these"
|
|
957
|
+
},
|
|
568
958
|
file: { type: "string", description: "JSON file with lookalike_spec / rule / full payload" }
|
|
569
959
|
},
|
|
570
|
-
run: async ({ args }) => {
|
|
960
|
+
run: async ({ args, rawArgs }) => {
|
|
571
961
|
const accountId = bareAccountId(args);
|
|
572
|
-
const
|
|
962
|
+
const file = loadJsonFileArg(args.file);
|
|
963
|
+
const payload = mergePayload(file, {
|
|
573
964
|
name: args.name,
|
|
574
965
|
subtype: upper(args.subtype),
|
|
575
966
|
description: args.description,
|
|
576
|
-
retention_days: numberFlag(args["retention-days"], "--retention-days")
|
|
967
|
+
retention_days: numberFlag(args["retention-days"], "--retention-days"),
|
|
968
|
+
customer_file_source: upper(args["customer-file-source"]),
|
|
969
|
+
is_value_based: args["value-based"] ? true : void 0,
|
|
970
|
+
lookalike_spec: lookalikeSpecFromFlags(args, file.lookalike_spec, rawArgs)
|
|
577
971
|
});
|
|
578
972
|
await stageOp({ kind: "customAudience.create", accountId, payload });
|
|
579
973
|
}
|
|
580
974
|
});
|
|
975
|
+
function lookalikeSpecFromFlags(args, fromFile, rawArgs) {
|
|
976
|
+
const base = fromFile && typeof fromFile === "object" ? fromFile : {};
|
|
977
|
+
const flags = {
|
|
978
|
+
origin: typeof args["lookalike-of"] === "string" ? [{ id: args["lookalike-of"] }] : void 0,
|
|
979
|
+
conversions_of: repeatedListFlag(rawArgs, "lookalike-of-conversions", args["lookalike-of-conversions"]),
|
|
980
|
+
ratio: numberFlag(args.ratio, "--ratio"),
|
|
981
|
+
starting_ratio: numberFlag(args["starting-ratio"], "--starting-ratio"),
|
|
982
|
+
country: typeof args.country === "string" ? args.country.toUpperCase() : void 0,
|
|
983
|
+
countries: repeatedListFlag(rawArgs, "countries", args.countries)?.map((code) => code.toUpperCase()),
|
|
984
|
+
allow_international_seeds: args["allow-international-seeds"] ? true : void 0
|
|
985
|
+
};
|
|
986
|
+
const merged = mergePayload(base, flags);
|
|
987
|
+
return Object.keys(merged).length > 0 ? merged : void 0;
|
|
988
|
+
}
|
|
581
989
|
var audiencesUpdateCommand = defineCommand({
|
|
582
990
|
meta: {
|
|
583
991
|
name: "update",
|
|
584
|
-
description: `Stage
|
|
992
|
+
description: `Stage changes to a custom audience: name, description, where a customer list came from, its opt-out link, or a website/engagement rule (--file {"rule": \u2026}). A customer list's retention and a lookalike's seed and size are fixed \u2014 a different one is a new audience. Delete with \`audiences delete\`. ${STAGED_NOTE}`
|
|
585
993
|
},
|
|
586
994
|
args: {
|
|
587
995
|
id: { type: "positional", description: "Audience id or meta_temp_* ref", required: true },
|
|
588
996
|
...accountArgs,
|
|
589
997
|
name: { type: "string", description: "New name" },
|
|
590
998
|
description: { type: "string", description: "New description" },
|
|
591
|
-
file: {
|
|
999
|
+
"customer-file-source": {
|
|
1000
|
+
type: "string",
|
|
1001
|
+
description: "USER_PROVIDED_ONLY | PARTNER_PROVIDED_ONLY | BOTH_USER_AND_PARTNER_PROVIDED"
|
|
1002
|
+
},
|
|
1003
|
+
"opt-out-link": { type: "string", description: "https link where people can opt out of this audience" },
|
|
1004
|
+
file: { type: "string", description: "JSON file with fields to change (rule for a website/engagement audience)" }
|
|
592
1005
|
},
|
|
593
1006
|
run: async ({ args }) => {
|
|
594
1007
|
const accountId = bareAccountId(args);
|
|
595
|
-
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
1008
|
+
const payload = mergePayload(loadJsonFileArg(args.file), {
|
|
1009
|
+
name: args.name,
|
|
1010
|
+
description: args.description,
|
|
1011
|
+
customer_file_source: upper(args["customer-file-source"]),
|
|
1012
|
+
opt_out_link: args["opt-out-link"]
|
|
1013
|
+
});
|
|
1014
|
+
if (payload.status === "DELETED") {
|
|
1015
|
+
failWriteValidation(
|
|
1016
|
+
"update does not delete \u2014 use `baker ads meta audiences delete <id>` if the user asked to delete it"
|
|
1017
|
+
);
|
|
1018
|
+
}
|
|
596
1019
|
await stageOp({
|
|
597
1020
|
kind: "customAudience.update",
|
|
598
1021
|
accountId,
|
|
@@ -666,7 +1089,7 @@ function duplicateCommand(entity, label) {
|
|
|
666
1089
|
const { apiPost } = await import("./client-WL2FKW4T.js");
|
|
667
1090
|
const { requireChatId } = await import("./env-5MUVYE2L.js");
|
|
668
1091
|
const { writeJsonEnvelope } = await import("./output-GWIP6ROX.js");
|
|
669
|
-
const { handleMetaError } = await import("./shared-
|
|
1092
|
+
const { handleMetaError } = await import("./shared-3IBNDEFL.js");
|
|
670
1093
|
try {
|
|
671
1094
|
const accountId = bareAccountId(args);
|
|
672
1095
|
const chatId = requireChatId();
|
|
@@ -727,11 +1150,16 @@ export {
|
|
|
727
1150
|
campaignsPauseCommand,
|
|
728
1151
|
campaignsResumeCommand,
|
|
729
1152
|
campaignsUpdateCommand,
|
|
1153
|
+
collectionThumbnailsFromFlags,
|
|
730
1154
|
creativeContentPatch,
|
|
731
1155
|
creativeCta,
|
|
732
1156
|
ctaPatchFromFlags,
|
|
733
1157
|
customConversionRuleFromFlags,
|
|
734
1158
|
customConversionsCreateCommand,
|
|
735
|
-
|
|
1159
|
+
lookalikeSpecFromFlags,
|
|
1160
|
+
mediaUploadCommand,
|
|
1161
|
+
partnerFromFlags,
|
|
1162
|
+
retagSetPairs,
|
|
1163
|
+
targetingFromFlags
|
|
736
1164
|
};
|
|
737
|
-
//# sourceMappingURL=write-commands-
|
|
1165
|
+
//# sourceMappingURL=write-commands-PEJBTME6.js.map
|