nubot-lite 0.1.0 → 0.1.2
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 +6 -5
- package/lib/api.mjs +6 -2
- package/lib/cloudflare.mjs +13 -12
- package/lib/commands/init.mjs +260 -251
- package/package.json +1 -1
- package/template/.claude/skills/nubot-lite/SKILL.md +7 -1
- package/template/panel/PANEL.md +1 -1
- package/template/panel/assets/AgendarDemoPage-Bn_BvTp1.js +1 -0
- package/template/panel/assets/{AgentDatasetsPage-D8vQhRWO.js → AgentDatasetsPage-wLtBtSB2.js} +2 -2
- package/template/panel/assets/AgentKnowledgeGroupsPage-BGHNFj-e.js +1 -0
- package/template/panel/assets/AgentListPage-F3ja9_o_.js +1 -0
- package/template/panel/assets/AgentQaTrainingPage-CojiU8_W.js +1 -0
- package/template/panel/assets/AiAgentWhatsappPage-Bn_BvTp1.js +1 -0
- package/template/panel/assets/BlogPage-Bn_BvTp1.js +1 -0
- package/template/panel/assets/BlogPostPage-Bn_BvTp1.js +1 -0
- package/template/panel/assets/CalculadoraTiempoRespuestaPage-Bn_BvTp1.js +1 -0
- package/template/panel/assets/{CampaignDetailPage-DFMctNEj.js → CampaignDetailPage-DUNnckvn.js} +1 -1
- package/template/panel/assets/CampaignsPage-CS60yZBd.js +1 -0
- package/template/panel/assets/ChannelSelector-C7R9zqrt.js +1 -0
- package/template/panel/assets/ChatbotParaWhatsappPage-Bn_BvTp1.js +1 -0
- package/template/panel/assets/ConfirmModal-B27OBQdm.js +1 -0
- package/template/panel/assets/ContactsPage-CvoDlFUN.js +14 -0
- package/template/panel/assets/CreateAgentPage-CbhikMY1.js +19 -0
- package/template/panel/assets/CreditLimitBanner-j72L7jgK.js +1 -0
- package/template/panel/assets/CrmParaWhatsappPage-Bn_BvTp1.js +1 -0
- package/template/panel/assets/DashboardPage-BGWkXY7W.js +1 -0
- package/template/panel/assets/{EmojiPicker-BToAe-MT.js → EmojiPicker-ByTMSXTj.js} +1 -1
- package/template/panel/assets/{EventTypesSettingsPage-DCedeQzM.js → EventTypesSettingsPage-CLpO1VBL.js} +1 -1
- package/template/panel/assets/GeneradorEnlacesPage-Bn_BvTp1.js +1 -0
- package/template/panel/assets/GeneradorQrWhatsappPage-Bn_BvTp1.js +1 -0
- package/template/panel/assets/{GeneralSettingsPage-B04ozcHb.js → GeneralSettingsPage-CY-5aGgL.js} +1 -1
- package/template/panel/assets/GoogleCalendarManagePage-oX7DuErV.js +1 -0
- package/template/panel/assets/{InvitationAcceptancePage-BPgtBFl5.js → InvitationAcceptancePage-BYllrAYs.js} +1 -1
- package/template/panel/assets/IrAlSitioPublico-Bn_BvTp1.js +1 -0
- package/template/panel/assets/LiteAiUsagePage-Dzm8jBL2.js +1 -0
- package/template/panel/assets/{LiteSetupPage-42rgAdnG.js → LiteSetupPage-CMSAur_e.js} +1 -1
- package/template/panel/assets/MarkdownRenderer-C3TD9KYa.js +3 -0
- package/template/panel/assets/MediaProcessingService-CG2DdSyN.js +1 -0
- package/template/panel/assets/NewCampaignPage-BfSEd075.js +1 -0
- package/template/panel/assets/OrdersConfigPage-BAKKaX0L.js +1 -0
- package/template/panel/assets/OrdersPage-CXiPOCXP.js +1 -0
- package/template/panel/assets/{PasswordStrengthIndicator-HZK_oU0W.js → PasswordStrengthIndicator-4h-Y0s2r.js} +1 -1
- package/template/panel/assets/PlantillaDetailPage-Bn_BvTp1.js +1 -0
- package/template/panel/assets/PlantillasIndexPage-Bn_BvTp1.js +1 -0
- package/template/panel/assets/PrivacyPolicy-Bn_BvTp1.js +1 -0
- package/template/panel/assets/{ProductManagementPage-DNM7DEgt.js → ProductManagementPage-CRkNTicv.js} +4 -4
- package/template/panel/assets/PublicFormPage-BxPxJ3Pq.js +1 -0
- package/template/panel/assets/QaForm-Px-cmakA.js +5 -0
- package/template/panel/assets/SelectPlanPage-Gyo5C1Hq.js +1 -0
- package/template/panel/assets/SignatureEditor-DIhmrXow.js +1 -0
- package/template/panel/assets/{TagSelector-ChoKzvjW.js → TagSelector-o6tVpRs9.js} +1 -1
- package/template/panel/assets/TagsSettingsPage-DT8MfW1H.js +2 -0
- package/template/panel/assets/TeamsPage-BuWuGxZo.js +1 -0
- package/template/panel/assets/WhatsappBusinessApiPage-Bn_BvTp1.js +1 -0
- package/template/panel/assets/WhatsappMultiagentePage-Bn_BvTp1.js +1 -0
- package/template/panel/assets/{account-D2ltXC_U.js → account-G3WXxisG.js} +1 -1
- package/template/panel/assets/{admin-lEgqZTsa.js → admin-CSMlOMR8.js} +1 -1
- package/template/panel/assets/{agent.service-BcAkMU7j.js → agent.service-BE2rJG_o.js} +1 -1
- package/template/panel/assets/{alert-dialog-D8P69s-m.js → alert-dialog-gzZZoAiu.js} +2 -2
- package/template/panel/assets/{alert-DI3GBLi1.js → alert-seLKo73M.js} +1 -1
- package/template/panel/assets/api-keys-BF33GS2N.js +1 -0
- package/template/panel/assets/{archive-LUe5bKi5.js → archive-CxUKRJwu.js} +1 -1
- package/template/panel/assets/{arrow-left-BeDdBs_Q.js → arrow-left-CI7mH7bD.js} +1 -1
- package/template/panel/assets/{arrow-up-BiBq8Pvx.js → arrow-up-DJzXCc8_.js} +1 -1
- package/template/panel/assets/{arrow-up-down-CaG2BONN.js → arrow-up-down-DkSCsCjR.js} +1 -1
- package/template/panel/assets/audit-slljESxh.js +1 -0
- package/template/panel/assets/{authService-Cbm8LdlJ.js → authService-CtvlzCDa.js} +1 -1
- package/template/panel/assets/{avatar-CILB1zwS.js → avatar-BXhSKQGY.js} +1 -1
- package/template/panel/assets/{billing-IVLNopU2.js → billing-Cy2XUBeY.js} +1 -1
- package/template/panel/assets/{brain-B9z7jZ7A.js → brain-BmrjUpsb.js} +1 -1
- package/template/panel/assets/{calendar-CIHhMjNy.js → calendar-Bu0aDtW1.js} +1 -1
- package/template/panel/assets/{calendar-days-BwJfOz8M.js → calendar-days-CXtOZxOF.js} +1 -1
- package/template/panel/assets/{card-DcKsxjXK.js → card-DdbmSh-v.js} +1 -1
- package/template/panel/assets/{checkbox-pcbjC0d3.js → checkbox-CuJh5AMO.js} +1 -1
- package/template/panel/assets/{chevrons-up-down-DC-BWTrj.js → chevrons-up-down-DNNdNhV8.js} +1 -1
- package/template/panel/assets/{circle-check-big-DzPo5zZX.js → circle-check-big-BOZQ_2Kv.js} +1 -1
- package/template/panel/assets/{circle-x-BwMKIs8b.js → circle-x-decmm7ip.js} +1 -1
- package/template/panel/assets/cloud-B3m0_VpL.js +1 -0
- package/template/panel/assets/{code-BMAyHFJe.js → code-C-UH-ZD-.js} +1 -1
- package/template/panel/assets/{cog-M7j64wa2.js → cog-BS-_-U4F.js} +1 -1
- package/template/panel/assets/{collapsible-B22t1J-V.js → collapsible-Ce_8EeFJ.js} +1 -1
- package/template/panel/assets/{command-COdSmSIB.js → command-aHRTWaYV.js} +1 -1
- package/template/panel/assets/connectionsService-BJg4S1e9.js +1 -0
- package/template/panel/assets/contactsApi-DI5dcMLo.js +1 -0
- package/template/panel/assets/creditErrors-DSbswjsG.js +1 -0
- package/template/panel/assets/{database-C1qvt3Py.js → database-Brb7Omak.js} +1 -1
- package/template/panel/assets/{datapath-C12uI_pT.js → datapath-CHeKabeh.js} +1 -1
- package/template/panel/assets/{datetime-BuZosCVk.js → datetime-D72Uxhjs.js} +1 -1
- package/template/panel/assets/{download-CiVQHPeB.js → download-CyfdxFCW.js} +1 -1
- package/template/panel/assets/{ellipsis-CMEJnUfK.js → ellipsis-GLu0u4ze.js} +1 -1
- package/template/panel/assets/{ellipsis-vertical-DTqbEYYp.js → ellipsis-vertical-CskGwbgN.js} +1 -1
- package/template/panel/assets/email-inbox-kyJ2qML5.js +1 -0
- package/template/panel/assets/es-BDgg6unH.js +1 -0
- package/template/panel/assets/external-link-w7K66ae2.js +1 -0
- package/template/panel/assets/{eye-HfQCUjxJ.js → eye-CR5C6hVv.js} +1 -1
- package/template/panel/assets/{eye-off-v1Z_lKS0.js → eye-off-CBiJXw4j.js} +1 -1
- package/template/panel/assets/facebook-D0SQMea2.js +1 -0
- package/template/panel/assets/{file-DMzjdlTL.js → file-CTZ8-xmL.js} +1 -1
- package/template/panel/assets/file-braces-54MsOnzo.js +1 -0
- package/template/panel/assets/file-spreadsheet-DpekIaV8.js +1 -0
- package/template/panel/assets/{folder-D0GKakGp.js → folder-DxTHNhQ_.js} +1 -1
- package/template/panel/assets/{folder-open-DQFc4qTJ.js → folder-open-BM4rA96e.js} +1 -1
- package/template/panel/assets/format-BG1mN6C0.js +1 -0
- package/template/panel/assets/{grip-vertical-FN-eTC2C.js → grip-vertical-CS-dU0tJ.js} +1 -1
- package/template/panel/assets/{hash-BoTE56iw.js → hash-ByrjK6gt.js} +1 -1
- package/template/panel/assets/{help-center-B1MAIBWA.js → help-center-fmvvoAkD.js} +1 -1
- package/template/panel/assets/{history-DhHayxUg.js → history-97D1GT_9.js} +1 -1
- package/template/panel/assets/house-CXew5LB-.js +1 -0
- package/template/panel/assets/{index-DsyZ_FlA.js → index-43NA2pdZ.js} +23 -23
- package/template/panel/assets/index-BG59-Kyv.js +6 -0
- package/template/panel/assets/{index-DUnioqCT.js → index-BGvtgHY3.js} +1 -1
- package/template/panel/assets/index-BL76lyPt.js +2 -0
- package/template/panel/assets/index-BUA9lP4J.js +1 -0
- package/template/panel/assets/index-Bfvq4Q3v.js +1 -0
- package/template/panel/assets/index-CK793Wzl.css +1 -0
- package/template/panel/assets/{index-BTxe6gLJ.js → index-ChrvveQm.js} +1 -1
- package/template/panel/assets/index-CoJIvJ6y.js +1 -0
- package/template/panel/assets/{index-CMEeV9dO.js → index-CsV1u-Y7.js} +2 -2
- package/template/panel/assets/{index-BiSc3WD9.js → index-DIxON2Dm.js} +1 -1
- package/template/panel/assets/index-DtoSJTyl.js +1 -0
- package/template/panel/assets/index-FBuxpbGF.js +36 -0
- package/template/panel/assets/index-YR5X3nd4.js +1 -0
- package/template/panel/assets/{instagram-CC7iYt7V.js → instagram-Bm17x-Fs.js} +1 -1
- package/template/panel/assets/interactiveLimits-C7Sx7s9W.js +1 -0
- package/template/panel/assets/landing-CEUFhLJ9.js +1 -0
- package/template/panel/assets/{layout-grid-Cm6hfBWZ.js → layout-grid-DN-t2Wjd.js} +1 -1
- package/template/panel/assets/{list-BKc6EXnV.js → list-B0uLKf1b.js} +1 -1
- package/template/panel/assets/{map-pin-CPmcofD3.js → map-pin-COYHwobx.js} +1 -1
- package/template/panel/assets/{maximize-2-WdbM7Kdx.js → maximize-2-SbmXBBYe.js} +1 -1
- package/template/panel/assets/mediaLimits-CAYdWqeQ.js +1 -0
- package/template/panel/assets/mediaValidation-Bg0xHQrv.js +1 -0
- package/template/panel/assets/message-circle-tNSzOeOW.js +1 -0
- package/template/panel/assets/{message-square-Dfn16oHc.js → message-square-B1_OirdW.js} +1 -1
- package/template/panel/assets/{meta-templates-C7yEjSOI.js → meta-templates-hhDdxBOR.js} +1 -1
- package/template/panel/assets/metadataSchemasApi-BmJko2eC.js +1 -0
- package/template/panel/assets/{mic-CT4vyzLZ.js → mic-ClFq9hMZ.js} +1 -1
- package/template/panel/assets/minus-vh4a51Mn.js +1 -0
- package/template/panel/assets/{music-Cu8AQMFp.js → music-CgtkroYi.js} +1 -1
- package/template/panel/assets/{page-components-o2TF52HV.js → page-components-DXOKtt_M.js} +1 -1
- package/template/panel/assets/{pages-Cj5Qd1QO.js → pages-BcYbyh_-.js} +1 -1
- package/template/panel/assets/{pages-B7digtXi.js → pages-BuibyrnC.js} +1 -1
- package/template/panel/assets/{pages-Dw7dvmaS.js → pages-CGXCBdff.js} +1 -1
- package/template/panel/assets/paperclip-DVRbzE7C.js +1 -0
- package/template/panel/assets/{pen-line-DLnhkIuw.js → pen-line-Cr0YFjAs.js} +1 -1
- package/template/panel/assets/{pencil-Cx8u1N8t.js → pencil-aqjc7AWb.js} +1 -1
- package/template/panel/assets/{popover-MyuU-yAK.js → popover-cWIhNmod.js} +1 -1
- package/template/panel/assets/{power-CdR2OkIX.js → power-CVFzhVJx.js} +1 -1
- package/template/panel/assets/{product.service-CRLZOQsr.js → product.service-FClit10f.js} +1 -1
- package/template/panel/assets/products.types-nZIsk2w8.js +1 -0
- package/template/panel/assets/proxy-CvX2KM2u.js +1 -0
- package/template/panel/assets/{save-Dua2yhWl.js → save-mwkHDnDL.js} +1 -1
- package/template/panel/assets/scroll-area-CSCo4HHB.js +1 -0
- package/template/panel/assets/{select-DlB_BbfM.js → select-DCY_lg9j.js} +1 -1
- package/template/panel/assets/{send-Dxmdupsl.js → send-DBQH77K9.js} +1 -1
- package/template/panel/assets/{separator-CPT3uVRM.js → separator-DznqP68l.js} +1 -1
- package/template/panel/assets/{settings-2-C-c8ECWW.js → settings-2-PhKPMrsj.js} +1 -1
- package/template/panel/assets/shield-alert-Fv3j9Wbv.js +1 -0
- package/template/panel/assets/{skeleton-B0zh8s_y.js → skeleton-CN6xlRXP.js} +1 -1
- package/template/panel/assets/{slider-CY71MXOW.js → slider-D0QB_Lme.js} +1 -1
- package/template/panel/assets/{square-BuGqLxJB.js → square-Dm5VC71z.js} +1 -1
- package/template/panel/assets/{square-pen-CJajoyrm.js → square-pen-Dbn7xmc-.js} +1 -1
- package/template/panel/assets/{star-Cuegk1GF.js → star-BMD3HmS6.js} +1 -1
- package/template/panel/assets/stat-card-W7s_-fHW.js +1 -0
- package/template/panel/assets/storage.api-C0ZJBoSz.js +20 -0
- package/template/panel/assets/{switch-ODBa0fCT.js → switch-C7XmAU1c.js} +1 -1
- package/template/panel/assets/{table-CvSELOPi.js → table-7NGq0kRw.js} +1 -1
- package/template/panel/assets/{tabs-DqXhuAr6.js → tabs-BGCKrmVw.js} +1 -1
- package/template/panel/assets/{tags-By_tlh_r.js → tags-HU2fuPFH.js} +1 -1
- package/template/panel/assets/{target-DEuCdeUI.js → target-CG_g4_Fj.js} +1 -1
- package/template/panel/assets/{textarea-BYtcLsMD.js → textarea-B1anutjq.js} +1 -1
- package/template/panel/assets/{ticket-CWba7G1i.js → ticket-CHs1Xojr.js} +1 -1
- package/template/panel/assets/{trash-2-Du2vmQCH.js → trash-2-D_kmHMwn.js} +1 -1
- package/template/panel/assets/{trending-up-Ba4HSvuW.js → trending-up-BnHeLWFs.js} +1 -1
- package/template/panel/assets/{upload-C7TwpdyA.js → upload-CQg4_W5r.js} +1 -1
- package/template/panel/assets/{useAiAgentsQuery-Bm6aRHKj.js → useAiAgentsQuery-CXo6TmU6.js} +1 -1
- package/template/panel/assets/useFunnelStats-Bk8wTET5.js +1 -0
- package/template/panel/assets/useFunnelsQuery-vDrahaDr.js +1 -0
- package/template/panel/assets/{useInfiniteQuery-BXUM1Z9V.js → useInfiniteQuery-D0sFT2K2.js} +1 -1
- package/template/panel/assets/{useMutation-a5tIBvQY.js → useMutation-0ypmz8SO.js} +1 -1
- package/template/panel/assets/useOrgSyncedFetch-FSgwRhpR.js +1 -0
- package/template/panel/assets/usePipelineBoardQuery-BysscZXI.js +9 -0
- package/template/panel/assets/{useUploadConfig-BuiF0X-3.js → useUploadConfig-CvVmSc6S.js} +1 -1
- package/template/panel/assets/{user-DwCALzIG.js → user-l48WDfDH.js} +1 -1
- package/template/panel/assets/{user-plus-BiUjcHil.js → user-plus-CWaaUP-O.js} +1 -1
- package/template/panel/assets/{video-VfwKgB6z.js → video-CILE66CA.js} +1 -1
- package/template/panel/assets/{volume-2-C5DMdOVq.js → volume-2-DfFqN0dw.js} +1 -1
- package/template/panel/assets/wrench-Dcbk4scY.js +1 -0
- package/template/panel/index.html +2 -2
- package/template/panel/version.json +2 -2
- package/template/worker/migrations/0006_ai_usage.sql +33 -0
- package/template/worker/migrations/0007_channels.sql +18 -0
- package/template/worker/src/agent/pricing.ts +37 -0
- package/template/worker/src/agent/prompt.ts +137 -134
- package/template/worker/src/agent/run.ts +350 -243
- package/template/worker/src/agent/sandbox.ts +2 -2
- package/template/worker/src/agent/tools.ts +463 -463
- package/template/worker/src/channels/accounts.ts +177 -0
- package/template/worker/src/channels/zernio.ts +161 -148
- package/template/worker/src/inbox/contacts.ts +2 -0
- package/template/worker/src/inbox/store.ts +199 -187
- package/template/worker/src/index.ts +2 -0
- package/template/worker/src/nubot/account.ts +163 -178
- package/template/worker/src/nubot/ai-usage.ts +197 -0
- package/template/worker/src/nubot/channels.ts +159 -0
- package/template/worker/src/nubot/contacts.ts +387 -386
- package/template/worker/src/nubot/funnels.ts +672 -670
- package/template/worker/src/nubot/inbox.ts +623 -616
- package/template/worker/src/nubot/index.ts +127 -122
- package/template/worker/src/nubot/mappers.ts +12 -5
- package/template/worker/src/routes/channels.ts +13 -0
- package/template/worker/src/routes/system.ts +110 -100
- package/template/worker/src/webhooks/zernio.ts +154 -125
- package/template/panel/assets/AgendarDemoPage-DOiS40FL.js +0 -1
- package/template/panel/assets/AgentKnowledgeGroupsPage-DEPS1lsk.js +0 -1
- package/template/panel/assets/AgentListPage-DqY9rze5.js +0 -1
- package/template/panel/assets/AgentQaTrainingPage-Ecis7xoc.js +0 -1
- package/template/panel/assets/AiAgentWhatsappPage-DOiS40FL.js +0 -1
- package/template/panel/assets/AiMetricsPage-DEPS1lsk.js +0 -1
- package/template/panel/assets/BlogPage-DOiS40FL.js +0 -1
- package/template/panel/assets/BlogPostPage-DOiS40FL.js +0 -1
- package/template/panel/assets/CalculadoraTiempoRespuestaPage-DOiS40FL.js +0 -1
- package/template/panel/assets/CampaignsPage-CLRaXGlj.js +0 -1
- package/template/panel/assets/ChannelSelector-q9tTirNo.js +0 -1
- package/template/panel/assets/ChatbotParaWhatsappPage-DOiS40FL.js +0 -1
- package/template/panel/assets/ConfirmModal-W7VUI3Z_.js +0 -1
- package/template/panel/assets/ContactsPage-CsOFsOPw.js +0 -14
- package/template/panel/assets/CreateAgentPage-Ifxx6_UX.js +0 -19
- package/template/panel/assets/CreditLimitBanner-J49rSVEn.js +0 -1
- package/template/panel/assets/CrmParaWhatsappPage-DOiS40FL.js +0 -1
- package/template/panel/assets/DashboardPage-3Viy83dd.js +0 -1
- package/template/panel/assets/GeneradorEnlacesPage-DOiS40FL.js +0 -1
- package/template/panel/assets/GeneradorQrWhatsappPage-DOiS40FL.js +0 -1
- package/template/panel/assets/IrAlSitioPublico-DOiS40FL.js +0 -1
- package/template/panel/assets/MediaProcessingService-glHGiE_o.js +0 -1
- package/template/panel/assets/NewCampaignPage-Cw99m3W8.js +0 -1
- package/template/panel/assets/OrdersConfigPage-B6BfM3lf.js +0 -1
- package/template/panel/assets/OrdersPage-Du7CJjty.js +0 -1
- package/template/panel/assets/PlantillaDetailPage-DOiS40FL.js +0 -1
- package/template/panel/assets/PlantillasIndexPage-DOiS40FL.js +0 -1
- package/template/panel/assets/PrivacyPolicy-DOiS40FL.js +0 -1
- package/template/panel/assets/PublicFormPage-DDb4OXEM.js +0 -1
- package/template/panel/assets/QaForm-BDboHNKo.js +0 -5
- package/template/panel/assets/SelectPlanPage-DALaf8E5.js +0 -1
- package/template/panel/assets/TagsSettingsPage-DYCKveQq.js +0 -2
- package/template/panel/assets/TeamsPage-DPUcRdlh.js +0 -1
- package/template/panel/assets/WhatsappBusinessApiPage-DOiS40FL.js +0 -1
- package/template/panel/assets/WhatsappMultiagentePage-DOiS40FL.js +0 -1
- package/template/panel/assets/api-keys-B0UQNR5E.js +0 -1
- package/template/panel/assets/audit-BrdHcTNl.js +0 -1
- package/template/panel/assets/connections-Dqwd01UI.js +0 -1
- package/template/panel/assets/connectionsService-BsJf8pFz.js +0 -3
- package/template/panel/assets/contactsApi-B851NME_.js +0 -1
- package/template/panel/assets/creditErrors-CrpkwwUI.js +0 -1
- package/template/panel/assets/email-inbox-LbGeQCty.js +0 -1
- package/template/panel/assets/es-BG480iA5.js +0 -1
- package/template/panel/assets/facebook-RxMBweMB.js +0 -1
- package/template/panel/assets/index-B183O0S5.js +0 -1
- package/template/panel/assets/index-BJCPaymI.css +0 -1
- package/template/panel/assets/index-BtxJGfLL.js +0 -6
- package/template/panel/assets/index-Bz-ixwph.js +0 -1
- package/template/panel/assets/index-CjQSv8hF.js +0 -2
- package/template/panel/assets/index-D3vkHHjD.js +0 -9
- package/template/panel/assets/index-D4WhIkMN.js +0 -1
- package/template/panel/assets/interactiveLimits-CfLJ1O4_.js +0 -1
- package/template/panel/assets/landing-If3oVsS0.js +0 -1
- package/template/panel/assets/mediaValidation-BR-ZOj5w.js +0 -1
- package/template/panel/assets/minus-CyVEzdqL.js +0 -1
- package/template/panel/assets/products.types-46xSxBS8.js +0 -1
- package/template/panel/assets/scroll-area-CavEOIyz.js +0 -1
- package/template/panel/assets/shield-alert-04pSYngI.js +0 -1
- package/template/panel/assets/storage.api-CFU3KJNp.js +0 -20
- package/template/panel/assets/useFunnelStats-tvjpmWIC.js +0 -1
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// Conexiones: las cuentas de WhatsApp, Instagram y Facebook de la empresa, conectadas por Zernio.
|
|
2
|
+
// El panel pide un enlace, la persona entra con su cuenta de Meta en Zernio y vuelve al CRM ya conectada.
|
|
3
|
+
|
|
4
|
+
import { Hono, type Context } from "hono";
|
|
5
|
+
import {
|
|
6
|
+
channelByAccount,
|
|
7
|
+
connectState,
|
|
8
|
+
connectUrl,
|
|
9
|
+
deleteAccount,
|
|
10
|
+
findAccount,
|
|
11
|
+
listChannels,
|
|
12
|
+
PLATFORM_NAMES,
|
|
13
|
+
readConnectState,
|
|
14
|
+
saveChannel,
|
|
15
|
+
syncWebhook,
|
|
16
|
+
ZernioError,
|
|
17
|
+
type ChannelRow,
|
|
18
|
+
type Platform,
|
|
19
|
+
} from "../channels/accounts";
|
|
20
|
+
import type { NubotEnv } from "./index";
|
|
21
|
+
import { PANEL_CHANNEL_TYPE } from "./mappers";
|
|
22
|
+
|
|
23
|
+
type Ctx = Context<NubotEnv>;
|
|
24
|
+
|
|
25
|
+
/** La pantalla del panel de cada red. Messenger es la página de Facebook. */
|
|
26
|
+
const PANEL_PAGE: Record<Platform, string> = { whatsapp: "whatsapp", instagram: "instagram", facebook: "messenger" };
|
|
27
|
+
|
|
28
|
+
const origin = (c: Ctx) => new URL(c.req.url).origin;
|
|
29
|
+
|
|
30
|
+
const onlyAdmin = (c: Ctx) =>
|
|
31
|
+
c.get("user").role === "admin" ? null : c.json({ message: "Solo un administrador puede cambiar las conexiones.", statusCode: 403 }, 403);
|
|
32
|
+
|
|
33
|
+
const explain = (err: unknown) => (err instanceof ZernioError ? err.message : "Algo falló al hablar con Zernio. Vuelve a intentar.");
|
|
34
|
+
|
|
35
|
+
/** Un canal en la forma del panel. Su id es el de la cuenta en Zernio, el mismo que llevan las conversaciones. */
|
|
36
|
+
function toPanelChannel(row: ChannelRow) {
|
|
37
|
+
const name = row.name ?? PLATFORM_NAMES[row.platform];
|
|
38
|
+
return {
|
|
39
|
+
id: row.zernio_account_id,
|
|
40
|
+
name: row.username && row.platform === "instagram" ? `@${row.username}` : name,
|
|
41
|
+
type: PANEL_CHANNEL_TYPE[row.platform],
|
|
42
|
+
providerId: row.zernio_account_id,
|
|
43
|
+
isActive: row.active === 1,
|
|
44
|
+
connectionMethod: "zernio",
|
|
45
|
+
// El panel considera conectada una página con este campo; el token real lo guarda Zernio.
|
|
46
|
+
accessTokenEncrypted: row.active === 1 ? "zernio" : null,
|
|
47
|
+
credentials: {
|
|
48
|
+
name,
|
|
49
|
+
username: row.username,
|
|
50
|
+
profilePictureUrl: row.picture,
|
|
51
|
+
pageName: name,
|
|
52
|
+
pagePicture: row.picture,
|
|
53
|
+
},
|
|
54
|
+
config: { webhookSubscribed: row.active === 1 },
|
|
55
|
+
createdAt: new Date(row.created_at).toISOString(),
|
|
56
|
+
updatedAt: new Date(row.updated_at).toISOString(),
|
|
57
|
+
deletedAt: row.active === 1 ? null : new Date(row.updated_at).toISOString(),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ---------- La vuelta desde Zernio (sin sesión: la trae el navegador) ----------
|
|
62
|
+
|
|
63
|
+
export const channelsPublic = new Hono<NubotEnv>();
|
|
64
|
+
|
|
65
|
+
channelsPublic.get("/channels/zernio/callback", async (c) => {
|
|
66
|
+
const platform = await readConnectState(c.env, c.req.query("state"));
|
|
67
|
+
if (!platform) return c.redirect("/conexiones?error=" + encodeURIComponent("El enlace para conectar venció. Vuelve a intentarlo."));
|
|
68
|
+
const page = `/conexiones/${PANEL_PAGE[platform]}`;
|
|
69
|
+
const fail = (message: string) => c.redirect(`${page}?error=${encodeURIComponent(message)}`);
|
|
70
|
+
|
|
71
|
+
const accountId = c.req.query("accountId");
|
|
72
|
+
if (c.req.query("error") || !accountId) {
|
|
73
|
+
return fail(c.req.query("error_message") ?? "No se completó la conexión con Meta. Vuelve a intentarlo.");
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const account = await findAccount(c.env, platform, accountId);
|
|
77
|
+
await saveChannel(c.env, {
|
|
78
|
+
platform,
|
|
79
|
+
accountId,
|
|
80
|
+
name: account?.displayName ?? c.req.query("username") ?? null,
|
|
81
|
+
username: account?.username ?? c.req.query("username") ?? null,
|
|
82
|
+
picture: account?.profilePicture ?? null,
|
|
83
|
+
});
|
|
84
|
+
await syncWebhook(c.env, origin(c));
|
|
85
|
+
} catch (err) {
|
|
86
|
+
return fail(explain(err));
|
|
87
|
+
}
|
|
88
|
+
return c.redirect(`${page}/${encodeURIComponent(accountId)}?success=true`);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// ---------- Con sesión ----------
|
|
92
|
+
|
|
93
|
+
export const channels = new Hono<NubotEnv>();
|
|
94
|
+
|
|
95
|
+
channels.get("/channels", async (c) => {
|
|
96
|
+
const rows = await listChannels(c.env, c.req.query("withDeleted") === "true");
|
|
97
|
+
return c.json(rows.map(toPanelChannel));
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
/** El enlace de Zernio para conectar. Si algo falla, el «enlace» es la misma pantalla con el aviso. */
|
|
101
|
+
async function authUrl(c: Ctx, platform: Platform) {
|
|
102
|
+
const denied = onlyAdmin(c);
|
|
103
|
+
if (denied) return denied;
|
|
104
|
+
const back = new URL("/api/v1/channels/zernio/callback", origin(c));
|
|
105
|
+
back.searchParams.set("state", await connectState(c.env, platform));
|
|
106
|
+
try {
|
|
107
|
+
return c.json({ url: await connectUrl(c.env, platform, back.toString()) });
|
|
108
|
+
} catch (err) {
|
|
109
|
+
return c.json({ url: `/conexiones/${PANEL_PAGE[platform]}?error=${encodeURIComponent(explain(err))}` });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
channels.post("/channels/instagram/auth/url", (c) => authUrl(c, "instagram"));
|
|
114
|
+
channels.post("/channels/messenger/auth/url", (c) => authUrl(c, "facebook"));
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Desconecta: el CRM deja de recibir sus mensajes y las conversaciones se quedan. Instagram y Facebook
|
|
118
|
+
* además se sueltan en Zernio (dejan de cobrarse); el número de WhatsApp no, porque registrarlo de nuevo con Meta es delicado.
|
|
119
|
+
*/
|
|
120
|
+
async function disconnect(c: Ctx, accountId: string | undefined) {
|
|
121
|
+
const denied = onlyAdmin(c);
|
|
122
|
+
if (denied) return denied;
|
|
123
|
+
const row = accountId ? await channelByAccount(c.env, accountId) : null;
|
|
124
|
+
if (!row) return c.json({ success: false, message: "Esa conexión no existe." }, 404);
|
|
125
|
+
try {
|
|
126
|
+
if (row.platform !== "whatsapp") await deleteAccount(c.env, row.zernio_account_id);
|
|
127
|
+
await c.env.DB.prepare("UPDATE channels SET active = 0, updated_at = ? WHERE id = ?").bind(Date.now(), row.id).run();
|
|
128
|
+
await syncWebhook(c.env, origin(c));
|
|
129
|
+
} catch (err) {
|
|
130
|
+
return c.json({ success: false, message: explain(err) }, 502);
|
|
131
|
+
}
|
|
132
|
+
return c.json({ success: true, message: `${PLATFORM_NAMES[row.platform]} desconectado.` });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
channels.post("/channels/instagram/auth/disconnect", async (c) => disconnect(c, (await c.req.json<{ channelId?: string }>()).channelId));
|
|
136
|
+
channels.post("/channels/messenger/auth/disconnect", async (c) => disconnect(c, (await c.req.json<{ channelId?: string }>()).channelId));
|
|
137
|
+
channels.delete("/channels/:id", (c) => disconnect(c, c.req.param("id")));
|
|
138
|
+
|
|
139
|
+
channels.get("/channels/:id", async (c) => {
|
|
140
|
+
const row = await channelByAccount(c.env, c.req.param("id"));
|
|
141
|
+
if (!row) return c.json({ message: "Esa conexión no existe.", statusCode: 404 }, 404);
|
|
142
|
+
return c.json(toPanelChannel(row));
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
/** Pregunta a Zernio si la cuenta sigue conectada y con permiso. */
|
|
146
|
+
channels.post("/channels/:id/test", async (c) => {
|
|
147
|
+
const row = await channelByAccount(c.env, c.req.param("id"));
|
|
148
|
+
if (!row) return c.json({ success: false, message: "Esa conexión no existe." }, 404);
|
|
149
|
+
try {
|
|
150
|
+
const account = await findAccount(c.env, row.platform, row.zernio_account_id);
|
|
151
|
+
if (!account) return c.json({ success: false, message: "Zernio ya no tiene esta cuenta. Conéctala otra vez." });
|
|
152
|
+
if (account.needsReconnection || account.isActive === false) {
|
|
153
|
+
return c.json({ success: false, message: "Meta pide volver a conectar esta cuenta. Desconéctala y conéctala otra vez." });
|
|
154
|
+
}
|
|
155
|
+
return c.json({ success: true, message: `${PLATFORM_NAMES[row.platform]} conectado y recibiendo mensajes.`, channel: toPanelChannel(row) });
|
|
156
|
+
} catch (err) {
|
|
157
|
+
return c.json({ success: false, message: explain(err) });
|
|
158
|
+
}
|
|
159
|
+
});
|